^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * HD audio interface patch for Creative CA0132 chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2011, Creative Technology Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on patch_ca0110.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) 2008 Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <sound/hda_codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "hda_local.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "hda_auto_parser.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "hda_jack.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "ca0132_regs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* Enable this to see controls for tuning purpose. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*#define ENABLE_TUNING_CONTROLS*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #ifdef ENABLE_TUNING_CONTROLS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define FLOAT_ZERO 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define FLOAT_ONE 0x3f800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define FLOAT_TWO 0x40000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define FLOAT_THREE 0x40400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define FLOAT_FIVE 0x40a00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define FLOAT_SIX 0x40c00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define FLOAT_EIGHT 0x41000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define FLOAT_MINUS_5 0xc0a00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define UNSOL_TAG_DSP 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define DSP_DMA_WRITE_BUFLEN_INIT (1UL<<18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define DSP_DMA_WRITE_BUFLEN_OVLY (1UL<<15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define DMA_TRANSFER_FRAME_SIZE_NWORDS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define DMA_TRANSFER_MAX_FRAME_SIZE_NWORDS 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define DMA_OVERLAY_FRAME_SIZE_NWORDS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define MASTERCONTROL 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define MASTERCONTROL_ALLOC_DMA_CHAN 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define MASTERCONTROL_QUERY_SPEAKER_EQ_ADDRESS 60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define WIDGET_CHIP_CTRL 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define WIDGET_DSP_CTRL 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define MEM_CONNID_MICIN1 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define MEM_CONNID_MICIN2 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define MEM_CONNID_MICOUT1 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define MEM_CONNID_MICOUT2 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define MEM_CONNID_WUH 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define MEM_CONNID_DSP 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define MEM_CONNID_DMIC 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define SCP_SET 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SCP_GET 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define EFX_FILE "ctefx.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define DESKTOP_EFX_FILE "ctefx-desktop.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define R3DI_EFX_FILE "ctefx-r3di.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #ifdef CONFIG_SND_HDA_CODEC_CA0132_DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) MODULE_FIRMWARE(EFX_FILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) MODULE_FIRMWARE(DESKTOP_EFX_FILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) MODULE_FIRMWARE(R3DI_EFX_FILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static const char *const dirstr[2] = { "Playback", "Capture" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define NUM_OF_OUTPUTS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static const char *const out_type_str[2] = { "Speakers", "Headphone" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) SPEAKER_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) HEADPHONE_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) DIGITAL_MIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) LINE_MIC_IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* Strings for Input Source Enum Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static const char *const in_src_str[3] = { "Microphone", "Line In", "Front Microphone" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define IN_SRC_NUM_OF_INPUTS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) REAR_MIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) REAR_LINE_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) FRONT_MIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define VNODE_START_NID 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) VNID_SPK = VNODE_START_NID, /* Speaker vnid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) VNID_MIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) VNID_HP_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) VNID_AMIC1_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) VNID_HP_ASEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) VNID_AMIC1_ASEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) VNODE_END_NID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define VNODES_COUNT (VNODE_END_NID - VNODE_START_NID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define EFFECT_START_NID 0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define OUT_EFFECT_START_NID EFFECT_START_NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) SURROUND = OUT_EFFECT_START_NID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) CRYSTALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) DIALOG_PLUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) SMART_VOLUME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) X_BASS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) EQUALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) OUT_EFFECT_END_NID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define OUT_EFFECTS_COUNT (OUT_EFFECT_END_NID - OUT_EFFECT_START_NID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define IN_EFFECT_START_NID OUT_EFFECT_END_NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ECHO_CANCELLATION = IN_EFFECT_START_NID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) VOICE_FOCUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) MIC_SVM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) NOISE_REDUCTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) IN_EFFECT_END_NID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define IN_EFFECTS_COUNT (IN_EFFECT_END_NID - IN_EFFECT_START_NID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) VOICEFX = IN_EFFECT_END_NID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) PLAY_ENHANCEMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) CRYSTAL_VOICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) EFFECT_END_NID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) OUTPUT_SOURCE_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) INPUT_SOURCE_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) XBASS_XOVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) EQ_PRESET_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) SMART_VOLUME_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) MIC_BOOST_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) AE5_HEADPHONE_GAIN_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) AE5_SOUND_FILTER_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ZXR_HEADPHONE_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) SPEAKER_CHANNEL_CFG_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) SPEAKER_FULL_RANGE_FRONT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) SPEAKER_FULL_RANGE_REAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) BASS_REDIRECTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) BASS_REDIRECTION_XOVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define EFFECTS_COUNT (EFFECT_END_NID - EFFECT_START_NID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* Effects values size*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define EFFECT_VALS_MAX_COUNT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * Default values for the effect slider controls, they are in order of their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * effect NID's. Surround, Crystalizer, Dialog Plus, Smart Volume, and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * X-bass.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static const unsigned int effect_slider_defaults[] = {67, 65, 50, 74, 50};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Amount of effect level sliders for ca0132_alt controls. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define EFFECT_LEVEL_SLIDERS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* Latency introduced by DSP blocks in milliseconds. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define DSP_CAPTURE_INIT_LATENCY 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define DSP_CRYSTAL_VOICE_LATENCY 124
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define DSP_PLAYBACK_INIT_LATENCY 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define DSP_PLAY_ENHANCEMENT_LATENCY 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define DSP_SPEAKER_OUT_LATENCY 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct ct_effect {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int mid; /*effect module ID*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int reqs[EFFECT_VALS_MAX_COUNT]; /*effect module request*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int direct; /* 0:output; 1:input*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int params; /* number of default non-on/off params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /*effect default values, 1st is on/off. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) unsigned int def_vals[EFFECT_VALS_MAX_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define EFX_DIR_OUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define EFX_DIR_IN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static const struct ct_effect ca0132_effects[EFFECTS_COUNT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) { .name = "Surround",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .nid = SURROUND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .reqs = {0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .params = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .def_vals = {0x3F800000, 0x3F2B851F}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) { .name = "Crystalizer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .nid = CRYSTALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .reqs = {7, 8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .params = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .def_vals = {0x3F800000, 0x3F266666}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) { .name = "Dialog Plus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .nid = DIALOG_PLUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .reqs = {2, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .params = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .def_vals = {0x00000000, 0x3F000000}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) { .name = "Smart Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .nid = SMART_VOLUME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .reqs = {4, 5, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .params = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .def_vals = {0x3F800000, 0x3F3D70A4, 0x00000000}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) { .name = "X-Bass",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .nid = X_BASS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .reqs = {24, 23, 25},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .params = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .def_vals = {0x3F800000, 0x42A00000, 0x3F000000}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) { .name = "Equalizer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) .nid = EQUALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .reqs = {9, 10, 11, 12, 13, 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 15, 16, 17, 18, 19, 20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .params = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .def_vals = {0x00000000, 0x00000000, 0x00000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 0x00000000, 0x00000000, 0x00000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 0x00000000, 0x00000000, 0x00000000, 0x00000000}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) { .name = "Echo Cancellation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .nid = ECHO_CANCELLATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .mid = 0x95,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .reqs = {0, 1, 2, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .direct = EFX_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .params = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .def_vals = {0x00000000, 0x3F3A9692, 0x00000000, 0x00000000}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) { .name = "Voice Focus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .nid = VOICE_FOCUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .mid = 0x95,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .reqs = {6, 7, 8, 9},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .direct = EFX_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .params = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .def_vals = {0x3F800000, 0x3D7DF3B6, 0x41F00000, 0x41F00000}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) { .name = "Mic SVM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .nid = MIC_SVM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .mid = 0x95,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .reqs = {44, 45},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .direct = EFX_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .params = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .def_vals = {0x00000000, 0x3F3D70A4}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) { .name = "Noise Reduction",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .nid = NOISE_REDUCTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .mid = 0x95,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .reqs = {4, 5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .direct = EFX_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .params = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .def_vals = {0x3F800000, 0x3F000000}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) { .name = "VoiceFX",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .nid = VOICEFX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .mid = 0x95,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .reqs = {10, 11, 12, 13, 14, 15, 16, 17, 18},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .direct = EFX_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) .params = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .def_vals = {0x00000000, 0x43C80000, 0x44AF0000, 0x44FA0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 0x3F800000, 0x3F800000, 0x3F800000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 0x00000000}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* Tuning controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #ifdef ENABLE_TUNING_CONTROLS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #define TUNING_CTL_START_NID 0xC0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) WEDGE_ANGLE = TUNING_CTL_START_NID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) SVM_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) EQUALIZER_BAND_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) EQUALIZER_BAND_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) EQUALIZER_BAND_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) EQUALIZER_BAND_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) EQUALIZER_BAND_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) EQUALIZER_BAND_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) EQUALIZER_BAND_6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) EQUALIZER_BAND_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) EQUALIZER_BAND_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) EQUALIZER_BAND_9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) TUNING_CTL_END_NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #define TUNING_CTLS_COUNT (TUNING_CTL_END_NID - TUNING_CTL_START_NID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct ct_tuning_ctl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) hda_nid_t parent_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) int mid; /*effect module ID*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int req; /*effect module request*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) int direct; /* 0:output; 1:input*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) unsigned int def_val;/*effect default values*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static const struct ct_tuning_ctl ca0132_tuning_ctls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) { .name = "Wedge Angle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) .parent_nid = VOICE_FOCUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) .nid = WEDGE_ANGLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) .mid = 0x95,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) .req = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .direct = EFX_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) .def_val = 0x41F00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) { .name = "SVM Level",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .parent_nid = MIC_SVM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .nid = SVM_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .mid = 0x95,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .req = 45,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .direct = EFX_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) .def_val = 0x3F3D70A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) { .name = "EQ Band0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) .parent_nid = EQUALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .nid = EQUALIZER_BAND_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .req = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) .def_val = 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) { .name = "EQ Band1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) .parent_nid = EQUALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) .nid = EQUALIZER_BAND_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) .req = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) .def_val = 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) { .name = "EQ Band2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .parent_nid = EQUALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) .nid = EQUALIZER_BAND_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) .req = 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .def_val = 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) { .name = "EQ Band3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) .parent_nid = EQUALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) .nid = EQUALIZER_BAND_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) .req = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .def_val = 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) { .name = "EQ Band4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) .parent_nid = EQUALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .nid = EQUALIZER_BAND_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .req = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .def_val = 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) { .name = "EQ Band5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) .parent_nid = EQUALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) .nid = EQUALIZER_BAND_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) .req = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) .def_val = 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) { .name = "EQ Band6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) .parent_nid = EQUALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) .nid = EQUALIZER_BAND_6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .req = 17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) .def_val = 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) { .name = "EQ Band7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .parent_nid = EQUALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .nid = EQUALIZER_BAND_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .req = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .def_val = 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) { .name = "EQ Band8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .parent_nid = EQUALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) .nid = EQUALIZER_BAND_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) .req = 19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) .def_val = 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) { .name = "EQ Band9",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .parent_nid = EQUALIZER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .nid = EQUALIZER_BAND_9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) .req = 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .direct = EFX_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .def_val = 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* Voice FX Presets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) #define VOICEFX_MAX_PARAM_COUNT 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct ct_voicefx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) int mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) int reqs[VOICEFX_MAX_PARAM_COUNT]; /*effect module request*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct ct_voicefx_preset {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) char *name; /*preset name*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) unsigned int vals[VOICEFX_MAX_PARAM_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static const struct ct_voicefx ca0132_voicefx = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .name = "VoiceFX Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .nid = VOICEFX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .mid = 0x95,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .reqs = {10, 11, 12, 13, 14, 15, 16, 17, 18}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static const struct ct_voicefx_preset ca0132_voicefx_presets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) { .name = "Neutral",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .vals = { 0x00000000, 0x43C80000, 0x44AF0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 0x44FA0000, 0x3F800000, 0x3F800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 0x3F800000, 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) { .name = "Female2Male",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 0x44FA0000, 0x3F19999A, 0x3F866666,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 0x3F800000, 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) { .name = "Male2Female",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 0x450AC000, 0x4017AE14, 0x3F6B851F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 0x3F800000, 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) { .name = "ScrappyKid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 0x44FA0000, 0x40400000, 0x3F28F5C3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 0x3F800000, 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) { .name = "Elderly",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .vals = { 0x3F800000, 0x44324000, 0x44BB8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 0x44E10000, 0x3FB33333, 0x3FB9999A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 0x3F800000, 0x3E3A2E43, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) { .name = "Orc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .vals = { 0x3F800000, 0x43EA0000, 0x44A52000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 0x45098000, 0x3F266666, 0x3FC00000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 0x3F800000, 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) { .name = "Elf",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) .vals = { 0x3F800000, 0x43C70000, 0x44AE6000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 0x45193000, 0x3F8E147B, 0x3F75C28F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 0x3F800000, 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) { .name = "Dwarf",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .vals = { 0x3F800000, 0x43930000, 0x44BEE000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 0x45007000, 0x3F451EB8, 0x3F7851EC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 0x3F800000, 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) { .name = "AlienBrute",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) .vals = { 0x3F800000, 0x43BFC5AC, 0x44B28FDF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 0x451F6000, 0x3F266666, 0x3FA7D945,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 0x3F800000, 0x3CF5C28F, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) { .name = "Robot",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 0x44FA0000, 0x3FB2718B, 0x3F800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 0xBC07010E, 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) { .name = "Marine",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) .vals = { 0x3F800000, 0x43C20000, 0x44906000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 0x44E70000, 0x3F4CCCCD, 0x3F8A3D71,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 0x3F0A3D71, 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) { .name = "Emo",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 0x44FA0000, 0x3F800000, 0x3F800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 0x3E4CCCCD, 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) { .name = "DeepVoice",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) .vals = { 0x3F800000, 0x43A9C5AC, 0x44AA4FDF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 0x44FFC000, 0x3EDBB56F, 0x3F99C4CA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 0x3F800000, 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) { .name = "Munchkin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 0x44FA0000, 0x3F800000, 0x3F1A043C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 0x3F800000, 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* ca0132 EQ presets, taken from Windows Sound Blaster Z Driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) #define EQ_PRESET_MAX_PARAM_COUNT 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct ct_eq {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) int mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) int reqs[EQ_PRESET_MAX_PARAM_COUNT]; /*effect module request*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct ct_eq_preset {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) char *name; /*preset name*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) unsigned int vals[EQ_PRESET_MAX_PARAM_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static const struct ct_eq ca0132_alt_eq_enum = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) .name = "FX: Equalizer Preset Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .nid = EQ_PRESET_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) .mid = 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) .reqs = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static const struct ct_eq_preset ca0132_alt_eq_presets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) { .name = "Flat",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .vals = { 0x00000000, 0x00000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 0x00000000, 0x00000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 0x00000000, 0x00000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 0x00000000, 0x00000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) { .name = "Acoustic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .vals = { 0x00000000, 0x00000000, 0x3F8CCCCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 0x40000000, 0x00000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 0x00000000, 0x00000000, 0x40000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 0x40000000, 0x40000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) { .name = "Classical",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .vals = { 0x00000000, 0x00000000, 0x40C00000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 0x40C00000, 0x40466666, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 0x00000000, 0x00000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 0x40466666, 0x40466666 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) { .name = "Country",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .vals = { 0x00000000, 0xBF99999A, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 0x3FA66666, 0x3FA66666, 0x3F8CCCCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 0x00000000, 0x00000000, 0x40000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 0x40466666, 0x40800000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) { .name = "Dance",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .vals = { 0x00000000, 0xBF99999A, 0x40000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 0x40466666, 0x40866666, 0xBF99999A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 0xBF99999A, 0x00000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 0x40800000, 0x40800000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) { .name = "Jazz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .vals = { 0x00000000, 0x00000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 0x3F8CCCCD, 0x40800000, 0x40800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 0x40800000, 0x00000000, 0x3F8CCCCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 0x40466666, 0x40466666 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) { .name = "New Age",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .vals = { 0x00000000, 0x00000000, 0x40000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 0x40000000, 0x00000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 0x00000000, 0x3F8CCCCD, 0x40000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 0x40000000, 0x40000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) { .name = "Pop",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .vals = { 0x00000000, 0xBFCCCCCD, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 0x40000000, 0x40000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 0xBF99999A, 0xBF99999A, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 0x40466666, 0x40C00000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) { .name = "Rock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .vals = { 0x00000000, 0xBF99999A, 0xBF99999A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 0x3F8CCCCD, 0x40000000, 0xBF99999A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 0xBF99999A, 0x00000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 0x40800000, 0x40800000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) { .name = "Vocal",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) .vals = { 0x00000000, 0xC0000000, 0xBF99999A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 0xBF99999A, 0x00000000, 0x40466666,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 0x40800000, 0x40466666, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 0x00000000, 0x3F8CCCCD }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * DSP reqs for handling full-range speakers/bass redirection. If a speaker is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * set as not being full range, and bass redirection is enabled, all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * frequencies below the crossover frequency are redirected to the LFE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * channel. If the surround configuration has no LFE channel, this can't be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * enabled. X-Bass must be disabled when using these.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) enum speaker_range_reqs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) SPEAKER_BASS_REDIRECT = 0x15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) SPEAKER_BASS_REDIRECT_XOVER_FREQ = 0x16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /* Between 0x16-0x1a are the X-Bass reqs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) SPEAKER_FULL_RANGE_FRONT_L_R = 0x1a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) SPEAKER_FULL_RANGE_CENTER_LFE = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) SPEAKER_FULL_RANGE_REAR_L_R = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) SPEAKER_FULL_RANGE_SURROUND_L_R = 0x1d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) SPEAKER_BASS_REDIRECT_SUB_GAIN = 0x1e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * Definitions for the DSP req's to handle speaker tuning. These all belong to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * module ID 0x96, the output effects module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) enum speaker_tuning_reqs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * Currently, this value is always set to 0.0f. However, on Windows,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * when selecting certain headphone profiles on the new Sound Blaster
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * connect software, the QUERY_SPEAKER_EQ_ADDRESS req on mid 0x80 is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * sent. This gets the speaker EQ address area, which is then used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * send over (presumably) an equalizer profile for the specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * headphone setup. It is sent using the same method the DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * firmware is uploaded with, which I believe is why the 'ctspeq.bin'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * file exists in linux firmware tree but goes unused. It would also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * explain why the QUERY_SPEAKER_EQ_ADDRESS req is defined but unused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * Once this profile is sent over, SPEAKER_TUNING_USE_SPEAKER_EQ is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * set to 1.0f.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) SPEAKER_TUNING_USE_SPEAKER_EQ = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) SPEAKER_TUNING_ENABLE_CENTER_EQ = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) SPEAKER_TUNING_FRONT_LEFT_VOL_LEVEL = 0x21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) SPEAKER_TUNING_FRONT_RIGHT_VOL_LEVEL = 0x22,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) SPEAKER_TUNING_CENTER_VOL_LEVEL = 0x23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) SPEAKER_TUNING_LFE_VOL_LEVEL = 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) SPEAKER_TUNING_REAR_LEFT_VOL_LEVEL = 0x25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) SPEAKER_TUNING_REAR_RIGHT_VOL_LEVEL = 0x26,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) SPEAKER_TUNING_SURROUND_LEFT_VOL_LEVEL = 0x27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) SPEAKER_TUNING_SURROUND_RIGHT_VOL_LEVEL = 0x28,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * Inversion is used when setting headphone virtualization to line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * out. Not sure why this is, but it's the only place it's ever used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) SPEAKER_TUNING_FRONT_LEFT_INVERT = 0x29,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) SPEAKER_TUNING_FRONT_RIGHT_INVERT = 0x2a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) SPEAKER_TUNING_CENTER_INVERT = 0x2b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) SPEAKER_TUNING_LFE_INVERT = 0x2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) SPEAKER_TUNING_REAR_LEFT_INVERT = 0x2d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) SPEAKER_TUNING_REAR_RIGHT_INVERT = 0x2e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) SPEAKER_TUNING_SURROUND_LEFT_INVERT = 0x2f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) SPEAKER_TUNING_SURROUND_RIGHT_INVERT = 0x30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /* Delay is used when setting surround speaker distance in Windows. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) SPEAKER_TUNING_FRONT_LEFT_DELAY = 0x31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) SPEAKER_TUNING_FRONT_RIGHT_DELAY = 0x32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) SPEAKER_TUNING_CENTER_DELAY = 0x33,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) SPEAKER_TUNING_LFE_DELAY = 0x34,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) SPEAKER_TUNING_REAR_LEFT_DELAY = 0x35,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) SPEAKER_TUNING_REAR_RIGHT_DELAY = 0x36,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) SPEAKER_TUNING_SURROUND_LEFT_DELAY = 0x37,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) SPEAKER_TUNING_SURROUND_RIGHT_DELAY = 0x38,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* Of these two, only mute seems to ever be used. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) SPEAKER_TUNING_MAIN_VOLUME = 0x39,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) SPEAKER_TUNING_MUTE = 0x3a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /* Surround output channel count configuration structures. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) #define SPEAKER_CHANNEL_CFG_COUNT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) SPEAKER_CHANNELS_2_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) SPEAKER_CHANNELS_2_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) SPEAKER_CHANNELS_4_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) SPEAKER_CHANNELS_4_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) SPEAKER_CHANNELS_5_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct ca0132_alt_speaker_channel_cfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static const struct ca0132_alt_speaker_channel_cfg speaker_channel_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) { .name = "2.0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) .val = FLOAT_ONE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) { .name = "2.1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) .val = FLOAT_TWO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) { .name = "4.0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) .val = FLOAT_FIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) { .name = "4.1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) .val = FLOAT_SIX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) { .name = "5.1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) .val = FLOAT_EIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * DSP volume setting structs. Req 1 is left volume, req 2 is right volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * and I don't know what the third req is, but it's always zero. I assume it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * some sort of update or set command to tell the DSP there's new volume info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) #define DSP_VOL_OUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) #define DSP_VOL_IN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct ct_dsp_volume_ctl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) hda_nid_t vnid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) int mid; /* module ID*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) unsigned int reqs[3]; /* scp req ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static const struct ct_dsp_volume_ctl ca0132_alt_vol_ctls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) { .vnid = VNID_SPK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) .mid = 0x32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) .reqs = {3, 4, 2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) { .vnid = VNID_MIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) .mid = 0x37,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) .reqs = {2, 3, 1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* Values for ca0113_mmio_command_set for selecting output. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) #define AE_CA0113_OUT_SET_COMMANDS 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct ae_ca0113_output_set {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) unsigned int group[AE_CA0113_OUT_SET_COMMANDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) unsigned int target[AE_CA0113_OUT_SET_COMMANDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) unsigned int vals[NUM_OF_OUTPUTS][AE_CA0113_OUT_SET_COMMANDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static const struct ae_ca0113_output_set ae5_ca0113_output_presets = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) .group = { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* Speakers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) .vals = { { 0x00, 0x00, 0x40, 0x00, 0x00, 0x3f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /* Headphones. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) { 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) static const struct ae_ca0113_output_set ae7_ca0113_output_presets = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .group = { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) /* Speakers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) .vals = { { 0x00, 0x00, 0x40, 0x00, 0x00, 0x3f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) /* Headphones. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) { 0x3f, 0x3f, 0x00, 0x00, 0x02, 0x00 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* ae5 ca0113 command sequences to set headphone gain levels. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) #define AE5_HEADPHONE_GAIN_PRESET_MAX_COMMANDS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct ae5_headphone_gain_set {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) unsigned int vals[AE5_HEADPHONE_GAIN_PRESET_MAX_COMMANDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) static const struct ae5_headphone_gain_set ae5_headphone_gain_presets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) { .name = "Low (16-31",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) .vals = { 0xff, 0x2c, 0xf5, 0x32 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) { .name = "Medium (32-149",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) .vals = { 0x38, 0xa8, 0x3e, 0x4c }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) { .name = "High (150-600",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .vals = { 0xff, 0xff, 0xff, 0x7f }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct ae5_filter_set {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static const struct ae5_filter_set ae5_filter_presets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) { .name = "Slow Roll Off",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) .val = 0xa0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) { .name = "Minimum Phase",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) .val = 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) { .name = "Fast Roll Off",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) .val = 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) enum hda_cmd_vendor_io {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) /* for DspIO node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) VENDOR_DSPIO_SCP_WRITE_DATA_LOW = 0x000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) VENDOR_DSPIO_SCP_WRITE_DATA_HIGH = 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) VENDOR_DSPIO_STATUS = 0xF01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) VENDOR_DSPIO_SCP_POST_READ_DATA = 0x702,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) VENDOR_DSPIO_SCP_READ_DATA = 0xF02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) VENDOR_DSPIO_DSP_INIT = 0x703,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) VENDOR_DSPIO_SCP_POST_COUNT_QUERY = 0x704,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) VENDOR_DSPIO_SCP_READ_COUNT = 0xF04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /* for ChipIO node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) VENDOR_CHIPIO_ADDRESS_LOW = 0x000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) VENDOR_CHIPIO_ADDRESS_HIGH = 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) VENDOR_CHIPIO_STREAM_FORMAT = 0x200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) VENDOR_CHIPIO_DATA_LOW = 0x300,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) VENDOR_CHIPIO_DATA_HIGH = 0x400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) VENDOR_CHIPIO_8051_WRITE_DIRECT = 0x500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) VENDOR_CHIPIO_8051_READ_DIRECT = 0xD00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) VENDOR_CHIPIO_GET_PARAMETER = 0xF00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) VENDOR_CHIPIO_STATUS = 0xF01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) VENDOR_CHIPIO_HIC_POST_READ = 0x702,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) VENDOR_CHIPIO_HIC_READ_DATA = 0xF03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) VENDOR_CHIPIO_8051_DATA_WRITE = 0x707,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) VENDOR_CHIPIO_8051_DATA_READ = 0xF07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) VENDOR_CHIPIO_8051_PMEM_READ = 0xF08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) VENDOR_CHIPIO_8051_IRAM_WRITE = 0x709,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) VENDOR_CHIPIO_8051_IRAM_READ = 0xF09,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE = 0x70A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) VENDOR_CHIPIO_CT_EXTENSIONS_GET = 0xF0A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) VENDOR_CHIPIO_PLL_PMU_WRITE = 0x70C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) VENDOR_CHIPIO_PLL_PMU_READ = 0xF0C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) VENDOR_CHIPIO_8051_ADDRESS_LOW = 0x70D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) VENDOR_CHIPIO_8051_ADDRESS_HIGH = 0x70E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) VENDOR_CHIPIO_FLAG_SET = 0x70F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) VENDOR_CHIPIO_FLAGS_GET = 0xF0F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) VENDOR_CHIPIO_PARAM_SET = 0x710,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) VENDOR_CHIPIO_PARAM_GET = 0xF10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) VENDOR_CHIPIO_PORT_ALLOC_CONFIG_SET = 0x711,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) VENDOR_CHIPIO_PORT_ALLOC_SET = 0x712,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) VENDOR_CHIPIO_PORT_ALLOC_GET = 0xF12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) VENDOR_CHIPIO_PORT_FREE_SET = 0x713,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) VENDOR_CHIPIO_PARAM_EX_ID_GET = 0xF17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) VENDOR_CHIPIO_PARAM_EX_ID_SET = 0x717,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) VENDOR_CHIPIO_PARAM_EX_VALUE_GET = 0xF18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) VENDOR_CHIPIO_PARAM_EX_VALUE_SET = 0x718,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) VENDOR_CHIPIO_DMIC_CTL_SET = 0x788,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) VENDOR_CHIPIO_DMIC_CTL_GET = 0xF88,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) VENDOR_CHIPIO_DMIC_PIN_SET = 0x789,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) VENDOR_CHIPIO_DMIC_PIN_GET = 0xF89,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) VENDOR_CHIPIO_DMIC_MCLK_SET = 0x78A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) VENDOR_CHIPIO_DMIC_MCLK_GET = 0xF8A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) VENDOR_CHIPIO_EAPD_SEL_SET = 0x78D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * Control flag IDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) enum control_flag_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) /* Connection manager stream setup is bypassed/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) CONTROL_FLAG_C_MGR = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) /* DSP DMA is bypassed/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) CONTROL_FLAG_DMA = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) /* 8051 'idle' mode is disabled/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) CONTROL_FLAG_IDLE_ENABLE = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /* Tracker for the SPDIF-in path is bypassed/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) CONTROL_FLAG_TRACKER = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) /* DigitalOut to Spdif2Out connection is disabled/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) CONTROL_FLAG_SPDIF2OUT = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) /* Digital Microphone is disabled/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) CONTROL_FLAG_DMIC = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /* ADC_B rate is 48 kHz/96 kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) CONTROL_FLAG_ADC_B_96KHZ = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /* ADC_C rate is 48 kHz/96 kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) CONTROL_FLAG_ADC_C_96KHZ = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) /* DAC rate is 48 kHz/96 kHz (affects all DACs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) CONTROL_FLAG_DAC_96KHZ = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) /* DSP rate is 48 kHz/96 kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) CONTROL_FLAG_DSP_96KHZ = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) /* SRC clock is 98 MHz/196 MHz (196 MHz forces rate to 96 KHz) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) CONTROL_FLAG_SRC_CLOCK_196MHZ = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) /* SRC rate is 48 kHz/96 kHz (48 kHz disabled when clock is 196 MHz) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) CONTROL_FLAG_SRC_RATE_96KHZ = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /* Decode Loop (DSP->SRC->DSP) is disabled/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) CONTROL_FLAG_DECODE_LOOP = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /* De-emphasis filter on DAC-1 disabled/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) CONTROL_FLAG_DAC1_DEEMPHASIS = 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /* De-emphasis filter on DAC-2 disabled/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) CONTROL_FLAG_DAC2_DEEMPHASIS = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) /* De-emphasis filter on DAC-3 disabled/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) CONTROL_FLAG_DAC3_DEEMPHASIS = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /* High-pass filter on ADC_B disabled/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) CONTROL_FLAG_ADC_B_HIGH_PASS = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /* High-pass filter on ADC_C disabled/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) CONTROL_FLAG_ADC_C_HIGH_PASS = 17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) /* Common mode on Port_A disabled/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) CONTROL_FLAG_PORT_A_COMMON_MODE = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) /* Common mode on Port_D disabled/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) CONTROL_FLAG_PORT_D_COMMON_MODE = 19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /* Impedance for ramp generator on Port_A 16 Ohm/10K Ohm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) CONTROL_FLAG_PORT_A_10KOHM_LOAD = 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) /* Impedance for ramp generator on Port_D, 16 Ohm/10K Ohm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) CONTROL_FLAG_PORT_D_10KOHM_LOAD = 21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /* ASI rate is 48kHz/96kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) CONTROL_FLAG_ASI_96KHZ = 22,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /* DAC power settings able to control attached ports no/yes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) CONTROL_FLAG_DACS_CONTROL_PORTS = 23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) /* Clock Stop OK reporting is disabled/enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) CONTROL_FLAG_CONTROL_STOP_OK_ENABLE = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) /* Number of control flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) CONTROL_FLAGS_MAX = (CONTROL_FLAG_CONTROL_STOP_OK_ENABLE+1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * Control parameter IDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) enum control_param_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /* 0: None, 1: Mic1In*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) CONTROL_PARAM_VIP_SOURCE = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /* 0: force HDA, 1: allow DSP if HDA Spdif1Out stream is idle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) CONTROL_PARAM_SPDIF1_SOURCE = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) /* Port A output stage gain setting to use when 16 Ohm output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * impedance is selected*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) CONTROL_PARAM_PORTA_160OHM_GAIN = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) /* Port D output stage gain setting to use when 16 Ohm output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * impedance is selected*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) CONTROL_PARAM_PORTD_160OHM_GAIN = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * This control param name was found in the 8051 memory, and makes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * sense given the fact the AE-5 uses it and has the ASI flag set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) CONTROL_PARAM_ASI = 23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) /* Stream Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) /* Select stream with the given ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) CONTROL_PARAM_STREAM_ID = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) /* Source connection point for the selected stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) CONTROL_PARAM_STREAM_SOURCE_CONN_POINT = 25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) /* Destination connection point for the selected stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) CONTROL_PARAM_STREAM_DEST_CONN_POINT = 26,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* Number of audio channels in the selected stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) CONTROL_PARAM_STREAMS_CHANNELS = 27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) /*Enable control for the selected stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) CONTROL_PARAM_STREAM_CONTROL = 28,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /* Connection Point Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) /* Select connection point with the given ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) CONTROL_PARAM_CONN_POINT_ID = 29,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) /* Connection point sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) CONTROL_PARAM_CONN_POINT_SAMPLE_RATE = 30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) /* Node Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) /* Select HDA node with the given ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) CONTROL_PARAM_NODE_ID = 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * Dsp Io Status codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) enum hda_vendor_status_dspio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /* Success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) VENDOR_STATUS_DSPIO_OK = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) /* Busy, unable to accept new command, the host must retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) VENDOR_STATUS_DSPIO_BUSY = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) /* SCP command queue is full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) VENDOR_STATUS_DSPIO_SCP_COMMAND_QUEUE_FULL = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) /* SCP response queue is empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) VENDOR_STATUS_DSPIO_SCP_RESPONSE_QUEUE_EMPTY = 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) * Chip Io Status codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) enum hda_vendor_status_chipio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /* Success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) VENDOR_STATUS_CHIPIO_OK = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) /* Busy, unable to accept new command, the host must retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) VENDOR_STATUS_CHIPIO_BUSY = 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) * CA0132 sample rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) enum ca0132_sample_rate {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) SR_6_000 = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) SR_8_000 = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) SR_9_600 = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) SR_11_025 = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) SR_16_000 = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) SR_22_050 = 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) SR_24_000 = 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) SR_32_000 = 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) SR_44_100 = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) SR_48_000 = 0x09,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) SR_88_200 = 0x0A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) SR_96_000 = 0x0B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) SR_144_000 = 0x0C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) SR_176_400 = 0x0D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) SR_192_000 = 0x0E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) SR_384_000 = 0x0F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) SR_COUNT = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) SR_RATE_UNKNOWN = 0x1F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) enum dsp_download_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) DSP_DOWNLOAD_FAILED = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) DSP_DOWNLOAD_INIT = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) DSP_DOWNLOADING = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) DSP_DOWNLOADED = 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) /* retrieve parameters from hda format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) #define get_hdafmt_chs(fmt) (fmt & 0xf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) #define get_hdafmt_bits(fmt) ((fmt >> 4) & 0x7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) #define get_hdafmt_rate(fmt) ((fmt >> 8) & 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) #define get_hdafmt_type(fmt) ((fmt >> 15) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * CA0132 specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct ca0132_spec {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) const struct snd_kcontrol_new *mixers[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) unsigned int num_mixers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) const struct hda_verb *base_init_verbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) const struct hda_verb *base_exit_verbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) const struct hda_verb *chip_init_verbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) const struct hda_verb *desktop_init_verbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) struct hda_verb *spec_init_verbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) struct auto_pin_cfg autocfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) /* Nodes configurations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) struct hda_multi_out multiout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) hda_nid_t out_pins[AUTO_CFG_MAX_OUTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) hda_nid_t dacs[AUTO_CFG_MAX_OUTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) unsigned int num_outputs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) hda_nid_t input_pins[AUTO_PIN_LAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) hda_nid_t adcs[AUTO_PIN_LAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) hda_nid_t dig_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) hda_nid_t dig_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) unsigned int num_inputs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) hda_nid_t shared_mic_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) hda_nid_t shared_out_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) hda_nid_t unsol_tag_hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) hda_nid_t unsol_tag_front_hp; /* for desktop ca0132 codecs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) hda_nid_t unsol_tag_amic1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) /* chip access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) struct mutex chipio_mutex; /* chip access mutex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) u32 curr_chip_addx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) /* DSP download related */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) enum dsp_download_state dsp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) unsigned int dsp_stream_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) unsigned int wait_scp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) unsigned int wait_scp_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) unsigned int wait_num_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) unsigned int scp_resp_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) unsigned int scp_resp_data[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) unsigned int scp_resp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) bool startup_check_entered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) bool dsp_reload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) /* mixer and effects related */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) unsigned char dmic_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) int cur_out_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) int cur_mic_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) long vnode_lvol[VNODES_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) long vnode_rvol[VNODES_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) long vnode_lswitch[VNODES_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) long vnode_rswitch[VNODES_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) long effects_switch[EFFECTS_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) long voicefx_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) long cur_mic_boost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /* ca0132_alt control related values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) unsigned char in_enum_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) unsigned char out_enum_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) unsigned char channel_cfg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) unsigned char speaker_range_val[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) unsigned char mic_boost_enum_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) unsigned char smart_volume_setting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) unsigned char bass_redirection_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) long bass_redirect_xover_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) long fx_ctl_val[EFFECT_LEVEL_SLIDERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) long xbass_xover_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) long eq_preset_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) unsigned int tlv[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) struct hda_vmaster_mute_hook vmaster_mute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) /* AE-5 Control values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) unsigned char ae5_headphone_gain_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) unsigned char ae5_filter_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) /* ZxR Control Values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) unsigned char zxr_gain_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) struct hda_codec *codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) struct delayed_work unsol_hp_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) int quirk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) #ifdef ENABLE_TUNING_CONTROLS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) long cur_ctl_vals[TUNING_CTLS_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) * The Recon3D, Sound Blaster Z, Sound Blaster ZxR, and Sound Blaster
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) * AE-5 all use PCI region 2 to toggle GPIO and other currently unknown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) * things.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) bool use_pci_mmio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) void __iomem *mem_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) * Whether or not to use the alt functions like alt_select_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) * alt_select_in, etc. Only used on desktop codecs for now, because of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) * surround sound support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) bool use_alt_functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * Whether or not to use alt controls: volume effect sliders, EQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * presets, smart volume presets, and new control names with FX prefix.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * Renames PlayEnhancement and CrystalVoice too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) bool use_alt_controls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) * CA0132 quirks table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) QUIRK_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) QUIRK_ALIENWARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) QUIRK_ALIENWARE_M17XR4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) QUIRK_SBZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) QUIRK_ZXR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) QUIRK_ZXR_DBPRO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) QUIRK_R3DI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) QUIRK_R3D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) QUIRK_AE5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) QUIRK_AE7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) #define ca0132_quirk(spec) ((spec)->quirk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) #define ca0132_use_pci_mmio(spec) ((spec)->use_pci_mmio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) #define ca0132_use_alt_functions(spec) ((spec)->use_alt_functions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) #define ca0132_use_alt_controls(spec) ((spec)->use_alt_controls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) #define ca0132_quirk(spec) ({ (void)(spec); QUIRK_NONE; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) #define ca0132_use_alt_functions(spec) ({ (void)(spec); false; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) #define ca0132_use_pci_mmio(spec) ({ (void)(spec); false; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) #define ca0132_use_alt_controls(spec) ({ (void)(spec); false; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static const struct hda_pintbl alienware_pincfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) { 0x0b, 0x90170110 }, /* Builtin Speaker */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) { 0x0c, 0x411111f0 }, /* N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) { 0x0d, 0x411111f0 }, /* N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) { 0x0e, 0x411111f0 }, /* N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) { 0x0f, 0x0321101f }, /* HP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) { 0x10, 0x411111f0 }, /* Headset? disabled for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) { 0x11, 0x03a11021 }, /* Mic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) { 0x12, 0xd5a30140 }, /* Builtin Mic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) { 0x13, 0x411111f0 }, /* N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) { 0x18, 0x411111f0 }, /* N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) /* Sound Blaster Z pin configs taken from Windows Driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) static const struct hda_pintbl sbz_pincfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) { 0x0b, 0x01017010 }, /* Port G -- Lineout FRONT L/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) { 0x0d, 0x014510f0 }, /* Digital Out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) { 0x0e, 0x01c510f0 }, /* SPDIF In */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) { 0x0f, 0x0221701f }, /* Port A -- BackPanel HP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) { 0x10, 0x01017012 }, /* Port D -- Center/LFE or FP Hp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) { 0x11, 0x01017014 }, /* Port B -- LineMicIn2 / Rear L/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) { 0x12, 0x01a170f0 }, /* Port C -- LineIn1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) { 0x13, 0x908700f0 }, /* What U Hear In*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) { 0x18, 0x50d000f0 }, /* N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) /* Sound Blaster ZxR pin configs taken from Windows Driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) static const struct hda_pintbl zxr_pincfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) { 0x0b, 0x01047110 }, /* Port G -- Lineout FRONT L/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) { 0x0c, 0x414510f0 }, /* SPDIF Out 1 - Disabled*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) { 0x0d, 0x014510f0 }, /* Digital Out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) { 0x0e, 0x41c520f0 }, /* SPDIF In - Disabled*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) { 0x0f, 0x0122711f }, /* Port A -- BackPanel HP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) { 0x10, 0x01017111 }, /* Port D -- Center/LFE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) { 0x11, 0x01017114 }, /* Port B -- LineMicIn2 / Rear L/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) { 0x12, 0x01a271f0 }, /* Port C -- LineIn1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) { 0x13, 0x908700f0 }, /* What U Hear In*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) { 0x18, 0x50d000f0 }, /* N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) /* Recon3D pin configs taken from Windows Driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) static const struct hda_pintbl r3d_pincfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) { 0x0b, 0x01014110 }, /* Port G -- Lineout FRONT L/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) { 0x0d, 0x014510f0 }, /* Digital Out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) { 0x0e, 0x01c520f0 }, /* SPDIF In */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) { 0x0f, 0x0221401f }, /* Port A -- BackPanel HP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) { 0x10, 0x01016011 }, /* Port D -- Center/LFE or FP Hp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) { 0x11, 0x01011014 }, /* Port B -- LineMicIn2 / Rear L/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) { 0x12, 0x02a090f0 }, /* Port C -- LineIn1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) { 0x13, 0x908700f0 }, /* What U Hear In*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) { 0x18, 0x50d000f0 }, /* N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) /* Sound Blaster AE-5 pin configs taken from Windows Driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static const struct hda_pintbl ae5_pincfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) { 0x0b, 0x01017010 }, /* Port G -- Lineout FRONT L/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) { 0x0d, 0x014510f0 }, /* Digital Out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) { 0x0e, 0x01c510f0 }, /* SPDIF In */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) { 0x0f, 0x01017114 }, /* Port A -- Rear L/R. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) { 0x10, 0x01017012 }, /* Port D -- Center/LFE or FP Hp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) { 0x11, 0x012170ff }, /* Port B -- LineMicIn2 / Rear Headphone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) { 0x12, 0x01a170f0 }, /* Port C -- LineIn1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) { 0x13, 0x908700f0 }, /* What U Hear In*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) { 0x18, 0x50d000f0 }, /* N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) /* Recon3D integrated pin configs taken from Windows Driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) static const struct hda_pintbl r3di_pincfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) { 0x0b, 0x01014110 }, /* Port G -- Lineout FRONT L/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) { 0x0d, 0x014510f0 }, /* Digital Out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) { 0x0e, 0x41c520f0 }, /* SPDIF In */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) { 0x0f, 0x0221401f }, /* Port A -- BackPanel HP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) { 0x10, 0x01016011 }, /* Port D -- Center/LFE or FP Hp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) { 0x11, 0x01011014 }, /* Port B -- LineMicIn2 / Rear L/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) { 0x12, 0x02a090f0 }, /* Port C -- LineIn1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) { 0x13, 0x908700f0 }, /* What U Hear In*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) { 0x18, 0x500000f0 }, /* N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) static const struct hda_pintbl ae7_pincfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) { 0x0b, 0x01017010 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) { 0x0c, 0x014510f0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) { 0x0d, 0x414510f0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) { 0x0e, 0x01c520f0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) { 0x0f, 0x01017114 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) { 0x10, 0x01017011 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) { 0x11, 0x018170ff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) { 0x12, 0x01a170f0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) { 0x13, 0x908700f0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) { 0x18, 0x500000f0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) static const struct snd_pci_quirk ca0132_quirks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) SND_PCI_QUIRK(0x1028, 0x057b, "Alienware M17x R4", QUIRK_ALIENWARE_M17XR4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) SND_PCI_QUIRK(0x1102, 0x0027, "Sound Blaster Z", QUIRK_SBZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) SND_PCI_QUIRK(0x1102, 0x0033, "Sound Blaster ZxR", QUIRK_SBZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) SND_PCI_QUIRK(0x3842, 0x1038, "EVGA X99 Classified", QUIRK_R3DI),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) SND_PCI_QUIRK(0x1102, 0x0191, "Sound Blaster AE-5 Plus", QUIRK_AE5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) SND_PCI_QUIRK(0x1102, 0x0081, "Sound Blaster AE-7", QUIRK_AE7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) /* Output selection quirk info structures. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) #define MAX_QUIRK_MMIO_GPIO_SET_VALS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) #define MAX_QUIRK_SCP_SET_VALS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) struct ca0132_alt_out_set_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) unsigned int dac2port; /* ParamID 0x0d value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) bool has_hda_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) char hda_gpio_pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) char hda_gpio_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) unsigned int mmio_gpio_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) char mmio_gpio_pin[MAX_QUIRK_MMIO_GPIO_SET_VALS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) char mmio_gpio_set[MAX_QUIRK_MMIO_GPIO_SET_VALS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) unsigned int scp_cmds_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) unsigned int scp_cmd_mid[MAX_QUIRK_SCP_SET_VALS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) unsigned int scp_cmd_req[MAX_QUIRK_SCP_SET_VALS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) unsigned int scp_cmd_val[MAX_QUIRK_SCP_SET_VALS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) bool has_chipio_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) unsigned int chipio_write_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) unsigned int chipio_write_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) struct ca0132_alt_out_set_quirk_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) int quirk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) bool has_headphone_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) bool is_ae_series;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) struct ca0132_alt_out_set_info out_set_info[NUM_OF_OUTPUTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) static const struct ca0132_alt_out_set_quirk_data quirk_out_set_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) { .quirk_id = QUIRK_R3DI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) .has_headphone_gain = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) .is_ae_series = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) .out_set_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) /* Speakers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) { .dac2port = 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) .has_hda_gpio = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) .hda_gpio_pin = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) .hda_gpio_set = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) .mmio_gpio_count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) .scp_cmds_count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) .has_chipio_write = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) /* Headphones. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) { .dac2port = 0x21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) .has_hda_gpio = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) .hda_gpio_pin = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) .hda_gpio_set = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) .mmio_gpio_count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) .scp_cmds_count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) .has_chipio_write = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) { .quirk_id = QUIRK_R3D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) .has_headphone_gain = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) .is_ae_series = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) .out_set_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) /* Speakers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) { .dac2port = 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) .has_hda_gpio = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) .mmio_gpio_count = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) .mmio_gpio_pin = { 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) .mmio_gpio_set = { 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) .scp_cmds_count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) .has_chipio_write = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) /* Headphones. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) { .dac2port = 0x21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) .has_hda_gpio = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) .mmio_gpio_count = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) .mmio_gpio_pin = { 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) .mmio_gpio_set = { 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) .scp_cmds_count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) .has_chipio_write = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) { .quirk_id = QUIRK_SBZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) .has_headphone_gain = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) .is_ae_series = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) .out_set_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) /* Speakers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) { .dac2port = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) .has_hda_gpio = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) .mmio_gpio_count = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) .mmio_gpio_pin = { 7, 4, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) .mmio_gpio_set = { 0, 1, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) .scp_cmds_count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) .has_chipio_write = false, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) /* Headphones. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) { .dac2port = 0x12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) .has_hda_gpio = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) .mmio_gpio_count = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) .mmio_gpio_pin = { 7, 4, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) .mmio_gpio_set = { 1, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) .scp_cmds_count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) .has_chipio_write = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) { .quirk_id = QUIRK_ZXR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) .has_headphone_gain = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) .is_ae_series = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) .out_set_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) /* Speakers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) { .dac2port = 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) .has_hda_gpio = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) .mmio_gpio_count = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) .mmio_gpio_pin = { 2, 3, 5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) .mmio_gpio_set = { 1, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) .scp_cmds_count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) .has_chipio_write = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) /* Headphones. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) { .dac2port = 0x21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) .has_hda_gpio = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) .mmio_gpio_count = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) .mmio_gpio_pin = { 2, 3, 5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) .mmio_gpio_set = { 0, 1, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) .scp_cmds_count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) .has_chipio_write = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) { .quirk_id = QUIRK_AE5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) .has_headphone_gain = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) .is_ae_series = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) .out_set_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) /* Speakers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) { .dac2port = 0xa4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) .has_hda_gpio = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) .mmio_gpio_count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) .scp_cmds_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) .scp_cmd_mid = { 0x96, 0x96 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) .scp_cmd_req = { SPEAKER_TUNING_FRONT_LEFT_INVERT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) SPEAKER_TUNING_FRONT_RIGHT_INVERT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) .scp_cmd_val = { FLOAT_ZERO, FLOAT_ZERO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) .has_chipio_write = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) .chipio_write_addr = 0x0018b03c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) .chipio_write_data = 0x00000012
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) /* Headphones. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) { .dac2port = 0xa1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) .has_hda_gpio = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) .mmio_gpio_count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) .scp_cmds_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) .scp_cmd_mid = { 0x96, 0x96 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) .scp_cmd_req = { SPEAKER_TUNING_FRONT_LEFT_INVERT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) SPEAKER_TUNING_FRONT_RIGHT_INVERT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) .scp_cmd_val = { FLOAT_ONE, FLOAT_ONE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) .has_chipio_write = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) .chipio_write_addr = 0x0018b03c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) .chipio_write_data = 0x00000012
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) { .quirk_id = QUIRK_AE7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) .has_headphone_gain = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) .is_ae_series = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) .out_set_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) /* Speakers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) { .dac2port = 0x58,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) .has_hda_gpio = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) .mmio_gpio_count = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) .mmio_gpio_pin = { 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) .mmio_gpio_set = { 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) .scp_cmds_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) .scp_cmd_mid = { 0x96, 0x96 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) .scp_cmd_req = { SPEAKER_TUNING_FRONT_LEFT_INVERT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) SPEAKER_TUNING_FRONT_RIGHT_INVERT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) .scp_cmd_val = { FLOAT_ZERO, FLOAT_ZERO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) .has_chipio_write = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) .chipio_write_addr = 0x0018b03c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) .chipio_write_data = 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) /* Headphones. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) { .dac2port = 0x58,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) .has_hda_gpio = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) .mmio_gpio_count = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) .mmio_gpio_pin = { 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) .mmio_gpio_set = { 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) .scp_cmds_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) .scp_cmd_mid = { 0x96, 0x96 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) .scp_cmd_req = { SPEAKER_TUNING_FRONT_LEFT_INVERT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) SPEAKER_TUNING_FRONT_RIGHT_INVERT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) .scp_cmd_val = { FLOAT_ONE, FLOAT_ONE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) .has_chipio_write = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) .chipio_write_addr = 0x0018b03c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) .chipio_write_data = 0x00000010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) * CA0132 codec access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) static unsigned int codec_send_command(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) unsigned int verb, unsigned int parm, unsigned int *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) unsigned int response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) response = snd_hda_codec_read(codec, nid, 0, verb, parm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) *res = response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) return ((response == -1) ? -1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) static int codec_set_converter_format(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) unsigned short converter_format, unsigned int *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) return codec_send_command(codec, nid, VENDOR_CHIPIO_STREAM_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) converter_format & 0xffff, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) static int codec_set_converter_stream_channel(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) hda_nid_t nid, unsigned char stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) unsigned char channel, unsigned int *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) unsigned char converter_stream_channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) converter_stream_channel = (stream << 4) | (channel & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) return codec_send_command(codec, nid, AC_VERB_SET_CHANNEL_STREAMID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) converter_stream_channel, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) /* Chip access helper function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) static int chipio_send(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) unsigned int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) unsigned long timeout = jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) /* send bits of data specified by reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) res = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (res == VENDOR_STATUS_CHIPIO_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) } while (time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) * Write chip address through the vendor widget -- NOT protected by the Mutex!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) static int chipio_write_address(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) unsigned int chip_addx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) if (spec->curr_chip_addx == chip_addx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) /* send low 16 bits of the address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) res = chipio_send(codec, VENDOR_CHIPIO_ADDRESS_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) chip_addx & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) if (res != -EIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) /* send high 16 bits of the address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) res = chipio_send(codec, VENDOR_CHIPIO_ADDRESS_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) chip_addx >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) spec->curr_chip_addx = (res < 0) ? ~0U : chip_addx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) * Write data through the vendor widget -- NOT protected by the Mutex!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) static int chipio_write_data(struct hda_codec *codec, unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) /* send low 16 bits of the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) res = chipio_send(codec, VENDOR_CHIPIO_DATA_LOW, data & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) if (res != -EIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) /* send high 16 bits of the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) res = chipio_send(codec, VENDOR_CHIPIO_DATA_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) data >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) /*If no error encountered, automatically increment the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) as per chip behaviour*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) spec->curr_chip_addx = (res != -EIO) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) (spec->curr_chip_addx + 4) : ~0U;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) * Write multiple data through the vendor widget -- NOT protected by the Mutex!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) static int chipio_write_data_multiple(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) const u32 *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (data == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) codec_dbg(codec, "chipio_write_data null ptr\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) while ((count-- != 0) && (status == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) status = chipio_write_data(codec, *data++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) * Read data through the vendor widget -- NOT protected by the Mutex!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) static int chipio_read_data(struct hda_codec *codec, unsigned int *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) /* post read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) res = chipio_send(codec, VENDOR_CHIPIO_HIC_POST_READ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (res != -EIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) /* read status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) res = chipio_send(codec, VENDOR_CHIPIO_STATUS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) if (res != -EIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) /* read data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) *data = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) VENDOR_CHIPIO_HIC_READ_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) /*If no error encountered, automatically increment the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) as per chip behaviour*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) spec->curr_chip_addx = (res != -EIO) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) (spec->curr_chip_addx + 4) : ~0U;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) * Write given value to the given address through the chip I/O widget.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) * protected by the Mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) static int chipio_write(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) unsigned int chip_addx, const unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /* write the address, and if successful proceed to write data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) err = chipio_write_address(codec, chip_addx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) err = chipio_write_data(codec, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) * Write given value to the given address through the chip I/O widget.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) * not protected by the Mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) static int chipio_write_no_mutex(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) unsigned int chip_addx, const unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) /* write the address, and if successful proceed to write data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) err = chipio_write_address(codec, chip_addx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) err = chipio_write_data(codec, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) * Write multiple values to the given address through the chip I/O widget.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) * protected by the Mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) static int chipio_write_multiple(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) u32 chip_addx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) const u32 *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) status = chipio_write_address(codec, chip_addx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) status = chipio_write_data_multiple(codec, data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) * Read the given address through the chip I/O widget
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) * protected by the Mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) static int chipio_read(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) unsigned int chip_addx, unsigned int *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) /* write the address, and if successful proceed to write data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) err = chipio_write_address(codec, chip_addx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) err = chipio_read_data(codec, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) * Set chip control flags through the chip I/O widget.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) static void chipio_set_control_flag(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) enum control_flag_id flag_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) bool flag_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) unsigned int flag_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) flag_bit = (flag_state ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) val = (flag_bit << 7) | (flag_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) VENDOR_CHIPIO_FLAG_SET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) * Set chip parameters through the chip I/O widget.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) static void chipio_set_control_param(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) enum control_param_id param_id, int param_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if ((param_id < 32) && (param_val < 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) val = (param_val << 5) | (param_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) VENDOR_CHIPIO_PARAM_SET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) if (chipio_send(codec, VENDOR_CHIPIO_STATUS, 0) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) VENDOR_CHIPIO_PARAM_EX_ID_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) param_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) VENDOR_CHIPIO_PARAM_EX_VALUE_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) param_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) * Set chip parameters through the chip I/O widget. NO MUTEX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) static void chipio_set_control_param_no_mutex(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) enum control_param_id param_id, int param_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) if ((param_id < 32) && (param_val < 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) val = (param_val << 5) | (param_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) VENDOR_CHIPIO_PARAM_SET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) if (chipio_send(codec, VENDOR_CHIPIO_STATUS, 0) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) VENDOR_CHIPIO_PARAM_EX_ID_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) param_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) VENDOR_CHIPIO_PARAM_EX_VALUE_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) param_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) * Connect stream to a source point, and then connect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) * that source point to a destination point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) static void chipio_set_stream_source_dest(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) int streamid, int source_point, int dest_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) chipio_set_control_param_no_mutex(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) CONTROL_PARAM_STREAM_ID, streamid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) chipio_set_control_param_no_mutex(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) CONTROL_PARAM_STREAM_SOURCE_CONN_POINT, source_point);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) chipio_set_control_param_no_mutex(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) CONTROL_PARAM_STREAM_DEST_CONN_POINT, dest_point);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) * Set number of channels in the selected stream.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) static void chipio_set_stream_channels(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) int streamid, unsigned int channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) chipio_set_control_param_no_mutex(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) CONTROL_PARAM_STREAM_ID, streamid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) chipio_set_control_param_no_mutex(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) CONTROL_PARAM_STREAMS_CHANNELS, channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) * Enable/Disable audio stream.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) static void chipio_set_stream_control(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) int streamid, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) chipio_set_control_param_no_mutex(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) CONTROL_PARAM_STREAM_ID, streamid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) chipio_set_control_param_no_mutex(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) CONTROL_PARAM_STREAM_CONTROL, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) * Set sampling rate of the connection point. NO MUTEX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) static void chipio_set_conn_rate_no_mutex(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) int connid, enum ca0132_sample_rate rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) chipio_set_control_param_no_mutex(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) CONTROL_PARAM_CONN_POINT_ID, connid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) chipio_set_control_param_no_mutex(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) CONTROL_PARAM_CONN_POINT_SAMPLE_RATE, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) * Set sampling rate of the connection point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) static void chipio_set_conn_rate(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) int connid, enum ca0132_sample_rate rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) chipio_set_control_param(codec, CONTROL_PARAM_CONN_POINT_ID, connid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) chipio_set_control_param(codec, CONTROL_PARAM_CONN_POINT_SAMPLE_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) * Writes to the 8051's internal address space directly instead of indirectly,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) * giving access to the special function registers located at addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) * 0x80-0xFF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) static void chipio_8051_write_direct(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) unsigned int addr, unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) unsigned int verb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) verb = VENDOR_CHIPIO_8051_WRITE_DIRECT | data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, verb, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) * Enable clocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) static void chipio_enable_clocks(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) VENDOR_CHIPIO_8051_ADDRESS_LOW, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) VENDOR_CHIPIO_PLL_PMU_WRITE, 0x0b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) VENDOR_CHIPIO_8051_ADDRESS_LOW, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) * CA0132 DSP IO stuffs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) static int dspio_send(struct hda_codec *codec, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) unsigned long timeout = jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) /* send bits of data specified by reg to dsp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) res = snd_hda_codec_read(codec, WIDGET_DSP_CTRL, 0, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) if ((res >= 0) && (res != VENDOR_STATUS_DSPIO_BUSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) } while (time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) * Wait for DSP to be ready for commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) static void dspio_write_wait(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) unsigned long timeout = jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) status = snd_hda_codec_read(codec, WIDGET_DSP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) VENDOR_DSPIO_STATUS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) if ((status == VENDOR_STATUS_DSPIO_OK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) (status == VENDOR_STATUS_DSPIO_SCP_RESPONSE_QUEUE_EMPTY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) } while (time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) * Write SCP data to DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) static int dspio_write(struct hda_codec *codec, unsigned int scp_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) dspio_write_wait(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) status = dspio_send(codec, VENDOR_DSPIO_SCP_WRITE_DATA_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) scp_data & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) status = dspio_send(codec, VENDOR_DSPIO_SCP_WRITE_DATA_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) scp_data >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) /* OK, now check if the write itself has executed*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) status = snd_hda_codec_read(codec, WIDGET_DSP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) VENDOR_DSPIO_STATUS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) return (status == VENDOR_STATUS_DSPIO_SCP_COMMAND_QUEUE_FULL) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) -EIO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) * Write multiple SCP data to DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) static int dspio_write_multiple(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) unsigned int *buffer, unsigned int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) if (buffer == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) while (count < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) status = dspio_write(codec, *buffer++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) static int dspio_read(struct hda_codec *codec, unsigned int *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) status = dspio_send(codec, VENDOR_DSPIO_SCP_POST_READ_DATA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) if (status == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) status = dspio_send(codec, VENDOR_DSPIO_STATUS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) if (status == -EIO ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) status == VENDOR_STATUS_DSPIO_SCP_RESPONSE_QUEUE_EMPTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) *data = snd_hda_codec_read(codec, WIDGET_DSP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) VENDOR_DSPIO_SCP_READ_DATA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) static int dspio_read_multiple(struct hda_codec *codec, unsigned int *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) unsigned int *buf_size, unsigned int size_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) unsigned int size = *buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) unsigned int skip_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) unsigned int dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) if (buffer == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) while (count < size && count < size_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) status = dspio_read(codec, buffer++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) skip_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) while (skip_count < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) status = dspio_read(codec, &dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) skip_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) *buf_size = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) * Construct the SCP header using corresponding fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) static inline unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) make_scp_header(unsigned int target_id, unsigned int source_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) unsigned int get_flag, unsigned int req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) unsigned int device_flag, unsigned int resp_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) unsigned int error_flag, unsigned int data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) unsigned int header = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) header = (data_size & 0x1f) << 27;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) header |= (error_flag & 0x01) << 26;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) header |= (resp_flag & 0x01) << 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) header |= (device_flag & 0x01) << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) header |= (req & 0x7f) << 17;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) header |= (get_flag & 0x01) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) header |= (source_id & 0xff) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) header |= target_id & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) return header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) * Extract corresponding fields from SCP header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) extract_scp_header(unsigned int header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) unsigned int *target_id, unsigned int *source_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) unsigned int *get_flag, unsigned int *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) unsigned int *device_flag, unsigned int *resp_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) unsigned int *error_flag, unsigned int *data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) if (data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) *data_size = (header >> 27) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) if (error_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) *error_flag = (header >> 26) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) if (resp_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) *resp_flag = (header >> 25) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) if (device_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) *device_flag = (header >> 24) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) if (req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) *req = (header >> 17) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) if (get_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) *get_flag = (header >> 16) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) if (source_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) *source_id = (header >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) if (target_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) *target_id = header & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) #define SCP_MAX_DATA_WORDS (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) /* Structure to contain any SCP message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) struct scp_msg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) unsigned int hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) unsigned int data[SCP_MAX_DATA_WORDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) static void dspio_clear_response_queue(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) unsigned long timeout = jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) unsigned int dummy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) /* clear all from the response queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) status = dspio_read(codec, &dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) } while (status == 0 && time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) static int dspio_get_response_data(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) unsigned int data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) if (dspio_read(codec, &data) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) if ((data & 0x00ffffff) == spec->wait_scp_header) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) spec->scp_resp_header = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) spec->scp_resp_count = data >> 27;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) count = spec->wait_num_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) dspio_read_multiple(codec, spec->scp_resp_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) &spec->scp_resp_count, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) * Send SCP message to DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) static int dspio_send_scp_message(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) unsigned char *send_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) unsigned int send_buf_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) unsigned char *return_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) unsigned int return_buf_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) unsigned int *bytes_returned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) int status = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) unsigned int scp_send_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) unsigned int total_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) bool waiting_for_resp = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) unsigned int header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) struct scp_msg *ret_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) unsigned int resp_src_id, resp_target_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) unsigned int data_size, src_id, target_id, get_flag, device_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) if (bytes_returned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) *bytes_returned = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) /* get scp header from buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) header = *((unsigned int *)send_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) extract_scp_header(header, &target_id, &src_id, &get_flag, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) &device_flag, NULL, NULL, &data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) scp_send_size = data_size + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) total_size = (scp_send_size * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) if (send_buf_size < total_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) if (get_flag || device_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) if (!return_buf || return_buf_size < 4 || !bytes_returned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) spec->wait_scp_header = *((unsigned int *)send_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) /* swap source id with target id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) resp_target_id = src_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) resp_src_id = target_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) spec->wait_scp_header &= 0xffff0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) spec->wait_scp_header |= (resp_src_id << 8) | (resp_target_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) spec->wait_num_data = return_buf_size/sizeof(unsigned int) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) spec->wait_scp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) waiting_for_resp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) status = dspio_write_multiple(codec, (unsigned int *)send_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) scp_send_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) spec->wait_scp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) if (waiting_for_resp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) unsigned long timeout = jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) memset(return_buf, 0, return_buf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) } while (spec->wait_scp && time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) waiting_for_resp = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) if (!spec->wait_scp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) ret_msg = (struct scp_msg *)return_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) memcpy(&ret_msg->hdr, &spec->scp_resp_header, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) memcpy(&ret_msg->data, spec->scp_resp_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) spec->wait_num_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) *bytes_returned = (spec->scp_resp_count + 1) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) spec->wait_scp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) * Prepare and send the SCP message to DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) * @mod_id: ID of the DSP module to send the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) * @src_id: ID of the source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) * @req: ID of request to send to the DSP module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) * @dir: SET or GET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) * @data: pointer to the data to send with the request, request specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) * @len: length of the data, in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) * @reply: point to the buffer to hold data returned for a reply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) * @reply_len: length of the reply buffer returned from GET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) * Returns zero or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) static int dspio_scp(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) int mod_id, int src_id, int req, int dir, const void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) unsigned int len, void *reply, unsigned int *reply_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) struct scp_msg scp_send, scp_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) unsigned int ret_bytes, send_size, ret_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) unsigned int send_get_flag, reply_resp_flag, reply_error_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) unsigned int reply_data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) memset(&scp_send, 0, sizeof(scp_send));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) memset(&scp_reply, 0, sizeof(scp_reply));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) if ((len != 0 && data == NULL) || (len > SCP_MAX_DATA_WORDS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) if (dir == SCP_GET && reply == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) codec_dbg(codec, "dspio_scp get but has no buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) if (reply != NULL && (reply_len == NULL || (*reply_len == 0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) codec_dbg(codec, "dspio_scp bad resp buf len parms\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) scp_send.hdr = make_scp_header(mod_id, src_id, (dir == SCP_GET), req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 0, 0, 0, len/sizeof(unsigned int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) if (data != NULL && len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) len = min((unsigned int)(sizeof(scp_send.data)), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) memcpy(scp_send.data, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) ret_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) send_size = sizeof(unsigned int) + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) status = dspio_send_scp_message(codec, (unsigned char *)&scp_send,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) send_size, (unsigned char *)&scp_reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) sizeof(scp_reply), &ret_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) codec_dbg(codec, "dspio_scp: send scp msg failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) /* extract send and reply headers members */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) extract_scp_header(scp_send.hdr, NULL, NULL, &send_get_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) NULL, NULL, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) extract_scp_header(scp_reply.hdr, NULL, NULL, NULL, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) &reply_resp_flag, &reply_error_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) &reply_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) if (!send_get_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) if (reply_resp_flag && !reply_error_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) ret_size = (ret_bytes - sizeof(scp_reply.hdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) / sizeof(unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) if (*reply_len < ret_size*sizeof(unsigned int)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) codec_dbg(codec, "reply too long for buf\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) } else if (ret_size != reply_data_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) codec_dbg(codec, "RetLen and HdrLen .NE.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) } else if (!reply) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) codec_dbg(codec, "NULL reply\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) *reply_len = ret_size*sizeof(unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) memcpy(reply, scp_reply.data, *reply_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) codec_dbg(codec, "reply ill-formed or errflag set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) * Set DSP parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) static int dspio_set_param(struct hda_codec *codec, int mod_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) int src_id, int req, const void *data, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) return dspio_scp(codec, mod_id, src_id, req, SCP_SET, data, len, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) static int dspio_set_uint_param(struct hda_codec *codec, int mod_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) int req, const unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) return dspio_set_param(codec, mod_id, 0x20, req, &data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) sizeof(unsigned int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) static int dspio_set_uint_param_no_source(struct hda_codec *codec, int mod_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) int req, const unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) return dspio_set_param(codec, mod_id, 0x00, req, &data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) sizeof(unsigned int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) * Allocate a DSP DMA channel via an SCP message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) static int dspio_alloc_dma_chan(struct hda_codec *codec, unsigned int *dma_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) unsigned int size = sizeof(dma_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) codec_dbg(codec, " dspio_alloc_dma_chan() -- begin\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) status = dspio_scp(codec, MASTERCONTROL, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) MASTERCONTROL_ALLOC_DMA_CHAN, SCP_GET, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) dma_chan, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) codec_dbg(codec, "dspio_alloc_dma_chan: SCP Failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) if ((*dma_chan + 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) codec_dbg(codec, "no free dma channels to allocate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) codec_dbg(codec, "dspio_alloc_dma_chan: chan=%d\n", *dma_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) codec_dbg(codec, " dspio_alloc_dma_chan() -- complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) * Free a DSP DMA via an SCP message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) static int dspio_free_dma_chan(struct hda_codec *codec, unsigned int dma_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) unsigned int dummy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) codec_dbg(codec, " dspio_free_dma_chan() -- begin\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) codec_dbg(codec, "dspio_free_dma_chan: chan=%d\n", dma_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) status = dspio_scp(codec, MASTERCONTROL, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) MASTERCONTROL_ALLOC_DMA_CHAN, SCP_SET, &dma_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) sizeof(dma_chan), NULL, &dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) codec_dbg(codec, "dspio_free_dma_chan: SCP Failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) codec_dbg(codec, " dspio_free_dma_chan() -- complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) * (Re)start the DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) static int dsp_set_run_state(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) unsigned int dbg_ctrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) unsigned int halt_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) err = chipio_read(codec, DSP_DBGCNTL_INST_OFFSET, &dbg_ctrl_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) halt_state = (dbg_ctrl_reg & DSP_DBGCNTL_STATE_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) DSP_DBGCNTL_STATE_LOBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) if (halt_state != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) dbg_ctrl_reg &= ~((halt_state << DSP_DBGCNTL_SS_LOBIT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) DSP_DBGCNTL_SS_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) err = chipio_write(codec, DSP_DBGCNTL_INST_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) dbg_ctrl_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) dbg_ctrl_reg |= (halt_state << DSP_DBGCNTL_EXEC_LOBIT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) DSP_DBGCNTL_EXEC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) err = chipio_write(codec, DSP_DBGCNTL_INST_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) dbg_ctrl_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) * Reset the DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) static int dsp_reset(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) unsigned int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) int retry = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) codec_dbg(codec, "dsp_reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) res = dspio_send(codec, VENDOR_DSPIO_DSP_INIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) retry--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) } while (res == -EIO && retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) if (!retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) codec_dbg(codec, "dsp_reset timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) * Convert chip address to DSP address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) static unsigned int dsp_chip_to_dsp_addx(unsigned int chip_addx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) bool *code, bool *yram)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) *code = *yram = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) if (UC_RANGE(chip_addx, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) *code = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) return UC_OFF(chip_addx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) } else if (X_RANGE_ALL(chip_addx, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) return X_OFF(chip_addx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) } else if (Y_RANGE_ALL(chip_addx, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) *yram = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) return Y_OFF(chip_addx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) return INVALID_CHIP_ADDRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) * Check if the DSP DMA is active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) static bool dsp_is_dma_active(struct hda_codec *codec, unsigned int dma_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) unsigned int dma_chnlstart_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) chipio_read(codec, DSPDMAC_CHNLSTART_INST_OFFSET, &dma_chnlstart_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) return ((dma_chnlstart_reg & (1 <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) (DSPDMAC_CHNLSTART_EN_LOBIT + dma_chan))) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) static int dsp_dma_setup_common(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) unsigned int chip_addx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) unsigned int dma_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) unsigned int port_map_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) bool ovly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) unsigned int chnl_prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) unsigned int dsp_addx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) unsigned int active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) bool code, yram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) codec_dbg(codec, "-- dsp_dma_setup_common() -- Begin ---------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) if (dma_chan >= DSPDMAC_DMA_CFG_CHANNEL_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) codec_dbg(codec, "dma chan num invalid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) if (dsp_is_dma_active(codec, dma_chan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) codec_dbg(codec, "dma already active\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) dsp_addx = dsp_chip_to_dsp_addx(chip_addx, &code, &yram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) if (dsp_addx == INVALID_CHIP_ADDRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) codec_dbg(codec, "invalid chip addr\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) chnl_prop = DSPDMAC_CHNLPROP_AC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) codec_dbg(codec, " dsp_dma_setup_common() start reg pgm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) if (ovly) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) status = chipio_read(codec, DSPDMAC_CHNLPROP_INST_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) &chnl_prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) codec_dbg(codec, "read CHNLPROP Reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) codec_dbg(codec, "dsp_dma_setup_common() Read CHNLPROP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) if (!code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) chnl_prop &= ~(1 << (DSPDMAC_CHNLPROP_MSPCE_LOBIT + dma_chan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) chnl_prop |= (1 << (DSPDMAC_CHNLPROP_MSPCE_LOBIT + dma_chan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) chnl_prop &= ~(1 << (DSPDMAC_CHNLPROP_DCON_LOBIT + dma_chan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) status = chipio_write(codec, DSPDMAC_CHNLPROP_INST_OFFSET, chnl_prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) codec_dbg(codec, "write CHNLPROP Reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) codec_dbg(codec, " dsp_dma_setup_common() Write CHNLPROP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) if (ovly) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) status = chipio_read(codec, DSPDMAC_ACTIVE_INST_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) &active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) codec_dbg(codec, "read ACTIVE Reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) codec_dbg(codec, "dsp_dma_setup_common() Read ACTIVE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) active &= (~(1 << (DSPDMAC_ACTIVE_AAR_LOBIT + dma_chan))) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) DSPDMAC_ACTIVE_AAR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) status = chipio_write(codec, DSPDMAC_ACTIVE_INST_OFFSET, active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) codec_dbg(codec, "write ACTIVE Reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) codec_dbg(codec, " dsp_dma_setup_common() Write ACTIVE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) status = chipio_write(codec, DSPDMAC_AUDCHSEL_INST_OFFSET(dma_chan),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) port_map_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) codec_dbg(codec, "write AUDCHSEL Reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) codec_dbg(codec, " dsp_dma_setup_common() Write AUDCHSEL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) status = chipio_write(codec, DSPDMAC_IRQCNT_INST_OFFSET(dma_chan),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) DSPDMAC_IRQCNT_BICNT_MASK | DSPDMAC_IRQCNT_CICNT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) codec_dbg(codec, "write IRQCNT Reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) codec_dbg(codec, " dsp_dma_setup_common() Write IRQCNT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) codec_dbg(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) "ChipA=0x%x,DspA=0x%x,dmaCh=%u, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) "CHSEL=0x%x,CHPROP=0x%x,Active=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) chip_addx, dsp_addx, dma_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) port_map_mask, chnl_prop, active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) codec_dbg(codec, "-- dsp_dma_setup_common() -- Complete ------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) * Setup the DSP DMA per-transfer-specific registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) static int dsp_dma_setup(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) unsigned int chip_addx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) unsigned int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) unsigned int dma_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) bool code, yram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) unsigned int dsp_addx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) unsigned int addr_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) unsigned int incr_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) unsigned int base_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) unsigned int cur_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) unsigned int dma_cfg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) unsigned int adr_ofs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) unsigned int xfr_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) const unsigned int max_dma_count = 1 << (DSPDMAC_XFRCNT_BCNT_HIBIT -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) DSPDMAC_XFRCNT_BCNT_LOBIT + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) codec_dbg(codec, "-- dsp_dma_setup() -- Begin ---------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) if (count > max_dma_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) codec_dbg(codec, "count too big\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) dsp_addx = dsp_chip_to_dsp_addx(chip_addx, &code, &yram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) if (dsp_addx == INVALID_CHIP_ADDRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) codec_dbg(codec, "invalid chip addr\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) codec_dbg(codec, " dsp_dma_setup() start reg pgm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) addr_field = dsp_addx << DSPDMAC_DMACFG_DBADR_LOBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) incr_field = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) if (!code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) addr_field <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) if (yram)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) addr_field |= (1 << DSPDMAC_DMACFG_DBADR_LOBIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) incr_field = (1 << DSPDMAC_DMACFG_AINCR_LOBIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) dma_cfg = addr_field + incr_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) status = chipio_write(codec, DSPDMAC_DMACFG_INST_OFFSET(dma_chan),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) dma_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) codec_dbg(codec, "write DMACFG Reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) codec_dbg(codec, " dsp_dma_setup() Write DMACFG\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) adr_ofs = (count - 1) << (DSPDMAC_DSPADROFS_BOFS_LOBIT +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) (code ? 0 : 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) status = chipio_write(codec, DSPDMAC_DSPADROFS_INST_OFFSET(dma_chan),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) adr_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) codec_dbg(codec, "write DSPADROFS Reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) codec_dbg(codec, " dsp_dma_setup() Write DSPADROFS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) base_cnt = (count - 1) << DSPDMAC_XFRCNT_BCNT_LOBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) cur_cnt = (count - 1) << DSPDMAC_XFRCNT_CCNT_LOBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) xfr_cnt = base_cnt | cur_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) status = chipio_write(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) DSPDMAC_XFRCNT_INST_OFFSET(dma_chan), xfr_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) codec_dbg(codec, "write XFRCNT Reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) codec_dbg(codec, " dsp_dma_setup() Write XFRCNT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) codec_dbg(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) "ChipA=0x%x, cnt=0x%x, DMACFG=0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) "ADROFS=0x%x, XFRCNT=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) chip_addx, count, dma_cfg, adr_ofs, xfr_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) codec_dbg(codec, "-- dsp_dma_setup() -- Complete ---------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) * Start the DSP DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) static int dsp_dma_start(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) unsigned int dma_chan, bool ovly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) unsigned int reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) codec_dbg(codec, "-- dsp_dma_start() -- Begin ---------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) if (ovly) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) status = chipio_read(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) DSPDMAC_CHNLSTART_INST_OFFSET, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) codec_dbg(codec, "read CHNLSTART reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) codec_dbg(codec, "-- dsp_dma_start() Read CHNLSTART\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) reg &= ~(DSPDMAC_CHNLSTART_EN_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) DSPDMAC_CHNLSTART_DIS_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) status = chipio_write(codec, DSPDMAC_CHNLSTART_INST_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) reg | (1 << (dma_chan + DSPDMAC_CHNLSTART_EN_LOBIT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) codec_dbg(codec, "write CHNLSTART reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) codec_dbg(codec, "-- dsp_dma_start() -- Complete ---------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) * Stop the DSP DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) static int dsp_dma_stop(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) unsigned int dma_chan, bool ovly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) unsigned int reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) codec_dbg(codec, "-- dsp_dma_stop() -- Begin ---------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) if (ovly) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) status = chipio_read(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) DSPDMAC_CHNLSTART_INST_OFFSET, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) codec_dbg(codec, "read CHNLSTART reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) codec_dbg(codec, "-- dsp_dma_stop() Read CHNLSTART\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) reg &= ~(DSPDMAC_CHNLSTART_EN_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) DSPDMAC_CHNLSTART_DIS_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) status = chipio_write(codec, DSPDMAC_CHNLSTART_INST_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) reg | (1 << (dma_chan + DSPDMAC_CHNLSTART_DIS_LOBIT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) codec_dbg(codec, "write CHNLSTART reg fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) codec_dbg(codec, "-- dsp_dma_stop() -- Complete ---------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) * Allocate router ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) * @num_chans: number of channels in the stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) * @ports_per_channel: number of ports per channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) * @start_device: start device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) * @port_map: pointer to the port list to hold the allocated ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) * Returns zero or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) static int dsp_allocate_router_ports(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) unsigned int num_chans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) unsigned int ports_per_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) unsigned int start_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) unsigned int *port_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) status = chipio_send(codec, VENDOR_CHIPIO_STATUS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) val = start_device << 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) val |= (ports_per_channel - 1) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) val |= num_chans - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) VENDOR_CHIPIO_PORT_ALLOC_CONFIG_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) VENDOR_CHIPIO_PORT_ALLOC_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) MEM_CONNID_DSP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) status = chipio_send(codec, VENDOR_CHIPIO_STATUS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) res = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) VENDOR_CHIPIO_PORT_ALLOC_GET, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) *port_map = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) return (res < 0) ? res : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) * Free router ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) static int dsp_free_router_ports(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) status = chipio_send(codec, VENDOR_CHIPIO_STATUS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) VENDOR_CHIPIO_PORT_FREE_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) MEM_CONNID_DSP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) status = chipio_send(codec, VENDOR_CHIPIO_STATUS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) * Allocate DSP ports for the download stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) static int dsp_allocate_ports(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) unsigned int num_chans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) unsigned int rate_multi, unsigned int *port_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) codec_dbg(codec, " dsp_allocate_ports() -- begin\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) if ((rate_multi != 1) && (rate_multi != 2) && (rate_multi != 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) codec_dbg(codec, "bad rate multiple\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) status = dsp_allocate_router_ports(codec, num_chans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) rate_multi, 0, port_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) codec_dbg(codec, " dsp_allocate_ports() -- complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) static int dsp_allocate_ports_format(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) const unsigned short fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) unsigned int *port_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) unsigned int num_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) unsigned int sample_rate_div = ((get_hdafmt_rate(fmt) >> 0) & 3) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) unsigned int sample_rate_mul = ((get_hdafmt_rate(fmt) >> 3) & 3) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) unsigned int rate_multi = sample_rate_mul / sample_rate_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) if ((rate_multi != 1) && (rate_multi != 2) && (rate_multi != 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) codec_dbg(codec, "bad rate multiple\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) num_chans = get_hdafmt_chs(fmt) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) status = dsp_allocate_ports(codec, num_chans, rate_multi, port_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) * free DSP ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) static int dsp_free_ports(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) codec_dbg(codec, " dsp_free_ports() -- begin\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) status = dsp_free_router_ports(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) codec_dbg(codec, "free router ports fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) codec_dbg(codec, " dsp_free_ports() -- complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) * HDA DMA engine stuffs for DSP code download
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) struct dma_engine {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) struct hda_codec *codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) unsigned short m_converter_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) struct snd_dma_buffer *dmab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) unsigned int buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) enum dma_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) DMA_STATE_STOP = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) DMA_STATE_RUN = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) static int dma_convert_to_hda_format(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) unsigned int sample_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) unsigned short channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) unsigned short *hda_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) unsigned int format_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) format_val = snd_hdac_calc_stream_format(sample_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) channels, SNDRV_PCM_FORMAT_S32_LE, 32, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) if (hda_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) *hda_format = (unsigned short)format_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) * Reset DMA for DSP download
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) static int dma_reset(struct dma_engine *dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) struct hda_codec *codec = dma->codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) if (dma->dmab->area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) snd_hda_codec_load_dsp_cleanup(codec, dma->dmab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) status = snd_hda_codec_load_dsp_prepare(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) dma->m_converter_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) dma->buf_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) dma->dmab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) spec->dsp_stream_id = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) static int dma_set_state(struct dma_engine *dma, enum dma_state state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) bool cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) case DMA_STATE_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) cmd = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) case DMA_STATE_RUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) cmd = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) snd_hda_codec_load_dsp_trigger(dma->codec, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) static unsigned int dma_get_buffer_size(struct dma_engine *dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) return dma->dmab->bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) static unsigned char *dma_get_buffer_addr(struct dma_engine *dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) return dma->dmab->area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) static int dma_xfer(struct dma_engine *dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) const unsigned int *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) memcpy(dma->dmab->area, data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) static void dma_get_converter_format(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) struct dma_engine *dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) unsigned short *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) if (format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) *format = dma->m_converter_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) static unsigned int dma_get_stream_id(struct dma_engine *dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) struct ca0132_spec *spec = dma->codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) return spec->dsp_stream_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) struct dsp_image_seg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) u32 magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) u32 chip_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) u32 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) u32 data[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) static const u32 g_magic_value = 0x4c46584d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) static const u32 g_chip_addr_magic_value = 0xFFFFFF01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) static bool is_valid(const struct dsp_image_seg *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) return p->magic == g_magic_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) static bool is_hci_prog_list_seg(const struct dsp_image_seg *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) return g_chip_addr_magic_value == p->chip_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) static bool is_last(const struct dsp_image_seg *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) return p->count == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) static size_t dsp_sizeof(const struct dsp_image_seg *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) return struct_size(p, data, p->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) static const struct dsp_image_seg *get_next_seg_ptr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) const struct dsp_image_seg *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) return (struct dsp_image_seg *)((unsigned char *)(p) + dsp_sizeof(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) * CA0132 chip DSP transfer stuffs. For DSP download.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) #define INVALID_DMA_CHANNEL (~0U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) * Program a list of address/data pairs via the ChipIO widget.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) * The segment data is in the format of successive pairs of words.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) * These are repeated as indicated by the segment's count field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) static int dspxfr_hci_write(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) const struct dsp_image_seg *fls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) const u32 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) if (fls == NULL || fls->chip_addr != g_chip_addr_magic_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) codec_dbg(codec, "hci_write invalid params\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) count = fls->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) data = (u32 *)(fls->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) while (count >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) status = chipio_write(codec, data[0], data[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) codec_dbg(codec, "hci_write chipio failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) count -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) data += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) * Write a block of data into DSP code or data RAM using pre-allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) * DMA engine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) * @fls: pointer to a fast load image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) * @reloc: Relocation address for loading single-segment overlays, or 0 for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) * no relocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) * @dma_engine: pointer to DMA engine to be used for DSP download
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) * @dma_chan: The number of DMA channels used for DSP download
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) * @port_map_mask: port mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) * @ovly: TRUE if overlay format is required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) * Returns zero or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) static int dspxfr_one_seg(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) const struct dsp_image_seg *fls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) unsigned int reloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) struct dma_engine *dma_engine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) unsigned int dma_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) unsigned int port_map_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) bool ovly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) bool comm_dma_setup_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) const unsigned int *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) unsigned int chip_addx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) unsigned int words_to_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) unsigned int buffer_size_words;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) unsigned char *buffer_addx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) unsigned short hda_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) unsigned int sample_rate_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) unsigned int sample_rate_mul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) unsigned int num_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) unsigned int hda_frame_size_words;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) unsigned int remainder_words;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) const u32 *data_remainder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) u32 chip_addx_remainder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) unsigned int run_size_words;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) const struct dsp_image_seg *hci_write = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) bool dma_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) if (fls == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) if (is_hci_prog_list_seg(fls)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) hci_write = fls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) fls = get_next_seg_ptr(fls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) if (hci_write && (!fls || is_last(fls))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) codec_dbg(codec, "hci_write\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) return dspxfr_hci_write(codec, hci_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) if (fls == NULL || dma_engine == NULL || port_map_mask == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) codec_dbg(codec, "Invalid Params\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) data = fls->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) chip_addx = fls->chip_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) words_to_write = fls->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) if (!words_to_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) return hci_write ? dspxfr_hci_write(codec, hci_write) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) if (reloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) chip_addx = (chip_addx & (0xFFFF0000 << 2)) + (reloc << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) if (!UC_RANGE(chip_addx, words_to_write) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) !X_RANGE_ALL(chip_addx, words_to_write) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) !Y_RANGE_ALL(chip_addx, words_to_write)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) codec_dbg(codec, "Invalid chip_addx Params\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) buffer_size_words = (unsigned int)dma_get_buffer_size(dma_engine) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) buffer_addx = dma_get_buffer_addr(dma_engine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) if (buffer_addx == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) codec_dbg(codec, "dma_engine buffer NULL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) dma_get_converter_format(dma_engine, &hda_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) sample_rate_div = ((get_hdafmt_rate(hda_format) >> 0) & 3) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) sample_rate_mul = ((get_hdafmt_rate(hda_format) >> 3) & 3) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) num_chans = get_hdafmt_chs(hda_format) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) hda_frame_size_words = ((sample_rate_div == 0) ? 0 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) (num_chans * sample_rate_mul / sample_rate_div));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) if (hda_frame_size_words == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) codec_dbg(codec, "frmsz zero\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) buffer_size_words = min(buffer_size_words,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) (unsigned int)(UC_RANGE(chip_addx, 1) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 65536 : 32768));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) buffer_size_words -= buffer_size_words % hda_frame_size_words;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) codec_dbg(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) "chpadr=0x%08x frmsz=%u nchan=%u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) "rate_mul=%u div=%u bufsz=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) chip_addx, hda_frame_size_words, num_chans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) sample_rate_mul, sample_rate_div, buffer_size_words);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) if (buffer_size_words < hda_frame_size_words) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) codec_dbg(codec, "dspxfr_one_seg:failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) remainder_words = words_to_write % hda_frame_size_words;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) data_remainder = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) chip_addx_remainder = chip_addx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) data += remainder_words;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) chip_addx += remainder_words*sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) words_to_write -= remainder_words;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) while (words_to_write != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) run_size_words = min(buffer_size_words, words_to_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) codec_dbg(codec, "dspxfr (seg loop)cnt=%u rs=%u remainder=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) words_to_write, run_size_words, remainder_words);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) dma_xfer(dma_engine, data, run_size_words*sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) if (!comm_dma_setup_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) status = dsp_dma_stop(codec, dma_chan, ovly);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) status = dsp_dma_setup_common(codec, chip_addx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) dma_chan, port_map_mask, ovly);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) comm_dma_setup_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) status = dsp_dma_setup(codec, chip_addx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) run_size_words, dma_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) status = dsp_dma_start(codec, dma_chan, ovly);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) if (!dsp_is_dma_active(codec, dma_chan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) codec_dbg(codec, "dspxfr:DMA did not start\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) status = dma_set_state(dma_engine, DMA_STATE_RUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) if (remainder_words != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) status = chipio_write_multiple(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) chip_addx_remainder,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) data_remainder,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) remainder_words);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) remainder_words = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) if (hci_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) status = dspxfr_hci_write(codec, hci_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) hci_write = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) timeout = jiffies + msecs_to_jiffies(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) dma_active = dsp_is_dma_active(codec, dma_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) if (!dma_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) } while (time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) if (dma_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) codec_dbg(codec, "+++++ DMA complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) dma_set_state(dma_engine, DMA_STATE_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) status = dma_reset(dma_engine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) data += run_size_words;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) chip_addx += run_size_words*sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) words_to_write -= run_size_words;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) if (remainder_words != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) status = chipio_write_multiple(codec, chip_addx_remainder,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) data_remainder, remainder_words);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) * Write the entire DSP image of a DSP code/data overlay to DSP memories
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) * @fls_data: pointer to a fast load image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) * @reloc: Relocation address for loading single-segment overlays, or 0 for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) * no relocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) * @sample_rate: sampling rate of the stream used for DSP download
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) * @channels: channels of the stream used for DSP download
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) * @ovly: TRUE if overlay format is required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) * Returns zero or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) static int dspxfr_image(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) const struct dsp_image_seg *fls_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) unsigned int reloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) unsigned int sample_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) unsigned short channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) bool ovly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) unsigned short hda_format = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) unsigned int response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) unsigned char stream_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) struct dma_engine *dma_engine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) unsigned int dma_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) unsigned int port_map_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) if (fls_data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) dma_engine = kzalloc(sizeof(*dma_engine), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) if (!dma_engine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) dma_engine->dmab = kzalloc(sizeof(*dma_engine->dmab), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) if (!dma_engine->dmab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) kfree(dma_engine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) dma_engine->codec = codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) dma_convert_to_hda_format(codec, sample_rate, channels, &hda_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) dma_engine->m_converter_format = hda_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) dma_engine->buf_size = (ovly ? DSP_DMA_WRITE_BUFLEN_OVLY :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) DSP_DMA_WRITE_BUFLEN_INIT) * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) dma_chan = ovly ? INVALID_DMA_CHANNEL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) status = codec_set_converter_format(codec, WIDGET_CHIP_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) hda_format, &response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) codec_dbg(codec, "set converter format fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) status = snd_hda_codec_load_dsp_prepare(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) dma_engine->m_converter_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) dma_engine->buf_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) dma_engine->dmab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) spec->dsp_stream_id = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) if (ovly) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) status = dspio_alloc_dma_chan(codec, &dma_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) codec_dbg(codec, "alloc dmachan fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) dma_chan = INVALID_DMA_CHANNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) port_map_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) status = dsp_allocate_ports_format(codec, hda_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) &port_map_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) codec_dbg(codec, "alloc ports fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) stream_id = dma_get_stream_id(dma_engine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) status = codec_set_converter_stream_channel(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) WIDGET_CHIP_CTRL, stream_id, 0, &response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) codec_dbg(codec, "set stream chan fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) while ((fls_data != NULL) && !is_last(fls_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) if (!is_valid(fls_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) codec_dbg(codec, "FLS check fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) status = dspxfr_one_seg(codec, fls_data, reloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) dma_engine, dma_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) port_map_mask, ovly);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) if (is_hci_prog_list_seg(fls_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) fls_data = get_next_seg_ptr(fls_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) if ((fls_data != NULL) && !is_last(fls_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) fls_data = get_next_seg_ptr(fls_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) if (port_map_mask != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) status = dsp_free_ports(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) status = codec_set_converter_stream_channel(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) WIDGET_CHIP_CTRL, 0, 0, &response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) if (ovly && (dma_chan != INVALID_DMA_CHANNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) dspio_free_dma_chan(codec, dma_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) if (dma_engine->dmab->area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) snd_hda_codec_load_dsp_cleanup(codec, dma_engine->dmab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) kfree(dma_engine->dmab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) kfree(dma_engine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) * CA0132 DSP download stuffs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) static void dspload_post_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) codec_dbg(codec, "---- dspload_post_setup ------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) if (!ca0132_use_alt_functions(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) /*set DSP speaker to 2.0 configuration*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x18), 0x08080080);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x19), 0x3f800000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) /*update write pointer*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x29), 0x00000002);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) * dspload_image - Download DSP from a DSP Image Fast Load structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) * @fls: pointer to a fast load image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) * @ovly: TRUE if overlay format is required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) * @reloc: Relocation address for loading single-segment overlays, or 0 for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) * no relocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) * @autostart: TRUE if DSP starts after loading; ignored if ovly is TRUE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) * @router_chans: number of audio router channels to be allocated (0 means use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) * internal defaults; max is 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) * Download DSP from a DSP Image Fast Load structure. This structure is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) * linear, non-constant sized element array of structures, each of which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) * contain the count of the data to be loaded, the data itself, and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) * corresponding starting chip address of the starting data location.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) * Returns zero or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) static int dspload_image(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) const struct dsp_image_seg *fls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) bool ovly,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) unsigned int reloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) bool autostart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) int router_chans)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) unsigned int sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) unsigned short channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) codec_dbg(codec, "---- dspload_image begin ------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) if (router_chans == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) if (!ovly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) router_chans = DMA_TRANSFER_FRAME_SIZE_NWORDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) router_chans = DMA_OVERLAY_FRAME_SIZE_NWORDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) sample_rate = 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) channels = (unsigned short)router_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) while (channels > 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) sample_rate *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) channels /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) codec_dbg(codec, "Ready to program DMA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) if (!ovly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) status = dsp_reset(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) codec_dbg(codec, "dsp_reset() complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) status = dspxfr_image(codec, fls, reloc, sample_rate, channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) ovly);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) codec_dbg(codec, "dspxfr_image() complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) if (autostart && !ovly) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) dspload_post_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) status = dsp_set_run_state(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) codec_dbg(codec, "LOAD FINISHED\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) } while (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) #ifdef CONFIG_SND_HDA_CODEC_CA0132_DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) static bool dspload_is_loaded(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) unsigned int data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) status = chipio_read(codec, 0x40004, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) if ((status < 0) || (data != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) #define dspload_is_loaded(codec) false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) static bool dspload_wait_loaded(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) unsigned long timeout = jiffies + msecs_to_jiffies(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) if (dspload_is_loaded(codec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) codec_info(codec, "ca0132 DSP downloaded and running\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) } while (time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) codec_err(codec, "ca0132 failed to download DSP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) * ca0113 related functions. The ca0113 acts as the HDA bus for the pci-e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) * based cards, and has a second mmio region, region2, that's used for special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) * commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) * For cards with PCI-E region2 (Sound Blaster Z/ZxR, Recon3D, and AE-5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) * the mmio address 0x320 is used to set GPIO pins. The format for the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) * The first eight bits are just the number of the pin. So far, I've only seen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) * this number go to 7.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) * AE-5 note: The AE-5 seems to use pins 2 and 3 to somehow set the color value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) * of the on-card LED. It seems to use pin 2 for data, then toggles 3 to on and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) * then off to send that bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) static void ca0113_mmio_gpio_set(struct hda_codec *codec, unsigned int gpio_pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) unsigned short gpio_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) gpio_data = gpio_pin & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) gpio_data |= ((enable << 8) & 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) writew(gpio_data, spec->mem_base + 0x320);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) * Special pci region2 commands that are only used by the AE-5. They follow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) * a set format, and require reads at certain points to seemingly 'clear'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) * the response data. My first tests didn't do these reads, and would cause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) * the card to get locked up until the memory was read. These commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) * seem to work with three distinct values that I've taken to calling group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) * target-id, and value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) static void ca0113_mmio_command_set(struct hda_codec *codec, unsigned int group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) unsigned int target, unsigned int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) unsigned int write_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) writel(0x0000007e, spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) readl(spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) writel(0x0000005a, spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) readl(spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) readl(spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) writel(0x00800005, spec->mem_base + 0x20c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) writel(group, spec->mem_base + 0x804);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) writel(0x00800005, spec->mem_base + 0x20c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) write_val = (target & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) write_val |= (value << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) writel(write_val, spec->mem_base + 0x204);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) * Need delay here or else it goes too fast and works inconsistently.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) readl(spec->mem_base + 0x860);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) readl(spec->mem_base + 0x854);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) readl(spec->mem_base + 0x840);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) writel(0x00800004, spec->mem_base + 0x20c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) writel(0x00000000, spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) readl(spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) readl(spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) * This second type of command is used for setting the sound filter type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) static void ca0113_mmio_command_set_type2(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) unsigned int group, unsigned int target, unsigned int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) unsigned int write_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) writel(0x0000007e, spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) readl(spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) writel(0x0000005a, spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) readl(spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) readl(spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) writel(0x00800003, spec->mem_base + 0x20c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) writel(group, spec->mem_base + 0x804);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) writel(0x00800005, spec->mem_base + 0x20c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) write_val = (target & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) write_val |= (value << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) writel(write_val, spec->mem_base + 0x204);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) readl(spec->mem_base + 0x860);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) readl(spec->mem_base + 0x854);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) readl(spec->mem_base + 0x840);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) writel(0x00800004, spec->mem_base + 0x20c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) writel(0x00000000, spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) readl(spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) readl(spec->mem_base + 0x210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) * Setup GPIO for the other variants of Core3D.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) * Sets up the GPIO pins so that they are discoverable. If this isn't done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) * the card shows as having no GPIO pins.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) static void ca0132_gpio_init(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) snd_hda_codec_write(codec, 0x01, 0, 0x790, 0x23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x5B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) /* Sets the GPIO for audio output. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) static void ca0132_gpio_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) snd_hda_codec_write(codec, 0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) AC_VERB_SET_GPIO_DIRECTION, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) snd_hda_codec_write(codec, 0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) AC_VERB_SET_GPIO_MASK, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) snd_hda_codec_write(codec, 0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) AC_VERB_SET_GPIO_DATA, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) snd_hda_codec_write(codec, 0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) AC_VERB_SET_GPIO_DATA, 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) snd_hda_codec_write(codec, 0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) AC_VERB_SET_GPIO_DIRECTION, 0x1E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) snd_hda_codec_write(codec, 0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) AC_VERB_SET_GPIO_MASK, 0x1F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) snd_hda_codec_write(codec, 0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) AC_VERB_SET_GPIO_DATA, 0x0C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) * GPIO control functions for the Recon3D integrated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) enum r3di_gpio_bit {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) /* Bit 1 - Switch between front/rear mic. 0 = rear, 1 = front */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) R3DI_MIC_SELECT_BIT = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) /* Bit 2 - Switch between headphone/line out. 0 = Headphone, 1 = Line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) R3DI_OUT_SELECT_BIT = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) * I dunno what this actually does, but it stays on until the dsp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) * is downloaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) R3DI_GPIO_DSP_DOWNLOADING = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) * Same as above, no clue what it does, but it comes on after the dsp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) * is downloaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) R3DI_GPIO_DSP_DOWNLOADED = 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) enum r3di_mic_select {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) /* Set GPIO bit 1 to 0 for rear mic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) R3DI_REAR_MIC = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) /* Set GPIO bit 1 to 1 for front microphone*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) R3DI_FRONT_MIC = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) enum r3di_out_select {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) /* Set GPIO bit 2 to 0 for headphone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) R3DI_HEADPHONE_OUT = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) /* Set GPIO bit 2 to 1 for speaker */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) R3DI_LINE_OUT = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) enum r3di_dsp_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) /* Set GPIO bit 3 to 1 until DSP is downloaded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) R3DI_DSP_DOWNLOADING = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) /* Set GPIO bit 4 to 1 once DSP is downloaded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) R3DI_DSP_DOWNLOADED = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) static void r3di_gpio_mic_set(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) enum r3di_mic_select cur_mic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) unsigned int cur_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) /* Get the current GPIO Data setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) switch (cur_mic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) case R3DI_REAR_MIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) cur_gpio &= ~(1 << R3DI_MIC_SELECT_BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) case R3DI_FRONT_MIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) cur_gpio |= (1 << R3DI_MIC_SELECT_BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) snd_hda_codec_write(codec, codec->core.afg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) AC_VERB_SET_GPIO_DATA, cur_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) static void r3di_gpio_dsp_status_set(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) enum r3di_dsp_status dsp_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) unsigned int cur_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) /* Get the current GPIO Data setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) switch (dsp_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) case R3DI_DSP_DOWNLOADING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) cur_gpio |= (1 << R3DI_GPIO_DSP_DOWNLOADING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) snd_hda_codec_write(codec, codec->core.afg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) AC_VERB_SET_GPIO_DATA, cur_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) case R3DI_DSP_DOWNLOADED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) /* Set DOWNLOADING bit to 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) cur_gpio &= ~(1 << R3DI_GPIO_DSP_DOWNLOADING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) snd_hda_codec_write(codec, codec->core.afg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) AC_VERB_SET_GPIO_DATA, cur_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) cur_gpio |= (1 << R3DI_GPIO_DSP_DOWNLOADED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) snd_hda_codec_write(codec, codec->core.afg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) AC_VERB_SET_GPIO_DATA, cur_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) * PCM callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) unsigned int stream_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) unsigned int format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) snd_hda_codec_setup_stream(codec, spec->dacs[0], stream_tag, 0, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) if (spec->dsp_state == DSP_DOWNLOADING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) /*If Playback effects are on, allow stream some time to flush
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) *effects tail*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) snd_hda_codec_cleanup_stream(codec, spec->dacs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) static unsigned int ca0132_playback_pcm_delay(struct hda_pcm_stream *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) unsigned int latency = DSP_PLAYBACK_INIT_LATENCY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) if (spec->dsp_state != DSP_DOWNLOADED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) /* Add latency if playback enhancement and either effect is enabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) if ((spec->effects_switch[SURROUND - EFFECT_START_NID]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) (spec->effects_switch[DIALOG_PLUS - EFFECT_START_NID]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) latency += DSP_PLAY_ENHANCEMENT_LATENCY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) /* Applying Speaker EQ adds latency as well. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) if (spec->cur_out_type == SPEAKER_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) latency += DSP_SPEAKER_OUT_LATENCY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) return (latency * runtime->rate) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) * Digital out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) static int ca0132_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) return snd_hda_multi_out_dig_open(codec, &spec->multiout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) unsigned int stream_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) unsigned int format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) stream_tag, format, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) static int ca0132_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) return snd_hda_multi_out_dig_close(codec, &spec->multiout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) * Analog capture
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) unsigned int stream_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) unsigned int format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) snd_hda_codec_setup_stream(codec, hinfo->nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) stream_tag, 0, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) if (spec->dsp_state == DSP_DOWNLOADING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) snd_hda_codec_cleanup_stream(codec, hinfo->nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) static unsigned int ca0132_capture_pcm_delay(struct hda_pcm_stream *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) unsigned int latency = DSP_CAPTURE_INIT_LATENCY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) if (spec->dsp_state != DSP_DOWNLOADED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) if (spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) latency += DSP_CRYSTAL_VOICE_LATENCY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) return (latency * runtime->rate) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) * Controls stuffs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) * Mixer controls helpers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) #define CA0132_CODEC_VOL_MONO(xname, nid, channel, dir) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) .subdevice = HDA_SUBDEV_AMP_FLAG, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) .info = ca0132_volume_info, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) .get = ca0132_volume_get, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) .put = ca0132_volume_put, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) .tlv = { .c = ca0132_volume_tlv }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, 0, dir) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) * Creates a mixer control that uses defaults of HDA_CODEC_VOL except for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) * volume put, which is used for setting the DSP volume. This was done because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) * the ca0132 functions were taking too much time and causing lag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) #define CA0132_ALT_CODEC_VOL_MONO(xname, nid, channel, dir) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) .subdevice = HDA_SUBDEV_AMP_FLAG, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) .info = snd_hda_mixer_amp_volume_info, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) .get = snd_hda_mixer_amp_volume_get, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) .put = ca0132_alt_volume_put, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) .tlv = { .c = snd_hda_mixer_amp_tlv }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, 0, dir) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) #define CA0132_CODEC_MUTE_MONO(xname, nid, channel, dir) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) .subdevice = HDA_SUBDEV_AMP_FLAG, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) .info = snd_hda_mixer_amp_switch_info, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) .get = ca0132_switch_get, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) .put = ca0132_switch_put, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, 0, dir) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) /* stereo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) #define CA0132_CODEC_VOL(xname, nid, dir) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) CA0132_CODEC_VOL_MONO(xname, nid, 3, dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) #define CA0132_ALT_CODEC_VOL(xname, nid, dir) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) CA0132_ALT_CODEC_VOL_MONO(xname, nid, 3, dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) #define CA0132_CODEC_MUTE(xname, nid, dir) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) CA0132_CODEC_MUTE_MONO(xname, nid, 3, dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) /* lookup tables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) * Lookup table with decibel values for the DSP. When volume is changed in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) * Windows, the DSP is also sent the dB value in floating point. In Windows,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) * these values have decimal points, probably because the Windows driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) * actually uses floating point. We can't here, so I made a lookup table of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) * values -90 to 9. -90 is the lowest decibel value for both the ADC's and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) * DAC's, and 9 is the maximum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) static const unsigned int float_vol_db_lookup[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 0xC2B40000, 0xC2B20000, 0xC2B00000, 0xC2AE0000, 0xC2AC0000, 0xC2AA0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 0xC2A80000, 0xC2A60000, 0xC2A40000, 0xC2A20000, 0xC2A00000, 0xC29E0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 0xC29C0000, 0xC29A0000, 0xC2980000, 0xC2960000, 0xC2940000, 0xC2920000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 0xC2900000, 0xC28E0000, 0xC28C0000, 0xC28A0000, 0xC2880000, 0xC2860000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 0xC2840000, 0xC2820000, 0xC2800000, 0xC27C0000, 0xC2780000, 0xC2740000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 0xC2700000, 0xC26C0000, 0xC2680000, 0xC2640000, 0xC2600000, 0xC25C0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 0xC2580000, 0xC2540000, 0xC2500000, 0xC24C0000, 0xC2480000, 0xC2440000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 0xC2400000, 0xC23C0000, 0xC2380000, 0xC2340000, 0xC2300000, 0xC22C0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 0xC2280000, 0xC2240000, 0xC2200000, 0xC21C0000, 0xC2180000, 0xC2140000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 0xC2100000, 0xC20C0000, 0xC2080000, 0xC2040000, 0xC2000000, 0xC1F80000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 0xC1F00000, 0xC1E80000, 0xC1E00000, 0xC1D80000, 0xC1D00000, 0xC1C80000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 0xC1C00000, 0xC1B80000, 0xC1B00000, 0xC1A80000, 0xC1A00000, 0xC1980000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 0xC1900000, 0xC1880000, 0xC1800000, 0xC1700000, 0xC1600000, 0xC1500000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 0xC1400000, 0xC1300000, 0xC1200000, 0xC1100000, 0xC1000000, 0xC0E00000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 0xC0C00000, 0xC0A00000, 0xC0800000, 0xC0400000, 0xC0000000, 0xBF800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 0x00000000, 0x3F800000, 0x40000000, 0x40400000, 0x40800000, 0x40A00000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 0x40C00000, 0x40E00000, 0x41000000, 0x41100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) * This table counts from float 0 to 1 in increments of .01, which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) * useful for a few different sliders.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) static const unsigned int float_zero_to_one_lookup[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 0x00000000, 0x3C23D70A, 0x3CA3D70A, 0x3CF5C28F, 0x3D23D70A, 0x3D4CCCCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 0x3D75C28F, 0x3D8F5C29, 0x3DA3D70A, 0x3DB851EC, 0x3DCCCCCD, 0x3DE147AE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 0x3DF5C28F, 0x3E051EB8, 0x3E0F5C29, 0x3E19999A, 0x3E23D70A, 0x3E2E147B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 0x3E3851EC, 0x3E428F5C, 0x3E4CCCCD, 0x3E570A3D, 0x3E6147AE, 0x3E6B851F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) 0x3E75C28F, 0x3E800000, 0x3E851EB8, 0x3E8A3D71, 0x3E8F5C29, 0x3E947AE1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 0x3E99999A, 0x3E9EB852, 0x3EA3D70A, 0x3EA8F5C3, 0x3EAE147B, 0x3EB33333,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) 0x3EB851EC, 0x3EBD70A4, 0x3EC28F5C, 0x3EC7AE14, 0x3ECCCCCD, 0x3ED1EB85,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 0x3ED70A3D, 0x3EDC28F6, 0x3EE147AE, 0x3EE66666, 0x3EEB851F, 0x3EF0A3D7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 0x3EF5C28F, 0x3EFAE148, 0x3F000000, 0x3F028F5C, 0x3F051EB8, 0x3F07AE14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) 0x3F0A3D71, 0x3F0CCCCD, 0x3F0F5C29, 0x3F11EB85, 0x3F147AE1, 0x3F170A3D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 0x3F19999A, 0x3F1C28F6, 0x3F1EB852, 0x3F2147AE, 0x3F23D70A, 0x3F266666,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 0x3F28F5C3, 0x3F2B851F, 0x3F2E147B, 0x3F30A3D7, 0x3F333333, 0x3F35C28F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 0x3F3851EC, 0x3F3AE148, 0x3F3D70A4, 0x3F400000, 0x3F428F5C, 0x3F451EB8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 0x3F47AE14, 0x3F4A3D71, 0x3F4CCCCD, 0x3F4F5C29, 0x3F51EB85, 0x3F547AE1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 0x3F570A3D, 0x3F59999A, 0x3F5C28F6, 0x3F5EB852, 0x3F6147AE, 0x3F63D70A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 0x3F666666, 0x3F68F5C3, 0x3F6B851F, 0x3F6E147B, 0x3F70A3D7, 0x3F733333,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 0x3F75C28F, 0x3F7851EC, 0x3F7AE148, 0x3F7D70A4, 0x3F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) * This table counts from float 10 to 1000, which is the range of the x-bass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) * crossover slider in Windows.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) static const unsigned int float_xbass_xover_lookup[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 0x41200000, 0x41A00000, 0x41F00000, 0x42200000, 0x42480000, 0x42700000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 0x428C0000, 0x42A00000, 0x42B40000, 0x42C80000, 0x42DC0000, 0x42F00000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 0x43020000, 0x430C0000, 0x43160000, 0x43200000, 0x432A0000, 0x43340000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 0x433E0000, 0x43480000, 0x43520000, 0x435C0000, 0x43660000, 0x43700000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 0x437A0000, 0x43820000, 0x43870000, 0x438C0000, 0x43910000, 0x43960000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 0x439B0000, 0x43A00000, 0x43A50000, 0x43AA0000, 0x43AF0000, 0x43B40000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 0x43B90000, 0x43BE0000, 0x43C30000, 0x43C80000, 0x43CD0000, 0x43D20000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 0x43D70000, 0x43DC0000, 0x43E10000, 0x43E60000, 0x43EB0000, 0x43F00000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 0x43F50000, 0x43FA0000, 0x43FF0000, 0x44020000, 0x44048000, 0x44070000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 0x44098000, 0x440C0000, 0x440E8000, 0x44110000, 0x44138000, 0x44160000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 0x44188000, 0x441B0000, 0x441D8000, 0x44200000, 0x44228000, 0x44250000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 0x44278000, 0x442A0000, 0x442C8000, 0x442F0000, 0x44318000, 0x44340000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 0x44368000, 0x44390000, 0x443B8000, 0x443E0000, 0x44408000, 0x44430000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 0x44458000, 0x44480000, 0x444A8000, 0x444D0000, 0x444F8000, 0x44520000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 0x44548000, 0x44570000, 0x44598000, 0x445C0000, 0x445E8000, 0x44610000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 0x44638000, 0x44660000, 0x44688000, 0x446B0000, 0x446D8000, 0x44700000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 0x44728000, 0x44750000, 0x44778000, 0x447A0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) /* The following are for tuning of products */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) #ifdef ENABLE_TUNING_CONTROLS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) static const unsigned int voice_focus_vals_lookup[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 0x41A00000, 0x41A80000, 0x41B00000, 0x41B80000, 0x41C00000, 0x41C80000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 0x41D00000, 0x41D80000, 0x41E00000, 0x41E80000, 0x41F00000, 0x41F80000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 0x42000000, 0x42040000, 0x42080000, 0x420C0000, 0x42100000, 0x42140000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) 0x42180000, 0x421C0000, 0x42200000, 0x42240000, 0x42280000, 0x422C0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 0x42300000, 0x42340000, 0x42380000, 0x423C0000, 0x42400000, 0x42440000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) 0x42480000, 0x424C0000, 0x42500000, 0x42540000, 0x42580000, 0x425C0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) 0x42600000, 0x42640000, 0x42680000, 0x426C0000, 0x42700000, 0x42740000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) 0x42780000, 0x427C0000, 0x42800000, 0x42820000, 0x42840000, 0x42860000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 0x42880000, 0x428A0000, 0x428C0000, 0x428E0000, 0x42900000, 0x42920000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) 0x42940000, 0x42960000, 0x42980000, 0x429A0000, 0x429C0000, 0x429E0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) 0x42A00000, 0x42A20000, 0x42A40000, 0x42A60000, 0x42A80000, 0x42AA0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 0x42AC0000, 0x42AE0000, 0x42B00000, 0x42B20000, 0x42B40000, 0x42B60000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) 0x42B80000, 0x42BA0000, 0x42BC0000, 0x42BE0000, 0x42C00000, 0x42C20000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 0x42C40000, 0x42C60000, 0x42C80000, 0x42CA0000, 0x42CC0000, 0x42CE0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 0x42D00000, 0x42D20000, 0x42D40000, 0x42D60000, 0x42D80000, 0x42DA0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 0x42DC0000, 0x42DE0000, 0x42E00000, 0x42E20000, 0x42E40000, 0x42E60000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 0x42E80000, 0x42EA0000, 0x42EC0000, 0x42EE0000, 0x42F00000, 0x42F20000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 0x42F40000, 0x42F60000, 0x42F80000, 0x42FA0000, 0x42FC0000, 0x42FE0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 0x43000000, 0x43010000, 0x43020000, 0x43030000, 0x43040000, 0x43050000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 0x43060000, 0x43070000, 0x43080000, 0x43090000, 0x430A0000, 0x430B0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 0x430C0000, 0x430D0000, 0x430E0000, 0x430F0000, 0x43100000, 0x43110000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 0x43120000, 0x43130000, 0x43140000, 0x43150000, 0x43160000, 0x43170000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 0x43180000, 0x43190000, 0x431A0000, 0x431B0000, 0x431C0000, 0x431D0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 0x431E0000, 0x431F0000, 0x43200000, 0x43210000, 0x43220000, 0x43230000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 0x43240000, 0x43250000, 0x43260000, 0x43270000, 0x43280000, 0x43290000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 0x432A0000, 0x432B0000, 0x432C0000, 0x432D0000, 0x432E0000, 0x432F0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 0x43300000, 0x43310000, 0x43320000, 0x43330000, 0x43340000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) static const unsigned int mic_svm_vals_lookup[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 0x00000000, 0x3C23D70A, 0x3CA3D70A, 0x3CF5C28F, 0x3D23D70A, 0x3D4CCCCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) 0x3D75C28F, 0x3D8F5C29, 0x3DA3D70A, 0x3DB851EC, 0x3DCCCCCD, 0x3DE147AE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 0x3DF5C28F, 0x3E051EB8, 0x3E0F5C29, 0x3E19999A, 0x3E23D70A, 0x3E2E147B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 0x3E3851EC, 0x3E428F5C, 0x3E4CCCCD, 0x3E570A3D, 0x3E6147AE, 0x3E6B851F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 0x3E75C28F, 0x3E800000, 0x3E851EB8, 0x3E8A3D71, 0x3E8F5C29, 0x3E947AE1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 0x3E99999A, 0x3E9EB852, 0x3EA3D70A, 0x3EA8F5C3, 0x3EAE147B, 0x3EB33333,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 0x3EB851EC, 0x3EBD70A4, 0x3EC28F5C, 0x3EC7AE14, 0x3ECCCCCD, 0x3ED1EB85,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 0x3ED70A3D, 0x3EDC28F6, 0x3EE147AE, 0x3EE66666, 0x3EEB851F, 0x3EF0A3D7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 0x3EF5C28F, 0x3EFAE148, 0x3F000000, 0x3F028F5C, 0x3F051EB8, 0x3F07AE14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 0x3F0A3D71, 0x3F0CCCCD, 0x3F0F5C29, 0x3F11EB85, 0x3F147AE1, 0x3F170A3D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 0x3F19999A, 0x3F1C28F6, 0x3F1EB852, 0x3F2147AE, 0x3F23D70A, 0x3F266666,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 0x3F28F5C3, 0x3F2B851F, 0x3F2E147B, 0x3F30A3D7, 0x3F333333, 0x3F35C28F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 0x3F3851EC, 0x3F3AE148, 0x3F3D70A4, 0x3F400000, 0x3F428F5C, 0x3F451EB8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 0x3F47AE14, 0x3F4A3D71, 0x3F4CCCCD, 0x3F4F5C29, 0x3F51EB85, 0x3F547AE1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) 0x3F570A3D, 0x3F59999A, 0x3F5C28F6, 0x3F5EB852, 0x3F6147AE, 0x3F63D70A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 0x3F666666, 0x3F68F5C3, 0x3F6B851F, 0x3F6E147B, 0x3F70A3D7, 0x3F733333,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 0x3F75C28F, 0x3F7851EC, 0x3F7AE148, 0x3F7D70A4, 0x3F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) static const unsigned int equalizer_vals_lookup[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 0xC1C00000, 0xC1B80000, 0xC1B00000, 0xC1A80000, 0xC1A00000, 0xC1980000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 0xC1900000, 0xC1880000, 0xC1800000, 0xC1700000, 0xC1600000, 0xC1500000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 0xC1400000, 0xC1300000, 0xC1200000, 0xC1100000, 0xC1000000, 0xC0E00000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 0xC0C00000, 0xC0A00000, 0xC0800000, 0xC0400000, 0xC0000000, 0xBF800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) 0x00000000, 0x3F800000, 0x40000000, 0x40400000, 0x40800000, 0x40A00000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 0x40C00000, 0x40E00000, 0x41000000, 0x41100000, 0x41200000, 0x41300000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 0x41400000, 0x41500000, 0x41600000, 0x41700000, 0x41800000, 0x41880000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) 0x41900000, 0x41980000, 0x41A00000, 0x41A80000, 0x41B00000, 0x41B80000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 0x41C00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) static int tuning_ctl_set(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) const unsigned int *lookup, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) for (i = 0; i < TUNING_CTLS_COUNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) if (nid == ca0132_tuning_ctls[i].nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) snd_hda_power_up(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) ca0132_tuning_ctls[i].req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) &(lookup[idx]), sizeof(unsigned int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) snd_hda_power_down(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) static int tuning_ctl_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) int idx = nid - TUNING_CTL_START_NID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) *valp = spec->cur_ctl_vals[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) static int voice_focus_ctl_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) int chs = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) uinfo->count = chs == 3 ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) uinfo->value.integer.min = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) uinfo->value.integer.max = 180;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) uinfo->value.integer.step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) static int voice_focus_ctl_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) idx = nid - TUNING_CTL_START_NID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) /* any change? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) if (spec->cur_ctl_vals[idx] == *valp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) spec->cur_ctl_vals[idx] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) idx = *valp - 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) tuning_ctl_set(codec, nid, voice_focus_vals_lookup, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) static int mic_svm_ctl_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) int chs = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) uinfo->count = chs == 3 ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) uinfo->value.integer.max = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) uinfo->value.integer.step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) static int mic_svm_ctl_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) idx = nid - TUNING_CTL_START_NID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) /* any change? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) if (spec->cur_ctl_vals[idx] == *valp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) spec->cur_ctl_vals[idx] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) idx = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) tuning_ctl_set(codec, nid, mic_svm_vals_lookup, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) static int equalizer_ctl_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) int chs = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) uinfo->count = chs == 3 ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) uinfo->value.integer.max = 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) uinfo->value.integer.step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) static int equalizer_ctl_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) idx = nid - TUNING_CTL_START_NID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) /* any change? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) if (spec->cur_ctl_vals[idx] == *valp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) spec->cur_ctl_vals[idx] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) idx = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) tuning_ctl_set(codec, nid, equalizer_vals_lookup, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(voice_focus_db_scale, 2000, 100, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(eq_db_scale, -2400, 100, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) static int add_tuning_control(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) hda_nid_t pnid, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) const char *name, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) int type = dir ? HDA_INPUT : HDA_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) HDA_CODEC_VOLUME_MONO(namestr, nid, 1, 0, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) SNDRV_CTL_ELEM_ACCESS_TLV_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) knew.tlv.c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) knew.tlv.p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) switch (pnid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) case VOICE_FOCUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) knew.info = voice_focus_ctl_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) knew.get = tuning_ctl_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) knew.put = voice_focus_ctl_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) knew.tlv.p = voice_focus_db_scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) case MIC_SVM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) knew.info = mic_svm_ctl_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) knew.get = tuning_ctl_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) knew.put = mic_svm_ctl_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) case EQUALIZER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) knew.info = equalizer_ctl_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) knew.get = tuning_ctl_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) knew.put = equalizer_ctl_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) knew.tlv.p = eq_db_scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) knew.private_value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) HDA_COMPOSE_AMP_VAL(nid, 1, 0, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) sprintf(namestr, "%s %s Volume", name, dirstr[dir]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) static int add_tuning_ctls(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) for (i = 0; i < TUNING_CTLS_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) err = add_tuning_control(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) ca0132_tuning_ctls[i].parent_nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) ca0132_tuning_ctls[i].nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) ca0132_tuning_ctls[i].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) ca0132_tuning_ctls[i].direct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) static void ca0132_init_tuning_defaults(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) /* Wedge Angle defaults to 30. 10 below is 30 - 20. 20 is min. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) spec->cur_ctl_vals[WEDGE_ANGLE - TUNING_CTL_START_NID] = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) /* SVM level defaults to 0.74. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) spec->cur_ctl_vals[SVM_LEVEL - TUNING_CTL_START_NID] = 74;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) /* EQ defaults to 0dB. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) for (i = 2; i < TUNING_CTLS_COUNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) spec->cur_ctl_vals[i] = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) #endif /*ENABLE_TUNING_CONTROLS*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) * Select the active output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) * If autodetect is enabled, output will be selected based on jack detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) * If jack inserted, headphone will be selected, else built-in speakers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) * If autodetect is disabled, output will be selected based on selection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) static int ca0132_select_out(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) unsigned int pin_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) int jack_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) int auto_jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) codec_dbg(codec, "ca0132_select_out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) snd_hda_power_up_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) auto_jack = spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) if (auto_jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) jack_present = snd_hda_jack_detect(codec, spec->unsol_tag_hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) jack_present =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) spec->vnode_lswitch[VNID_HP_SEL - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) if (jack_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) spec->cur_out_type = HEADPHONE_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) spec->cur_out_type = SPEAKER_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) if (spec->cur_out_type == SPEAKER_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) codec_dbg(codec, "ca0132_select_out speaker\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) /*speaker out config*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) err = dspio_set_uint_param(codec, 0x80, 0x04, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) /*enable speaker EQ*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) err = dspio_set_uint_param(codec, 0x8f, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) /* Setup EAPD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) snd_hda_codec_write(codec, spec->out_pins[1], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) VENDOR_CHIPIO_EAPD_SEL_SET, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) snd_hda_codec_write(codec, spec->out_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) AC_VERB_SET_EAPD_BTLENABLE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) snd_hda_codec_write(codec, spec->out_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) VENDOR_CHIPIO_EAPD_SEL_SET, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) snd_hda_codec_write(codec, spec->out_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) AC_VERB_SET_EAPD_BTLENABLE, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) /* disable headphone node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) pin_ctl = snd_hda_codec_read(codec, spec->out_pins[1], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) snd_hda_set_pin_ctl(codec, spec->out_pins[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) pin_ctl & ~PIN_HP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) /* enable speaker node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) snd_hda_set_pin_ctl(codec, spec->out_pins[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) pin_ctl | PIN_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) codec_dbg(codec, "ca0132_select_out hp\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) /*headphone out config*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) err = dspio_set_uint_param(codec, 0x80, 0x04, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) /*disable speaker EQ*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) err = dspio_set_uint_param(codec, 0x8f, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) /* Setup EAPD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) snd_hda_codec_write(codec, spec->out_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) VENDOR_CHIPIO_EAPD_SEL_SET, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) snd_hda_codec_write(codec, spec->out_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) AC_VERB_SET_EAPD_BTLENABLE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) snd_hda_codec_write(codec, spec->out_pins[1], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) VENDOR_CHIPIO_EAPD_SEL_SET, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) snd_hda_codec_write(codec, spec->out_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) AC_VERB_SET_EAPD_BTLENABLE, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) /* disable speaker*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) snd_hda_set_pin_ctl(codec, spec->out_pins[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) pin_ctl & ~PIN_HP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) /* enable headphone*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) pin_ctl = snd_hda_codec_read(codec, spec->out_pins[1], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) snd_hda_set_pin_ctl(codec, spec->out_pins[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) pin_ctl | PIN_HP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) snd_hda_power_down_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) return err < 0 ? err : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) static int ae5_headphone_gain_set(struct hda_codec *codec, long val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) static int zxr_headphone_gain_set(struct hda_codec *codec, long val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) static void ae5_mmio_select_out(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) const struct ae_ca0113_output_set *out_cmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) if (ca0132_quirk(spec) == QUIRK_AE5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) out_cmds = &ae5_ca0113_output_presets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) out_cmds = &ae7_ca0113_output_presets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) for (i = 0; i < AE_CA0113_OUT_SET_COMMANDS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) ca0113_mmio_command_set(codec, out_cmds->group[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) out_cmds->target[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) out_cmds->vals[spec->cur_out_type][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) static int ca0132_alt_set_full_range_speaker(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) int quirk = ca0132_quirk(spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) /* 2.0/4.0 setup has no LFE channel, so setting full-range does nothing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) if (spec->channel_cfg_val == SPEAKER_CHANNELS_4_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) || spec->channel_cfg_val == SPEAKER_CHANNELS_2_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) /* Set front L/R full range. Zero for full-range, one for redirection. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) tmp = spec->speaker_range_val[0] ? FLOAT_ZERO : FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) err = dspio_set_uint_param(codec, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) SPEAKER_FULL_RANGE_FRONT_L_R, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) /* When setting full-range rear, both rear and center/lfe are set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) tmp = spec->speaker_range_val[1] ? FLOAT_ZERO : FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) err = dspio_set_uint_param(codec, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) SPEAKER_FULL_RANGE_CENTER_LFE, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) err = dspio_set_uint_param(codec, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) SPEAKER_FULL_RANGE_REAR_L_R, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) * Only the AE series cards set this value when setting full-range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) * and it's always 1.0f.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) if (quirk == QUIRK_AE5 || quirk == QUIRK_AE7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) err = dspio_set_uint_param(codec, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) SPEAKER_FULL_RANGE_SURROUND_L_R, FLOAT_ONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) static int ca0132_alt_surround_set_bass_redirection(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) bool val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) if (val && spec->channel_cfg_val != SPEAKER_CHANNELS_4_0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) spec->channel_cfg_val != SPEAKER_CHANNELS_2_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) err = dspio_set_uint_param(codec, 0x96, SPEAKER_BASS_REDIRECT, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) /* If it is enabled, make sure to set the crossover frequency. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) if (tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) tmp = float_xbass_xover_lookup[spec->xbass_xover_freq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) err = dspio_set_uint_param(codec, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) SPEAKER_BASS_REDIRECT_XOVER_FREQ, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) * These are the commands needed to setup output on each of the different card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) * types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) static void ca0132_alt_select_out_get_quirk_data(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) const struct ca0132_alt_out_set_quirk_data **quirk_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) int quirk = ca0132_quirk(spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) *quirk_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) for (i = 0; i < ARRAY_SIZE(quirk_out_set_data); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) if (quirk_out_set_data[i].quirk_id == quirk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) *quirk_data = &quirk_out_set_data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) static int ca0132_alt_select_out_quirk_set(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) const struct ca0132_alt_out_set_quirk_data *quirk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) const struct ca0132_alt_out_set_info *out_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) unsigned int i, gpio_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) ca0132_alt_select_out_get_quirk_data(codec, &quirk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) if (!quirk_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) out_info = &quirk_data->out_set_info[spec->cur_out_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) if (quirk_data->is_ae_series)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) ae5_mmio_select_out(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) if (out_info->has_hda_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) gpio_data = snd_hda_codec_read(codec, codec->core.afg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) AC_VERB_GET_GPIO_DATA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) if (out_info->hda_gpio_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) gpio_data |= (1 << out_info->hda_gpio_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) gpio_data &= ~(1 << out_info->hda_gpio_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) snd_hda_codec_write(codec, codec->core.afg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) AC_VERB_SET_GPIO_DATA, gpio_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) if (out_info->mmio_gpio_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) for (i = 0; i < out_info->mmio_gpio_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) ca0113_mmio_gpio_set(codec, out_info->mmio_gpio_pin[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) out_info->mmio_gpio_set[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) if (out_info->scp_cmds_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) for (i = 0; i < out_info->scp_cmds_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) err = dspio_set_uint_param(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) out_info->scp_cmd_mid[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) out_info->scp_cmd_req[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) out_info->scp_cmd_val[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) chipio_set_control_param(codec, 0x0d, out_info->dac2port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) if (out_info->has_chipio_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) chipio_write(codec, out_info->chipio_write_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) out_info->chipio_write_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) if (quirk_data->has_headphone_gain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) if (spec->cur_out_type != HEADPHONE_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) if (quirk_data->is_ae_series)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) ae5_headphone_gain_set(codec, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) zxr_headphone_gain_set(codec, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) if (quirk_data->is_ae_series)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) ae5_headphone_gain_set(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) spec->ae5_headphone_gain_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) zxr_headphone_gain_set(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) spec->zxr_gain_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) static void ca0132_set_out_node_pincfg(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) bool out_enable, bool hp_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) unsigned int pin_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) pin_ctl = snd_hda_codec_read(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) pin_ctl = hp_enable ? pin_ctl | PIN_HP_AMP : pin_ctl & ~PIN_HP_AMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) pin_ctl = out_enable ? pin_ctl | PIN_OUT : pin_ctl & ~PIN_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) snd_hda_set_pin_ctl(codec, nid, pin_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) * This function behaves similarly to the ca0132_select_out funciton above,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) * except with a few differences. It adds the ability to select the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) * output with an enumerated control "output source" if the auto detect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) * mute switch is set to off. If the auto detect mute switch is enabled, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) * will detect either headphone or lineout(SPEAKER_OUT) from jack detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) * It also adds the ability to auto-detect the front headphone port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) static int ca0132_alt_select_out(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) unsigned int tmp, outfx_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) int jack_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) int auto_jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) /* Default Headphone is rear headphone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) hda_nid_t headphone_nid = spec->out_pins[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) codec_dbg(codec, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) snd_hda_power_up_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) auto_jack = spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) * If headphone rear or front is plugged in, set to headphone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) * If neither is plugged in, set to rear line out. Only if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) * hp/speaker auto detect is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) if (auto_jack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) jack_present = snd_hda_jack_detect(codec, spec->unsol_tag_hp) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) snd_hda_jack_detect(codec, spec->unsol_tag_front_hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) if (jack_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) spec->cur_out_type = HEADPHONE_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) spec->cur_out_type = SPEAKER_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) spec->cur_out_type = spec->out_enum_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) outfx_set = spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) /* Begin DSP output switch, mute DSP volume. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) err = dspio_set_uint_param(codec, 0x96, SPEAKER_TUNING_MUTE, FLOAT_ONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) if (ca0132_alt_select_out_quirk_set(codec) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) switch (spec->cur_out_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) case SPEAKER_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) codec_dbg(codec, "%s speaker\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) /* Enable EAPD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) snd_hda_codec_write(codec, spec->out_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) AC_VERB_SET_EAPD_BTLENABLE, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) /* Disable headphone node. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) ca0132_set_out_node_pincfg(codec, spec->out_pins[1], 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) /* Set front L-R to output. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) ca0132_set_out_node_pincfg(codec, spec->out_pins[0], 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) /* Set Center/LFE to output. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) ca0132_set_out_node_pincfg(codec, spec->out_pins[2], 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) /* Set rear surround to output. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) ca0132_set_out_node_pincfg(codec, spec->out_pins[3], 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) * Without PlayEnhancement being enabled, if we've got a 2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) * setup, set it to floating point eight to disable any DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) * processing effects.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) if (!outfx_set && spec->channel_cfg_val == SPEAKER_CHANNELS_2_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) tmp = FLOAT_EIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) tmp = speaker_channel_cfgs[spec->channel_cfg_val].val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) err = dspio_set_uint_param(codec, 0x80, 0x04, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) case HEADPHONE_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) codec_dbg(codec, "%s hp\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) snd_hda_codec_write(codec, spec->out_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) AC_VERB_SET_EAPD_BTLENABLE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) /* Disable all speaker nodes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) ca0132_set_out_node_pincfg(codec, spec->out_pins[0], 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) ca0132_set_out_node_pincfg(codec, spec->out_pins[2], 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) ca0132_set_out_node_pincfg(codec, spec->out_pins[3], 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) /* enable headphone, either front or rear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) if (snd_hda_jack_detect(codec, spec->unsol_tag_front_hp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) headphone_nid = spec->out_pins[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) else if (snd_hda_jack_detect(codec, spec->unsol_tag_hp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) headphone_nid = spec->out_pins[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) ca0132_set_out_node_pincfg(codec, headphone_nid, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) if (outfx_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) err = dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) err = dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) * If output effects are enabled, set the X-Bass effect value again to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) * make sure that it's properly enabled/disabled for speaker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) * configurations with an LFE channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) if (outfx_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) ca0132_effects_set(codec, X_BASS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) spec->effects_switch[X_BASS - EFFECT_START_NID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) /* Set speaker EQ bypass attenuation to 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) err = dspio_set_uint_param(codec, 0x8f, 0x01, FLOAT_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) * Although unused on all cards but the AE series, this is always set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) * to zero when setting the output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) err = dspio_set_uint_param(codec, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) SPEAKER_TUNING_USE_SPEAKER_EQ, FLOAT_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) if (spec->cur_out_type == SPEAKER_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) err = ca0132_alt_surround_set_bass_redirection(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) spec->bass_redirection_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) err = ca0132_alt_surround_set_bass_redirection(codec, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) /* Unmute DSP now that we're done with output selection. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) err = dspio_set_uint_param(codec, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) SPEAKER_TUNING_MUTE, FLOAT_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) if (spec->cur_out_type == SPEAKER_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) err = ca0132_alt_set_full_range_speaker(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) snd_hda_power_down_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) return err < 0 ? err : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) static void ca0132_unsol_hp_delayed(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) struct ca0132_spec *spec = container_of(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) to_delayed_work(work), struct ca0132_spec, unsol_hp_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) struct hda_jack_tbl *jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) if (ca0132_use_alt_functions(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) ca0132_alt_select_out(spec->codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) ca0132_select_out(spec->codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) jack = snd_hda_jack_tbl_get(spec->codec, spec->unsol_tag_hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) if (jack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) jack->block_report = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) snd_hda_jack_report_sync(spec->codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) static void ca0132_set_dmic(struct hda_codec *codec, int enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) static int ca0132_mic_boost_set(struct hda_codec *codec, long val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) static void resume_mic1(struct hda_codec *codec, unsigned int oldval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) static int stop_mic1(struct hda_codec *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) static int ca0132_cvoice_switch_set(struct hda_codec *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) static int ca0132_alt_mic_boost_set(struct hda_codec *codec, long val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) * Select the active VIP source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) static int ca0132_set_vipsource(struct hda_codec *codec, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) if (spec->dsp_state != DSP_DOWNLOADED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) /* if CrystalVoice if off, vipsource should be 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) if (!spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) (val == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) if (spec->cur_mic_type == DIGITAL_MIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) tmp = FLOAT_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) dspio_set_uint_param(codec, 0x80, 0x05, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_16_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_16_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) if (spec->cur_mic_type == DIGITAL_MIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) tmp = FLOAT_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) dspio_set_uint_param(codec, 0x80, 0x05, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) static int ca0132_alt_set_vipsource(struct hda_codec *codec, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) if (spec->dsp_state != DSP_DOWNLOADED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) codec_dbg(codec, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) chipio_set_stream_control(codec, 0x03, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) chipio_set_stream_control(codec, 0x04, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) /* if CrystalVoice is off, vipsource should be 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) if (!spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) (val == 0) || spec->in_enum_val == REAR_LINE_IN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) codec_dbg(codec, "%s: off.", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) dspio_set_uint_param(codec, 0x80, 0x05, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) if (ca0132_quirk(spec) == QUIRK_R3DI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) chipio_set_conn_rate(codec, 0x0F, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) if (spec->in_enum_val == REAR_LINE_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) if (ca0132_quirk(spec) == QUIRK_SBZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) tmp = FLOAT_THREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) codec_dbg(codec, "%s: on.", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_16_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_16_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) if (ca0132_quirk(spec) == QUIRK_R3DI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) chipio_set_conn_rate(codec, 0x0F, SR_16_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) if (spec->effects_switch[VOICE_FOCUS - EFFECT_START_NID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) tmp = FLOAT_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) dspio_set_uint_param(codec, 0x80, 0x05, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) chipio_set_stream_control(codec, 0x03, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) chipio_set_stream_control(codec, 0x04, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) * Select the active microphone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) * If autodetect is enabled, mic will be selected based on jack detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) * If jack inserted, ext.mic will be selected, else built-in mic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) * If autodetect is disabled, mic will be selected based on selection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) static int ca0132_select_mic(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) int jack_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) int auto_jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) codec_dbg(codec, "ca0132_select_mic\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) snd_hda_power_up_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) auto_jack = spec->vnode_lswitch[VNID_AMIC1_ASEL - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) if (auto_jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) jack_present = snd_hda_jack_detect(codec, spec->unsol_tag_amic1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) jack_present =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) spec->vnode_lswitch[VNID_AMIC1_SEL - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) if (jack_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) spec->cur_mic_type = LINE_MIC_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) spec->cur_mic_type = DIGITAL_MIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) if (spec->cur_mic_type == DIGITAL_MIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) /* enable digital Mic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) chipio_set_conn_rate(codec, MEM_CONNID_DMIC, SR_32_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) ca0132_set_dmic(codec, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) ca0132_mic_boost_set(codec, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) /* set voice focus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) ca0132_effects_set(codec, VOICE_FOCUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) spec->effects_switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) [VOICE_FOCUS - EFFECT_START_NID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) /* disable digital Mic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) chipio_set_conn_rate(codec, MEM_CONNID_DMIC, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) ca0132_set_dmic(codec, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) ca0132_mic_boost_set(codec, spec->cur_mic_boost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) /* disable voice focus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) ca0132_effects_set(codec, VOICE_FOCUS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) snd_hda_power_down_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) * Select the active input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) * Mic detection isn't used, because it's kind of pointless on the SBZ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) * The front mic has no jack-detection, so the only way to switch to it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) * is to do it manually in alsamixer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) static int ca0132_alt_select_in(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) codec_dbg(codec, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) snd_hda_power_up_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) chipio_set_stream_control(codec, 0x03, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) chipio_set_stream_control(codec, 0x04, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) spec->cur_mic_type = spec->in_enum_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) switch (spec->cur_mic_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) case REAR_MIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) ca0113_mmio_gpio_set(codec, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) tmp = FLOAT_THREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) tmp = FLOAT_THREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) r3di_gpio_mic_set(codec, R3DI_REAR_MIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) tmp = FLOAT_THREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) tmp = FLOAT_THREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) chipio_set_conn_rate(codec, MEM_CONNID_MICIN2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) dspio_set_uint_param(codec, 0x80, 0x01, FLOAT_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) if (ca0132_quirk(spec) == QUIRK_R3DI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) chipio_set_conn_rate(codec, 0x0F, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) chipio_set_stream_control(codec, 0x03, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) chipio_set_stream_control(codec, 0x04, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) chipio_write(codec, 0x18B098, 0x0000000C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) chipio_write(codec, 0x18B09C, 0x0000000C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) chipio_write(codec, 0x18B098, 0x0000000C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) chipio_write(codec, 0x18B09C, 0x000000CC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) chipio_write(codec, 0x18B098, 0x0000000C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) chipio_write(codec, 0x18B09C, 0x0000004C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) ca0132_alt_mic_boost_set(codec, spec->mic_boost_enum_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) case REAR_LINE_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) ca0132_mic_boost_set(codec, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) ca0113_mmio_gpio_set(codec, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) r3di_gpio_mic_set(codec, R3DI_REAR_MIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) ca0113_mmio_command_set(codec, 0x30, 0x28, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) chipio_set_conn_rate(codec, MEM_CONNID_MICIN2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) dspio_set_uint_param(codec, 0x80, 0x01, FLOAT_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) if (ca0132_quirk(spec) == QUIRK_R3DI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) chipio_set_conn_rate(codec, 0x0F, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) if (ca0132_quirk(spec) == QUIRK_AE7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) tmp = FLOAT_THREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) chipio_write(codec, 0x18B098, 0x00000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) chipio_write(codec, 0x18B09C, 0x00000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) chipio_set_stream_control(codec, 0x03, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) chipio_set_stream_control(codec, 0x04, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) case FRONT_MIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) ca0113_mmio_gpio_set(codec, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) ca0113_mmio_gpio_set(codec, 5, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) tmp = FLOAT_THREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) r3di_gpio_mic_set(codec, R3DI_FRONT_MIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) ca0113_mmio_command_set(codec, 0x30, 0x28, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) tmp = FLOAT_THREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) if (ca0132_quirk(spec) == QUIRK_R3DI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) chipio_set_conn_rate(codec, 0x0F, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) chipio_set_stream_control(codec, 0x03, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) chipio_set_stream_control(codec, 0x04, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) chipio_write(codec, 0x18B098, 0x0000000C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) chipio_write(codec, 0x18B09C, 0x000000CC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) chipio_write(codec, 0x18B098, 0x0000000C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) chipio_write(codec, 0x18B09C, 0x0000004C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) ca0132_alt_mic_boost_set(codec, spec->mic_boost_enum_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) ca0132_cvoice_switch_set(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) snd_hda_power_down_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) * Check if VNODE settings take effect immediately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) static bool ca0132_is_vnode_effective(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) hda_nid_t vnid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) hda_nid_t *shared_nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) switch (vnid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) case VNID_SPK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) nid = spec->shared_out_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) case VNID_MIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) nid = spec->shared_mic_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) if (shared_nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) *shared_nid = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) * The following functions are control change helpers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) * They return 0 if no changed. Return 1 if changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) static int ca0132_voicefx_set(struct hda_codec *codec, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) /* based on CrystalVoice state to enable VoiceFX. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) tmp = spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID] ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) FLOAT_ONE : FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) dspio_set_uint_param(codec, ca0132_voicefx.mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) ca0132_voicefx.reqs[0], tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) * Set the effects parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) unsigned int on, tmp, channel_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) int num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) int idx = nid - EFFECT_START_NID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) if ((idx < 0) || (idx >= num_fx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) return 0; /* no changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) /* for out effect, qualify with PE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) if ((nid >= OUT_EFFECT_START_NID) && (nid < OUT_EFFECT_END_NID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) /* if PE if off, turn off out effects. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) if (!spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) if (spec->cur_out_type == SPEAKER_OUT && nid == X_BASS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) channel_cfg = spec->channel_cfg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) if (channel_cfg != SPEAKER_CHANNELS_2_0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) channel_cfg != SPEAKER_CHANNELS_4_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) /* for in effect, qualify with CrystalVoice */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) if ((nid >= IN_EFFECT_START_NID) && (nid < IN_EFFECT_END_NID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) /* if CrystalVoice if off, turn off in effects. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) if (!spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) /* Voice Focus applies to 2-ch Mic, Digital Mic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) if ((nid == VOICE_FOCUS) && (spec->cur_mic_type != DIGITAL_MIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) /* If Voice Focus on SBZ, set to two channel. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) if ((nid == VOICE_FOCUS) && ca0132_use_pci_mmio(spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) && (spec->cur_mic_type != REAR_LINE_IN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) if (spec->effects_switch[CRYSTAL_VOICE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) EFFECT_START_NID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) if (spec->effects_switch[VOICE_FOCUS -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) EFFECT_START_NID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) tmp = FLOAT_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) * For SBZ noise reduction, there's an extra command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) * to module ID 0x47. No clue why.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) if ((nid == NOISE_REDUCTION) && ca0132_use_pci_mmio(spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) && (spec->cur_mic_type != REAR_LINE_IN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) if (spec->effects_switch[CRYSTAL_VOICE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) EFFECT_START_NID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) if (spec->effects_switch[NOISE_REDUCTION -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) EFFECT_START_NID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) dspio_set_uint_param(codec, 0x47, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) /* If rear line in disable effects. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) if (ca0132_use_alt_functions(spec) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) spec->in_enum_val == REAR_LINE_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) codec_dbg(codec, "ca0132_effect_set: nid=0x%x, val=%ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) nid, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) on = (val == 0) ? FLOAT_ZERO : FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) err = dspio_set_uint_param(codec, ca0132_effects[idx].mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) ca0132_effects[idx].reqs[0], on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) return 0; /* no changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) * Turn on/off Playback Enhancements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) static int ca0132_pe_switch_set(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) codec_dbg(codec, "ca0132_pe_switch_set: val=%ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) if (ca0132_use_alt_functions(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) ca0132_alt_select_out(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) i = OUT_EFFECT_START_NID - EFFECT_START_NID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) nid = OUT_EFFECT_START_NID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) /* PE affects all out effects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) for (; nid < OUT_EFFECT_END_NID; nid++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) ret |= ca0132_effects_set(codec, nid, spec->effects_switch[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) /* Check if Mic1 is streaming, if so, stop streaming */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) static int stop_mic1(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) unsigned int oldval = snd_hda_codec_read(codec, spec->adcs[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) AC_VERB_GET_CONV, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) if (oldval != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) snd_hda_codec_write(codec, spec->adcs[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) AC_VERB_SET_CHANNEL_STREAMID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) return oldval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) /* Resume Mic1 streaming if it was stopped. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) static void resume_mic1(struct hda_codec *codec, unsigned int oldval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) /* Restore the previous stream and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) if (oldval != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) snd_hda_codec_write(codec, spec->adcs[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) AC_VERB_SET_CHANNEL_STREAMID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) oldval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) * Turn on/off CrystalVoice
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) static int ca0132_cvoice_switch_set(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) unsigned int oldval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) codec_dbg(codec, "ca0132_cvoice_switch_set: val=%ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) i = IN_EFFECT_START_NID - EFFECT_START_NID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) nid = IN_EFFECT_START_NID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) /* CrystalVoice affects all in effects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) for (; nid < IN_EFFECT_END_NID; nid++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) ret |= ca0132_effects_set(codec, nid, spec->effects_switch[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) /* including VoiceFX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) ret |= ca0132_voicefx_set(codec, (spec->voicefx_val ? 1 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) /* set correct vipsource */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) oldval = stop_mic1(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) if (ca0132_use_alt_functions(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) ret |= ca0132_alt_set_vipsource(codec, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) ret |= ca0132_set_vipsource(codec, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) resume_mic1(codec, oldval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) static int ca0132_mic_boost_set(struct hda_codec *codec, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) if (val) /* on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) ret = snd_hda_codec_amp_update(codec, spec->input_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) HDA_INPUT, 0, HDA_AMP_VOLMASK, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) else /* off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) ret = snd_hda_codec_amp_update(codec, spec->input_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) HDA_INPUT, 0, HDA_AMP_VOLMASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) static int ca0132_alt_mic_boost_set(struct hda_codec *codec, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) ret = snd_hda_codec_amp_update(codec, spec->input_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) HDA_INPUT, 0, HDA_AMP_VOLMASK, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) static int ae5_headphone_gain_set(struct hda_codec *codec, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) ca0113_mmio_command_set(codec, 0x48, 0x11 + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) ae5_headphone_gain_presets[val].vals[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) * gpio pin 1 is a relay that switches on/off, apparently setting the headphone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) * amplifier to handle a 600 ohm load.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) static int zxr_headphone_gain_set(struct hda_codec *codec, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) ca0113_mmio_gpio_set(codec, 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) static int ca0132_vnode_switch_set(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) hda_nid_t shared_nid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) bool effective;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) int auto_jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) if (nid == VNID_HP_SEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) auto_jack =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) if (!auto_jack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) if (ca0132_use_alt_functions(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) ca0132_alt_select_out(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) ca0132_select_out(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) if (nid == VNID_AMIC1_SEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) auto_jack =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) spec->vnode_lswitch[VNID_AMIC1_ASEL - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) if (!auto_jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) ca0132_select_mic(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) if (nid == VNID_HP_ASEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) if (ca0132_use_alt_functions(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) ca0132_alt_select_out(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) ca0132_select_out(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) if (nid == VNID_AMIC1_ASEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) ca0132_select_mic(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) /* if effective conditions, then update hw immediately. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) effective = ca0132_is_vnode_effective(codec, nid, &shared_nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) if (effective) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) int dir = get_amp_direction(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) int ch = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) unsigned long pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) mutex_lock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) pval = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) kcontrol->private_value = HDA_COMPOSE_AMP_VAL(shared_nid, ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) 0, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) kcontrol->private_value = pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) mutex_unlock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) /* End of control change helpers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) static void ca0132_alt_bass_redirection_xover_set(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) long idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) snd_hda_power_up(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) dspio_set_param(codec, 0x96, 0x20, SPEAKER_BASS_REDIRECT_XOVER_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) &(float_xbass_xover_lookup[idx]), sizeof(unsigned int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) snd_hda_power_down(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) * Below I've added controls to mess with the effect levels, I've only enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) * them on the Sound Blaster Z, but they would probably also work on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) * Chromebook. I figured they were probably tuned specifically for it, and left
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) * out for a reason.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) /* Sets DSP effect level from the sliders above the controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) static int ca0132_alt_slider_ctl_set(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) const unsigned int *lookup, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) unsigned int y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) * For X_BASS, req 2 is actually crossover freq instead of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500) * effect level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) if (nid == X_BASS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) y = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) y = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) snd_hda_power_up(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) if (nid == XBASS_XOVER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) for (i = 0; i < OUT_EFFECTS_COUNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) if (ca0132_effects[i].nid == X_BASS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) dspio_set_param(codec, ca0132_effects[i].mid, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) ca0132_effects[i].reqs[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) &(lookup[idx - 1]), sizeof(unsigned int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) /* Find the actual effect structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) for (i = 0; i < OUT_EFFECTS_COUNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) if (nid == ca0132_effects[i].nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) dspio_set_param(codec, ca0132_effects[i].mid, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) ca0132_effects[i].reqs[y],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) &(lookup[idx]), sizeof(unsigned int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) snd_hda_power_down(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) static int ca0132_alt_xbass_xover_slider_ctl_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) if (nid == BASS_REDIRECTION_XOVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) *valp = spec->bass_redirect_xover_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) *valp = spec->xbass_xover_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) static int ca0132_alt_slider_ctl_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) int idx = nid - OUT_EFFECT_START_NID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) *valp = spec->fx_ctl_val[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) * The X-bass crossover starts at 10hz, so the min is 1. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) * frequency is set in multiples of 10.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) static int ca0132_alt_xbass_xover_slider_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) uinfo->value.integer.min = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) uinfo->value.integer.max = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) uinfo->value.integer.step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) static int ca0132_alt_effect_slider_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) int chs = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) uinfo->count = chs == 3 ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) uinfo->value.integer.max = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) uinfo->value.integer.step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) static int ca0132_alt_xbass_xover_slider_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) long *cur_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) if (nid == BASS_REDIRECTION_XOVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) cur_val = &spec->bass_redirect_xover_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) cur_val = &spec->xbass_xover_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) /* any change? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) if (*cur_val == *valp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) *cur_val = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) idx = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) if (nid == BASS_REDIRECTION_XOVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) ca0132_alt_bass_redirection_xover_set(codec, *cur_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) ca0132_alt_slider_ctl_set(codec, nid, float_xbass_xover_lookup, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) static int ca0132_alt_effect_slider_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) idx = nid - EFFECT_START_NID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) /* any change? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) if (spec->fx_ctl_val[idx] == *valp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) spec->fx_ctl_val[idx] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) idx = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) ca0132_alt_slider_ctl_set(codec, nid, float_zero_to_one_lookup, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) * Mic Boost Enum for alternative ca0132 codecs. I didn't like that the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) * only has off or full 30 dB, and didn't like making a volume slider that has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) * traditional 0-100 in alsamixer that goes in big steps. I like enum better.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) #define MIC_BOOST_NUM_OF_STEPS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) #define MIC_BOOST_ENUM_MAX_STRLEN 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) static int ca0132_alt_mic_boost_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) char *sfx = "dB";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660) uinfo->value.enumerated.items = MIC_BOOST_NUM_OF_STEPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) if (uinfo->value.enumerated.item >= MIC_BOOST_NUM_OF_STEPS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662) uinfo->value.enumerated.item = MIC_BOOST_NUM_OF_STEPS - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) sprintf(namestr, "%d %s", (uinfo->value.enumerated.item * 10), sfx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664) strcpy(uinfo->value.enumerated.name, namestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) static int ca0132_alt_mic_boost_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) ucontrol->value.enumerated.item[0] = spec->mic_boost_enum_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) static int ca0132_alt_mic_boost_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683) int sel = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) unsigned int items = MIC_BOOST_NUM_OF_STEPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) if (sel >= items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) codec_dbg(codec, "ca0132_alt_mic_boost: boost=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) spec->mic_boost_enum_val = sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) if (spec->in_enum_val != REAR_LINE_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695) ca0132_alt_mic_boost_set(codec, spec->mic_boost_enum_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) * Sound BlasterX AE-5 Headphone Gain Controls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703) #define AE5_HEADPHONE_GAIN_MAX 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) static int ae5_headphone_gain_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707) char *sfx = " Ohms)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712) uinfo->value.enumerated.items = AE5_HEADPHONE_GAIN_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) if (uinfo->value.enumerated.item >= AE5_HEADPHONE_GAIN_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) uinfo->value.enumerated.item = AE5_HEADPHONE_GAIN_MAX - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) sprintf(namestr, "%s %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716) ae5_headphone_gain_presets[uinfo->value.enumerated.item].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) sfx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718) strcpy(uinfo->value.enumerated.name, namestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722) static int ae5_headphone_gain_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) ucontrol->value.enumerated.item[0] = spec->ae5_headphone_gain_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) static int ae5_headphone_gain_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) int sel = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738) unsigned int items = AE5_HEADPHONE_GAIN_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) if (sel >= items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743) codec_dbg(codec, "ae5_headphone_gain: boost=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746) spec->ae5_headphone_gain_val = sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) if (spec->out_enum_val == HEADPHONE_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) ae5_headphone_gain_set(codec, spec->ae5_headphone_gain_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) * Sound BlasterX AE-5 sound filter enumerated control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) #define AE5_SOUND_FILTER_MAX 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759) static int ae5_sound_filter_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762) char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764) uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) uinfo->value.enumerated.items = AE5_SOUND_FILTER_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) if (uinfo->value.enumerated.item >= AE5_SOUND_FILTER_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768) uinfo->value.enumerated.item = AE5_SOUND_FILTER_MAX - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) sprintf(namestr, "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) ae5_filter_presets[uinfo->value.enumerated.item].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) strcpy(uinfo->value.enumerated.name, namestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775) static int ae5_sound_filter_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781) ucontrol->value.enumerated.item[0] = spec->ae5_filter_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) static int ae5_sound_filter_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790) int sel = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) unsigned int items = AE5_SOUND_FILTER_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) if (sel >= items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796) codec_dbg(codec, "ae5_sound_filter: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) ae5_filter_presets[sel].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799) spec->ae5_filter_val = sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) ca0113_mmio_command_set_type2(codec, 0x48, 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802) ae5_filter_presets[sel].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) * Input Select Control for alternative ca0132 codecs. This exists because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809) * front microphone has no auto-detect, and we need a way to set the rear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810) * as line-in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812) static int ca0132_alt_input_source_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817) uinfo->value.enumerated.items = IN_SRC_NUM_OF_INPUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) if (uinfo->value.enumerated.item >= IN_SRC_NUM_OF_INPUTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) uinfo->value.enumerated.item = IN_SRC_NUM_OF_INPUTS - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) strcpy(uinfo->value.enumerated.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821) in_src_str[uinfo->value.enumerated.item]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) static int ca0132_alt_input_source_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831) ucontrol->value.enumerated.item[0] = spec->in_enum_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) static int ca0132_alt_input_source_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) int sel = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) unsigned int items = IN_SRC_NUM_OF_INPUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) * The AE-7 has no front microphone, so limit items to 2: rear mic and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) * line-in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847) if (ca0132_quirk(spec) == QUIRK_AE7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) items = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) if (sel >= items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853) codec_dbg(codec, "ca0132_alt_input_select: sel=%d, preset=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854) sel, in_src_str[sel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) spec->in_enum_val = sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858) ca0132_alt_select_in(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863) /* Sound Blaster Z Output Select Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864) static int ca0132_alt_output_select_get_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867) uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869) uinfo->value.enumerated.items = NUM_OF_OUTPUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870) if (uinfo->value.enumerated.item >= NUM_OF_OUTPUTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871) uinfo->value.enumerated.item = NUM_OF_OUTPUTS - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) strcpy(uinfo->value.enumerated.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) out_type_str[uinfo->value.enumerated.item]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) static int ca0132_alt_output_select_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) ucontrol->value.enumerated.item[0] = spec->out_enum_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887) static int ca0132_alt_output_select_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892) int sel = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) unsigned int items = NUM_OF_OUTPUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894) unsigned int auto_jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) if (sel >= items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899) codec_dbg(codec, "ca0132_alt_output_select: sel=%d, preset=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900) sel, out_type_str[sel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902) spec->out_enum_val = sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) auto_jack = spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) if (!auto_jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907) ca0132_alt_select_out(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912) /* Select surround output type: 2.1, 4.0, 4.1, or 5.1. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) static int ca0132_alt_speaker_channel_cfg_get_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916) unsigned int items = SPEAKER_CHANNEL_CFG_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920) uinfo->value.enumerated.items = items;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921) if (uinfo->value.enumerated.item >= items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) uinfo->value.enumerated.item = items - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923) strcpy(uinfo->value.enumerated.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) speaker_channel_cfgs[uinfo->value.enumerated.item].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928) static int ca0132_alt_speaker_channel_cfg_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) ucontrol->value.enumerated.item[0] = spec->channel_cfg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) static int ca0132_alt_speaker_channel_cfg_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943) int sel = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) unsigned int items = SPEAKER_CHANNEL_CFG_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) if (sel >= items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) codec_dbg(codec, "ca0132_alt_speaker_channels: sel=%d, channels=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) sel, speaker_channel_cfgs[sel].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952) spec->channel_cfg_val = sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954) if (spec->out_enum_val == SPEAKER_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955) ca0132_alt_select_out(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) * Smart Volume output setting control. Three different settings, Normal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962) * which takes the value from the smart volume slider. The two others, loud
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963) * and night, disregard the slider value and have uneditable values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) #define NUM_OF_SVM_SETTINGS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) static const char *const out_svm_set_enum_str[3] = {"Normal", "Loud", "Night" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) static int ca0132_alt_svm_setting_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971) uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973) uinfo->value.enumerated.items = NUM_OF_SVM_SETTINGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) if (uinfo->value.enumerated.item >= NUM_OF_SVM_SETTINGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975) uinfo->value.enumerated.item = NUM_OF_SVM_SETTINGS - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976) strcpy(uinfo->value.enumerated.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) out_svm_set_enum_str[uinfo->value.enumerated.item]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) static int ca0132_alt_svm_setting_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) ucontrol->value.enumerated.item[0] = spec->smart_volume_setting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) static int ca0132_alt_svm_setting_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996) int sel = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) unsigned int items = NUM_OF_SVM_SETTINGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998) unsigned int idx = SMART_VOLUME - EFFECT_START_NID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001) if (sel >= items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004) codec_dbg(codec, "ca0132_alt_svm_setting: sel=%d, preset=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) sel, out_svm_set_enum_str[sel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007) spec->smart_volume_setting = sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009) switch (sel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6015) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017) tmp = FLOAT_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023) /* Req 2 is the Smart Volume Setting req. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024) dspio_set_uint_param(codec, ca0132_effects[idx].mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025) ca0132_effects[idx].reqs[2], tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029) /* Sound Blaster Z EQ preset controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030) static int ca0132_alt_eq_preset_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033) unsigned int items = ARRAY_SIZE(ca0132_alt_eq_presets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035) uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037) uinfo->value.enumerated.items = items;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038) if (uinfo->value.enumerated.item >= items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039) uinfo->value.enumerated.item = items - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) strcpy(uinfo->value.enumerated.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041) ca0132_alt_eq_presets[uinfo->value.enumerated.item].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045) static int ca0132_alt_eq_preset_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051) ucontrol->value.enumerated.item[0] = spec->eq_preset_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055) static int ca0132_alt_eq_preset_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060) int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061) int sel = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) unsigned int items = ARRAY_SIZE(ca0132_alt_eq_presets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064) if (sel >= items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) codec_dbg(codec, "%s: sel=%d, preset=%s\n", __func__, sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068) ca0132_alt_eq_presets[sel].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070) * Idx 0 is default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071) * Default needs to qualify with CrystalVoice state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073) for (i = 0; i < EQ_PRESET_MAX_PARAM_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074) err = dspio_set_uint_param(codec, ca0132_alt_eq_enum.mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) ca0132_alt_eq_enum.reqs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076) ca0132_alt_eq_presets[sel].vals[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) if (err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082) spec->eq_preset_val = sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087) static int ca0132_voicefx_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090) unsigned int items = ARRAY_SIZE(ca0132_voicefx_presets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092) uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094) uinfo->value.enumerated.items = items;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095) if (uinfo->value.enumerated.item >= items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096) uinfo->value.enumerated.item = items - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097) strcpy(uinfo->value.enumerated.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098) ca0132_voicefx_presets[uinfo->value.enumerated.item].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) static int ca0132_voicefx_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108) ucontrol->value.enumerated.item[0] = spec->voicefx_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112) static int ca0132_voicefx_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118) int sel = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) if (sel >= ARRAY_SIZE(ca0132_voicefx_presets))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123) codec_dbg(codec, "ca0132_voicefx_put: sel=%d, preset=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124) sel, ca0132_voicefx_presets[sel].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127) * Idx 0 is default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128) * Default needs to qualify with CrystalVoice state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130) for (i = 0; i < VOICEFX_MAX_PARAM_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131) err = dspio_set_uint_param(codec, ca0132_voicefx.mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) ca0132_voicefx.reqs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133) ca0132_voicefx_presets[sel].vals[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138) if (err >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139) spec->voicefx_val = sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140) /* enable voice fx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141) ca0132_voicefx_set(codec, (sel ? 1 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147) static int ca0132_switch_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) int ch = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) /* vnode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157) if ((nid >= VNODE_START_NID) && (nid < VNODE_END_NID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158) if (ch & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) *valp = spec->vnode_lswitch[nid - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160) valp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) if (ch & 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163) *valp = spec->vnode_rswitch[nid - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) valp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169) /* effects, include PE and CrystalVoice */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) if ((nid >= EFFECT_START_NID) && (nid < EFFECT_END_NID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171) *valp = spec->effects_switch[nid - EFFECT_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) /* mic boost */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176) if (nid == spec->input_pins[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) *valp = spec->cur_mic_boost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181) if (nid == ZXR_HEADPHONE_GAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182) *valp = spec->zxr_gain_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186) if (nid == SPEAKER_FULL_RANGE_FRONT || nid == SPEAKER_FULL_RANGE_REAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) *valp = spec->speaker_range_val[nid - SPEAKER_FULL_RANGE_FRONT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191) if (nid == BASS_REDIRECTION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) *valp = spec->bass_redirection_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199) static int ca0132_switch_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205) int ch = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) int changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209) codec_dbg(codec, "ca0132_switch_put: nid=0x%x, val=%ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210) nid, *valp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) snd_hda_power_up(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213) /* vnode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) if ((nid >= VNODE_START_NID) && (nid < VNODE_END_NID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215) if (ch & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216) spec->vnode_lswitch[nid - VNODE_START_NID] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6217) valp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6219) if (ch & 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6220) spec->vnode_rswitch[nid - VNODE_START_NID] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6221) valp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6223) changed = ca0132_vnode_switch_set(kcontrol, ucontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6224) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6227) /* PE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6228) if (nid == PLAY_ENHANCEMENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6229) spec->effects_switch[nid - EFFECT_START_NID] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6230) changed = ca0132_pe_switch_set(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6231) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6234) /* CrystalVoice */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6235) if (nid == CRYSTAL_VOICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6236) spec->effects_switch[nid - EFFECT_START_NID] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6237) changed = ca0132_cvoice_switch_set(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6238) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6241) /* out and in effects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6242) if (((nid >= OUT_EFFECT_START_NID) && (nid < OUT_EFFECT_END_NID)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6243) ((nid >= IN_EFFECT_START_NID) && (nid < IN_EFFECT_END_NID))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6244) spec->effects_switch[nid - EFFECT_START_NID] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6245) changed = ca0132_effects_set(codec, nid, *valp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6246) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6249) /* mic boost */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6250) if (nid == spec->input_pins[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6251) spec->cur_mic_boost = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6252) if (ca0132_use_alt_functions(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6253) if (spec->in_enum_val != REAR_LINE_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6254) changed = ca0132_mic_boost_set(codec, *valp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6255) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6256) /* Mic boost does not apply to Digital Mic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6257) if (spec->cur_mic_type != DIGITAL_MIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6258) changed = ca0132_mic_boost_set(codec, *valp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6261) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6264) if (nid == ZXR_HEADPHONE_GAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6265) spec->zxr_gain_set = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6266) if (spec->cur_out_type == HEADPHONE_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6267) changed = zxr_headphone_gain_set(codec, *valp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6268) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6269) changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6271) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6274) if (nid == SPEAKER_FULL_RANGE_FRONT || nid == SPEAKER_FULL_RANGE_REAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6275) spec->speaker_range_val[nid - SPEAKER_FULL_RANGE_FRONT] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6276) if (spec->cur_out_type == SPEAKER_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6277) ca0132_alt_set_full_range_speaker(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6279) changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6282) if (nid == BASS_REDIRECTION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6283) spec->bass_redirection_val = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6284) if (spec->cur_out_type == SPEAKER_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6285) ca0132_alt_surround_set_bass_redirection(codec, *valp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6287) changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6290) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6291) snd_hda_power_down(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6292) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6295) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6296) * Volume related
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6298) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6299) * Sets the internal DSP decibel level to match the DAC for output, and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6300) * ADC for input. Currently only the SBZ sets dsp capture volume level, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6301) * all alternative codecs set DSP playback volume.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6303) static void ca0132_alt_dsp_volume_put(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6305) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6306) unsigned int dsp_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6307) unsigned int lookup_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6309) if (nid == VNID_SPK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6310) dsp_dir = DSP_VOL_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6311) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6312) dsp_dir = DSP_VOL_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6314) lookup_val = spec->vnode_lvol[nid - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6316) dspio_set_uint_param(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6317) ca0132_alt_vol_ctls[dsp_dir].mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6318) ca0132_alt_vol_ctls[dsp_dir].reqs[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6319) float_vol_db_lookup[lookup_val]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6321) lookup_val = spec->vnode_rvol[nid - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6323) dspio_set_uint_param(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6324) ca0132_alt_vol_ctls[dsp_dir].mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6325) ca0132_alt_vol_ctls[dsp_dir].reqs[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6326) float_vol_db_lookup[lookup_val]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6328) dspio_set_uint_param(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6329) ca0132_alt_vol_ctls[dsp_dir].mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6330) ca0132_alt_vol_ctls[dsp_dir].reqs[2], FLOAT_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6333) static int ca0132_volume_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6334) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6336) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6337) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6338) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6339) int ch = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6340) int dir = get_amp_direction(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6341) unsigned long pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6342) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6344) switch (nid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6345) case VNID_SPK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6346) /* follow shared_out info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6347) nid = spec->shared_out_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6348) mutex_lock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6349) pval = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6350) kcontrol->private_value = HDA_COMPOSE_AMP_VAL(nid, ch, 0, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6351) err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6352) kcontrol->private_value = pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6353) mutex_unlock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6355) case VNID_MIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6356) /* follow shared_mic info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6357) nid = spec->shared_mic_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6358) mutex_lock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6359) pval = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6360) kcontrol->private_value = HDA_COMPOSE_AMP_VAL(nid, ch, 0, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6361) err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6362) kcontrol->private_value = pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6363) mutex_unlock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6365) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6366) err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6368) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6371) static int ca0132_volume_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6372) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6374) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6375) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6376) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6377) int ch = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6378) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6380) /* store the left and right volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6381) if (ch & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6382) *valp = spec->vnode_lvol[nid - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6383) valp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6385) if (ch & 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6386) *valp = spec->vnode_rvol[nid - VNODE_START_NID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6387) valp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6389) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6392) static int ca0132_volume_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6393) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6395) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6396) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6397) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6398) int ch = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6399) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6400) hda_nid_t shared_nid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6401) bool effective;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6402) int changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6404) /* store the left and right volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6405) if (ch & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6406) spec->vnode_lvol[nid - VNODE_START_NID] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6407) valp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6409) if (ch & 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6410) spec->vnode_rvol[nid - VNODE_START_NID] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6411) valp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6414) /* if effective conditions, then update hw immediately. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6415) effective = ca0132_is_vnode_effective(codec, nid, &shared_nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6416) if (effective) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6417) int dir = get_amp_direction(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6418) unsigned long pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6420) snd_hda_power_up(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6421) mutex_lock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6422) pval = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6423) kcontrol->private_value = HDA_COMPOSE_AMP_VAL(shared_nid, ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6424) 0, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6425) changed = snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6426) kcontrol->private_value = pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6427) mutex_unlock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6428) snd_hda_power_down(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6431) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6434) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6435) * This function is the same as the one above, because using an if statement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6436) * inside of the above volume control for the DSP volume would cause too much
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6437) * lag. This is a lot more smooth.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6438) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6439) static int ca0132_alt_volume_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6440) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6442) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6443) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6444) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6445) int ch = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6446) long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6447) hda_nid_t vnid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6448) int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6450) switch (nid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6451) case 0x02:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6452) vnid = VNID_SPK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6454) case 0x07:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6455) vnid = VNID_MIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6456) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6459) /* store the left and right volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6460) if (ch & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6461) spec->vnode_lvol[vnid - VNODE_START_NID] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6462) valp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6464) if (ch & 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6465) spec->vnode_rvol[vnid - VNODE_START_NID] = *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6466) valp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6469) snd_hda_power_up(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6470) ca0132_alt_dsp_volume_put(codec, vnid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6471) mutex_lock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6472) changed = snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6473) mutex_unlock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6474) snd_hda_power_down(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6476) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6479) static int ca0132_volume_tlv(struct snd_kcontrol *kcontrol, int op_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6480) unsigned int size, unsigned int __user *tlv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6482) struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6483) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6484) hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6485) int ch = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6486) int dir = get_amp_direction(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6487) unsigned long pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6488) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6490) switch (nid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6491) case VNID_SPK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6492) /* follow shared_out tlv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6493) nid = spec->shared_out_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6494) mutex_lock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6495) pval = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6496) kcontrol->private_value = HDA_COMPOSE_AMP_VAL(nid, ch, 0, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6497) err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6498) kcontrol->private_value = pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6499) mutex_unlock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6500) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6501) case VNID_MIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6502) /* follow shared_mic tlv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6503) nid = spec->shared_mic_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6504) mutex_lock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6505) pval = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6506) kcontrol->private_value = HDA_COMPOSE_AMP_VAL(nid, ch, 0, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6507) err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6508) kcontrol->private_value = pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6509) mutex_unlock(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6510) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6511) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6512) err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6514) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6517) /* Add volume slider control for effect level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6518) static int ca0132_alt_add_effect_slider(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6519) const char *pfx, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6521) char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6522) int type = dir ? HDA_INPUT : HDA_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6523) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6524) HDA_CODEC_VOLUME_MONO(namestr, nid, 1, 0, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6526) sprintf(namestr, "FX: %s %s Volume", pfx, dirstr[dir]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6528) knew.tlv.c = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6530) switch (nid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6531) case XBASS_XOVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6532) knew.info = ca0132_alt_xbass_xover_slider_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6533) knew.get = ca0132_alt_xbass_xover_slider_ctl_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6534) knew.put = ca0132_alt_xbass_xover_slider_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6535) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6536) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6537) knew.info = ca0132_alt_effect_slider_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6538) knew.get = ca0132_alt_slider_ctl_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6539) knew.put = ca0132_alt_effect_slider_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6540) knew.private_value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6541) HDA_COMPOSE_AMP_VAL(nid, 1, 0, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6542) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6545) return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6548) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6549) * Added FX: prefix for the alternative codecs, because otherwise the surround
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6550) * effect would conflict with the Surround sound volume control. Also seems more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6551) * clear as to what the switches do. Left alone for others.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6552) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6553) static int add_fx_switch(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6554) const char *pfx, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6556) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6557) char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6558) int type = dir ? HDA_INPUT : HDA_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6559) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6560) CA0132_CODEC_MUTE_MONO(namestr, nid, 1, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6561) /* If using alt_controls, add FX: prefix. But, don't add FX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6562) * prefix to OutFX or InFX enable controls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6563) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6564) if (ca0132_use_alt_controls(spec) && (nid <= IN_EFFECT_END_NID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6565) sprintf(namestr, "FX: %s %s Switch", pfx, dirstr[dir]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6566) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6567) sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6569) return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6572) static int add_voicefx(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6574) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6575) HDA_CODEC_MUTE_MONO(ca0132_voicefx.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6576) VOICEFX, 1, 0, HDA_INPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6577) knew.info = ca0132_voicefx_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6578) knew.get = ca0132_voicefx_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6579) knew.put = ca0132_voicefx_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6580) return snd_hda_ctl_add(codec, VOICEFX, snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6583) /* Create the EQ Preset control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6584) static int add_ca0132_alt_eq_presets(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6586) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6587) HDA_CODEC_MUTE_MONO(ca0132_alt_eq_enum.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6588) EQ_PRESET_ENUM, 1, 0, HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6589) knew.info = ca0132_alt_eq_preset_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6590) knew.get = ca0132_alt_eq_preset_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6591) knew.put = ca0132_alt_eq_preset_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6592) return snd_hda_ctl_add(codec, EQ_PRESET_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6593) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6596) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6597) * Add enumerated control for the three different settings of the smart volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6598) * output effect. Normal just uses the slider value, and loud and night are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6599) * their own things that ignore that value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6600) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6601) static int ca0132_alt_add_svm_enum(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6603) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6604) HDA_CODEC_MUTE_MONO("FX: Smart Volume Setting",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6605) SMART_VOLUME_ENUM, 1, 0, HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6606) knew.info = ca0132_alt_svm_setting_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6607) knew.get = ca0132_alt_svm_setting_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6608) knew.put = ca0132_alt_svm_setting_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6609) return snd_hda_ctl_add(codec, SMART_VOLUME_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6610) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6614) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6615) * Create an Output Select enumerated control for codecs with surround
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6616) * out capabilities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6617) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6618) static int ca0132_alt_add_output_enum(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6620) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6621) HDA_CODEC_MUTE_MONO("Output Select",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6622) OUTPUT_SOURCE_ENUM, 1, 0, HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6623) knew.info = ca0132_alt_output_select_get_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6624) knew.get = ca0132_alt_output_select_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6625) knew.put = ca0132_alt_output_select_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6626) return snd_hda_ctl_add(codec, OUTPUT_SOURCE_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6627) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6630) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6631) * Add a control for selecting channel count on speaker output. Setting this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6632) * allows the DSP to do bass redirection and channel upmixing on surround
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6633) * configurations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6634) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6635) static int ca0132_alt_add_speaker_channel_cfg_enum(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6637) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6638) HDA_CODEC_MUTE_MONO("Surround Channel Config",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6639) SPEAKER_CHANNEL_CFG_ENUM, 1, 0, HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6640) knew.info = ca0132_alt_speaker_channel_cfg_get_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6641) knew.get = ca0132_alt_speaker_channel_cfg_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6642) knew.put = ca0132_alt_speaker_channel_cfg_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6643) return snd_hda_ctl_add(codec, SPEAKER_CHANNEL_CFG_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6644) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6647) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6648) * Full range front stereo and rear surround switches. When these are set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6649) * full range, the lower frequencies from these channels are no longer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6650) * redirected to the LFE channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6651) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6652) static int ca0132_alt_add_front_full_range_switch(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6654) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6655) CA0132_CODEC_MUTE_MONO("Full-Range Front Speakers",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6656) SPEAKER_FULL_RANGE_FRONT, 1, HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6658) return snd_hda_ctl_add(codec, SPEAKER_FULL_RANGE_FRONT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6659) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6662) static int ca0132_alt_add_rear_full_range_switch(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6664) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6665) CA0132_CODEC_MUTE_MONO("Full-Range Rear Speakers",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6666) SPEAKER_FULL_RANGE_REAR, 1, HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6668) return snd_hda_ctl_add(codec, SPEAKER_FULL_RANGE_REAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6669) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6672) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6673) * Bass redirection redirects audio below the crossover frequency to the LFE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6674) * channel on speakers that are set as not being full-range. On configurations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6675) * without an LFE channel, it does nothing. Bass redirection seems to be the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6676) * replacement for X-Bass on configurations with an LFE channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6677) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6678) static int ca0132_alt_add_bass_redirection_crossover(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6680) const char *namestr = "Bass Redirection Crossover";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6681) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6682) HDA_CODEC_VOLUME_MONO(namestr, BASS_REDIRECTION_XOVER, 1, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6683) HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6685) knew.tlv.c = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6686) knew.info = ca0132_alt_xbass_xover_slider_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6687) knew.get = ca0132_alt_xbass_xover_slider_ctl_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6688) knew.put = ca0132_alt_xbass_xover_slider_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6690) return snd_hda_ctl_add(codec, BASS_REDIRECTION_XOVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6691) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6694) static int ca0132_alt_add_bass_redirection_switch(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6696) const char *namestr = "Bass Redirection";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6697) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6698) CA0132_CODEC_MUTE_MONO(namestr, BASS_REDIRECTION, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6699) HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6701) return snd_hda_ctl_add(codec, BASS_REDIRECTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6702) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6705) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6706) * Create an Input Source enumerated control for the alternate ca0132 codecs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6707) * because the front microphone has no auto-detect, and Line-in has to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6708) * somehow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6709) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6710) static int ca0132_alt_add_input_enum(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6712) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6713) HDA_CODEC_MUTE_MONO("Input Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6714) INPUT_SOURCE_ENUM, 1, 0, HDA_INPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6715) knew.info = ca0132_alt_input_source_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6716) knew.get = ca0132_alt_input_source_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6717) knew.put = ca0132_alt_input_source_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6718) return snd_hda_ctl_add(codec, INPUT_SOURCE_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6719) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6722) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6723) * Add mic boost enumerated control. Switches through 0dB to 30dB. This adds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6724) * more control than the original mic boost, which is either full 30dB or off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6725) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6726) static int ca0132_alt_add_mic_boost_enum(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6728) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6729) HDA_CODEC_MUTE_MONO("Mic Boost Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6730) MIC_BOOST_ENUM, 1, 0, HDA_INPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6731) knew.info = ca0132_alt_mic_boost_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6732) knew.get = ca0132_alt_mic_boost_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6733) knew.put = ca0132_alt_mic_boost_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6734) return snd_hda_ctl_add(codec, MIC_BOOST_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6735) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6739) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6740) * Add headphone gain enumerated control for the AE-5. This switches between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6741) * three modes, low, medium, and high. When non-headphone outputs are selected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6742) * it is automatically set to high. This is the same behavior as Windows.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6743) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6744) static int ae5_add_headphone_gain_enum(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6746) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6747) HDA_CODEC_MUTE_MONO("AE-5: Headphone Gain",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6748) AE5_HEADPHONE_GAIN_ENUM, 1, 0, HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6749) knew.info = ae5_headphone_gain_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6750) knew.get = ae5_headphone_gain_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6751) knew.put = ae5_headphone_gain_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6752) return snd_hda_ctl_add(codec, AE5_HEADPHONE_GAIN_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6753) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6756) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6757) * Add sound filter enumerated control for the AE-5. This adds three different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6758) * settings: Slow Roll Off, Minimum Phase, and Fast Roll Off. From what I've
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6759) * read into it, it changes the DAC's interpolation filter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6760) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6761) static int ae5_add_sound_filter_enum(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6763) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6764) HDA_CODEC_MUTE_MONO("AE-5: Sound Filter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6765) AE5_SOUND_FILTER_ENUM, 1, 0, HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6766) knew.info = ae5_sound_filter_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6767) knew.get = ae5_sound_filter_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6768) knew.put = ae5_sound_filter_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6769) return snd_hda_ctl_add(codec, AE5_SOUND_FILTER_ENUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6770) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6773) static int zxr_add_headphone_gain_switch(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6775) struct snd_kcontrol_new knew =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6776) CA0132_CODEC_MUTE_MONO("ZxR: 600 Ohm Gain",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6777) ZXR_HEADPHONE_GAIN, 1, HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6779) return snd_hda_ctl_add(codec, ZXR_HEADPHONE_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6780) snd_ctl_new1(&knew, codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6783) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6784) * Need to create follower controls for the alternate codecs that have surround
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6785) * capabilities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6786) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6787) static const char * const ca0132_alt_follower_pfxs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6788) "Front", "Surround", "Center", "LFE", NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6789) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6791) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6792) * Also need special channel map, because the default one is incorrect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6793) * I think this has to do with the pin for rear surround being 0x11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6794) * and the center/lfe being 0x10. Usually the pin order is the opposite.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6795) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6796) static const struct snd_pcm_chmap_elem ca0132_alt_chmaps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6797) { .channels = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6798) .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6799) { .channels = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6800) .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6801) SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6802) { .channels = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6803) .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6804) SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6805) SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6806) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6807) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6809) /* Add the correct chmap for streams with 6 channels. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6810) static void ca0132_alt_add_chmap_ctls(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6812) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6813) struct hda_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6815) list_for_each_entry(pcm, &codec->pcm_list_head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6816) struct hda_pcm_stream *hinfo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6817) &pcm->stream[SNDRV_PCM_STREAM_PLAYBACK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6818) struct snd_pcm_chmap *chmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6819) const struct snd_pcm_chmap_elem *elem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6821) elem = ca0132_alt_chmaps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6822) if (hinfo->channels_max == 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6823) err = snd_pcm_add_chmap_ctls(pcm->pcm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6824) SNDRV_PCM_STREAM_PLAYBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6825) elem, hinfo->channels_max, 0, &chmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6826) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6827) codec_dbg(codec, "snd_pcm_add_chmap_ctls failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6832) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6833) * When changing Node IDs for Mixer Controls below, make sure to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6834) * Node IDs in ca0132_config() as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6835) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6836) static const struct snd_kcontrol_new ca0132_mixer[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6837) CA0132_CODEC_VOL("Master Playback Volume", VNID_SPK, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6838) CA0132_CODEC_MUTE("Master Playback Switch", VNID_SPK, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6839) CA0132_CODEC_VOL("Capture Volume", VNID_MIC, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6840) CA0132_CODEC_MUTE("Capture Switch", VNID_MIC, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6841) HDA_CODEC_VOLUME("Analog-Mic2 Capture Volume", 0x08, 0, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6842) HDA_CODEC_MUTE("Analog-Mic2 Capture Switch", 0x08, 0, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6843) HDA_CODEC_VOLUME("What U Hear Capture Volume", 0x0a, 0, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6844) HDA_CODEC_MUTE("What U Hear Capture Switch", 0x0a, 0, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6845) CA0132_CODEC_MUTE_MONO("Mic1-Boost (30dB) Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6846) 0x12, 1, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6847) CA0132_CODEC_MUTE_MONO("HP/Speaker Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6848) VNID_HP_SEL, 1, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6849) CA0132_CODEC_MUTE_MONO("AMic1/DMic Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6850) VNID_AMIC1_SEL, 1, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6851) CA0132_CODEC_MUTE_MONO("HP/Speaker Auto Detect Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6852) VNID_HP_ASEL, 1, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6853) CA0132_CODEC_MUTE_MONO("AMic1/DMic Auto Detect Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6854) VNID_AMIC1_ASEL, 1, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6855) { } /* end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6856) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6858) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6859) * Desktop specific control mixer. Removes auto-detect for mic, and adds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6860) * surround controls. Also sets both the Front Playback and Capture Volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6861) * controls to alt so they set the DSP's decibel level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6862) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6863) static const struct snd_kcontrol_new desktop_mixer[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6864) CA0132_ALT_CODEC_VOL("Front Playback Volume", 0x02, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6865) CA0132_CODEC_MUTE("Front Playback Switch", VNID_SPK, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6866) HDA_CODEC_VOLUME("Surround Playback Volume", 0x04, 0, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6867) HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6868) HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x03, 1, 0, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6869) HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x03, 1, 0, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6870) HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x03, 2, 0, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6871) HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x03, 2, 0, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6872) CA0132_ALT_CODEC_VOL("Capture Volume", 0x07, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6873) CA0132_CODEC_MUTE("Capture Switch", VNID_MIC, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6874) HDA_CODEC_VOLUME("What U Hear Capture Volume", 0x0a, 0, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6875) HDA_CODEC_MUTE("What U Hear Capture Switch", 0x0a, 0, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6876) CA0132_CODEC_MUTE_MONO("HP/Speaker Auto Detect Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6877) VNID_HP_ASEL, 1, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6878) { } /* end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6879) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6881) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6882) * Same as the Sound Blaster Z, except doesn't use the alt volume for capture
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6883) * because it doesn't set decibel levels for the DSP for capture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6884) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6885) static const struct snd_kcontrol_new r3di_mixer[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6886) CA0132_ALT_CODEC_VOL("Front Playback Volume", 0x02, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6887) CA0132_CODEC_MUTE("Front Playback Switch", VNID_SPK, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6888) HDA_CODEC_VOLUME("Surround Playback Volume", 0x04, 0, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6889) HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6890) HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x03, 1, 0, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6891) HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x03, 1, 0, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6892) HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x03, 2, 0, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6893) HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x03, 2, 0, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6894) CA0132_CODEC_VOL("Capture Volume", VNID_MIC, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6895) CA0132_CODEC_MUTE("Capture Switch", VNID_MIC, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6896) HDA_CODEC_VOLUME("What U Hear Capture Volume", 0x0a, 0, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6897) HDA_CODEC_MUTE("What U Hear Capture Switch", 0x0a, 0, HDA_INPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6898) CA0132_CODEC_MUTE_MONO("HP/Speaker Auto Detect Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6899) VNID_HP_ASEL, 1, HDA_OUTPUT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6900) { } /* end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6901) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6903) static int ca0132_build_controls(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6905) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6906) int i, num_fx, num_sliders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6907) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6909) /* Add Mixer controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6910) for (i = 0; i < spec->num_mixers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6911) err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6912) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6913) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6915) /* Setup vmaster with surround followers for desktop ca0132 devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6916) if (ca0132_use_alt_functions(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6917) snd_hda_set_vmaster_tlv(codec, spec->dacs[0], HDA_OUTPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6918) spec->tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6919) snd_hda_add_vmaster(codec, "Master Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6920) spec->tlv, ca0132_alt_follower_pfxs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6921) "Playback Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6922) err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6923) NULL, ca0132_alt_follower_pfxs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6924) "Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6925) true, &spec->vmaster_mute.sw_kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6926) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6927) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6930) /* Add in and out effects controls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6931) * VoiceFX, PE and CrystalVoice are added separately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6932) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6933) num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6934) for (i = 0; i < num_fx; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6935) /* Desktop cards break if Echo Cancellation is used. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6936) if (ca0132_use_pci_mmio(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6937) if (i == (ECHO_CANCELLATION - IN_EFFECT_START_NID +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6938) OUT_EFFECTS_COUNT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6939) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6942) err = add_fx_switch(codec, ca0132_effects[i].nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6943) ca0132_effects[i].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6944) ca0132_effects[i].direct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6945) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6946) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6948) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6949) * If codec has use_alt_controls set to true, add effect level sliders,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6950) * EQ presets, and Smart Volume presets. Also, change names to add FX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6951) * prefix, and change PlayEnhancement and CrystalVoice to match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6952) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6953) if (ca0132_use_alt_controls(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6954) err = ca0132_alt_add_svm_enum(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6955) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6956) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6958) err = add_ca0132_alt_eq_presets(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6959) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6960) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6962) err = add_fx_switch(codec, PLAY_ENHANCEMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6963) "Enable OutFX", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6964) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6965) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6967) err = add_fx_switch(codec, CRYSTAL_VOICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6968) "Enable InFX", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6969) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6970) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6972) num_sliders = OUT_EFFECTS_COUNT - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6973) for (i = 0; i < num_sliders; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6974) err = ca0132_alt_add_effect_slider(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6975) ca0132_effects[i].nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6976) ca0132_effects[i].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6977) ca0132_effects[i].direct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6978) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6979) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6982) err = ca0132_alt_add_effect_slider(codec, XBASS_XOVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6983) "X-Bass Crossover", EFX_DIR_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6985) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6986) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6987) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6988) err = add_fx_switch(codec, PLAY_ENHANCEMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6989) "PlayEnhancement", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6990) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6991) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6993) err = add_fx_switch(codec, CRYSTAL_VOICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6994) "CrystalVoice", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6995) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6996) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6998) err = add_voicefx(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6999) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7000) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7002) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7003) * If the codec uses alt_functions, you need the enumerated controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7004) * to select the new outputs and inputs, plus add the new mic boost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7005) * setting control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7006) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7007) if (ca0132_use_alt_functions(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7008) err = ca0132_alt_add_output_enum(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7009) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7010) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7011) err = ca0132_alt_add_speaker_channel_cfg_enum(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7012) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7013) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7014) err = ca0132_alt_add_front_full_range_switch(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7015) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7016) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7017) err = ca0132_alt_add_rear_full_range_switch(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7018) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7019) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7020) err = ca0132_alt_add_bass_redirection_crossover(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7021) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7022) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7023) err = ca0132_alt_add_bass_redirection_switch(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7024) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7025) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7026) err = ca0132_alt_add_mic_boost_enum(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7027) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7028) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7029) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7030) * ZxR only has microphone input, there is no front panel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7031) * header on the card, and aux-in is handled by the DBPro board.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7032) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7033) if (ca0132_quirk(spec) != QUIRK_ZXR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7034) err = ca0132_alt_add_input_enum(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7035) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7036) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7040) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7041) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7042) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7043) err = ae5_add_headphone_gain_enum(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7044) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7045) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7046) err = ae5_add_sound_filter_enum(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7047) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7048) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7049) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7050) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7051) err = zxr_add_headphone_gain_switch(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7052) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7053) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7054) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7055) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7056) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7059) #ifdef ENABLE_TUNING_CONTROLS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7060) add_tuning_ctls(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7061) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7063) err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7064) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7065) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7067) if (spec->dig_out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7068) err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7069) spec->dig_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7070) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7071) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7072) err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7073) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7074) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7075) /* spec->multiout.share_spdif = 1; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7078) if (spec->dig_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7079) err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7080) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7081) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7084) if (ca0132_use_alt_functions(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7085) ca0132_alt_add_chmap_ctls(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7087) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7090) static int dbpro_build_controls(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7092) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7093) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7095) if (spec->dig_out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7096) err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7097) spec->dig_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7098) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7099) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7102) if (spec->dig_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7103) err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7104) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7105) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7108) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7112) * PCM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7114) static const struct hda_pcm_stream ca0132_pcm_analog_playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7115) .substreams = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7116) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7117) .channels_max = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7118) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7119) .prepare = ca0132_playback_pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7120) .cleanup = ca0132_playback_pcm_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7121) .get_delay = ca0132_playback_pcm_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7122) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7125) static const struct hda_pcm_stream ca0132_pcm_analog_capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7126) .substreams = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7127) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7128) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7129) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7130) .prepare = ca0132_capture_pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7131) .cleanup = ca0132_capture_pcm_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7132) .get_delay = ca0132_capture_pcm_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7133) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7136) static const struct hda_pcm_stream ca0132_pcm_digital_playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7137) .substreams = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7138) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7139) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7140) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7141) .open = ca0132_dig_playback_pcm_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7142) .close = ca0132_dig_playback_pcm_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7143) .prepare = ca0132_dig_playback_pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7144) .cleanup = ca0132_dig_playback_pcm_cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7145) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7148) static const struct hda_pcm_stream ca0132_pcm_digital_capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7149) .substreams = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7150) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7151) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7154) static int ca0132_build_pcms(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7156) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7157) struct hda_pcm *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7159) info = snd_hda_codec_pcm_new(codec, "CA0132 Analog");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7160) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7161) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7162) if (ca0132_use_alt_functions(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7163) info->own_chmap = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7164) info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7165) = ca0132_alt_chmaps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7167) info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0132_pcm_analog_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7168) info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7169) info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7170) spec->multiout.max_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7171) info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7172) info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7173) info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7175) /* With the DSP enabled, desktops don't use this ADC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7176) if (!ca0132_use_alt_functions(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7177) info = snd_hda_codec_pcm_new(codec, "CA0132 Analog Mic-In2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7178) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7179) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7180) info->stream[SNDRV_PCM_STREAM_CAPTURE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7181) ca0132_pcm_analog_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7182) info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7183) info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7186) info = snd_hda_codec_pcm_new(codec, "CA0132 What U Hear");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7187) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7188) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7189) info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7190) info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7191) info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7193) if (!spec->dig_out && !spec->dig_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7196) info = snd_hda_codec_pcm_new(codec, "CA0132 Digital");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7197) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7198) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7199) info->pcm_type = HDA_PCM_TYPE_SPDIF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7200) if (spec->dig_out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7201) info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7202) ca0132_pcm_digital_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7203) info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7205) if (spec->dig_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7206) info->stream[SNDRV_PCM_STREAM_CAPTURE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7207) ca0132_pcm_digital_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7208) info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7211) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7214) static int dbpro_build_pcms(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7216) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7217) struct hda_pcm *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7219) info = snd_hda_codec_pcm_new(codec, "CA0132 Alt Analog");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7220) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7221) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7222) info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7223) info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7224) info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7227) if (!spec->dig_out && !spec->dig_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7228) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7230) info = snd_hda_codec_pcm_new(codec, "CA0132 Digital");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7231) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7232) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7233) info->pcm_type = HDA_PCM_TYPE_SPDIF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7234) if (spec->dig_out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7235) info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7236) ca0132_pcm_digital_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7237) info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7239) if (spec->dig_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7240) info->stream[SNDRV_PCM_STREAM_CAPTURE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7241) ca0132_pcm_digital_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7242) info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7248) static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7250) if (pin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7251) snd_hda_set_pin_ctl(codec, pin, PIN_HP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7252) if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7253) snd_hda_codec_write(codec, pin, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7254) AC_VERB_SET_AMP_GAIN_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7255) AMP_OUT_UNMUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7257) if (dac && (get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7258) snd_hda_codec_write(codec, dac, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7259) AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7262) static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7264) if (pin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7265) snd_hda_set_pin_ctl(codec, pin, PIN_VREF80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7266) if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7267) snd_hda_codec_write(codec, pin, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7268) AC_VERB_SET_AMP_GAIN_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7269) AMP_IN_UNMUTE(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7271) if (adc && (get_wcaps(codec, adc) & AC_WCAP_IN_AMP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7272) snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7273) AMP_IN_UNMUTE(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7275) /* init to 0 dB and unmute. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7276) snd_hda_codec_amp_stereo(codec, adc, HDA_INPUT, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7277) HDA_AMP_VOLMASK, 0x5a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7278) snd_hda_codec_amp_stereo(codec, adc, HDA_INPUT, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7279) HDA_AMP_MUTE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7283) static void refresh_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7285) unsigned int caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7287) caps = snd_hda_param_read(codec, nid, dir == HDA_OUTPUT ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7288) AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7289) snd_hda_override_amp_caps(codec, nid, dir, caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7293) * Switch between Digital built-in mic and analog mic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7294) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7295) static void ca0132_set_dmic(struct hda_codec *codec, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7297) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7298) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7299) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7300) unsigned int oldval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7302) codec_dbg(codec, "ca0132_set_dmic: enable=%d\n", enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7304) oldval = stop_mic1(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7305) ca0132_set_vipsource(codec, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7306) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7307) /* set DMic input as 2-ch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7308) tmp = FLOAT_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7309) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7311) val = spec->dmic_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7312) val |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7313) snd_hda_codec_write(codec, spec->input_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7314) VENDOR_CHIPIO_DMIC_CTL_SET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7316) if (!(spec->dmic_ctl & 0x20))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7317) chipio_set_control_flag(codec, CONTROL_FLAG_DMIC, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7318) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7319) /* set AMic input as mono */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7320) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7321) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7323) val = spec->dmic_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7324) /* clear bit7 and bit5 to disable dmic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7325) val &= 0x5f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7326) snd_hda_codec_write(codec, spec->input_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7327) VENDOR_CHIPIO_DMIC_CTL_SET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7329) if (!(spec->dmic_ctl & 0x20))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7330) chipio_set_control_flag(codec, CONTROL_FLAG_DMIC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7332) ca0132_set_vipsource(codec, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7333) resume_mic1(codec, oldval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7337) * Initialization for Digital Mic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7338) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7339) static void ca0132_init_dmic(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7341) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7342) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7344) /* Setup Digital Mic here, but don't enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7345) * Enable based on jack detect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7348) /* MCLK uses MPIO1, set to enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7349) * Bit 2-0: MPIO select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7350) * Bit 3: set to disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7351) * Bit 7-4: reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7353) val = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7354) snd_hda_codec_write(codec, spec->input_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7355) VENDOR_CHIPIO_DMIC_MCLK_SET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7357) /* Data1 uses MPIO3. Data2 not use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7358) * Bit 2-0: Data1 MPIO select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7359) * Bit 3: set disable Data1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7360) * Bit 6-4: Data2 MPIO select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7361) * Bit 7: set disable Data2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7363) val = 0x83;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7364) snd_hda_codec_write(codec, spec->input_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7365) VENDOR_CHIPIO_DMIC_PIN_SET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7367) /* Use Ch-0 and Ch-1. Rate is 48K, mode 1. Disable DMic first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7368) * Bit 3-0: Channel mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7369) * Bit 4: set for 48KHz, clear for 32KHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7370) * Bit 5: mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7371) * Bit 6: set to select Data2, clear for Data1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7372) * Bit 7: set to enable DMic, clear for AMic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7373) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7374) if (ca0132_quirk(spec) == QUIRK_ALIENWARE_M17XR4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7375) val = 0x33;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7376) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7377) val = 0x23;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7378) /* keep a copy of dmic ctl val for enable/disable dmic purpuse */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7379) spec->dmic_ctl = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7380) snd_hda_codec_write(codec, spec->input_pins[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7381) VENDOR_CHIPIO_DMIC_CTL_SET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7384) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7385) * Initialization for Analog Mic 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7386) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7387) static void ca0132_init_analog_mic2(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7389) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7391) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7392) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7393) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7394) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7395) VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7396) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7397) VENDOR_CHIPIO_8051_DATA_WRITE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7398) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7399) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x2D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7400) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7401) VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7402) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7403) VENDOR_CHIPIO_8051_DATA_WRITE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7404) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7407) static void ca0132_refresh_widget_caps(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7409) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7410) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7412) codec_dbg(codec, "ca0132_refresh_widget_caps.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7413) snd_hda_codec_update_widgets(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7415) for (i = 0; i < spec->multiout.num_dacs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7416) refresh_amp_caps(codec, spec->dacs[i], HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7418) for (i = 0; i < spec->num_outputs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7419) refresh_amp_caps(codec, spec->out_pins[i], HDA_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7421) for (i = 0; i < spec->num_inputs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7422) refresh_amp_caps(codec, spec->adcs[i], HDA_INPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7423) refresh_amp_caps(codec, spec->input_pins[i], HDA_INPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7427) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7428) * Default speaker tuning values setup for alternative codecs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7429) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7430) static const unsigned int sbz_default_delay_values[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7431) /* Non-zero values are floating point 0.000198. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7432) 0x394f9e38, 0x394f9e38, 0x00000000, 0x00000000, 0x00000000, 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7433) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7435) static const unsigned int zxr_default_delay_values[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7436) /* Non-zero values are floating point 0.000220. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7437) 0x00000000, 0x00000000, 0x3966afcd, 0x3966afcd, 0x3966afcd, 0x3966afcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7438) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7440) static const unsigned int ae5_default_delay_values[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7441) /* Non-zero values are floating point 0.000100. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7442) 0x00000000, 0x00000000, 0x38d1b717, 0x38d1b717, 0x38d1b717, 0x38d1b717
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7443) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7445) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7446) * If we never change these, probably only need them on initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7448) static void ca0132_alt_init_speaker_tuning(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7450) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7451) unsigned int i, tmp, start_req, end_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7452) const unsigned int *values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7454) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7455) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7456) values = sbz_default_delay_values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7458) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7459) values = zxr_default_delay_values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7460) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7461) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7462) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7463) values = ae5_default_delay_values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7465) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7466) values = sbz_default_delay_values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7470) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7471) dspio_set_uint_param(codec, 0x96, SPEAKER_TUNING_ENABLE_CENTER_EQ, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7473) start_req = SPEAKER_TUNING_FRONT_LEFT_VOL_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7474) end_req = SPEAKER_TUNING_REAR_RIGHT_VOL_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7475) for (i = start_req; i < end_req + 1; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7476) dspio_set_uint_param(codec, 0x96, i, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7478) start_req = SPEAKER_TUNING_FRONT_LEFT_INVERT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7479) end_req = SPEAKER_TUNING_REAR_RIGHT_INVERT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7480) for (i = start_req; i < end_req + 1; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7481) dspio_set_uint_param(codec, 0x96, i, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7484) for (i = 0; i < 6; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7485) dspio_set_uint_param(codec, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7486) SPEAKER_TUNING_FRONT_LEFT_DELAY + i, values[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7489) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7490) * Creates a dummy stream to bind the output to. This seems to have to be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7491) * after changing the main outputs source and destination streams.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7492) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7493) static void ca0132_alt_create_dummy_stream(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7495) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7496) unsigned int stream_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7498) stream_format = snd_hdac_calc_stream_format(48000, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7499) SNDRV_PCM_FORMAT_S32_LE, 32, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7501) snd_hda_codec_setup_stream(codec, spec->dacs[0], spec->dsp_stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7502) 0, stream_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7504) snd_hda_codec_cleanup_stream(codec, spec->dacs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7507) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7508) * Initialize mic for non-chromebook ca0132 implementations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7509) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7510) static void ca0132_alt_init_analog_mics(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7512) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7513) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7515) /* Mic 1 Setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7516) chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7517) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7518) if (ca0132_quirk(spec) == QUIRK_R3DI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7519) chipio_set_conn_rate(codec, 0x0F, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7520) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7521) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7522) tmp = FLOAT_THREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7523) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7525) /* Mic 2 setup (not present on desktop cards) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7526) chipio_set_conn_rate(codec, MEM_CONNID_MICIN2, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7527) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT2, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7528) if (ca0132_quirk(spec) == QUIRK_R3DI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7529) chipio_set_conn_rate(codec, 0x0F, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7530) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7531) dspio_set_uint_param(codec, 0x80, 0x01, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7534) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7535) * Sets the source of stream 0x14 to connpointID 0x48, and the destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7536) * connpointID to 0x91. If this isn't done, the destination is 0x71, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7537) * you get no sound. I'm guessing this has to do with the Sound Blaster Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7538) * having an updated DAC, which changes the destination to that DAC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7539) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7540) static void sbz_connect_streams(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7542) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7544) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7546) codec_dbg(codec, "Connect Streams entered, mutex locked and loaded.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7548) chipio_set_stream_channels(codec, 0x0C, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7549) chipio_set_stream_control(codec, 0x0C, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7551) /* This value is 0x43 for 96khz, and 0x83 for 192khz. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7552) chipio_write_no_mutex(codec, 0x18a020, 0x00000043);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7554) /* Setup stream 0x14 with it's source and destination points */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7555) chipio_set_stream_source_dest(codec, 0x14, 0x48, 0x91);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7556) chipio_set_conn_rate_no_mutex(codec, 0x48, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7557) chipio_set_conn_rate_no_mutex(codec, 0x91, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7558) chipio_set_stream_channels(codec, 0x14, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7559) chipio_set_stream_control(codec, 0x14, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7561) codec_dbg(codec, "Connect Streams exited, mutex released.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7563) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7567) * Write data through ChipIO to setup proper stream destinations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7568) * Not sure how it exactly works, but it seems to direct data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7569) * to different destinations. Example is f8 to c0, e0 to c0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7570) * All I know is, if you don't set these, you get no sound.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7571) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7572) static void sbz_chipio_startup_data(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7574) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7576) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7577) codec_dbg(codec, "Startup Data entered, mutex locked and loaded.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7579) /* These control audio output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7580) chipio_write_no_mutex(codec, 0x190060, 0x0001f8c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7581) chipio_write_no_mutex(codec, 0x190064, 0x0001f9c1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7582) chipio_write_no_mutex(codec, 0x190068, 0x0001fac6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7583) chipio_write_no_mutex(codec, 0x19006c, 0x0001fbc7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7584) /* Signal to update I think */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7585) chipio_write_no_mutex(codec, 0x19042c, 0x00000001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7587) chipio_set_stream_channels(codec, 0x0C, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7588) chipio_set_stream_control(codec, 0x0C, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7589) /* No clue what these control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7590) if (ca0132_quirk(spec) == QUIRK_SBZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7591) chipio_write_no_mutex(codec, 0x190030, 0x0001e0c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7592) chipio_write_no_mutex(codec, 0x190034, 0x0001e1c1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7593) chipio_write_no_mutex(codec, 0x190038, 0x0001e4c2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7594) chipio_write_no_mutex(codec, 0x19003c, 0x0001e5c3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7595) chipio_write_no_mutex(codec, 0x190040, 0x0001e2c4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7596) chipio_write_no_mutex(codec, 0x190044, 0x0001e3c5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7597) chipio_write_no_mutex(codec, 0x190048, 0x0001e8c6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7598) chipio_write_no_mutex(codec, 0x19004c, 0x0001e9c7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7599) chipio_write_no_mutex(codec, 0x190050, 0x0001ecc8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7600) chipio_write_no_mutex(codec, 0x190054, 0x0001edc9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7601) chipio_write_no_mutex(codec, 0x190058, 0x0001eaca);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7602) chipio_write_no_mutex(codec, 0x19005c, 0x0001ebcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7603) } else if (ca0132_quirk(spec) == QUIRK_ZXR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7604) chipio_write_no_mutex(codec, 0x190038, 0x000140c2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7605) chipio_write_no_mutex(codec, 0x19003c, 0x000141c3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7606) chipio_write_no_mutex(codec, 0x190040, 0x000150c4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7607) chipio_write_no_mutex(codec, 0x190044, 0x000151c5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7608) chipio_write_no_mutex(codec, 0x190050, 0x000142c8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7609) chipio_write_no_mutex(codec, 0x190054, 0x000143c9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7610) chipio_write_no_mutex(codec, 0x190058, 0x000152ca);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7611) chipio_write_no_mutex(codec, 0x19005c, 0x000153cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7613) chipio_write_no_mutex(codec, 0x19042c, 0x00000001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7615) codec_dbg(codec, "Startup Data exited, mutex released.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7616) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7619) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7620) * Custom DSP SCP commands where the src value is 0x00 instead of 0x20. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7621) * done after the DSP is loaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7622) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7623) static void ca0132_alt_dsp_scp_startup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7625) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7626) unsigned int tmp, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7628) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7629) * Gotta run these twice, or else mic works inconsistently. Not clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7630) * why this is, but multiple tests have confirmed it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7631) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7632) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7633) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7634) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7635) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7636) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7637) tmp = 0x00000003;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7638) dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7639) tmp = 0x00000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7640) dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7641) tmp = 0x00000001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7642) dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7643) tmp = 0x00000004;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7644) dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7645) tmp = 0x00000005;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7646) dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7647) tmp = 0x00000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7648) dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7649) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7650) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7651) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7652) tmp = 0x00000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7653) dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7654) tmp = 0x00000001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7655) dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7656) tmp = 0x00000004;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7657) dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7658) tmp = 0x00000005;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7659) dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7660) tmp = 0x00000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7661) dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7663) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7664) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7666) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7670) static void ca0132_alt_dsp_initial_mic_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7672) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7673) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7675) chipio_set_stream_control(codec, 0x03, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7676) chipio_set_stream_control(codec, 0x04, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7678) chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7679) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7681) tmp = FLOAT_THREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7682) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7684) chipio_set_stream_control(codec, 0x03, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7685) chipio_set_stream_control(codec, 0x04, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7687) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7688) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7689) chipio_write(codec, 0x18b098, 0x0000000c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7690) chipio_write(codec, 0x18b09C, 0x0000000c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7691) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7692) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7693) chipio_write(codec, 0x18b098, 0x0000000c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7694) chipio_write(codec, 0x18b09c, 0x0000004c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7695) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7696) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7697) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7701) static void ae5_post_dsp_register_set(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7703) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7705) chipio_8051_write_direct(codec, 0x93, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7706) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7707) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7708) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7709) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7711) writeb(0xff, spec->mem_base + 0x304);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7712) writeb(0xff, spec->mem_base + 0x304);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7713) writeb(0xff, spec->mem_base + 0x304);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7714) writeb(0xff, spec->mem_base + 0x304);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7715) writeb(0x00, spec->mem_base + 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7716) writeb(0xff, spec->mem_base + 0x304);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7717) writeb(0x00, spec->mem_base + 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7718) writeb(0xff, spec->mem_base + 0x304);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7719) writeb(0x00, spec->mem_base + 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7720) writeb(0xff, spec->mem_base + 0x304);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7721) writeb(0x00, spec->mem_base + 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7722) writeb(0xff, spec->mem_base + 0x304);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7724) ca0113_mmio_command_set(codec, 0x30, 0x2b, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7725) ca0113_mmio_command_set(codec, 0x30, 0x2d, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7726) ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7729) static void ae5_post_dsp_param_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7731) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7732) * Param3 in the 8051's memory is represented by the ascii string 'mch'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7733) * which seems to be 'multichannel'. This is also mentioned in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7734) * AE-5's registry values in Windows.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7735) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7736) chipio_set_control_param(codec, 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7737) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7738) * I believe ASI is 'audio serial interface' and that it's used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7739) * change colors on the external LED strip connected to the AE-5.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7740) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7741) chipio_set_control_flag(codec, CONTROL_FLAG_ASI_96KHZ, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7743) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x724, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7744) chipio_set_control_param(codec, CONTROL_PARAM_ASI, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7746) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7747) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x92);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7748) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7749) VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0xfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7750) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7751) VENDOR_CHIPIO_8051_DATA_WRITE, 0x22);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7754) static void ae5_post_dsp_pll_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7756) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7757) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x41);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7758) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7759) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7761) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7762) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x45);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7763) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7764) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7766) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7767) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7768) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7769) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7771) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7772) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x43);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7773) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7774) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7776) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7777) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x51);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7778) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7779) VENDOR_CHIPIO_PLL_PMU_WRITE, 0x8d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7782) static void ae5_post_dsp_stream_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7784) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7786) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7788) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x725, 0x81);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7790) chipio_set_conn_rate_no_mutex(codec, 0x70, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7792) chipio_set_stream_channels(codec, 0x0C, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7793) chipio_set_stream_control(codec, 0x0C, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7795) chipio_set_stream_source_dest(codec, 0x5, 0x43, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7797) chipio_set_stream_source_dest(codec, 0x18, 0x9, 0xd0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7798) chipio_set_conn_rate_no_mutex(codec, 0xd0, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7799) chipio_set_stream_channels(codec, 0x18, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7800) chipio_set_stream_control(codec, 0x18, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7802) chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_ASI, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7804) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7805) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x43);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7806) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7807) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7809) ca0113_mmio_command_set(codec, 0x48, 0x01, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7811) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7814) static void ae5_post_dsp_startup_data(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7816) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7818) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7820) chipio_write_no_mutex(codec, 0x189000, 0x0001f101);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7821) chipio_write_no_mutex(codec, 0x189004, 0x0001f101);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7822) chipio_write_no_mutex(codec, 0x189024, 0x00014004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7823) chipio_write_no_mutex(codec, 0x189028, 0x0002000f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7825) ca0113_mmio_command_set(codec, 0x48, 0x0a, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7826) chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_ASI, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7827) ca0113_mmio_command_set(codec, 0x48, 0x0b, 0x12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7828) ca0113_mmio_command_set(codec, 0x48, 0x04, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7829) ca0113_mmio_command_set(codec, 0x48, 0x06, 0x48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7830) ca0113_mmio_command_set(codec, 0x48, 0x0a, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7831) ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7832) ca0113_mmio_command_set(codec, 0x48, 0x0f, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7833) ca0113_mmio_command_set(codec, 0x48, 0x10, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7834) ca0113_mmio_gpio_set(codec, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7835) ca0113_mmio_gpio_set(codec, 1, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7836) ca0113_mmio_command_set(codec, 0x48, 0x07, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7838) chipio_write_no_mutex(codec, 0x18b03c, 0x00000012);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7840) ca0113_mmio_command_set(codec, 0x48, 0x0f, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7841) ca0113_mmio_command_set(codec, 0x48, 0x10, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7843) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7846) static const unsigned int ae7_port_set_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7847) 0x0001e0c0, 0x0001e1c1, 0x0001e4c2, 0x0001e5c3, 0x0001e2c4, 0x0001e3c5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7848) 0x0001e8c6, 0x0001e9c7, 0x0001ecc8, 0x0001edc9, 0x0001eaca, 0x0001ebcb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7849) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7851) static void ae7_post_dsp_setup_ports(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7853) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7854) unsigned int i, count, addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7856) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7858) chipio_set_stream_channels(codec, 0x0c, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7859) chipio_set_stream_control(codec, 0x0c, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7861) count = ARRAY_SIZE(ae7_port_set_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7862) addr = 0x190030;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7863) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7864) chipio_write_no_mutex(codec, addr, ae7_port_set_data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7866) /* Addresses are incremented by 4-bytes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7867) addr += 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7870) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7871) * Port setting always ends with a write of 0x1 to address 0x19042c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7872) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7873) chipio_write_no_mutex(codec, 0x19042c, 0x00000001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7875) ca0113_mmio_command_set(codec, 0x30, 0x30, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7876) ca0113_mmio_command_set(codec, 0x48, 0x0d, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7877) ca0113_mmio_command_set(codec, 0x48, 0x17, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7878) ca0113_mmio_command_set(codec, 0x48, 0x19, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7879) ca0113_mmio_command_set(codec, 0x48, 0x11, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7880) ca0113_mmio_command_set(codec, 0x48, 0x12, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7881) ca0113_mmio_command_set(codec, 0x48, 0x13, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7882) ca0113_mmio_command_set(codec, 0x48, 0x14, 0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7884) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7887) static void ae7_post_dsp_asi_stream_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7889) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7891) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7893) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x725, 0x81);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7894) ca0113_mmio_command_set(codec, 0x30, 0x2b, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7896) chipio_set_conn_rate_no_mutex(codec, 0x70, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7897) chipio_set_stream_channels(codec, 0x0c, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7898) chipio_set_stream_control(codec, 0x0c, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7900) chipio_set_stream_source_dest(codec, 0x05, 0x43, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7901) chipio_set_stream_source_dest(codec, 0x18, 0x09, 0xd0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7903) chipio_set_conn_rate_no_mutex(codec, 0xd0, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7904) chipio_set_stream_channels(codec, 0x18, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7905) chipio_set_stream_control(codec, 0x18, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7907) chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_ASI, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7909) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7912) static void ae7_post_dsp_pll_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7914) static const unsigned int addr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7915) 0x41, 0x45, 0x40, 0x43, 0x51
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7916) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7917) static const unsigned int data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7918) 0xc8, 0xcc, 0xcb, 0xc7, 0x8d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7919) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7920) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7922) for (i = 0; i < ARRAY_SIZE(addr); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7923) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7924) VENDOR_CHIPIO_8051_ADDRESS_LOW, addr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7925) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7926) VENDOR_CHIPIO_PLL_PMU_WRITE, data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7930) static void ae7_post_dsp_asi_setup_ports(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7932) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7933) static const unsigned int target[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7934) 0x0b, 0x04, 0x06, 0x0a, 0x0c, 0x11, 0x12, 0x13, 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7935) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7936) static const unsigned int data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7937) 0x12, 0x00, 0x48, 0x05, 0x5f, 0xff, 0xff, 0xff, 0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7938) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7939) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7941) mutex_lock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7943) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7944) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x43);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7945) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7946) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7948) chipio_write_no_mutex(codec, 0x189000, 0x0001f101);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7949) chipio_write_no_mutex(codec, 0x189004, 0x0001f101);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7950) chipio_write_no_mutex(codec, 0x189024, 0x00014004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7951) chipio_write_no_mutex(codec, 0x189028, 0x0002000f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7953) ae7_post_dsp_pll_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7954) chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_ASI, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7956) for (i = 0; i < ARRAY_SIZE(target); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7957) ca0113_mmio_command_set(codec, 0x48, target[i], data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7959) ca0113_mmio_command_set_type2(codec, 0x48, 0x07, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7960) ca0113_mmio_command_set(codec, 0x48, 0x0f, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7961) ca0113_mmio_command_set(codec, 0x48, 0x10, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7963) chipio_set_stream_source_dest(codec, 0x21, 0x64, 0x56);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7964) chipio_set_stream_channels(codec, 0x21, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7965) chipio_set_conn_rate_no_mutex(codec, 0x56, SR_8_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7967) chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_NODE_ID, 0x09);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7968) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7969) * In the 8051's memory, this param is referred to as 'n2sid', which I
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7970) * believe is 'node to streamID'. It seems to be a way to assign a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7971) * stream to a given HDA node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7972) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7973) chipio_set_control_param_no_mutex(codec, 0x20, 0x21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7975) chipio_write_no_mutex(codec, 0x18b038, 0x00000088);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7977) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7978) * Now, at this point on Windows, an actual stream is setup and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7979) * seemingly sends data to the HDA node 0x09, which is the digital
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7980) * audio input node. This is left out here, because obviously I don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7981) * know what data is being sent. Interestingly, the AE-5 seems to go
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7982) * through the motions of getting here and never actually takes this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7983) * step, but the AE-7 does.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7984) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7986) ca0113_mmio_gpio_set(codec, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7987) ca0113_mmio_gpio_set(codec, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7989) ca0113_mmio_command_set_type2(codec, 0x48, 0x07, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7990) chipio_write_no_mutex(codec, 0x18b03c, 0x00000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7991) ca0113_mmio_command_set(codec, 0x48, 0x0f, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7992) ca0113_mmio_command_set(codec, 0x48, 0x10, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7994) chipio_set_stream_source_dest(codec, 0x05, 0x43, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7995) chipio_set_stream_source_dest(codec, 0x18, 0x09, 0xd0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7997) chipio_set_conn_rate_no_mutex(codec, 0xd0, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7998) chipio_set_stream_channels(codec, 0x18, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8000) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8001) * Runs again, this has been repeated a few times, but I'm just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8002) * following what the Windows driver does.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8003) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8004) ae7_post_dsp_pll_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8005) chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_ASI, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8007) mutex_unlock(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8010) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8011) * The Windows driver has commands that seem to setup ASI, which I believe to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8012) * be some sort of audio serial interface. My current speculation is that it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8013) * related to communicating with the new DAC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8014) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8015) static void ae7_post_dsp_asi_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8017) chipio_8051_write_direct(codec, 0x93, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8019) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8020) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8021) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8022) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8024) ca0113_mmio_command_set_type2(codec, 0x48, 0x07, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8025) ca0113_mmio_command_set(codec, 0x30, 0x2e, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8027) chipio_set_control_param(codec, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8028) chipio_set_control_flag(codec, CONTROL_FLAG_ASI_96KHZ, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8030) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x724, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8031) chipio_set_control_param(codec, CONTROL_PARAM_ASI, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8032) snd_hda_codec_write(codec, 0x17, 0, 0x794, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8034) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8035) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x92);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8036) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8037) VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0xfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8038) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8039) VENDOR_CHIPIO_8051_DATA_WRITE, 0x22);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8041) ae7_post_dsp_pll_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8042) ae7_post_dsp_asi_stream_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8044) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8045) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x43);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8046) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8047) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8049) ae7_post_dsp_asi_setup_ports(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8052) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8053) * Setup default parameters for DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8054) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8055) static void ca0132_setup_defaults(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8057) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8058) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8059) int num_fx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8060) int idx, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8062) if (spec->dsp_state != DSP_DOWNLOADED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8063) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8065) /* out, in effects + voicefx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8066) num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8067) for (idx = 0; idx < num_fx; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8068) for (i = 0; i <= ca0132_effects[idx].params; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8069) dspio_set_uint_param(codec, ca0132_effects[idx].mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8070) ca0132_effects[idx].reqs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8071) ca0132_effects[idx].def_vals[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8075) /*remove DSP headroom*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8076) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8077) dspio_set_uint_param(codec, 0x96, 0x3C, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8079) /*set speaker EQ bypass attenuation*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8080) dspio_set_uint_param(codec, 0x8f, 0x01, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8082) /* set AMic1 and AMic2 as mono mic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8083) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8084) dspio_set_uint_param(codec, 0x80, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8085) dspio_set_uint_param(codec, 0x80, 0x01, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8087) /* set AMic1 as CrystalVoice input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8088) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8089) dspio_set_uint_param(codec, 0x80, 0x05, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8091) /* set WUH source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8092) tmp = FLOAT_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8093) dspio_set_uint_param(codec, 0x31, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8096) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8097) * Setup default parameters for Recon3D/Recon3Di DSP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8098) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8100) static void r3d_setup_defaults(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8102) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8103) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8104) int num_fx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8105) int idx, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8107) if (spec->dsp_state != DSP_DOWNLOADED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8108) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8110) ca0132_alt_dsp_scp_startup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8111) ca0132_alt_init_analog_mics(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8113) /*remove DSP headroom*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8114) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8115) dspio_set_uint_param(codec, 0x96, 0x3C, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8117) /* set WUH source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8118) tmp = FLOAT_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8119) dspio_set_uint_param(codec, 0x31, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8120) chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8122) /* Set speaker source? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8123) dspio_set_uint_param(codec, 0x32, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8125) if (ca0132_quirk(spec) == QUIRK_R3DI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8126) r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8128) /* Disable mute on Center/LFE. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8129) if (ca0132_quirk(spec) == QUIRK_R3D) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8130) ca0113_mmio_gpio_set(codec, 2, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8131) ca0113_mmio_gpio_set(codec, 4, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8134) /* Setup effect defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8135) num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8136) for (idx = 0; idx < num_fx; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8137) for (i = 0; i <= ca0132_effects[idx].params; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8138) dspio_set_uint_param(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8139) ca0132_effects[idx].mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8140) ca0132_effects[idx].reqs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8141) ca0132_effects[idx].def_vals[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8146) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8147) * Setup default parameters for the Sound Blaster Z DSP. A lot more going on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8148) * than the Chromebook setup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8149) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8150) static void sbz_setup_defaults(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8152) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8153) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8154) int num_fx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8155) int idx, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8157) if (spec->dsp_state != DSP_DOWNLOADED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8158) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8160) ca0132_alt_dsp_scp_startup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8161) ca0132_alt_init_analog_mics(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8162) sbz_connect_streams(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8163) sbz_chipio_startup_data(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8165) chipio_set_stream_control(codec, 0x03, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8166) chipio_set_stream_control(codec, 0x04, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8169) * Sets internal input loopback to off, used to have a switch to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8170) * enable input loopback, but turned out to be way too buggy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8172) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8173) dspio_set_uint_param(codec, 0x37, 0x08, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8174) dspio_set_uint_param(codec, 0x37, 0x10, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8176) /*remove DSP headroom*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8177) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8178) dspio_set_uint_param(codec, 0x96, 0x3C, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8180) /* set WUH source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8181) tmp = FLOAT_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8182) dspio_set_uint_param(codec, 0x31, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8183) chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8185) /* Set speaker source? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8186) dspio_set_uint_param(codec, 0x32, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8188) ca0132_alt_dsp_initial_mic_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8190) /* out, in effects + voicefx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8191) num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8192) for (idx = 0; idx < num_fx; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8193) for (i = 0; i <= ca0132_effects[idx].params; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8194) dspio_set_uint_param(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8195) ca0132_effects[idx].mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8196) ca0132_effects[idx].reqs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8197) ca0132_effects[idx].def_vals[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8201) ca0132_alt_init_speaker_tuning(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8203) ca0132_alt_create_dummy_stream(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8207) * Setup default parameters for the Sound BlasterX AE-5 DSP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8209) static void ae5_setup_defaults(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8211) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8212) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8213) int num_fx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8214) int idx, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8216) if (spec->dsp_state != DSP_DOWNLOADED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8217) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8219) ca0132_alt_dsp_scp_startup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8220) ca0132_alt_init_analog_mics(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8221) chipio_set_stream_control(codec, 0x03, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8222) chipio_set_stream_control(codec, 0x04, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8224) /* New, unknown SCP req's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8225) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8226) dspio_set_uint_param(codec, 0x96, 0x29, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8227) dspio_set_uint_param(codec, 0x96, 0x2a, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8228) dspio_set_uint_param(codec, 0x80, 0x0d, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8229) dspio_set_uint_param(codec, 0x80, 0x0e, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8231) ca0113_mmio_command_set(codec, 0x30, 0x2e, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8232) ca0113_mmio_gpio_set(codec, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8233) ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8235) /* Internal loopback off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8236) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8237) dspio_set_uint_param(codec, 0x37, 0x08, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8238) dspio_set_uint_param(codec, 0x37, 0x10, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8240) /*remove DSP headroom*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8241) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8242) dspio_set_uint_param(codec, 0x96, 0x3C, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8244) /* set WUH source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8245) tmp = FLOAT_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8246) dspio_set_uint_param(codec, 0x31, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8247) chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8249) /* Set speaker source? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8250) dspio_set_uint_param(codec, 0x32, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8252) ca0132_alt_dsp_initial_mic_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8253) ae5_post_dsp_register_set(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8254) ae5_post_dsp_param_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8255) ae5_post_dsp_pll_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8256) ae5_post_dsp_stream_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8257) ae5_post_dsp_startup_data(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8259) /* out, in effects + voicefx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8260) num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8261) for (idx = 0; idx < num_fx; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8262) for (i = 0; i <= ca0132_effects[idx].params; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8263) dspio_set_uint_param(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8264) ca0132_effects[idx].mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8265) ca0132_effects[idx].reqs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8266) ca0132_effects[idx].def_vals[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8270) ca0132_alt_init_speaker_tuning(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8272) ca0132_alt_create_dummy_stream(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8276) * Setup default parameters for the Sound Blaster AE-7 DSP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8277) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8278) static void ae7_setup_defaults(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8280) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8281) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8282) int num_fx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8283) int idx, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8285) if (spec->dsp_state != DSP_DOWNLOADED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8286) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8288) ca0132_alt_dsp_scp_startup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8289) ca0132_alt_init_analog_mics(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8290) ae7_post_dsp_setup_ports(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8292) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8293) dspio_set_uint_param(codec, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8294) SPEAKER_TUNING_FRONT_LEFT_INVERT, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8295) dspio_set_uint_param(codec, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8296) SPEAKER_TUNING_FRONT_RIGHT_INVERT, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8298) ca0113_mmio_command_set(codec, 0x30, 0x2e, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8300) /* New, unknown SCP req's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8301) dspio_set_uint_param(codec, 0x80, 0x0d, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8302) dspio_set_uint_param(codec, 0x80, 0x0e, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8304) ca0113_mmio_gpio_set(codec, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8306) /* Internal loopback off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8307) tmp = FLOAT_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8308) dspio_set_uint_param(codec, 0x37, 0x08, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8309) dspio_set_uint_param(codec, 0x37, 0x10, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8311) /*remove DSP headroom*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8312) tmp = FLOAT_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8313) dspio_set_uint_param(codec, 0x96, 0x3C, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8315) /* set WUH source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8316) tmp = FLOAT_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8317) dspio_set_uint_param(codec, 0x31, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8318) chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8320) /* Set speaker source? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8321) dspio_set_uint_param(codec, 0x32, 0x00, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8322) ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8324) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8325) * This is the second time we've called this, but this is seemingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8326) * what Windows does.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8328) ca0132_alt_init_analog_mics(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8330) ae7_post_dsp_asi_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8333) * Not sure why, but these are both set to 1. They're only set to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8334) * upon shutdown.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8335) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8336) ca0113_mmio_gpio_set(codec, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8337) ca0113_mmio_gpio_set(codec, 1, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8339) /* Volume control related. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8340) ca0113_mmio_command_set(codec, 0x48, 0x0f, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8341) ca0113_mmio_command_set(codec, 0x48, 0x10, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8342) ca0113_mmio_command_set_type2(codec, 0x48, 0x07, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8344) /* out, in effects + voicefx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8345) num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8346) for (idx = 0; idx < num_fx; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8347) for (i = 0; i <= ca0132_effects[idx].params; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8348) dspio_set_uint_param(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8349) ca0132_effects[idx].mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8350) ca0132_effects[idx].reqs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8351) ca0132_effects[idx].def_vals[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8355) ca0132_alt_init_speaker_tuning(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8357) ca0132_alt_create_dummy_stream(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8361) * Initialization of flags in chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8363) static void ca0132_init_flags(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8365) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8367) if (ca0132_use_alt_functions(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8368) chipio_set_control_flag(codec, CONTROL_FLAG_DSP_96KHZ, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8369) chipio_set_control_flag(codec, CONTROL_FLAG_DAC_96KHZ, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8370) chipio_set_control_flag(codec, CONTROL_FLAG_ADC_B_96KHZ, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8371) chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_96KHZ, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8372) chipio_set_control_flag(codec, CONTROL_FLAG_SRC_RATE_96KHZ, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8373) chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8374) chipio_set_control_flag(codec, CONTROL_FLAG_SPDIF2OUT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8375) chipio_set_control_flag(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8376) CONTROL_FLAG_PORT_D_10KOHM_LOAD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8377) chipio_set_control_flag(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8378) CONTROL_FLAG_PORT_A_10KOHM_LOAD, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8379) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8380) chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8381) chipio_set_control_flag(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8382) CONTROL_FLAG_PORT_A_COMMON_MODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8383) chipio_set_control_flag(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8384) CONTROL_FLAG_PORT_D_COMMON_MODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8385) chipio_set_control_flag(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8386) CONTROL_FLAG_PORT_A_10KOHM_LOAD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8387) chipio_set_control_flag(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8388) CONTROL_FLAG_PORT_D_10KOHM_LOAD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8389) chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_HIGH_PASS, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8393) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8394) * Initialization of parameters in chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8395) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8396) static void ca0132_init_params(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8398) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8400) if (ca0132_use_alt_functions(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8401) chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8402) chipio_set_conn_rate(codec, 0x0B, SR_48_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8403) chipio_set_control_param(codec, CONTROL_PARAM_SPDIF1_SOURCE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8404) chipio_set_control_param(codec, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8405) chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8408) chipio_set_control_param(codec, CONTROL_PARAM_PORTA_160OHM_GAIN, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8409) chipio_set_control_param(codec, CONTROL_PARAM_PORTD_160OHM_GAIN, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8412) static void ca0132_set_dsp_msr(struct hda_codec *codec, bool is96k)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8414) chipio_set_control_flag(codec, CONTROL_FLAG_DSP_96KHZ, is96k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8415) chipio_set_control_flag(codec, CONTROL_FLAG_DAC_96KHZ, is96k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8416) chipio_set_control_flag(codec, CONTROL_FLAG_SRC_RATE_96KHZ, is96k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8417) chipio_set_control_flag(codec, CONTROL_FLAG_SRC_CLOCK_196MHZ, is96k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8418) chipio_set_control_flag(codec, CONTROL_FLAG_ADC_B_96KHZ, is96k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8419) chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_96KHZ, is96k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8421) chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8422) chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8423) chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8426) static bool ca0132_download_dsp_images(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8428) bool dsp_loaded = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8429) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8430) const struct dsp_image_seg *dsp_os_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8431) const struct firmware *fw_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8433) * Alternate firmwares for different variants. The Recon3Di apparently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8434) * can use the default firmware, but I'll leave the option in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8435) * it needs it again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8436) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8437) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8438) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8439) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8440) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8441) if (request_firmware(&fw_entry, DESKTOP_EFX_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8442) codec->card->dev) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8443) codec_dbg(codec, "Desktop firmware not found.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8444) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8445) codec_dbg(codec, "Desktop firmware selected.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8447) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8448) if (request_firmware(&fw_entry, R3DI_EFX_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8449) codec->card->dev) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8450) codec_dbg(codec, "Recon3Di alt firmware not detected.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8451) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8452) codec_dbg(codec, "Recon3Di firmware selected.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8454) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8455) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8457) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8458) * Use default ctefx.bin if no alt firmware is detected, or if none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8459) * exists for your particular codec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8461) if (!fw_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8462) codec_dbg(codec, "Default firmware selected.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8463) if (request_firmware(&fw_entry, EFX_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8464) codec->card->dev) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8465) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8468) dsp_os_image = (struct dsp_image_seg *)(fw_entry->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8469) if (dspload_image(codec, dsp_os_image, 0, 0, true, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8470) codec_err(codec, "ca0132 DSP load image failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8471) goto exit_download;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8474) dsp_loaded = dspload_wait_loaded(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8476) exit_download:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8477) release_firmware(fw_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8479) return dsp_loaded;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8482) static void ca0132_download_dsp(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8484) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8486) #ifndef CONFIG_SND_HDA_CODEC_CA0132_DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8487) return; /* NOP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8488) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8490) if (spec->dsp_state == DSP_DOWNLOAD_FAILED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8491) return; /* don't retry failures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8493) chipio_enable_clocks(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8494) if (spec->dsp_state != DSP_DOWNLOADED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8495) spec->dsp_state = DSP_DOWNLOADING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8497) if (!ca0132_download_dsp_images(codec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8498) spec->dsp_state = DSP_DOWNLOAD_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8499) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8500) spec->dsp_state = DSP_DOWNLOADED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8503) /* For codecs using alt functions, this is already done earlier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8504) if (spec->dsp_state == DSP_DOWNLOADED && !ca0132_use_alt_functions(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8505) ca0132_set_dsp_msr(codec, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8508) static void ca0132_process_dsp_response(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8509) struct hda_jack_callback *callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8511) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8513) codec_dbg(codec, "ca0132_process_dsp_response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8514) snd_hda_power_up_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8515) if (spec->wait_scp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8516) if (dspio_get_response_data(codec) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8517) spec->wait_scp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8520) dspio_clear_response_queue(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8521) snd_hda_power_down_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8524) static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8526) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8527) struct hda_jack_tbl *tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8529) /* Delay enabling the HP amp, to let the mic-detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8530) * state machine run.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8531) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8532) tbl = snd_hda_jack_tbl_get(codec, cb->nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8533) if (tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8534) tbl->block_report = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8535) schedule_delayed_work(&spec->unsol_hp_work, msecs_to_jiffies(500));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8538) static void amic_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8540) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8542) if (ca0132_use_alt_functions(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8543) ca0132_alt_select_in(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8544) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8545) ca0132_select_mic(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8548) static void ca0132_init_unsol(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8550) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8551) snd_hda_jack_detect_enable_callback(codec, spec->unsol_tag_hp, hp_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8552) snd_hda_jack_detect_enable_callback(codec, spec->unsol_tag_amic1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8553) amic_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8554) snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_DSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8555) ca0132_process_dsp_response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8556) /* Front headphone jack detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8557) if (ca0132_use_alt_functions(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8558) snd_hda_jack_detect_enable_callback(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8559) spec->unsol_tag_front_hp, hp_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8562) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8563) * Verbs tables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8564) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8566) /* Sends before DSP download. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8567) static const struct hda_verb ca0132_base_init_verbs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8568) /*enable ct extension*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8569) {0x15, VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8570) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8571) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8573) /* Send at exit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8574) static const struct hda_verb ca0132_base_exit_verbs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8575) /*set afg to D3*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8576) {0x01, AC_VERB_SET_POWER_STATE, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8577) /*disable ct extension*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8578) {0x15, VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8579) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8580) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8582) /* Other verbs tables. Sends after DSP download. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8584) static const struct hda_verb ca0132_init_verbs0[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8585) /* chip init verbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8586) {0x15, 0x70D, 0xF0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8587) {0x15, 0x70E, 0xFE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8588) {0x15, 0x707, 0x75},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8589) {0x15, 0x707, 0xD3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8590) {0x15, 0x707, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8591) {0x15, 0x707, 0x53},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8592) {0x15, 0x707, 0xD4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8593) {0x15, 0x707, 0xEF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8594) {0x15, 0x707, 0x75},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8595) {0x15, 0x707, 0xD3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8596) {0x15, 0x707, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8597) {0x15, 0x707, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8598) {0x15, 0x707, 0x37},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8599) {0x15, 0x707, 0x78},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8600) {0x15, 0x53C, 0xCE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8601) {0x15, 0x575, 0xC9},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8602) {0x15, 0x53D, 0xCE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8603) {0x15, 0x5B7, 0xC9},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8604) {0x15, 0x70D, 0xE8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8605) {0x15, 0x70E, 0xFE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8606) {0x15, 0x707, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8607) {0x15, 0x707, 0x68},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8608) {0x15, 0x707, 0x62},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8609) {0x15, 0x53A, 0xCE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8610) {0x15, 0x546, 0xC9},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8611) {0x15, 0x53B, 0xCE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8612) {0x15, 0x5E8, 0xC9},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8613) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8614) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8616) /* Extra init verbs for desktop cards. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8617) static const struct hda_verb ca0132_init_verbs1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8618) {0x15, 0x70D, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8619) {0x15, 0x70E, 0x19},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8620) {0x15, 0x707, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8621) {0x15, 0x539, 0xCE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8622) {0x15, 0x546, 0xC9},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8623) {0x15, 0x70D, 0xB7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8624) {0x15, 0x70E, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8625) {0x15, 0x707, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8626) {0x15, 0x70D, 0xAF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8627) {0x15, 0x70E, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8628) {0x15, 0x707, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8629) {0x15, 0x707, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8630) {0x15, 0x70D, 0x73},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8631) {0x15, 0x70E, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8632) {0x15, 0x707, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8633) {0x15, 0x6FF, 0xC4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8634) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8635) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8637) static void ca0132_init_chip(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8639) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8640) int num_fx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8641) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8642) unsigned int on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8644) mutex_init(&spec->chipio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8646) spec->cur_out_type = SPEAKER_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8647) if (!ca0132_use_alt_functions(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8648) spec->cur_mic_type = DIGITAL_MIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8649) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8650) spec->cur_mic_type = REAR_MIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8652) spec->cur_mic_boost = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8654) for (i = 0; i < VNODES_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8655) spec->vnode_lvol[i] = 0x5a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8656) spec->vnode_rvol[i] = 0x5a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8657) spec->vnode_lswitch[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8658) spec->vnode_rswitch[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8661) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8662) * Default states for effects are in ca0132_effects[].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8664) num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8665) for (i = 0; i < num_fx; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8666) on = (unsigned int)ca0132_effects[i].reqs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8667) spec->effects_switch[i] = on ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8669) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8670) * Sets defaults for the effect slider controls, only for alternative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8671) * ca0132 codecs. Also sets x-bass crossover frequency to 80hz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8672) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8673) if (ca0132_use_alt_controls(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8674) /* Set speakers to default to full range. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8675) spec->speaker_range_val[0] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8676) spec->speaker_range_val[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8678) spec->xbass_xover_freq = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8679) for (i = 0; i < EFFECT_LEVEL_SLIDERS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8680) spec->fx_ctl_val[i] = effect_slider_defaults[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8682) spec->bass_redirect_xover_freq = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8685) spec->voicefx_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8686) spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8687) spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8689) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8690) * The ZxR doesn't have a front panel header, and it's line-in is on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8691) * the daughter board. So, there is no input enum control, and we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8692) * to make sure that spec->in_enum_val is set properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8693) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8694) if (ca0132_quirk(spec) == QUIRK_ZXR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8695) spec->in_enum_val = REAR_MIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8697) #ifdef ENABLE_TUNING_CONTROLS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8698) ca0132_init_tuning_defaults(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8699) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8702) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8703) * Recon3Di exit specific commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8704) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8705) /* prevents popping noise on shutdown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8706) static void r3di_gpio_shutdown(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8708) snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8711) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8712) * Sound Blaster Z exit specific commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8713) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8714) static void sbz_region2_exit(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8716) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8717) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8719) for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8720) writeb(0x0, spec->mem_base + 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8721) for (i = 0; i < 8; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8722) writeb(0xb3, spec->mem_base + 0x304);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8724) ca0113_mmio_gpio_set(codec, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8725) ca0113_mmio_gpio_set(codec, 1, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8726) ca0113_mmio_gpio_set(codec, 4, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8727) ca0113_mmio_gpio_set(codec, 5, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8728) ca0113_mmio_gpio_set(codec, 7, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8731) static void sbz_set_pin_ctl_default(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8733) static const hda_nid_t pins[] = {0x0B, 0x0C, 0x0E, 0x12, 0x13};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8734) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8736) snd_hda_codec_write(codec, 0x11, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8737) AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8739) for (i = 0; i < ARRAY_SIZE(pins); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8740) snd_hda_codec_write(codec, pins[i], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8741) AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8744) static void ca0132_clear_unsolicited(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8746) static const hda_nid_t pins[] = {0x0B, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8747) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8749) for (i = 0; i < ARRAY_SIZE(pins); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8750) snd_hda_codec_write(codec, pins[i], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8751) AC_VERB_SET_UNSOLICITED_ENABLE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8755) /* On shutdown, sends commands in sets of three */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8756) static void sbz_gpio_shutdown_commands(struct hda_codec *codec, int dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8757) int mask, int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8759) if (dir >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8760) snd_hda_codec_write(codec, 0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8761) AC_VERB_SET_GPIO_DIRECTION, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8762) if (mask >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8763) snd_hda_codec_write(codec, 0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8764) AC_VERB_SET_GPIO_MASK, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8766) if (data >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8767) snd_hda_codec_write(codec, 0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8768) AC_VERB_SET_GPIO_DATA, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8771) static void zxr_dbpro_power_state_shutdown(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8773) static const hda_nid_t pins[] = {0x05, 0x0c, 0x09, 0x0e, 0x08, 0x11, 0x01};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8774) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8776) for (i = 0; i < ARRAY_SIZE(pins); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8777) snd_hda_codec_write(codec, pins[i], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8778) AC_VERB_SET_POWER_STATE, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8781) static void sbz_exit_chip(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8783) chipio_set_stream_control(codec, 0x03, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8784) chipio_set_stream_control(codec, 0x04, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8786) /* Mess with GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8787) sbz_gpio_shutdown_commands(codec, 0x07, 0x07, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8788) sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8789) sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8791) chipio_set_stream_control(codec, 0x14, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8792) chipio_set_stream_control(codec, 0x0C, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8794) chipio_set_conn_rate(codec, 0x41, SR_192_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8795) chipio_set_conn_rate(codec, 0x91, SR_192_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8797) chipio_write(codec, 0x18a020, 0x00000083);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8799) sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8800) sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8801) sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8803) chipio_set_stream_control(codec, 0x0C, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8805) chipio_set_control_param(codec, 0x0D, 0x24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8807) ca0132_clear_unsolicited(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8808) sbz_set_pin_ctl_default(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8810) snd_hda_codec_write(codec, 0x0B, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8811) AC_VERB_SET_EAPD_BTLENABLE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8813) sbz_region2_exit(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8816) static void r3d_exit_chip(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8818) ca0132_clear_unsolicited(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8819) snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8820) snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x5b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8823) static void ae5_exit_chip(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8825) chipio_set_stream_control(codec, 0x03, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8826) chipio_set_stream_control(codec, 0x04, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8828) ca0113_mmio_command_set(codec, 0x30, 0x32, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8829) ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8830) ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8831) ca0113_mmio_command_set(codec, 0x30, 0x30, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8832) ca0113_mmio_command_set(codec, 0x30, 0x2b, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8833) ca0113_mmio_command_set(codec, 0x30, 0x2d, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8834) ca0113_mmio_gpio_set(codec, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8835) ca0113_mmio_gpio_set(codec, 1, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8837) snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8838) snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8840) chipio_set_control_param(codec, CONTROL_PARAM_ASI, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8842) chipio_set_stream_control(codec, 0x18, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8843) chipio_set_stream_control(codec, 0x0c, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8845) snd_hda_codec_write(codec, 0x01, 0, 0x724, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8848) static void ae7_exit_chip(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8850) chipio_set_stream_control(codec, 0x18, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8851) chipio_set_stream_source_dest(codec, 0x21, 0xc8, 0xc8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8852) chipio_set_stream_channels(codec, 0x21, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8853) chipio_set_control_param(codec, CONTROL_PARAM_NODE_ID, 0x09);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8854) chipio_set_control_param(codec, 0x20, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8856) chipio_set_control_param(codec, CONTROL_PARAM_ASI, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8858) chipio_set_stream_control(codec, 0x18, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8859) chipio_set_stream_control(codec, 0x0c, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8861) ca0113_mmio_command_set(codec, 0x30, 0x2b, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8862) snd_hda_codec_write(codec, 0x15, 0, 0x724, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8863) ca0113_mmio_command_set_type2(codec, 0x48, 0x07, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8864) ca0113_mmio_command_set(codec, 0x30, 0x30, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8865) ca0113_mmio_command_set(codec, 0x30, 0x2e, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8866) ca0113_mmio_gpio_set(codec, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8867) ca0113_mmio_gpio_set(codec, 1, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8868) ca0113_mmio_command_set(codec, 0x30, 0x32, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8870) snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8871) snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8874) static void zxr_exit_chip(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8876) chipio_set_stream_control(codec, 0x03, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8877) chipio_set_stream_control(codec, 0x04, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8878) chipio_set_stream_control(codec, 0x14, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8879) chipio_set_stream_control(codec, 0x0C, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8881) chipio_set_conn_rate(codec, 0x41, SR_192_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8882) chipio_set_conn_rate(codec, 0x91, SR_192_000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8884) chipio_write(codec, 0x18a020, 0x00000083);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8886) snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8887) snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8889) ca0132_clear_unsolicited(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8890) sbz_set_pin_ctl_default(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8891) snd_hda_codec_write(codec, 0x0B, 0, AC_VERB_SET_EAPD_BTLENABLE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8893) ca0113_mmio_gpio_set(codec, 5, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8894) ca0113_mmio_gpio_set(codec, 2, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8895) ca0113_mmio_gpio_set(codec, 3, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8896) ca0113_mmio_gpio_set(codec, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8897) ca0113_mmio_gpio_set(codec, 4, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8898) ca0113_mmio_gpio_set(codec, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8899) ca0113_mmio_gpio_set(codec, 5, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8900) ca0113_mmio_gpio_set(codec, 2, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8901) ca0113_mmio_gpio_set(codec, 3, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8904) static void ca0132_exit_chip(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8906) /* put any chip cleanup stuffs here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8908) if (dspload_is_loaded(codec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8909) dsp_reset(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8912) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8913) * This fixes a problem that was hard to reproduce. Very rarely, I would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8914) * boot up, and there would be no sound, but the DSP indicated it had loaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8915) * properly. I did a few memory dumps to see if anything was different, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8916) * there were a few areas of memory uninitialized with a1a2a3a4. This function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8917) * checks if those areas are uninitialized, and if they are, it'll attempt to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8918) * reload the card 3 times. Usually it fixes by the second.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8920) static void sbz_dsp_startup_check(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8922) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8923) unsigned int dsp_data_check[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8924) unsigned int cur_address = 0x390;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8925) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8926) unsigned int failure = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8927) unsigned int reload = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8929) if (spec->startup_check_entered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8930) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8932) spec->startup_check_entered = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8934) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8935) chipio_read(codec, cur_address, &dsp_data_check[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8936) cur_address += 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8938) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8939) if (dsp_data_check[i] == 0xa1a2a3a4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8940) failure = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8943) codec_dbg(codec, "Startup Check: %d ", failure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8944) if (failure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8945) codec_info(codec, "DSP not initialized properly. Attempting to fix.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8946) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8947) * While the failure condition is true, and we haven't reached our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8948) * three reload limit, continue trying to reload the driver and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8949) * fix the issue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8950) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8951) while (failure && (reload != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8952) codec_info(codec, "Reloading... Tries left: %d", reload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8953) sbz_exit_chip(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8954) spec->dsp_state = DSP_DOWNLOAD_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8955) codec->patch_ops.init(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8956) failure = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8957) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8958) chipio_read(codec, cur_address, &dsp_data_check[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8959) cur_address += 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8961) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8962) if (dsp_data_check[i] == 0xa1a2a3a4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8963) failure = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8965) reload--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8968) if (!failure && reload < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8969) codec_info(codec, "DSP fixed.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8971) if (!failure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8972) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8974) codec_info(codec, "DSP failed to initialize properly. Either try a full shutdown or a suspend to clear the internal memory.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8977) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8978) * This is for the extra volume verbs 0x797 (left) and 0x798 (right). These add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8979) * extra precision for decibel values. If you had the dB value in floating point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8980) * you would take the value after the decimal point, multiply by 64, and divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8981) * by 2. So for 8.59, it's (59 * 64) / 100. Useful if someone wanted to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8982) * implement fixed point or floating point dB volumes. For now, I'll set them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8983) * to 0 just incase a value has lingered from a boot into Windows.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8984) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8985) static void ca0132_alt_vol_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8987) snd_hda_codec_write(codec, 0x02, 0, 0x797, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8988) snd_hda_codec_write(codec, 0x02, 0, 0x798, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8989) snd_hda_codec_write(codec, 0x03, 0, 0x797, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8990) snd_hda_codec_write(codec, 0x03, 0, 0x798, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8991) snd_hda_codec_write(codec, 0x04, 0, 0x797, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8992) snd_hda_codec_write(codec, 0x04, 0, 0x798, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8993) snd_hda_codec_write(codec, 0x07, 0, 0x797, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8994) snd_hda_codec_write(codec, 0x07, 0, 0x798, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8997) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8998) * Extra commands that don't really fit anywhere else.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8999) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9000) static void sbz_pre_dsp_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9002) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9004) writel(0x00820680, spec->mem_base + 0x01C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9005) writel(0x00820680, spec->mem_base + 0x01C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9007) chipio_write(codec, 0x18b0a4, 0x000000c2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9009) snd_hda_codec_write(codec, 0x11, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9010) AC_VERB_SET_PIN_WIDGET_CONTROL, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9013) static void r3d_pre_dsp_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9015) chipio_write(codec, 0x18b0a4, 0x000000c2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9017) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9018) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x1E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9019) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9020) VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x1C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9021) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9022) VENDOR_CHIPIO_8051_DATA_WRITE, 0x5B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9024) snd_hda_codec_write(codec, 0x11, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9025) AC_VERB_SET_PIN_WIDGET_CONTROL, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9028) static void r3di_pre_dsp_setup(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9030) chipio_write(codec, 0x18b0a4, 0x000000c2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9032) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9033) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x1E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9034) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9035) VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x1C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9036) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9037) VENDOR_CHIPIO_8051_DATA_WRITE, 0x5B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9039) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9040) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9041) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9042) VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9043) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9044) VENDOR_CHIPIO_8051_DATA_WRITE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9045) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9046) VENDOR_CHIPIO_8051_DATA_WRITE, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9048) snd_hda_codec_write(codec, 0x11, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9049) AC_VERB_SET_PIN_WIDGET_CONTROL, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9052) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9053) * These are sent before the DSP is downloaded. Not sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9054) * what they do, or if they're necessary. Could possibly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9055) * be removed. Figure they're better to leave in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9056) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9057) static const unsigned int ca0113_mmio_init_address_sbz[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9058) 0x400, 0x408, 0x40c, 0x01c, 0xc0c, 0xc00, 0xc04, 0xc0c, 0xc0c, 0xc0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9059) 0xc0c, 0xc08, 0xc08, 0xc08, 0xc08, 0xc08, 0xc04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9060) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9062) static const unsigned int ca0113_mmio_init_data_sbz[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9063) 0x00000030, 0x00000000, 0x00000003, 0x00000003, 0x00000003,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9064) 0x00000003, 0x000000c1, 0x000000f1, 0x00000001, 0x000000c7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9065) 0x000000c1, 0x00000080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9066) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9068) static const unsigned int ca0113_mmio_init_data_zxr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9069) 0x00000030, 0x00000000, 0x00000000, 0x00000003, 0x00000003,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9070) 0x00000003, 0x00000001, 0x000000f1, 0x00000001, 0x000000c7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9071) 0x000000c1, 0x00000080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9072) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9074) static const unsigned int ca0113_mmio_init_address_ae5[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9075) 0x400, 0x42c, 0x46c, 0x4ac, 0x4ec, 0x43c, 0x47c, 0x4bc, 0x4fc, 0x408,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9076) 0x100, 0x410, 0x40c, 0x100, 0x100, 0x830, 0x86c, 0x800, 0x86c, 0x800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9077) 0x804, 0x20c, 0x01c, 0xc0c, 0xc00, 0xc04, 0xc0c, 0xc0c, 0xc0c, 0xc0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9078) 0xc08, 0xc08, 0xc08, 0xc08, 0xc08, 0xc04, 0x01c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9079) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9081) static const unsigned int ca0113_mmio_init_data_ae5[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9082) 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9083) 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9084) 0x00000600, 0x00000014, 0x00000001, 0x0000060f, 0x0000070f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9085) 0x00000aff, 0x00000000, 0x0000006b, 0x00000001, 0x0000006b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9086) 0x00000057, 0x00800000, 0x00880680, 0x00000080, 0x00000030,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9087) 0x00000000, 0x00000000, 0x00000003, 0x00000003, 0x00000003,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9088) 0x00000001, 0x000000f1, 0x00000001, 0x000000c7, 0x000000c1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9089) 0x00000080, 0x00880680
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9090) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9092) static void ca0132_mmio_init_sbz(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9094) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9095) unsigned int tmp[2], i, count, cur_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9096) const unsigned int *addr, *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9098) addr = ca0113_mmio_init_address_sbz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9099) for (i = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9100) writel(0x00000000, spec->mem_base + addr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9102) cur_addr = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9103) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9104) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9105) tmp[0] = 0x00880480;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9106) tmp[1] = 0x00000080;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9107) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9108) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9109) tmp[0] = 0x00820680;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9110) tmp[1] = 0x00000083;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9112) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9113) tmp[0] = 0x00880680;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9114) tmp[1] = 0x00000083;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9116) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9117) tmp[0] = 0x00000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9118) tmp[1] = 0x00000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9122) for (i = 0; i < 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9123) writel(tmp[i], spec->mem_base + addr[cur_addr + i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9125) cur_addr += i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9127) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9128) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9129) count = ARRAY_SIZE(ca0113_mmio_init_data_zxr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9130) data = ca0113_mmio_init_data_zxr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9131) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9132) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9133) count = ARRAY_SIZE(ca0113_mmio_init_data_sbz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9134) data = ca0113_mmio_init_data_sbz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9135) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9138) for (i = 0; i < count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9139) writel(data[i], spec->mem_base + addr[cur_addr + i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9142) static void ca0132_mmio_init_ae5(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9144) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9145) const unsigned int *addr, *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9146) unsigned int i, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9148) addr = ca0113_mmio_init_address_ae5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9149) data = ca0113_mmio_init_data_ae5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9150) count = ARRAY_SIZE(ca0113_mmio_init_data_ae5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9152) if (ca0132_quirk(spec) == QUIRK_AE7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9153) writel(0x00000680, spec->mem_base + 0x1c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9154) writel(0x00880680, spec->mem_base + 0x1c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9157) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9158) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9159) * AE-7 shares all writes with the AE-5, except that it writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9160) * a different value to 0x20c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9162) if (i == 21 && ca0132_quirk(spec) == QUIRK_AE7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9163) writel(0x00800001, spec->mem_base + addr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9164) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9167) writel(data[i], spec->mem_base + addr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9170) if (ca0132_quirk(spec) == QUIRK_AE5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9171) writel(0x00880680, spec->mem_base + 0x1c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9174) static void ca0132_mmio_init(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9176) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9178) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9179) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9180) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9181) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9182) ca0132_mmio_init_sbz(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9183) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9184) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9185) ca0132_mmio_init_ae5(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9187) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9192) static const unsigned int ca0132_ae5_register_set_addresses[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9193) 0x304, 0x304, 0x304, 0x304, 0x100, 0x304, 0x100, 0x304, 0x100, 0x304,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9194) 0x100, 0x304, 0x86c, 0x800, 0x86c, 0x800, 0x804
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9195) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9197) static const unsigned char ca0132_ae5_register_set_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9198) 0x0f, 0x0e, 0x1f, 0x0c, 0x3f, 0x08, 0x7f, 0x00, 0xff, 0x00, 0x6b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9199) 0x01, 0x6b, 0x57
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9200) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9202) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9203) * This function writes to some SFR's, does some region2 writes, and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9204) * eventually resets the codec with the 0x7ff verb. Not quite sure why it does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9205) * what it does.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9206) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9207) static void ae5_register_set(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9209) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9210) unsigned int count = ARRAY_SIZE(ca0132_ae5_register_set_addresses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9211) const unsigned int *addr = ca0132_ae5_register_set_addresses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9212) const unsigned char *data = ca0132_ae5_register_set_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9213) unsigned int i, cur_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9214) unsigned char tmp[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9216) if (ca0132_quirk(spec) == QUIRK_AE7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9217) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9218) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x41);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9219) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9220) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9223) chipio_8051_write_direct(codec, 0x93, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9224) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9225) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9226) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9227) VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9229) if (ca0132_quirk(spec) == QUIRK_AE7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9230) tmp[0] = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9231) tmp[1] = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9232) tmp[2] = 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9233) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9234) tmp[0] = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9235) tmp[1] = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9236) tmp[2] = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9239) for (i = cur_addr = 0; i < 3; i++, cur_addr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9240) writeb(tmp[i], spec->mem_base + addr[cur_addr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9243) * First writes are in single bytes, final are in 4 bytes. So, we use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9244) * writeb, then writel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9246) for (i = 0; cur_addr < 12; i++, cur_addr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9247) writeb(data[i], spec->mem_base + addr[cur_addr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9249) for (; cur_addr < count; i++, cur_addr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9250) writel(data[i], spec->mem_base + addr[cur_addr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9252) writel(0x00800001, spec->mem_base + 0x20c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9254) if (ca0132_quirk(spec) == QUIRK_AE7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9255) ca0113_mmio_command_set_type2(codec, 0x48, 0x07, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9256) ca0113_mmio_command_set(codec, 0x30, 0x2e, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9257) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9258) ca0113_mmio_command_set(codec, 0x30, 0x2d, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9261) chipio_8051_write_direct(codec, 0x90, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9262) chipio_8051_write_direct(codec, 0x90, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9264) if (ca0132_quirk(spec) == QUIRK_AE5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9265) ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9267) chipio_write(codec, 0x18b0a4, 0x000000c2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9269) snd_hda_codec_write(codec, 0x01, 0, 0x7ff, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9270) snd_hda_codec_write(codec, 0x01, 0, 0x7ff, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9273) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9274) * Extra init functions for alternative ca0132 codecs. Done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9275) * here so they don't clutter up the main ca0132_init function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9276) * anymore than they have to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9277) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9278) static void ca0132_alt_init(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9280) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9282) ca0132_alt_vol_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9284) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9285) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9286) codec_dbg(codec, "SBZ alt_init");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9287) ca0132_gpio_init(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9288) sbz_pre_dsp_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9289) snd_hda_sequence_write(codec, spec->chip_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9290) snd_hda_sequence_write(codec, spec->desktop_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9291) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9292) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9293) codec_dbg(codec, "R3DI alt_init");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9294) ca0132_gpio_init(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9295) ca0132_gpio_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9296) r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9297) r3di_pre_dsp_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9298) snd_hda_sequence_write(codec, spec->chip_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9299) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x6FF, 0xC4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9300) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9301) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9302) r3d_pre_dsp_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9303) snd_hda_sequence_write(codec, spec->chip_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9304) snd_hda_sequence_write(codec, spec->desktop_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9305) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9306) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9307) ca0132_gpio_init(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9308) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9309) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x49);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9310) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9311) VENDOR_CHIPIO_PLL_PMU_WRITE, 0x88);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9312) chipio_write(codec, 0x18b030, 0x00000020);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9313) snd_hda_sequence_write(codec, spec->chip_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9314) snd_hda_sequence_write(codec, spec->desktop_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9315) ca0113_mmio_command_set(codec, 0x30, 0x32, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9317) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9318) ca0132_gpio_init(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9319) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9320) VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x49);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9321) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9322) VENDOR_CHIPIO_PLL_PMU_WRITE, 0x88);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9323) snd_hda_sequence_write(codec, spec->chip_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9324) snd_hda_sequence_write(codec, spec->desktop_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9325) chipio_write(codec, 0x18b008, 0x000000f8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9326) chipio_write(codec, 0x18b008, 0x000000f0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9327) chipio_write(codec, 0x18b030, 0x00000020);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9328) ca0113_mmio_command_set(codec, 0x30, 0x32, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9329) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9330) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9331) snd_hda_sequence_write(codec, spec->chip_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9332) snd_hda_sequence_write(codec, spec->desktop_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9334) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9339) static int ca0132_init(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9341) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9342) struct auto_pin_cfg *cfg = &spec->autocfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9343) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9344) bool dsp_loaded;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9347) * If the DSP is already downloaded, and init has been entered again,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9348) * there's only two reasons for it. One, the codec has awaken from a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9349) * suspended state, and in that case dspload_is_loaded will return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9350) * false, and the init will be ran again. The other reason it gets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9351) * re entered is on startup for some reason it triggers a suspend and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9352) * resume state. In this case, it will check if the DSP is downloaded,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9353) * and not run the init function again. For codecs using alt_functions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9354) * it will check if the DSP is loaded properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9356) if (spec->dsp_state == DSP_DOWNLOADED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9357) dsp_loaded = dspload_is_loaded(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9358) if (!dsp_loaded) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9359) spec->dsp_reload = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9360) spec->dsp_state = DSP_DOWNLOAD_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9361) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9362) if (ca0132_quirk(spec) == QUIRK_SBZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9363) sbz_dsp_startup_check(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9364) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9368) if (spec->dsp_state != DSP_DOWNLOAD_FAILED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9369) spec->dsp_state = DSP_DOWNLOAD_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9370) spec->curr_chip_addx = INVALID_CHIP_ADDRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9372) if (ca0132_use_pci_mmio(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9373) ca0132_mmio_init(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9375) snd_hda_power_up_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9377) if (ca0132_quirk(spec) == QUIRK_AE5 || ca0132_quirk(spec) == QUIRK_AE7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9378) ae5_register_set(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9380) ca0132_init_unsol(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9381) ca0132_init_params(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9382) ca0132_init_flags(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9384) snd_hda_sequence_write(codec, spec->base_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9386) if (ca0132_use_alt_functions(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9387) ca0132_alt_init(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9389) ca0132_download_dsp(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9391) ca0132_refresh_widget_caps(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9393) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9394) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9395) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9396) r3d_setup_defaults(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9397) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9398) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9399) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9400) sbz_setup_defaults(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9402) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9403) ae5_setup_defaults(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9404) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9405) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9406) ae7_setup_defaults(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9408) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9409) ca0132_setup_defaults(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9410) ca0132_init_analog_mic2(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9411) ca0132_init_dmic(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9412) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9415) for (i = 0; i < spec->num_outputs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9416) init_output(codec, spec->out_pins[i], spec->dacs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9418) init_output(codec, cfg->dig_out_pins[0], spec->dig_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9420) for (i = 0; i < spec->num_inputs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9421) init_input(codec, spec->input_pins[i], spec->adcs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9423) init_input(codec, cfg->dig_in_pin, spec->dig_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9425) if (!ca0132_use_alt_functions(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9426) snd_hda_sequence_write(codec, spec->chip_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9427) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9428) VENDOR_CHIPIO_PARAM_EX_ID_SET, 0x0D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9429) snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9430) VENDOR_CHIPIO_PARAM_EX_VALUE_SET, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9433) if (ca0132_quirk(spec) == QUIRK_SBZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9434) ca0132_gpio_setup(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9436) snd_hda_sequence_write(codec, spec->spec_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9437) if (ca0132_use_alt_functions(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9438) ca0132_alt_select_out(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9439) ca0132_alt_select_in(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9440) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9441) ca0132_select_out(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9442) ca0132_select_mic(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9445) snd_hda_jack_report_sync(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9447) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9448) * Re set the PlayEnhancement switch on a resume event, because the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9449) * controls will not be reloaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9451) if (spec->dsp_reload) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9452) spec->dsp_reload = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9453) ca0132_pe_switch_set(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9456) snd_hda_power_down_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9458) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9461) static int dbpro_init(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9463) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9464) struct auto_pin_cfg *cfg = &spec->autocfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9465) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9467) init_output(codec, cfg->dig_out_pins[0], spec->dig_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9468) init_input(codec, cfg->dig_in_pin, spec->dig_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9470) for (i = 0; i < spec->num_inputs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9471) init_input(codec, spec->input_pins[i], spec->adcs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9473) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9476) static void ca0132_free(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9478) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9480) cancel_delayed_work_sync(&spec->unsol_hp_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9481) snd_hda_power_up(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9482) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9483) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9484) sbz_exit_chip(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9486) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9487) zxr_exit_chip(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9488) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9489) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9490) r3d_exit_chip(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9491) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9492) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9493) ae5_exit_chip(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9494) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9495) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9496) ae7_exit_chip(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9497) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9498) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9499) r3di_gpio_shutdown(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9500) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9501) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9502) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9505) snd_hda_sequence_write(codec, spec->base_exit_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9506) ca0132_exit_chip(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9508) snd_hda_power_down(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9509) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9510) if (spec->mem_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9511) pci_iounmap(codec->bus->pci, spec->mem_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9512) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9513) kfree(spec->spec_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9514) kfree(codec->spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9517) static void dbpro_free(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9519) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9521) zxr_dbpro_power_state_shutdown(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9523) kfree(spec->spec_init_verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9524) kfree(codec->spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9527) static void ca0132_reboot_notify(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9529) codec->patch_ops.free(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9532) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9533) static int ca0132_suspend(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9535) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9537) cancel_delayed_work_sync(&spec->unsol_hp_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9538) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9540) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9542) static const struct hda_codec_ops ca0132_patch_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9543) .build_controls = ca0132_build_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9544) .build_pcms = ca0132_build_pcms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9545) .init = ca0132_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9546) .free = ca0132_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9547) .unsol_event = snd_hda_jack_unsol_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9548) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9549) .suspend = ca0132_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9550) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9551) .reboot_notify = ca0132_reboot_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9552) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9554) static const struct hda_codec_ops dbpro_patch_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9555) .build_controls = dbpro_build_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9556) .build_pcms = dbpro_build_pcms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9557) .init = dbpro_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9558) .free = dbpro_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9559) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9561) static void ca0132_config(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9563) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9565) spec->dacs[0] = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9566) spec->dacs[1] = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9567) spec->dacs[2] = 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9569) spec->multiout.dac_nids = spec->dacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9570) spec->multiout.num_dacs = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9572) if (!ca0132_use_alt_functions(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9573) spec->multiout.max_channels = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9574) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9575) spec->multiout.max_channels = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9577) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9578) case QUIRK_ALIENWARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9579) codec_dbg(codec, "%s: QUIRK_ALIENWARE applied.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9580) snd_hda_apply_pincfgs(codec, alienware_pincfgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9581) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9582) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9583) codec_dbg(codec, "%s: QUIRK_SBZ applied.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9584) snd_hda_apply_pincfgs(codec, sbz_pincfgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9586) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9587) codec_dbg(codec, "%s: QUIRK_ZXR applied.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9588) snd_hda_apply_pincfgs(codec, zxr_pincfgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9590) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9591) codec_dbg(codec, "%s: QUIRK_R3D applied.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9592) snd_hda_apply_pincfgs(codec, r3d_pincfgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9594) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9595) codec_dbg(codec, "%s: QUIRK_R3DI applied.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9596) snd_hda_apply_pincfgs(codec, r3di_pincfgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9598) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9599) codec_dbg(codec, "%s: QUIRK_AE5 applied.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9600) snd_hda_apply_pincfgs(codec, ae5_pincfgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9601) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9602) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9603) codec_dbg(codec, "%s: QUIRK_AE7 applied.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9604) snd_hda_apply_pincfgs(codec, ae7_pincfgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9605) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9606) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9607) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9610) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9611) case QUIRK_ALIENWARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9612) spec->num_outputs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9613) spec->out_pins[0] = 0x0b; /* speaker out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9614) spec->out_pins[1] = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9615) spec->shared_out_nid = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9616) spec->unsol_tag_hp = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9618) spec->adcs[0] = 0x7; /* digital mic / analog mic1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9619) spec->adcs[1] = 0x8; /* analog mic2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9620) spec->adcs[2] = 0xa; /* what u hear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9622) spec->num_inputs = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9623) spec->input_pins[0] = 0x12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9624) spec->input_pins[1] = 0x11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9625) spec->input_pins[2] = 0x13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9626) spec->shared_mic_nid = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9627) spec->unsol_tag_amic1 = 0x11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9629) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9630) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9631) spec->num_outputs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9632) spec->out_pins[0] = 0x0B; /* Line out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9633) spec->out_pins[1] = 0x0F; /* Rear headphone out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9634) spec->out_pins[2] = 0x10; /* Front Headphone / Center/LFE*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9635) spec->out_pins[3] = 0x11; /* Rear surround */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9636) spec->shared_out_nid = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9637) spec->unsol_tag_hp = spec->out_pins[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9638) spec->unsol_tag_front_hp = spec->out_pins[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9640) spec->adcs[0] = 0x7; /* Rear Mic / Line-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9641) spec->adcs[1] = 0x8; /* Front Mic, but only if no DSP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9642) spec->adcs[2] = 0xa; /* what u hear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9644) spec->num_inputs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9645) spec->input_pins[0] = 0x12; /* Rear Mic / Line-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9646) spec->input_pins[1] = 0x13; /* What U Hear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9647) spec->shared_mic_nid = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9648) spec->unsol_tag_amic1 = spec->input_pins[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9650) /* SPDIF I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9651) spec->dig_out = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9652) spec->multiout.dig_out_nid = spec->dig_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9653) spec->dig_in = 0x09;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9654) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9655) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9656) spec->num_outputs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9657) spec->out_pins[0] = 0x0B; /* Line out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9658) spec->out_pins[1] = 0x0F; /* Rear headphone out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9659) spec->out_pins[2] = 0x10; /* Center/LFE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9660) spec->out_pins[3] = 0x11; /* Rear surround */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9661) spec->shared_out_nid = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9662) spec->unsol_tag_hp = spec->out_pins[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9663) spec->unsol_tag_front_hp = spec->out_pins[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9665) spec->adcs[0] = 0x7; /* Rear Mic / Line-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9666) spec->adcs[1] = 0x8; /* Not connected, no front mic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9667) spec->adcs[2] = 0xa; /* what u hear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9669) spec->num_inputs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9670) spec->input_pins[0] = 0x12; /* Rear Mic / Line-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9671) spec->input_pins[1] = 0x13; /* What U Hear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9672) spec->shared_mic_nid = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9673) spec->unsol_tag_amic1 = spec->input_pins[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9674) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9675) case QUIRK_ZXR_DBPRO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9676) spec->adcs[0] = 0x8; /* ZxR DBPro Aux In */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9678) spec->num_inputs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9679) spec->input_pins[0] = 0x11; /* RCA Line-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9681) spec->dig_out = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9682) spec->multiout.dig_out_nid = spec->dig_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9684) spec->dig_in = 0x09;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9685) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9686) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9687) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9688) spec->num_outputs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9689) spec->out_pins[0] = 0x0B; /* Line out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9690) spec->out_pins[1] = 0x11; /* Rear headphone out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9691) spec->out_pins[2] = 0x10; /* Front Headphone / Center/LFE*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9692) spec->out_pins[3] = 0x0F; /* Rear surround */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9693) spec->shared_out_nid = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9694) spec->unsol_tag_hp = spec->out_pins[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9695) spec->unsol_tag_front_hp = spec->out_pins[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9697) spec->adcs[0] = 0x7; /* Rear Mic / Line-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9698) spec->adcs[1] = 0x8; /* Front Mic, but only if no DSP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9699) spec->adcs[2] = 0xa; /* what u hear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9701) spec->num_inputs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9702) spec->input_pins[0] = 0x12; /* Rear Mic / Line-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9703) spec->input_pins[1] = 0x13; /* What U Hear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9704) spec->shared_mic_nid = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9705) spec->unsol_tag_amic1 = spec->input_pins[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9707) /* SPDIF I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9708) spec->dig_out = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9709) spec->multiout.dig_out_nid = spec->dig_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9710) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9711) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9712) spec->num_outputs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9713) spec->out_pins[0] = 0x0B; /* Line out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9714) spec->out_pins[1] = 0x0F; /* Rear headphone out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9715) spec->out_pins[2] = 0x10; /* Front Headphone / Center/LFE*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9716) spec->out_pins[3] = 0x11; /* Rear surround */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9717) spec->shared_out_nid = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9718) spec->unsol_tag_hp = spec->out_pins[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9719) spec->unsol_tag_front_hp = spec->out_pins[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9721) spec->adcs[0] = 0x07; /* Rear Mic / Line-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9722) spec->adcs[1] = 0x08; /* Front Mic, but only if no DSP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9723) spec->adcs[2] = 0x0a; /* what u hear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9725) spec->num_inputs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9726) spec->input_pins[0] = 0x12; /* Rear Mic / Line-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9727) spec->input_pins[1] = 0x13; /* What U Hear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9728) spec->shared_mic_nid = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9729) spec->unsol_tag_amic1 = spec->input_pins[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9731) /* SPDIF I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9732) spec->dig_out = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9733) spec->multiout.dig_out_nid = spec->dig_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9734) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9735) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9736) spec->num_outputs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9737) spec->out_pins[0] = 0x0b; /* speaker out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9738) spec->out_pins[1] = 0x10; /* headphone out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9739) spec->shared_out_nid = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9740) spec->unsol_tag_hp = spec->out_pins[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9742) spec->adcs[0] = 0x7; /* digital mic / analog mic1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9743) spec->adcs[1] = 0x8; /* analog mic2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9744) spec->adcs[2] = 0xa; /* what u hear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9746) spec->num_inputs = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9747) spec->input_pins[0] = 0x12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9748) spec->input_pins[1] = 0x11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9749) spec->input_pins[2] = 0x13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9750) spec->shared_mic_nid = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9751) spec->unsol_tag_amic1 = spec->input_pins[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9753) /* SPDIF I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9754) spec->dig_out = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9755) spec->multiout.dig_out_nid = spec->dig_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9756) spec->dig_in = 0x09;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9757) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9761) static int ca0132_prepare_verbs(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9763) /* Verbs + terminator (an empty element) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9764) #define NUM_SPEC_VERBS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9765) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9767) spec->chip_init_verbs = ca0132_init_verbs0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9768) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9769) * Since desktop cards use pci_mmio, this can be used to determine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9770) * whether or not to use these verbs instead of a separate bool.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9771) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9772) if (ca0132_use_pci_mmio(spec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9773) spec->desktop_init_verbs = ca0132_init_verbs1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9774) spec->spec_init_verbs = kcalloc(NUM_SPEC_VERBS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9775) sizeof(struct hda_verb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9776) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9777) if (!spec->spec_init_verbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9778) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9780) /* config EAPD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9781) spec->spec_init_verbs[0].nid = 0x0b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9782) spec->spec_init_verbs[0].param = 0x78D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9783) spec->spec_init_verbs[0].verb = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9785) /* Previously commented configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9786) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9787) spec->spec_init_verbs[2].nid = 0x0b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9788) spec->spec_init_verbs[2].param = AC_VERB_SET_EAPD_BTLENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9789) spec->spec_init_verbs[2].verb = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9791) spec->spec_init_verbs[3].nid = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9792) spec->spec_init_verbs[3].param = 0x78D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9793) spec->spec_init_verbs[3].verb = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9795) spec->spec_init_verbs[4].nid = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9796) spec->spec_init_verbs[4].param = AC_VERB_SET_EAPD_BTLENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9797) spec->spec_init_verbs[4].verb = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9798) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9800) /* Terminator: spec->spec_init_verbs[NUM_SPEC_VERBS-1] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9801) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9804) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9805) * The Sound Blaster ZxR shares the same PCI subsystem ID as some regular
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9806) * Sound Blaster Z cards. However, they have different HDA codec subsystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9807) * ID's. So, we check for the ZxR's subsystem ID, as well as the DBPro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9808) * daughter boards ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9810) static void sbz_detect_quirk(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9812) struct ca0132_spec *spec = codec->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9814) switch (codec->core.subsystem_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9815) case 0x11020033:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9816) spec->quirk = QUIRK_ZXR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9817) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9818) case 0x1102003f:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9819) spec->quirk = QUIRK_ZXR_DBPRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9820) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9821) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9822) spec->quirk = QUIRK_SBZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9823) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9827) static int patch_ca0132(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9829) struct ca0132_spec *spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9830) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9831) const struct snd_pci_quirk *quirk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9833) codec_dbg(codec, "patch_ca0132\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9835) spec = kzalloc(sizeof(*spec), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9836) if (!spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9837) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9838) codec->spec = spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9839) spec->codec = codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9841) /* Detect codec quirk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9842) quirk = snd_pci_quirk_lookup(codec->bus->pci, ca0132_quirks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9843) if (quirk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9844) spec->quirk = quirk->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9845) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9846) spec->quirk = QUIRK_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9847) if (ca0132_quirk(spec) == QUIRK_SBZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9848) sbz_detect_quirk(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9850) if (ca0132_quirk(spec) == QUIRK_ZXR_DBPRO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9851) codec->patch_ops = dbpro_patch_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9852) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9853) codec->patch_ops = ca0132_patch_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9855) codec->pcm_format_first = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9856) codec->no_sticky_stream = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9859) spec->dsp_state = DSP_DOWNLOAD_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9860) spec->num_mixers = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9862) /* Set which mixers each quirk uses. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9863) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9864) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9865) spec->mixers[0] = desktop_mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9866) snd_hda_codec_set_name(codec, "Sound Blaster Z");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9867) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9868) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9869) spec->mixers[0] = desktop_mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9870) snd_hda_codec_set_name(codec, "Sound Blaster ZxR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9871) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9872) case QUIRK_ZXR_DBPRO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9873) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9874) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9875) spec->mixers[0] = desktop_mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9876) snd_hda_codec_set_name(codec, "Recon3D");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9877) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9878) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9879) spec->mixers[0] = r3di_mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9880) snd_hda_codec_set_name(codec, "Recon3Di");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9881) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9882) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9883) spec->mixers[0] = desktop_mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9884) snd_hda_codec_set_name(codec, "Sound BlasterX AE-5");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9885) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9886) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9887) spec->mixers[0] = desktop_mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9888) snd_hda_codec_set_name(codec, "Sound Blaster AE-7");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9889) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9890) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9891) spec->mixers[0] = ca0132_mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9892) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9895) /* Setup whether or not to use alt functions/controls/pci_mmio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9896) switch (ca0132_quirk(spec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9897) case QUIRK_SBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9898) case QUIRK_R3D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9899) case QUIRK_AE5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9900) case QUIRK_AE7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9901) case QUIRK_ZXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9902) spec->use_alt_controls = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9903) spec->use_alt_functions = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9904) spec->use_pci_mmio = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9905) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9906) case QUIRK_R3DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9907) spec->use_alt_controls = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9908) spec->use_alt_functions = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9909) spec->use_pci_mmio = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9910) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9911) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9912) spec->use_alt_controls = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9913) spec->use_alt_functions = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9914) spec->use_pci_mmio = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9915) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9918) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9919) if (spec->use_pci_mmio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9920) spec->mem_base = pci_iomap(codec->bus->pci, 2, 0xC20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9921) if (spec->mem_base == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9922) codec_warn(codec, "pci_iomap failed! Setting quirk to QUIRK_NONE.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9923) spec->quirk = QUIRK_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9926) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9928) spec->base_init_verbs = ca0132_base_init_verbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9929) spec->base_exit_verbs = ca0132_base_exit_verbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9931) INIT_DELAYED_WORK(&spec->unsol_hp_work, ca0132_unsol_hp_delayed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9933) ca0132_init_chip(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9935) ca0132_config(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9937) err = ca0132_prepare_verbs(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9938) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9939) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9941) err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9942) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9943) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9945) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9947) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9948) ca0132_free(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9949) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9952) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9953) * patch entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9954) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9955) static const struct hda_device_id snd_hda_id_ca0132[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9956) HDA_CODEC_ENTRY(0x11020011, "CA0132", patch_ca0132),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9957) {} /* terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9958) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9959) MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_ca0132);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9961) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9962) MODULE_DESCRIPTION("Creative Sound Core3D codec");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9964) static struct hda_codec_driver ca0132_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9965) .id = snd_hda_id_ca0132,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9966) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9968) module_hda_codec_driver(ca0132_driver);