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