Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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, &reg);
^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, &reg);
^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);