1/* 2 * Apple Onboard Audio driver for Onyx codec 3 * 4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net> 5 * 6 * GPL v2, can be found in COPYING. 7 * 8 * 9 * This is a driver for the pcm3052 codec chip (codenamed Onyx) 10 * that is present in newer Apple hardware (with digital output). 11 * 12 * The Onyx codec has the following connections (listed by the bit 13 * to be used in aoa_codec.connected): 14 * 0: analog output 15 * 1: digital output 16 * 2: line input 17 * 3: microphone input 18 * Note that even though I know of no machine that has for example 19 * the digital output connected but not the analog, I have handled 20 * all the different cases in the code so that this driver may serve 21 * as a good example of what to do. 22 * 23 * NOTE: This driver assumes that there's at most one chip to be 24 * used with one alsa card, in form of creating all kinds 25 * of mixer elements without regard for their existence. 26 * But snd-aoa assumes that there's at most one card, so 27 * this means you can only have one onyx on a system. This 28 * should probably be fixed by changing the assumption of 29 * having just a single card on a system, and making the 30 * 'card' pointer accessible to anyone who needs it instead 31 * of hiding it in the aoa_snd_* functions... 32 * 33 */ 34#include <linux/delay.h> 35#include <linux/module.h> 36#include <linux/slab.h> 37MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); 38MODULE_LICENSE("GPL"); 39MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa"); 40 41#include "onyx.h" 42#include "../aoa.h" 43#include "../soundbus/soundbus.h" 44 45 46#define PFX "snd-aoa-codec-onyx: " 47 48struct onyx { 49 /* cache registers 65 to 80, they are write-only! */ 50 u8 cache[16]; 51 struct i2c_client *i2c; 52 struct aoa_codec codec; 53 u32 initialised:1, 54 spdif_locked:1, 55 analog_locked:1, 56 original_mute:2; 57 int open_count; 58 struct codec_info *codec_info; 59 60 /* mutex serializes concurrent access to the device 61 * and this structure. 62 */ 63 struct mutex mutex; 64}; 65#define codec_to_onyx(c) container_of(c, struct onyx, codec) 66 67/* both return 0 if all ok, else on error */ 68static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value) 69{ 70 s32 v; 71 72 if (reg != ONYX_REG_CONTROL) { 73 *value = onyx->cache[reg-FIRSTREGISTER]; 74 return 0; 75 } 76 v = i2c_smbus_read_byte_data(onyx->i2c, reg); 77 if (v < 0) 78 return -1; 79 *value = (u8)v; 80 onyx->cache[ONYX_REG_CONTROL-FIRSTREGISTER] = *value; 81 return 0; 82} 83 84static int onyx_write_register(struct onyx *onyx, u8 reg, u8 value) 85{ 86 int result; 87 88 result = i2c_smbus_write_byte_data(onyx->i2c, reg, value); 89 if (!result) 90 onyx->cache[reg-FIRSTREGISTER] = value; 91 return result; 92} 93 94/* alsa stuff */ 95 96static int onyx_dev_register(struct snd_device *dev) 97{ 98 return 0; 99} 100 101static struct snd_device_ops ops = { 102 .dev_register = onyx_dev_register, 103}; 104 105/* this is necessary because most alsa mixer programs 106 * can't properly handle the negative range */ 107#define VOLUME_RANGE_SHIFT 128 108 109static int onyx_snd_vol_info(struct snd_kcontrol *kcontrol, 110 struct snd_ctl_elem_info *uinfo) 111{ 112 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 113 uinfo->count = 2; 114 uinfo->value.integer.min = -128 + VOLUME_RANGE_SHIFT; 115 uinfo->value.integer.max = -1 + VOLUME_RANGE_SHIFT; 116 return 0; 117} 118 119static int onyx_snd_vol_get(struct snd_kcontrol *kcontrol, 120 struct snd_ctl_elem_value *ucontrol) 121{ 122 struct onyx *onyx = snd_kcontrol_chip(kcontrol); 123 s8 l, r; 124 125 mutex_lock(&onyx->mutex); 126 onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l); 127 onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r); 128 mutex_unlock(&onyx->mutex); 129 130 ucontrol->value.integer.value[0] = l + VOLUME_RANGE_SHIFT; 131 ucontrol->value.integer.value[1] = r + VOLUME_RANGE_SHIFT; 132 133 return 0; 134} 135 136static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol, 137 struct snd_ctl_elem_value *ucontrol) 138{ 139 struct onyx *onyx = snd_kcontrol_chip(kcontrol); 140 s8 l, r; 141 142 if (ucontrol->value.integer.value[0] < -128 + VOLUME_RANGE_SHIFT || 143 ucontrol->value.integer.value[0] > -1 + VOLUME_RANGE_SHIFT) 144 return -EINVAL; 145 if (ucontrol->value.integer.value[1] < -128 + VOLUME_RANGE_SHIFT || 146 ucontrol->value.integer.value[1] > -1 + VOLUME_RANGE_SHIFT) 147 return -EINVAL; 148 149 mutex_lock(&onyx->mutex); 150 onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l); 151 onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r); 152 153 if (l + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[0] && 154 r + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[1]) { 155 mutex_unlock(&onyx->mutex); 156 return 0; 157 } 158 159 onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, 160 ucontrol->value.integer.value[0] 161 - VOLUME_RANGE_SHIFT); 162 onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, 163 ucontrol->value.integer.value[1] 164 - VOLUME_RANGE_SHIFT); 165 mutex_unlock(&onyx->mutex); 166 167 return 1; 168} 169 170static struct snd_kcontrol_new volume_control = { 171 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 172 .name = "Master Playback Volume", 173 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 174 .info = onyx_snd_vol_info, 175 .get = onyx_snd_vol_get, 176 .put = onyx_snd_vol_put, 177}; 178 179/* like above, this is necessary because a lot 180 * of alsa mixer programs don't handle ranges 181 * that don't start at 0 properly. 182 * even alsamixer is one of them... */ 183#define INPUTGAIN_RANGE_SHIFT (-3) 184 185static int onyx_snd_inputgain_info(struct snd_kcontrol *kcontrol, 186 struct snd_ctl_elem_info *uinfo) 187{ 188 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 189 uinfo->count = 1; 190 uinfo->value.integer.min = 3 + INPUTGAIN_RANGE_SHIFT; 191 uinfo->value.integer.max = 28 + INPUTGAIN_RANGE_SHIFT; 192 return 0; 193} 194 195static int onyx_snd_inputgain_get(struct snd_kcontrol *kcontrol, 196 struct snd_ctl_elem_value *ucontrol) 197{ 198 struct onyx *onyx = snd_kcontrol_chip(kcontrol); 199 u8 ig; 200 201 mutex_lock(&onyx->mutex); 202 onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &ig); 203 mutex_unlock(&onyx->mutex); 204 205 ucontrol->value.integer.value[0] = 206 (ig & ONYX_ADC_PGA_GAIN_MASK) + INPUTGAIN_RANGE_SHIFT; 207 208 return 0; 209} 210 211static int onyx_snd_inputgain_put(struct snd_kcontrol *kcontrol, 212 struct snd_ctl_elem_value *ucontrol) 213{ 214 struct onyx *onyx = snd_kcontrol_chip(kcontrol); 215 u8 v, n; 216 217 if (ucontrol->value.integer.value[0] < 3 + INPUTGAIN_RANGE_SHIFT || 218 ucontrol->value.integer.value[0] > 28 + INPUTGAIN_RANGE_SHIFT) 219 return -EINVAL; 220 mutex_lock(&onyx->mutex); 221 onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v); 222 n = v; 223 n &= ~ONYX_ADC_PGA_GAIN_MASK; 224 n |= (ucontrol->value.integer.value[0] - INPUTGAIN_RANGE_SHIFT) 225 & ONYX_ADC_PGA_GAIN_MASK; 226 onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, n); 227 mutex_unlock(&onyx->mutex); 228 229 return n != v; 230} 231 232static struct snd_kcontrol_new inputgain_control = { 233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 234 .name = "Master Capture Volume", 235 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 236 .info = onyx_snd_inputgain_info, 237 .get = onyx_snd_inputgain_get, 238 .put = onyx_snd_inputgain_put, 239}; 240 241static int onyx_snd_capture_source_info(struct snd_kcontrol *kcontrol, 242 struct snd_ctl_elem_info *uinfo) 243{ 244 static const char * const texts[] = { "Line-In", "Microphone" }; 245 246 return snd_ctl_enum_info(uinfo, 1, 2, texts); 247} 248 249static int onyx_snd_capture_source_get(struct snd_kcontrol *kcontrol, 250 struct snd_ctl_elem_value *ucontrol) 251{ 252 struct onyx *onyx = snd_kcontrol_chip(kcontrol); 253 s8 v; 254 255 mutex_lock(&onyx->mutex); 256 onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v); 257 mutex_unlock(&onyx->mutex); 258 259 ucontrol->value.enumerated.item[0] = !!(v&ONYX_ADC_INPUT_MIC); 260 261 return 0; 262} 263 264static void onyx_set_capture_source(struct onyx *onyx, int mic) 265{ 266 s8 v; 267 268 mutex_lock(&onyx->mutex); 269 onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v); 270 v &= ~ONYX_ADC_INPUT_MIC; 271 if (mic) 272 v |= ONYX_ADC_INPUT_MIC; 273 onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, v); 274 mutex_unlock(&onyx->mutex); 275} 276 277static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol, 278 struct snd_ctl_elem_value *ucontrol) 279{ 280 if (ucontrol->value.enumerated.item[0] > 1) 281 return -EINVAL; 282 onyx_set_capture_source(snd_kcontrol_chip(kcontrol), 283 ucontrol->value.enumerated.item[0]); 284 return 1; 285} 286 287static struct snd_kcontrol_new capture_source_control = { 288 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 289 /* If we name this 'Input Source', it properly shows up in 290 * alsamixer as a selection, * but it's shown under the 291 * 'Playback' category. 292 * If I name it 'Capture Source', it shows up in strange 293 * ways (two bools of which one can be selected at a 294 * time) but at least it's shown in the 'Capture' 295 * category. 296 * I was told that this was due to backward compatibility, 297 * but I don't understand then why the mangling is *not* 298 * done when I name it "Input Source"..... 299 */ 300 .name = "Capture Source", 301 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 302 .info = onyx_snd_capture_source_info, 303 .get = onyx_snd_capture_source_get, 304 .put = onyx_snd_capture_source_put, 305}; 306 307#define onyx_snd_mute_info snd_ctl_boolean_stereo_info 308 309static int onyx_snd_mute_get(struct snd_kcontrol *kcontrol, 310 struct snd_ctl_elem_value *ucontrol) 311{ 312 struct onyx *onyx = snd_kcontrol_chip(kcontrol); 313 u8 c; 314 315 mutex_lock(&onyx->mutex); 316 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &c); 317 mutex_unlock(&onyx->mutex); 318 319 ucontrol->value.integer.value[0] = !(c & ONYX_MUTE_LEFT); 320 ucontrol->value.integer.value[1] = !(c & ONYX_MUTE_RIGHT); 321 322 return 0; 323} 324 325static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol, 326 struct snd_ctl_elem_value *ucontrol) 327{ 328 struct onyx *onyx = snd_kcontrol_chip(kcontrol); 329 u8 v = 0, c = 0; 330 int err = -EBUSY; 331 332 mutex_lock(&onyx->mutex); 333 if (onyx->analog_locked) 334 goto out_unlock; 335 336 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v); 337 c = v; 338 c &= ~(ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT); 339 if (!ucontrol->value.integer.value[0]) 340 c |= ONYX_MUTE_LEFT; 341 if (!ucontrol->value.integer.value[1]) 342 c |= ONYX_MUTE_RIGHT; 343 err = onyx_write_register(onyx, ONYX_REG_DAC_CONTROL, c); 344 345 out_unlock: 346 mutex_unlock(&onyx->mutex); 347 348 return !err ? (v != c) : err; 349} 350 351static struct snd_kcontrol_new mute_control = { 352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 353 .name = "Master Playback Switch", 354 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 355 .info = onyx_snd_mute_info, 356 .get = onyx_snd_mute_get, 357 .put = onyx_snd_mute_put, 358}; 359 360 361#define onyx_snd_single_bit_info snd_ctl_boolean_mono_info 362 363#define FLAG_POLARITY_INVERT 1 364#define FLAG_SPDIFLOCK 2 365 366static int onyx_snd_single_bit_get(struct snd_kcontrol *kcontrol, 367 struct snd_ctl_elem_value *ucontrol) 368{ 369 struct onyx *onyx = snd_kcontrol_chip(kcontrol); 370 u8 c; 371 long int pv = kcontrol->private_value; 372 u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT; 373 u8 address = (pv >> 8) & 0xff; 374 u8 mask = pv & 0xff; 375 376 mutex_lock(&onyx->mutex); 377 onyx_read_register(onyx, address, &c); 378 mutex_unlock(&onyx->mutex); 379 380 ucontrol->value.integer.value[0] = !!(c & mask) ^ polarity; 381 382 return 0; 383} 384 385static int onyx_snd_single_bit_put(struct snd_kcontrol *kcontrol, 386 struct snd_ctl_elem_value *ucontrol) 387{ 388 struct onyx *onyx = snd_kcontrol_chip(kcontrol); 389 u8 v = 0, c = 0; 390 int err; 391 long int pv = kcontrol->private_value; 392 u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT; 393 u8 spdiflock = (pv >> 16) & FLAG_SPDIFLOCK; 394 u8 address = (pv >> 8) & 0xff; 395 u8 mask = pv & 0xff; 396 397 mutex_lock(&onyx->mutex); 398 if (spdiflock && onyx->spdif_locked) { 399 /* even if alsamixer doesn't care.. */ 400 err = -EBUSY; 401 goto out_unlock; 402 } 403 onyx_read_register(onyx, address, &v); 404 c = v; 405 c &= ~(mask); 406 if (!!ucontrol->value.integer.value[0] ^ polarity) 407 c |= mask; 408 err = onyx_write_register(onyx, address, c); 409 410 out_unlock: 411 mutex_unlock(&onyx->mutex); 412 413 return !err ? (v != c) : err; 414} 415 416#define SINGLE_BIT(n, type, description, address, mask, flags) \ 417static struct snd_kcontrol_new n##_control = { \ 418 .iface = SNDRV_CTL_ELEM_IFACE_##type, \ 419 .name = description, \ 420 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 421 .info = onyx_snd_single_bit_info, \ 422 .get = onyx_snd_single_bit_get, \ 423 .put = onyx_snd_single_bit_put, \ 424 .private_value = (flags << 16) | (address << 8) | mask \ 425} 426 427SINGLE_BIT(spdif, 428 MIXER, 429 SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH), 430 ONYX_REG_DIG_INFO4, 431 ONYX_SPDIF_ENABLE, 432 FLAG_SPDIFLOCK); 433SINGLE_BIT(ovr1, 434 MIXER, 435 "Oversampling Rate", 436 ONYX_REG_DAC_CONTROL, 437 ONYX_OVR1, 438 0); 439SINGLE_BIT(flt0, 440 MIXER, 441 "Fast Digital Filter Rolloff", 442 ONYX_REG_DAC_FILTER, 443 ONYX_ROLLOFF_FAST, 444 FLAG_POLARITY_INVERT); 445SINGLE_BIT(hpf, 446 MIXER, 447 "Highpass Filter", 448 ONYX_REG_ADC_HPF_BYPASS, 449 ONYX_HPF_DISABLE, 450 FLAG_POLARITY_INVERT); 451SINGLE_BIT(dm12, 452 MIXER, 453 "Digital De-Emphasis", 454 ONYX_REG_DAC_DEEMPH, 455 ONYX_DIGDEEMPH_CTRL, 456 0); 457 458static int onyx_spdif_info(struct snd_kcontrol *kcontrol, 459 struct snd_ctl_elem_info *uinfo) 460{ 461 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 462 uinfo->count = 1; 463 return 0; 464} 465 466static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol, 467 struct snd_ctl_elem_value *ucontrol) 468{ 469 /* datasheet page 30, all others are 0 */ 470 ucontrol->value.iec958.status[0] = 0x3e; 471 ucontrol->value.iec958.status[1] = 0xff; 472 473 ucontrol->value.iec958.status[3] = 0x3f; 474 ucontrol->value.iec958.status[4] = 0x0f; 475 476 return 0; 477} 478 479static struct snd_kcontrol_new onyx_spdif_mask = { 480 .access = SNDRV_CTL_ELEM_ACCESS_READ, 481 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 482 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), 483 .info = onyx_spdif_info, 484 .get = onyx_spdif_mask_get, 485}; 486 487static int onyx_spdif_get(struct snd_kcontrol *kcontrol, 488 struct snd_ctl_elem_value *ucontrol) 489{ 490 struct onyx *onyx = snd_kcontrol_chip(kcontrol); 491 u8 v; 492 493 mutex_lock(&onyx->mutex); 494 onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v); 495 ucontrol->value.iec958.status[0] = v & 0x3e; 496 497 onyx_read_register(onyx, ONYX_REG_DIG_INFO2, &v); 498 ucontrol->value.iec958.status[1] = v; 499 500 onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v); 501 ucontrol->value.iec958.status[3] = v & 0x3f; 502 503 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v); 504 ucontrol->value.iec958.status[4] = v & 0x0f; 505 mutex_unlock(&onyx->mutex); 506 507 return 0; 508} 509 510static int onyx_spdif_put(struct snd_kcontrol *kcontrol, 511 struct snd_ctl_elem_value *ucontrol) 512{ 513 struct onyx *onyx = snd_kcontrol_chip(kcontrol); 514 u8 v; 515 516 mutex_lock(&onyx->mutex); 517 onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v); 518 v = (v & ~0x3e) | (ucontrol->value.iec958.status[0] & 0x3e); 519 onyx_write_register(onyx, ONYX_REG_DIG_INFO1, v); 520 521 v = ucontrol->value.iec958.status[1]; 522 onyx_write_register(onyx, ONYX_REG_DIG_INFO2, v); 523 524 onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v); 525 v = (v & ~0x3f) | (ucontrol->value.iec958.status[3] & 0x3f); 526 onyx_write_register(onyx, ONYX_REG_DIG_INFO3, v); 527 528 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v); 529 v = (v & ~0x0f) | (ucontrol->value.iec958.status[4] & 0x0f); 530 onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v); 531 mutex_unlock(&onyx->mutex); 532 533 return 1; 534} 535 536static struct snd_kcontrol_new onyx_spdif_ctrl = { 537 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 538 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 539 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 540 .info = onyx_spdif_info, 541 .get = onyx_spdif_get, 542 .put = onyx_spdif_put, 543}; 544 545/* our registers */ 546 547static u8 register_map[] = { 548 ONYX_REG_DAC_ATTEN_LEFT, 549 ONYX_REG_DAC_ATTEN_RIGHT, 550 ONYX_REG_CONTROL, 551 ONYX_REG_DAC_CONTROL, 552 ONYX_REG_DAC_DEEMPH, 553 ONYX_REG_DAC_FILTER, 554 ONYX_REG_DAC_OUTPHASE, 555 ONYX_REG_ADC_CONTROL, 556 ONYX_REG_ADC_HPF_BYPASS, 557 ONYX_REG_DIG_INFO1, 558 ONYX_REG_DIG_INFO2, 559 ONYX_REG_DIG_INFO3, 560 ONYX_REG_DIG_INFO4 561}; 562 563static u8 initial_values[ARRAY_SIZE(register_map)] = { 564 0x80, 0x80, /* muted */ 565 ONYX_MRST | ONYX_SRST, /* but handled specially! */ 566 ONYX_MUTE_LEFT | ONYX_MUTE_RIGHT, 567 0, /* no deemphasis */ 568 ONYX_DAC_FILTER_ALWAYS, 569 ONYX_OUTPHASE_INVERTED, 570 (-1 /*dB*/ + 8) & 0xF, /* line in selected, -1 dB gain*/ 571 ONYX_ADC_HPF_ALWAYS, 572 (1<<2), /* pcm audio */ 573 2, /* category: pcm coder */ 574 0, /* sampling frequency 44.1 kHz, clock accuracy level II */ 575 1 /* 24 bit depth */ 576}; 577 578/* reset registers of chip, either to initial or to previous values */ 579static int onyx_register_init(struct onyx *onyx) 580{ 581 int i; 582 u8 val; 583 u8 regs[sizeof(initial_values)]; 584 585 if (!onyx->initialised) { 586 memcpy(regs, initial_values, sizeof(initial_values)); 587 if (onyx_read_register(onyx, ONYX_REG_CONTROL, &val)) 588 return -1; 589 val &= ~ONYX_SILICONVERSION; 590 val |= initial_values[3]; 591 regs[3] = val; 592 } else { 593 for (i=0; i<sizeof(register_map); i++) 594 regs[i] = onyx->cache[register_map[i]-FIRSTREGISTER]; 595 } 596 597 for (i=0; i<sizeof(register_map); i++) { 598 if (onyx_write_register(onyx, register_map[i], regs[i])) 599 return -1; 600 } 601 onyx->initialised = 1; 602 return 0; 603} 604 605static struct transfer_info onyx_transfers[] = { 606 /* this is first so we can skip it if no input is present... 607 * No hardware exists with that, but it's here as an example 608 * of what to do :) */ 609 { 610 /* analog input */ 611 .formats = SNDRV_PCM_FMTBIT_S8 | 612 SNDRV_PCM_FMTBIT_S16_BE | 613 SNDRV_PCM_FMTBIT_S24_BE, 614 .rates = SNDRV_PCM_RATE_8000_96000, 615 .transfer_in = 1, 616 .must_be_clock_source = 0, 617 .tag = 0, 618 }, 619 { 620 /* if analog and digital are currently off, anything should go, 621 * so this entry describes everything we can do... */ 622 .formats = SNDRV_PCM_FMTBIT_S8 | 623 SNDRV_PCM_FMTBIT_S16_BE | 624 SNDRV_PCM_FMTBIT_S24_BE 625#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE 626 | SNDRV_PCM_FMTBIT_COMPRESSED_16BE 627#endif 628 , 629 .rates = SNDRV_PCM_RATE_8000_96000, 630 .tag = 0, 631 }, 632 { 633 /* analog output */ 634 .formats = SNDRV_PCM_FMTBIT_S8 | 635 SNDRV_PCM_FMTBIT_S16_BE | 636 SNDRV_PCM_FMTBIT_S24_BE, 637 .rates = SNDRV_PCM_RATE_8000_96000, 638 .transfer_in = 0, 639 .must_be_clock_source = 0, 640 .tag = 1, 641 }, 642 { 643 /* digital pcm output, also possible for analog out */ 644 .formats = SNDRV_PCM_FMTBIT_S8 | 645 SNDRV_PCM_FMTBIT_S16_BE | 646 SNDRV_PCM_FMTBIT_S24_BE, 647 .rates = SNDRV_PCM_RATE_32000 | 648 SNDRV_PCM_RATE_44100 | 649 SNDRV_PCM_RATE_48000, 650 .transfer_in = 0, 651 .must_be_clock_source = 0, 652 .tag = 2, 653 }, 654#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE 655 /* Once alsa gets supports for this kind of thing we can add it... */ 656 { 657 /* digital compressed output */ 658 .formats = SNDRV_PCM_FMTBIT_COMPRESSED_16BE, 659 .rates = SNDRV_PCM_RATE_32000 | 660 SNDRV_PCM_RATE_44100 | 661 SNDRV_PCM_RATE_48000, 662 .tag = 2, 663 }, 664#endif 665 {} 666}; 667 668static int onyx_usable(struct codec_info_item *cii, 669 struct transfer_info *ti, 670 struct transfer_info *out) 671{ 672 u8 v; 673 struct onyx *onyx = cii->codec_data; 674 int spdif_enabled, analog_enabled; 675 676 mutex_lock(&onyx->mutex); 677 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v); 678 spdif_enabled = !!(v & ONYX_SPDIF_ENABLE); 679 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v); 680 analog_enabled = 681 (v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT)) 682 != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT); 683 mutex_unlock(&onyx->mutex); 684 685 switch (ti->tag) { 686 case 0: return 1; 687 case 1: return analog_enabled; 688 case 2: return spdif_enabled; 689 } 690 return 1; 691} 692 693static int onyx_prepare(struct codec_info_item *cii, 694 struct bus_info *bi, 695 struct snd_pcm_substream *substream) 696{ 697 u8 v; 698 struct onyx *onyx = cii->codec_data; 699 int err = -EBUSY; 700 701 mutex_lock(&onyx->mutex); 702 703#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE 704 if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) { 705 /* mute and lock analog output */ 706 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v); 707 if (onyx_write_register(onyx, 708 ONYX_REG_DAC_CONTROL, 709 v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT)) 710 goto out_unlock; 711 onyx->analog_locked = 1; 712 err = 0; 713 goto out_unlock; 714 } 715#endif 716 switch (substream->runtime->rate) { 717 case 32000: 718 case 44100: 719 case 48000: 720 /* these rates are ok for all outputs */ 721 /* FIXME: program spdif channel control bits here so that 722 * userspace doesn't have to if it only plays pcm! */ 723 err = 0; 724 goto out_unlock; 725 default: 726 /* got some rate that the digital output can't do, 727 * so disable and lock it */ 728 onyx_read_register(cii->codec_data, ONYX_REG_DIG_INFO4, &v); 729 if (onyx_write_register(onyx, 730 ONYX_REG_DIG_INFO4, 731 v & ~ONYX_SPDIF_ENABLE)) 732 goto out_unlock; 733 onyx->spdif_locked = 1; 734 err = 0; 735 goto out_unlock; 736 } 737 738 out_unlock: 739 mutex_unlock(&onyx->mutex); 740 741 return err; 742} 743 744static int onyx_open(struct codec_info_item *cii, 745 struct snd_pcm_substream *substream) 746{ 747 struct onyx *onyx = cii->codec_data; 748 749 mutex_lock(&onyx->mutex); 750 onyx->open_count++; 751 mutex_unlock(&onyx->mutex); 752 753 return 0; 754} 755 756static int onyx_close(struct codec_info_item *cii, 757 struct snd_pcm_substream *substream) 758{ 759 struct onyx *onyx = cii->codec_data; 760 761 mutex_lock(&onyx->mutex); 762 onyx->open_count--; 763 if (!onyx->open_count) 764 onyx->spdif_locked = onyx->analog_locked = 0; 765 mutex_unlock(&onyx->mutex); 766 767 return 0; 768} 769 770static int onyx_switch_clock(struct codec_info_item *cii, 771 enum clock_switch what) 772{ 773 struct onyx *onyx = cii->codec_data; 774 775 mutex_lock(&onyx->mutex); 776 /* this *MUST* be more elaborate later... */ 777 switch (what) { 778 case CLOCK_SWITCH_PREPARE_SLAVE: 779 onyx->codec.gpio->methods->all_amps_off(onyx->codec.gpio); 780 break; 781 case CLOCK_SWITCH_SLAVE: 782 onyx->codec.gpio->methods->all_amps_restore(onyx->codec.gpio); 783 break; 784 default: /* silence warning */ 785 break; 786 } 787 mutex_unlock(&onyx->mutex); 788 789 return 0; 790} 791 792#ifdef CONFIG_PM 793 794static int onyx_suspend(struct codec_info_item *cii, pm_message_t state) 795{ 796 struct onyx *onyx = cii->codec_data; 797 u8 v; 798 int err = -ENXIO; 799 800 mutex_lock(&onyx->mutex); 801 if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v)) 802 goto out_unlock; 803 onyx_write_register(onyx, ONYX_REG_CONTROL, v | ONYX_ADPSV | ONYX_DAPSV); 804 /* Apple does a sleep here but the datasheet says to do it on resume */ 805 err = 0; 806 out_unlock: 807 mutex_unlock(&onyx->mutex); 808 809 return err; 810} 811 812static int onyx_resume(struct codec_info_item *cii) 813{ 814 struct onyx *onyx = cii->codec_data; 815 u8 v; 816 int err = -ENXIO; 817 818 mutex_lock(&onyx->mutex); 819 820 /* reset codec */ 821 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0); 822 msleep(1); 823 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1); 824 msleep(1); 825 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0); 826 msleep(1); 827 828 /* take codec out of suspend (if it still is after reset) */ 829 if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v)) 830 goto out_unlock; 831 onyx_write_register(onyx, ONYX_REG_CONTROL, v & ~(ONYX_ADPSV | ONYX_DAPSV)); 832 /* FIXME: should divide by sample rate, but 8k is the lowest we go */ 833 msleep(2205000/8000); 834 /* reset all values */ 835 onyx_register_init(onyx); 836 err = 0; 837 out_unlock: 838 mutex_unlock(&onyx->mutex); 839 840 return err; 841} 842 843#endif /* CONFIG_PM */ 844 845static struct codec_info onyx_codec_info = { 846 .transfers = onyx_transfers, 847 .sysclock_factor = 256, 848 .bus_factor = 64, 849 .owner = THIS_MODULE, 850 .usable = onyx_usable, 851 .prepare = onyx_prepare, 852 .open = onyx_open, 853 .close = onyx_close, 854 .switch_clock = onyx_switch_clock, 855#ifdef CONFIG_PM 856 .suspend = onyx_suspend, 857 .resume = onyx_resume, 858#endif 859}; 860 861static int onyx_init_codec(struct aoa_codec *codec) 862{ 863 struct onyx *onyx = codec_to_onyx(codec); 864 struct snd_kcontrol *ctl; 865 struct codec_info *ci = &onyx_codec_info; 866 u8 v; 867 int err; 868 869 if (!onyx->codec.gpio || !onyx->codec.gpio->methods) { 870 printk(KERN_ERR PFX "gpios not assigned!!\n"); 871 return -EINVAL; 872 } 873 874 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0); 875 msleep(1); 876 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1); 877 msleep(1); 878 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0); 879 msleep(1); 880 881 if (onyx_register_init(onyx)) { 882 printk(KERN_ERR PFX "failed to initialise onyx registers\n"); 883 return -ENODEV; 884 } 885 886 if (aoa_snd_device_new(SNDRV_DEV_CODEC, onyx, &ops)) { 887 printk(KERN_ERR PFX "failed to create onyx snd device!\n"); 888 return -ENODEV; 889 } 890 891 /* nothing connected? what a joke! */ 892 if ((onyx->codec.connected & 0xF) == 0) 893 return -ENOTCONN; 894 895 /* if no inputs are present... */ 896 if ((onyx->codec.connected & 0xC) == 0) { 897 if (!onyx->codec_info) 898 onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL); 899 if (!onyx->codec_info) 900 return -ENOMEM; 901 ci = onyx->codec_info; 902 *ci = onyx_codec_info; 903 ci->transfers++; 904 } 905 906 /* if no outputs are present... */ 907 if ((onyx->codec.connected & 3) == 0) { 908 if (!onyx->codec_info) 909 onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL); 910 if (!onyx->codec_info) 911 return -ENOMEM; 912 ci = onyx->codec_info; 913 /* this is fine as there have to be inputs 914 * if we end up in this part of the code */ 915 *ci = onyx_codec_info; 916 ci->transfers[1].formats = 0; 917 } 918 919 if (onyx->codec.soundbus_dev->attach_codec(onyx->codec.soundbus_dev, 920 aoa_get_card(), 921 ci, onyx)) { 922 printk(KERN_ERR PFX "error creating onyx pcm\n"); 923 return -ENODEV; 924 } 925#define ADDCTL(n) \ 926 do { \ 927 ctl = snd_ctl_new1(&n, onyx); \ 928 if (ctl) { \ 929 ctl->id.device = \ 930 onyx->codec.soundbus_dev->pcm->device; \ 931 err = aoa_snd_ctl_add(ctl); \ 932 if (err) \ 933 goto error; \ 934 } \ 935 } while (0) 936 937 if (onyx->codec.soundbus_dev->pcm) { 938 /* give the user appropriate controls 939 * depending on what inputs are connected */ 940 if ((onyx->codec.connected & 0xC) == 0xC) 941 ADDCTL(capture_source_control); 942 else if (onyx->codec.connected & 4) 943 onyx_set_capture_source(onyx, 0); 944 else 945 onyx_set_capture_source(onyx, 1); 946 if (onyx->codec.connected & 0xC) 947 ADDCTL(inputgain_control); 948 949 /* depending on what output is connected, 950 * give the user appropriate controls */ 951 if (onyx->codec.connected & 1) { 952 ADDCTL(volume_control); 953 ADDCTL(mute_control); 954 ADDCTL(ovr1_control); 955 ADDCTL(flt0_control); 956 ADDCTL(hpf_control); 957 ADDCTL(dm12_control); 958 /* spdif control defaults to off */ 959 } 960 if (onyx->codec.connected & 2) { 961 ADDCTL(onyx_spdif_mask); 962 ADDCTL(onyx_spdif_ctrl); 963 } 964 if ((onyx->codec.connected & 3) == 3) 965 ADDCTL(spdif_control); 966 /* if only S/PDIF is connected, enable it unconditionally */ 967 if ((onyx->codec.connected & 3) == 2) { 968 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v); 969 v |= ONYX_SPDIF_ENABLE; 970 onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v); 971 } 972 } 973#undef ADDCTL 974 printk(KERN_INFO PFX "attached to onyx codec via i2c\n"); 975 976 return 0; 977 error: 978 onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx); 979 snd_device_free(aoa_get_card(), onyx); 980 return err; 981} 982 983static void onyx_exit_codec(struct aoa_codec *codec) 984{ 985 struct onyx *onyx = codec_to_onyx(codec); 986 987 if (!onyx->codec.soundbus_dev) { 988 printk(KERN_ERR PFX "onyx_exit_codec called without soundbus_dev!\n"); 989 return; 990 } 991 onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx); 992} 993 994static int onyx_i2c_probe(struct i2c_client *client, 995 const struct i2c_device_id *id) 996{ 997 struct device_node *node = client->dev.of_node; 998 struct onyx *onyx; 999 u8 dummy; 1000 1001 onyx = kzalloc(sizeof(struct onyx), GFP_KERNEL); 1002 1003 if (!onyx) 1004 return -ENOMEM; 1005 1006 mutex_init(&onyx->mutex); 1007 onyx->i2c = client; 1008 i2c_set_clientdata(client, onyx); 1009 1010 /* we try to read from register ONYX_REG_CONTROL 1011 * to check if the codec is present */ 1012 if (onyx_read_register(onyx, ONYX_REG_CONTROL, &dummy) != 0) { 1013 printk(KERN_ERR PFX "failed to read control register\n"); 1014 goto fail; 1015 } 1016 1017 strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN); 1018 onyx->codec.owner = THIS_MODULE; 1019 onyx->codec.init = onyx_init_codec; 1020 onyx->codec.exit = onyx_exit_codec; 1021 onyx->codec.node = of_node_get(node); 1022 1023 if (aoa_codec_register(&onyx->codec)) { 1024 goto fail; 1025 } 1026 printk(KERN_DEBUG PFX "created and attached onyx instance\n"); 1027 return 0; 1028 fail: 1029 kfree(onyx); 1030 return -ENODEV; 1031} 1032 1033static int onyx_i2c_remove(struct i2c_client *client) 1034{ 1035 struct onyx *onyx = i2c_get_clientdata(client); 1036 1037 aoa_codec_unregister(&onyx->codec); 1038 of_node_put(onyx->codec.node); 1039 kfree(onyx->codec_info); 1040 kfree(onyx); 1041 return 0; 1042} 1043 1044static const struct i2c_device_id onyx_i2c_id[] = { 1045 { "MAC,pcm3052", 0 }, 1046 { } 1047}; 1048MODULE_DEVICE_TABLE(i2c,onyx_i2c_id); 1049 1050static struct i2c_driver onyx_driver = { 1051 .driver = { 1052 .name = "aoa_codec_onyx", 1053 .owner = THIS_MODULE, 1054 }, 1055 .probe = onyx_i2c_probe, 1056 .remove = onyx_i2c_remove, 1057 .id_table = onyx_i2c_id, 1058}; 1059 1060module_i2c_driver(onyx_driver); 1061