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