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