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