blob: 72a2219f56b509637f7f5cae016818e6dc7066d4 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * PMac Tumbler/Snapper lowlevel functions
3 *
4 * Copyright (c) by Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * Rene Rebe <rene.rebe@gmx.net>:
21 * * update from shadow registers on wakeup and headphone plug
22 * * automatically toggle DRC on headphone plug
23 *
24 */
25
26
27#include <sound/driver.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/i2c.h>
31#include <linux/i2c-dev.h>
32#include <linux/kmod.h>
33#include <linux/slab.h>
34#include <linux/interrupt.h>
35#include <sound/core.h>
36#include <asm/io.h>
37#include <asm/irq.h>
38#ifdef CONFIG_PPC_HAS_FEATURE_CALLS
39#include <asm/pmac_feature.h>
Benjamin Herrenschmidtb75550e2005-04-16 15:24:31 -070040#else
41#error old crap
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#endif
43#include "pmac.h"
44#include "tumbler_volume.h"
45
46/* i2c address for tumbler */
47#define TAS_I2C_ADDR 0x34
48
49/* registers */
50#define TAS_REG_MCS 0x01 /* main control */
51#define TAS_REG_DRC 0x02
52#define TAS_REG_VOL 0x04
53#define TAS_REG_TREBLE 0x05
54#define TAS_REG_BASS 0x06
55#define TAS_REG_INPUT1 0x07
56#define TAS_REG_INPUT2 0x08
57
58/* tas3001c */
59#define TAS_REG_PCM TAS_REG_INPUT1
60
61/* tas3004 */
62#define TAS_REG_LMIX TAS_REG_INPUT1
63#define TAS_REG_RMIX TAS_REG_INPUT2
64#define TAS_REG_MCS2 0x43 /* main control 2 */
65#define TAS_REG_ACS 0x40 /* analog control */
66
67/* mono volumes for tas3001c/tas3004 */
68enum {
69 VOL_IDX_PCM_MONO, /* tas3001c only */
70 VOL_IDX_BASS, VOL_IDX_TREBLE,
71 VOL_IDX_LAST_MONO
72};
73
74/* stereo volumes for tas3004 */
75enum {
76 VOL_IDX_PCM, VOL_IDX_PCM2, VOL_IDX_ADC,
77 VOL_IDX_LAST_MIX
78};
79
80typedef struct pmac_gpio {
81#ifdef CONFIG_PPC_HAS_FEATURE_CALLS
82 unsigned int addr;
83#else
84 void __iomem *addr;
85#endif
86 int active_state;
87} pmac_gpio_t;
88
89typedef struct pmac_tumbler_t {
90 pmac_keywest_t i2c;
91 pmac_gpio_t audio_reset;
92 pmac_gpio_t amp_mute;
93 pmac_gpio_t hp_mute;
94 pmac_gpio_t hp_detect;
95 int headphone_irq;
96 unsigned int master_vol[2];
97 unsigned int master_switch[2];
98 unsigned int mono_vol[VOL_IDX_LAST_MONO];
99 unsigned int mix_vol[VOL_IDX_LAST_MIX][2]; /* stereo volumes for tas3004 */
100 int drc_range;
101 int drc_enable;
102 int capture_source;
103} pmac_tumbler_t;
104
105
106/*
107 */
108
109static int send_init_client(pmac_keywest_t *i2c, unsigned int *regs)
110{
111 while (*regs > 0) {
112 int err, count = 10;
113 do {
114 err = i2c_smbus_write_byte_data(i2c->client,
115 regs[0], regs[1]);
116 if (err >= 0)
117 break;
118 mdelay(10);
119 } while (count--);
120 if (err < 0)
121 return -ENXIO;
122 regs += 2;
123 }
124 return 0;
125}
126
127
128static int tumbler_init_client(pmac_keywest_t *i2c)
129{
130 static unsigned int regs[] = {
131 /* normal operation, SCLK=64fps, i2s output, i2s input, 16bit width */
132 TAS_REG_MCS, (1<<6)|(2<<4)|(2<<2)|0,
133 0, /* terminator */
134 };
135 return send_init_client(i2c, regs);
136}
137
138static int snapper_init_client(pmac_keywest_t *i2c)
139{
140 static unsigned int regs[] = {
141 /* normal operation, SCLK=64fps, i2s output, 16bit width */
142 TAS_REG_MCS, (1<<6)|(2<<4)|0,
143 /* normal operation, all-pass mode */
144 TAS_REG_MCS2, (1<<1),
145 /* normal output, no deemphasis, A input, power-up, line-in */
146 TAS_REG_ACS, 0,
147 0, /* terminator */
148 };
149 return send_init_client(i2c, regs);
150}
151
152/*
153 * gpio access
154 */
155#ifdef CONFIG_PPC_HAS_FEATURE_CALLS
156#define do_gpio_write(gp, val) \
157 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, (gp)->addr, val)
158#define do_gpio_read(gp) \
159 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, (gp)->addr, 0)
160#define tumbler_gpio_free(gp) /* NOP */
161#else
162#define do_gpio_write(gp, val) writeb(val, (gp)->addr)
163#define do_gpio_read(gp) readb((gp)->addr)
164static inline void tumbler_gpio_free(pmac_gpio_t *gp)
165{
166 if (gp->addr) {
167 iounmap(gp->addr);
168 gp->addr = NULL;
169 }
170}
171#endif /* CONFIG_PPC_HAS_FEATURE_CALLS */
172
173static void write_audio_gpio(pmac_gpio_t *gp, int active)
174{
175 if (! gp->addr)
176 return;
177 active = active ? gp->active_state : !gp->active_state;
178 do_gpio_write(gp, active ? 0x05 : 0x04);
179}
180
181static int read_audio_gpio(pmac_gpio_t *gp)
182{
183 int ret;
184 if (! gp->addr)
185 return 0;
186 ret = ((do_gpio_read(gp) & 0x02) !=0);
187 return ret == gp->active_state;
188}
189
190/*
191 * update master volume
192 */
193static int tumbler_set_master_volume(pmac_tumbler_t *mix)
194{
195 unsigned char block[6];
196 unsigned int left_vol, right_vol;
197
198 if (! mix->i2c.client)
199 return -ENODEV;
200
201 if (! mix->master_switch[0])
202 left_vol = 0;
203 else {
204 left_vol = mix->master_vol[0];
205 if (left_vol >= ARRAY_SIZE(master_volume_table))
206 left_vol = ARRAY_SIZE(master_volume_table) - 1;
207 left_vol = master_volume_table[left_vol];
208 }
209 if (! mix->master_switch[1])
210 right_vol = 0;
211 else {
212 right_vol = mix->master_vol[1];
213 if (right_vol >= ARRAY_SIZE(master_volume_table))
214 right_vol = ARRAY_SIZE(master_volume_table) - 1;
215 right_vol = master_volume_table[right_vol];
216 }
217
218 block[0] = (left_vol >> 16) & 0xff;
219 block[1] = (left_vol >> 8) & 0xff;
220 block[2] = (left_vol >> 0) & 0xff;
221
222 block[3] = (right_vol >> 16) & 0xff;
223 block[4] = (right_vol >> 8) & 0xff;
224 block[5] = (right_vol >> 0) & 0xff;
225
226 if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_VOL,
227 6, block) < 0) {
228 snd_printk("failed to set volume \n");
229 return -EINVAL;
230 }
231 return 0;
232}
233
234
235/* output volume */
236static int tumbler_info_master_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
237{
238 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
239 uinfo->count = 2;
240 uinfo->value.integer.min = 0;
241 uinfo->value.integer.max = ARRAY_SIZE(master_volume_table) - 1;
242 return 0;
243}
244
245static int tumbler_get_master_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
246{
247 pmac_t *chip = snd_kcontrol_chip(kcontrol);
248 pmac_tumbler_t *mix = chip->mixer_data;
249 snd_assert(mix, return -ENODEV);
250 ucontrol->value.integer.value[0] = mix->master_vol[0];
251 ucontrol->value.integer.value[1] = mix->master_vol[1];
252 return 0;
253}
254
255static int tumbler_put_master_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
256{
257 pmac_t *chip = snd_kcontrol_chip(kcontrol);
258 pmac_tumbler_t *mix = chip->mixer_data;
259 int change;
260
261 snd_assert(mix, return -ENODEV);
262 change = mix->master_vol[0] != ucontrol->value.integer.value[0] ||
263 mix->master_vol[1] != ucontrol->value.integer.value[1];
264 if (change) {
265 mix->master_vol[0] = ucontrol->value.integer.value[0];
266 mix->master_vol[1] = ucontrol->value.integer.value[1];
267 tumbler_set_master_volume(mix);
268 }
269 return change;
270}
271
272/* output switch */
273static int tumbler_get_master_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
274{
275 pmac_t *chip = snd_kcontrol_chip(kcontrol);
276 pmac_tumbler_t *mix = chip->mixer_data;
277 snd_assert(mix, return -ENODEV);
278 ucontrol->value.integer.value[0] = mix->master_switch[0];
279 ucontrol->value.integer.value[1] = mix->master_switch[1];
280 return 0;
281}
282
283static int tumbler_put_master_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
284{
285 pmac_t *chip = snd_kcontrol_chip(kcontrol);
286 pmac_tumbler_t *mix = chip->mixer_data;
287 int change;
288
289 snd_assert(mix, return -ENODEV);
290 change = mix->master_switch[0] != ucontrol->value.integer.value[0] ||
291 mix->master_switch[1] != ucontrol->value.integer.value[1];
292 if (change) {
293 mix->master_switch[0] = !!ucontrol->value.integer.value[0];
294 mix->master_switch[1] = !!ucontrol->value.integer.value[1];
295 tumbler_set_master_volume(mix);
296 }
297 return change;
298}
299
300
301/*
302 * TAS3001c dynamic range compression
303 */
304
305#define TAS3001_DRC_MAX 0x5f
306
307static int tumbler_set_drc(pmac_tumbler_t *mix)
308{
309 unsigned char val[2];
310
311 if (! mix->i2c.client)
312 return -ENODEV;
313
314 if (mix->drc_enable) {
315 val[0] = 0xc1; /* enable, 3:1 compression */
316 if (mix->drc_range > TAS3001_DRC_MAX)
317 val[1] = 0xf0;
318 else if (mix->drc_range < 0)
319 val[1] = 0x91;
320 else
321 val[1] = mix->drc_range + 0x91;
322 } else {
323 val[0] = 0;
324 val[1] = 0;
325 }
326
327 if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
328 2, val) < 0) {
329 snd_printk("failed to set DRC\n");
330 return -EINVAL;
331 }
332 return 0;
333}
334
335/*
336 * TAS3004
337 */
338
339#define TAS3004_DRC_MAX 0xef
340
341static int snapper_set_drc(pmac_tumbler_t *mix)
342{
343 unsigned char val[6];
344
345 if (! mix->i2c.client)
346 return -ENODEV;
347
348 if (mix->drc_enable)
349 val[0] = 0x50; /* 3:1 above threshold */
350 else
351 val[0] = 0x51; /* disabled */
352 val[1] = 0x02; /* 1:1 below threshold */
353 if (mix->drc_range > 0xef)
354 val[2] = 0xef;
355 else if (mix->drc_range < 0)
356 val[2] = 0x00;
357 else
358 val[2] = mix->drc_range;
359 val[3] = 0xb0;
360 val[4] = 0x60;
361 val[5] = 0xa0;
362
363 if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
364 6, val) < 0) {
365 snd_printk("failed to set DRC\n");
366 return -EINVAL;
367 }
368 return 0;
369}
370
371static int tumbler_info_drc_value(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
372{
373 pmac_t *chip = snd_kcontrol_chip(kcontrol);
374 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
375 uinfo->count = 1;
376 uinfo->value.integer.min = 0;
377 uinfo->value.integer.max =
378 chip->model == PMAC_TUMBLER ? TAS3001_DRC_MAX : TAS3004_DRC_MAX;
379 return 0;
380}
381
382static int tumbler_get_drc_value(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
383{
384 pmac_t *chip = snd_kcontrol_chip(kcontrol);
385 pmac_tumbler_t *mix;
386 if (! (mix = chip->mixer_data))
387 return -ENODEV;
388 ucontrol->value.integer.value[0] = mix->drc_range;
389 return 0;
390}
391
392static int tumbler_put_drc_value(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
393{
394 pmac_t *chip = snd_kcontrol_chip(kcontrol);
395 pmac_tumbler_t *mix;
396 int change;
397
398 if (! (mix = chip->mixer_data))
399 return -ENODEV;
400 change = mix->drc_range != ucontrol->value.integer.value[0];
401 if (change) {
402 mix->drc_range = ucontrol->value.integer.value[0];
403 if (chip->model == PMAC_TUMBLER)
404 tumbler_set_drc(mix);
405 else
406 snapper_set_drc(mix);
407 }
408 return change;
409}
410
411static int tumbler_get_drc_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
412{
413 pmac_t *chip = snd_kcontrol_chip(kcontrol);
414 pmac_tumbler_t *mix;
415 if (! (mix = chip->mixer_data))
416 return -ENODEV;
417 ucontrol->value.integer.value[0] = mix->drc_enable;
418 return 0;
419}
420
421static int tumbler_put_drc_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
422{
423 pmac_t *chip = snd_kcontrol_chip(kcontrol);
424 pmac_tumbler_t *mix;
425 int change;
426
427 if (! (mix = chip->mixer_data))
428 return -ENODEV;
429 change = mix->drc_enable != ucontrol->value.integer.value[0];
430 if (change) {
431 mix->drc_enable = !!ucontrol->value.integer.value[0];
432 if (chip->model == PMAC_TUMBLER)
433 tumbler_set_drc(mix);
434 else
435 snapper_set_drc(mix);
436 }
437 return change;
438}
439
440
441/*
442 * mono volumes
443 */
444
445struct tumbler_mono_vol {
446 int index;
447 int reg;
448 int bytes;
449 unsigned int max;
450 unsigned int *table;
451};
452
453static int tumbler_set_mono_volume(pmac_tumbler_t *mix, struct tumbler_mono_vol *info)
454{
455 unsigned char block[4];
456 unsigned int vol;
457 int i;
458
459 if (! mix->i2c.client)
460 return -ENODEV;
461
462 vol = mix->mono_vol[info->index];
463 if (vol >= info->max)
464 vol = info->max - 1;
465 vol = info->table[vol];
466 for (i = 0; i < info->bytes; i++)
467 block[i] = (vol >> ((info->bytes - i - 1) * 8)) & 0xff;
468 if (i2c_smbus_write_block_data(mix->i2c.client, info->reg,
469 info->bytes, block) < 0) {
470 snd_printk("failed to set mono volume %d\n", info->index);
471 return -EINVAL;
472 }
473 return 0;
474}
475
476static int tumbler_info_mono(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
477{
478 struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;
479
480 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
481 uinfo->count = 1;
482 uinfo->value.integer.min = 0;
483 uinfo->value.integer.max = info->max - 1;
484 return 0;
485}
486
487static int tumbler_get_mono(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
488{
489 struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;
490 pmac_t *chip = snd_kcontrol_chip(kcontrol);
491 pmac_tumbler_t *mix;
492 if (! (mix = chip->mixer_data))
493 return -ENODEV;
494 ucontrol->value.integer.value[0] = mix->mono_vol[info->index];
495 return 0;
496}
497
498static int tumbler_put_mono(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
499{
500 struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;
501 pmac_t *chip = snd_kcontrol_chip(kcontrol);
502 pmac_tumbler_t *mix;
503 int change;
504
505 if (! (mix = chip->mixer_data))
506 return -ENODEV;
507 change = mix->mono_vol[info->index] != ucontrol->value.integer.value[0];
508 if (change) {
509 mix->mono_vol[info->index] = ucontrol->value.integer.value[0];
510 tumbler_set_mono_volume(mix, info);
511 }
512 return change;
513}
514
515/* TAS3001c mono volumes */
516static struct tumbler_mono_vol tumbler_pcm_vol_info = {
517 .index = VOL_IDX_PCM_MONO,
518 .reg = TAS_REG_PCM,
519 .bytes = 3,
520 .max = ARRAY_SIZE(mixer_volume_table),
521 .table = mixer_volume_table,
522};
523
524static struct tumbler_mono_vol tumbler_bass_vol_info = {
525 .index = VOL_IDX_BASS,
526 .reg = TAS_REG_BASS,
527 .bytes = 1,
528 .max = ARRAY_SIZE(bass_volume_table),
529 .table = bass_volume_table,
530};
531
532static struct tumbler_mono_vol tumbler_treble_vol_info = {
533 .index = VOL_IDX_TREBLE,
534 .reg = TAS_REG_TREBLE,
535 .bytes = 1,
536 .max = ARRAY_SIZE(treble_volume_table),
537 .table = treble_volume_table,
538};
539
540/* TAS3004 mono volumes */
541static struct tumbler_mono_vol snapper_bass_vol_info = {
542 .index = VOL_IDX_BASS,
543 .reg = TAS_REG_BASS,
544 .bytes = 1,
545 .max = ARRAY_SIZE(snapper_bass_volume_table),
546 .table = snapper_bass_volume_table,
547};
548
549static struct tumbler_mono_vol snapper_treble_vol_info = {
550 .index = VOL_IDX_TREBLE,
551 .reg = TAS_REG_TREBLE,
552 .bytes = 1,
553 .max = ARRAY_SIZE(snapper_treble_volume_table),
554 .table = snapper_treble_volume_table,
555};
556
557
558#define DEFINE_MONO(xname,type) { \
559 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
560 .name = xname, \
561 .info = tumbler_info_mono, \
562 .get = tumbler_get_mono, \
563 .put = tumbler_put_mono, \
564 .private_value = (unsigned long)(&tumbler_##type##_vol_info), \
565}
566
567#define DEFINE_SNAPPER_MONO(xname,type) { \
568 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
569 .name = xname, \
570 .info = tumbler_info_mono, \
571 .get = tumbler_get_mono, \
572 .put = tumbler_put_mono, \
573 .private_value = (unsigned long)(&snapper_##type##_vol_info), \
574}
575
576
577/*
578 * snapper mixer volumes
579 */
580
581static int snapper_set_mix_vol1(pmac_tumbler_t *mix, int idx, int ch, int reg)
582{
583 int i, j, vol;
584 unsigned char block[9];
585
586 vol = mix->mix_vol[idx][ch];
587 if (vol >= ARRAY_SIZE(mixer_volume_table)) {
588 vol = ARRAY_SIZE(mixer_volume_table) - 1;
589 mix->mix_vol[idx][ch] = vol;
590 }
591
592 for (i = 0; i < 3; i++) {
593 vol = mix->mix_vol[i][ch];
594 vol = mixer_volume_table[vol];
595 for (j = 0; j < 3; j++)
596 block[i * 3 + j] = (vol >> ((2 - j) * 8)) & 0xff;
597 }
598 if (i2c_smbus_write_block_data(mix->i2c.client, reg, 9, block) < 0) {
599 snd_printk("failed to set mono volume %d\n", reg);
600 return -EINVAL;
601 }
602 return 0;
603}
604
605static int snapper_set_mix_vol(pmac_tumbler_t *mix, int idx)
606{
607 if (! mix->i2c.client)
608 return -ENODEV;
609 if (snapper_set_mix_vol1(mix, idx, 0, TAS_REG_LMIX) < 0 ||
610 snapper_set_mix_vol1(mix, idx, 1, TAS_REG_RMIX) < 0)
611 return -EINVAL;
612 return 0;
613}
614
615static int snapper_info_mix(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
616{
617 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
618 uinfo->count = 2;
619 uinfo->value.integer.min = 0;
620 uinfo->value.integer.max = ARRAY_SIZE(mixer_volume_table) - 1;
621 return 0;
622}
623
624static int snapper_get_mix(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
625{
626 int idx = (int)kcontrol->private_value;
627 pmac_t *chip = snd_kcontrol_chip(kcontrol);
628 pmac_tumbler_t *mix;
629 if (! (mix = chip->mixer_data))
630 return -ENODEV;
631 ucontrol->value.integer.value[0] = mix->mix_vol[idx][0];
632 ucontrol->value.integer.value[1] = mix->mix_vol[idx][1];
633 return 0;
634}
635
636static int snapper_put_mix(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
637{
638 int idx = (int)kcontrol->private_value;
639 pmac_t *chip = snd_kcontrol_chip(kcontrol);
640 pmac_tumbler_t *mix;
641 int change;
642
643 if (! (mix = chip->mixer_data))
644 return -ENODEV;
645 change = mix->mix_vol[idx][0] != ucontrol->value.integer.value[0] ||
646 mix->mix_vol[idx][1] != ucontrol->value.integer.value[1];
647 if (change) {
648 mix->mix_vol[idx][0] = ucontrol->value.integer.value[0];
649 mix->mix_vol[idx][1] = ucontrol->value.integer.value[1];
650 snapper_set_mix_vol(mix, idx);
651 }
652 return change;
653}
654
655
656/*
657 * mute switches
658 */
659
660enum { TUMBLER_MUTE_HP, TUMBLER_MUTE_AMP };
661
662static int tumbler_get_mute_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
663{
664 pmac_t *chip = snd_kcontrol_chip(kcontrol);
665 pmac_tumbler_t *mix;
666 pmac_gpio_t *gp;
667 if (! (mix = chip->mixer_data))
668 return -ENODEV;
669 gp = (kcontrol->private_value == TUMBLER_MUTE_HP) ? &mix->hp_mute : &mix->amp_mute;
670 ucontrol->value.integer.value[0] = ! read_audio_gpio(gp);
671 return 0;
672}
673
674static int tumbler_put_mute_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
675{
676 pmac_t *chip = snd_kcontrol_chip(kcontrol);
677 pmac_tumbler_t *mix;
678 pmac_gpio_t *gp;
679 int val;
680#ifdef PMAC_SUPPORT_AUTOMUTE
681 if (chip->update_automute && chip->auto_mute)
682 return 0; /* don't touch in the auto-mute mode */
683#endif
684 if (! (mix = chip->mixer_data))
685 return -ENODEV;
686 gp = (kcontrol->private_value == TUMBLER_MUTE_HP) ? &mix->hp_mute : &mix->amp_mute;
687 val = ! read_audio_gpio(gp);
688 if (val != ucontrol->value.integer.value[0]) {
689 write_audio_gpio(gp, ! ucontrol->value.integer.value[0]);
690 return 1;
691 }
692 return 0;
693}
694
695static int snapper_set_capture_source(pmac_tumbler_t *mix)
696{
697 if (! mix->i2c.client)
698 return -ENODEV;
699 return i2c_smbus_write_byte_data(mix->i2c.client, TAS_REG_ACS,
700 mix->capture_source ? 2 : 0);
701}
702
703static int snapper_info_capture_source(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
704{
705 static char *texts[2] = {
706 "Line", "Mic"
707 };
708 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
709 uinfo->count = 1;
710 uinfo->value.enumerated.items = 2;
711 if (uinfo->value.enumerated.item > 1)
712 uinfo->value.enumerated.item = 1;
713 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
714 return 0;
715}
716
717static int snapper_get_capture_source(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
718{
719 pmac_t *chip = snd_kcontrol_chip(kcontrol);
720 pmac_tumbler_t *mix = chip->mixer_data;
721
722 snd_assert(mix, return -ENODEV);
723 ucontrol->value.integer.value[0] = mix->capture_source;
724 return 0;
725}
726
727static int snapper_put_capture_source(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
728{
729 pmac_t *chip = snd_kcontrol_chip(kcontrol);
730 pmac_tumbler_t *mix = chip->mixer_data;
731 int change;
732
733 snd_assert(mix, return -ENODEV);
734 change = ucontrol->value.integer.value[0] != mix->capture_source;
735 if (change) {
736 mix->capture_source = !!ucontrol->value.integer.value[0];
737 snapper_set_capture_source(mix);
738 }
739 return change;
740}
741
742#define DEFINE_SNAPPER_MIX(xname,idx,ofs) { \
743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
744 .name = xname, \
745 .info = snapper_info_mix, \
746 .get = snapper_get_mix, \
747 .put = snapper_put_mix, \
748 .index = idx,\
749 .private_value = ofs, \
750}
751
752
753/*
754 */
755static snd_kcontrol_new_t tumbler_mixers[] __initdata = {
756 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
757 .name = "Master Playback Volume",
758 .info = tumbler_info_master_volume,
759 .get = tumbler_get_master_volume,
760 .put = tumbler_put_master_volume
761 },
762 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
763 .name = "Master Playback Switch",
764 .info = snd_pmac_boolean_stereo_info,
765 .get = tumbler_get_master_switch,
766 .put = tumbler_put_master_switch
767 },
768 DEFINE_MONO("Tone Control - Bass", bass),
769 DEFINE_MONO("Tone Control - Treble", treble),
770 DEFINE_MONO("PCM Playback Volume", pcm),
771 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
772 .name = "DRC Range",
773 .info = tumbler_info_drc_value,
774 .get = tumbler_get_drc_value,
775 .put = tumbler_put_drc_value
776 },
777};
778
779static snd_kcontrol_new_t snapper_mixers[] __initdata = {
780 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
781 .name = "Master Playback Volume",
782 .info = tumbler_info_master_volume,
783 .get = tumbler_get_master_volume,
784 .put = tumbler_put_master_volume
785 },
786 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
787 .name = "Master Playback Switch",
788 .info = snd_pmac_boolean_stereo_info,
789 .get = tumbler_get_master_switch,
790 .put = tumbler_put_master_switch
791 },
792 DEFINE_SNAPPER_MIX("PCM Playback Volume", 0, VOL_IDX_PCM),
793 DEFINE_SNAPPER_MIX("PCM Playback Volume", 1, VOL_IDX_PCM2),
794 DEFINE_SNAPPER_MIX("Monitor Mix Volume", 0, VOL_IDX_ADC),
795 DEFINE_SNAPPER_MONO("Tone Control - Bass", bass),
796 DEFINE_SNAPPER_MONO("Tone Control - Treble", treble),
797 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
798 .name = "DRC Range",
799 .info = tumbler_info_drc_value,
800 .get = tumbler_get_drc_value,
801 .put = tumbler_put_drc_value
802 },
803 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
804 .name = "Input Source", /* FIXME: "Capture Source" doesn't work properly */
805 .info = snapper_info_capture_source,
806 .get = snapper_get_capture_source,
807 .put = snapper_put_capture_source
808 },
809};
810
811static snd_kcontrol_new_t tumbler_hp_sw __initdata = {
812 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
813 .name = "Headphone Playback Switch",
814 .info = snd_pmac_boolean_mono_info,
815 .get = tumbler_get_mute_switch,
816 .put = tumbler_put_mute_switch,
817 .private_value = TUMBLER_MUTE_HP,
818};
819static snd_kcontrol_new_t tumbler_speaker_sw __initdata = {
820 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
821 .name = "PC Speaker Playback Switch",
822 .info = snd_pmac_boolean_mono_info,
823 .get = tumbler_get_mute_switch,
824 .put = tumbler_put_mute_switch,
825 .private_value = TUMBLER_MUTE_AMP,
826};
827static snd_kcontrol_new_t tumbler_drc_sw __initdata = {
828 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
829 .name = "DRC Switch",
830 .info = snd_pmac_boolean_mono_info,
831 .get = tumbler_get_drc_switch,
832 .put = tumbler_put_drc_switch
833};
834
835
836#ifdef PMAC_SUPPORT_AUTOMUTE
837/*
838 * auto-mute stuffs
839 */
840static int tumbler_detect_headphone(pmac_t *chip)
841{
842 pmac_tumbler_t *mix = chip->mixer_data;
843 return read_audio_gpio(&mix->hp_detect);
844}
845
846static void check_mute(pmac_t *chip, pmac_gpio_t *gp, int val, int do_notify, snd_kcontrol_t *sw)
847{
848 //pmac_tumbler_t *mix = chip->mixer_data;
849 if (val != read_audio_gpio(gp)) {
850 write_audio_gpio(gp, val);
851 if (do_notify)
852 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &sw->id);
853 }
854}
855
856static struct work_struct device_change;
857
858static void
859device_change_handler(void *self)
860{
861 pmac_t *chip = (pmac_t*) self;
862 pmac_tumbler_t *mix;
863
864 if (!chip)
865 return;
866
867 mix = chip->mixer_data;
868
869 /* first set the DRC so the speaker do not explode -ReneR */
870 if (chip->model == PMAC_TUMBLER)
871 tumbler_set_drc(mix);
872 else
873 snapper_set_drc(mix);
874
875 /* reset the master volume so the correct amplification is applied */
876 tumbler_set_master_volume(mix);
877}
878
879static void tumbler_update_automute(pmac_t *chip, int do_notify)
880{
881 if (chip->auto_mute) {
882 pmac_tumbler_t *mix = chip->mixer_data;
883 snd_assert(mix, return);
884 if (tumbler_detect_headphone(chip)) {
885 /* mute speaker */
886 check_mute(chip, &mix->amp_mute, 1, do_notify, chip->speaker_sw_ctl);
887 check_mute(chip, &mix->hp_mute, 0, do_notify, chip->master_sw_ctl);
888 mix->drc_enable = 0;
889
890 } else {
891 /* unmute speaker */
892 check_mute(chip, &mix->amp_mute, 0, do_notify, chip->speaker_sw_ctl);
893 check_mute(chip, &mix->hp_mute, 1, do_notify, chip->master_sw_ctl);
894 mix->drc_enable = 1;
895 }
896 if (do_notify) {
897 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
898 &chip->hp_detect_ctl->id);
899 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
900 &chip->drc_sw_ctl->id);
901 }
902
903 /* finally we need to schedule an update of the mixer values
904 (master and DRC are enough for now) -ReneR */
905 schedule_work(&device_change);
906
907 }
908}
909#endif /* PMAC_SUPPORT_AUTOMUTE */
910
911
912/* interrupt - headphone plug changed */
913static irqreturn_t headphone_intr(int irq, void *devid, struct pt_regs *regs)
914{
915 pmac_t *chip = devid;
916 if (chip->update_automute && chip->initialized) {
917 chip->update_automute(chip, 1);
918 return IRQ_HANDLED;
919 }
920 return IRQ_NONE;
921}
922
923/* look for audio-gpio device */
924static struct device_node *find_audio_device(const char *name)
925{
926 struct device_node *np;
927
928 if (! (np = find_devices("gpio")))
929 return NULL;
930
931 for (np = np->child; np; np = np->sibling) {
932 char *property = get_property(np, "audio-gpio", NULL);
933 if (property && strcmp(property, name) == 0)
934 return np;
935 }
936 return NULL;
937}
938
939/* look for audio-gpio device */
940static struct device_node *find_compatible_audio_device(const char *name)
941{
942 struct device_node *np;
943
944 if (! (np = find_devices("gpio")))
945 return NULL;
946
947 for (np = np->child; np; np = np->sibling) {
948 if (device_is_compatible(np, name))
949 return np;
950 }
951 return NULL;
952}
953
954/* find an audio device and get its address */
Benjamin Herrenschmidtb75550e2005-04-16 15:24:31 -0700955static long tumbler_find_device(const char *device, pmac_gpio_t *gp, int is_compatible)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956{
957 struct device_node *node;
Benjamin Herrenschmidtb75550e2005-04-16 15:24:31 -0700958 u32 *base, addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
960 if (is_compatible)
961 node = find_compatible_audio_device(device);
962 else
963 node = find_audio_device(device);
964 if (! node) {
965 snd_printdd("cannot find device %s\n", device);
966 return -ENODEV;
967 }
968
969 base = (u32 *)get_property(node, "AAPL,address", NULL);
970 if (! base) {
Benjamin Herrenschmidtb75550e2005-04-16 15:24:31 -0700971 base = (u32 *)get_property(node, "reg", NULL);
972 if (!base) {
973 snd_printd("cannot find address for device %s\n", device);
974 return -ENODEV;
975 }
976 /* this only work if PPC_HAS_FEATURE_CALLS is set as we
977 * are only getting the low part of the address
978 */
979 addr = *base;
980 if (addr < 0x50)
981 addr += 0x50;
982 } else
983 addr = *base;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984
985#ifdef CONFIG_PPC_HAS_FEATURE_CALLS
Benjamin Herrenschmidtb75550e2005-04-16 15:24:31 -0700986 gp->addr = addr & 0x0000ffff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987#else
Benjamin Herrenschmidtb75550e2005-04-16 15:24:31 -0700988 gp->addr = ioremap((unsigned long)addr, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989#endif
Benjamin Herrenschmidtb75550e2005-04-16 15:24:31 -0700990 /* Try to find the active state, default to 0 ! */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991 base = (u32 *)get_property(node, "audio-gpio-active-state", NULL);
992 if (base)
993 gp->active_state = *base;
994 else
Benjamin Herrenschmidtb75550e2005-04-16 15:24:31 -0700995 gp->active_state = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996
997 return (node->n_intrs > 0) ? node->intrs[0].line : 0;
998}
999
1000/* reset audio */
1001static void tumbler_reset_audio(pmac_t *chip)
1002{
1003 pmac_tumbler_t *mix = chip->mixer_data;
1004
1005 write_audio_gpio(&mix->audio_reset, 0);
1006 big_mdelay(200);
1007 write_audio_gpio(&mix->audio_reset, 1);
1008 big_mdelay(100);
1009 write_audio_gpio(&mix->audio_reset, 0);
1010 big_mdelay(100);
1011}
1012
1013#ifdef CONFIG_PMAC_PBOOK
1014/* resume mixer */
1015static void tumbler_resume(pmac_t *chip)
1016{
1017 pmac_tumbler_t *mix = chip->mixer_data;
1018
1019 snd_assert(mix, return);
1020
1021 tumbler_reset_audio(chip);
1022 if (mix->i2c.client && mix->i2c.init_client) {
1023 if (mix->i2c.init_client(&mix->i2c) < 0)
1024 printk(KERN_ERR "tumbler_init_client error\n");
1025 } else
1026 printk(KERN_ERR "tumbler: i2c is not initialized\n");
1027 if (chip->model == PMAC_TUMBLER) {
1028 tumbler_set_mono_volume(mix, &tumbler_pcm_vol_info);
1029 tumbler_set_mono_volume(mix, &tumbler_bass_vol_info);
1030 tumbler_set_mono_volume(mix, &tumbler_treble_vol_info);
1031 tumbler_set_drc(mix);
1032 } else {
1033 snapper_set_mix_vol(mix, VOL_IDX_PCM);
1034 snapper_set_mix_vol(mix, VOL_IDX_PCM2);
1035 snapper_set_mix_vol(mix, VOL_IDX_ADC);
1036 tumbler_set_mono_volume(mix, &snapper_bass_vol_info);
1037 tumbler_set_mono_volume(mix, &snapper_treble_vol_info);
1038 snapper_set_drc(mix);
1039 snapper_set_capture_source(mix);
1040 }
1041 tumbler_set_master_volume(mix);
1042 if (chip->update_automute)
1043 chip->update_automute(chip, 0);
1044}
1045#endif
1046
1047/* initialize tumbler */
1048static int __init tumbler_init(pmac_t *chip)
1049{
1050 int irq, err;
1051 pmac_tumbler_t *mix = chip->mixer_data;
1052 snd_assert(mix, return -EINVAL);
1053
Benjamin Herrenschmidtb75550e2005-04-16 15:24:31 -07001054 if (tumbler_find_device("audio-hw-reset", &mix->audio_reset, 0) < 0)
1055 tumbler_find_device("hw-reset", &mix->audio_reset, 1);
1056 if (tumbler_find_device("amp-mute", &mix->amp_mute, 0) < 0)
1057 tumbler_find_device("amp-mute", &mix->amp_mute, 1);
1058 if (tumbler_find_device("headphone-mute", &mix->hp_mute, 0) < 0)
1059 tumbler_find_device("headphone-mute", &mix->hp_mute, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 irq = tumbler_find_device("headphone-detect", &mix->hp_detect, 0);
1061 if (irq < 0)
Benjamin Herrenschmidtb75550e2005-04-16 15:24:31 -07001062 irq = tumbler_find_device("headphone-detect", &mix->hp_detect, 1);
1063 if (irq < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 irq = tumbler_find_device("keywest-gpio15", &mix->hp_detect, 1);
1065
1066 tumbler_reset_audio(chip);
1067
1068 /* activate headphone status interrupts */
1069 if (irq >= 0) {
1070 unsigned char val;
1071 if ((err = request_irq(irq, headphone_intr, 0,
1072 "Tumbler Headphone Detection", chip)) < 0)
1073 return err;
1074 /* activate headphone status interrupts */
1075 val = do_gpio_read(&mix->hp_detect);
1076 do_gpio_write(&mix->hp_detect, val | 0x80);
1077 }
1078 mix->headphone_irq = irq;
1079
1080 return 0;
1081}
1082
1083static void tumbler_cleanup(pmac_t *chip)
1084{
1085 pmac_tumbler_t *mix = chip->mixer_data;
1086 if (! mix)
1087 return;
1088
1089 if (mix->headphone_irq >= 0)
1090 free_irq(mix->headphone_irq, chip);
1091 tumbler_gpio_free(&mix->audio_reset);
1092 tumbler_gpio_free(&mix->amp_mute);
1093 tumbler_gpio_free(&mix->hp_mute);
1094 tumbler_gpio_free(&mix->hp_detect);
1095 snd_pmac_keywest_cleanup(&mix->i2c);
1096 kfree(mix);
1097 chip->mixer_data = NULL;
1098}
1099
1100/* exported */
1101int __init snd_pmac_tumbler_init(pmac_t *chip)
1102{
1103 int i, err;
1104 pmac_tumbler_t *mix;
1105 u32 *paddr;
1106 struct device_node *tas_node;
1107 char *chipname;
1108
1109#ifdef CONFIG_KMOD
1110 if (current->fs->root)
1111 request_module("i2c-keywest");
1112#endif /* CONFIG_KMOD */
1113
1114 mix = kmalloc(sizeof(*mix), GFP_KERNEL);
1115 if (! mix)
1116 return -ENOMEM;
1117 memset(mix, 0, sizeof(*mix));
1118 mix->headphone_irq = -1;
1119
1120 chip->mixer_data = mix;
1121 chip->mixer_free = tumbler_cleanup;
1122
1123 if ((err = tumbler_init(chip)) < 0)
1124 return err;
1125
1126 /* set up TAS */
1127 tas_node = find_devices("deq");
1128 if (tas_node == NULL)
Benjamin Herrenschmidtb75550e2005-04-16 15:24:31 -07001129 tas_node = find_devices("codec");
1130 if (tas_node == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 return -ENODEV;
1132
1133 paddr = (u32 *)get_property(tas_node, "i2c-address", NULL);
Benjamin Herrenschmidtb75550e2005-04-16 15:24:31 -07001134 if (paddr == NULL)
1135 paddr = (u32 *)get_property(tas_node, "reg", NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 if (paddr)
1137 mix->i2c.addr = (*paddr) >> 1;
1138 else
1139 mix->i2c.addr = TAS_I2C_ADDR;
1140
1141 if (chip->model == PMAC_TUMBLER) {
1142 mix->i2c.init_client = tumbler_init_client;
1143 mix->i2c.name = "TAS3001c";
1144 chipname = "Tumbler";
1145 } else {
1146 mix->i2c.init_client = snapper_init_client;
1147 mix->i2c.name = "TAS3004";
1148 chipname = "Snapper";
1149 }
1150
1151 if ((err = snd_pmac_keywest_init(&mix->i2c)) < 0)
1152 return err;
1153
1154 /*
1155 * build mixers
1156 */
1157 sprintf(chip->card->mixername, "PowerMac %s", chipname);
1158
1159 if (chip->model == PMAC_TUMBLER) {
1160 for (i = 0; i < ARRAY_SIZE(tumbler_mixers); i++) {
1161 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&tumbler_mixers[i], chip))) < 0)
1162 return err;
1163 }
1164 } else {
1165 for (i = 0; i < ARRAY_SIZE(snapper_mixers); i++) {
1166 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snapper_mixers[i], chip))) < 0)
1167 return err;
1168 }
1169 }
1170 chip->master_sw_ctl = snd_ctl_new1(&tumbler_hp_sw, chip);
1171 if ((err = snd_ctl_add(chip->card, chip->master_sw_ctl)) < 0)
1172 return err;
1173 chip->speaker_sw_ctl = snd_ctl_new1(&tumbler_speaker_sw, chip);
1174 if ((err = snd_ctl_add(chip->card, chip->speaker_sw_ctl)) < 0)
1175 return err;
1176 chip->drc_sw_ctl = snd_ctl_new1(&tumbler_drc_sw, chip);
1177 if ((err = snd_ctl_add(chip->card, chip->drc_sw_ctl)) < 0)
1178 return err;
1179
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180#ifdef CONFIG_PMAC_PBOOK
1181 chip->resume = tumbler_resume;
1182#endif
1183
1184 INIT_WORK(&device_change, device_change_handler, (void *)chip);
1185
1186#ifdef PMAC_SUPPORT_AUTOMUTE
1187 if (mix->headphone_irq >=0 && (err = snd_pmac_add_automute(chip)) < 0)
1188 return err;
1189 chip->detect_headphone = tumbler_detect_headphone;
1190 chip->update_automute = tumbler_update_automute;
1191 tumbler_update_automute(chip, 0); /* update the status only */
1192#endif
1193
1194 return 0;
1195}