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