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)  * PMac AWACS lowlevel functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (c) by Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * code based on dmasound.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <asm/nvram.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include "pmac.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #ifdef CONFIG_ADB_CUDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #define PMAC_AMP_AVAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #ifdef PMAC_AMP_AVAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) struct awacs_amp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 	unsigned char amp_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 	unsigned char amp_vol[2][2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 	unsigned char amp_tone[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define CHECK_CUDA_AMP() (sys_ctrler == SYS_CTRLER_CUDA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #endif /* PMAC_AMP_AVAIL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) static void snd_pmac_screamer_wait(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	long timeout = 2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	while (!(in_le32(&chip->awacs->codec_stat) & MASK_VALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 		mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 		if (! --timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 			snd_printd("snd_pmac_screamer_wait timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48)  * write AWACS register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) snd_pmac_awacs_write(struct snd_pmac *chip, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	long timeout = 5000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	if (chip->model == PMAC_SCREAMER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 		snd_pmac_screamer_wait(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	out_le32(&chip->awacs->codec_ctrl, val | (chip->subframe << 22));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	while (in_le32(&chip->awacs->codec_ctrl) & MASK_NEWECMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 		if (! --timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 			snd_printd("snd_pmac_awacs_write timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) snd_pmac_awacs_write_reg(struct snd_pmac *chip, int reg, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	snd_pmac_awacs_write(chip, val | (reg << 12));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	chip->awacs_reg[reg] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) snd_pmac_awacs_write_noreg(struct snd_pmac *chip, int reg, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	snd_pmac_awacs_write(chip, val | (reg << 12));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) /* Recalibrate chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) static void screamer_recalibrate(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	if (chip->model != PMAC_SCREAMER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	/* Sorry for the horrible delays... I hope to get that improved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	 * by making the whole PM process asynchronous in a future version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	if (chip->manufacturer == 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 		/* delay for broken crystal part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		msleep(750);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	snd_pmac_awacs_write_noreg(chip, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 				   chip->awacs_reg[1] | MASK_RECALIBRATE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 				   MASK_CMUTE | MASK_AMUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) #define screamer_recalibrate(chip) /* NOP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) #endif
^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)  * additional callback to set the pcm format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) static void snd_pmac_awacs_set_format(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	chip->awacs_reg[1] &= ~MASK_SAMPLERATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	chip->awacs_reg[1] |= chip->rate_index << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	snd_pmac_awacs_write_reg(chip, 1, chip->awacs_reg[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117)  * AWACS volume callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120)  * volumes: 0-15 stereo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) static int snd_pmac_awacs_info_volume(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 				      struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	uinfo->value.integer.max = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) static int snd_pmac_awacs_get_volume(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 				     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	int lshift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	int inverted = (kcontrol->private_value >> 16) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	int vol[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	vol[0] = (chip->awacs_reg[reg] >> lshift) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	vol[1] = chip->awacs_reg[reg] & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	if (inverted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		vol[0] = 0x0f - vol[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		vol[1] = 0x0f - vol[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	ucontrol->value.integer.value[0] = vol[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	ucontrol->value.integer.value[1] = vol[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) static int snd_pmac_awacs_put_volume(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 				     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	int lshift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	int inverted = (kcontrol->private_value >> 16) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	int val, oldval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	unsigned int vol[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	vol[0] = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	vol[1] = ucontrol->value.integer.value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	if (vol[0] > 0x0f || vol[1] > 0x0f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	if (inverted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		vol[0] = 0x0f - vol[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 		vol[1] = 0x0f - vol[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	vol[0] &= 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	vol[1] &= 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	oldval = chip->awacs_reg[reg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	val = oldval & ~(0xf | (0xf << lshift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	val |= vol[0] << lshift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	val |= vol[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	if (oldval != val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		snd_pmac_awacs_write_reg(chip, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	return oldval != reg;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) #define AWACS_VOLUME(xname, xreg, xshift, xinverted) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)   .info = snd_pmac_awacs_info_volume, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191)   .get = snd_pmac_awacs_get_volume, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192)   .put = snd_pmac_awacs_put_volume, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193)   .private_value = (xreg) | ((xshift) << 8) | ((xinverted) << 16) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196)  * mute master/ogain for AWACS: mono
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) static int snd_pmac_awacs_get_switch(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 				     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	int invert = (kcontrol->private_value >> 16) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	val = (chip->awacs_reg[reg] >> shift) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		val = 1 - val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	ucontrol->value.integer.value[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) static int snd_pmac_awacs_put_switch(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 				     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	int invert = (kcontrol->private_value >> 16) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	int mask = 1 << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	int val, changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	val = chip->awacs_reg[reg] & ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	if (ucontrol->value.integer.value[0] != invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		val |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	changed = chip->awacs_reg[reg] != val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		snd_pmac_awacs_write_reg(chip, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) #define AWACS_SWITCH(xname, xreg, xshift, xinvert) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241)   .info = snd_pmac_boolean_mono_info, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242)   .get = snd_pmac_awacs_get_switch, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243)   .put = snd_pmac_awacs_put_switch, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244)   .private_value = (xreg) | ((xshift) << 8) | ((xinvert) << 16) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) #ifdef PMAC_AMP_AVAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249)  * controls for perch/whisper extension cards, e.g. G3 desktop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251)  * TDA7433 connected via i2c address 0x45 (= 0x8a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252)  * accessed through cuda
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) static void awacs_set_cuda(int reg, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	struct adb_request req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, 0x8a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 			reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	while (! req.complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		cuda_poll();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264)  * level = 0 - 14, 7 = 0 dB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) static void awacs_amp_set_tone(struct awacs_amp *amp, int bass, int treble)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	amp->amp_tone[0] = bass;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	amp->amp_tone[1] = treble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	if (bass > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		bass = (14 - bass) + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	if (treble > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 		treble = (14 - treble) + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	awacs_set_cuda(2, (bass << 4) | treble);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278)  * vol = 0 - 31 (attenuation), 32 = mute bit, stereo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) static int awacs_amp_set_vol(struct awacs_amp *amp, int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 			     int lvol, int rvol, int do_check)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	if (do_check && amp->amp_vol[index][0] == lvol &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 			amp->amp_vol[index][1] == rvol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	awacs_set_cuda(3 + index, lvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	awacs_set_cuda(5 + index, rvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	amp->amp_vol[index][0] = lvol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	amp->amp_vol[index][1] = rvol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) }
^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)  * 0 = -79 dB, 79 = 0 dB, 99 = +20 dB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) static void awacs_amp_set_master(struct awacs_amp *amp, int vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	amp->amp_master = vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	if (vol <= 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		vol = 32 + (79 - vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		vol = 32 - (vol - 79);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	awacs_set_cuda(1, vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) static void awacs_amp_free(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	struct awacs_amp *amp = chip->mixer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	if (!amp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	kfree(amp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	chip->mixer_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	chip->mixer_free = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) }
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318)  * mixer controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) static int snd_pmac_awacs_info_volume_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 					  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	uinfo->value.integer.max = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	return 0;
^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) static int snd_pmac_awacs_get_volume_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 					 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	int index = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	struct awacs_amp *amp = chip->mixer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	ucontrol->value.integer.value[0] = 31 - (amp->amp_vol[index][0] & 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	ucontrol->value.integer.value[1] = 31 - (amp->amp_vol[index][1] & 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) static int snd_pmac_awacs_put_volume_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 					 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	int index = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	int vol[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	struct awacs_amp *amp = chip->mixer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	vol[0] = (31 - (ucontrol->value.integer.value[0] & 31))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		| (amp->amp_vol[index][0] & 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	vol[1] = (31 - (ucontrol->value.integer.value[1] & 31))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		| (amp->amp_vol[index][1] & 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) static int snd_pmac_awacs_get_switch_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 					 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	int index = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	struct awacs_amp *amp = chip->mixer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	ucontrol->value.integer.value[0] = (amp->amp_vol[index][0] & 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 					? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	ucontrol->value.integer.value[1] = (amp->amp_vol[index][1] & 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 					? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) static int snd_pmac_awacs_put_switch_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 					 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	int index = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	int vol[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	struct awacs_amp *amp = chip->mixer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	vol[0] = (ucontrol->value.integer.value[0] ? 0 : 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		| (amp->amp_vol[index][0] & 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	vol[1] = (ucontrol->value.integer.value[1] ? 0 : 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		| (amp->amp_vol[index][1] & 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) static int snd_pmac_awacs_info_tone_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 					struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	uinfo->value.integer.max = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) static int snd_pmac_awacs_get_tone_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 				       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	int index = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	struct awacs_amp *amp = chip->mixer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	ucontrol->value.integer.value[0] = amp->amp_tone[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) static int snd_pmac_awacs_put_tone_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 				       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	int index = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	struct awacs_amp *amp = chip->mixer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	val = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	if (val > 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	if (val != amp->amp_tone[index]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		amp->amp_tone[index] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) static int snd_pmac_awacs_info_master_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 					  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	uinfo->value.integer.max = 99;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) static int snd_pmac_awacs_get_master_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 					 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	struct awacs_amp *amp = chip->mixer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	ucontrol->value.integer.value[0] = amp->amp_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) static int snd_pmac_awacs_put_master_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 					 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	struct awacs_amp *amp = chip->mixer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	val = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	if (val > 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	if (val != amp->amp_master) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		amp->amp_master = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		awacs_amp_set_master(amp, amp->amp_master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) #define AMP_CH_SPK	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) #define AMP_CH_HD	1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) static const struct snd_kcontrol_new snd_pmac_awacs_amp_vol[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	  .name = "Speaker Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	  .info = snd_pmac_awacs_info_volume_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	  .get = snd_pmac_awacs_get_volume_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	  .put = snd_pmac_awacs_put_volume_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	  .private_value = AMP_CH_SPK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	  .name = "Headphone Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	  .info = snd_pmac_awacs_info_volume_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	  .get = snd_pmac_awacs_get_volume_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	  .put = snd_pmac_awacs_put_volume_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	  .private_value = AMP_CH_HD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	  .name = "Tone Control - Bass",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	  .info = snd_pmac_awacs_info_tone_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	  .get = snd_pmac_awacs_get_tone_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	  .put = snd_pmac_awacs_put_tone_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	  .private_value = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	  .name = "Tone Control - Treble",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	  .info = snd_pmac_awacs_info_tone_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	  .get = snd_pmac_awacs_get_tone_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	  .put = snd_pmac_awacs_put_tone_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	  .private_value = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	  .name = "Amp Master Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	  .info = snd_pmac_awacs_info_master_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	  .get = snd_pmac_awacs_get_master_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	  .put = snd_pmac_awacs_put_master_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) static const struct snd_kcontrol_new snd_pmac_awacs_amp_hp_sw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	.name = "Headphone Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	.info = snd_pmac_boolean_stereo_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	.get = snd_pmac_awacs_get_switch_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	.put = snd_pmac_awacs_put_switch_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	.private_value = AMP_CH_HD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) static const struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	.name = "Speaker Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	.info = snd_pmac_boolean_stereo_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	.get = snd_pmac_awacs_get_switch_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	.put = snd_pmac_awacs_put_switch_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	.private_value = AMP_CH_SPK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) #endif /* PMAC_AMP_AVAIL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526)  * mic boost for screamer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) static int snd_pmac_screamer_mic_boost_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 					    struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	uinfo->value.integer.max = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) static int snd_pmac_screamer_mic_boost_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 					   struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	if (chip->awacs_reg[6] & MASK_MIC_BOOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		val |= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	if (chip->awacs_reg[0] & MASK_GAINLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		val |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	ucontrol->value.integer.value[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) static int snd_pmac_screamer_mic_boost_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 					   struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	int val0, val6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	val0 = chip->awacs_reg[0] & ~MASK_GAINLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	val6 = chip->awacs_reg[6] & ~MASK_MIC_BOOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	if (ucontrol->value.integer.value[0] & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		val0 |= MASK_GAINLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	if (ucontrol->value.integer.value[0] & 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		val6 |= MASK_MIC_BOOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	if (val0 != chip->awacs_reg[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		snd_pmac_awacs_write_reg(chip, 0, val0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	if (val6 != chip->awacs_reg[6]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		snd_pmac_awacs_write_reg(chip, 6, val6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583)  * lists of mixer elements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) static const struct snd_kcontrol_new snd_pmac_awacs_mixers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	AWACS_SWITCH("Master Capture Switch", 1, SHIFT_LOOPTHRU, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	AWACS_VOLUME("Master Capture Volume", 0, 4, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) /*	AWACS_SWITCH("Unknown Playback Switch", 6, SHIFT_PAROUT0, 0), */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) static const struct snd_kcontrol_new snd_pmac_screamer_mixers_beige[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	AWACS_VOLUME("Play-through Playback Volume", 5, 6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_LINE, 0),
^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) static const struct snd_kcontrol_new snd_pmac_screamer_mixers_lo[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) static const struct snd_kcontrol_new snd_pmac_screamer_mixers_imac[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	AWACS_VOLUME("Play-through Playback Volume", 5, 6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) static const struct snd_kcontrol_new snd_pmac_screamer_mixers_g4agp[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	AWACS_VOLUME("Master Playback Volume", 5, 6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) static const struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) static const struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac5500[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	AWACS_VOLUME("Headphone Playback Volume", 2, 6, 1),
^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) static const struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) /* FIXME: is this correct order?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630)  * screamer (powerbook G3 pismo) seems to have different bits...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) static const struct snd_kcontrol_new snd_pmac_awacs_mixers2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_LINE, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_MIC, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) static const struct snd_kcontrol_new snd_pmac_screamer_mixers2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_LINE, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) static const struct snd_kcontrol_new snd_pmac_awacs_mixers2_pmac5500[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
^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) static const struct snd_kcontrol_new snd_pmac_awacs_master_sw =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) AWACS_SWITCH("Master Playback Switch", 1, SHIFT_HDMUTE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) static const struct snd_kcontrol_new snd_pmac_awacs_master_sw_imac =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) AWACS_SWITCH("Line out Playback Switch", 1, SHIFT_HDMUTE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) static const struct snd_kcontrol_new snd_pmac_awacs_master_sw_pmac5500 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) AWACS_SWITCH("Headphone Playback Switch", 1, SHIFT_HDMUTE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) static const struct snd_kcontrol_new snd_pmac_awacs_mic_boost[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	AWACS_SWITCH("Mic Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) static const struct snd_kcontrol_new snd_pmac_screamer_mic_boost[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	  .name = "Mic Boost Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	  .info = snd_pmac_screamer_mic_boost_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	  .get = snd_pmac_screamer_mic_boost_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	  .put = snd_pmac_screamer_mic_boost_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) static const struct snd_kcontrol_new snd_pmac_awacs_mic_boost_pmac7500[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) static const struct snd_kcontrol_new snd_pmac_screamer_mic_boost_beige[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	AWACS_SWITCH("CD Boost Capture Switch", 6, SHIFT_MIC_BOOST, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) static const struct snd_kcontrol_new snd_pmac_screamer_mic_boost_imac[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	AWACS_SWITCH("Mic Boost Capture Switch", 6, SHIFT_MIC_BOOST, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) static const struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	AWACS_VOLUME("Speaker Playback Volume", 4, 6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) static const struct snd_kcontrol_new snd_pmac_awacs_speaker_sw =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) static const struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) static const struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700)  * add new mixer elements to the card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) static int build_mixers(struct snd_pmac *chip, int nums,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 			const struct snd_kcontrol_new *mixers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	for (i = 0; i < nums; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		err = snd_ctl_add(chip->card, snd_ctl_new1(&mixers[i], chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	return 0;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717)  * restore all registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) static void awacs_restore_all_regs(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	snd_pmac_awacs_write_noreg(chip, 2, chip->awacs_reg[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	snd_pmac_awacs_write_noreg(chip, 4, chip->awacs_reg[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	if (chip->model == PMAC_SCREAMER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		snd_pmac_awacs_write_noreg(chip, 5, chip->awacs_reg[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		snd_pmac_awacs_write_noreg(chip, 7, chip->awacs_reg[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) static void snd_pmac_awacs_suspend(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	snd_pmac_awacs_write_noreg(chip, 1, (chip->awacs_reg[1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 					     | MASK_AMUTE | MASK_CMUTE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) static void snd_pmac_awacs_resume(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	if (of_machine_is_compatible("PowerBook3,1")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	    || of_machine_is_compatible("PowerBook3,2")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		snd_pmac_awacs_write_reg(chip, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 			chip->awacs_reg[1] & ~MASK_PAROUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		msleep(300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	awacs_restore_all_regs(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	if (chip->model == PMAC_SCREAMER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		/* reset power bits in reg 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		mdelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	screamer_recalibrate(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) #ifdef PMAC_AMP_AVAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	if (chip->mixer_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		struct awacs_amp *amp = chip->mixer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		awacs_amp_set_vol(amp, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 				  amp->amp_vol[0][0], amp->amp_vol[0][1], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		awacs_amp_set_vol(amp, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 				  amp->amp_vol[1][0], amp->amp_vol[1][1], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		awacs_amp_set_master(amp, amp->amp_master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) #define IS_PM7500 (of_machine_is_compatible("AAPL,7500") \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		|| of_machine_is_compatible("AAPL,8500") \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		|| of_machine_is_compatible("AAPL,9500"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) #define IS_PM5500 (of_machine_is_compatible("AAPL,e411"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) #define IS_BEIGE (of_machine_is_compatible("AAPL,Gossamer"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) #define IS_IMAC1 (of_machine_is_compatible("PowerMac2,1"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) #define IS_IMAC2 (of_machine_is_compatible("PowerMac2,2") \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		|| of_machine_is_compatible("PowerMac4,1"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) #define IS_G4AGP (of_machine_is_compatible("PowerMac3,1"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) #define IS_LOMBARD (of_machine_is_compatible("PowerBook1,1"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) static int imac1, imac2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) #ifdef PMAC_SUPPORT_AUTOMUTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785)  * auto-mute stuffs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) static int snd_pmac_awacs_detect_headphone(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	return (in_le32(&chip->awacs->codec_stat) & chip->hp_stat_mask) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) #ifdef PMAC_AMP_AVAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) static int toggle_amp_mute(struct awacs_amp *amp, int index, int mute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	int vol[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	vol[0] = amp->amp_vol[index][0] & 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	vol[1] = amp->amp_vol[index][1] & 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	if (mute) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		vol[0] |= 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		vol[1] |= 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) static void snd_pmac_awacs_update_automute(struct snd_pmac *chip, int do_notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	if (chip->auto_mute) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) #ifdef PMAC_AMP_AVAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		if (chip->mixer_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 			struct awacs_amp *amp = chip->mixer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 			int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			if (snd_pmac_awacs_detect_headphone(chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 				changed = toggle_amp_mute(amp, AMP_CH_HD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 				changed |= toggle_amp_mute(amp, AMP_CH_SPK, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 				changed = toggle_amp_mute(amp, AMP_CH_HD, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 				changed |= toggle_amp_mute(amp, AMP_CH_SPK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 			if (do_notify && ! changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 			int reg = chip->awacs_reg[1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 				| (MASK_HDMUTE | MASK_SPKMUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 			if (imac1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 				reg &= ~MASK_SPKMUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 				reg |= MASK_PAROUT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 			} else if (imac2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 				reg &= ~MASK_SPKMUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 				reg &= ~MASK_PAROUT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 			if (snd_pmac_awacs_detect_headphone(chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 				reg &= ~MASK_HDMUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 			else if (imac1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 				reg &= ~MASK_PAROUT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 			else if (imac2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 				reg |= MASK_PAROUT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 				reg &= ~MASK_SPKMUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 			if (do_notify && reg == chip->awacs_reg[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 			snd_pmac_awacs_write_reg(chip, 1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		if (do_notify) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 				       &chip->master_sw_ctl->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 				       &chip->speaker_sw_ctl->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 				       &chip->hp_detect_ctl->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		}
^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) #endif /* PMAC_SUPPORT_AUTOMUTE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860)  * initialize chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) snd_pmac_awacs_init(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	int pm7500 = IS_PM7500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	int pm5500 = IS_PM5500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	int beige = IS_BEIGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	int g4agp = IS_G4AGP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	int lombard = IS_LOMBARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	int imac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	int err, vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	struct snd_kcontrol *vmaster_sw, *vmaster_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	struct snd_kcontrol *master_vol, *speaker_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	imac1 = IS_IMAC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	imac2 = IS_IMAC2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	imac = imac1 || imac2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	/* looks like MASK_GAINLINE triggers something, so we set here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	 * as start-up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	chip->awacs_reg[0] = MASK_MUX_CD | 0xff | MASK_GAINLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	chip->awacs_reg[1] = MASK_CMUTE | MASK_AMUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	/* FIXME: Only machines with external SRS module need MASK_PAROUT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	if (chip->has_iic || chip->device_id == 0x5 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	    /* chip->_device_id == 0x8 || */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	    chip->device_id == 0xb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		chip->awacs_reg[1] |= MASK_PAROUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	/* get default volume from nvram */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	// vol = (~nvram_read_byte(0x1308) & 7) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	// vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	vol = 0x0f; /* no, on alsa, muted as default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	vol = vol + (vol << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	chip->awacs_reg[2] = vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	chip->awacs_reg[4] = vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	if (chip->model == PMAC_SCREAMER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		/* FIXME: screamer has loopthru vol control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		chip->awacs_reg[5] = vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		/* FIXME: maybe should be vol << 3 for PCMCIA speaker */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		chip->awacs_reg[6] = MASK_MIC_BOOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		chip->awacs_reg[7] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	awacs_restore_all_regs(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	chip->manufacturer = (in_le32(&chip->awacs->codec_stat) >> 8) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	screamer_recalibrate(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	chip->revision = (in_le32(&chip->awacs->codec_stat) >> 12) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) #ifdef PMAC_AMP_AVAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	if (chip->revision == 3 && chip->has_iic && CHECK_CUDA_AMP()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		struct awacs_amp *amp = kzalloc(sizeof(*amp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 		if (! amp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		chip->mixer_data = amp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		chip->mixer_free = awacs_amp_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		/* mute and zero vol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		awacs_amp_set_vol(amp, 0, 63, 63, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		awacs_amp_set_vol(amp, 1, 63, 63, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		awacs_amp_set_tone(amp, 7, 7); /* 0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		awacs_amp_set_master(amp, 79); /* 0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) #endif /* PMAC_AMP_AVAIL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	if (chip->hp_stat_mask == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		/* set headphone-jack detection bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		switch (chip->model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		case PMAC_AWACS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 			chip->hp_stat_mask = pm7500 || pm5500 ? MASK_HDPCONN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 				: MASK_LOCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		case PMAC_SCREAMER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			switch (chip->device_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 			case 0x08:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 			case 0x0B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 				chip->hp_stat_mask = imac
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 					? MASK_LOCONN_IMAC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 					MASK_HDPLCONN_IMAC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 					MASK_HDPRCONN_IMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 					: MASK_HDPCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 			case 0x00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 			case 0x05:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 				chip->hp_stat_mask = MASK_LOCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 				chip->hp_stat_mask = MASK_HDPCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 			snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	 * build mixers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	strcpy(chip->card->mixername, "PowerMac AWACS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 				snd_pmac_awacs_mixers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (beige || g4agp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	else if (chip->model == PMAC_SCREAMER || pm5500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 				   snd_pmac_screamer_mixers2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	else if (!pm7500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 				   snd_pmac_awacs_mixers2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	if (pm5500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		err = build_mixers(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 				   ARRAY_SIZE(snd_pmac_awacs_mixers2_pmac5500),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 				   snd_pmac_awacs_mixers2_pmac5500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	master_vol = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	if (pm7500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		err = build_mixers(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 				   ARRAY_SIZE(snd_pmac_awacs_mixers_pmac7500),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 				   snd_pmac_awacs_mixers_pmac7500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	else if (pm5500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		    (master_vol = snd_ctl_new1(snd_pmac_awacs_mixers_pmac5500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 						chip)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	else if (beige)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		err = build_mixers(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 				   ARRAY_SIZE(snd_pmac_screamer_mixers_beige),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 				   snd_pmac_screamer_mixers_beige);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	else if (imac || lombard) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		    (master_vol = snd_ctl_new1(snd_pmac_screamer_mixers_lo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 						chip)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		err = build_mixers(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 				   ARRAY_SIZE(snd_pmac_screamer_mixers_imac),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 				   snd_pmac_screamer_mixers_imac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	} else if (g4agp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		err = build_mixers(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 				   ARRAY_SIZE(snd_pmac_screamer_mixers_g4agp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 				   snd_pmac_screamer_mixers_g4agp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		err = build_mixers(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 				   ARRAY_SIZE(snd_pmac_awacs_mixers_pmac),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 				   snd_pmac_awacs_mixers_pmac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac || g4agp || lombard)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 			? &snd_pmac_awacs_master_sw_imac
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 			: pm5500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 			? &snd_pmac_awacs_master_sw_pmac5500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			: &snd_pmac_awacs_master_sw, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	err = snd_ctl_add(chip->card, chip->master_sw_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) #ifdef PMAC_AMP_AVAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	if (chip->mixer_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		/* use amplifier.  the signal is connected from route A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		 * to the amp.  the amp has its headphone and speaker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		 * volumes and mute switches, so we use them instead of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 		 * screamer registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		 * in this case, it seems the route C is not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_amp_vol),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 					snd_pmac_awacs_amp_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		/* overwrite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		chip->master_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_amp_hp_sw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 							chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		err = snd_ctl_add(chip->card, chip->master_sw_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		chip->speaker_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_amp_spk_sw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 							chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) #endif /* PMAC_AMP_AVAIL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		/* route A = headphone, route C = speaker */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		    (speaker_vol = snd_ctl_new1(snd_pmac_awacs_speaker_vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 						chip)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		chip->speaker_sw_ctl = snd_ctl_new1(imac1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 				? &snd_pmac_awacs_speaker_sw_imac1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 				: imac2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 				? &snd_pmac_awacs_speaker_sw_imac2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 				: &snd_pmac_awacs_speaker_sw, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	if (pm5500 || imac || lombard) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		vmaster_sw = snd_ctl_make_virtual_master(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 			"Master Playback Switch", (unsigned int *) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		err = snd_ctl_add_follower_uncached(vmaster_sw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 						    chip->master_sw_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		err = snd_ctl_add_follower_uncached(vmaster_sw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 						    chip->speaker_sw_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		err = snd_ctl_add(chip->card, vmaster_sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		vmaster_vol = snd_ctl_make_virtual_master(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 			"Master Playback Volume", (unsigned int *) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		err = snd_ctl_add_follower(vmaster_vol, master_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		err = snd_ctl_add_follower(vmaster_vol, speaker_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		err = snd_ctl_add(chip->card, vmaster_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	if (beige || g4agp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		err = build_mixers(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 				ARRAY_SIZE(snd_pmac_screamer_mic_boost_beige),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 				snd_pmac_screamer_mic_boost_beige);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	else if (imac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		err = build_mixers(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 				ARRAY_SIZE(snd_pmac_screamer_mic_boost_imac),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 				snd_pmac_screamer_mic_boost_imac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	else if (chip->model == PMAC_SCREAMER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		err = build_mixers(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 				ARRAY_SIZE(snd_pmac_screamer_mic_boost),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 				snd_pmac_screamer_mic_boost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	else if (pm7500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		err = build_mixers(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 				ARRAY_SIZE(snd_pmac_awacs_mic_boost_pmac7500),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 				snd_pmac_awacs_mic_boost_pmac7500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mic_boost),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 				snd_pmac_awacs_mic_boost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	 * set lowlevel callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	chip->set_format = snd_pmac_awacs_set_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	chip->suspend = snd_pmac_awacs_suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	chip->resume = snd_pmac_awacs_resume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) #ifdef PMAC_SUPPORT_AUTOMUTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	err = snd_pmac_add_automute(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	chip->detect_headphone = snd_pmac_awacs_detect_headphone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	chip->update_automute = snd_pmac_awacs_update_automute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	snd_pmac_awacs_update_automute(chip, 0); /* update the status only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	if (chip->model == PMAC_SCREAMER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 		snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) }