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