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