Linux Audio

Check our new training course

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