Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Apple Onboard Audio driver for Onyx codec
0004  *
0005  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
0006  *
0007  * This is a driver for the pcm3052 codec chip (codenamed Onyx)
0008  * that is present in newer Apple hardware (with digital output).
0009  *
0010  * The Onyx codec has the following connections (listed by the bit
0011  * to be used in aoa_codec.connected):
0012  *  0: analog output
0013  *  1: digital output
0014  *  2: line input
0015  *  3: microphone input
0016  * Note that even though I know of no machine that has for example
0017  * the digital output connected but not the analog, I have handled
0018  * all the different cases in the code so that this driver may serve
0019  * as a good example of what to do.
0020  *
0021  * NOTE: This driver assumes that there's at most one chip to be
0022  *   used with one alsa card, in form of creating all kinds
0023  *   of mixer elements without regard for their existence.
0024  *   But snd-aoa assumes that there's at most one card, so
0025  *   this means you can only have one onyx on a system. This
0026  *   should probably be fixed by changing the assumption of
0027  *   having just a single card on a system, and making the
0028  *   'card' pointer accessible to anyone who needs it instead
0029  *   of hiding it in the aoa_snd_* functions...
0030  */
0031 #include <linux/delay.h>
0032 #include <linux/module.h>
0033 #include <linux/slab.h>
0034 MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
0035 MODULE_LICENSE("GPL");
0036 MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");
0037 
0038 #include "onyx.h"
0039 #include "../aoa.h"
0040 #include "../soundbus/soundbus.h"
0041 
0042 
0043 #define PFX "snd-aoa-codec-onyx: "
0044 
0045 struct onyx {
0046     /* cache registers 65 to 80, they are write-only! */
0047     u8          cache[16];
0048     struct i2c_client   *i2c;
0049     struct aoa_codec    codec;
0050     u32         initialised:1,
0051                 spdif_locked:1,
0052                 analog_locked:1,
0053                 original_mute:2;
0054     int         open_count;
0055     struct codec_info   *codec_info;
0056 
0057     /* mutex serializes concurrent access to the device
0058      * and this structure.
0059      */
0060     struct mutex mutex;
0061 };
0062 #define codec_to_onyx(c) container_of(c, struct onyx, codec)
0063 
0064 /* both return 0 if all ok, else on error */
0065 static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value)
0066 {
0067     s32 v;
0068 
0069     if (reg != ONYX_REG_CONTROL) {
0070         *value = onyx->cache[reg-FIRSTREGISTER];
0071         return 0;
0072     }
0073     v = i2c_smbus_read_byte_data(onyx->i2c, reg);
0074     if (v < 0) {
0075         *value = 0;
0076         return -1;
0077     }
0078     *value = (u8)v;
0079     onyx->cache[ONYX_REG_CONTROL-FIRSTREGISTER] = *value;
0080     return 0;
0081 }
0082 
0083 static int onyx_write_register(struct onyx *onyx, u8 reg, u8 value)
0084 {
0085     int result;
0086 
0087     result = i2c_smbus_write_byte_data(onyx->i2c, reg, value);
0088     if (!result)
0089         onyx->cache[reg-FIRSTREGISTER] = value;
0090     return result;
0091 }
0092 
0093 /* alsa stuff */
0094 
0095 static int onyx_dev_register(struct snd_device *dev)
0096 {
0097     return 0;
0098 }
0099 
0100 static const struct snd_device_ops ops = {
0101     .dev_register = onyx_dev_register,
0102 };
0103 
0104 /* this is necessary because most alsa mixer programs
0105  * can't properly handle the negative range */
0106 #define VOLUME_RANGE_SHIFT  128
0107 
0108 static int onyx_snd_vol_info(struct snd_kcontrol *kcontrol,
0109     struct snd_ctl_elem_info *uinfo)
0110 {
0111     uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0112     uinfo->count = 2;
0113     uinfo->value.integer.min = -128 + VOLUME_RANGE_SHIFT;
0114     uinfo->value.integer.max = -1 + VOLUME_RANGE_SHIFT;
0115     return 0;
0116 }
0117 
0118 static int onyx_snd_vol_get(struct snd_kcontrol *kcontrol,
0119     struct snd_ctl_elem_value *ucontrol)
0120 {
0121     struct onyx *onyx = snd_kcontrol_chip(kcontrol);
0122     s8 l, r;
0123 
0124     mutex_lock(&onyx->mutex);
0125     onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
0126     onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
0127     mutex_unlock(&onyx->mutex);
0128 
0129     ucontrol->value.integer.value[0] = l + VOLUME_RANGE_SHIFT;
0130     ucontrol->value.integer.value[1] = r + VOLUME_RANGE_SHIFT;
0131 
0132     return 0;
0133 }
0134 
0135 static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol,
0136     struct snd_ctl_elem_value *ucontrol)
0137 {
0138     struct onyx *onyx = snd_kcontrol_chip(kcontrol);
0139     s8 l, r;
0140 
0141     if (ucontrol->value.integer.value[0] < -128 + VOLUME_RANGE_SHIFT ||
0142         ucontrol->value.integer.value[0] > -1 + VOLUME_RANGE_SHIFT)
0143         return -EINVAL;
0144     if (ucontrol->value.integer.value[1] < -128 + VOLUME_RANGE_SHIFT ||
0145         ucontrol->value.integer.value[1] > -1 + VOLUME_RANGE_SHIFT)
0146         return -EINVAL;
0147 
0148     mutex_lock(&onyx->mutex);
0149     onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
0150     onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
0151 
0152     if (l + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[0] &&
0153         r + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[1]) {
0154         mutex_unlock(&onyx->mutex);
0155         return 0;
0156     }
0157 
0158     onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_LEFT,
0159                 ucontrol->value.integer.value[0]
0160                  - VOLUME_RANGE_SHIFT);
0161     onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT,
0162                 ucontrol->value.integer.value[1]
0163                  - VOLUME_RANGE_SHIFT);
0164     mutex_unlock(&onyx->mutex);
0165 
0166     return 1;
0167 }
0168 
0169 static const struct snd_kcontrol_new volume_control = {
0170     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0171     .name = "Master Playback Volume",
0172     .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0173     .info = onyx_snd_vol_info,
0174     .get = onyx_snd_vol_get,
0175     .put = onyx_snd_vol_put,
0176 };
0177 
0178 /* like above, this is necessary because a lot
0179  * of alsa mixer programs don't handle ranges
0180  * that don't start at 0 properly.
0181  * even alsamixer is one of them... */
0182 #define INPUTGAIN_RANGE_SHIFT   (-3)
0183 
0184 static int onyx_snd_inputgain_info(struct snd_kcontrol *kcontrol,
0185     struct snd_ctl_elem_info *uinfo)
0186 {
0187     uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0188     uinfo->count = 1;
0189     uinfo->value.integer.min = 3 + INPUTGAIN_RANGE_SHIFT;
0190     uinfo->value.integer.max = 28 + INPUTGAIN_RANGE_SHIFT;
0191     return 0;
0192 }
0193 
0194 static int onyx_snd_inputgain_get(struct snd_kcontrol *kcontrol,
0195     struct snd_ctl_elem_value *ucontrol)
0196 {
0197     struct onyx *onyx = snd_kcontrol_chip(kcontrol);
0198     u8 ig;
0199 
0200     mutex_lock(&onyx->mutex);
0201     onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &ig);
0202     mutex_unlock(&onyx->mutex);
0203 
0204     ucontrol->value.integer.value[0] =
0205         (ig & ONYX_ADC_PGA_GAIN_MASK) + INPUTGAIN_RANGE_SHIFT;
0206 
0207     return 0;
0208 }
0209 
0210 static int onyx_snd_inputgain_put(struct snd_kcontrol *kcontrol,
0211     struct snd_ctl_elem_value *ucontrol)
0212 {
0213     struct onyx *onyx = snd_kcontrol_chip(kcontrol);
0214     u8 v, n;
0215 
0216     if (ucontrol->value.integer.value[0] < 3 + INPUTGAIN_RANGE_SHIFT ||
0217         ucontrol->value.integer.value[0] > 28 + INPUTGAIN_RANGE_SHIFT)
0218         return -EINVAL;
0219     mutex_lock(&onyx->mutex);
0220     onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
0221     n = v;
0222     n &= ~ONYX_ADC_PGA_GAIN_MASK;
0223     n |= (ucontrol->value.integer.value[0] - INPUTGAIN_RANGE_SHIFT)
0224         & ONYX_ADC_PGA_GAIN_MASK;
0225     onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, n);
0226     mutex_unlock(&onyx->mutex);
0227 
0228     return n != v;
0229 }
0230 
0231 static const struct snd_kcontrol_new inputgain_control = {
0232     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0233     .name = "Master Capture Volume",
0234     .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0235     .info = onyx_snd_inputgain_info,
0236     .get = onyx_snd_inputgain_get,
0237     .put = onyx_snd_inputgain_put,
0238 };
0239 
0240 static int onyx_snd_capture_source_info(struct snd_kcontrol *kcontrol,
0241     struct snd_ctl_elem_info *uinfo)
0242 {
0243     static const char * const texts[] = { "Line-In", "Microphone" };
0244 
0245     return snd_ctl_enum_info(uinfo, 1, 2, texts);
0246 }
0247 
0248 static int onyx_snd_capture_source_get(struct snd_kcontrol *kcontrol,
0249     struct snd_ctl_elem_value *ucontrol)
0250 {
0251     struct onyx *onyx = snd_kcontrol_chip(kcontrol);
0252     s8 v;
0253 
0254     mutex_lock(&onyx->mutex);
0255     onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
0256     mutex_unlock(&onyx->mutex);
0257 
0258     ucontrol->value.enumerated.item[0] = !!(v&ONYX_ADC_INPUT_MIC);
0259 
0260     return 0;
0261 }
0262 
0263 static void onyx_set_capture_source(struct onyx *onyx, int mic)
0264 {
0265     s8 v;
0266 
0267     mutex_lock(&onyx->mutex);
0268     onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
0269     v &= ~ONYX_ADC_INPUT_MIC;
0270     if (mic)
0271         v |= ONYX_ADC_INPUT_MIC;
0272     onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, v);
0273     mutex_unlock(&onyx->mutex);
0274 }
0275 
0276 static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
0277     struct snd_ctl_elem_value *ucontrol)
0278 {
0279     if (ucontrol->value.enumerated.item[0] > 1)
0280         return -EINVAL;
0281     onyx_set_capture_source(snd_kcontrol_chip(kcontrol),
0282                 ucontrol->value.enumerated.item[0]);
0283     return 1;
0284 }
0285 
0286 static const struct snd_kcontrol_new capture_source_control = {
0287     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0288     /* If we name this 'Input Source', it properly shows up in
0289      * alsamixer as a selection, * but it's shown under the
0290      * 'Playback' category.
0291      * If I name it 'Capture Source', it shows up in strange
0292      * ways (two bools of which one can be selected at a
0293      * time) but at least it's shown in the 'Capture'
0294      * category.
0295      * I was told that this was due to backward compatibility,
0296      * but I don't understand then why the mangling is *not*
0297      * done when I name it "Input Source".....
0298      */
0299     .name = "Capture Source",
0300     .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0301     .info = onyx_snd_capture_source_info,
0302     .get = onyx_snd_capture_source_get,
0303     .put = onyx_snd_capture_source_put,
0304 };
0305 
0306 #define onyx_snd_mute_info  snd_ctl_boolean_stereo_info
0307 
0308 static int onyx_snd_mute_get(struct snd_kcontrol *kcontrol,
0309     struct snd_ctl_elem_value *ucontrol)
0310 {
0311     struct onyx *onyx = snd_kcontrol_chip(kcontrol);
0312     u8 c;
0313 
0314     mutex_lock(&onyx->mutex);
0315     onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &c);
0316     mutex_unlock(&onyx->mutex);
0317 
0318     ucontrol->value.integer.value[0] = !(c & ONYX_MUTE_LEFT);
0319     ucontrol->value.integer.value[1] = !(c & ONYX_MUTE_RIGHT);
0320 
0321     return 0;
0322 }
0323 
0324 static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol,
0325     struct snd_ctl_elem_value *ucontrol)
0326 {
0327     struct onyx *onyx = snd_kcontrol_chip(kcontrol);
0328     u8 v = 0, c = 0;
0329     int err = -EBUSY;
0330 
0331     mutex_lock(&onyx->mutex);
0332     if (onyx->analog_locked)
0333         goto out_unlock;
0334 
0335     onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
0336     c = v;
0337     c &= ~(ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT);
0338     if (!ucontrol->value.integer.value[0])
0339         c |= ONYX_MUTE_LEFT;
0340     if (!ucontrol->value.integer.value[1])
0341         c |= ONYX_MUTE_RIGHT;
0342     err = onyx_write_register(onyx, ONYX_REG_DAC_CONTROL, c);
0343 
0344  out_unlock:
0345     mutex_unlock(&onyx->mutex);
0346 
0347     return !err ? (v != c) : err;
0348 }
0349 
0350 static const struct snd_kcontrol_new mute_control = {
0351     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0352     .name = "Master Playback Switch",
0353     .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0354     .info = onyx_snd_mute_info,
0355     .get = onyx_snd_mute_get,
0356     .put = onyx_snd_mute_put,
0357 };
0358 
0359 
0360 #define onyx_snd_single_bit_info    snd_ctl_boolean_mono_info
0361 
0362 #define FLAG_POLARITY_INVERT    1
0363 #define FLAG_SPDIFLOCK      2
0364 
0365 static int onyx_snd_single_bit_get(struct snd_kcontrol *kcontrol,
0366     struct snd_ctl_elem_value *ucontrol)
0367 {
0368     struct onyx *onyx = snd_kcontrol_chip(kcontrol);
0369     u8 c;
0370     long int pv = kcontrol->private_value;
0371     u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
0372     u8 address = (pv >> 8) & 0xff;
0373     u8 mask = pv & 0xff;
0374 
0375     mutex_lock(&onyx->mutex);
0376     onyx_read_register(onyx, address, &c);
0377     mutex_unlock(&onyx->mutex);
0378 
0379     ucontrol->value.integer.value[0] = !!(c & mask) ^ polarity;
0380 
0381     return 0;
0382 }
0383 
0384 static int onyx_snd_single_bit_put(struct snd_kcontrol *kcontrol,
0385     struct snd_ctl_elem_value *ucontrol)
0386 {
0387     struct onyx *onyx = snd_kcontrol_chip(kcontrol);
0388     u8 v = 0, c = 0;
0389     int err;
0390     long int pv = kcontrol->private_value;
0391     u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
0392     u8 spdiflock = (pv >> 16) & FLAG_SPDIFLOCK;
0393     u8 address = (pv >> 8) & 0xff;
0394     u8 mask = pv & 0xff;
0395 
0396     mutex_lock(&onyx->mutex);
0397     if (spdiflock && onyx->spdif_locked) {
0398         /* even if alsamixer doesn't care.. */
0399         err = -EBUSY;
0400         goto out_unlock;
0401     }
0402     onyx_read_register(onyx, address, &v);
0403     c = v;
0404     c &= ~(mask);
0405     if (!!ucontrol->value.integer.value[0] ^ polarity)
0406         c |= mask;
0407     err = onyx_write_register(onyx, address, c);
0408 
0409  out_unlock:
0410     mutex_unlock(&onyx->mutex);
0411 
0412     return !err ? (v != c) : err;
0413 }
0414 
0415 #define SINGLE_BIT(n, type, description, address, mask, flags)      \
0416 static const struct snd_kcontrol_new n##_control = {            \
0417     .iface = SNDRV_CTL_ELEM_IFACE_##type,               \
0418     .name = description,                        \
0419     .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,          \
0420     .info = onyx_snd_single_bit_info,               \
0421     .get = onyx_snd_single_bit_get,                 \
0422     .put = onyx_snd_single_bit_put,                 \
0423     .private_value = (flags << 16) | (address << 8) | mask      \
0424 }
0425 
0426 SINGLE_BIT(spdif,
0427        MIXER,
0428        SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
0429        ONYX_REG_DIG_INFO4,
0430        ONYX_SPDIF_ENABLE,
0431        FLAG_SPDIFLOCK);
0432 SINGLE_BIT(ovr1,
0433        MIXER,
0434        "Oversampling Rate",
0435        ONYX_REG_DAC_CONTROL,
0436        ONYX_OVR1,
0437        0);
0438 SINGLE_BIT(flt0,
0439        MIXER,
0440        "Fast Digital Filter Rolloff",
0441        ONYX_REG_DAC_FILTER,
0442        ONYX_ROLLOFF_FAST,
0443        FLAG_POLARITY_INVERT);
0444 SINGLE_BIT(hpf,
0445        MIXER,
0446        "Highpass Filter",
0447        ONYX_REG_ADC_HPF_BYPASS,
0448        ONYX_HPF_DISABLE,
0449        FLAG_POLARITY_INVERT);
0450 SINGLE_BIT(dm12,
0451        MIXER,
0452        "Digital De-Emphasis",
0453        ONYX_REG_DAC_DEEMPH,
0454        ONYX_DIGDEEMPH_CTRL,
0455        0);
0456 
0457 static int onyx_spdif_info(struct snd_kcontrol *kcontrol,
0458                struct snd_ctl_elem_info *uinfo)
0459 {
0460     uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
0461     uinfo->count = 1;
0462     return 0;
0463 }
0464 
0465 static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol,
0466                    struct snd_ctl_elem_value *ucontrol)
0467 {
0468     /* datasheet page 30, all others are 0 */
0469     ucontrol->value.iec958.status[0] = 0x3e;
0470     ucontrol->value.iec958.status[1] = 0xff;
0471 
0472     ucontrol->value.iec958.status[3] = 0x3f;
0473     ucontrol->value.iec958.status[4] = 0x0f;
0474 
0475     return 0;
0476 }
0477 
0478 static const struct snd_kcontrol_new onyx_spdif_mask = {
0479     .access =   SNDRV_CTL_ELEM_ACCESS_READ,
0480     .iface =    SNDRV_CTL_ELEM_IFACE_PCM,
0481     .name =     SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
0482     .info =     onyx_spdif_info,
0483     .get =      onyx_spdif_mask_get,
0484 };
0485 
0486 static int onyx_spdif_get(struct snd_kcontrol *kcontrol,
0487               struct snd_ctl_elem_value *ucontrol)
0488 {
0489     struct onyx *onyx = snd_kcontrol_chip(kcontrol);
0490     u8 v;
0491 
0492     mutex_lock(&onyx->mutex);
0493     onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
0494     ucontrol->value.iec958.status[0] = v & 0x3e;
0495 
0496     onyx_read_register(onyx, ONYX_REG_DIG_INFO2, &v);
0497     ucontrol->value.iec958.status[1] = v;
0498 
0499     onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
0500     ucontrol->value.iec958.status[3] = v & 0x3f;
0501 
0502     onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
0503     ucontrol->value.iec958.status[4] = v & 0x0f;
0504     mutex_unlock(&onyx->mutex);
0505 
0506     return 0;
0507 }
0508 
0509 static int onyx_spdif_put(struct snd_kcontrol *kcontrol,
0510               struct snd_ctl_elem_value *ucontrol)
0511 {
0512     struct onyx *onyx = snd_kcontrol_chip(kcontrol);
0513     u8 v;
0514 
0515     mutex_lock(&onyx->mutex);
0516     onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
0517     v = (v & ~0x3e) | (ucontrol->value.iec958.status[0] & 0x3e);
0518     onyx_write_register(onyx, ONYX_REG_DIG_INFO1, v);
0519 
0520     v = ucontrol->value.iec958.status[1];
0521     onyx_write_register(onyx, ONYX_REG_DIG_INFO2, v);
0522 
0523     onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
0524     v = (v & ~0x3f) | (ucontrol->value.iec958.status[3] & 0x3f);
0525     onyx_write_register(onyx, ONYX_REG_DIG_INFO3, v);
0526 
0527     onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
0528     v = (v & ~0x0f) | (ucontrol->value.iec958.status[4] & 0x0f);
0529     onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
0530     mutex_unlock(&onyx->mutex);
0531 
0532     return 1;
0533 }
0534 
0535 static const struct snd_kcontrol_new onyx_spdif_ctrl = {
0536     .access =   SNDRV_CTL_ELEM_ACCESS_READWRITE,
0537     .iface =    SNDRV_CTL_ELEM_IFACE_PCM,
0538     .name =     SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
0539     .info =     onyx_spdif_info,
0540     .get =      onyx_spdif_get,
0541     .put =      onyx_spdif_put,
0542 };
0543 
0544 /* our registers */
0545 
0546 static const u8 register_map[] = {
0547     ONYX_REG_DAC_ATTEN_LEFT,
0548     ONYX_REG_DAC_ATTEN_RIGHT,
0549     ONYX_REG_CONTROL,
0550     ONYX_REG_DAC_CONTROL,
0551     ONYX_REG_DAC_DEEMPH,
0552     ONYX_REG_DAC_FILTER,
0553     ONYX_REG_DAC_OUTPHASE,
0554     ONYX_REG_ADC_CONTROL,
0555     ONYX_REG_ADC_HPF_BYPASS,
0556     ONYX_REG_DIG_INFO1,
0557     ONYX_REG_DIG_INFO2,
0558     ONYX_REG_DIG_INFO3,
0559     ONYX_REG_DIG_INFO4
0560 };
0561 
0562 static const u8 initial_values[ARRAY_SIZE(register_map)] = {
0563     0x80, 0x80, /* muted */
0564     ONYX_MRST | ONYX_SRST, /* but handled specially! */
0565     ONYX_MUTE_LEFT | ONYX_MUTE_RIGHT,
0566     0, /* no deemphasis */
0567     ONYX_DAC_FILTER_ALWAYS,
0568     ONYX_OUTPHASE_INVERTED,
0569     (-1 /*dB*/ + 8) & 0xF, /* line in selected, -1 dB gain*/
0570     ONYX_ADC_HPF_ALWAYS,
0571     (1<<2), /* pcm audio */
0572     2,  /* category: pcm coder */
0573     0,  /* sampling frequency 44.1 kHz, clock accuracy level II */
0574     1   /* 24 bit depth */
0575 };
0576 
0577 /* reset registers of chip, either to initial or to previous values */
0578 static int onyx_register_init(struct onyx *onyx)
0579 {
0580     int i;
0581     u8 val;
0582     u8 regs[sizeof(initial_values)];
0583 
0584     if (!onyx->initialised) {
0585         memcpy(regs, initial_values, sizeof(initial_values));
0586         if (onyx_read_register(onyx, ONYX_REG_CONTROL, &val))
0587             return -1;
0588         val &= ~ONYX_SILICONVERSION;
0589         val |= initial_values[3];
0590         regs[3] = val;
0591     } else {
0592         for (i=0; i<sizeof(register_map); i++)
0593             regs[i] = onyx->cache[register_map[i]-FIRSTREGISTER];
0594     }
0595 
0596     for (i=0; i<sizeof(register_map); i++) {
0597         if (onyx_write_register(onyx, register_map[i], regs[i]))
0598             return -1;
0599     }
0600     onyx->initialised = 1;
0601     return 0;
0602 }
0603 
0604 static struct transfer_info onyx_transfers[] = {
0605     /* this is first so we can skip it if no input is present...
0606      * No hardware exists with that, but it's here as an example
0607      * of what to do :) */
0608     {
0609         /* analog input */
0610         .formats = SNDRV_PCM_FMTBIT_S8 |
0611                SNDRV_PCM_FMTBIT_S16_BE |
0612                SNDRV_PCM_FMTBIT_S24_BE,
0613         .rates = SNDRV_PCM_RATE_8000_96000,
0614         .transfer_in = 1,
0615         .must_be_clock_source = 0,
0616         .tag = 0,
0617     },
0618     {
0619         /* if analog and digital are currently off, anything should go,
0620          * so this entry describes everything we can do... */
0621         .formats = SNDRV_PCM_FMTBIT_S8 |
0622                SNDRV_PCM_FMTBIT_S16_BE |
0623                SNDRV_PCM_FMTBIT_S24_BE
0624 #ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
0625                | SNDRV_PCM_FMTBIT_COMPRESSED_16BE
0626 #endif
0627         ,
0628         .rates = SNDRV_PCM_RATE_8000_96000,
0629         .tag = 0,
0630     },
0631     {
0632         /* analog output */
0633         .formats = SNDRV_PCM_FMTBIT_S8 |
0634                SNDRV_PCM_FMTBIT_S16_BE |
0635                SNDRV_PCM_FMTBIT_S24_BE,
0636         .rates = SNDRV_PCM_RATE_8000_96000,
0637         .transfer_in = 0,
0638         .must_be_clock_source = 0,
0639         .tag = 1,
0640     },
0641     {
0642         /* digital pcm output, also possible for analog out */
0643         .formats = SNDRV_PCM_FMTBIT_S8 |
0644                SNDRV_PCM_FMTBIT_S16_BE |
0645                SNDRV_PCM_FMTBIT_S24_BE,
0646         .rates = SNDRV_PCM_RATE_32000 |
0647              SNDRV_PCM_RATE_44100 |
0648              SNDRV_PCM_RATE_48000,
0649         .transfer_in = 0,
0650         .must_be_clock_source = 0,
0651         .tag = 2,
0652     },
0653 #ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
0654     /* Once alsa gets supports for this kind of thing we can add it... */
0655     {
0656         /* digital compressed output */
0657         .formats =  SNDRV_PCM_FMTBIT_COMPRESSED_16BE,
0658         .rates = SNDRV_PCM_RATE_32000 |
0659              SNDRV_PCM_RATE_44100 |
0660              SNDRV_PCM_RATE_48000,
0661         .tag = 2,
0662     },
0663 #endif
0664     {}
0665 };
0666 
0667 static int onyx_usable(struct codec_info_item *cii,
0668                struct transfer_info *ti,
0669                struct transfer_info *out)
0670 {
0671     u8 v;
0672     struct onyx *onyx = cii->codec_data;
0673     int spdif_enabled, analog_enabled;
0674 
0675     mutex_lock(&onyx->mutex);
0676     onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
0677     spdif_enabled = !!(v & ONYX_SPDIF_ENABLE);
0678     onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
0679     analog_enabled =
0680         (v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT))
0681          != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT);
0682     mutex_unlock(&onyx->mutex);
0683 
0684     switch (ti->tag) {
0685     case 0: return 1;
0686     case 1: return analog_enabled;
0687     case 2: return spdif_enabled;
0688     }
0689     return 1;
0690 }
0691 
0692 static int onyx_prepare(struct codec_info_item *cii,
0693             struct bus_info *bi,
0694             struct snd_pcm_substream *substream)
0695 {
0696     u8 v;
0697     struct onyx *onyx = cii->codec_data;
0698     int err = -EBUSY;
0699 
0700     mutex_lock(&onyx->mutex);
0701 
0702 #ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
0703     if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) {
0704         /* mute and lock analog output */
0705         onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
0706         if (onyx_write_register(onyx,
0707                     ONYX_REG_DAC_CONTROL,
0708                     v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT))
0709             goto out_unlock;
0710         onyx->analog_locked = 1;
0711         err = 0;
0712         goto out_unlock;
0713     }
0714 #endif
0715     switch (substream->runtime->rate) {
0716     case 32000:
0717     case 44100:
0718     case 48000:
0719         /* these rates are ok for all outputs */
0720         /* FIXME: program spdif channel control bits here so that
0721          *    userspace doesn't have to if it only plays pcm! */
0722         err = 0;
0723         goto out_unlock;
0724     default:
0725         /* got some rate that the digital output can't do,
0726          * so disable and lock it */
0727         onyx_read_register(cii->codec_data, ONYX_REG_DIG_INFO4, &v);
0728         if (onyx_write_register(onyx,
0729                     ONYX_REG_DIG_INFO4,
0730                     v & ~ONYX_SPDIF_ENABLE))
0731             goto out_unlock;
0732         onyx->spdif_locked = 1;
0733         err = 0;
0734         goto out_unlock;
0735     }
0736 
0737  out_unlock:
0738     mutex_unlock(&onyx->mutex);
0739 
0740     return err;
0741 }
0742 
0743 static int onyx_open(struct codec_info_item *cii,
0744              struct snd_pcm_substream *substream)
0745 {
0746     struct onyx *onyx = cii->codec_data;
0747 
0748     mutex_lock(&onyx->mutex);
0749     onyx->open_count++;
0750     mutex_unlock(&onyx->mutex);
0751 
0752     return 0;
0753 }
0754 
0755 static int onyx_close(struct codec_info_item *cii,
0756               struct snd_pcm_substream *substream)
0757 {
0758     struct onyx *onyx = cii->codec_data;
0759 
0760     mutex_lock(&onyx->mutex);
0761     onyx->open_count--;
0762     if (!onyx->open_count)
0763         onyx->spdif_locked = onyx->analog_locked = 0;
0764     mutex_unlock(&onyx->mutex);
0765 
0766     return 0;
0767 }
0768 
0769 static int onyx_switch_clock(struct codec_info_item *cii,
0770                  enum clock_switch what)
0771 {
0772     struct onyx *onyx = cii->codec_data;
0773 
0774     mutex_lock(&onyx->mutex);
0775     /* this *MUST* be more elaborate later... */
0776     switch (what) {
0777     case CLOCK_SWITCH_PREPARE_SLAVE:
0778         onyx->codec.gpio->methods->all_amps_off(onyx->codec.gpio);
0779         break;
0780     case CLOCK_SWITCH_SLAVE:
0781         onyx->codec.gpio->methods->all_amps_restore(onyx->codec.gpio);
0782         break;
0783     default: /* silence warning */
0784         break;
0785     }
0786     mutex_unlock(&onyx->mutex);
0787 
0788     return 0;
0789 }
0790 
0791 #ifdef CONFIG_PM
0792 
0793 static int onyx_suspend(struct codec_info_item *cii, pm_message_t state)
0794 {
0795     struct onyx *onyx = cii->codec_data;
0796     u8 v;
0797     int err = -ENXIO;
0798 
0799     mutex_lock(&onyx->mutex);
0800     if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
0801         goto out_unlock;
0802     onyx_write_register(onyx, ONYX_REG_CONTROL, v | ONYX_ADPSV | ONYX_DAPSV);
0803     /* Apple does a sleep here but the datasheet says to do it on resume */
0804     err = 0;
0805  out_unlock:
0806     mutex_unlock(&onyx->mutex);
0807 
0808     return err;
0809 }
0810 
0811 static int onyx_resume(struct codec_info_item *cii)
0812 {
0813     struct onyx *onyx = cii->codec_data;
0814     u8 v;
0815     int err = -ENXIO;
0816 
0817     mutex_lock(&onyx->mutex);
0818 
0819     /* reset codec */
0820     onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
0821     msleep(1);
0822     onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1);
0823     msleep(1);
0824     onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
0825     msleep(1);
0826 
0827     /* take codec out of suspend (if it still is after reset) */
0828     if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
0829         goto out_unlock;
0830     onyx_write_register(onyx, ONYX_REG_CONTROL, v & ~(ONYX_ADPSV | ONYX_DAPSV));
0831     /* FIXME: should divide by sample rate, but 8k is the lowest we go */
0832     msleep(2205000/8000);
0833     /* reset all values */
0834     onyx_register_init(onyx);
0835     err = 0;
0836  out_unlock:
0837     mutex_unlock(&onyx->mutex);
0838 
0839     return err;
0840 }
0841 
0842 #endif /* CONFIG_PM */
0843 
0844 static struct codec_info onyx_codec_info = {
0845     .transfers = onyx_transfers,
0846     .sysclock_factor = 256,
0847     .bus_factor = 64,
0848     .owner = THIS_MODULE,
0849     .usable = onyx_usable,
0850     .prepare = onyx_prepare,
0851     .open = onyx_open,
0852     .close = onyx_close,
0853     .switch_clock = onyx_switch_clock,
0854 #ifdef CONFIG_PM
0855     .suspend = onyx_suspend,
0856     .resume = onyx_resume,
0857 #endif
0858 };
0859 
0860 static int onyx_init_codec(struct aoa_codec *codec)
0861 {
0862     struct onyx *onyx = codec_to_onyx(codec);
0863     struct snd_kcontrol *ctl;
0864     struct codec_info *ci = &onyx_codec_info;
0865     u8 v;
0866     int err;
0867 
0868     if (!onyx->codec.gpio || !onyx->codec.gpio->methods) {
0869         printk(KERN_ERR PFX "gpios not assigned!!\n");
0870         return -EINVAL;
0871     }
0872 
0873     onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
0874     msleep(1);
0875     onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1);
0876     msleep(1);
0877     onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
0878     msleep(1);
0879 
0880     if (onyx_register_init(onyx)) {
0881         printk(KERN_ERR PFX "failed to initialise onyx registers\n");
0882         return -ENODEV;
0883     }
0884 
0885     if (aoa_snd_device_new(SNDRV_DEV_CODEC, onyx, &ops)) {
0886         printk(KERN_ERR PFX "failed to create onyx snd device!\n");
0887         return -ENODEV;
0888     }
0889 
0890     /* nothing connected? what a joke! */
0891     if ((onyx->codec.connected & 0xF) == 0)
0892         return -ENOTCONN;
0893 
0894     /* if no inputs are present... */
0895     if ((onyx->codec.connected & 0xC) == 0) {
0896         if (!onyx->codec_info)
0897             onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
0898         if (!onyx->codec_info)
0899             return -ENOMEM;
0900         ci = onyx->codec_info;
0901         *ci = onyx_codec_info;
0902         ci->transfers++;
0903     }
0904 
0905     /* if no outputs are present... */
0906     if ((onyx->codec.connected & 3) == 0) {
0907         if (!onyx->codec_info)
0908             onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
0909         if (!onyx->codec_info)
0910             return -ENOMEM;
0911         ci = onyx->codec_info;
0912         /* this is fine as there have to be inputs
0913          * if we end up in this part of the code */
0914         *ci = onyx_codec_info;
0915         ci->transfers[1].formats = 0;
0916     }
0917 
0918     if (onyx->codec.soundbus_dev->attach_codec(onyx->codec.soundbus_dev,
0919                            aoa_get_card(),
0920                            ci, onyx)) {
0921         printk(KERN_ERR PFX "error creating onyx pcm\n");
0922         return -ENODEV;
0923     }
0924 #define ADDCTL(n)                           \
0925     do {                                \
0926         ctl = snd_ctl_new1(&n, onyx);               \
0927         if (ctl) {                      \
0928             ctl->id.device =                \
0929                 onyx->codec.soundbus_dev->pcm->device;  \
0930             err = aoa_snd_ctl_add(ctl);         \
0931             if (err)                    \
0932                 goto error;             \
0933         }                           \
0934     } while (0)
0935 
0936     if (onyx->codec.soundbus_dev->pcm) {
0937         /* give the user appropriate controls
0938          * depending on what inputs are connected */
0939         if ((onyx->codec.connected & 0xC) == 0xC)
0940             ADDCTL(capture_source_control);
0941         else if (onyx->codec.connected & 4)
0942             onyx_set_capture_source(onyx, 0);
0943         else
0944             onyx_set_capture_source(onyx, 1);
0945         if (onyx->codec.connected & 0xC)
0946             ADDCTL(inputgain_control);
0947 
0948         /* depending on what output is connected,
0949          * give the user appropriate controls */
0950         if (onyx->codec.connected & 1) {
0951             ADDCTL(volume_control);
0952             ADDCTL(mute_control);
0953             ADDCTL(ovr1_control);
0954             ADDCTL(flt0_control);
0955             ADDCTL(hpf_control);
0956             ADDCTL(dm12_control);
0957             /* spdif control defaults to off */
0958         }
0959         if (onyx->codec.connected & 2) {
0960             ADDCTL(onyx_spdif_mask);
0961             ADDCTL(onyx_spdif_ctrl);
0962         }
0963         if ((onyx->codec.connected & 3) == 3)
0964             ADDCTL(spdif_control);
0965         /* if only S/PDIF is connected, enable it unconditionally */
0966         if ((onyx->codec.connected & 3) == 2) {
0967             onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
0968             v |= ONYX_SPDIF_ENABLE;
0969             onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
0970         }
0971     }
0972 #undef ADDCTL
0973     printk(KERN_INFO PFX "attached to onyx codec via i2c\n");
0974 
0975     return 0;
0976  error:
0977     onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
0978     snd_device_free(aoa_get_card(), onyx);
0979     return err;
0980 }
0981 
0982 static void onyx_exit_codec(struct aoa_codec *codec)
0983 {
0984     struct onyx *onyx = codec_to_onyx(codec);
0985 
0986     if (!onyx->codec.soundbus_dev) {
0987         printk(KERN_ERR PFX "onyx_exit_codec called without soundbus_dev!\n");
0988         return;
0989     }
0990     onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
0991 }
0992 
0993 static int onyx_i2c_probe(struct i2c_client *client,
0994               const struct i2c_device_id *id)
0995 {
0996     struct device_node *node = client->dev.of_node;
0997     struct onyx *onyx;
0998     u8 dummy;
0999 
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 
1032 static 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 
1043 static const struct i2c_device_id onyx_i2c_id[] = {
1044     { "MAC,pcm3052", 0 },
1045     { }
1046 };
1047 MODULE_DEVICE_TABLE(i2c,onyx_i2c_id);
1048 
1049 static 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 
1058 module_i2c_driver(onyx_driver);