1498 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * PMac Tumbler/Snapper lowlevel functions4 *5 * Copyright (c) by Takashi Iwai <tiwai@suse.de>6 *7 * Rene Rebe <rene.rebe@gmx.net>:8 * * update from shadow registers on wakeup and headphone plug9 * * automatically toggle DRC on headphone plug10 */11 12 13#include <linux/init.h>14#include <linux/delay.h>15#include <linux/i2c.h>16#include <linux/kmod.h>17#include <linux/slab.h>18#include <linux/interrupt.h>19#include <linux/string.h>20#include <linux/of_irq.h>21#include <linux/io.h>22#include <sound/core.h>23#include <asm/irq.h>24#include <asm/machdep.h>25#include <asm/pmac_feature.h>26#include "pmac.h"27#include "tumbler_volume.h"28 29#undef DEBUG30 31#ifdef DEBUG32#define DBG(fmt...) pr_debug(fmt)33#else34#define DBG(fmt...)35#endif36 37#define IS_G4DA (of_machine_is_compatible("PowerMac3,4"))38 39/* i2c address for tumbler */40#define TAS_I2C_ADDR 0x3441 42/* registers */43#define TAS_REG_MCS 0x01 /* main control */44#define TAS_REG_DRC 0x0245#define TAS_REG_VOL 0x0446#define TAS_REG_TREBLE 0x0547#define TAS_REG_BASS 0x0648#define TAS_REG_INPUT1 0x0749#define TAS_REG_INPUT2 0x0850 51/* tas3001c */52#define TAS_REG_PCM TAS_REG_INPUT153 54/* tas3004 */55#define TAS_REG_LMIX TAS_REG_INPUT156#define TAS_REG_RMIX TAS_REG_INPUT257#define TAS_REG_MCS2 0x43 /* main control 2 */58#define TAS_REG_ACS 0x40 /* analog control */59 60/* mono volumes for tas3001c/tas3004 */61enum {62 VOL_IDX_PCM_MONO, /* tas3001c only */63 VOL_IDX_BASS, VOL_IDX_TREBLE,64 VOL_IDX_LAST_MONO65};66 67/* stereo volumes for tas3004 */68enum {69 VOL_IDX_PCM, VOL_IDX_PCM2, VOL_IDX_ADC,70 VOL_IDX_LAST_MIX71};72 73struct pmac_gpio {74 unsigned int addr;75 u8 active_val;76 u8 inactive_val;77 u8 active_state;78};79 80struct pmac_tumbler {81 struct pmac_keywest i2c;82 struct pmac_gpio audio_reset;83 struct pmac_gpio amp_mute;84 struct pmac_gpio line_mute;85 struct pmac_gpio line_detect;86 struct pmac_gpio hp_mute;87 struct pmac_gpio hp_detect;88 int headphone_irq;89 int lineout_irq;90 unsigned int save_master_vol[2];91 unsigned int master_vol[2];92 unsigned int save_master_switch[2];93 unsigned int master_switch[2];94 unsigned int mono_vol[VOL_IDX_LAST_MONO];95 unsigned int mix_vol[VOL_IDX_LAST_MIX][2]; /* stereo volumes for tas3004 */96 int drc_range;97 int drc_enable;98 int capture_source;99 int anded_reset;100 int auto_mute_notify;101 int reset_on_sleep;102 u8 acs;103};104 105 106/*107 */108 109static int send_init_client(struct pmac_keywest *i2c, const 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 DBG("(W) i2c error %d\n", err);119 mdelay(10);120 } while (count--);121 if (err < 0)122 return -ENXIO;123 regs += 2;124 }125 return 0;126}127 128 129static int tumbler_init_client(struct pmac_keywest *i2c)130{131 static const unsigned int regs[] = {132 /* normal operation, SCLK=64fps, i2s output, i2s input, 16bit width */133 TAS_REG_MCS, (1<<6)|(2<<4)|(2<<2)|0,134 0, /* terminator */135 };136 DBG("(I) tumbler init client\n");137 return send_init_client(i2c, regs);138}139 140static int snapper_init_client(struct pmac_keywest *i2c)141{142 static const unsigned int regs[] = {143 /* normal operation, SCLK=64fps, i2s output, 16bit width */144 TAS_REG_MCS, (1<<6)|(2<<4)|0,145 /* normal operation, all-pass mode */146 TAS_REG_MCS2, (1<<1),147 /* normal output, no deemphasis, A input, power-up, line-in */148 TAS_REG_ACS, 0,149 0, /* terminator */150 };151 DBG("(I) snapper init client\n");152 return send_init_client(i2c, regs);153}154 155/*156 * gpio access157 */158#define do_gpio_write(gp, val) \159 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, (gp)->addr, val)160#define do_gpio_read(gp) \161 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, (gp)->addr, 0)162#define tumbler_gpio_free(gp) /* NOP */163 164static void write_audio_gpio(struct pmac_gpio *gp, int active)165{166 if (! gp->addr)167 return;168 active = active ? gp->active_val : gp->inactive_val;169 do_gpio_write(gp, active);170 DBG("(I) gpio %x write %d\n", gp->addr, active);171}172 173static int check_audio_gpio(struct pmac_gpio *gp)174{175 int ret;176 177 if (! gp->addr)178 return 0;179 180 ret = do_gpio_read(gp);181 182 return (ret & 0x1) == (gp->active_val & 0x1);183}184 185static int read_audio_gpio(struct pmac_gpio *gp)186{187 int ret;188 if (! gp->addr)189 return 0;190 ret = do_gpio_read(gp);191 ret = (ret & 0x02) !=0;192 return ret == gp->active_state;193}194 195/*196 * update master volume197 */198static int tumbler_set_master_volume(struct pmac_tumbler *mix)199{200 unsigned char block[6];201 unsigned int left_vol, right_vol;202 203 if (! mix->i2c.client)204 return -ENODEV;205 206 if (! mix->master_switch[0])207 left_vol = 0;208 else {209 left_vol = mix->master_vol[0];210 if (left_vol >= ARRAY_SIZE(master_volume_table))211 left_vol = ARRAY_SIZE(master_volume_table) - 1;212 left_vol = master_volume_table[left_vol];213 }214 if (! mix->master_switch[1])215 right_vol = 0;216 else {217 right_vol = mix->master_vol[1];218 if (right_vol >= ARRAY_SIZE(master_volume_table))219 right_vol = ARRAY_SIZE(master_volume_table) - 1;220 right_vol = master_volume_table[right_vol];221 }222 223 block[0] = (left_vol >> 16) & 0xff;224 block[1] = (left_vol >> 8) & 0xff;225 block[2] = (left_vol >> 0) & 0xff;226 227 block[3] = (right_vol >> 16) & 0xff;228 block[4] = (right_vol >> 8) & 0xff;229 block[5] = (right_vol >> 0) & 0xff;230 231 if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_VOL, 6,232 block) < 0) {233 dev_err(&mix->i2c.client->dev, "failed to set volume\n");234 return -EINVAL;235 }236 DBG("(I) succeeded to set volume (%u, %u)\n", left_vol, right_vol);237 return 0;238}239 240 241/* output volume */242static int tumbler_info_master_volume(struct snd_kcontrol *kcontrol,243 struct snd_ctl_elem_info *uinfo)244{245 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;246 uinfo->count = 2;247 uinfo->value.integer.min = 0;248 uinfo->value.integer.max = ARRAY_SIZE(master_volume_table) - 1;249 return 0;250}251 252static int tumbler_get_master_volume(struct snd_kcontrol *kcontrol,253 struct snd_ctl_elem_value *ucontrol)254{255 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);256 struct pmac_tumbler *mix = chip->mixer_data;257 258 ucontrol->value.integer.value[0] = mix->master_vol[0];259 ucontrol->value.integer.value[1] = mix->master_vol[1];260 return 0;261}262 263static int tumbler_put_master_volume(struct snd_kcontrol *kcontrol,264 struct snd_ctl_elem_value *ucontrol)265{266 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);267 struct pmac_tumbler *mix = chip->mixer_data;268 unsigned int vol[2];269 int change;270 271 vol[0] = ucontrol->value.integer.value[0];272 vol[1] = ucontrol->value.integer.value[1];273 if (vol[0] >= ARRAY_SIZE(master_volume_table) ||274 vol[1] >= ARRAY_SIZE(master_volume_table))275 return -EINVAL;276 change = mix->master_vol[0] != vol[0] ||277 mix->master_vol[1] != vol[1];278 if (change) {279 mix->master_vol[0] = vol[0];280 mix->master_vol[1] = vol[1];281 tumbler_set_master_volume(mix);282 }283 return change;284}285 286/* output switch */287static int tumbler_get_master_switch(struct snd_kcontrol *kcontrol,288 struct snd_ctl_elem_value *ucontrol)289{290 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);291 struct pmac_tumbler *mix = chip->mixer_data;292 293 ucontrol->value.integer.value[0] = mix->master_switch[0];294 ucontrol->value.integer.value[1] = mix->master_switch[1];295 return 0;296}297 298static int tumbler_put_master_switch(struct snd_kcontrol *kcontrol,299 struct snd_ctl_elem_value *ucontrol)300{301 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);302 struct pmac_tumbler *mix = chip->mixer_data;303 int change;304 305 change = mix->master_switch[0] != ucontrol->value.integer.value[0] ||306 mix->master_switch[1] != ucontrol->value.integer.value[1];307 if (change) {308 mix->master_switch[0] = !!ucontrol->value.integer.value[0];309 mix->master_switch[1] = !!ucontrol->value.integer.value[1];310 tumbler_set_master_volume(mix);311 }312 return change;313}314 315 316/*317 * TAS3001c dynamic range compression318 */319 320#define TAS3001_DRC_MAX 0x5f321 322static int tumbler_set_drc(struct pmac_tumbler *mix)323{324 unsigned char val[2];325 326 if (! mix->i2c.client)327 return -ENODEV;328 329 if (mix->drc_enable) {330 val[0] = 0xc1; /* enable, 3:1 compression */331 if (mix->drc_range > TAS3001_DRC_MAX)332 val[1] = 0xf0;333 else if (mix->drc_range < 0)334 val[1] = 0x91;335 else336 val[1] = mix->drc_range + 0x91;337 } else {338 val[0] = 0;339 val[1] = 0;340 }341 342 if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC,343 2, val) < 0) {344 dev_err(&mix->i2c.client->dev, "failed to set DRC\n");345 return -EINVAL;346 }347 DBG("(I) succeeded to set DRC (%u, %u)\n", val[0], val[1]);348 return 0;349}350 351/*352 * TAS3004353 */354 355#define TAS3004_DRC_MAX 0xef356 357static int snapper_set_drc(struct pmac_tumbler *mix)358{359 unsigned char val[6];360 361 if (! mix->i2c.client)362 return -ENODEV;363 364 if (mix->drc_enable)365 val[0] = 0x50; /* 3:1 above threshold */366 else367 val[0] = 0x51; /* disabled */368 val[1] = 0x02; /* 1:1 below threshold */369 if (mix->drc_range > 0xef)370 val[2] = 0xef;371 else if (mix->drc_range < 0)372 val[2] = 0x00;373 else374 val[2] = mix->drc_range;375 val[3] = 0xb0;376 val[4] = 0x60;377 val[5] = 0xa0;378 379 if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC,380 6, val) < 0) {381 dev_err(&mix->i2c.client->dev, "failed to set DRC\n");382 return -EINVAL;383 }384 DBG("(I) succeeded to set DRC (%u, %u)\n", val[0], val[1]);385 return 0;386}387 388static int tumbler_info_drc_value(struct snd_kcontrol *kcontrol,389 struct snd_ctl_elem_info *uinfo)390{391 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);392 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;393 uinfo->count = 1;394 uinfo->value.integer.min = 0;395 uinfo->value.integer.max =396 chip->model == PMAC_TUMBLER ? TAS3001_DRC_MAX : TAS3004_DRC_MAX;397 return 0;398}399 400static int tumbler_get_drc_value(struct snd_kcontrol *kcontrol,401 struct snd_ctl_elem_value *ucontrol)402{403 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);404 struct pmac_tumbler *mix;405 mix = chip->mixer_data;406 if (!mix)407 return -ENODEV;408 ucontrol->value.integer.value[0] = mix->drc_range;409 return 0;410}411 412static int tumbler_put_drc_value(struct snd_kcontrol *kcontrol,413 struct snd_ctl_elem_value *ucontrol)414{415 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);416 struct pmac_tumbler *mix;417 unsigned int val;418 int change;419 420 mix = chip->mixer_data;421 if (!mix)422 return -ENODEV;423 val = ucontrol->value.integer.value[0];424 if (chip->model == PMAC_TUMBLER) {425 if (val > TAS3001_DRC_MAX)426 return -EINVAL;427 } else {428 if (val > TAS3004_DRC_MAX)429 return -EINVAL;430 }431 change = mix->drc_range != val;432 if (change) {433 mix->drc_range = val;434 if (chip->model == PMAC_TUMBLER)435 tumbler_set_drc(mix);436 else437 snapper_set_drc(mix);438 }439 return change;440}441 442static int tumbler_get_drc_switch(struct snd_kcontrol *kcontrol,443 struct snd_ctl_elem_value *ucontrol)444{445 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);446 struct pmac_tumbler *mix;447 mix = chip->mixer_data;448 if (!mix)449 return -ENODEV;450 ucontrol->value.integer.value[0] = mix->drc_enable;451 return 0;452}453 454static int tumbler_put_drc_switch(struct snd_kcontrol *kcontrol,455 struct snd_ctl_elem_value *ucontrol)456{457 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);458 struct pmac_tumbler *mix;459 int change;460 461 mix = chip->mixer_data;462 if (!mix)463 return -ENODEV;464 change = mix->drc_enable != ucontrol->value.integer.value[0];465 if (change) {466 mix->drc_enable = !!ucontrol->value.integer.value[0];467 if (chip->model == PMAC_TUMBLER)468 tumbler_set_drc(mix);469 else470 snapper_set_drc(mix);471 }472 return change;473}474 475 476/*477 * mono volumes478 */479 480struct tumbler_mono_vol {481 int index;482 int reg;483 int bytes;484 unsigned int max;485 const unsigned int *table;486};487 488static int tumbler_set_mono_volume(struct pmac_tumbler *mix,489 const struct tumbler_mono_vol *info)490{491 unsigned char block[4];492 unsigned int vol;493 int i;494 495 if (! mix->i2c.client)496 return -ENODEV;497 498 vol = mix->mono_vol[info->index];499 if (vol >= info->max)500 vol = info->max - 1;501 vol = info->table[vol];502 for (i = 0; i < info->bytes; i++)503 block[i] = (vol >> ((info->bytes - i - 1) * 8)) & 0xff;504 if (i2c_smbus_write_i2c_block_data(mix->i2c.client, info->reg,505 info->bytes, block) < 0) {506 dev_err(&mix->i2c.client->dev, "failed to set mono volume %d\n",507 info->index);508 return -EINVAL;509 }510 return 0;511}512 513static int tumbler_info_mono(struct snd_kcontrol *kcontrol,514 struct snd_ctl_elem_info *uinfo)515{516 struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;517 518 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;519 uinfo->count = 1;520 uinfo->value.integer.min = 0;521 uinfo->value.integer.max = info->max - 1;522 return 0;523}524 525static int tumbler_get_mono(struct snd_kcontrol *kcontrol,526 struct snd_ctl_elem_value *ucontrol)527{528 struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;529 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);530 struct pmac_tumbler *mix;531 mix = chip->mixer_data;532 if (!mix)533 return -ENODEV;534 ucontrol->value.integer.value[0] = mix->mono_vol[info->index];535 return 0;536}537 538static int tumbler_put_mono(struct snd_kcontrol *kcontrol,539 struct snd_ctl_elem_value *ucontrol)540{541 struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;542 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);543 struct pmac_tumbler *mix;544 unsigned int vol;545 int change;546 547 mix = chip->mixer_data;548 if (!mix)549 return -ENODEV;550 vol = ucontrol->value.integer.value[0];551 if (vol >= info->max)552 return -EINVAL;553 change = mix->mono_vol[info->index] != vol;554 if (change) {555 mix->mono_vol[info->index] = vol;556 tumbler_set_mono_volume(mix, info);557 }558 return change;559}560 561/* TAS3001c mono volumes */562static const struct tumbler_mono_vol tumbler_pcm_vol_info = {563 .index = VOL_IDX_PCM_MONO,564 .reg = TAS_REG_PCM,565 .bytes = 3,566 .max = ARRAY_SIZE(mixer_volume_table),567 .table = mixer_volume_table,568};569 570static const struct tumbler_mono_vol tumbler_bass_vol_info = {571 .index = VOL_IDX_BASS,572 .reg = TAS_REG_BASS,573 .bytes = 1,574 .max = ARRAY_SIZE(bass_volume_table),575 .table = bass_volume_table,576};577 578static const struct tumbler_mono_vol tumbler_treble_vol_info = {579 .index = VOL_IDX_TREBLE,580 .reg = TAS_REG_TREBLE,581 .bytes = 1,582 .max = ARRAY_SIZE(treble_volume_table),583 .table = treble_volume_table,584};585 586/* TAS3004 mono volumes */587static const struct tumbler_mono_vol snapper_bass_vol_info = {588 .index = VOL_IDX_BASS,589 .reg = TAS_REG_BASS,590 .bytes = 1,591 .max = ARRAY_SIZE(snapper_bass_volume_table),592 .table = snapper_bass_volume_table,593};594 595static const struct tumbler_mono_vol snapper_treble_vol_info = {596 .index = VOL_IDX_TREBLE,597 .reg = TAS_REG_TREBLE,598 .bytes = 1,599 .max = ARRAY_SIZE(snapper_treble_volume_table),600 .table = snapper_treble_volume_table,601};602 603 604#define DEFINE_MONO(xname,type) { \605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\606 .name = xname, \607 .info = tumbler_info_mono, \608 .get = tumbler_get_mono, \609 .put = tumbler_put_mono, \610 .private_value = (unsigned long)(&tumbler_##type##_vol_info), \611}612 613#define DEFINE_SNAPPER_MONO(xname,type) { \614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\615 .name = xname, \616 .info = tumbler_info_mono, \617 .get = tumbler_get_mono, \618 .put = tumbler_put_mono, \619 .private_value = (unsigned long)(&snapper_##type##_vol_info), \620}621 622 623/*624 * snapper mixer volumes625 */626 627static int snapper_set_mix_vol1(struct pmac_tumbler *mix, int idx, int ch, int reg)628{629 int i, j, vol;630 unsigned char block[9];631 632 vol = mix->mix_vol[idx][ch];633 if (vol >= ARRAY_SIZE(mixer_volume_table)) {634 vol = ARRAY_SIZE(mixer_volume_table) - 1;635 mix->mix_vol[idx][ch] = vol;636 }637 638 for (i = 0; i < 3; i++) {639 vol = mix->mix_vol[i][ch];640 vol = mixer_volume_table[vol];641 for (j = 0; j < 3; j++)642 block[i * 3 + j] = (vol >> ((2 - j) * 8)) & 0xff;643 }644 if (i2c_smbus_write_i2c_block_data(mix->i2c.client, reg,645 9, block) < 0) {646 dev_err(&mix->i2c.client->dev,647 "failed to set mono volume %d\n", reg);648 return -EINVAL;649 }650 return 0;651}652 653static int snapper_set_mix_vol(struct pmac_tumbler *mix, int idx)654{655 if (! mix->i2c.client)656 return -ENODEV;657 if (snapper_set_mix_vol1(mix, idx, 0, TAS_REG_LMIX) < 0 ||658 snapper_set_mix_vol1(mix, idx, 1, TAS_REG_RMIX) < 0)659 return -EINVAL;660 return 0;661}662 663static int snapper_info_mix(struct snd_kcontrol *kcontrol,664 struct snd_ctl_elem_info *uinfo)665{666 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;667 uinfo->count = 2;668 uinfo->value.integer.min = 0;669 uinfo->value.integer.max = ARRAY_SIZE(mixer_volume_table) - 1;670 return 0;671}672 673static int snapper_get_mix(struct snd_kcontrol *kcontrol,674 struct snd_ctl_elem_value *ucontrol)675{676 int idx = (int)kcontrol->private_value;677 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);678 struct pmac_tumbler *mix;679 mix = chip->mixer_data;680 if (!mix)681 return -ENODEV;682 ucontrol->value.integer.value[0] = mix->mix_vol[idx][0];683 ucontrol->value.integer.value[1] = mix->mix_vol[idx][1];684 return 0;685}686 687static int snapper_put_mix(struct snd_kcontrol *kcontrol,688 struct snd_ctl_elem_value *ucontrol)689{690 int idx = (int)kcontrol->private_value;691 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);692 struct pmac_tumbler *mix;693 unsigned int vol[2];694 int change;695 696 mix = chip->mixer_data;697 if (!mix)698 return -ENODEV;699 vol[0] = ucontrol->value.integer.value[0];700 vol[1] = ucontrol->value.integer.value[1];701 if (vol[0] >= ARRAY_SIZE(mixer_volume_table) ||702 vol[1] >= ARRAY_SIZE(mixer_volume_table))703 return -EINVAL;704 change = mix->mix_vol[idx][0] != vol[0] ||705 mix->mix_vol[idx][1] != vol[1];706 if (change) {707 mix->mix_vol[idx][0] = vol[0];708 mix->mix_vol[idx][1] = vol[1];709 snapper_set_mix_vol(mix, idx);710 }711 return change;712}713 714 715/*716 * mute switches. FIXME: Turn that into software mute when both outputs are muted717 * to avoid codec reset on ibook M7718 */719 720enum { TUMBLER_MUTE_HP, TUMBLER_MUTE_AMP, TUMBLER_MUTE_LINE };721 722static int tumbler_get_mute_switch(struct snd_kcontrol *kcontrol,723 struct snd_ctl_elem_value *ucontrol)724{725 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);726 struct pmac_tumbler *mix;727 struct pmac_gpio *gp;728 mix = chip->mixer_data;729 if (!mix)730 return -ENODEV;731 switch(kcontrol->private_value) {732 case TUMBLER_MUTE_HP:733 gp = &mix->hp_mute; break;734 case TUMBLER_MUTE_AMP:735 gp = &mix->amp_mute; break;736 case TUMBLER_MUTE_LINE:737 gp = &mix->line_mute; break;738 default:739 gp = NULL;740 }741 if (gp == NULL)742 return -EINVAL;743 ucontrol->value.integer.value[0] = !check_audio_gpio(gp);744 return 0;745}746 747static int tumbler_put_mute_switch(struct snd_kcontrol *kcontrol,748 struct snd_ctl_elem_value *ucontrol)749{750 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);751 struct pmac_tumbler *mix;752 struct pmac_gpio *gp;753 int val;754#ifdef PMAC_SUPPORT_AUTOMUTE755 if (chip->update_automute && chip->auto_mute)756 return 0; /* don't touch in the auto-mute mode */757#endif 758 mix = chip->mixer_data;759 if (!mix)760 return -ENODEV;761 switch(kcontrol->private_value) {762 case TUMBLER_MUTE_HP:763 gp = &mix->hp_mute; break;764 case TUMBLER_MUTE_AMP:765 gp = &mix->amp_mute; break;766 case TUMBLER_MUTE_LINE:767 gp = &mix->line_mute; break;768 default:769 gp = NULL;770 }771 if (gp == NULL)772 return -EINVAL;773 val = ! check_audio_gpio(gp);774 if (val != ucontrol->value.integer.value[0]) {775 write_audio_gpio(gp, ! ucontrol->value.integer.value[0]);776 return 1;777 }778 return 0;779}780 781static int snapper_set_capture_source(struct pmac_tumbler *mix)782{783 if (! mix->i2c.client)784 return -ENODEV;785 if (mix->capture_source)786 mix->acs |= 2;787 else788 mix->acs &= ~2;789 return i2c_smbus_write_byte_data(mix->i2c.client, TAS_REG_ACS, mix->acs);790}791 792static int snapper_info_capture_source(struct snd_kcontrol *kcontrol,793 struct snd_ctl_elem_info *uinfo)794{795 static const char * const texts[2] = {796 "Line", "Mic"797 };798 799 return snd_ctl_enum_info(uinfo, 1, 2, texts);800}801 802static int snapper_get_capture_source(struct snd_kcontrol *kcontrol,803 struct snd_ctl_elem_value *ucontrol)804{805 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);806 struct pmac_tumbler *mix = chip->mixer_data;807 808 ucontrol->value.enumerated.item[0] = mix->capture_source;809 return 0;810}811 812static int snapper_put_capture_source(struct snd_kcontrol *kcontrol,813 struct snd_ctl_elem_value *ucontrol)814{815 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);816 struct pmac_tumbler *mix = chip->mixer_data;817 int change;818 819 change = ucontrol->value.enumerated.item[0] != mix->capture_source;820 if (change) {821 mix->capture_source = !!ucontrol->value.enumerated.item[0];822 snapper_set_capture_source(mix);823 }824 return change;825}826 827#define DEFINE_SNAPPER_MIX(xname,idx,ofs) { \828 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\829 .name = xname, \830 .info = snapper_info_mix, \831 .get = snapper_get_mix, \832 .put = snapper_put_mix, \833 .index = idx,\834 .private_value = ofs, \835}836 837 838/*839 */840static const struct snd_kcontrol_new tumbler_mixers[] = {841 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,842 .name = "Master Playback Volume",843 .info = tumbler_info_master_volume,844 .get = tumbler_get_master_volume,845 .put = tumbler_put_master_volume846 },847 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,848 .name = "Master Playback Switch",849 .info = snd_pmac_boolean_stereo_info,850 .get = tumbler_get_master_switch,851 .put = tumbler_put_master_switch852 },853 DEFINE_MONO("Tone Control - Bass", bass),854 DEFINE_MONO("Tone Control - Treble", treble),855 DEFINE_MONO("PCM Playback Volume", pcm),856 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,857 .name = "DRC Range",858 .info = tumbler_info_drc_value,859 .get = tumbler_get_drc_value,860 .put = tumbler_put_drc_value861 },862};863 864static const struct snd_kcontrol_new snapper_mixers[] = {865 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,866 .name = "Master Playback Volume",867 .info = tumbler_info_master_volume,868 .get = tumbler_get_master_volume,869 .put = tumbler_put_master_volume870 },871 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,872 .name = "Master Playback Switch",873 .info = snd_pmac_boolean_stereo_info,874 .get = tumbler_get_master_switch,875 .put = tumbler_put_master_switch876 },877 DEFINE_SNAPPER_MIX("PCM Playback Volume", 0, VOL_IDX_PCM),878 /* Alternative PCM is assigned to Mic analog loopback on iBook G4 */879 DEFINE_SNAPPER_MIX("Mic Playback Volume", 0, VOL_IDX_PCM2),880 DEFINE_SNAPPER_MIX("Monitor Mix Volume", 0, VOL_IDX_ADC),881 DEFINE_SNAPPER_MONO("Tone Control - Bass", bass),882 DEFINE_SNAPPER_MONO("Tone Control - Treble", treble),883 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,884 .name = "DRC Range",885 .info = tumbler_info_drc_value,886 .get = tumbler_get_drc_value,887 .put = tumbler_put_drc_value888 },889 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,890 .name = "Input Source", /* FIXME: "Capture Source" doesn't work properly */891 .info = snapper_info_capture_source,892 .get = snapper_get_capture_source,893 .put = snapper_put_capture_source894 },895};896 897static const struct snd_kcontrol_new tumbler_hp_sw = {898 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,899 .name = "Headphone Playback Switch",900 .info = snd_pmac_boolean_mono_info,901 .get = tumbler_get_mute_switch,902 .put = tumbler_put_mute_switch,903 .private_value = TUMBLER_MUTE_HP,904};905static const struct snd_kcontrol_new tumbler_speaker_sw = {906 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,907 .name = "Speaker Playback Switch",908 .info = snd_pmac_boolean_mono_info,909 .get = tumbler_get_mute_switch,910 .put = tumbler_put_mute_switch,911 .private_value = TUMBLER_MUTE_AMP,912};913static const struct snd_kcontrol_new tumbler_lineout_sw = {914 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,915 .name = "Line Out Playback Switch",916 .info = snd_pmac_boolean_mono_info,917 .get = tumbler_get_mute_switch,918 .put = tumbler_put_mute_switch,919 .private_value = TUMBLER_MUTE_LINE,920};921static const struct snd_kcontrol_new tumbler_drc_sw = {922 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,923 .name = "DRC Switch",924 .info = snd_pmac_boolean_mono_info,925 .get = tumbler_get_drc_switch,926 .put = tumbler_put_drc_switch927};928 929 930#ifdef PMAC_SUPPORT_AUTOMUTE931/*932 * auto-mute stuffs933 */934static int tumbler_detect_headphone(struct snd_pmac *chip)935{936 struct pmac_tumbler *mix = chip->mixer_data;937 int detect = 0;938 939 if (mix->hp_detect.addr)940 detect |= read_audio_gpio(&mix->hp_detect);941 return detect;942}943 944static int tumbler_detect_lineout(struct snd_pmac *chip)945{946 struct pmac_tumbler *mix = chip->mixer_data;947 int detect = 0;948 949 if (mix->line_detect.addr)950 detect |= read_audio_gpio(&mix->line_detect);951 return detect;952}953 954static void check_mute(struct snd_pmac *chip, struct pmac_gpio *gp, int val, int do_notify,955 struct snd_kcontrol *sw)956{957 if (check_audio_gpio(gp) != val) {958 write_audio_gpio(gp, val);959 if (do_notify)960 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,961 &sw->id);962 }963}964 965static struct work_struct device_change;966static struct snd_pmac *device_change_chip;967 968static void device_change_handler(struct work_struct *work)969{970 struct snd_pmac *chip = device_change_chip;971 struct pmac_tumbler *mix;972 int headphone, lineout;973 974 if (!chip)975 return;976 977 mix = chip->mixer_data;978 if (snd_BUG_ON(!mix))979 return;980 981 headphone = tumbler_detect_headphone(chip);982 lineout = tumbler_detect_lineout(chip);983 984 DBG("headphone: %d, lineout: %d\n", headphone, lineout);985 986 if (headphone || lineout) {987 /* unmute headphone/lineout & mute speaker */988 if (headphone)989 check_mute(chip, &mix->hp_mute, 0, mix->auto_mute_notify,990 chip->master_sw_ctl);991 if (lineout && mix->line_mute.addr != 0)992 check_mute(chip, &mix->line_mute, 0, mix->auto_mute_notify,993 chip->lineout_sw_ctl);994 if (mix->anded_reset)995 msleep(10);996 check_mute(chip, &mix->amp_mute, !IS_G4DA, mix->auto_mute_notify,997 chip->speaker_sw_ctl);998 } else {999 /* unmute speaker, mute others */1000 check_mute(chip, &mix->amp_mute, 0, mix->auto_mute_notify,1001 chip->speaker_sw_ctl);1002 if (mix->anded_reset)1003 msleep(10);1004 check_mute(chip, &mix->hp_mute, 1, mix->auto_mute_notify,1005 chip->master_sw_ctl);1006 if (mix->line_mute.addr != 0)1007 check_mute(chip, &mix->line_mute, 1, mix->auto_mute_notify,1008 chip->lineout_sw_ctl);1009 }1010 if (mix->auto_mute_notify)1011 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,1012 &chip->hp_detect_ctl->id);1013 1014#ifdef CONFIG_SND_POWERMAC_AUTO_DRC1015 mix->drc_enable = ! (headphone || lineout);1016 if (mix->auto_mute_notify)1017 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,1018 &chip->drc_sw_ctl->id);1019 if (chip->model == PMAC_TUMBLER)1020 tumbler_set_drc(mix);1021 else1022 snapper_set_drc(mix);1023#endif1024 1025 /* reset the master volume so the correct amplification is applied */1026 tumbler_set_master_volume(mix);1027}1028 1029static void tumbler_update_automute(struct snd_pmac *chip, int do_notify)1030{1031 if (chip->auto_mute) {1032 struct pmac_tumbler *mix;1033 mix = chip->mixer_data;1034 if (snd_BUG_ON(!mix))1035 return;1036 mix->auto_mute_notify = do_notify;1037 schedule_work(&device_change);1038 }1039}1040#endif /* PMAC_SUPPORT_AUTOMUTE */1041 1042 1043/* interrupt - headphone plug changed */1044static irqreturn_t headphone_intr(int irq, void *devid)1045{1046 struct snd_pmac *chip = devid;1047 if (chip->update_automute && chip->initialized) {1048 chip->update_automute(chip, 1);1049 return IRQ_HANDLED;1050 }1051 return IRQ_NONE;1052}1053 1054/* look for audio-gpio device */1055static struct device_node *find_audio_device(const char *name)1056{1057 struct device_node *gpiop;1058 struct device_node *np;1059 1060 gpiop = of_find_node_by_name(NULL, "gpio");1061 if (! gpiop)1062 return NULL;1063 1064 for_each_child_of_node(gpiop, np) {1065 const char *property = of_get_property(np, "audio-gpio", NULL);1066 if (property && strcmp(property, name) == 0)1067 break;1068 } 1069 of_node_put(gpiop);1070 return np;1071}1072 1073/* look for audio-gpio device */1074static struct device_node *find_compatible_audio_device(const char *name)1075{1076 struct device_node *gpiop;1077 struct device_node *np;1078 1079 gpiop = of_find_node_by_name(NULL, "gpio");1080 if (!gpiop)1081 return NULL;1082 1083 for_each_child_of_node(gpiop, np) {1084 if (of_device_is_compatible(np, name))1085 break;1086 } 1087 of_node_put(gpiop);1088 return np;1089}1090 1091/* find an audio device and get its address */1092static long tumbler_find_device(const char *device, const char *platform,1093 struct pmac_gpio *gp, int is_compatible)1094{1095 struct device_node *node;1096 const u32 *base;1097 u32 addr;1098 long ret;1099 1100 if (is_compatible)1101 node = find_compatible_audio_device(device);1102 else1103 node = find_audio_device(device);1104 if (! node) {1105 DBG("(W) cannot find audio device %s !\n", device);1106 return -ENODEV;1107 }1108 1109 base = of_get_property(node, "AAPL,address", NULL);1110 if (! base) {1111 base = of_get_property(node, "reg", NULL);1112 if (!base) {1113 DBG("(E) cannot find address for device %s !\n", device);1114 of_node_put(node);1115 return -ENODEV;1116 }1117 addr = *base;1118 if (addr < 0x50)1119 addr += 0x50;1120 } else1121 addr = *base;1122 1123 gp->addr = addr & 0x0000ffff;1124 /* Try to find the active state, default to 0 ! */1125 base = of_get_property(node, "audio-gpio-active-state", NULL);1126 if (base) {1127 gp->active_state = *base;1128 gp->active_val = (*base) ? 0x5 : 0x4;1129 gp->inactive_val = (*base) ? 0x4 : 0x5;1130 } else {1131 const u32 *prop = NULL;1132 gp->active_state = IS_G4DA1133 && !strncmp(device, "keywest-gpio1", 13);1134 gp->active_val = 0x4;1135 gp->inactive_val = 0x5;1136 /* Here are some crude hacks to extract the GPIO polarity and1137 * open collector informations out of the do-platform script1138 * as we don't yet have an interpreter for these things1139 */1140 if (platform)1141 prop = of_get_property(node, platform, NULL);1142 if (prop) {1143 if (prop[3] == 0x9 && prop[4] == 0x9) {1144 gp->active_val = 0xd;1145 gp->inactive_val = 0xc;1146 }1147 if (prop[3] == 0x1 && prop[4] == 0x1) {1148 gp->active_val = 0x5;1149 gp->inactive_val = 0x4;1150 }1151 }1152 }1153 1154 DBG("(I) GPIO device %s found, offset: %x, active state: %d !\n",1155 device, gp->addr, gp->active_state);1156 1157 ret = irq_of_parse_and_map(node, 0);1158 of_node_put(node);1159 return ret;1160}1161 1162/* reset audio */1163static void tumbler_reset_audio(struct snd_pmac *chip)1164{1165 struct pmac_tumbler *mix = chip->mixer_data;1166 1167 if (mix->anded_reset) {1168 DBG("(I) codec anded reset !\n");1169 write_audio_gpio(&mix->hp_mute, 0);1170 write_audio_gpio(&mix->amp_mute, 0);1171 msleep(200);1172 write_audio_gpio(&mix->hp_mute, 1);1173 write_audio_gpio(&mix->amp_mute, 1);1174 msleep(100);1175 write_audio_gpio(&mix->hp_mute, 0);1176 write_audio_gpio(&mix->amp_mute, 0);1177 msleep(100);1178 } else {1179 DBG("(I) codec normal reset !\n");1180 1181 write_audio_gpio(&mix->audio_reset, 0);1182 msleep(200);1183 write_audio_gpio(&mix->audio_reset, 1);1184 msleep(100);1185 write_audio_gpio(&mix->audio_reset, 0);1186 msleep(100);1187 }1188}1189 1190#ifdef CONFIG_PM1191/* suspend mixer */1192static void tumbler_suspend(struct snd_pmac *chip)1193{1194 struct pmac_tumbler *mix = chip->mixer_data;1195 1196 if (mix->headphone_irq >= 0)1197 disable_irq(mix->headphone_irq);1198 if (mix->lineout_irq >= 0)1199 disable_irq(mix->lineout_irq);1200 mix->save_master_switch[0] = mix->master_switch[0];1201 mix->save_master_switch[1] = mix->master_switch[1];1202 mix->save_master_vol[0] = mix->master_vol[0];1203 mix->save_master_vol[1] = mix->master_vol[1];1204 mix->master_switch[0] = mix->master_switch[1] = 0;1205 tumbler_set_master_volume(mix);1206 if (!mix->anded_reset) {1207 write_audio_gpio(&mix->amp_mute, 1);1208 write_audio_gpio(&mix->hp_mute, 1);1209 }1210 if (chip->model == PMAC_SNAPPER) {1211 mix->acs |= 1;1212 i2c_smbus_write_byte_data(mix->i2c.client, TAS_REG_ACS, mix->acs);1213 }1214 if (mix->anded_reset) {1215 write_audio_gpio(&mix->amp_mute, 1);1216 write_audio_gpio(&mix->hp_mute, 1);1217 } else1218 write_audio_gpio(&mix->audio_reset, 1);1219}1220 1221/* resume mixer */1222static void tumbler_resume(struct snd_pmac *chip)1223{1224 struct pmac_tumbler *mix = chip->mixer_data;1225 1226 mix->acs &= ~1;1227 mix->master_switch[0] = mix->save_master_switch[0];1228 mix->master_switch[1] = mix->save_master_switch[1];1229 mix->master_vol[0] = mix->save_master_vol[0];1230 mix->master_vol[1] = mix->save_master_vol[1];1231 tumbler_reset_audio(chip);1232 if (mix->i2c.client && mix->i2c.init_client) {1233 if (mix->i2c.init_client(&mix->i2c) < 0)1234 dev_err(chip->card->dev, "tumbler_init_client error\n");1235 } else1236 dev_err(chip->card->dev, "tumbler: i2c is not initialized\n");1237 if (chip->model == PMAC_TUMBLER) {1238 tumbler_set_mono_volume(mix, &tumbler_pcm_vol_info);1239 tumbler_set_mono_volume(mix, &tumbler_bass_vol_info);1240 tumbler_set_mono_volume(mix, &tumbler_treble_vol_info);1241 tumbler_set_drc(mix);1242 } else {1243 snapper_set_mix_vol(mix, VOL_IDX_PCM);1244 snapper_set_mix_vol(mix, VOL_IDX_PCM2);1245 snapper_set_mix_vol(mix, VOL_IDX_ADC);1246 tumbler_set_mono_volume(mix, &snapper_bass_vol_info);1247 tumbler_set_mono_volume(mix, &snapper_treble_vol_info);1248 snapper_set_drc(mix);1249 snapper_set_capture_source(mix);1250 }1251 tumbler_set_master_volume(mix);1252 if (chip->update_automute)1253 chip->update_automute(chip, 0);1254 if (mix->headphone_irq >= 0) {1255 unsigned char val;1256 1257 enable_irq(mix->headphone_irq);1258 /* activate headphone status interrupts */1259 val = do_gpio_read(&mix->hp_detect);1260 do_gpio_write(&mix->hp_detect, val | 0x80);1261 }1262 if (mix->lineout_irq >= 0)1263 enable_irq(mix->lineout_irq);1264}1265#endif1266 1267/* initialize tumbler */1268static int tumbler_init(struct snd_pmac *chip)1269{1270 int irq;1271 struct pmac_tumbler *mix = chip->mixer_data;1272 1273 if (tumbler_find_device("audio-hw-reset",1274 "platform-do-hw-reset",1275 &mix->audio_reset, 0) < 0)1276 tumbler_find_device("hw-reset",1277 "platform-do-hw-reset",1278 &mix->audio_reset, 1);1279 if (tumbler_find_device("amp-mute",1280 "platform-do-amp-mute",1281 &mix->amp_mute, 0) < 0)1282 tumbler_find_device("amp-mute",1283 "platform-do-amp-mute",1284 &mix->amp_mute, 1);1285 if (tumbler_find_device("headphone-mute",1286 "platform-do-headphone-mute",1287 &mix->hp_mute, 0) < 0)1288 tumbler_find_device("headphone-mute",1289 "platform-do-headphone-mute",1290 &mix->hp_mute, 1);1291 if (tumbler_find_device("line-output-mute",1292 "platform-do-lineout-mute",1293 &mix->line_mute, 0) < 0)1294 tumbler_find_device("line-output-mute",1295 "platform-do-lineout-mute",1296 &mix->line_mute, 1);1297 irq = tumbler_find_device("headphone-detect",1298 NULL, &mix->hp_detect, 0);1299 if (irq <= 0)1300 irq = tumbler_find_device("headphone-detect",1301 NULL, &mix->hp_detect, 1);1302 if (irq <= 0)1303 irq = tumbler_find_device("keywest-gpio15",1304 NULL, &mix->hp_detect, 1);1305 mix->headphone_irq = irq;1306 irq = tumbler_find_device("line-output-detect",1307 NULL, &mix->line_detect, 0);1308 if (irq <= 0)1309 irq = tumbler_find_device("line-output-detect",1310 NULL, &mix->line_detect, 1);1311 if (IS_G4DA && irq <= 0)1312 irq = tumbler_find_device("keywest-gpio16",1313 NULL, &mix->line_detect, 1);1314 mix->lineout_irq = irq;1315 1316 tumbler_reset_audio(chip);1317 1318 return 0;1319}1320 1321static void tumbler_cleanup(struct snd_pmac *chip)1322{1323 struct pmac_tumbler *mix = chip->mixer_data;1324 if (! mix)1325 return;1326 1327 if (mix->headphone_irq >= 0)1328 free_irq(mix->headphone_irq, chip);1329 if (mix->lineout_irq >= 0)1330 free_irq(mix->lineout_irq, chip);1331 tumbler_gpio_free(&mix->audio_reset);1332 tumbler_gpio_free(&mix->amp_mute);1333 tumbler_gpio_free(&mix->hp_mute);1334 tumbler_gpio_free(&mix->hp_detect);1335 snd_pmac_keywest_cleanup(&mix->i2c);1336 kfree(mix);1337 chip->mixer_data = NULL;1338}1339 1340/* exported */1341int snd_pmac_tumbler_init(struct snd_pmac *chip)1342{1343 int i, err;1344 struct pmac_tumbler *mix;1345 const u32 *paddr;1346 struct device_node *tas_node, *np;1347 char *chipname;1348 1349 request_module("i2c-powermac");1350 1351 mix = kzalloc(sizeof(*mix), GFP_KERNEL);1352 if (! mix)1353 return -ENOMEM;1354 mix->headphone_irq = -1;1355 1356 chip->mixer_data = mix;1357 chip->mixer_free = tumbler_cleanup;1358 mix->anded_reset = 0;1359 mix->reset_on_sleep = 1;1360 1361 for_each_child_of_node(chip->node, np) {1362 if (of_node_name_eq(np, "sound")) {1363 if (of_property_read_bool(np, "has-anded-reset"))1364 mix->anded_reset = 1;1365 if (of_property_present(np, "layout-id"))1366 mix->reset_on_sleep = 0;1367 of_node_put(np);1368 break;1369 }1370 }1371 err = tumbler_init(chip);1372 if (err < 0)1373 return err;1374 1375 /* set up TAS */1376 tas_node = of_find_node_by_name(NULL, "deq");1377 if (tas_node == NULL)1378 tas_node = of_find_node_by_name(NULL, "codec");1379 if (tas_node == NULL)1380 return -ENODEV;1381 1382 paddr = of_get_property(tas_node, "i2c-address", NULL);1383 if (paddr == NULL)1384 paddr = of_get_property(tas_node, "reg", NULL);1385 if (paddr)1386 mix->i2c.addr = (*paddr) >> 1;1387 else1388 mix->i2c.addr = TAS_I2C_ADDR;1389 of_node_put(tas_node);1390 1391 DBG("(I) TAS i2c address is: %x\n", mix->i2c.addr);1392 1393 if (chip->model == PMAC_TUMBLER) {1394 mix->i2c.init_client = tumbler_init_client;1395 mix->i2c.name = "TAS3001c";1396 chipname = "Tumbler";1397 } else {1398 mix->i2c.init_client = snapper_init_client;1399 mix->i2c.name = "TAS3004";1400 chipname = "Snapper";1401 }1402 1403 err = snd_pmac_keywest_init(&mix->i2c);1404 if (err < 0)1405 return err;1406 1407 /*1408 * build mixers1409 */1410 sprintf(chip->card->mixername, "PowerMac %s", chipname);1411 1412 if (chip->model == PMAC_TUMBLER) {1413 for (i = 0; i < ARRAY_SIZE(tumbler_mixers); i++) {1414 err = snd_ctl_add(chip->card, snd_ctl_new1(&tumbler_mixers[i], chip));1415 if (err < 0)1416 return err;1417 }1418 } else {1419 for (i = 0; i < ARRAY_SIZE(snapper_mixers); i++) {1420 err = snd_ctl_add(chip->card, snd_ctl_new1(&snapper_mixers[i], chip));1421 if (err < 0)1422 return err;1423 }1424 }1425 chip->master_sw_ctl = snd_ctl_new1(&tumbler_hp_sw, chip);1426 err = snd_ctl_add(chip->card, chip->master_sw_ctl);1427 if (err < 0)1428 return err;1429 chip->speaker_sw_ctl = snd_ctl_new1(&tumbler_speaker_sw, chip);1430 err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);1431 if (err < 0)1432 return err;1433 if (mix->line_mute.addr != 0) {1434 chip->lineout_sw_ctl = snd_ctl_new1(&tumbler_lineout_sw, chip);1435 err = snd_ctl_add(chip->card, chip->lineout_sw_ctl);1436 if (err < 0)1437 return err;1438 }1439 chip->drc_sw_ctl = snd_ctl_new1(&tumbler_drc_sw, chip);1440 err = snd_ctl_add(chip->card, chip->drc_sw_ctl);1441 if (err < 0)1442 return err;1443 1444 /* set initial DRC range to 60% */1445 if (chip->model == PMAC_TUMBLER)1446 mix->drc_range = (TAS3001_DRC_MAX * 6) / 10;1447 else1448 mix->drc_range = (TAS3004_DRC_MAX * 6) / 10;1449 mix->drc_enable = 1; /* will be changed later if AUTO_DRC is set */1450 if (chip->model == PMAC_TUMBLER)1451 tumbler_set_drc(mix);1452 else1453 snapper_set_drc(mix);1454 1455#ifdef CONFIG_PM1456 chip->suspend = tumbler_suspend;1457 chip->resume = tumbler_resume;1458#endif1459 1460 INIT_WORK(&device_change, device_change_handler);1461 device_change_chip = chip;1462 1463#ifdef PMAC_SUPPORT_AUTOMUTE1464 if (mix->headphone_irq >= 0 || mix->lineout_irq >= 0) {1465 err = snd_pmac_add_automute(chip);1466 if (err < 0)1467 return err;1468 }1469 chip->detect_headphone = tumbler_detect_headphone;1470 chip->update_automute = tumbler_update_automute;1471 tumbler_update_automute(chip, 0); /* update the status only */1472 1473 /* activate headphone status interrupts */1474 if (mix->headphone_irq >= 0) {1475 unsigned char val;1476 err = request_irq(mix->headphone_irq, headphone_intr, 0,1477 "Sound Headphone Detection", chip);1478 if (err < 0)1479 return 0;1480 /* activate headphone status interrupts */1481 val = do_gpio_read(&mix->hp_detect);1482 do_gpio_write(&mix->hp_detect, val | 0x80);1483 }1484 if (mix->lineout_irq >= 0) {1485 unsigned char val;1486 err = request_irq(mix->lineout_irq, headphone_intr, 0,1487 "Sound Lineout Detection", chip);1488 if (err < 0)1489 return 0;1490 /* activate headphone status interrupts */1491 val = do_gpio_read(&mix->line_detect);1492 do_gpio_write(&mix->line_detect, val | 0x80);1493 }1494#endif1495 1496 return 0;1497}1498