0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
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
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
0058
0059
0060 struct mutex mutex;
0061 };
0062 #define codec_to_onyx(c) container_of(c, struct onyx, codec)
0063
0064
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
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
0105
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
0179
0180
0181
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
0289
0290
0291
0292
0293
0294
0295
0296
0297
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
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
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
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,
0564 ONYX_MRST | ONYX_SRST,
0565 ONYX_MUTE_LEFT | ONYX_MUTE_RIGHT,
0566 0,
0567 ONYX_DAC_FILTER_ALWAYS,
0568 ONYX_OUTPHASE_INVERTED,
0569 (-1 + 8) & 0xF,
0570 ONYX_ADC_HPF_ALWAYS,
0571 (1<<2),
0572 2,
0573 0,
0574 1
0575 };
0576
0577
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
0606
0607
0608 {
0609
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
0620
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
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
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
0655 {
0656
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
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
0720
0721
0722 err = 0;
0723 goto out_unlock;
0724 default:
0725
0726
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
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:
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
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
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
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
0832 msleep(2205000/8000);
0833
0834 onyx_register_init(onyx);
0835 err = 0;
0836 out_unlock:
0837 mutex_unlock(&onyx->mutex);
0838
0839 return err;
0840 }
0841
0842 #endif
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
0891 if ((onyx->codec.connected & 0xF) == 0)
0892 return -ENOTCONN;
0893
0894
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
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
0913
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
0938
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
0949
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
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
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
1010
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);