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>
  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 char *texts[] = { "Line-In", "Microphone" };
 245
 246        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 247        uinfo->count = 1;
 248        uinfo->value.enumerated.items = 2;
 249        if (uinfo->value.enumerated.item > 1)
 250                uinfo->value.enumerated.item = 1;
 251        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
 252        return 0;
 253}
 254
 255static int onyx_snd_capture_source_get(struct snd_kcontrol *kcontrol,
 256        struct snd_ctl_elem_value *ucontrol)
 257{
 258        struct onyx *onyx = snd_kcontrol_chip(kcontrol);
 259        s8 v;
 260
 261        mutex_lock(&onyx->mutex);
 262        onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
 263        mutex_unlock(&onyx->mutex);
 264
 265        ucontrol->value.enumerated.item[0] = !!(v&ONYX_ADC_INPUT_MIC);
 266
 267        return 0;
 268}
 269
 270static void onyx_set_capture_source(struct onyx *onyx, int mic)
 271{
 272        s8 v;
 273
 274        mutex_lock(&onyx->mutex);
 275        onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
 276        v &= ~ONYX_ADC_INPUT_MIC;
 277        if (mic)
 278                v |= ONYX_ADC_INPUT_MIC;
 279        onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, v);
 280        mutex_unlock(&onyx->mutex);
 281}
 282
 283static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
 284        struct snd_ctl_elem_value *ucontrol)
 285{
 286        if (ucontrol->value.enumerated.item[0] > 1)
 287                return -EINVAL;
 288        onyx_set_capture_source(snd_kcontrol_chip(kcontrol),
 289                                ucontrol->value.enumerated.item[0]);
 290        return 1;
 291}
 292
 293static struct snd_kcontrol_new capture_source_control = {
 294        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 295        /* If we name this 'Input Source', it properly shows up in
 296         * alsamixer as a selection, * but it's shown under the
 297         * 'Playback' category.
 298         * If I name it 'Capture Source', it shows up in strange
 299         * ways (two bools of which one can be selected at a
 300         * time) but at least it's shown in the 'Capture'
 301         * category.
 302         * I was told that this was due to backward compatibility,
 303         * but I don't understand then why the mangling is *not*
 304         * done when I name it "Input Source".....
 305         */
 306        .name = "Capture Source",
 307        .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 308        .info = onyx_snd_capture_source_info,
 309        .get = onyx_snd_capture_source_get,
 310        .put = onyx_snd_capture_source_put,
 311};
 312
 313#define onyx_snd_mute_info      snd_ctl_boolean_stereo_info
 314
 315static int onyx_snd_mute_get(struct snd_kcontrol *kcontrol,
 316        struct snd_ctl_elem_value *ucontrol)
 317{
 318        struct onyx *onyx = snd_kcontrol_chip(kcontrol);
 319        u8 c;
 320
 321        mutex_lock(&onyx->mutex);
 322        onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &c);
 323        mutex_unlock(&onyx->mutex);
 324
 325        ucontrol->value.integer.value[0] = !(c & ONYX_MUTE_LEFT);
 326        ucontrol->value.integer.value[1] = !(c & ONYX_MUTE_RIGHT);
 327
 328        return 0;
 329}
 330
 331static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol,
 332        struct snd_ctl_elem_value *ucontrol)
 333{
 334        struct onyx *onyx = snd_kcontrol_chip(kcontrol);
 335        u8 v = 0, c = 0;
 336        int err = -EBUSY;
 337
 338        mutex_lock(&onyx->mutex);
 339        if (onyx->analog_locked)
 340                goto out_unlock;
 341
 342        onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
 343        c = v;
 344        c &= ~(ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT);
 345        if (!ucontrol->value.integer.value[0])
 346                c |= ONYX_MUTE_LEFT;
 347        if (!ucontrol->value.integer.value[1])
 348                c |= ONYX_MUTE_RIGHT;
 349        err = onyx_write_register(onyx, ONYX_REG_DAC_CONTROL, c);
 350
 351 out_unlock:
 352        mutex_unlock(&onyx->mutex);
 353
 354        return !err ? (v != c) : err;
 355}
 356
 357static struct snd_kcontrol_new mute_control = {
 358        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 359        .name = "Master Playback Switch",
 360        .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 361        .info = onyx_snd_mute_info,
 362        .get = onyx_snd_mute_get,
 363        .put = onyx_snd_mute_put,
 364};
 365
 366
 367#define onyx_snd_single_bit_info        snd_ctl_boolean_mono_info
 368
 369#define FLAG_POLARITY_INVERT    1
 370#define FLAG_SPDIFLOCK          2
 371
 372static int onyx_snd_single_bit_get(struct snd_kcontrol *kcontrol,
 373        struct snd_ctl_elem_value *ucontrol)
 374{
 375        struct onyx *onyx = snd_kcontrol_chip(kcontrol);
 376        u8 c;
 377        long int pv = kcontrol->private_value;
 378        u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
 379        u8 address = (pv >> 8) & 0xff;
 380        u8 mask = pv & 0xff;
 381
 382        mutex_lock(&onyx->mutex);
 383        onyx_read_register(onyx, address, &c);
 384        mutex_unlock(&onyx->mutex);
 385
 386        ucontrol->value.integer.value[0] = !!(c & mask) ^ polarity;
 387
 388        return 0;
 389}
 390
 391static int onyx_snd_single_bit_put(struct snd_kcontrol *kcontrol,
 392        struct snd_ctl_elem_value *ucontrol)
 393{
 394        struct onyx *onyx = snd_kcontrol_chip(kcontrol);
 395        u8 v = 0, c = 0;
 396        int err;
 397        long int pv = kcontrol->private_value;
 398        u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
 399        u8 spdiflock = (pv >> 16) & FLAG_SPDIFLOCK;
 400        u8 address = (pv >> 8) & 0xff;
 401        u8 mask = pv & 0xff;
 402
 403        mutex_lock(&onyx->mutex);
 404        if (spdiflock && onyx->spdif_locked) {
 405                /* even if alsamixer doesn't care.. */
 406                err = -EBUSY;
 407                goto out_unlock;
 408        }
 409        onyx_read_register(onyx, address, &v);
 410        c = v;
 411        c &= ~(mask);
 412        if (!!ucontrol->value.integer.value[0] ^ polarity)
 413                c |= mask;
 414        err = onyx_write_register(onyx, address, c);
 415
 416 out_unlock:
 417        mutex_unlock(&onyx->mutex);
 418
 419        return !err ? (v != c) : err;
 420}
 421
 422#define SINGLE_BIT(n, type, description, address, mask, flags)          \
 423static struct snd_kcontrol_new n##_control = {                          \
 424        .iface = SNDRV_CTL_ELEM_IFACE_##type,                           \
 425        .name = description,                                            \
 426        .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,                      \
 427        .info = onyx_snd_single_bit_info,                               \
 428        .get = onyx_snd_single_bit_get,                                 \
 429        .put = onyx_snd_single_bit_put,                                 \
 430        .private_value = (flags << 16) | (address << 8) | mask          \
 431}
 432
 433SINGLE_BIT(spdif,
 434           MIXER,
 435           SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
 436           ONYX_REG_DIG_INFO4,
 437           ONYX_SPDIF_ENABLE,
 438           FLAG_SPDIFLOCK);
 439SINGLE_BIT(ovr1,
 440           MIXER,
 441           "Oversampling Rate",
 442           ONYX_REG_DAC_CONTROL,
 443           ONYX_OVR1,
 444           0);
 445SINGLE_BIT(flt0,
 446           MIXER,
 447           "Fast Digital Filter Rolloff",
 448           ONYX_REG_DAC_FILTER,
 449           ONYX_ROLLOFF_FAST,
 450           FLAG_POLARITY_INVERT);
 451SINGLE_BIT(hpf,
 452           MIXER,
 453           "Highpass Filter",
 454           ONYX_REG_ADC_HPF_BYPASS,
 455           ONYX_HPF_DISABLE,
 456           FLAG_POLARITY_INVERT);
 457SINGLE_BIT(dm12,
 458           MIXER,
 459           "Digital De-Emphasis",
 460           ONYX_REG_DAC_DEEMPH,
 461           ONYX_DIGDEEMPH_CTRL,
 462           0);
 463
 464static int onyx_spdif_info(struct snd_kcontrol *kcontrol,
 465                           struct snd_ctl_elem_info *uinfo)
 466{
 467        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 468        uinfo->count = 1;
 469        return 0;
 470}
 471
 472static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol,
 473                               struct snd_ctl_elem_value *ucontrol)
 474{
 475        /* datasheet page 30, all others are 0 */
 476        ucontrol->value.iec958.status[0] = 0x3e;
 477        ucontrol->value.iec958.status[1] = 0xff;
 478
 479        ucontrol->value.iec958.status[3] = 0x3f;
 480        ucontrol->value.iec958.status[4] = 0x0f;
 481
 482        return 0;
 483}
 484
 485static struct snd_kcontrol_new onyx_spdif_mask = {
 486        .access =       SNDRV_CTL_ELEM_ACCESS_READ,
 487        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
 488        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
 489        .info =         onyx_spdif_info,
 490        .get =          onyx_spdif_mask_get,
 491};
 492
 493static int onyx_spdif_get(struct snd_kcontrol *kcontrol,
 494                          struct snd_ctl_elem_value *ucontrol)
 495{
 496        struct onyx *onyx = snd_kcontrol_chip(kcontrol);
 497        u8 v;
 498
 499        mutex_lock(&onyx->mutex);
 500        onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
 501        ucontrol->value.iec958.status[0] = v & 0x3e;
 502
 503        onyx_read_register(onyx, ONYX_REG_DIG_INFO2, &v);
 504        ucontrol->value.iec958.status[1] = v;
 505
 506        onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
 507        ucontrol->value.iec958.status[3] = v & 0x3f;
 508
 509        onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
 510        ucontrol->value.iec958.status[4] = v & 0x0f;
 511        mutex_unlock(&onyx->mutex);
 512
 513        return 0;
 514}
 515
 516static int onyx_spdif_put(struct snd_kcontrol *kcontrol,
 517                          struct snd_ctl_elem_value *ucontrol)
 518{
 519        struct onyx *onyx = snd_kcontrol_chip(kcontrol);
 520        u8 v;
 521
 522        mutex_lock(&onyx->mutex);
 523        onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
 524        v = (v & ~0x3e) | (ucontrol->value.iec958.status[0] & 0x3e);
 525        onyx_write_register(onyx, ONYX_REG_DIG_INFO1, v);
 526
 527        v = ucontrol->value.iec958.status[1];
 528        onyx_write_register(onyx, ONYX_REG_DIG_INFO2, v);
 529
 530        onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
 531        v = (v & ~0x3f) | (ucontrol->value.iec958.status[3] & 0x3f);
 532        onyx_write_register(onyx, ONYX_REG_DIG_INFO3, v);
 533
 534        onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
 535        v = (v & ~0x0f) | (ucontrol->value.iec958.status[4] & 0x0f);
 536        onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
 537        mutex_unlock(&onyx->mutex);
 538
 539        return 1;
 540}
 541
 542static struct snd_kcontrol_new onyx_spdif_ctrl = {
 543        .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE,
 544        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
 545        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
 546        .info =         onyx_spdif_info,
 547        .get =          onyx_spdif_get,
 548        .put =          onyx_spdif_put,
 549};
 550
 551/* our registers */
 552
 553static u8 register_map[] = {
 554        ONYX_REG_DAC_ATTEN_LEFT,
 555        ONYX_REG_DAC_ATTEN_RIGHT,
 556        ONYX_REG_CONTROL,
 557        ONYX_REG_DAC_CONTROL,
 558        ONYX_REG_DAC_DEEMPH,
 559        ONYX_REG_DAC_FILTER,
 560        ONYX_REG_DAC_OUTPHASE,
 561        ONYX_REG_ADC_CONTROL,
 562        ONYX_REG_ADC_HPF_BYPASS,
 563        ONYX_REG_DIG_INFO1,
 564        ONYX_REG_DIG_INFO2,
 565        ONYX_REG_DIG_INFO3,
 566        ONYX_REG_DIG_INFO4
 567};
 568
 569static u8 initial_values[ARRAY_SIZE(register_map)] = {
 570        0x80, 0x80, /* muted */
 571        ONYX_MRST | ONYX_SRST, /* but handled specially! */
 572        ONYX_MUTE_LEFT | ONYX_MUTE_RIGHT,
 573        0, /* no deemphasis */
 574        ONYX_DAC_FILTER_ALWAYS,
 575        ONYX_OUTPHASE_INVERTED,
 576        (-1 /*dB*/ + 8) & 0xF, /* line in selected, -1 dB gain*/
 577        ONYX_ADC_HPF_ALWAYS,
 578        (1<<2), /* pcm audio */
 579        2,      /* category: pcm coder */
 580        0,      /* sampling frequency 44.1 kHz, clock accuracy level II */
 581        1       /* 24 bit depth */
 582};
 583
 584/* reset registers of chip, either to initial or to previous values */
 585static int onyx_register_init(struct onyx *onyx)
 586{
 587        int i;
 588        u8 val;
 589        u8 regs[sizeof(initial_values)];
 590
 591        if (!onyx->initialised) {
 592                memcpy(regs, initial_values, sizeof(initial_values));
 593                if (onyx_read_register(onyx, ONYX_REG_CONTROL, &val))
 594                        return -1;
 595                val &= ~ONYX_SILICONVERSION;
 596                val |= initial_values[3];
 597                regs[3] = val;
 598        } else {
 599                for (i=0; i<sizeof(register_map); i++)
 600                        regs[i] = onyx->cache[register_map[i]-FIRSTREGISTER];
 601        }
 602
 603        for (i=0; i<sizeof(register_map); i++) {
 604                if (onyx_write_register(onyx, register_map[i], regs[i]))
 605                        return -1;
 606        }
 607        onyx->initialised = 1;
 608        return 0;
 609}
 610
 611static struct transfer_info onyx_transfers[] = {
 612        /* this is first so we can skip it if no input is present...
 613         * No hardware exists with that, but it's here as an example
 614         * of what to do :) */
 615        {
 616                /* analog input */
 617                .formats = SNDRV_PCM_FMTBIT_S8 |
 618                           SNDRV_PCM_FMTBIT_S16_BE |
 619                           SNDRV_PCM_FMTBIT_S24_BE,
 620                .rates = SNDRV_PCM_RATE_8000_96000,
 621                .transfer_in = 1,
 622                .must_be_clock_source = 0,
 623                .tag = 0,
 624        },
 625        {
 626                /* if analog and digital are currently off, anything should go,
 627                 * so this entry describes everything we can do... */
 628                .formats = SNDRV_PCM_FMTBIT_S8 |
 629                           SNDRV_PCM_FMTBIT_S16_BE |
 630                           SNDRV_PCM_FMTBIT_S24_BE
 631#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
 632                           | SNDRV_PCM_FMTBIT_COMPRESSED_16BE
 633#endif
 634                ,
 635                .rates = SNDRV_PCM_RATE_8000_96000,
 636                .tag = 0,
 637        },
 638        {
 639                /* analog output */
 640                .formats = SNDRV_PCM_FMTBIT_S8 |
 641                           SNDRV_PCM_FMTBIT_S16_BE |
 642                           SNDRV_PCM_FMTBIT_S24_BE,
 643                .rates = SNDRV_PCM_RATE_8000_96000,
 644                .transfer_in = 0,
 645                .must_be_clock_source = 0,
 646                .tag = 1,
 647        },
 648        {
 649                /* digital pcm output, also possible for analog out */
 650                .formats = SNDRV_PCM_FMTBIT_S8 |
 651                           SNDRV_PCM_FMTBIT_S16_BE |
 652                           SNDRV_PCM_FMTBIT_S24_BE,
 653                .rates = SNDRV_PCM_RATE_32000 |
 654                         SNDRV_PCM_RATE_44100 |
 655                         SNDRV_PCM_RATE_48000,
 656                .transfer_in = 0,
 657                .must_be_clock_source = 0,
 658                .tag = 2,
 659        },
 660#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
 661        /* Once alsa gets supports for this kind of thing we can add it... */
 662        {
 663                /* digital compressed output */
 664                .formats =  SNDRV_PCM_FMTBIT_COMPRESSED_16BE,
 665                .rates = SNDRV_PCM_RATE_32000 |
 666                         SNDRV_PCM_RATE_44100 |
 667                         SNDRV_PCM_RATE_48000,
 668                .tag = 2,
 669        },
 670#endif
 671        {}
 672};
 673
 674static int onyx_usable(struct codec_info_item *cii,
 675                       struct transfer_info *ti,
 676                       struct transfer_info *out)
 677{
 678        u8 v;
 679        struct onyx *onyx = cii->codec_data;
 680        int spdif_enabled, analog_enabled;
 681
 682        mutex_lock(&onyx->mutex);
 683        onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
 684        spdif_enabled = !!(v & ONYX_SPDIF_ENABLE);
 685        onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
 686        analog_enabled =
 687                (v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT))
 688                 != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT);
 689        mutex_unlock(&onyx->mutex);
 690
 691        switch (ti->tag) {
 692        case 0: return 1;
 693        case 1: return analog_enabled;
 694        case 2: return spdif_enabled;
 695        }
 696        return 1;
 697}
 698
 699static int onyx_prepare(struct codec_info_item *cii,
 700                        struct bus_info *bi,
 701                        struct snd_pcm_substream *substream)
 702{
 703        u8 v;
 704        struct onyx *onyx = cii->codec_data;
 705        int err = -EBUSY;
 706
 707        mutex_lock(&onyx->mutex);
 708
 709#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
 710        if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) {
 711                /* mute and lock analog output */
 712                onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
 713                if (onyx_write_register(onyx,
 714                                        ONYX_REG_DAC_CONTROL,
 715                                        v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT))
 716                        goto out_unlock;
 717                onyx->analog_locked = 1;
 718                err = 0;
 719                goto out_unlock;
 720        }
 721#endif
 722        switch (substream->runtime->rate) {
 723        case 32000:
 724        case 44100:
 725        case 48000:
 726                /* these rates are ok for all outputs */
 727                /* FIXME: program spdif channel control bits here so that
 728                 *        userspace doesn't have to if it only plays pcm! */
 729                err = 0;
 730                goto out_unlock;
 731        default:
 732                /* got some rate that the digital output can't do,
 733                 * so disable and lock it */
 734                onyx_read_register(cii->codec_data, ONYX_REG_DIG_INFO4, &v);
 735                if (onyx_write_register(onyx,
 736                                        ONYX_REG_DIG_INFO4,
 737                                        v & ~ONYX_SPDIF_ENABLE))
 738                        goto out_unlock;
 739                onyx->spdif_locked = 1;
 740                err = 0;
 741                goto out_unlock;
 742        }
 743
 744 out_unlock:
 745        mutex_unlock(&onyx->mutex);
 746
 747        return err;
 748}
 749
 750static int onyx_open(struct codec_info_item *cii,
 751                     struct snd_pcm_substream *substream)
 752{
 753        struct onyx *onyx = cii->codec_data;
 754
 755        mutex_lock(&onyx->mutex);
 756        onyx->open_count++;
 757        mutex_unlock(&onyx->mutex);
 758
 759        return 0;
 760}
 761
 762static int onyx_close(struct codec_info_item *cii,
 763                      struct snd_pcm_substream *substream)
 764{
 765        struct onyx *onyx = cii->codec_data;
 766
 767        mutex_lock(&onyx->mutex);
 768        onyx->open_count--;
 769        if (!onyx->open_count)
 770                onyx->spdif_locked = onyx->analog_locked = 0;
 771        mutex_unlock(&onyx->mutex);
 772
 773        return 0;
 774}
 775
 776static int onyx_switch_clock(struct codec_info_item *cii,
 777                             enum clock_switch what)
 778{
 779        struct onyx *onyx = cii->codec_data;
 780
 781        mutex_lock(&onyx->mutex);
 782        /* this *MUST* be more elaborate later... */
 783        switch (what) {
 784        case CLOCK_SWITCH_PREPARE_SLAVE:
 785                onyx->codec.gpio->methods->all_amps_off(onyx->codec.gpio);
 786                break;
 787        case CLOCK_SWITCH_SLAVE:
 788                onyx->codec.gpio->methods->all_amps_restore(onyx->codec.gpio);
 789                break;
 790        default: /* silence warning */
 791                break;
 792        }
 793        mutex_unlock(&onyx->mutex);
 794
 795        return 0;
 796}
 797
 798#ifdef CONFIG_PM
 799
 800static int onyx_suspend(struct codec_info_item *cii, pm_message_t state)
 801{
 802        struct onyx *onyx = cii->codec_data;
 803        u8 v;
 804        int err = -ENXIO;
 805
 806        mutex_lock(&onyx->mutex);
 807        if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
 808                goto out_unlock;
 809        onyx_write_register(onyx, ONYX_REG_CONTROL, v | ONYX_ADPSV | ONYX_DAPSV);
 810        /* Apple does a sleep here but the datasheet says to do it on resume */
 811        err = 0;
 812 out_unlock:
 813        mutex_unlock(&onyx->mutex);
 814
 815        return err;
 816}
 817
 818static int onyx_resume(struct codec_info_item *cii)
 819{
 820        struct onyx *onyx = cii->codec_data;
 821        u8 v;
 822        int err = -ENXIO;
 823
 824        mutex_lock(&onyx->mutex);
 825
 826        /* reset codec */
 827        onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
 828        msleep(1);
 829        onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1);
 830        msleep(1);
 831        onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
 832        msleep(1);
 833
 834        /* take codec out of suspend (if it still is after reset) */
 835        if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
 836                goto out_unlock;
 837        onyx_write_register(onyx, ONYX_REG_CONTROL, v & ~(ONYX_ADPSV | ONYX_DAPSV));
 838        /* FIXME: should divide by sample rate, but 8k is the lowest we go */
 839        msleep(2205000/8000);
 840        /* reset all values */
 841        onyx_register_init(onyx);
 842        err = 0;
 843 out_unlock:
 844        mutex_unlock(&onyx->mutex);
 845
 846        return err;
 847}
 848
 849#endif /* CONFIG_PM */
 850
 851static struct codec_info onyx_codec_info = {
 852        .transfers = onyx_transfers,
 853        .sysclock_factor = 256,
 854        .bus_factor = 64,
 855        .owner = THIS_MODULE,
 856        .usable = onyx_usable,
 857        .prepare = onyx_prepare,
 858        .open = onyx_open,
 859        .close = onyx_close,
 860        .switch_clock = onyx_switch_clock,
 861#ifdef CONFIG_PM
 862        .suspend = onyx_suspend,
 863        .resume = onyx_resume,
 864#endif
 865};
 866
 867static int onyx_init_codec(struct aoa_codec *codec)
 868{
 869        struct onyx *onyx = codec_to_onyx(codec);
 870        struct snd_kcontrol *ctl;
 871        struct codec_info *ci = &onyx_codec_info;
 872        u8 v;
 873        int err;
 874
 875        if (!onyx->codec.gpio || !onyx->codec.gpio->methods) {
 876                printk(KERN_ERR PFX "gpios not assigned!!\n");
 877                return -EINVAL;
 878        }
 879
 880        onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
 881        msleep(1);
 882        onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1);
 883        msleep(1);
 884        onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
 885        msleep(1);
 886
 887        if (onyx_register_init(onyx)) {
 888                printk(KERN_ERR PFX "failed to initialise onyx registers\n");
 889                return -ENODEV;
 890        }
 891
 892        if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, onyx, &ops)) {
 893                printk(KERN_ERR PFX "failed to create onyx snd device!\n");
 894                return -ENODEV;
 895        }
 896
 897        /* nothing connected? what a joke! */
 898        if ((onyx->codec.connected & 0xF) == 0)
 899                return -ENOTCONN;
 900
 901        /* if no inputs are present... */
 902        if ((onyx->codec.connected & 0xC) == 0) {
 903                if (!onyx->codec_info)
 904                        onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
 905                if (!onyx->codec_info)
 906                        return -ENOMEM;
 907                ci = onyx->codec_info;
 908                *ci = onyx_codec_info;
 909                ci->transfers++;
 910        }
 911
 912        /* if no outputs are present... */
 913        if ((onyx->codec.connected & 3) == 0) {
 914                if (!onyx->codec_info)
 915                        onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
 916                if (!onyx->codec_info)
 917                        return -ENOMEM;
 918                ci = onyx->codec_info;
 919                /* this is fine as there have to be inputs
 920                 * if we end up in this part of the code */
 921                *ci = onyx_codec_info;
 922                ci->transfers[1].formats = 0;
 923        }
 924
 925        if (onyx->codec.soundbus_dev->attach_codec(onyx->codec.soundbus_dev,
 926                                                   aoa_get_card(),
 927                                                   ci, onyx)) {
 928                printk(KERN_ERR PFX "error creating onyx pcm\n");
 929                return -ENODEV;
 930        }
 931#define ADDCTL(n)                                                       \
 932        do {                                                            \
 933                ctl = snd_ctl_new1(&n, onyx);                           \
 934                if (ctl) {                                              \
 935                        ctl->id.device =                                \
 936                                onyx->codec.soundbus_dev->pcm->device;  \
 937                        err = aoa_snd_ctl_add(ctl);                     \
 938                        if (err)                                        \
 939                                goto error;                             \
 940                }                                                       \
 941        } while (0)
 942
 943        if (onyx->codec.soundbus_dev->pcm) {
 944                /* give the user appropriate controls
 945                 * depending on what inputs are connected */
 946                if ((onyx->codec.connected & 0xC) == 0xC)
 947                        ADDCTL(capture_source_control);
 948                else if (onyx->codec.connected & 4)
 949                        onyx_set_capture_source(onyx, 0);
 950                else
 951                        onyx_set_capture_source(onyx, 1);
 952                if (onyx->codec.connected & 0xC)
 953                        ADDCTL(inputgain_control);
 954
 955                /* depending on what output is connected,
 956                 * give the user appropriate controls */
 957                if (onyx->codec.connected & 1) {
 958                        ADDCTL(volume_control);
 959                        ADDCTL(mute_control);
 960                        ADDCTL(ovr1_control);
 961                        ADDCTL(flt0_control);
 962                        ADDCTL(hpf_control);
 963                        ADDCTL(dm12_control);
 964                        /* spdif control defaults to off */
 965                }
 966                if (onyx->codec.connected & 2) {
 967                        ADDCTL(onyx_spdif_mask);
 968                        ADDCTL(onyx_spdif_ctrl);
 969                }
 970                if ((onyx->codec.connected & 3) == 3)
 971                        ADDCTL(spdif_control);
 972                /* if only S/PDIF is connected, enable it unconditionally */
 973                if ((onyx->codec.connected & 3) == 2) {
 974                        onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
 975                        v |= ONYX_SPDIF_ENABLE;
 976                        onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
 977                }
 978        }
 979#undef ADDCTL
 980        printk(KERN_INFO PFX "attached to onyx codec via i2c\n");
 981
 982        return 0;
 983 error:
 984        onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
 985        snd_device_free(aoa_get_card(), onyx);
 986        return err;
 987}
 988
 989static void onyx_exit_codec(struct aoa_codec *codec)
 990{
 991        struct onyx *onyx = codec_to_onyx(codec);
 992
 993        if (!onyx->codec.soundbus_dev) {
 994                printk(KERN_ERR PFX "onyx_exit_codec called without soundbus_dev!\n");
 995                return;
 996        }
 997        onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
 998}
 999
1000static int onyx_i2c_probe(struct i2c_client *client,
1001                          const struct i2c_device_id *id)
1002{
1003        struct device_node *node = client->dev.of_node;
1004        struct onyx *onyx;
1005        u8 dummy;
1006
1007        onyx = kzalloc(sizeof(struct onyx), GFP_KERNEL);
1008
1009        if (!onyx)
1010                return -ENOMEM;
1011
1012        mutex_init(&onyx->mutex);
1013        onyx->i2c = client;
1014        i2c_set_clientdata(client, onyx);
1015
1016        /* we try to read from register ONYX_REG_CONTROL
1017         * to check if the codec is present */
1018        if (onyx_read_register(onyx, ONYX_REG_CONTROL, &dummy) != 0) {
1019                printk(KERN_ERR PFX "failed to read control register\n");
1020                goto fail;
1021        }
1022
1023        strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN);
1024        onyx->codec.owner = THIS_MODULE;
1025        onyx->codec.init = onyx_init_codec;
1026        onyx->codec.exit = onyx_exit_codec;
1027        onyx->codec.node = of_node_get(node);
1028
1029        if (aoa_codec_register(&onyx->codec)) {
1030                goto fail;
1031        }
1032        printk(KERN_DEBUG PFX "created and attached onyx instance\n");
1033        return 0;
1034 fail:
1035        kfree(onyx);
1036        return -ENODEV;
1037}
1038
1039static int onyx_i2c_remove(struct i2c_client *client)
1040{
1041        struct onyx *onyx = i2c_get_clientdata(client);
1042
1043        aoa_codec_unregister(&onyx->codec);
1044        of_node_put(onyx->codec.node);
1045        kfree(onyx->codec_info);
1046        kfree(onyx);
1047        return 0;
1048}
1049
1050static const struct i2c_device_id onyx_i2c_id[] = {
1051        { "MAC,pcm3052", 0 },
1052        { }
1053};
1054MODULE_DEVICE_TABLE(i2c,onyx_i2c_id);
1055
1056static struct i2c_driver onyx_driver = {
1057        .driver = {
1058                .name = "aoa_codec_onyx",
1059                .owner = THIS_MODULE,
1060        },
1061        .probe = onyx_i2c_probe,
1062        .remove = onyx_i2c_remove,
1063        .id_table = onyx_i2c_id,
1064};
1065
1066module_i2c_driver(onyx_driver);
1067