Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/ppc/awacs.c
29266 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* PMac AWACS lowlevel functions
4
*
5
* Copyright (c) by Takashi Iwai <[email protected]>
6
* code based on dmasound.c.
7
*/
8
9
10
#include <linux/io.h>
11
#include <asm/nvram.h>
12
#include <linux/init.h>
13
#include <linux/delay.h>
14
#include <linux/of.h>
15
#include <linux/slab.h>
16
#include <sound/core.h>
17
#include "pmac.h"
18
19
20
#ifdef CONFIG_ADB_CUDA
21
#define PMAC_AMP_AVAIL
22
#endif
23
24
#ifdef PMAC_AMP_AVAIL
25
struct awacs_amp {
26
unsigned char amp_master;
27
unsigned char amp_vol[2][2];
28
unsigned char amp_tone[2];
29
};
30
31
#define CHECK_CUDA_AMP() (sys_ctrler == SYS_CTRLER_CUDA)
32
33
#endif /* PMAC_AMP_AVAIL */
34
35
36
static void snd_pmac_screamer_wait(struct snd_pmac *chip)
37
{
38
long timeout = 2000;
39
while (!(in_le32(&chip->awacs->codec_stat) & MASK_VALID)) {
40
mdelay(1);
41
if (! --timeout) {
42
dev_dbg(chip->card->dev, "%s timeout\n", __func__);
43
break;
44
}
45
}
46
}
47
48
/*
49
* write AWACS register
50
*/
51
static void
52
snd_pmac_awacs_write(struct snd_pmac *chip, int val)
53
{
54
long timeout = 5000000;
55
56
if (chip->model == PMAC_SCREAMER)
57
snd_pmac_screamer_wait(chip);
58
out_le32(&chip->awacs->codec_ctrl, val | (chip->subframe << 22));
59
while (in_le32(&chip->awacs->codec_ctrl) & MASK_NEWECMD) {
60
if (! --timeout) {
61
dev_dbg(chip->card->dev, "%s timeout\n", __func__);
62
break;
63
}
64
}
65
}
66
67
static void
68
snd_pmac_awacs_write_reg(struct snd_pmac *chip, int reg, int val)
69
{
70
snd_pmac_awacs_write(chip, val | (reg << 12));
71
chip->awacs_reg[reg] = val;
72
}
73
74
static void
75
snd_pmac_awacs_write_noreg(struct snd_pmac *chip, int reg, int val)
76
{
77
snd_pmac_awacs_write(chip, val | (reg << 12));
78
}
79
80
#ifdef CONFIG_PM
81
/* Recalibrate chip */
82
static void screamer_recalibrate(struct snd_pmac *chip)
83
{
84
if (chip->model != PMAC_SCREAMER)
85
return;
86
87
/* Sorry for the horrible delays... I hope to get that improved
88
* by making the whole PM process asynchronous in a future version
89
*/
90
snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
91
if (chip->manufacturer == 0x1)
92
/* delay for broken crystal part */
93
msleep(750);
94
snd_pmac_awacs_write_noreg(chip, 1,
95
chip->awacs_reg[1] | MASK_RECALIBRATE |
96
MASK_CMUTE | MASK_AMUTE);
97
snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
98
snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
99
}
100
101
#else
102
#define screamer_recalibrate(chip) /* NOP */
103
#endif
104
105
106
/*
107
* additional callback to set the pcm format
108
*/
109
static void snd_pmac_awacs_set_format(struct snd_pmac *chip)
110
{
111
chip->awacs_reg[1] &= ~MASK_SAMPLERATE;
112
chip->awacs_reg[1] |= chip->rate_index << 3;
113
snd_pmac_awacs_write_reg(chip, 1, chip->awacs_reg[1]);
114
}
115
116
117
/*
118
* AWACS volume callbacks
119
*/
120
/*
121
* volumes: 0-15 stereo
122
*/
123
static int snd_pmac_awacs_info_volume(struct snd_kcontrol *kcontrol,
124
struct snd_ctl_elem_info *uinfo)
125
{
126
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
127
uinfo->count = 2;
128
uinfo->value.integer.min = 0;
129
uinfo->value.integer.max = 15;
130
return 0;
131
}
132
133
static int snd_pmac_awacs_get_volume(struct snd_kcontrol *kcontrol,
134
struct snd_ctl_elem_value *ucontrol)
135
{
136
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
137
int reg = kcontrol->private_value & 0xff;
138
int lshift = (kcontrol->private_value >> 8) & 0xff;
139
int inverted = (kcontrol->private_value >> 16) & 1;
140
int vol[2];
141
142
guard(spinlock_irqsave)(&chip->reg_lock);
143
vol[0] = (chip->awacs_reg[reg] >> lshift) & 0xf;
144
vol[1] = chip->awacs_reg[reg] & 0xf;
145
if (inverted) {
146
vol[0] = 0x0f - vol[0];
147
vol[1] = 0x0f - vol[1];
148
}
149
ucontrol->value.integer.value[0] = vol[0];
150
ucontrol->value.integer.value[1] = vol[1];
151
return 0;
152
}
153
154
static int snd_pmac_awacs_put_volume(struct snd_kcontrol *kcontrol,
155
struct snd_ctl_elem_value *ucontrol)
156
{
157
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
158
int reg = kcontrol->private_value & 0xff;
159
int lshift = (kcontrol->private_value >> 8) & 0xff;
160
int inverted = (kcontrol->private_value >> 16) & 1;
161
int val, oldval;
162
unsigned int vol[2];
163
164
vol[0] = ucontrol->value.integer.value[0];
165
vol[1] = ucontrol->value.integer.value[1];
166
if (vol[0] > 0x0f || vol[1] > 0x0f)
167
return -EINVAL;
168
if (inverted) {
169
vol[0] = 0x0f - vol[0];
170
vol[1] = 0x0f - vol[1];
171
}
172
vol[0] &= 0x0f;
173
vol[1] &= 0x0f;
174
guard(spinlock_irqsave)(&chip->reg_lock);
175
oldval = chip->awacs_reg[reg];
176
val = oldval & ~(0xf | (0xf << lshift));
177
val |= vol[0] << lshift;
178
val |= vol[1];
179
if (oldval != val)
180
snd_pmac_awacs_write_reg(chip, reg, val);
181
return oldval != reg;
182
}
183
184
185
#define AWACS_VOLUME(xname, xreg, xshift, xinverted) \
186
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
187
.info = snd_pmac_awacs_info_volume, \
188
.get = snd_pmac_awacs_get_volume, \
189
.put = snd_pmac_awacs_put_volume, \
190
.private_value = (xreg) | ((xshift) << 8) | ((xinverted) << 16) }
191
192
/*
193
* mute master/ogain for AWACS: mono
194
*/
195
static int snd_pmac_awacs_get_switch(struct snd_kcontrol *kcontrol,
196
struct snd_ctl_elem_value *ucontrol)
197
{
198
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
199
int reg = kcontrol->private_value & 0xff;
200
int shift = (kcontrol->private_value >> 8) & 0xff;
201
int invert = (kcontrol->private_value >> 16) & 1;
202
int val;
203
204
guard(spinlock_irqsave)(&chip->reg_lock);
205
val = (chip->awacs_reg[reg] >> shift) & 1;
206
if (invert)
207
val = 1 - val;
208
ucontrol->value.integer.value[0] = val;
209
return 0;
210
}
211
212
static int snd_pmac_awacs_put_switch(struct snd_kcontrol *kcontrol,
213
struct snd_ctl_elem_value *ucontrol)
214
{
215
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
216
int reg = kcontrol->private_value & 0xff;
217
int shift = (kcontrol->private_value >> 8) & 0xff;
218
int invert = (kcontrol->private_value >> 16) & 1;
219
int mask = 1 << shift;
220
int val, changed;
221
222
guard(spinlock_irqsave)(&chip->reg_lock);
223
val = chip->awacs_reg[reg] & ~mask;
224
if (ucontrol->value.integer.value[0] != invert)
225
val |= mask;
226
changed = chip->awacs_reg[reg] != val;
227
if (changed)
228
snd_pmac_awacs_write_reg(chip, reg, val);
229
return changed;
230
}
231
232
#define AWACS_SWITCH(xname, xreg, xshift, xinvert) \
233
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
234
.info = snd_pmac_boolean_mono_info, \
235
.get = snd_pmac_awacs_get_switch, \
236
.put = snd_pmac_awacs_put_switch, \
237
.private_value = (xreg) | ((xshift) << 8) | ((xinvert) << 16) }
238
239
240
#ifdef PMAC_AMP_AVAIL
241
/*
242
* controls for perch/whisper extension cards, e.g. G3 desktop
243
*
244
* TDA7433 connected via i2c address 0x45 (= 0x8a),
245
* accessed through cuda
246
*/
247
static void awacs_set_cuda(int reg, int val)
248
{
249
struct adb_request req;
250
cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, 0x8a,
251
reg, val);
252
while (! req.complete)
253
cuda_poll();
254
}
255
256
/*
257
* level = 0 - 14, 7 = 0 dB
258
*/
259
static void awacs_amp_set_tone(struct awacs_amp *amp, int bass, int treble)
260
{
261
amp->amp_tone[0] = bass;
262
amp->amp_tone[1] = treble;
263
if (bass > 7)
264
bass = (14 - bass) + 8;
265
if (treble > 7)
266
treble = (14 - treble) + 8;
267
awacs_set_cuda(2, (bass << 4) | treble);
268
}
269
270
/*
271
* vol = 0 - 31 (attenuation), 32 = mute bit, stereo
272
*/
273
static int awacs_amp_set_vol(struct awacs_amp *amp, int index,
274
int lvol, int rvol, int do_check)
275
{
276
if (do_check && amp->amp_vol[index][0] == lvol &&
277
amp->amp_vol[index][1] == rvol)
278
return 0;
279
awacs_set_cuda(3 + index, lvol);
280
awacs_set_cuda(5 + index, rvol);
281
amp->amp_vol[index][0] = lvol;
282
amp->amp_vol[index][1] = rvol;
283
return 1;
284
}
285
286
/*
287
* 0 = -79 dB, 79 = 0 dB, 99 = +20 dB
288
*/
289
static void awacs_amp_set_master(struct awacs_amp *amp, int vol)
290
{
291
amp->amp_master = vol;
292
if (vol <= 79)
293
vol = 32 + (79 - vol);
294
else
295
vol = 32 - (vol - 79);
296
awacs_set_cuda(1, vol);
297
}
298
299
static void awacs_amp_free(struct snd_pmac *chip)
300
{
301
struct awacs_amp *amp = chip->mixer_data;
302
if (!amp)
303
return;
304
kfree(amp);
305
chip->mixer_data = NULL;
306
chip->mixer_free = NULL;
307
}
308
309
310
/*
311
* mixer controls
312
*/
313
static int snd_pmac_awacs_info_volume_amp(struct snd_kcontrol *kcontrol,
314
struct snd_ctl_elem_info *uinfo)
315
{
316
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
317
uinfo->count = 2;
318
uinfo->value.integer.min = 0;
319
uinfo->value.integer.max = 31;
320
return 0;
321
}
322
323
static int snd_pmac_awacs_get_volume_amp(struct snd_kcontrol *kcontrol,
324
struct snd_ctl_elem_value *ucontrol)
325
{
326
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
327
int index = kcontrol->private_value;
328
struct awacs_amp *amp = chip->mixer_data;
329
330
ucontrol->value.integer.value[0] = 31 - (amp->amp_vol[index][0] & 31);
331
ucontrol->value.integer.value[1] = 31 - (amp->amp_vol[index][1] & 31);
332
return 0;
333
}
334
335
static int snd_pmac_awacs_put_volume_amp(struct snd_kcontrol *kcontrol,
336
struct snd_ctl_elem_value *ucontrol)
337
{
338
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
339
int index = kcontrol->private_value;
340
int vol[2];
341
struct awacs_amp *amp = chip->mixer_data;
342
343
vol[0] = (31 - (ucontrol->value.integer.value[0] & 31))
344
| (amp->amp_vol[index][0] & 32);
345
vol[1] = (31 - (ucontrol->value.integer.value[1] & 31))
346
| (amp->amp_vol[index][1] & 32);
347
return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
348
}
349
350
static int snd_pmac_awacs_get_switch_amp(struct snd_kcontrol *kcontrol,
351
struct snd_ctl_elem_value *ucontrol)
352
{
353
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
354
int index = kcontrol->private_value;
355
struct awacs_amp *amp = chip->mixer_data;
356
357
ucontrol->value.integer.value[0] = (amp->amp_vol[index][0] & 32)
358
? 0 : 1;
359
ucontrol->value.integer.value[1] = (amp->amp_vol[index][1] & 32)
360
? 0 : 1;
361
return 0;
362
}
363
364
static int snd_pmac_awacs_put_switch_amp(struct snd_kcontrol *kcontrol,
365
struct snd_ctl_elem_value *ucontrol)
366
{
367
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
368
int index = kcontrol->private_value;
369
int vol[2];
370
struct awacs_amp *amp = chip->mixer_data;
371
372
vol[0] = (ucontrol->value.integer.value[0] ? 0 : 32)
373
| (amp->amp_vol[index][0] & 31);
374
vol[1] = (ucontrol->value.integer.value[1] ? 0 : 32)
375
| (amp->amp_vol[index][1] & 31);
376
return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
377
}
378
379
static int snd_pmac_awacs_info_tone_amp(struct snd_kcontrol *kcontrol,
380
struct snd_ctl_elem_info *uinfo)
381
{
382
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
383
uinfo->count = 1;
384
uinfo->value.integer.min = 0;
385
uinfo->value.integer.max = 14;
386
return 0;
387
}
388
389
static int snd_pmac_awacs_get_tone_amp(struct snd_kcontrol *kcontrol,
390
struct snd_ctl_elem_value *ucontrol)
391
{
392
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
393
int index = kcontrol->private_value;
394
struct awacs_amp *amp = chip->mixer_data;
395
396
ucontrol->value.integer.value[0] = amp->amp_tone[index];
397
return 0;
398
}
399
400
static int snd_pmac_awacs_put_tone_amp(struct snd_kcontrol *kcontrol,
401
struct snd_ctl_elem_value *ucontrol)
402
{
403
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
404
int index = kcontrol->private_value;
405
struct awacs_amp *amp = chip->mixer_data;
406
unsigned int val;
407
408
val = ucontrol->value.integer.value[0];
409
if (val > 14)
410
return -EINVAL;
411
if (val != amp->amp_tone[index]) {
412
amp->amp_tone[index] = val;
413
awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]);
414
return 1;
415
}
416
return 0;
417
}
418
419
static int snd_pmac_awacs_info_master_amp(struct snd_kcontrol *kcontrol,
420
struct snd_ctl_elem_info *uinfo)
421
{
422
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
423
uinfo->count = 1;
424
uinfo->value.integer.min = 0;
425
uinfo->value.integer.max = 99;
426
return 0;
427
}
428
429
static int snd_pmac_awacs_get_master_amp(struct snd_kcontrol *kcontrol,
430
struct snd_ctl_elem_value *ucontrol)
431
{
432
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
433
struct awacs_amp *amp = chip->mixer_data;
434
435
ucontrol->value.integer.value[0] = amp->amp_master;
436
return 0;
437
}
438
439
static int snd_pmac_awacs_put_master_amp(struct snd_kcontrol *kcontrol,
440
struct snd_ctl_elem_value *ucontrol)
441
{
442
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
443
struct awacs_amp *amp = chip->mixer_data;
444
unsigned int val;
445
446
val = ucontrol->value.integer.value[0];
447
if (val > 99)
448
return -EINVAL;
449
if (val != amp->amp_master) {
450
amp->amp_master = val;
451
awacs_amp_set_master(amp, amp->amp_master);
452
return 1;
453
}
454
return 0;
455
}
456
457
#define AMP_CH_SPK 0
458
#define AMP_CH_HD 1
459
460
static const struct snd_kcontrol_new snd_pmac_awacs_amp_vol[] = {
461
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
462
.name = "Speaker Playback Volume",
463
.info = snd_pmac_awacs_info_volume_amp,
464
.get = snd_pmac_awacs_get_volume_amp,
465
.put = snd_pmac_awacs_put_volume_amp,
466
.private_value = AMP_CH_SPK,
467
},
468
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
469
.name = "Headphone Playback Volume",
470
.info = snd_pmac_awacs_info_volume_amp,
471
.get = snd_pmac_awacs_get_volume_amp,
472
.put = snd_pmac_awacs_put_volume_amp,
473
.private_value = AMP_CH_HD,
474
},
475
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
476
.name = "Tone Control - Bass",
477
.info = snd_pmac_awacs_info_tone_amp,
478
.get = snd_pmac_awacs_get_tone_amp,
479
.put = snd_pmac_awacs_put_tone_amp,
480
.private_value = 0,
481
},
482
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
483
.name = "Tone Control - Treble",
484
.info = snd_pmac_awacs_info_tone_amp,
485
.get = snd_pmac_awacs_get_tone_amp,
486
.put = snd_pmac_awacs_put_tone_amp,
487
.private_value = 1,
488
},
489
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
490
.name = "Amp Master Playback Volume",
491
.info = snd_pmac_awacs_info_master_amp,
492
.get = snd_pmac_awacs_get_master_amp,
493
.put = snd_pmac_awacs_put_master_amp,
494
},
495
};
496
497
static const struct snd_kcontrol_new snd_pmac_awacs_amp_hp_sw = {
498
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
499
.name = "Headphone Playback Switch",
500
.info = snd_pmac_boolean_stereo_info,
501
.get = snd_pmac_awacs_get_switch_amp,
502
.put = snd_pmac_awacs_put_switch_amp,
503
.private_value = AMP_CH_HD,
504
};
505
506
static const struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw = {
507
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
508
.name = "Speaker Playback Switch",
509
.info = snd_pmac_boolean_stereo_info,
510
.get = snd_pmac_awacs_get_switch_amp,
511
.put = snd_pmac_awacs_put_switch_amp,
512
.private_value = AMP_CH_SPK,
513
};
514
515
#endif /* PMAC_AMP_AVAIL */
516
517
518
/*
519
* mic boost for screamer
520
*/
521
static int snd_pmac_screamer_mic_boost_info(struct snd_kcontrol *kcontrol,
522
struct snd_ctl_elem_info *uinfo)
523
{
524
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
525
uinfo->count = 1;
526
uinfo->value.integer.min = 0;
527
uinfo->value.integer.max = 3;
528
return 0;
529
}
530
531
static int snd_pmac_screamer_mic_boost_get(struct snd_kcontrol *kcontrol,
532
struct snd_ctl_elem_value *ucontrol)
533
{
534
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
535
int val = 0;
536
537
guard(spinlock_irqsave)(&chip->reg_lock);
538
if (chip->awacs_reg[6] & MASK_MIC_BOOST)
539
val |= 2;
540
if (chip->awacs_reg[0] & MASK_GAINLINE)
541
val |= 1;
542
ucontrol->value.integer.value[0] = val;
543
return 0;
544
}
545
546
static int snd_pmac_screamer_mic_boost_put(struct snd_kcontrol *kcontrol,
547
struct snd_ctl_elem_value *ucontrol)
548
{
549
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
550
int changed = 0;
551
int val0, val6;
552
553
guard(spinlock_irqsave)(&chip->reg_lock);
554
val0 = chip->awacs_reg[0] & ~MASK_GAINLINE;
555
val6 = chip->awacs_reg[6] & ~MASK_MIC_BOOST;
556
if (ucontrol->value.integer.value[0] & 1)
557
val0 |= MASK_GAINLINE;
558
if (ucontrol->value.integer.value[0] & 2)
559
val6 |= MASK_MIC_BOOST;
560
if (val0 != chip->awacs_reg[0]) {
561
snd_pmac_awacs_write_reg(chip, 0, val0);
562
changed = 1;
563
}
564
if (val6 != chip->awacs_reg[6]) {
565
snd_pmac_awacs_write_reg(chip, 6, val6);
566
changed = 1;
567
}
568
return changed;
569
}
570
571
/*
572
* lists of mixer elements
573
*/
574
static const struct snd_kcontrol_new snd_pmac_awacs_mixers[] = {
575
AWACS_SWITCH("Master Capture Switch", 1, SHIFT_LOOPTHRU, 0),
576
AWACS_VOLUME("Master Capture Volume", 0, 4, 0),
577
/* AWACS_SWITCH("Unknown Playback Switch", 6, SHIFT_PAROUT0, 0), */
578
};
579
580
static const struct snd_kcontrol_new snd_pmac_screamer_mixers_beige[] = {
581
AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
582
AWACS_VOLUME("Play-through Playback Volume", 5, 6, 1),
583
AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
584
AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_LINE, 0),
585
};
586
587
static const struct snd_kcontrol_new snd_pmac_screamer_mixers_lo[] = {
588
AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
589
};
590
591
static const struct snd_kcontrol_new snd_pmac_screamer_mixers_imac[] = {
592
AWACS_VOLUME("Play-through Playback Volume", 5, 6, 1),
593
AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
594
};
595
596
static const struct snd_kcontrol_new snd_pmac_screamer_mixers_g4agp[] = {
597
AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
598
AWACS_VOLUME("Master Playback Volume", 5, 6, 1),
599
AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
600
AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
601
};
602
603
static const struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] = {
604
AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
605
AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
606
AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
607
};
608
609
static const struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac5500[] = {
610
AWACS_VOLUME("Headphone Playback Volume", 2, 6, 1),
611
};
612
613
static const struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac[] = {
614
AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
615
AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
616
};
617
618
/* FIXME: is this correct order?
619
* screamer (powerbook G3 pismo) seems to have different bits...
620
*/
621
static const struct snd_kcontrol_new snd_pmac_awacs_mixers2[] = {
622
AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_LINE, 0),
623
AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_MIC, 0),
624
};
625
626
static const struct snd_kcontrol_new snd_pmac_screamer_mixers2[] = {
627
AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
628
AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_LINE, 0),
629
};
630
631
static const struct snd_kcontrol_new snd_pmac_awacs_mixers2_pmac5500[] = {
632
AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
633
};
634
635
static const struct snd_kcontrol_new snd_pmac_awacs_master_sw =
636
AWACS_SWITCH("Master Playback Switch", 1, SHIFT_HDMUTE, 1);
637
638
static const struct snd_kcontrol_new snd_pmac_awacs_master_sw_imac =
639
AWACS_SWITCH("Line out Playback Switch", 1, SHIFT_HDMUTE, 1);
640
641
static const struct snd_kcontrol_new snd_pmac_awacs_master_sw_pmac5500 =
642
AWACS_SWITCH("Headphone Playback Switch", 1, SHIFT_HDMUTE, 1);
643
644
static const struct snd_kcontrol_new snd_pmac_awacs_mic_boost[] = {
645
AWACS_SWITCH("Mic Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
646
};
647
648
static const struct snd_kcontrol_new snd_pmac_screamer_mic_boost[] = {
649
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
650
.name = "Mic Boost Capture Volume",
651
.info = snd_pmac_screamer_mic_boost_info,
652
.get = snd_pmac_screamer_mic_boost_get,
653
.put = snd_pmac_screamer_mic_boost_put,
654
},
655
};
656
657
static const struct snd_kcontrol_new snd_pmac_awacs_mic_boost_pmac7500[] =
658
{
659
AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
660
};
661
662
static const struct snd_kcontrol_new snd_pmac_screamer_mic_boost_beige[] =
663
{
664
AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
665
AWACS_SWITCH("CD Boost Capture Switch", 6, SHIFT_MIC_BOOST, 0),
666
};
667
668
static const struct snd_kcontrol_new snd_pmac_screamer_mic_boost_imac[] =
669
{
670
AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
671
AWACS_SWITCH("Mic Boost Capture Switch", 6, SHIFT_MIC_BOOST, 0),
672
};
673
674
static const struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] = {
675
AWACS_VOLUME("Speaker Playback Volume", 4, 6, 1),
676
};
677
678
static const struct snd_kcontrol_new snd_pmac_awacs_speaker_sw =
679
AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
680
681
static const struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 =
682
AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 1);
683
684
static const struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 =
685
AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
686
687
688
/*
689
* add new mixer elements to the card
690
*/
691
static int build_mixers(struct snd_pmac *chip, int nums,
692
const struct snd_kcontrol_new *mixers)
693
{
694
int i, err;
695
696
for (i = 0; i < nums; i++) {
697
err = snd_ctl_add(chip->card, snd_ctl_new1(&mixers[i], chip));
698
if (err < 0)
699
return err;
700
}
701
return 0;
702
}
703
704
705
/*
706
* restore all registers
707
*/
708
static void awacs_restore_all_regs(struct snd_pmac *chip)
709
{
710
snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
711
snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
712
snd_pmac_awacs_write_noreg(chip, 2, chip->awacs_reg[2]);
713
snd_pmac_awacs_write_noreg(chip, 4, chip->awacs_reg[4]);
714
if (chip->model == PMAC_SCREAMER) {
715
snd_pmac_awacs_write_noreg(chip, 5, chip->awacs_reg[5]);
716
snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
717
snd_pmac_awacs_write_noreg(chip, 7, chip->awacs_reg[7]);
718
}
719
}
720
721
#ifdef CONFIG_PM
722
static void snd_pmac_awacs_suspend(struct snd_pmac *chip)
723
{
724
snd_pmac_awacs_write_noreg(chip, 1, (chip->awacs_reg[1]
725
| MASK_AMUTE | MASK_CMUTE));
726
}
727
728
static void snd_pmac_awacs_resume(struct snd_pmac *chip)
729
{
730
if (of_machine_is_compatible("PowerBook3,1")
731
|| of_machine_is_compatible("PowerBook3,2")) {
732
msleep(100);
733
snd_pmac_awacs_write_reg(chip, 1,
734
chip->awacs_reg[1] & ~MASK_PAROUT);
735
msleep(300);
736
}
737
738
awacs_restore_all_regs(chip);
739
if (chip->model == PMAC_SCREAMER) {
740
/* reset power bits in reg 6 */
741
mdelay(5);
742
snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
743
}
744
screamer_recalibrate(chip);
745
#ifdef PMAC_AMP_AVAIL
746
if (chip->mixer_data) {
747
struct awacs_amp *amp = chip->mixer_data;
748
awacs_amp_set_vol(amp, 0,
749
amp->amp_vol[0][0], amp->amp_vol[0][1], 0);
750
awacs_amp_set_vol(amp, 1,
751
amp->amp_vol[1][0], amp->amp_vol[1][1], 0);
752
awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]);
753
awacs_amp_set_master(amp, amp->amp_master);
754
}
755
#endif
756
}
757
#endif /* CONFIG_PM */
758
759
#define IS_PM7500 (of_machine_is_compatible("AAPL,7500") \
760
|| of_machine_is_compatible("AAPL,8500") \
761
|| of_machine_is_compatible("AAPL,9500"))
762
#define IS_PM5500 (of_machine_is_compatible("AAPL,e411"))
763
#define IS_BEIGE (of_machine_is_compatible("AAPL,Gossamer"))
764
#define IS_IMAC1 (of_machine_is_compatible("PowerMac2,1"))
765
#define IS_IMAC2 (of_machine_is_compatible("PowerMac2,2") \
766
|| of_machine_is_compatible("PowerMac4,1"))
767
#define IS_G4AGP (of_machine_is_compatible("PowerMac3,1"))
768
#define IS_LOMBARD (of_machine_is_compatible("PowerBook1,1"))
769
770
static int imac1, imac2;
771
772
#ifdef PMAC_SUPPORT_AUTOMUTE
773
/*
774
* auto-mute stuffs
775
*/
776
static int snd_pmac_awacs_detect_headphone(struct snd_pmac *chip)
777
{
778
return (in_le32(&chip->awacs->codec_stat) & chip->hp_stat_mask) ? 1 : 0;
779
}
780
781
#ifdef PMAC_AMP_AVAIL
782
static int toggle_amp_mute(struct awacs_amp *amp, int index, int mute)
783
{
784
int vol[2];
785
vol[0] = amp->amp_vol[index][0] & 31;
786
vol[1] = amp->amp_vol[index][1] & 31;
787
if (mute) {
788
vol[0] |= 32;
789
vol[1] |= 32;
790
}
791
return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
792
}
793
#endif
794
795
static void snd_pmac_awacs_update_automute(struct snd_pmac *chip, int do_notify)
796
{
797
if (chip->auto_mute) {
798
#ifdef PMAC_AMP_AVAIL
799
if (chip->mixer_data) {
800
struct awacs_amp *amp = chip->mixer_data;
801
int changed;
802
if (snd_pmac_awacs_detect_headphone(chip)) {
803
changed = toggle_amp_mute(amp, AMP_CH_HD, 0);
804
changed |= toggle_amp_mute(amp, AMP_CH_SPK, 1);
805
} else {
806
changed = toggle_amp_mute(amp, AMP_CH_HD, 1);
807
changed |= toggle_amp_mute(amp, AMP_CH_SPK, 0);
808
}
809
if (do_notify && ! changed)
810
return;
811
} else
812
#endif
813
{
814
int reg = chip->awacs_reg[1]
815
| (MASK_HDMUTE | MASK_SPKMUTE);
816
if (imac1) {
817
reg &= ~MASK_SPKMUTE;
818
reg |= MASK_PAROUT1;
819
} else if (imac2) {
820
reg &= ~MASK_SPKMUTE;
821
reg &= ~MASK_PAROUT1;
822
}
823
if (snd_pmac_awacs_detect_headphone(chip))
824
reg &= ~MASK_HDMUTE;
825
else if (imac1)
826
reg &= ~MASK_PAROUT1;
827
else if (imac2)
828
reg |= MASK_PAROUT1;
829
else
830
reg &= ~MASK_SPKMUTE;
831
if (do_notify && reg == chip->awacs_reg[1])
832
return;
833
snd_pmac_awacs_write_reg(chip, 1, reg);
834
}
835
if (do_notify) {
836
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
837
&chip->master_sw_ctl->id);
838
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
839
&chip->speaker_sw_ctl->id);
840
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
841
&chip->hp_detect_ctl->id);
842
}
843
}
844
}
845
#endif /* PMAC_SUPPORT_AUTOMUTE */
846
847
848
/*
849
* initialize chip
850
*/
851
int
852
snd_pmac_awacs_init(struct snd_pmac *chip)
853
{
854
int pm7500 = IS_PM7500;
855
int pm5500 = IS_PM5500;
856
int beige = IS_BEIGE;
857
int g4agp = IS_G4AGP;
858
int lombard = IS_LOMBARD;
859
int imac;
860
int err, vol;
861
struct snd_kcontrol *vmaster_sw, *vmaster_vol;
862
struct snd_kcontrol *master_vol, *speaker_vol;
863
864
imac1 = IS_IMAC1;
865
imac2 = IS_IMAC2;
866
imac = imac1 || imac2;
867
/* looks like MASK_GAINLINE triggers something, so we set here
868
* as start-up
869
*/
870
chip->awacs_reg[0] = MASK_MUX_CD | 0xff | MASK_GAINLINE;
871
chip->awacs_reg[1] = MASK_CMUTE | MASK_AMUTE;
872
/* FIXME: Only machines with external SRS module need MASK_PAROUT */
873
if (chip->has_iic || chip->device_id == 0x5 ||
874
/* chip->_device_id == 0x8 || */
875
chip->device_id == 0xb)
876
chip->awacs_reg[1] |= MASK_PAROUT;
877
/* get default volume from nvram */
878
// vol = (~nvram_read_byte(0x1308) & 7) << 1;
879
// vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 );
880
vol = 0x0f; /* no, on alsa, muted as default */
881
vol = vol + (vol << 6);
882
chip->awacs_reg[2] = vol;
883
chip->awacs_reg[4] = vol;
884
if (chip->model == PMAC_SCREAMER) {
885
/* FIXME: screamer has loopthru vol control */
886
chip->awacs_reg[5] = vol;
887
/* FIXME: maybe should be vol << 3 for PCMCIA speaker */
888
chip->awacs_reg[6] = MASK_MIC_BOOST;
889
chip->awacs_reg[7] = 0;
890
}
891
892
awacs_restore_all_regs(chip);
893
chip->manufacturer = (in_le32(&chip->awacs->codec_stat) >> 8) & 0xf;
894
screamer_recalibrate(chip);
895
896
chip->revision = (in_le32(&chip->awacs->codec_stat) >> 12) & 0xf;
897
#ifdef PMAC_AMP_AVAIL
898
if (chip->revision == 3 && chip->has_iic && CHECK_CUDA_AMP()) {
899
struct awacs_amp *amp = kzalloc(sizeof(*amp), GFP_KERNEL);
900
if (! amp)
901
return -ENOMEM;
902
chip->mixer_data = amp;
903
chip->mixer_free = awacs_amp_free;
904
/* mute and zero vol */
905
awacs_amp_set_vol(amp, 0, 63, 63, 0);
906
awacs_amp_set_vol(amp, 1, 63, 63, 0);
907
awacs_amp_set_tone(amp, 7, 7); /* 0 dB */
908
awacs_amp_set_master(amp, 79); /* 0 dB */
909
}
910
#endif /* PMAC_AMP_AVAIL */
911
912
if (chip->hp_stat_mask == 0) {
913
/* set headphone-jack detection bit */
914
switch (chip->model) {
915
case PMAC_AWACS:
916
chip->hp_stat_mask = pm7500 || pm5500 ? MASK_HDPCONN
917
: MASK_LOCONN;
918
break;
919
case PMAC_SCREAMER:
920
switch (chip->device_id) {
921
case 0x08:
922
case 0x0B:
923
chip->hp_stat_mask = imac
924
? MASK_LOCONN_IMAC |
925
MASK_HDPLCONN_IMAC |
926
MASK_HDPRCONN_IMAC
927
: MASK_HDPCONN;
928
break;
929
case 0x00:
930
case 0x05:
931
chip->hp_stat_mask = MASK_LOCONN;
932
break;
933
default:
934
chip->hp_stat_mask = MASK_HDPCONN;
935
break;
936
}
937
break;
938
default:
939
snd_BUG();
940
break;
941
}
942
}
943
944
/*
945
* build mixers
946
*/
947
strscpy(chip->card->mixername, "PowerMac AWACS");
948
949
err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers),
950
snd_pmac_awacs_mixers);
951
if (err < 0)
952
return err;
953
if (beige || g4agp)
954
;
955
else if (chip->model == PMAC_SCREAMER || pm5500)
956
err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2),
957
snd_pmac_screamer_mixers2);
958
else if (!pm7500)
959
err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers2),
960
snd_pmac_awacs_mixers2);
961
if (err < 0)
962
return err;
963
if (pm5500) {
964
err = build_mixers(chip,
965
ARRAY_SIZE(snd_pmac_awacs_mixers2_pmac5500),
966
snd_pmac_awacs_mixers2_pmac5500);
967
if (err < 0)
968
return err;
969
}
970
master_vol = NULL;
971
if (pm7500)
972
err = build_mixers(chip,
973
ARRAY_SIZE(snd_pmac_awacs_mixers_pmac7500),
974
snd_pmac_awacs_mixers_pmac7500);
975
else if (pm5500)
976
err = snd_ctl_add(chip->card,
977
(master_vol = snd_ctl_new1(snd_pmac_awacs_mixers_pmac5500,
978
chip)));
979
else if (beige)
980
err = build_mixers(chip,
981
ARRAY_SIZE(snd_pmac_screamer_mixers_beige),
982
snd_pmac_screamer_mixers_beige);
983
else if (imac || lombard) {
984
err = snd_ctl_add(chip->card,
985
(master_vol = snd_ctl_new1(snd_pmac_screamer_mixers_lo,
986
chip)));
987
if (err < 0)
988
return err;
989
err = build_mixers(chip,
990
ARRAY_SIZE(snd_pmac_screamer_mixers_imac),
991
snd_pmac_screamer_mixers_imac);
992
} else if (g4agp)
993
err = build_mixers(chip,
994
ARRAY_SIZE(snd_pmac_screamer_mixers_g4agp),
995
snd_pmac_screamer_mixers_g4agp);
996
else
997
err = build_mixers(chip,
998
ARRAY_SIZE(snd_pmac_awacs_mixers_pmac),
999
snd_pmac_awacs_mixers_pmac);
1000
if (err < 0)
1001
return err;
1002
chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac || g4agp || lombard)
1003
? &snd_pmac_awacs_master_sw_imac
1004
: pm5500
1005
? &snd_pmac_awacs_master_sw_pmac5500
1006
: &snd_pmac_awacs_master_sw, chip);
1007
err = snd_ctl_add(chip->card, chip->master_sw_ctl);
1008
if (err < 0)
1009
return err;
1010
#ifdef PMAC_AMP_AVAIL
1011
if (chip->mixer_data) {
1012
/* use amplifier. the signal is connected from route A
1013
* to the amp. the amp has its headphone and speaker
1014
* volumes and mute switches, so we use them instead of
1015
* screamer registers.
1016
* in this case, it seems the route C is not used.
1017
*/
1018
err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_amp_vol),
1019
snd_pmac_awacs_amp_vol);
1020
if (err < 0)
1021
return err;
1022
/* overwrite */
1023
chip->master_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_amp_hp_sw,
1024
chip);
1025
err = snd_ctl_add(chip->card, chip->master_sw_ctl);
1026
if (err < 0)
1027
return err;
1028
chip->speaker_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_amp_spk_sw,
1029
chip);
1030
err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
1031
if (err < 0)
1032
return err;
1033
} else
1034
#endif /* PMAC_AMP_AVAIL */
1035
{
1036
/* route A = headphone, route C = speaker */
1037
err = snd_ctl_add(chip->card,
1038
(speaker_vol = snd_ctl_new1(snd_pmac_awacs_speaker_vol,
1039
chip)));
1040
if (err < 0)
1041
return err;
1042
chip->speaker_sw_ctl = snd_ctl_new1(imac1
1043
? &snd_pmac_awacs_speaker_sw_imac1
1044
: imac2
1045
? &snd_pmac_awacs_speaker_sw_imac2
1046
: &snd_pmac_awacs_speaker_sw, chip);
1047
err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
1048
if (err < 0)
1049
return err;
1050
}
1051
1052
if (pm5500 || imac || lombard) {
1053
vmaster_sw = snd_ctl_make_virtual_master(
1054
"Master Playback Switch", (unsigned int *) NULL);
1055
err = snd_ctl_add_follower_uncached(vmaster_sw,
1056
chip->master_sw_ctl);
1057
if (err < 0)
1058
return err;
1059
err = snd_ctl_add_follower_uncached(vmaster_sw,
1060
chip->speaker_sw_ctl);
1061
if (err < 0)
1062
return err;
1063
err = snd_ctl_add(chip->card, vmaster_sw);
1064
if (err < 0)
1065
return err;
1066
vmaster_vol = snd_ctl_make_virtual_master(
1067
"Master Playback Volume", (unsigned int *) NULL);
1068
err = snd_ctl_add_follower(vmaster_vol, master_vol);
1069
if (err < 0)
1070
return err;
1071
err = snd_ctl_add_follower(vmaster_vol, speaker_vol);
1072
if (err < 0)
1073
return err;
1074
err = snd_ctl_add(chip->card, vmaster_vol);
1075
if (err < 0)
1076
return err;
1077
}
1078
1079
if (beige || g4agp)
1080
err = build_mixers(chip,
1081
ARRAY_SIZE(snd_pmac_screamer_mic_boost_beige),
1082
snd_pmac_screamer_mic_boost_beige);
1083
else if (imac)
1084
err = build_mixers(chip,
1085
ARRAY_SIZE(snd_pmac_screamer_mic_boost_imac),
1086
snd_pmac_screamer_mic_boost_imac);
1087
else if (chip->model == PMAC_SCREAMER)
1088
err = build_mixers(chip,
1089
ARRAY_SIZE(snd_pmac_screamer_mic_boost),
1090
snd_pmac_screamer_mic_boost);
1091
else if (pm7500)
1092
err = build_mixers(chip,
1093
ARRAY_SIZE(snd_pmac_awacs_mic_boost_pmac7500),
1094
snd_pmac_awacs_mic_boost_pmac7500);
1095
else
1096
err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mic_boost),
1097
snd_pmac_awacs_mic_boost);
1098
if (err < 0)
1099
return err;
1100
1101
/*
1102
* set lowlevel callbacks
1103
*/
1104
chip->set_format = snd_pmac_awacs_set_format;
1105
#ifdef CONFIG_PM
1106
chip->suspend = snd_pmac_awacs_suspend;
1107
chip->resume = snd_pmac_awacs_resume;
1108
#endif
1109
#ifdef PMAC_SUPPORT_AUTOMUTE
1110
err = snd_pmac_add_automute(chip);
1111
if (err < 0)
1112
return err;
1113
chip->detect_headphone = snd_pmac_awacs_detect_headphone;
1114
chip->update_automute = snd_pmac_awacs_update_automute;
1115
snd_pmac_awacs_update_automute(chip, 0); /* update the status only */
1116
#endif
1117
if (chip->model == PMAC_SCREAMER) {
1118
snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
1119
snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
1120
}
1121
1122
return 0;
1123
}
1124
1125