OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [tags/] [linux-2.6/] [linux-2.6.24_or32_unified_v2.3/] [sound/] [aoa/] [codecs/] [snd-aoa-codec-onyx.c] - Blame information for rev 8

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.