ad1843.c (15708B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * AD1843 low level driver 4 * 5 * Copyright 2003 Vivien Chappelier <vivien.chappelier@linux-mips.org> 6 * Copyright 2008 Thomas Bogendoerfer <tsbogend@alpha.franken.de> 7 * 8 * inspired from vwsnd.c (SGI VW audio driver) 9 * Copyright 1999 Silicon Graphics, Inc. All rights reserved. 10 */ 11 12#include <linux/init.h> 13#include <linux/sched.h> 14#include <linux/errno.h> 15#include <sound/core.h> 16#include <sound/pcm.h> 17#include <sound/ad1843.h> 18 19/* 20 * AD1843 bitfield definitions. All are named as in the AD1843 data 21 * sheet, with ad1843_ prepended and individual bit numbers removed. 22 * 23 * E.g., bits LSS0 through LSS2 become ad1843_LSS. 24 * 25 * Only the bitfields we need are defined. 26 */ 27 28struct ad1843_bitfield { 29 char reg; 30 char lo_bit; 31 char nbits; 32}; 33 34static const struct ad1843_bitfield 35 ad1843_PDNO = { 0, 14, 1 }, /* Converter Power-Down Flag */ 36 ad1843_INIT = { 0, 15, 1 }, /* Clock Initialization Flag */ 37 ad1843_RIG = { 2, 0, 4 }, /* Right ADC Input Gain */ 38 ad1843_RMGE = { 2, 4, 1 }, /* Right ADC Mic Gain Enable */ 39 ad1843_RSS = { 2, 5, 3 }, /* Right ADC Source Select */ 40 ad1843_LIG = { 2, 8, 4 }, /* Left ADC Input Gain */ 41 ad1843_LMGE = { 2, 12, 1 }, /* Left ADC Mic Gain Enable */ 42 ad1843_LSS = { 2, 13, 3 }, /* Left ADC Source Select */ 43 ad1843_RD2M = { 3, 0, 5 }, /* Right DAC 2 Mix Gain/Atten */ 44 ad1843_RD2MM = { 3, 7, 1 }, /* Right DAC 2 Mix Mute */ 45 ad1843_LD2M = { 3, 8, 5 }, /* Left DAC 2 Mix Gain/Atten */ 46 ad1843_LD2MM = { 3, 15, 1 }, /* Left DAC 2 Mix Mute */ 47 ad1843_RX1M = { 4, 0, 5 }, /* Right Aux 1 Mix Gain/Atten */ 48 ad1843_RX1MM = { 4, 7, 1 }, /* Right Aux 1 Mix Mute */ 49 ad1843_LX1M = { 4, 8, 5 }, /* Left Aux 1 Mix Gain/Atten */ 50 ad1843_LX1MM = { 4, 15, 1 }, /* Left Aux 1 Mix Mute */ 51 ad1843_RX2M = { 5, 0, 5 }, /* Right Aux 2 Mix Gain/Atten */ 52 ad1843_RX2MM = { 5, 7, 1 }, /* Right Aux 2 Mix Mute */ 53 ad1843_LX2M = { 5, 8, 5 }, /* Left Aux 2 Mix Gain/Atten */ 54 ad1843_LX2MM = { 5, 15, 1 }, /* Left Aux 2 Mix Mute */ 55 ad1843_RMCM = { 7, 0, 5 }, /* Right Mic Mix Gain/Atten */ 56 ad1843_RMCMM = { 7, 7, 1 }, /* Right Mic Mix Mute */ 57 ad1843_LMCM = { 7, 8, 5 }, /* Left Mic Mix Gain/Atten */ 58 ad1843_LMCMM = { 7, 15, 1 }, /* Left Mic Mix Mute */ 59 ad1843_HPOS = { 8, 4, 1 }, /* Headphone Output Voltage Swing */ 60 ad1843_HPOM = { 8, 5, 1 }, /* Headphone Output Mute */ 61 ad1843_MPOM = { 8, 6, 1 }, /* Mono Output Mute */ 62 ad1843_RDA1G = { 9, 0, 6 }, /* Right DAC1 Analog/Digital Gain */ 63 ad1843_RDA1GM = { 9, 7, 1 }, /* Right DAC1 Analog Mute */ 64 ad1843_LDA1G = { 9, 8, 6 }, /* Left DAC1 Analog/Digital Gain */ 65 ad1843_LDA1GM = { 9, 15, 1 }, /* Left DAC1 Analog Mute */ 66 ad1843_RDA2G = { 10, 0, 6 }, /* Right DAC2 Analog/Digital Gain */ 67 ad1843_RDA2GM = { 10, 7, 1 }, /* Right DAC2 Analog Mute */ 68 ad1843_LDA2G = { 10, 8, 6 }, /* Left DAC2 Analog/Digital Gain */ 69 ad1843_LDA2GM = { 10, 15, 1 }, /* Left DAC2 Analog Mute */ 70 ad1843_RDA1AM = { 11, 7, 1 }, /* Right DAC1 Digital Mute */ 71 ad1843_LDA1AM = { 11, 15, 1 }, /* Left DAC1 Digital Mute */ 72 ad1843_RDA2AM = { 12, 7, 1 }, /* Right DAC2 Digital Mute */ 73 ad1843_LDA2AM = { 12, 15, 1 }, /* Left DAC2 Digital Mute */ 74 ad1843_ADLC = { 15, 0, 2 }, /* ADC Left Sample Rate Source */ 75 ad1843_ADRC = { 15, 2, 2 }, /* ADC Right Sample Rate Source */ 76 ad1843_DA1C = { 15, 8, 2 }, /* DAC1 Sample Rate Source */ 77 ad1843_DA2C = { 15, 10, 2 }, /* DAC2 Sample Rate Source */ 78 ad1843_C1C = { 17, 0, 16 }, /* Clock 1 Sample Rate Select */ 79 ad1843_C2C = { 20, 0, 16 }, /* Clock 2 Sample Rate Select */ 80 ad1843_C3C = { 23, 0, 16 }, /* Clock 3 Sample Rate Select */ 81 ad1843_DAADL = { 25, 4, 2 }, /* Digital ADC Left Source Select */ 82 ad1843_DAADR = { 25, 6, 2 }, /* Digital ADC Right Source Select */ 83 ad1843_DAMIX = { 25, 14, 1 }, /* DAC Digital Mix Enable */ 84 ad1843_DRSFLT = { 25, 15, 1 }, /* Digital Reampler Filter Mode */ 85 ad1843_ADLF = { 26, 0, 2 }, /* ADC Left Channel Data Format */ 86 ad1843_ADRF = { 26, 2, 2 }, /* ADC Right Channel Data Format */ 87 ad1843_ADTLK = { 26, 4, 1 }, /* ADC Transmit Lock Mode Select */ 88 ad1843_SCF = { 26, 7, 1 }, /* SCLK Frequency Select */ 89 ad1843_DA1F = { 26, 8, 2 }, /* DAC1 Data Format Select */ 90 ad1843_DA2F = { 26, 10, 2 }, /* DAC2 Data Format Select */ 91 ad1843_DA1SM = { 26, 14, 1 }, /* DAC1 Stereo/Mono Mode Select */ 92 ad1843_DA2SM = { 26, 15, 1 }, /* DAC2 Stereo/Mono Mode Select */ 93 ad1843_ADLEN = { 27, 0, 1 }, /* ADC Left Channel Enable */ 94 ad1843_ADREN = { 27, 1, 1 }, /* ADC Right Channel Enable */ 95 ad1843_AAMEN = { 27, 4, 1 }, /* Analog to Analog Mix Enable */ 96 ad1843_ANAEN = { 27, 7, 1 }, /* Analog Channel Enable */ 97 ad1843_DA1EN = { 27, 8, 1 }, /* DAC1 Enable */ 98 ad1843_DA2EN = { 27, 9, 1 }, /* DAC2 Enable */ 99 ad1843_DDMEN = { 27, 12, 1 }, /* DAC2 to DAC1 Mix Enable */ 100 ad1843_C1EN = { 28, 11, 1 }, /* Clock Generator 1 Enable */ 101 ad1843_C2EN = { 28, 12, 1 }, /* Clock Generator 2 Enable */ 102 ad1843_C3EN = { 28, 13, 1 }, /* Clock Generator 3 Enable */ 103 ad1843_PDNI = { 28, 15, 1 }; /* Converter Power Down */ 104 105/* 106 * The various registers of the AD1843 use three different formats for 107 * specifying gain. The ad1843_gain structure parameterizes the 108 * formats. 109 */ 110 111struct ad1843_gain { 112 int negative; /* nonzero if gain is negative. */ 113 const struct ad1843_bitfield *lfield; 114 const struct ad1843_bitfield *rfield; 115 const struct ad1843_bitfield *lmute; 116 const struct ad1843_bitfield *rmute; 117}; 118 119static const struct ad1843_gain ad1843_gain_RECLEV = { 120 .negative = 0, 121 .lfield = &ad1843_LIG, 122 .rfield = &ad1843_RIG 123}; 124static const struct ad1843_gain ad1843_gain_LINE = { 125 .negative = 1, 126 .lfield = &ad1843_LX1M, 127 .rfield = &ad1843_RX1M, 128 .lmute = &ad1843_LX1MM, 129 .rmute = &ad1843_RX1MM 130}; 131static const struct ad1843_gain ad1843_gain_LINE_2 = { 132 .negative = 1, 133 .lfield = &ad1843_LDA2G, 134 .rfield = &ad1843_RDA2G, 135 .lmute = &ad1843_LDA2GM, 136 .rmute = &ad1843_RDA2GM 137}; 138static const struct ad1843_gain ad1843_gain_MIC = { 139 .negative = 1, 140 .lfield = &ad1843_LMCM, 141 .rfield = &ad1843_RMCM, 142 .lmute = &ad1843_LMCMM, 143 .rmute = &ad1843_RMCMM 144}; 145static const struct ad1843_gain ad1843_gain_PCM_0 = { 146 .negative = 1, 147 .lfield = &ad1843_LDA1G, 148 .rfield = &ad1843_RDA1G, 149 .lmute = &ad1843_LDA1GM, 150 .rmute = &ad1843_RDA1GM 151}; 152static const struct ad1843_gain ad1843_gain_PCM_1 = { 153 .negative = 1, 154 .lfield = &ad1843_LD2M, 155 .rfield = &ad1843_RD2M, 156 .lmute = &ad1843_LD2MM, 157 .rmute = &ad1843_RD2MM 158}; 159 160static const struct ad1843_gain *ad1843_gain[AD1843_GAIN_SIZE] = 161{ 162 &ad1843_gain_RECLEV, 163 &ad1843_gain_LINE, 164 &ad1843_gain_LINE_2, 165 &ad1843_gain_MIC, 166 &ad1843_gain_PCM_0, 167 &ad1843_gain_PCM_1, 168}; 169 170/* read the current value of an AD1843 bitfield. */ 171 172static int ad1843_read_bits(struct snd_ad1843 *ad1843, 173 const struct ad1843_bitfield *field) 174{ 175 int w; 176 177 w = ad1843->read(ad1843->chip, field->reg); 178 return w >> field->lo_bit & ((1 << field->nbits) - 1); 179} 180 181/* 182 * write a new value to an AD1843 bitfield and return the old value. 183 */ 184 185static int ad1843_write_bits(struct snd_ad1843 *ad1843, 186 const struct ad1843_bitfield *field, 187 int newval) 188{ 189 int w, mask, oldval, newbits; 190 191 w = ad1843->read(ad1843->chip, field->reg); 192 mask = ((1 << field->nbits) - 1) << field->lo_bit; 193 oldval = (w & mask) >> field->lo_bit; 194 newbits = (newval << field->lo_bit) & mask; 195 w = (w & ~mask) | newbits; 196 ad1843->write(ad1843->chip, field->reg, w); 197 198 return oldval; 199} 200 201/* 202 * ad1843_read_multi reads multiple bitfields from the same AD1843 203 * register. It uses a single read cycle to do it. (Reading the 204 * ad1843 requires 256 bit times at 12.288 MHz, or nearly 20 205 * microseconds.) 206 * 207 * Called like this. 208 * 209 * ad1843_read_multi(ad1843, nfields, 210 * &ad1843_FIELD1, &val1, 211 * &ad1843_FIELD2, &val2, ...); 212 */ 213 214static void ad1843_read_multi(struct snd_ad1843 *ad1843, int argcount, ...) 215{ 216 va_list ap; 217 const struct ad1843_bitfield *fp; 218 int w = 0, mask, *value, reg = -1; 219 220 va_start(ap, argcount); 221 while (--argcount >= 0) { 222 fp = va_arg(ap, const struct ad1843_bitfield *); 223 value = va_arg(ap, int *); 224 if (reg == -1) { 225 reg = fp->reg; 226 w = ad1843->read(ad1843->chip, reg); 227 } 228 229 mask = (1 << fp->nbits) - 1; 230 *value = w >> fp->lo_bit & mask; 231 } 232 va_end(ap); 233} 234 235/* 236 * ad1843_write_multi stores multiple bitfields into the same AD1843 237 * register. It uses one read and one write cycle to do it. 238 * 239 * Called like this. 240 * 241 * ad1843_write_multi(ad1843, nfields, 242 * &ad1843_FIELD1, val1, 243 * &ad1843_FIELF2, val2, ...); 244 */ 245 246static void ad1843_write_multi(struct snd_ad1843 *ad1843, int argcount, ...) 247{ 248 va_list ap; 249 int reg; 250 const struct ad1843_bitfield *fp; 251 int value; 252 int w, m, mask, bits; 253 254 mask = 0; 255 bits = 0; 256 reg = -1; 257 258 va_start(ap, argcount); 259 while (--argcount >= 0) { 260 fp = va_arg(ap, const struct ad1843_bitfield *); 261 value = va_arg(ap, int); 262 if (reg == -1) 263 reg = fp->reg; 264 else 265 WARN_ON(reg != fp->reg); 266 m = ((1 << fp->nbits) - 1) << fp->lo_bit; 267 mask |= m; 268 bits |= (value << fp->lo_bit) & m; 269 } 270 va_end(ap); 271 272 if (~mask & 0xFFFF) 273 w = ad1843->read(ad1843->chip, reg); 274 else 275 w = 0; 276 w = (w & ~mask) | bits; 277 ad1843->write(ad1843->chip, reg, w); 278} 279 280int ad1843_get_gain_max(struct snd_ad1843 *ad1843, int id) 281{ 282 const struct ad1843_gain *gp = ad1843_gain[id]; 283 int ret; 284 285 ret = (1 << gp->lfield->nbits); 286 if (!gp->lmute) 287 ret -= 1; 288 return ret; 289} 290 291/* 292 * ad1843_get_gain reads the specified register and extracts the gain value 293 * using the supplied gain type. 294 */ 295 296int ad1843_get_gain(struct snd_ad1843 *ad1843, int id) 297{ 298 int lg, rg, lm, rm; 299 const struct ad1843_gain *gp = ad1843_gain[id]; 300 unsigned short mask = (1 << gp->lfield->nbits) - 1; 301 302 ad1843_read_multi(ad1843, 2, gp->lfield, &lg, gp->rfield, &rg); 303 if (gp->negative) { 304 lg = mask - lg; 305 rg = mask - rg; 306 } 307 if (gp->lmute) { 308 ad1843_read_multi(ad1843, 2, gp->lmute, &lm, gp->rmute, &rm); 309 if (lm) 310 lg = 0; 311 if (rm) 312 rg = 0; 313 } 314 return lg << 0 | rg << 8; 315} 316 317/* 318 * Set an audio channel's gain. 319 * 320 * Returns the new gain, which may be lower than the old gain. 321 */ 322 323int ad1843_set_gain(struct snd_ad1843 *ad1843, int id, int newval) 324{ 325 const struct ad1843_gain *gp = ad1843_gain[id]; 326 unsigned short mask = (1 << gp->lfield->nbits) - 1; 327 328 int lg = (newval >> 0) & mask; 329 int rg = (newval >> 8) & mask; 330 int lm = (lg == 0) ? 1 : 0; 331 int rm = (rg == 0) ? 1 : 0; 332 333 if (gp->negative) { 334 lg = mask - lg; 335 rg = mask - rg; 336 } 337 if (gp->lmute) 338 ad1843_write_multi(ad1843, 2, gp->lmute, lm, gp->rmute, rm); 339 ad1843_write_multi(ad1843, 2, gp->lfield, lg, gp->rfield, rg); 340 return ad1843_get_gain(ad1843, id); 341} 342 343/* Returns the current recording source */ 344 345int ad1843_get_recsrc(struct snd_ad1843 *ad1843) 346{ 347 int val = ad1843_read_bits(ad1843, &ad1843_LSS); 348 349 if (val < 0 || val > 2) { 350 val = 2; 351 ad1843_write_multi(ad1843, 2, 352 &ad1843_LSS, val, &ad1843_RSS, val); 353 } 354 return val; 355} 356 357/* 358 * Set recording source. 359 * 360 * Returns newsrc on success, -errno on failure. 361 */ 362 363int ad1843_set_recsrc(struct snd_ad1843 *ad1843, int newsrc) 364{ 365 if (newsrc < 0 || newsrc > 2) 366 return -EINVAL; 367 368 ad1843_write_multi(ad1843, 2, &ad1843_LSS, newsrc, &ad1843_RSS, newsrc); 369 return newsrc; 370} 371 372/* Setup ad1843 for D/A conversion. */ 373 374void ad1843_setup_dac(struct snd_ad1843 *ad1843, 375 unsigned int id, 376 unsigned int framerate, 377 snd_pcm_format_t fmt, 378 unsigned int channels) 379{ 380 int ad_fmt = 0, ad_mode = 0; 381 382 switch (fmt) { 383 case SNDRV_PCM_FORMAT_S8: 384 ad_fmt = 0; 385 break; 386 case SNDRV_PCM_FORMAT_U8: 387 ad_fmt = 0; 388 break; 389 case SNDRV_PCM_FORMAT_S16_LE: 390 ad_fmt = 1; 391 break; 392 case SNDRV_PCM_FORMAT_MU_LAW: 393 ad_fmt = 2; 394 break; 395 case SNDRV_PCM_FORMAT_A_LAW: 396 ad_fmt = 3; 397 break; 398 default: 399 break; 400 } 401 402 switch (channels) { 403 case 2: 404 ad_mode = 0; 405 break; 406 case 1: 407 ad_mode = 1; 408 break; 409 default: 410 break; 411 } 412 413 if (id) { 414 ad1843_write_bits(ad1843, &ad1843_C2C, framerate); 415 ad1843_write_multi(ad1843, 2, 416 &ad1843_DA2SM, ad_mode, 417 &ad1843_DA2F, ad_fmt); 418 } else { 419 ad1843_write_bits(ad1843, &ad1843_C1C, framerate); 420 ad1843_write_multi(ad1843, 2, 421 &ad1843_DA1SM, ad_mode, 422 &ad1843_DA1F, ad_fmt); 423 } 424} 425 426void ad1843_shutdown_dac(struct snd_ad1843 *ad1843, unsigned int id) 427{ 428 if (id) 429 ad1843_write_bits(ad1843, &ad1843_DA2F, 1); 430 else 431 ad1843_write_bits(ad1843, &ad1843_DA1F, 1); 432} 433 434void ad1843_setup_adc(struct snd_ad1843 *ad1843, 435 unsigned int framerate, 436 snd_pcm_format_t fmt, 437 unsigned int channels) 438{ 439 int da_fmt = 0; 440 441 switch (fmt) { 442 case SNDRV_PCM_FORMAT_S8: da_fmt = 0; break; 443 case SNDRV_PCM_FORMAT_U8: da_fmt = 0; break; 444 case SNDRV_PCM_FORMAT_S16_LE: da_fmt = 1; break; 445 case SNDRV_PCM_FORMAT_MU_LAW: da_fmt = 2; break; 446 case SNDRV_PCM_FORMAT_A_LAW: da_fmt = 3; break; 447 default: break; 448 } 449 450 ad1843_write_bits(ad1843, &ad1843_C3C, framerate); 451 ad1843_write_multi(ad1843, 2, 452 &ad1843_ADLF, da_fmt, &ad1843_ADRF, da_fmt); 453} 454 455void ad1843_shutdown_adc(struct snd_ad1843 *ad1843) 456{ 457 /* nothing to do */ 458} 459 460/* 461 * Fully initialize the ad1843. As described in the AD1843 data 462 * sheet, section "START-UP SEQUENCE". The numbered comments are 463 * subsection headings from the data sheet. See the data sheet, pages 464 * 52-54, for more info. 465 * 466 * return 0 on success, -errno on failure. */ 467 468int ad1843_init(struct snd_ad1843 *ad1843) 469{ 470 unsigned long later; 471 472 if (ad1843_read_bits(ad1843, &ad1843_INIT) != 0) { 473 printk(KERN_ERR "ad1843: AD1843 won't initialize\n"); 474 return -EIO; 475 } 476 477 ad1843_write_bits(ad1843, &ad1843_SCF, 1); 478 479 /* 4. Put the conversion resources into standby. */ 480 ad1843_write_bits(ad1843, &ad1843_PDNI, 0); 481 later = jiffies + msecs_to_jiffies(500); 482 483 while (ad1843_read_bits(ad1843, &ad1843_PDNO)) { 484 if (time_after(jiffies, later)) { 485 printk(KERN_ERR 486 "ad1843: AD1843 won't power up\n"); 487 return -EIO; 488 } 489 schedule_timeout_interruptible(5); 490 } 491 492 /* 5. Power up the clock generators and enable clock output pins. */ 493 ad1843_write_multi(ad1843, 3, 494 &ad1843_C1EN, 1, 495 &ad1843_C2EN, 1, 496 &ad1843_C3EN, 1); 497 498 /* 6. Configure conversion resources while they are in standby. */ 499 500 /* DAC1/2 use clock 1/2 as source, ADC uses clock 3. Always. */ 501 ad1843_write_multi(ad1843, 4, 502 &ad1843_DA1C, 1, 503 &ad1843_DA2C, 2, 504 &ad1843_ADLC, 3, 505 &ad1843_ADRC, 3); 506 507 /* 7. Enable conversion resources. */ 508 ad1843_write_bits(ad1843, &ad1843_ADTLK, 1); 509 ad1843_write_multi(ad1843, 7, 510 &ad1843_ANAEN, 1, 511 &ad1843_AAMEN, 1, 512 &ad1843_DA1EN, 1, 513 &ad1843_DA2EN, 1, 514 &ad1843_DDMEN, 1, 515 &ad1843_ADLEN, 1, 516 &ad1843_ADREN, 1); 517 518 /* 8. Configure conversion resources while they are enabled. */ 519 520 /* set gain to 0 for all channels */ 521 ad1843_set_gain(ad1843, AD1843_GAIN_RECLEV, 0); 522 ad1843_set_gain(ad1843, AD1843_GAIN_LINE, 0); 523 ad1843_set_gain(ad1843, AD1843_GAIN_LINE_2, 0); 524 ad1843_set_gain(ad1843, AD1843_GAIN_MIC, 0); 525 ad1843_set_gain(ad1843, AD1843_GAIN_PCM_0, 0); 526 ad1843_set_gain(ad1843, AD1843_GAIN_PCM_1, 0); 527 528 /* Unmute all channels. */ 529 /* DAC1 */ 530 ad1843_write_multi(ad1843, 2, &ad1843_LDA1GM, 0, &ad1843_RDA1GM, 0); 531 /* DAC2 */ 532 ad1843_write_multi(ad1843, 2, &ad1843_LDA2GM, 0, &ad1843_RDA2GM, 0); 533 534 /* Set default recording source to Line In and set 535 * mic gain to +20 dB. 536 */ 537 ad1843_set_recsrc(ad1843, 2); 538 ad1843_write_multi(ad1843, 2, &ad1843_LMGE, 1, &ad1843_RMGE, 1); 539 540 /* Set Speaker Out level to +/- 4V and unmute it. */ 541 ad1843_write_multi(ad1843, 3, 542 &ad1843_HPOS, 1, 543 &ad1843_HPOM, 0, 544 &ad1843_MPOM, 0); 545 546 return 0; 547}