1 // SPDX-License-Identifier: GPL-2.0-or-later << 2 /* 1 /* 3 * PMac Burgundy lowlevel functions 2 * PMac Burgundy lowlevel functions 4 * 3 * 5 * Copyright (c) by Takashi Iwai <tiwai@suse.d 4 * Copyright (c) by Takashi Iwai <tiwai@suse.de> 6 * code based on dmasound.c. 5 * code based on dmasound.c. >> 6 * >> 7 * This program is free software; you can redistribute it and/or modify >> 8 * it under the terms of the GNU General Public License as published by >> 9 * the Free Software Foundation; either version 2 of the License, or >> 10 * (at your option) any later version. >> 11 * >> 12 * This program is distributed in the hope that it will be useful, >> 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of >> 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> 15 * GNU General Public License for more details. >> 16 * >> 17 * You should have received a copy of the GNU General Public License >> 18 * along with this program; if not, write to the Free Software >> 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7 */ 20 */ 8 21 9 #include <linux/io.h> !! 22 #include <sound/driver.h> >> 23 #include <asm/io.h> 10 #include <linux/init.h> 24 #include <linux/init.h> >> 25 #include <linux/slab.h> 11 #include <linux/delay.h> 26 #include <linux/delay.h> 12 #include <linux/of.h> << 13 #include <sound/core.h> 27 #include <sound/core.h> 14 #include "pmac.h" 28 #include "pmac.h" 15 #include "burgundy.h" 29 #include "burgundy.h" 16 30 >> 31 #define chip_t pmac_t >> 32 17 33 18 /* Waits for busy flag to clear */ 34 /* Waits for busy flag to clear */ 19 static inline void !! 35 inline static void 20 snd_pmac_burgundy_busy_wait(struct snd_pmac *c !! 36 snd_pmac_burgundy_busy_wait(pmac_t *chip) 21 { 37 { 22 int timeout = 50; 38 int timeout = 50; 23 while ((in_le32(&chip->awacs->codec_ct 39 while ((in_le32(&chip->awacs->codec_ctrl) & MASK_NEWECMD) && timeout--) 24 udelay(1); 40 udelay(1); 25 if (timeout < 0) !! 41 if (! timeout) 26 printk(KERN_DEBUG "burgundy_bu 42 printk(KERN_DEBUG "burgundy_busy_wait: timeout\n"); 27 } 43 } 28 44 29 static inline void !! 45 inline static void 30 snd_pmac_burgundy_extend_wait(struct snd_pmac !! 46 snd_pmac_burgundy_extend_wait(pmac_t *chip) 31 { 47 { 32 int timeout; 48 int timeout; 33 timeout = 50; 49 timeout = 50; 34 while (!(in_le32(&chip->awacs->codec_s 50 while (!(in_le32(&chip->awacs->codec_stat) & MASK_EXTEND) && timeout--) 35 udelay(1); 51 udelay(1); 36 if (timeout < 0) !! 52 if (! timeout) 37 printk(KERN_DEBUG "burgundy_ex 53 printk(KERN_DEBUG "burgundy_extend_wait: timeout #1\n"); 38 timeout = 50; 54 timeout = 50; 39 while ((in_le32(&chip->awacs->codec_st 55 while ((in_le32(&chip->awacs->codec_stat) & MASK_EXTEND) && timeout--) 40 udelay(1); 56 udelay(1); 41 if (timeout < 0) !! 57 if (! timeout) 42 printk(KERN_DEBUG "burgundy_ex 58 printk(KERN_DEBUG "burgundy_extend_wait: timeout #2\n"); 43 } 59 } 44 60 45 static void 61 static void 46 snd_pmac_burgundy_wcw(struct snd_pmac *chip, u !! 62 snd_pmac_burgundy_wcw(pmac_t *chip, unsigned addr, unsigned val) 47 { 63 { 48 out_le32(&chip->awacs->codec_ctrl, add 64 out_le32(&chip->awacs->codec_ctrl, addr + 0x200c00 + (val & 0xff)); 49 snd_pmac_burgundy_busy_wait(chip); 65 snd_pmac_burgundy_busy_wait(chip); 50 out_le32(&chip->awacs->codec_ctrl, add 66 out_le32(&chip->awacs->codec_ctrl, addr + 0x200d00 +((val>>8) & 0xff)); 51 snd_pmac_burgundy_busy_wait(chip); 67 snd_pmac_burgundy_busy_wait(chip); 52 out_le32(&chip->awacs->codec_ctrl, add 68 out_le32(&chip->awacs->codec_ctrl, addr + 0x200e00 +((val>>16) & 0xff)); 53 snd_pmac_burgundy_busy_wait(chip); 69 snd_pmac_burgundy_busy_wait(chip); 54 out_le32(&chip->awacs->codec_ctrl, add 70 out_le32(&chip->awacs->codec_ctrl, addr + 0x200f00 +((val>>24) & 0xff)); 55 snd_pmac_burgundy_busy_wait(chip); 71 snd_pmac_burgundy_busy_wait(chip); 56 } 72 } 57 73 58 static unsigned 74 static unsigned 59 snd_pmac_burgundy_rcw(struct snd_pmac *chip, u !! 75 snd_pmac_burgundy_rcw(pmac_t *chip, unsigned addr) 60 { 76 { 61 unsigned val = 0; 77 unsigned val = 0; 62 unsigned long flags; 78 unsigned long flags; 63 79 64 spin_lock_irqsave(&chip->reg_lock, fla 80 spin_lock_irqsave(&chip->reg_lock, flags); 65 81 66 out_le32(&chip->awacs->codec_ctrl, add 82 out_le32(&chip->awacs->codec_ctrl, addr + 0x100000); 67 snd_pmac_burgundy_busy_wait(chip); 83 snd_pmac_burgundy_busy_wait(chip); 68 snd_pmac_burgundy_extend_wait(chip); 84 snd_pmac_burgundy_extend_wait(chip); 69 val += (in_le32(&chip->awacs->codec_st 85 val += (in_le32(&chip->awacs->codec_stat) >> 4) & 0xff; 70 86 71 out_le32(&chip->awacs->codec_ctrl, add 87 out_le32(&chip->awacs->codec_ctrl, addr + 0x100100); 72 snd_pmac_burgundy_busy_wait(chip); 88 snd_pmac_burgundy_busy_wait(chip); 73 snd_pmac_burgundy_extend_wait(chip); 89 snd_pmac_burgundy_extend_wait(chip); 74 val += ((in_le32(&chip->awacs->codec_s 90 val += ((in_le32(&chip->awacs->codec_stat)>>4) & 0xff) <<8; 75 91 76 out_le32(&chip->awacs->codec_ctrl, add 92 out_le32(&chip->awacs->codec_ctrl, addr + 0x100200); 77 snd_pmac_burgundy_busy_wait(chip); 93 snd_pmac_burgundy_busy_wait(chip); 78 snd_pmac_burgundy_extend_wait(chip); 94 snd_pmac_burgundy_extend_wait(chip); 79 val += ((in_le32(&chip->awacs->codec_s 95 val += ((in_le32(&chip->awacs->codec_stat)>>4) & 0xff) <<16; 80 96 81 out_le32(&chip->awacs->codec_ctrl, add 97 out_le32(&chip->awacs->codec_ctrl, addr + 0x100300); 82 snd_pmac_burgundy_busy_wait(chip); 98 snd_pmac_burgundy_busy_wait(chip); 83 snd_pmac_burgundy_extend_wait(chip); 99 snd_pmac_burgundy_extend_wait(chip); 84 val += ((in_le32(&chip->awacs->codec_s 100 val += ((in_le32(&chip->awacs->codec_stat)>>4) & 0xff) <<24; 85 101 86 spin_unlock_irqrestore(&chip->reg_lock 102 spin_unlock_irqrestore(&chip->reg_lock, flags); 87 103 88 return val; 104 return val; 89 } 105 } 90 106 91 static void 107 static void 92 snd_pmac_burgundy_wcb(struct snd_pmac *chip, u !! 108 snd_pmac_burgundy_wcb(pmac_t *chip, unsigned int addr, unsigned int val) 93 unsigned int val) << 94 { 109 { 95 out_le32(&chip->awacs->codec_ctrl, add 110 out_le32(&chip->awacs->codec_ctrl, addr + 0x300000 + (val & 0xff)); 96 snd_pmac_burgundy_busy_wait(chip); 111 snd_pmac_burgundy_busy_wait(chip); 97 } 112 } 98 113 99 static unsigned 114 static unsigned 100 snd_pmac_burgundy_rcb(struct snd_pmac *chip, u !! 115 snd_pmac_burgundy_rcb(pmac_t *chip, unsigned int addr) 101 { 116 { 102 unsigned val = 0; 117 unsigned val = 0; 103 unsigned long flags; 118 unsigned long flags; 104 119 105 spin_lock_irqsave(&chip->reg_lock, fla 120 spin_lock_irqsave(&chip->reg_lock, flags); 106 121 107 out_le32(&chip->awacs->codec_ctrl, add 122 out_le32(&chip->awacs->codec_ctrl, addr + 0x100000); 108 snd_pmac_burgundy_busy_wait(chip); 123 snd_pmac_burgundy_busy_wait(chip); 109 snd_pmac_burgundy_extend_wait(chip); 124 snd_pmac_burgundy_extend_wait(chip); 110 val += (in_le32(&chip->awacs->codec_st 125 val += (in_le32(&chip->awacs->codec_stat) >> 4) & 0xff; 111 126 112 spin_unlock_irqrestore(&chip->reg_lock 127 spin_unlock_irqrestore(&chip->reg_lock, flags); 113 128 114 return val; 129 return val; 115 } 130 } 116 131 117 #define BASE2ADDR(base) ((base) << 12) << 118 #define ADDR2BASE(addr) ((addr) >> 12) << 119 << 120 /* 132 /* 121 * Burgundy volume: 0 - 100, stereo, word reg !! 133 * Burgundy volume: 0 - 100, stereo 122 */ 134 */ 123 static void 135 static void 124 snd_pmac_burgundy_write_volume(struct snd_pmac !! 136 snd_pmac_burgundy_write_volume(pmac_t *chip, unsigned int address, long *volume, int shift) 125 long *volume, i << 126 { 137 { 127 int hardvolume, lvolume, rvolume; 138 int hardvolume, lvolume, rvolume; 128 139 129 if (volume[0] < 0 || volume[0] > 100 | << 130 volume[1] < 0 || volume[1] > 100) << 131 return; /* -EINVAL */ << 132 lvolume = volume[0] ? volume[0] + BURG 140 lvolume = volume[0] ? volume[0] + BURGUNDY_VOLUME_OFFSET : 0; 133 rvolume = volume[1] ? volume[1] + BURG 141 rvolume = volume[1] ? volume[1] + BURGUNDY_VOLUME_OFFSET : 0; 134 142 135 hardvolume = lvolume + (rvolume << shi 143 hardvolume = lvolume + (rvolume << shift); 136 if (shift == 8) 144 if (shift == 8) 137 hardvolume |= hardvolume << 16 145 hardvolume |= hardvolume << 16; 138 146 139 snd_pmac_burgundy_wcw(chip, address, h 147 snd_pmac_burgundy_wcw(chip, address, hardvolume); 140 } 148 } 141 149 142 static void 150 static void 143 snd_pmac_burgundy_read_volume(struct snd_pmac !! 151 snd_pmac_burgundy_read_volume(pmac_t *chip, unsigned int address, long *volume, int shift) 144 long *volume, in << 145 { 152 { 146 int wvolume; 153 int wvolume; 147 154 148 wvolume = snd_pmac_burgundy_rcw(chip, 155 wvolume = snd_pmac_burgundy_rcw(chip, address); 149 156 150 volume[0] = wvolume & 0xff; 157 volume[0] = wvolume & 0xff; 151 if (volume[0] >= BURGUNDY_VOLUME_OFFSE 158 if (volume[0] >= BURGUNDY_VOLUME_OFFSET) 152 volume[0] -= BURGUNDY_VOLUME_O 159 volume[0] -= BURGUNDY_VOLUME_OFFSET; 153 else 160 else 154 volume[0] = 0; 161 volume[0] = 0; 155 volume[1] = (wvolume >> shift) & 0xff; 162 volume[1] = (wvolume >> shift) & 0xff; 156 if (volume[1] >= BURGUNDY_VOLUME_OFFSE 163 if (volume[1] >= BURGUNDY_VOLUME_OFFSET) 157 volume[1] -= BURGUNDY_VOLUME_O 164 volume[1] -= BURGUNDY_VOLUME_OFFSET; 158 else 165 else 159 volume[1] = 0; 166 volume[1] = 0; 160 } 167 } 161 168 162 static int snd_pmac_burgundy_info_volume(struc !! 169 163 struc !! 170 /* >> 171 */ >> 172 >> 173 #define BASE2ADDR(base) ((base) << 12) >> 174 #define ADDR2BASE(addr) ((addr) >> 12) >> 175 >> 176 static int snd_pmac_burgundy_info_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 164 { 177 { 165 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTE 178 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 166 uinfo->count = 2; 179 uinfo->count = 2; 167 uinfo->value.integer.min = 0; 180 uinfo->value.integer.min = 0; 168 uinfo->value.integer.max = 100; 181 uinfo->value.integer.max = 100; 169 return 0; 182 return 0; 170 } 183 } 171 184 172 static int snd_pmac_burgundy_get_volume(struct !! 185 static int snd_pmac_burgundy_get_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 173 struct << 174 { 186 { 175 struct snd_pmac *chip = snd_kcontrol_c !! 187 pmac_t *chip = snd_kcontrol_chip(kcontrol); 176 unsigned int addr = BASE2ADDR(kcontrol 188 unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff); 177 int shift = (kcontrol->private_value > 189 int shift = (kcontrol->private_value >> 8) & 0xff; 178 snd_pmac_burgundy_read_volume(chip, ad !! 190 snd_pmac_burgundy_read_volume(chip, addr, ucontrol->value.integer.value, shift); 179 ucontrol << 180 return 0; 191 return 0; 181 } 192 } 182 193 183 static int snd_pmac_burgundy_put_volume(struct !! 194 static int snd_pmac_burgundy_put_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 184 struct << 185 { 195 { 186 struct snd_pmac *chip = snd_kcontrol_c !! 196 pmac_t *chip = snd_kcontrol_chip(kcontrol); 187 unsigned int addr = BASE2ADDR(kcontrol 197 unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff); 188 int shift = (kcontrol->private_value > 198 int shift = (kcontrol->private_value >> 8) & 0xff; 189 long nvoices[2]; 199 long nvoices[2]; 190 200 191 snd_pmac_burgundy_write_volume(chip, a !! 201 snd_pmac_burgundy_write_volume(chip, addr, ucontrol->value.integer.value, shift); 192 ucontro << 193 snd_pmac_burgundy_read_volume(chip, ad 202 snd_pmac_burgundy_read_volume(chip, addr, nvoices, shift); 194 return (nvoices[0] != ucontrol->value. 203 return (nvoices[0] != ucontrol->value.integer.value[0] || 195 nvoices[1] != ucontrol->value. 204 nvoices[1] != ucontrol->value.integer.value[1]); 196 } 205 } 197 206 198 #define BURGUNDY_VOLUME_W(xname, xindex, addr, !! 207 #define BURGUNDY_VOLUME(xname, xindex, addr, shift) \ 199 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = 208 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\ 200 .info = snd_pmac_burgundy_info_volume,\ 209 .info = snd_pmac_burgundy_info_volume,\ 201 .get = snd_pmac_burgundy_get_volume,\ 210 .get = snd_pmac_burgundy_get_volume,\ 202 .put = snd_pmac_burgundy_put_volume,\ 211 .put = snd_pmac_burgundy_put_volume,\ 203 .private_value = ((ADDR2BASE(addr) & 0xff) | 212 .private_value = ((ADDR2BASE(addr) & 0xff) | ((shift) << 8)) } 204 213 205 /* !! 214 /* lineout/speaker */ 206 * Burgundy volume: 0 - 100, stereo, 2-byte re << 207 */ << 208 static void << 209 snd_pmac_burgundy_write_volume_2b(struct snd_p << 210 long *volume << 211 { << 212 int lvolume, rvolume; << 213 << 214 off |= off << 2; << 215 lvolume = volume[0] ? volume[0] + BURG << 216 rvolume = volume[1] ? volume[1] + BURG << 217 << 218 snd_pmac_burgundy_wcb(chip, address + << 219 snd_pmac_burgundy_wcb(chip, address + << 220 } << 221 << 222 static void << 223 snd_pmac_burgundy_read_volume_2b(struct snd_pm << 224 long *volume, << 225 { << 226 volume[0] = snd_pmac_burgundy_rcb(chip << 227 if (volume[0] >= BURGUNDY_VOLUME_OFFSE << 228 volume[0] -= BURGUNDY_VOLUME_O << 229 else << 230 volume[0] = 0; << 231 volume[1] = snd_pmac_burgundy_rcb(chip << 232 if (volume[1] >= BURGUNDY_VOLUME_OFFSE << 233 volume[1] -= BURGUNDY_VOLUME_O << 234 else << 235 volume[1] = 0; << 236 } << 237 << 238 static int snd_pmac_burgundy_info_volume_2b(st << 239 st << 240 { << 241 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTE << 242 uinfo->count = 2; << 243 uinfo->value.integer.min = 0; << 244 uinfo->value.integer.max = 100; << 245 return 0; << 246 } << 247 << 248 static int snd_pmac_burgundy_get_volume_2b(str << 249 str << 250 { << 251 struct snd_pmac *chip = snd_kcontrol_c << 252 unsigned int addr = BASE2ADDR(kcontrol << 253 int off = kcontrol->private_value & 0x << 254 snd_pmac_burgundy_read_volume_2b(chip, << 255 ucontrol->value.intege << 256 return 0; << 257 } << 258 << 259 static int snd_pmac_burgundy_put_volume_2b(str << 260 str << 261 { << 262 struct snd_pmac *chip = snd_kcontrol_c << 263 unsigned int addr = BASE2ADDR(kcontrol << 264 int off = kcontrol->private_value & 0x << 265 long nvoices[2]; << 266 << 267 snd_pmac_burgundy_write_volume_2b(chip << 268 ucontrol->value.intege << 269 snd_pmac_burgundy_read_volume_2b(chip, << 270 return (nvoices[0] != ucontrol->value. << 271 nvoices[1] != ucontrol->value. << 272 } << 273 << 274 #define BURGUNDY_VOLUME_2B(xname, xindex, addr << 275 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = << 276 .info = snd_pmac_burgundy_info_volume_2b,\ << 277 .get = snd_pmac_burgundy_get_volume_2b,\ << 278 .put = snd_pmac_burgundy_put_volume_2b,\ << 279 .private_value = ((ADDR2BASE(addr) & 0xff) | << 280 << 281 /* << 282 * Burgundy gain/attenuation: 0 - 15, mono/ste << 283 */ << 284 static int snd_pmac_burgundy_info_gain(struct << 285 struct << 286 { << 287 int stereo = (kcontrol->private_value << 288 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTE << 289 uinfo->count = stereo + 1; << 290 uinfo->value.integer.min = 0; << 291 uinfo->value.integer.max = 15; << 292 return 0; << 293 } << 294 << 295 static int snd_pmac_burgundy_get_gain(struct s << 296 struct s << 297 { << 298 struct snd_pmac *chip = snd_kcontrol_c << 299 unsigned int addr = BASE2ADDR(kcontrol << 300 int stereo = (kcontrol->private_value << 301 int atten = (kcontrol->private_value > << 302 int oval; << 303 << 304 oval = snd_pmac_burgundy_rcb(chip, add << 305 if (atten) << 306 oval = ~oval & 0xff; << 307 ucontrol->value.integer.value[0] = ova << 308 if (stereo) << 309 ucontrol->value.integer.value[ << 310 return 0; << 311 } << 312 << 313 static int snd_pmac_burgundy_put_gain(struct s << 314 struct s << 315 { << 316 struct snd_pmac *chip = snd_kcontrol_c << 317 unsigned int addr = BASE2ADDR(kcontrol << 318 int stereo = (kcontrol->private_value << 319 int atten = (kcontrol->private_value > << 320 int oval, val; << 321 << 322 oval = snd_pmac_burgundy_rcb(chip, add << 323 if (atten) << 324 oval = ~oval & 0xff; << 325 val = ucontrol->value.integer.value[0] << 326 if (stereo) << 327 val |= ucontrol->value.integer << 328 else << 329 val |= ucontrol->value.integer << 330 if (atten) << 331 val = ~val & 0xff; << 332 snd_pmac_burgundy_wcb(chip, addr, val) << 333 return val != oval; << 334 } << 335 << 336 #define BURGUNDY_VOLUME_B(xname, xindex, addr, << 337 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = << 338 .info = snd_pmac_burgundy_info_gain,\ << 339 .get = snd_pmac_burgundy_get_gain,\ << 340 .put = snd_pmac_burgundy_put_gain,\ << 341 .private_value = (ADDR2BASE(addr) | ((stereo << 342 215 343 /* !! 216 static int snd_pmac_burgundy_info_switch_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 344 * Burgundy switch: 0/1, mono/stereo, word reg << 345 */ << 346 static int snd_pmac_burgundy_info_switch_w(str << 347 str << 348 { 217 { 349 int stereo = (kcontrol->private_value 218 int stereo = (kcontrol->private_value >> 24) & 1; 350 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOL 219 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 351 uinfo->count = stereo + 1; 220 uinfo->count = stereo + 1; 352 uinfo->value.integer.min = 0; 221 uinfo->value.integer.min = 0; 353 uinfo->value.integer.max = 1; 222 uinfo->value.integer.max = 1; 354 return 0; 223 return 0; 355 } 224 } 356 225 357 static int snd_pmac_burgundy_get_switch_w(stru !! 226 static int snd_pmac_burgundy_get_switch_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 358 stru << 359 { 227 { 360 struct snd_pmac *chip = snd_kcontrol_c !! 228 pmac_t *chip = snd_kcontrol_chip(kcontrol); 361 unsigned int addr = BASE2ADDR((kcontro !! 229 int lmask = kcontrol->private_value & 0xff; 362 int lmask = 1 << (kcontrol->private_va !! 230 int rmask = (kcontrol->private_value >> 8) & 0xff; 363 int rmask = 1 << ((kcontrol->private_v << 364 int stereo = (kcontrol->private_value 231 int stereo = (kcontrol->private_value >> 24) & 1; 365 int val = snd_pmac_burgundy_rcw(chip, !! 232 int val = snd_pmac_burgundy_rcb(chip, MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES); 366 ucontrol->value.integer.value[0] = (va 233 ucontrol->value.integer.value[0] = (val & lmask) ? 1 : 0; 367 if (stereo) 234 if (stereo) 368 ucontrol->value.integer.value[ 235 ucontrol->value.integer.value[1] = (val & rmask) ? 1 : 0; 369 return 0; 236 return 0; 370 } 237 } 371 238 372 static int snd_pmac_burgundy_put_switch_w(stru !! 239 static int snd_pmac_burgundy_put_switch_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 373 stru << 374 { 240 { 375 struct snd_pmac *chip = snd_kcontrol_c !! 241 pmac_t *chip = snd_kcontrol_chip(kcontrol); 376 unsigned int addr = BASE2ADDR((kcontro !! 242 int lmask = kcontrol->private_value & 0xff; 377 int lmask = 1 << (kcontrol->private_va !! 243 int rmask = (kcontrol->private_value >> 8) & 0xff; 378 int rmask = 1 << ((kcontrol->private_v << 379 int stereo = (kcontrol->private_value 244 int stereo = (kcontrol->private_value >> 24) & 1; 380 int val, oval; 245 int val, oval; 381 oval = snd_pmac_burgundy_rcw(chip, add !! 246 oval = snd_pmac_burgundy_rcb(chip, MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES); 382 val = oval & ~(lmask | (stereo ? rmask !! 247 val = oval & ~(lmask | rmask); 383 if (ucontrol->value.integer.value[0]) 248 if (ucontrol->value.integer.value[0]) 384 val |= lmask; 249 val |= lmask; 385 if (stereo && ucontrol->value.integer. 250 if (stereo && ucontrol->value.integer.value[1]) 386 val |= rmask; 251 val |= rmask; 387 snd_pmac_burgundy_wcw(chip, addr, val) !! 252 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, val); 388 return val != oval; 253 return val != oval; 389 } 254 } 390 255 391 #define BURGUNDY_SWITCH_W(xname, xindex, addr, !! 256 #define BURGUNDY_OUTPUT_SWITCH(xname, xindex, lmask, rmask, stereo) \ 392 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = 257 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\ 393 .info = snd_pmac_burgundy_info_switch_w,\ !! 258 .info = snd_pmac_burgundy_info_switch_out,\ 394 .get = snd_pmac_burgundy_get_switch_w,\ !! 259 .get = snd_pmac_burgundy_get_switch_out,\ 395 .put = snd_pmac_burgundy_put_switch_w,\ !! 260 .put = snd_pmac_burgundy_put_switch_out,\ 396 .private_value = ((lbit) | ((rbit) << 8)\ !! 261 .private_value = ((lmask) | ((rmask) << 8) | ((stereo) << 24)) } 397 | (ADDR2BASE(addr) << 16) | (( << 398 262 399 /* !! 263 /* line/speaker output volume */ 400 * Burgundy switch: 0/1, mono/stereo, byte reg !! 264 static int snd_pmac_burgundy_info_volume_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 401 */ << 402 static int snd_pmac_burgundy_info_switch_b(str << 403 str << 404 { 265 { 405 int stereo = (kcontrol->private_value 266 int stereo = (kcontrol->private_value >> 24) & 1; 406 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOL !! 267 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 407 uinfo->count = stereo + 1; 268 uinfo->count = stereo + 1; 408 uinfo->value.integer.min = 0; 269 uinfo->value.integer.min = 0; 409 uinfo->value.integer.max = 1; !! 270 uinfo->value.integer.max = 15; 410 return 0; 271 return 0; 411 } 272 } 412 273 413 static int snd_pmac_burgundy_get_switch_b(stru !! 274 static int snd_pmac_burgundy_get_volume_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 414 stru << 415 { 275 { 416 struct snd_pmac *chip = snd_kcontrol_c !! 276 pmac_t *chip = snd_kcontrol_chip(kcontrol); 417 unsigned int addr = BASE2ADDR((kcontro !! 277 unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff); 418 int lmask = kcontrol->private_value & << 419 int rmask = (kcontrol->private_value > << 420 int stereo = (kcontrol->private_value 278 int stereo = (kcontrol->private_value >> 24) & 1; 421 int val = snd_pmac_burgundy_rcb(chip, !! 279 int oval; 422 ucontrol->value.integer.value[0] = (va !! 280 >> 281 oval = ~snd_pmac_burgundy_rcb(chip, addr) & 0xff; >> 282 ucontrol->value.integer.value[0] = oval & 0xf; 423 if (stereo) 283 if (stereo) 424 ucontrol->value.integer.value[ !! 284 ucontrol->value.integer.value[1] = (oval >> 4) & 0xf; 425 return 0; 285 return 0; 426 } 286 } 427 287 428 static int snd_pmac_burgundy_put_switch_b(stru !! 288 static int snd_pmac_burgundy_put_volume_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 429 stru << 430 { 289 { 431 struct snd_pmac *chip = snd_kcontrol_c !! 290 pmac_t *chip = snd_kcontrol_chip(kcontrol); 432 unsigned int addr = BASE2ADDR((kcontro !! 291 unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff); 433 int lmask = kcontrol->private_value & << 434 int rmask = (kcontrol->private_value > << 435 int stereo = (kcontrol->private_value 292 int stereo = (kcontrol->private_value >> 24) & 1; 436 int val, oval; !! 293 int oval, val; 437 oval = snd_pmac_burgundy_rcb(chip, add !! 294 438 val = oval & ~(lmask | rmask); !! 295 oval = ~snd_pmac_burgundy_rcb(chip, addr) & 0xff; 439 if (ucontrol->value.integer.value[0]) !! 296 val = ucontrol->value.integer.value[0]; 440 val |= lmask; !! 297 if (stereo) 441 if (stereo && ucontrol->value.integer. !! 298 val |= ucontrol->value.integer.value[1] << 4; 442 val |= rmask; !! 299 else >> 300 val |= ucontrol->value.integer.value[0] << 4; >> 301 val = ~val & 0xff; 443 snd_pmac_burgundy_wcb(chip, addr, val) 302 snd_pmac_burgundy_wcb(chip, addr, val); 444 return val != oval; 303 return val != oval; 445 } 304 } 446 305 447 #define BURGUNDY_SWITCH_B(xname, xindex, addr, !! 306 #define BURGUNDY_OUTPUT_VOLUME(xname, xindex, addr, stereo) \ 448 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = 307 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\ 449 .info = snd_pmac_burgundy_info_switch_b,\ !! 308 .info = snd_pmac_burgundy_info_volume_out,\ 450 .get = snd_pmac_burgundy_get_switch_b,\ !! 309 .get = snd_pmac_burgundy_get_volume_out,\ 451 .put = snd_pmac_burgundy_put_switch_b,\ !! 310 .put = snd_pmac_burgundy_put_volume_out,\ 452 .private_value = ((lmask) | ((rmask) << 8)\ !! 311 .private_value = (ADDR2BASE(addr) | ((stereo) << 24)) } 453 | (ADDR2BASE(addr) << 16) | (( !! 312 >> 313 static snd_kcontrol_new_t snd_pmac_burgundy_mixers[] __initdata = { >> 314 BURGUNDY_VOLUME("Master Playback Volume", 0, MASK_ADDR_BURGUNDY_MASTER_VOLUME, 8), >> 315 BURGUNDY_VOLUME("Line Playback Volume", 0, MASK_ADDR_BURGUNDY_VOLLINE, 16), >> 316 BURGUNDY_VOLUME("CD Playback Volume", 0, MASK_ADDR_BURGUNDY_VOLCD, 16), >> 317 BURGUNDY_VOLUME("Mic Playback Volume", 0, MASK_ADDR_BURGUNDY_VOLMIC, 16), >> 318 BURGUNDY_OUTPUT_VOLUME("PC Speaker Playback Volume", 0, MASK_ADDR_BURGUNDY_ATTENHP, 0), >> 319 /*BURGUNDY_OUTPUT_VOLUME("PCM Playback Volume", 0, MASK_ADDR_BURGUNDY_ATTENLINEOUT, 1),*/ >> 320 BURGUNDY_OUTPUT_VOLUME("Headphone Playback Volume", 0, MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1), >> 321 }; >> 322 static snd_kcontrol_new_t snd_pmac_burgundy_master_sw __initdata = >> 323 BURGUNDY_OUTPUT_SWITCH("Headphone Playback Switch", 0, BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1); >> 324 static snd_kcontrol_new_t snd_pmac_burgundy_speaker_sw __initdata = >> 325 BURGUNDY_OUTPUT_SWITCH("PC Speaker Playback Switch", 0, BURGUNDY_OUTPUT_INTERN, 0, 0); 454 326 455 /* !! 327 #define num_controls(ary) (sizeof(ary) / sizeof(snd_kcontrol_new_t)) 456 * Burgundy mixers << 457 */ << 458 static const struct snd_kcontrol_new snd_pmac_ << 459 BURGUNDY_VOLUME_W("Master Playback Vol << 460 MASK_ADDR_BURGUNDY_MAS << 461 BURGUNDY_VOLUME_W("CD Capture Volume", << 462 MASK_ADDR_BURGUNDY_VOL << 463 BURGUNDY_VOLUME_2B("Input Capture Volu << 464 MASK_ADDR_BURGUNDY_VOL << 465 BURGUNDY_VOLUME_2B("Mixer Playback Vol << 466 MASK_ADDR_BURGUNDY_VOL << 467 BURGUNDY_VOLUME_B("CD Gain Capture Vol << 468 MASK_ADDR_BURGUNDY_GAI << 469 BURGUNDY_SWITCH_W("Master Capture Swit << 470 MASK_ADDR_BURGUNDY_OUT << 471 BURGUNDY_SWITCH_W("CD Capture Switch", << 472 MASK_ADDR_BURGUNDY_CAP << 473 BURGUNDY_SWITCH_W("CD Playback Switch" << 474 MASK_ADDR_BURGUNDY_OUT << 475 /* BURGUNDY_SWITCH_W("Loop Capture Switch << 476 * MASK_ADDR_BURGUNDY_CAPTURESELE << 477 * BURGUNDY_SWITCH_B("Mixer out Capture S << 478 * MASK_ADDR_BURGUNDY_HOSTIFAD, 0 << 479 * BURGUNDY_SWITCH_B("Mixer Capture Switc << 480 * MASK_ADDR_BURGUNDY_HOSTIFAD, 0 << 481 * BURGUNDY_SWITCH_B("PCM out Capture Swi << 482 * MASK_ADDR_BURGUNDY_HOSTIFEH, 0 << 483 */ BURGUNDY_SWITCH_B("PCM Capture Switch" << 484 MASK_ADDR_BURGUNDY_HOS << 485 }; << 486 static const struct snd_kcontrol_new snd_pmac_ << 487 BURGUNDY_VOLUME_W("Line in Capture Vol << 488 MASK_ADDR_BURGUNDY_VOL << 489 BURGUNDY_VOLUME_W("Mic Capture Volume" << 490 MASK_ADDR_BURGUNDY_VOL << 491 BURGUNDY_VOLUME_B("Line in Gain Captur << 492 MASK_ADDR_BURGUNDY_GAI << 493 BURGUNDY_VOLUME_B("Mic Gain Capture Vo << 494 MASK_ADDR_BURGUNDY_GAI << 495 BURGUNDY_VOLUME_B("Speaker Playback Vo << 496 MASK_ADDR_BURGUNDY_ATT << 497 BURGUNDY_VOLUME_B("Line out Playback V << 498 MASK_ADDR_BURGUNDY_ATT << 499 BURGUNDY_VOLUME_B("Headphone Playback << 500 MASK_ADDR_BURGUNDY_ATT << 501 BURGUNDY_SWITCH_W("Line in Capture Swi << 502 MASK_ADDR_BURGUNDY_CAP << 503 BURGUNDY_SWITCH_W("Mic Capture Switch" << 504 MASK_ADDR_BURGUNDY_CAP << 505 BURGUNDY_SWITCH_W("Line in Playback Sw << 506 MASK_ADDR_BURGUNDY_OUT << 507 BURGUNDY_SWITCH_W("Mic Playback Switch << 508 MASK_ADDR_BURGUNDY_OUT << 509 BURGUNDY_SWITCH_B("Mic Boost Capture S << 510 MASK_ADDR_BURGUNDY_INP << 511 }; << 512 static const struct snd_kcontrol_new snd_pmac_ << 513 BURGUNDY_VOLUME_W("Line in Capture Vol << 514 MASK_ADDR_BURGUNDY_VOL << 515 BURGUNDY_VOLUME_B("Line in Gain Captur << 516 MASK_ADDR_BURGUNDY_GAI << 517 BURGUNDY_VOLUME_B("Speaker Playback Vo << 518 MASK_ADDR_BURGUNDY_ATT << 519 BURGUNDY_VOLUME_B("Line out Playback V << 520 MASK_ADDR_BURGUNDY_ATT << 521 BURGUNDY_SWITCH_W("Line in Capture Swi << 522 MASK_ADDR_BURGUNDY_CAP << 523 BURGUNDY_SWITCH_W("Line in Playback Sw << 524 MASK_ADDR_BURGUNDY_OUT << 525 /* BURGUNDY_SWITCH_B("Line in Boost Captu << 526 * MASK_ADDR_BURGUNDY_INPBOOST, 0 << 527 }; << 528 static const struct snd_kcontrol_new snd_pmac_ << 529 BURGUNDY_SWITCH_B("Master Playback Switch", 0, << 530 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, << 531 BURGUNDY_OUTPUT_LEFT | BURGUNDY_LINEOU << 532 BURGUNDY_OUTPUT_RIGHT | BURGUNDY_LINEO << 533 static const struct snd_kcontrol_new snd_pmac_ << 534 BURGUNDY_SWITCH_B("Master Playback Switch", 0, << 535 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, << 536 BURGUNDY_OUTPUT_INTERN << 537 | BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPU << 538 static const struct snd_kcontrol_new snd_pmac_ << 539 BURGUNDY_SWITCH_B("Speaker Playback Switch", 0 << 540 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, << 541 BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_ << 542 static const struct snd_kcontrol_new snd_pmac_ << 543 BURGUNDY_SWITCH_B("Speaker Playback Switch", 0 << 544 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, << 545 BURGUNDY_OUTPUT_INTERN, 0, 0); << 546 static const struct snd_kcontrol_new snd_pmac_ << 547 BURGUNDY_SWITCH_B("Line out Playback Switch", << 548 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, << 549 BURGUNDY_LINEOUT_LEFT, BURGUNDY_LINEOU << 550 static const struct snd_kcontrol_new snd_pmac_ << 551 BURGUNDY_SWITCH_B("Line out Playback Switch", << 552 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, << 553 BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_ << 554 static const struct snd_kcontrol_new snd_pmac_ << 555 BURGUNDY_SWITCH_B("Headphone Playback Switch", << 556 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, << 557 BURGUNDY_HP_LEFT, BURGUNDY_HP_RIGHT, 1 << 558 328 559 329 560 #ifdef PMAC_SUPPORT_AUTOMUTE 330 #ifdef PMAC_SUPPORT_AUTOMUTE 561 /* 331 /* 562 * auto-mute stuffs 332 * auto-mute stuffs 563 */ 333 */ 564 static int snd_pmac_burgundy_detect_headphone( !! 334 static int snd_pmac_burgundy_detect_headphone(pmac_t *chip) 565 { 335 { 566 return (in_le32(&chip->awacs->codec_st 336 return (in_le32(&chip->awacs->codec_stat) & chip->hp_stat_mask) ? 1 : 0; 567 } 337 } 568 338 569 static void snd_pmac_burgundy_update_automute( !! 339 static void snd_pmac_burgundy_update_automute(pmac_t *chip, int do_notify) 570 { 340 { 571 if (chip->auto_mute) { 341 if (chip->auto_mute) { 572 int imac = of_machine_is_compa << 573 int reg, oreg; 342 int reg, oreg; 574 reg = oreg = snd_pmac_burgundy !! 343 reg = oreg = snd_pmac_burgundy_rcb(chip, MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES); 575 MASK_ADDR_BURG !! 344 reg &= ~(BURGUNDY_OUTPUT_LEFT | BURGUNDY_OUTPUT_RIGHT | BURGUNDY_OUTPUT_INTERN); 576 reg &= imac ? ~(BURGUNDY_OUTPU << 577 | BURGUNDY_HP_ << 578 : ~(BURGUNDY_OUTPUT_LE << 579 | BURGUNDY_OUT << 580 if (snd_pmac_burgundy_detect_h 345 if (snd_pmac_burgundy_detect_headphone(chip)) 581 reg |= imac ? (BURGUND !! 346 reg |= BURGUNDY_OUTPUT_LEFT | BURGUNDY_OUTPUT_RIGHT; 582 : (BURGUNDY_OU << 583 | BURG << 584 else 347 else 585 reg |= imac ? (BURGUND !! 348 reg |= BURGUNDY_OUTPUT_INTERN; 586 | BURG << 587 : (BURGUNDY_OU << 588 if (do_notify && reg == oreg) 349 if (do_notify && reg == oreg) 589 return; 350 return; 590 snd_pmac_burgundy_wcb(chip, !! 351 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, reg); 591 MASK_ADDR_BURG << 592 if (do_notify) { 352 if (do_notify) { 593 snd_ctl_notify(chip->c 353 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, 594 &chip-> 354 &chip->master_sw_ctl->id); 595 snd_ctl_notify(chip->c 355 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, 596 &chip-> 356 &chip->speaker_sw_ctl->id); 597 snd_ctl_notify(chip->c 357 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, 598 &chip-> 358 &chip->hp_detect_ctl->id); 599 } 359 } 600 } 360 } 601 } 361 } 602 #endif /* PMAC_SUPPORT_AUTOMUTE */ 362 #endif /* PMAC_SUPPORT_AUTOMUTE */ 603 363 604 364 605 /* 365 /* 606 * initialize burgundy 366 * initialize burgundy 607 */ 367 */ 608 int snd_pmac_burgundy_init(struct snd_pmac *ch !! 368 int __init snd_pmac_burgundy_init(pmac_t *chip) 609 { 369 { 610 int imac = of_machine_is_compatible("i << 611 int i, err; 370 int i, err; 612 371 613 /* Checks to see the chip is alive and 372 /* Checks to see the chip is alive and kicking */ 614 if ((in_le32(&chip->awacs->codec_ctrl) 373 if ((in_le32(&chip->awacs->codec_ctrl) & MASK_ERRCODE) == 0xf0000) { 615 printk(KERN_WARNING "pmac burg 374 printk(KERN_WARNING "pmac burgundy: disabled by MacOS :-(\n"); 616 return 1; 375 return 1; 617 } 376 } 618 377 619 snd_pmac_burgundy_wcw(chip, MASK_ADDR_ !! 378 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_OUTPUTENABLES, 620 DEF_BURGUNDY_OUTPUT 379 DEF_BURGUNDY_OUTPUTENABLES); 621 snd_pmac_burgundy_wcb(chip, MASK_ADDR_ 380 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, 622 DEF_BURGUNDY_MORE_O 381 DEF_BURGUNDY_MORE_OUTPUTENABLES); 623 snd_pmac_burgundy_wcw(chip, MASK_ADDR_ 382 snd_pmac_burgundy_wcw(chip, MASK_ADDR_BURGUNDY_OUTPUTSELECTS, 624 DEF_BURGUNDY_OUTPUT 383 DEF_BURGUNDY_OUTPUTSELECTS); 625 384 626 snd_pmac_burgundy_wcb(chip, MASK_ADDR_ 385 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_INPSEL21, 627 DEF_BURGUNDY_INPSEL 386 DEF_BURGUNDY_INPSEL21); 628 snd_pmac_burgundy_wcb(chip, MASK_ADDR_ 387 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_INPSEL3, 629 imac ? DEF_BURGUNDY !! 388 DEF_BURGUNDY_INPSEL3); 630 : DEF_BURGUNDY_INPS << 631 snd_pmac_burgundy_wcb(chip, MASK_ADDR_ 389 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_GAINCD, 632 DEF_BURGUNDY_GAINCD 390 DEF_BURGUNDY_GAINCD); 633 snd_pmac_burgundy_wcb(chip, MASK_ADDR_ 391 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_GAINLINE, 634 DEF_BURGUNDY_GAINLI 392 DEF_BURGUNDY_GAINLINE); 635 snd_pmac_burgundy_wcb(chip, MASK_ADDR_ 393 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_GAINMIC, 636 DEF_BURGUNDY_GAINMI 394 DEF_BURGUNDY_GAINMIC); 637 snd_pmac_burgundy_wcb(chip, MASK_ADDR_ 395 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_GAINMODEM, 638 DEF_BURGUNDY_GAINMO 396 DEF_BURGUNDY_GAINMODEM); 639 397 640 snd_pmac_burgundy_wcb(chip, MASK_ADDR_ 398 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_ATTENSPEAKER, 641 DEF_BURGUNDY_ATTENS 399 DEF_BURGUNDY_ATTENSPEAKER); 642 snd_pmac_burgundy_wcb(chip, MASK_ADDR_ 400 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_ATTENLINEOUT, 643 DEF_BURGUNDY_ATTENL 401 DEF_BURGUNDY_ATTENLINEOUT); 644 snd_pmac_burgundy_wcb(chip, MASK_ADDR_ 402 snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_ATTENHP, 645 DEF_BURGUNDY_ATTENH 403 DEF_BURGUNDY_ATTENHP); 646 404 647 snd_pmac_burgundy_wcw(chip, MASK_ADDR_ 405 snd_pmac_burgundy_wcw(chip, MASK_ADDR_BURGUNDY_MASTER_VOLUME, 648 DEF_BURGUNDY_MASTER 406 DEF_BURGUNDY_MASTER_VOLUME); 649 snd_pmac_burgundy_wcw(chip, MASK_ADDR_ 407 snd_pmac_burgundy_wcw(chip, MASK_ADDR_BURGUNDY_VOLCD, 650 DEF_BURGUNDY_VOLCD) 408 DEF_BURGUNDY_VOLCD); 651 snd_pmac_burgundy_wcw(chip, MASK_ADDR_ 409 snd_pmac_burgundy_wcw(chip, MASK_ADDR_BURGUNDY_VOLLINE, 652 DEF_BURGUNDY_VOLLIN 410 DEF_BURGUNDY_VOLLINE); 653 snd_pmac_burgundy_wcw(chip, MASK_ADDR_ 411 snd_pmac_burgundy_wcw(chip, MASK_ADDR_BURGUNDY_VOLMIC, 654 DEF_BURGUNDY_VOLMIC 412 DEF_BURGUNDY_VOLMIC); 655 413 656 if (chip->hp_stat_mask == 0) { !! 414 if (chip->hp_stat_mask == 0) 657 /* set headphone-jack detectio 415 /* set headphone-jack detection bit */ 658 if (imac) !! 416 chip->hp_stat_mask = 0x04; 659 chip->hp_stat_mask = B !! 417 660 | BURGUNDY_HPD << 661 | BURGUNDY_HPD << 662 else << 663 chip->hp_stat_mask = B << 664 } << 665 /* 418 /* 666 * build burgundy mixers 419 * build burgundy mixers 667 */ 420 */ 668 strcpy(chip->card->mixername, "PowerMa 421 strcpy(chip->card->mixername, "PowerMac Burgundy"); 669 422 670 for (i = 0; i < ARRAY_SIZE(snd_pmac_bu !! 423 for (i = 0; i < num_controls(snd_pmac_burgundy_mixers); i++) { 671 err = snd_ctl_add(chip->card, !! 424 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_pmac_burgundy_mixers[i], chip))) < 0) 672 snd_ctl_new1(&snd_pmac_bur << 673 if (err < 0) << 674 return err; 425 return err; 675 } 426 } 676 for (i = 0; i < (imac ? ARRAY_SIZE(snd !! 427 chip->master_sw_ctl = snd_ctl_new1(&snd_pmac_burgundy_master_sw, chip); 677 : ARRAY_SIZE(snd_pmac_ !! 428 if ((err = snd_ctl_add(chip->card, chip->master_sw_ctl)) < 0) 678 err = snd_ctl_add(chip->card, << 679 snd_ctl_new1(imac ? &snd_p << 680 : &snd_pmac_burgundy_mixer << 681 if (err < 0) << 682 return err; << 683 } << 684 chip->master_sw_ctl = snd_ctl_new1(ima << 685 ? &snd_pmac_burgundy_m << 686 : &snd_pmac_burgundy_m << 687 err = snd_ctl_add(chip->card, chip->ma << 688 if (err < 0) << 689 return err; << 690 chip->master_sw_ctl = snd_ctl_new1(ima << 691 ? &snd_pmac_burgundy_l << 692 : &snd_pmac_burgundy_l << 693 err = snd_ctl_add(chip->card, chip->ma << 694 if (err < 0) << 695 return err; 429 return err; 696 if (imac) { !! 430 chip->speaker_sw_ctl = snd_ctl_new1(&snd_pmac_burgundy_speaker_sw, chip); 697 chip->master_sw_ctl = snd_ctl_ !! 431 if ((err = snd_ctl_add(chip->card, chip->speaker_sw_ctl)) < 0) 698 &snd_pmac_burg << 699 err = snd_ctl_add(chip->card, << 700 if (err < 0) << 701 return err; << 702 } << 703 chip->speaker_sw_ctl = snd_ctl_new1(im << 704 ? &snd_pmac_burgundy_s << 705 : &snd_pmac_burgundy_s << 706 err = snd_ctl_add(chip->card, chip->sp << 707 if (err < 0) << 708 return err; 432 return err; 709 #ifdef PMAC_SUPPORT_AUTOMUTE 433 #ifdef PMAC_SUPPORT_AUTOMUTE 710 err = snd_pmac_add_automute(chip); !! 434 if ((err = snd_pmac_add_automute(chip)) < 0) 711 if (err < 0) << 712 return err; 435 return err; 713 436 714 chip->detect_headphone = snd_pmac_burg 437 chip->detect_headphone = snd_pmac_burgundy_detect_headphone; 715 chip->update_automute = snd_pmac_burgu 438 chip->update_automute = snd_pmac_burgundy_update_automute; 716 snd_pmac_burgundy_update_automute(chip 439 snd_pmac_burgundy_update_automute(chip, 0); /* update the status only */ 717 #endif 440 #endif 718 441 719 return 0; 442 return 0; 720 } 443 } 721 444
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.