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 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        },
1054        .probe = onyx_i2c_probe,
1055        .remove = onyx_i2c_remove,
1056        .id_table = onyx_i2c_id,
1057};
1058
1059module_i2c_driver(onyx_driver);
1060