1 /* 2 * ALSA driver for AK4524 / AK4528 / AK4529 / AK4355 / AK4358 / AK4381 3 * AD and DA converters 4 * 5 * Copyright (c) 2000-2004 Jaroslav Kysela <perex@suse.cz>, 6 * Takashi Iwai <tiwai@suse.de> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 23 24 #include <sound/driver.h> 25 #include <asm/io.h> 26 #include <linux/delay.h> 27 #include <linux/interrupt.h> 28 #include <linux/init.h> 29 #include <sound/core.h> 30 #include <sound/control.h> 31 #include <sound/ak4xxx-adda.h> 32 33 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Takashi Iwai <tiwai@suse.de>"); 34 MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters"); 35 MODULE_LICENSE("GPL"); 36 37 void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsigned char val) 38 { 39 ak->ops.lock(ak, chip); 40 ak->ops.write(ak, chip, reg, val); 41 42 /* save the data */ 43 if (ak->type == SND_AK4524 || ak->type == SND_AK4528) { 44 if ((reg != 0x04 && reg != 0x05) || (val & 0x80) == 0) 45 snd_akm4xxx_set(ak, chip, reg, val); 46 else 47 snd_akm4xxx_set_ipga(ak, chip, reg, val); 48 } else { 49 /* AK4529, or else */ 50 snd_akm4xxx_set(ak, chip, reg, val); 51 } 52 ak->ops.unlock(ak, chip); 53 } 54 55 /* 56 * reset the AKM codecs 57 * @state: 1 = reset codec, 0 = restore the registers 58 * 59 * assert the reset operation and restores the register values to the chips. 60 */ 61 void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state) 62 { 63 unsigned int chip; 64 unsigned char reg; 65 66 switch (ak->type) { 67 case SND_AK4524: 68 case SND_AK4528: 69 for (chip = 0; chip < ak->num_dacs/2; chip++) { 70 snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03); 71 if (state) 72 continue; 73 /* DAC volumes */ 74 for (reg = 0x04; reg < (ak->type == SND_AK4528 ? 0x06 : 0x08); reg++) 75 snd_akm4xxx_write(ak, chip, reg, snd_akm4xxx_get(ak, chip, reg)); 76 if (ak->type == SND_AK4528) 77 continue; 78 /* IPGA */ 79 for (reg = 0x04; reg < 0x06; reg++) 80 snd_akm4xxx_write(ak, chip, reg, snd_akm4xxx_get_ipga(ak, chip, reg)); 81 } 82 break; 83 case SND_AK4529: 84 /* FIXME: needed for ak4529? */ 85 break; 86 case SND_AK4355: 87 case SND_AK4358: 88 if (state) { 89 snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */ 90 return; 91 } 92 for (reg = 0x00; reg < 0x0b; reg++) 93 if (reg != 0x01) 94 snd_akm4xxx_write(ak, 0, reg, snd_akm4xxx_get(ak, 0, reg)); 95 snd_akm4xxx_write(ak, 0, 0x01, 0x01); /* un-reset, unmute */ 96 break; 97 case SND_AK4381: 98 for (chip = 0; chip < ak->num_dacs/2; chip++) { 99 snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f); 100 if (state) 101 continue; 102 for (reg = 0x01; reg < 0x05; reg++) 103 snd_akm4xxx_write(ak, chip, reg, snd_akm4xxx_get(ak, chip, reg)); 104 } 105 break; 106 } 107 } 108 109 /* 110 * initialize all the ak4xxx chips 111 */ 112 void snd_akm4xxx_init(struct snd_akm4xxx *ak) 113 { 114 static unsigned char inits_ak4524[] = { 115 0x00, 0x07, /* 0: all power up */ 116 0x01, 0x00, /* 1: ADC/DAC reset */ 117 0x02, 0x60, /* 2: 24bit I2S */ 118 0x03, 0x19, /* 3: deemphasis off */ 119 0x01, 0x03, /* 1: ADC/DAC enable */ 120 0x04, 0x00, /* 4: ADC left muted */ 121 0x05, 0x00, /* 5: ADC right muted */ 122 0x04, 0x80, /* 4: ADC IPGA gain 0dB */ 123 0x05, 0x80, /* 5: ADC IPGA gain 0dB */ 124 0x06, 0x00, /* 6: DAC left muted */ 125 0x07, 0x00, /* 7: DAC right muted */ 126 0xff, 0xff 127 }; 128 static unsigned char inits_ak4528[] = { 129 0x00, 0x07, /* 0: all power up */ 130 0x01, 0x00, /* 1: ADC/DAC reset */ 131 0x02, 0x60, /* 2: 24bit I2S */ 132 0x03, 0x0d, /* 3: deemphasis off, turn LR highpass filters on */ 133 0x01, 0x03, /* 1: ADC/DAC enable */ 134 0x04, 0x00, /* 4: ADC left muted */ 135 0x05, 0x00, /* 5: ADC right muted */ 136 0xff, 0xff 137 }; 138 static unsigned char inits_ak4529[] = { 139 0x09, 0x01, /* 9: ATS=0, RSTN=1 */ 140 0x0a, 0x3f, /* A: all power up, no zero/overflow detection */ 141 0x00, 0x0c, /* 0: TDM=0, 24bit I2S, SMUTE=0 */ 142 0x01, 0x00, /* 1: ACKS=0, ADC, loop off */ 143 0x02, 0xff, /* 2: LOUT1 muted */ 144 0x03, 0xff, /* 3: ROUT1 muted */ 145 0x04, 0xff, /* 4: LOUT2 muted */ 146 0x05, 0xff, /* 5: ROUT2 muted */ 147 0x06, 0xff, /* 6: LOUT3 muted */ 148 0x07, 0xff, /* 7: ROUT3 muted */ 149 0x0b, 0xff, /* B: LOUT4 muted */ 150 0x0c, 0xff, /* C: ROUT4 muted */ 151 0x08, 0x55, /* 8: deemphasis all off */ 152 0xff, 0xff 153 }; 154 static unsigned char inits_ak4355[] = { 155 0x01, 0x02, /* 1: reset and soft-mute */ 156 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, disable DZF, sharp roll-off, RSTN#=0 */ 157 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ 158 // 0x02, 0x2e, /* quad speed */ 159 0x03, 0x01, /* 3: de-emphasis off */ 160 0x04, 0x00, /* 4: LOUT1 volume muted */ 161 0x05, 0x00, /* 5: ROUT1 volume muted */ 162 0x06, 0x00, /* 6: LOUT2 volume muted */ 163 0x07, 0x00, /* 7: ROUT2 volume muted */ 164 0x08, 0x00, /* 8: LOUT3 volume muted */ 165 0x09, 0x00, /* 9: ROUT3 volume muted */ 166 0x0a, 0x00, /* a: DATT speed=0, ignore DZF */ 167 0x01, 0x01, /* 1: un-reset, unmute */ 168 0xff, 0xff 169 }; 170 static unsigned char inits_ak4358[] = { 171 0x01, 0x02, /* 1: reset and soft-mute */ 172 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, disable DZF, sharp roll-off, RSTN#=0 */ 173 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ 174 // 0x02, 0x2e, /* quad speed */ 175 0x03, 0x01, /* 3: de-emphasis off */ 176 0x04, 0x00, /* 4: LOUT1 volume muted */ 177 0x05, 0x00, /* 5: ROUT1 volume muted */ 178 0x06, 0x00, /* 6: LOUT2 volume muted */ 179 0x07, 0x00, /* 7: ROUT2 volume muted */ 180 0x08, 0x00, /* 8: LOUT3 volume muted */ 181 0x09, 0x00, /* 9: ROUT3 volume muted */ 182 0x0b, 0x00, /* b: LOUT4 volume muted */ 183 0x0c, 0x00, /* c: ROUT4 volume muted */ 184 0x0a, 0x00, /* a: DATT speed=0, ignore DZF */ 185 0x01, 0x01, /* 1: un-reset, unmute */ 186 0xff, 0xff 187 }; 188 static unsigned char inits_ak4381[] = { 189 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */ 190 0x01, 0x02, /* 1: de-emphasis off, normal speed, sharp roll-off, DZF off */ 191 // 0x01, 0x12, /* quad speed */ 192 0x02, 0x00, /* 2: DZF disabled */ 193 0x03, 0x00, /* 3: LATT 0 */ 194 0x04, 0x00, /* 4: RATT 0 */ 195 0x00, 0x0f, /* 0: power-up, un-reset */ 196 0xff, 0xff 197 }; 198 199 int chip, num_chips; 200 unsigned char *ptr, reg, data, *inits; 201 202 switch (ak->type) { 203 case SND_AK4524: 204 inits = inits_ak4524; 205 num_chips = ak->num_dacs / 2; 206 break; 207 case SND_AK4528: 208 inits = inits_ak4528; 209 num_chips = ak->num_dacs / 2; 210 break; 211 case SND_AK4529: 212 inits = inits_ak4529; 213 num_chips = 1; 214 break; 215 case SND_AK4355: 216 inits = inits_ak4355; 217 num_chips = 1; 218 break; 219 case SND_AK4358: 220 inits = inits_ak4358; 221 num_chips = 1; 222 break; 223 case SND_AK4381: 224 inits = inits_ak4381; 225 num_chips = ak->num_dacs / 2; 226 break; 227 default: 228 snd_BUG(); 229 return; 230 } 231 232 for (chip = 0; chip < num_chips; chip++) { 233 ptr = inits; 234 while (*ptr != 0xff) { 235 reg = *ptr++; 236 data = *ptr++; 237 snd_akm4xxx_write(ak, chip, reg, data); 238 } 239 } 240 } 241 242 #define AK_GET_CHIP(val) (((val) >> 8) & 0xff) 243 #define AK_GET_ADDR(val) ((val) & 0xff) 244 #define AK_GET_SHIFT(val) (((val) >> 16) & 0x7f) 245 #define AK_GET_INVERT(val) (((val) >> 23) & 1) 246 #define AK_GET_MASK(val) (((val) >> 24) & 0xff) 247 #define AK_COMPOSE(chip,addr,shift,mask) (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24)) 248 #define AK_INVERT (1<<23) 249 250 static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol, 251 struct snd_ctl_elem_info *uinfo) 252 { 253 unsigned int mask = AK_GET_MASK(kcontrol->private_value); 254 255 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 256 uinfo->count = 1; 257 uinfo->value.integer.min = 0; 258 uinfo->value.integer.max = mask; 259 return 0; 260 } 261 262 static int snd_akm4xxx_volume_get(struct snd_kcontrol *kcontrol, 263 struct snd_ctl_elem_value *ucontrol) 264 { 265 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); 266 int chip = AK_GET_CHIP(kcontrol->private_value); 267 int addr = AK_GET_ADDR(kcontrol->private_value); 268 int invert = AK_GET_INVERT(kcontrol->private_value); 269 unsigned int mask = AK_GET_MASK(kcontrol->private_value); 270 unsigned char val = snd_akm4xxx_get(ak, chip, addr); 271 272 ucontrol->value.integer.value[0] = invert ? mask - val : val; 273 return 0; 274 } 275 276 static int snd_akm4xxx_volume_put(struct snd_kcontrol *kcontrol, 277 struct snd_ctl_elem_value *ucontrol) 278 { 279 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); 280 int chip = AK_GET_CHIP(kcontrol->private_value); 281 int addr = AK_GET_ADDR(kcontrol->private_value); 282 int invert = AK_GET_INVERT(kcontrol->private_value); 283 unsigned int mask = AK_GET_MASK(kcontrol->private_value); 284 unsigned char nval = ucontrol->value.integer.value[0] % (mask+1); 285 int change; 286 287 if (invert) 288 nval = mask - nval; 289 change = snd_akm4xxx_get(ak, chip, addr) != nval; 290 if (change) 291 snd_akm4xxx_write(ak, chip, addr, nval); 292 return change; 293 } 294 295 static int snd_akm4xxx_ipga_gain_info(struct snd_kcontrol *kcontrol, 296 struct snd_ctl_elem_info *uinfo) 297 { 298 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 299 uinfo->count = 1; 300 uinfo->value.integer.min = 0; 301 uinfo->value.integer.max = 36; 302 return 0; 303 } 304 305 static int snd_akm4xxx_ipga_gain_get(struct snd_kcontrol *kcontrol, 306 struct snd_ctl_elem_value *ucontrol) 307 { 308 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); 309 int chip = AK_GET_CHIP(kcontrol->private_value); 310 int addr = AK_GET_ADDR(kcontrol->private_value); 311 ucontrol->value.integer.value[0] = snd_akm4xxx_get_ipga(ak, chip, addr) & 0x7f; 312 return 0; 313 } 314 315 static int snd_akm4xxx_ipga_gain_put(struct snd_kcontrol *kcontrol, 316 struct snd_ctl_elem_value *ucontrol) 317 { 318 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); 319 int chip = AK_GET_CHIP(kcontrol->private_value); 320 int addr = AK_GET_ADDR(kcontrol->private_value); 321 unsigned char nval = (ucontrol->value.integer.value[0] % 37) | 0x80; 322 int change = snd_akm4xxx_get_ipga(ak, chip, addr) != nval; 323 if (change) 324 snd_akm4xxx_write(ak, chip, addr, nval); 325 return change; 326 } 327 328 static int snd_akm4xxx_deemphasis_info(struct snd_kcontrol *kcontrol, 329 struct snd_ctl_elem_info *uinfo) 330 { 331 static char *texts[4] = { 332 "44.1kHz", "Off", "48kHz", "32kHz", 333 }; 334 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 335 uinfo->count = 1; 336 uinfo->value.enumerated.items = 4; 337 if (uinfo->value.enumerated.item >= 4) 338 uinfo->value.enumerated.item = 3; 339 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 340 return 0; 341 } 342 343 static int snd_akm4xxx_deemphasis_get(struct snd_kcontrol *kcontrol, 344 struct snd_ctl_elem_value *ucontrol) 345 { 346 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); 347 int chip = AK_GET_CHIP(kcontrol->private_value); 348 int addr = AK_GET_ADDR(kcontrol->private_value); 349 int shift = AK_GET_SHIFT(kcontrol->private_value); 350 ucontrol->value.enumerated.item[0] = (snd_akm4xxx_get(ak, chip, addr) >> shift) & 3; 351 return 0; 352 } 353 354 static int snd_akm4xxx_deemphasis_put(struct snd_kcontrol *kcontrol, 355 struct snd_ctl_elem_value *ucontrol) 356 { 357 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); 358 int chip = AK_GET_CHIP(kcontrol->private_value); 359 int addr = AK_GET_ADDR(kcontrol->private_value); 360 int shift = AK_GET_SHIFT(kcontrol->private_value); 361 unsigned char nval = ucontrol->value.enumerated.item[0] & 3; 362 int change; 363 364 nval = (nval << shift) | (snd_akm4xxx_get(ak, chip, addr) & ~(3 << shift)); 365 change = snd_akm4xxx_get(ak, chip, addr) != nval; 366 if (change) 367 snd_akm4xxx_write(ak, chip, addr, nval); 368 return change; 369 } 370 371 /* 372 * build AK4xxx controls 373 */ 374 375 int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) 376 { 377 unsigned int idx, num_emphs; 378 struct snd_kcontrol *ctl; 379 int err; 380 381 ctl = kmalloc(sizeof(*ctl), GFP_KERNEL); 382 if (! ctl) 383 return -ENOMEM; 384 385 for (idx = 0; idx < ak->num_dacs; ++idx) { 386 memset(ctl, 0, sizeof(*ctl)); 387 strcpy(ctl->id.name, "DAC Volume"); 388 ctl->id.index = idx + ak->idx_offset * 2; 389 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 390 ctl->count = 1; 391 ctl->info = snd_akm4xxx_volume_info; 392 ctl->get = snd_akm4xxx_volume_get; 393 ctl->put = snd_akm4xxx_volume_put; 394 switch (ak->type) { 395 case SND_AK4524: 396 ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127); /* register 6 & 7 */ 397 break; 398 case SND_AK4528: 399 ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */ 400 break; 401 case SND_AK4529: { 402 int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb; /* registers 2-7 and b,c */ 403 ctl->private_value = AK_COMPOSE(0, val, 0, 255) | AK_INVERT; 404 break; 405 } 406 case SND_AK4355: 407 ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */ 408 break; 409 case SND_AK4358: 410 if (idx >= 6) 411 ctl->private_value = AK_COMPOSE(0, idx + 5, 0, 255); /* register 4-9, chip #0 only */ 412 else 413 ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */ 414 break; 415 case SND_AK4381: 416 ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255); /* register 3 & 4 */ 417 break; 418 default: 419 err = -EINVAL; 420 goto __error; 421 } 422 ctl->private_data = ak; 423 if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) 424 goto __error; 425 } 426 for (idx = 0; idx < ak->num_adcs && ak->type == SND_AK4524; ++idx) { 427 memset(ctl, 0, sizeof(*ctl)); 428 strcpy(ctl->id.name, "ADC Volume"); 429 ctl->id.index = idx + ak->idx_offset * 2; 430 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 431 ctl->count = 1; 432 ctl->info = snd_akm4xxx_volume_info; 433 ctl->get = snd_akm4xxx_volume_get; 434 ctl->put = snd_akm4xxx_volume_put; 435 ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */ 436 ctl->private_data = ak; 437 if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) 438 goto __error; 439 440 memset(ctl, 0, sizeof(*ctl)); 441 strcpy(ctl->id.name, "IPGA Analog Capture Volume"); 442 ctl->id.index = idx + ak->idx_offset * 2; 443 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 444 ctl->count = 1; 445 ctl->info = snd_akm4xxx_ipga_gain_info; 446 ctl->get = snd_akm4xxx_ipga_gain_get; 447 ctl->put = snd_akm4xxx_ipga_gain_put; 448 ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 0); /* register 4 & 5 */ 449 ctl->private_data = ak; 450 if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) 451 goto __error; 452 } 453 if (ak->type == SND_AK4355 || ak->type == SND_AK4358) 454 num_emphs = 1; 455 else 456 num_emphs = ak->num_dacs / 2; 457 for (idx = 0; idx < num_emphs; idx++) { 458 memset(ctl, 0, sizeof(*ctl)); 459 strcpy(ctl->id.name, "Deemphasis"); 460 ctl->id.index = idx + ak->idx_offset; 461 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 462 ctl->count = 1; 463 ctl->info = snd_akm4xxx_deemphasis_info; 464 ctl->get = snd_akm4xxx_deemphasis_get; 465 ctl->put = snd_akm4xxx_deemphasis_put; 466 switch (ak->type) { 467 case SND_AK4524: 468 case SND_AK4528: 469 ctl->private_value = AK_COMPOSE(idx, 3, 0, 0); /* register 3 */ 470 break; 471 case SND_AK4529: { 472 int shift = idx == 3 ? 6 : (2 - idx) * 2; 473 ctl->private_value = AK_COMPOSE(0, 8, shift, 0); /* register 8 with shift */ 474 break; 475 } 476 case SND_AK4355: 477 case SND_AK4358: 478 ctl->private_value = AK_COMPOSE(idx, 3, 0, 0); 479 break; 480 case SND_AK4381: 481 ctl->private_value = AK_COMPOSE(idx, 1, 1, 0); 482 break; 483 } 484 ctl->private_data = ak; 485 if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) 486 goto __error; 487 } 488 err = 0; 489 490 __error: 491 kfree(ctl); 492 return err; 493 } 494 495 static int __init alsa_akm4xxx_module_init(void) 496 { 497 return 0; 498 } 499 500 static void __exit alsa_akm4xxx_module_exit(void) 501 { 502 } 503 504 module_init(alsa_akm4xxx_module_init) 505 module_exit(alsa_akm4xxx_module_exit) 506 507 EXPORT_SYMBOL(snd_akm4xxx_write); 508 EXPORT_SYMBOL(snd_akm4xxx_reset); 509 EXPORT_SYMBOL(snd_akm4xxx_init); 510 EXPORT_SYMBOL(snd_akm4xxx_build_controls); 511