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)  *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *   Lowlevel functions for ESI Maya44 cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *	Copyright (c) 2009 Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *	Based on the patches by Rainer Zimmermann <mail@lightshed.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/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "ice1712.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "envy24ht.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "maya44.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) /* WM8776 register indexes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define WM8776_REG_HEADPHONE_L		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define WM8776_REG_HEADPHONE_R		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define WM8776_REG_HEADPHONE_MASTER	0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define WM8776_REG_DAC_ATTEN_L		0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define WM8776_REG_DAC_ATTEN_R		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define WM8776_REG_DAC_ATTEN_MASTER	0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define WM8776_REG_DAC_PHASE		0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define WM8776_REG_DAC_CONTROL		0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define WM8776_REG_DAC_MUTE		0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define WM8776_REG_DAC_DEEMPH		0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define WM8776_REG_DAC_IF_CONTROL	0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define WM8776_REG_ADC_IF_CONTROL	0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define WM8776_REG_MASTER_MODE_CONTROL	0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define WM8776_REG_POWERDOWN		0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define WM8776_REG_ADC_ATTEN_L		0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define WM8776_REG_ADC_ATTEN_R		0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define WM8776_REG_ADC_ALC1		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define WM8776_REG_ADC_ALC2		0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define WM8776_REG_ADC_ALC3		0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define WM8776_REG_ADC_NOISE_GATE	0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define WM8776_REG_ADC_LIMITER		0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define WM8776_REG_ADC_MUX		0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define WM8776_REG_OUTPUT_MUX		0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define WM8776_REG_RESET		0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define WM8776_NUM_REGS			0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) /* clock ratio identifiers for snd_wm8776_set_rate() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define WM8776_CLOCK_RATIO_128FS	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define WM8776_CLOCK_RATIO_192FS	1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define WM8776_CLOCK_RATIO_256FS	2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define WM8776_CLOCK_RATIO_384FS	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define WM8776_CLOCK_RATIO_512FS	4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define WM8776_CLOCK_RATIO_768FS	5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) enum { WM_VOL_HP, WM_VOL_DAC, WM_VOL_ADC, WM_NUM_VOLS };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) enum { WM_SW_DAC, WM_SW_BYPASS, WM_NUM_SWITCHES };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) struct snd_wm8776 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	unsigned char addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	unsigned short regs[WM8776_NUM_REGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	unsigned char volumes[WM_NUM_VOLS][2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	unsigned int switch_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) struct snd_maya44 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	struct snd_ice1712 *ice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct snd_wm8776 wm[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) /* write the given register and save the data to the cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) static void wm8776_write(struct snd_ice1712 *ice, struct snd_wm8776 *wm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 			 unsigned char reg, unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	 * WM8776 registers are up to 9 bits wide, bit 8 is placed in the LSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	 * of the address field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	snd_vt1724_write_i2c(ice, wm->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			     (reg << 1) | ((val >> 8) & 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			     val & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	wm->regs[reg] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * update the given register with and/or mask and save the data to the cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) static int wm8776_write_bits(struct snd_ice1712 *ice, struct snd_wm8776 *wm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			     unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 			     unsigned short mask, unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	val |= wm->regs[reg] & ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (val != wm->regs[reg]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		wm8776_write(ice, wm, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^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)  * WM8776 volume controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct maya_vol_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	unsigned int maxval;		/* volume range: 0..maxval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	unsigned char regs[2];		/* left and right registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	unsigned short mask;		/* value mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	unsigned short offset;		/* zero-value offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	unsigned short mute;		/* mute bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	unsigned short update;		/* update bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	unsigned char mux_bits[2];	/* extra bits for ADC mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static const struct maya_vol_info vol_info[WM_NUM_VOLS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	[WM_VOL_HP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		.maxval = 80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		.regs = { WM8776_REG_HEADPHONE_L, WM8776_REG_HEADPHONE_R },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		.mask = 0x7f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		.offset = 0x30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		.mute = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		.update = 0x180,	/* update and zero-cross enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	[WM_VOL_DAC] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		.maxval = 255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		.regs = { WM8776_REG_DAC_ATTEN_L, WM8776_REG_DAC_ATTEN_R },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		.mask = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		.offset = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		.mute = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		.update = 0x100,	/* zero-cross enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	[WM_VOL_ADC] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		.maxval = 91,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		.regs = { WM8776_REG_ADC_ATTEN_L, WM8776_REG_ADC_ATTEN_R },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		.mask = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		.offset = 0xa5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		.mute = 0xa5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		.update = 0x100,	/* update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		.mux_bits = { 0x80, 0x40 }, /* ADCMUX bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  * dB tables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* headphone output: mute, -73..+6db (1db step) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static const DECLARE_TLV_DB_SCALE(db_scale_hp, -7400, 100, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* DAC output: mute, -127..0db (0.5db step) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static const DECLARE_TLV_DB_SCALE(db_scale_dac, -12750, 50, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* ADC gain: mute, -21..+24db (0.5db step) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static const DECLARE_TLV_DB_SCALE(db_scale_adc, -2100, 50, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int maya_vol_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			 struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	unsigned int idx = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	const struct maya_vol_info *vol = &vol_info[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	uinfo->value.integer.max = vol->maxval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int maya_vol_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	struct snd_wm8776 *wm =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		&chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	unsigned int idx = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	ucontrol->value.integer.value[0] = wm->volumes[idx][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	ucontrol->value.integer.value[1] = wm->volumes[idx][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static int maya_vol_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	struct snd_wm8776 *wm =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		&chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	unsigned int idx = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	const struct maya_vol_info *vol = &vol_info[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	unsigned int val, data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	int ch, changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	for (ch = 0; ch < 2; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		val = ucontrol->value.integer.value[ch];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		if (val > vol->maxval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			val = vol->maxval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		if (val == wm->volumes[idx][ch])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			data = vol->mute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			data = (val - 1) + vol->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		data |= vol->update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		changed |= wm8776_write_bits(chip->ice, wm, vol->regs[ch],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 					     vol->mask | vol->update, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		if (vol->mux_bits[ch])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			wm8776_write_bits(chip->ice, wm, WM8776_REG_ADC_MUX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 					  vol->mux_bits[ch],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 					  val ? 0 : vol->mux_bits[ch]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		wm->volumes[idx][ch] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  * WM8776 switch controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #define COMPOSE_SW_VAL(idx, reg, mask)	((idx) | ((reg) << 8) | ((mask) << 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define GET_SW_VAL_IDX(val)	((val) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define GET_SW_VAL_REG(val)	(((val) >> 8) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define GET_SW_VAL_MASK(val)	(((val) >> 16) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #define maya_sw_info	snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static int maya_sw_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	struct snd_wm8776 *wm =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		&chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	unsigned int idx = GET_SW_VAL_IDX(kcontrol->private_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	ucontrol->value.integer.value[0] = (wm->switch_bits >> idx) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static int maya_sw_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	struct snd_wm8776 *wm =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		&chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	unsigned int idx = GET_SW_VAL_IDX(kcontrol->private_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	unsigned int mask, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	mask = 1 << idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	wm->switch_bits &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	val = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		wm->switch_bits |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	mask = GET_SW_VAL_MASK(kcontrol->private_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	changed = wm8776_write_bits(chip->ice, wm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 				    GET_SW_VAL_REG(kcontrol->private_value),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 				    mask, val ? mask : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)  * GPIO pins (known ones for maya44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #define GPIO_PHANTOM_OFF	2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) #define GPIO_MIC_RELAY		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #define GPIO_SPDIF_IN_INV	5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #define GPIO_MUST_BE_0		7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  * GPIO switch controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #define COMPOSE_GPIO_VAL(shift, inv)	((shift) | ((inv) << 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) #define GET_GPIO_VAL_SHIFT(val)		((val) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #define GET_GPIO_VAL_INV(val)		(((val) >> 8) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static int maya_set_gpio_bits(struct snd_ice1712 *ice, unsigned int mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			      unsigned int bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	unsigned int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	data = snd_ice1712_gpio_read(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	if ((data & mask) == bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	snd_ice1712_gpio_write(ice, (data & ~mask) | bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) #define maya_gpio_sw_info	snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static int maya_gpio_sw_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 			    struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	unsigned int shift = GET_GPIO_VAL_SHIFT(kcontrol->private_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	val = (snd_ice1712_gpio_read(chip->ice) >> shift) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	if (GET_GPIO_VAL_INV(kcontrol->private_value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		val = !val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	ucontrol->value.integer.value[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static int maya_gpio_sw_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			    struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	unsigned int shift = GET_GPIO_VAL_SHIFT(kcontrol->private_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	unsigned int val, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	mask = 1 << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	val = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	if (GET_GPIO_VAL_INV(kcontrol->private_value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		val = !val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	val = val ? mask : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	changed = maya_set_gpio_bits(chip->ice, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)  * capture source selection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /* known working input slots (0-4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) #define MAYA_LINE_IN	1	/* in-2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #define MAYA_MIC_IN	3	/* in-4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	wm8776_write_bits(chip->ice, &chip->wm[idx], WM8776_REG_ADC_MUX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			  0x1f, 1 << line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static int maya_rec_src_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			     struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	static const char * const texts[] = { "Line", "Mic" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int maya_rec_src_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 			    struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	int sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	if (snd_ice1712_gpio_read(chip->ice) & (1 << GPIO_MIC_RELAY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		sel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		sel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	ucontrol->value.enumerated.item[0] = sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static int maya_rec_src_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 			    struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	int sel = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	changed = maya_set_gpio_bits(chip->ice, 1 << GPIO_MIC_RELAY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 				     sel ? (1 << GPIO_MIC_RELAY) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)  * Maya44 routing switch settings have different meanings than the standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)  * ice1724 switches as defined in snd_vt1724_pro_route_info (ice1724.c).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static int maya_pb_route_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 			      struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	static const char * const texts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		"PCM Out", /* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		"Input 1", "Input 2", "Input 3", "Input 4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static int maya_pb_route_shift(int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	static const unsigned char shift[10] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		{ 8, 20, 0, 3, 11, 23, 14, 26, 17, 29 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	return shift[idx % 10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static int maya_pb_route_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	ucontrol->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		snd_ice1724_get_route_val(chip->ice, maya_pb_route_shift(idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static int maya_pb_route_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 			     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	return snd_ice1724_put_route_val(chip->ice,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 					 ucontrol->value.enumerated.item[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 					 maya_pb_route_shift(idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  * controls to be added
^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) static const struct snd_kcontrol_new maya_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		.name = "Crossmix Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		.info = maya_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		.get = maya_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		.put = maya_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		.tlv = { .p = db_scale_hp },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		.private_value = WM_VOL_HP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		.count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		.name = "PCM Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 			SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		.info = maya_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		.get = maya_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		.put = maya_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		.tlv = { .p = db_scale_dac },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		.private_value = WM_VOL_DAC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		.count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		.name = "Line Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		.info = maya_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		.get = maya_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		.put = maya_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		.tlv = { .p = db_scale_adc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		.private_value = WM_VOL_ADC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		.count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		.name = "PCM Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		.info = maya_sw_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		.get = maya_sw_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		.put = maya_sw_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		.private_value = COMPOSE_SW_VAL(WM_SW_DAC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 						WM8776_REG_OUTPUT_MUX, 0x01),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		.count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		.name = "Bypass Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		.info = maya_sw_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		.get = maya_sw_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		.put = maya_sw_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		.private_value = COMPOSE_SW_VAL(WM_SW_BYPASS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 						WM8776_REG_OUTPUT_MUX, 0x04),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		.count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		.name = "Capture Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		.info = maya_rec_src_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		.get = maya_rec_src_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		.put = maya_rec_src_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		.name = "Mic Phantom Power Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		.info = maya_gpio_sw_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		.get = maya_gpio_sw_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		.put = maya_gpio_sw_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		.private_value = COMPOSE_GPIO_VAL(GPIO_PHANTOM_OFF, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		.name = "SPDIF Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		.info = maya_gpio_sw_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		.get = maya_gpio_sw_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		.put = maya_gpio_sw_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		.private_value = COMPOSE_GPIO_VAL(GPIO_SPDIF_IN_INV, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		.name = "H/W Playback Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		.info = maya_pb_route_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		.get = maya_pb_route_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		.put = maya_pb_route_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		.count = 4,  /* FIXME: do controls 5-9 have any meaning? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static int maya44_add_controls(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	for (i = 0; i < ARRAY_SIZE(maya_controls); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		err = snd_ctl_add(ice->card, snd_ctl_new1(&maya_controls[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 							  ice->spec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)  * initialize a wm8776 chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static void wm8776_init(struct snd_ice1712 *ice,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			struct snd_wm8776 *wm, unsigned int addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	static const unsigned short inits_wm8776[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		0x02, 0x100, /* R2: headphone L+R muted + update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		0x05, 0x100, /* R5: DAC output L+R muted + update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		0x06, 0x000, /* R6: DAC output phase normal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		0x07, 0x091, /* R7: DAC enable zero cross detection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 				normal output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		0x08, 0x000, /* R8: DAC soft mute off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		0x09, 0x000, /* R9: no deemph, DAC zero detect disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		0x0a, 0x022, /* R10: DAC I2C mode, std polarities, 24bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		0x0b, 0x022, /* R11: ADC I2C mode, std polarities, 24bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 				highpass filter enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		0x0c, 0x042, /* R12: ADC+DAC slave, ADC+DAC 44,1kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		0x0d, 0x000, /* R13: all power up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		0x0e, 0x100, /* R14: ADC left muted,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 				enable zero cross detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		0x0f, 0x100, /* R15: ADC right muted,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 				enable zero cross detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 			     /* R16: ALC...*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		0x11, 0x000, /* R17: disable ALC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 			     /* R18: ALC...*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 			     /* R19: noise gate...*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		0x15, 0x000, /* R21: ADC input mux init, mute all inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		0x16, 0x001, /* R22: output mux, select DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		0xff, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	const unsigned short *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	unsigned char reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	unsigned short data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	wm->addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	/* enable DAC output; mute bypass, aux & all inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	wm->switch_bits = (1 << WM_SW_DAC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	ptr = inits_wm8776;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	while (*ptr != 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		reg = *ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		data = *ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		wm8776_write(ice, wm, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)  * change the rate on the WM8776 codecs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)  * this assumes that the VT17xx's rate is changed by the calling function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)  * NOTE: even though the WM8776's are running in slave mode and rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)  * selection is automatic, we need to call snd_wm8776_set_rate() here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)  * to make sure some flags are set correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static void set_rate(struct snd_ice1712 *ice, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	struct snd_maya44 *chip = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	unsigned int ratio, adc_ratio, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	switch (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	case 192000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		ratio = WM8776_CLOCK_RATIO_128FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	case 176400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		ratio = WM8776_CLOCK_RATIO_128FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	case 96000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		ratio = WM8776_CLOCK_RATIO_256FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	case 88200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		ratio = WM8776_CLOCK_RATIO_384FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	case 48000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		ratio = WM8776_CLOCK_RATIO_512FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	case 44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		ratio = WM8776_CLOCK_RATIO_512FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	case 32000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		ratio = WM8776_CLOCK_RATIO_768FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		/* no hint - S/PDIF input is master, simply return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	 * this currently sets the same rate for ADC and DAC, but limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	 * ADC rate to 256X (96kHz). For 256X mode (96kHz), this sets ADC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	 * oversampling to 64x, as recommended by WM8776 datasheet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	 * Setting the rate is not really necessary in slave mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	adc_ratio = ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	if (adc_ratio < WM8776_CLOCK_RATIO_256FS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		adc_ratio = WM8776_CLOCK_RATIO_256FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	val = adc_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	if (adc_ratio == WM8776_CLOCK_RATIO_256FS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		val |= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	val |= ratio << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	for (i = 0; i < 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		wm8776_write_bits(ice, &chip->wm[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 				  WM8776_REG_MASTER_MODE_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 				  0x180, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)  * supported sample rates (to override the default one)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static const unsigned int rates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /* playback rates: 32..192 kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static const struct snd_pcm_hw_constraint_list dac_rates = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	.count = ARRAY_SIZE(rates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	.list = rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	.mask = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)  * chip addresses on I2C bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static const unsigned char wm8776_addr[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	0x34, 0x36, /* codec 0 & 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)  * initialize the chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static int maya44_init(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	struct snd_maya44 *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	mutex_init(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	chip->ice = ice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	ice->spec = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	/* initialise codecs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	ice->num_total_dacs = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	ice->num_total_adcs = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	ice->akm_codecs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		wm8776_init(ice, &chip->wm[i], wm8776_addr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		wm8776_select_input(chip, i, MAYA_LINE_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	/* set card specific rates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	ice->hw_rates = &dac_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	/* register change rate notifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	ice->gpio.set_pro_rate = set_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	/* RDMA1 (2nd input channel) is used for ADC by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	ice->force_rdma1 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	/* have an own routing control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	ice->own_routing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)  * Maya44 boards don't provide the EEPROM data except for the vendor IDs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)  * hence the driver needs to sets up it properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static const unsigned char maya44_eeprom[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	[ICE_EEP2_SYSCONF]     = 0x45,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 		/* clock xin1=49.152MHz, mpu401, 2 stereo ADCs+DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	[ICE_EEP2_ACLINK]      = 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		/* I2S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	[ICE_EEP2_I2S]         = 0xf8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		/* vol, 96k, 24bit, 192k */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	[ICE_EEP2_SPDIF]       = 0xc3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 		/* enable spdif out, spdif out supp, spdif-in, ext spdif out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	[ICE_EEP2_GPIO_DIR]    = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	[ICE_EEP2_GPIO_DIR1]   = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	[ICE_EEP2_GPIO_DIR2]   = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	[ICE_EEP2_GPIO_MASK]   = 0/*0x9f*/,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	[ICE_EEP2_GPIO_MASK1]  = 0/*0xff*/,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	[ICE_EEP2_GPIO_MASK2]  = 0/*0x7f*/,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	[ICE_EEP2_GPIO_STATE]  = (1 << GPIO_PHANTOM_OFF) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 			(1 << GPIO_SPDIF_IN_INV),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	[ICE_EEP2_GPIO_STATE1] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	[ICE_EEP2_GPIO_STATE2] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /* entry point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) struct snd_ice1712_card_info snd_vt1724_maya44_cards[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		.subvendor = VT1724_SUBDEVICE_MAYA44,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		.name = "ESI Maya44",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		.model = "maya44",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		.chip_init = maya44_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		.build_controls = maya44_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 		.eeprom_size = sizeof(maya44_eeprom),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		.eeprom_data = maya44_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	{ } /* terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) };