Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/aoa/codecs/onyx.c
29266 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Apple Onboard Audio driver for Onyx codec
4
*
5
* Copyright 2006 Johannes Berg <[email protected]>
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 <[email protected]>");
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
1019