From 871480933a1c28f8a9fed4c4d34d06c439a7a422 Mon Sep 17 00:00:00 2001 From: Srikant Patnaik Date: Sun, 11 Jan 2015 12:28:04 +0530 Subject: Moved, renamed, and deleted files The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure. --- ANDROID_3.4.5/sound/pci/ice1712/Makefile | 12 - ANDROID_3.4.5/sound/pci/ice1712/ak4xxx.c | 196 -- ANDROID_3.4.5/sound/pci/ice1712/amp.c | 98 - ANDROID_3.4.5/sound/pci/ice1712/amp.h | 48 - ANDROID_3.4.5/sound/pci/ice1712/aureon.c | 2308 ------------------- ANDROID_3.4.5/sound/pci/ice1712/aureon.h | 65 - ANDROID_3.4.5/sound/pci/ice1712/delta.c | 881 ------- ANDROID_3.4.5/sound/pci/ice1712/delta.h | 166 -- ANDROID_3.4.5/sound/pci/ice1712/envy24ht.h | 220 -- ANDROID_3.4.5/sound/pci/ice1712/ews.c | 1087 --------- ANDROID_3.4.5/sound/pci/ice1712/ews.h | 86 - ANDROID_3.4.5/sound/pci/ice1712/hoontech.c | 360 --- ANDROID_3.4.5/sound/pci/ice1712/hoontech.h | 77 - ANDROID_3.4.5/sound/pci/ice1712/ice1712.c | 2824 ----------------------- ANDROID_3.4.5/sound/pci/ice1712/ice1712.h | 531 ----- ANDROID_3.4.5/sound/pci/ice1712/ice1724.c | 2898 ------------------------ ANDROID_3.4.5/sound/pci/ice1712/juli.c | 700 ------ ANDROID_3.4.5/sound/pci/ice1712/juli.h | 10 - ANDROID_3.4.5/sound/pci/ice1712/maya44.c | 779 ------- ANDROID_3.4.5/sound/pci/ice1712/maya44.h | 10 - ANDROID_3.4.5/sound/pci/ice1712/phase.c | 975 -------- ANDROID_3.4.5/sound/pci/ice1712/phase.h | 53 - ANDROID_3.4.5/sound/pci/ice1712/pontis.c | 836 ------- ANDROID_3.4.5/sound/pci/ice1712/pontis.h | 33 - ANDROID_3.4.5/sound/pci/ice1712/prodigy192.c | 822 ------- ANDROID_3.4.5/sound/pci/ice1712/prodigy192.h | 19 - ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.c | 1236 ---------- ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.h | 38 - ANDROID_3.4.5/sound/pci/ice1712/quartet.c | 1130 --------- ANDROID_3.4.5/sound/pci/ice1712/quartet.h | 10 - ANDROID_3.4.5/sound/pci/ice1712/revo.c | 633 ------ ANDROID_3.4.5/sound/pci/ice1712/revo.h | 55 - ANDROID_3.4.5/sound/pci/ice1712/se.c | 774 ------- ANDROID_3.4.5/sound/pci/ice1712/se.h | 15 - ANDROID_3.4.5/sound/pci/ice1712/stac946x.h | 25 - ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.c | 139 -- ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.h | 41 - ANDROID_3.4.5/sound/pci/ice1712/wtm.c | 517 ----- ANDROID_3.4.5/sound/pci/ice1712/wtm.h | 20 - 39 files changed, 20727 deletions(-) delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/Makefile delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/ak4xxx.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/amp.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/amp.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/aureon.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/aureon.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/delta.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/delta.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/envy24ht.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/ews.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/ews.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/hoontech.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/hoontech.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/ice1712.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/ice1712.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/ice1724.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/juli.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/juli.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/maya44.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/maya44.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/phase.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/phase.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/pontis.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/pontis.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/prodigy192.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/prodigy192.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/quartet.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/quartet.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/revo.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/revo.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/se.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/se.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/stac946x.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.h delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/wtm.c delete mode 100644 ANDROID_3.4.5/sound/pci/ice1712/wtm.h (limited to 'ANDROID_3.4.5/sound/pci/ice1712') diff --git a/ANDROID_3.4.5/sound/pci/ice1712/Makefile b/ANDROID_3.4.5/sound/pci/ice1712/Makefile deleted file mode 100644 index f7ce33f0..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela -# - -snd-ice17xx-ak4xxx-objs := ak4xxx.o -snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o -snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o maya44.o quartet.o - -# Toplevel Module Dependency -obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o -obj-$(CONFIG_SND_ICE1724) += snd-ice1724.o snd-ice17xx-ak4xxx.o diff --git a/ANDROID_3.4.5/sound/pci/ice1712/ak4xxx.c b/ANDROID_3.4.5/sound/pci/ice1712/ak4xxx.c deleted file mode 100644 index 3981823f..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/ak4xxx.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * ALSA driver for ICEnsemble ICE1712 (Envy24) - * - * AK4524 / AK4528 / AK4529 / AK4355 / AK4381 interface - * - * Copyright (c) 2000 Jaroslav Kysela - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "ice1712.h" - -MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("ICEnsemble ICE17xx <-> AK4xxx AD/DA chip interface"); -MODULE_LICENSE("GPL"); - -static void snd_ice1712_akm4xxx_lock(struct snd_akm4xxx *ak, int chip) -{ - struct snd_ice1712 *ice = ak->private_data[0]; - - snd_ice1712_save_gpio_status(ice); -} - -static void snd_ice1712_akm4xxx_unlock(struct snd_akm4xxx *ak, int chip) -{ - struct snd_ice1712 *ice = ak->private_data[0]; - - snd_ice1712_restore_gpio_status(ice); -} - -/* - * write AK4xxx register - */ -static void snd_ice1712_akm4xxx_write(struct snd_akm4xxx *ak, int chip, - unsigned char addr, unsigned char data) -{ - unsigned int tmp; - int idx; - unsigned int addrdata; - struct snd_ak4xxx_private *priv = (void *)ak->private_value[0]; - struct snd_ice1712 *ice = ak->private_data[0]; - - if (snd_BUG_ON(chip < 0 || chip >= 4)) - return; - - tmp = snd_ice1712_gpio_read(ice); - tmp |= priv->add_flags; - tmp &= ~priv->mask_flags; - if (priv->cs_mask == priv->cs_addr) { - if (priv->cif) { - tmp |= priv->cs_mask; /* start without chip select */ - } else { - tmp &= ~priv->cs_mask; /* chip select low */ - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - } - } else { - /* doesn't handle cf=1 yet */ - tmp &= ~priv->cs_mask; - tmp |= priv->cs_addr; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - } - - /* build I2C address + data byte */ - addrdata = (priv->caddr << 6) | 0x20 | (addr & 0x1f); - addrdata = (addrdata << 8) | data; - for (idx = 15; idx >= 0; idx--) { - /* drop clock */ - tmp &= ~priv->clk_mask; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - /* set data */ - if (addrdata & (1 << idx)) - tmp |= priv->data_mask; - else - tmp &= ~priv->data_mask; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - /* raise clock */ - tmp |= priv->clk_mask; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - } - - if (priv->cs_mask == priv->cs_addr) { - if (priv->cif) { - /* assert a cs pulse to trigger */ - tmp &= ~priv->cs_mask; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - } - tmp |= priv->cs_mask; /* chip select high to trigger */ - } else { - tmp &= ~priv->cs_mask; - tmp |= priv->cs_none; /* deselect address */ - } - snd_ice1712_gpio_write(ice, tmp); - udelay(1); -} - -/* - * initialize the struct snd_akm4xxx record with the template - */ -int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak, const struct snd_akm4xxx *temp, - const struct snd_ak4xxx_private *_priv, struct snd_ice1712 *ice) -{ - struct snd_ak4xxx_private *priv; - - if (_priv != NULL) { - priv = kmalloc(sizeof(*priv), GFP_KERNEL); - if (priv == NULL) - return -ENOMEM; - *priv = *_priv; - } else { - priv = NULL; - } - *ak = *temp; - ak->card = ice->card; - ak->private_value[0] = (unsigned long)priv; - ak->private_data[0] = ice; - if (ak->ops.lock == NULL) - ak->ops.lock = snd_ice1712_akm4xxx_lock; - if (ak->ops.unlock == NULL) - ak->ops.unlock = snd_ice1712_akm4xxx_unlock; - if (ak->ops.write == NULL) - ak->ops.write = snd_ice1712_akm4xxx_write; - snd_akm4xxx_init(ak); - return 0; -} - -void snd_ice1712_akm4xxx_free(struct snd_ice1712 *ice) -{ - unsigned int akidx; - if (ice->akm == NULL) - return; - for (akidx = 0; akidx < ice->akm_codecs; akidx++) { - struct snd_akm4xxx *ak = &ice->akm[akidx]; - kfree((void*)ak->private_value[0]); - } - kfree(ice->akm); -} - -/* - * build AK4xxx controls - */ -int snd_ice1712_akm4xxx_build_controls(struct snd_ice1712 *ice) -{ - unsigned int akidx; - int err; - - for (akidx = 0; akidx < ice->akm_codecs; akidx++) { - struct snd_akm4xxx *ak = &ice->akm[akidx]; - err = snd_akm4xxx_build_controls(ak); - if (err < 0) - return err; - } - return 0; -} - -static int __init alsa_ice1712_akm4xxx_module_init(void) -{ - return 0; -} - -static void __exit alsa_ice1712_akm4xxx_module_exit(void) -{ -} - -module_init(alsa_ice1712_akm4xxx_module_init) -module_exit(alsa_ice1712_akm4xxx_module_exit) - -EXPORT_SYMBOL(snd_ice1712_akm4xxx_init); -EXPORT_SYMBOL(snd_ice1712_akm4xxx_free); -EXPORT_SYMBOL(snd_ice1712_akm4xxx_build_controls); diff --git a/ANDROID_3.4.5/sound/pci/ice1712/amp.c b/ANDROID_3.4.5/sound/pci/ice1712/amp.c deleted file mode 100644 index e525da26..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/amp.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * ALSA driver for ICEnsemble VT1724 (Envy24HT) - * - * Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000 - * - * Copyright (c) 2000 Jaroslav Kysela - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "amp.h" - -static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val) -{ - unsigned short cval; - cval = (reg << 9) | val; - snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff); -} - -static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice) -{ - static const unsigned short wm_inits[] = { - WM_ATTEN_L, 0x0000, /* 0 db */ - WM_ATTEN_R, 0x0000, /* 0 db */ - WM_DAC_CTRL, 0x0008, /* 24bit I2S */ - WM_INT_CTRL, 0x0001, /* 24bit I2S */ - }; - - unsigned int i; - - /* only use basic functionality for now */ - - /* VT1616 6ch codec connected to PSDOUT0 using packed mode */ - ice->num_total_dacs = 6; - ice->num_total_adcs = 2; - - /* Chaintech AV-710 has another WM8728 codec connected to PSDOUT4 - (shared with the SPDIF output). Mixer control for this codec - is not yet supported. */ - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AV710) { - for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2) - wm_put(ice, wm_inits[i], wm_inits[i+1]); - } - - return 0; -} - -static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice) -{ - if (ice->ac97) - /* we use pins 39 and 41 of the VT1616 for left and right - read outputs */ - snd_ac97_write_cache(ice->ac97, 0x5a, - snd_ac97_read(ice->ac97, 0x5a) & ~0x8000); - return 0; -} - - -/* entry point */ -struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_AV710, - .name = "Chaintech AV-710", - .model = "av710", - .chip_init = snd_vt1724_amp_init, - .build_controls = snd_vt1724_amp_add_controls, - }, - { - .subvendor = VT1724_SUBDEVICE_AUDIO2000, - .name = "AMP Ltd AUDIO2000", - .model = "amp2000", - .chip_init = snd_vt1724_amp_init, - .build_controls = snd_vt1724_amp_add_controls, - }, - { } /* terminator */ -}; - diff --git a/ANDROID_3.4.5/sound/pci/ice1712/amp.h b/ANDROID_3.4.5/sound/pci/ice1712/amp.h deleted file mode 100644 index bf81d30d..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/amp.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef __SOUND_AMP_H -#define __SOUND_AMP_H - -/* - * ALSA driver for VIA VT1724 (Envy24HT) - * - * Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000 - * - * Copyright (c) 2000 Jaroslav Kysela - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define AMP_AUDIO2000_DEVICE_DESC "{AMP Ltd,AUDIO2000},"\ - "{Chaintech,AV-710}," - -#if 0 -#define VT1724_SUBDEVICE_AUDIO2000 0x12142417 /* Advanced Micro Peripherals Ltd AUDIO2000 */ -#else -#define VT1724_SUBDEVICE_AUDIO2000 0x00030003 /* a dummy ID for AMP Audio2000 */ -#endif -#define VT1724_SUBDEVICE_AV710 0x12142417 /* AV710 - the same ID with Audio2000! */ - -/* WM8728 on I2C for AV710 */ -#define WM_DEV 0x36 - -#define WM_ATTEN_L 0x00 -#define WM_ATTEN_R 0x01 -#define WM_DAC_CTRL 0x02 -#define WM_INT_CTRL 0x03 - -extern struct snd_ice1712_card_info snd_vt1724_amp_cards[]; - - -#endif /* __SOUND_AMP_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/aureon.c b/ANDROID_3.4.5/sound/pci/ice1712/aureon.c deleted file mode 100644 index 3e4f8c12..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/aureon.c +++ /dev/null @@ -1,2308 +0,0 @@ -/* - * ALSA driver for ICEnsemble VT1724 (Envy24HT) - * - * Lowlevel functions for Terratec Aureon cards - * - * Copyright (c) 2003 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * NOTES: - * - * - we reuse the struct snd_akm4xxx record for storing the wm8770 codec data. - * both wm and akm codecs are pretty similar, so we can integrate - * both controls in the future, once if wm codecs are reused in - * many boards. - * - * - DAC digital volumes are not implemented in the mixer. - * if they show better response than DAC analog volumes, we can use them - * instead. - * - * Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards - * Copyright (c) 2003 Dimitromanolakis Apostolos - * - * version 0.82: Stable / not all features work yet (no communication with AC97 secondary) - * added 64x/128x oversampling switch (should be 64x only for 96khz) - * fixed some recording labels (still need to check the rest) - * recording is working probably thanks to correct wm8770 initialization - * - * version 0.5: Initial release: - * working: analog output, mixer, headphone amplifier switch - * not working: prety much everything else, at least i could verify that - * we have no digital output, no capture, pretty bad clicks and poops - * on mixer switch and other coll stuff. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "aureon.h" -#include - -/* AC97 register cache for Aureon */ -struct aureon_spec { - unsigned short stac9744[64]; - unsigned int cs8415_mux; - unsigned short master[2]; - unsigned short vol[8]; - unsigned char pca9554_out; -}; - -/* WM8770 registers */ -#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */ -#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */ -#define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */ -#define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */ -#define WM_PHASE_SWAP 0x12 /* DAC phase */ -#define WM_DAC_CTRL1 0x13 /* DAC control bits */ -#define WM_MUTE 0x14 /* mute controls */ -#define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */ -#define WM_INT_CTRL 0x16 /* interface control */ -#define WM_MASTER 0x17 /* master clock and mode */ -#define WM_POWERDOWN 0x18 /* power-down controls */ -#define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */ -#define WM_ADC_MUX 0x1b /* input MUX */ -#define WM_OUT_MUX1 0x1c /* output MUX */ -#define WM_OUT_MUX2 0x1e /* output MUX */ -#define WM_RESET 0x1f /* software reset */ - -/* CS8415A registers */ -#define CS8415_CTRL1 0x01 -#define CS8415_CTRL2 0x02 -#define CS8415_QSUB 0x14 -#define CS8415_RATIO 0x1E -#define CS8415_C_BUFFER 0x20 -#define CS8415_ID 0x7F - -/* PCA9554 registers */ -#define PCA9554_DEV 0x40 /* I2C device address */ -#define PCA9554_IN 0x00 /* input port */ -#define PCA9554_OUT 0x01 /* output port */ -#define PCA9554_INVERT 0x02 /* input invert */ -#define PCA9554_DIR 0x03 /* port directions */ - -/* - * Aureon Universe additional controls using PCA9554 - */ - -/* - * Send data to pca9554 - */ -static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg, - unsigned char data) -{ - unsigned int tmp; - int i, j; - unsigned char dev = PCA9554_DEV; /* ID 0100000, write */ - unsigned char val = 0; - - tmp = snd_ice1712_gpio_read(ice); - - snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK| - AUREON_WM_RW|AUREON_WM_CS| - AUREON_CS8415_CS)); - tmp |= AUREON_WM_RW; - tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */ - - tmp &= ~AUREON_SPI_MOSI; - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(50); - - /* - * send i2c stop condition and start condition - * to obtain sane state - */ - tmp |= AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(50); - tmp |= AUREON_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(100); - tmp &= ~AUREON_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(50); - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(100); - /* - * send device address, command and value, - * skipping ack cycles in between - */ - for (j = 0; j < 3; j++) { - switch (j) { - case 0: - val = dev; - break; - case 1: - val = reg; - break; - case 2: - val = data; - break; - } - for (i = 7; i >= 0; i--) { - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - if (val & (1 << i)) - tmp |= AUREON_SPI_MOSI; - else - tmp &= ~AUREON_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - tmp |= AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - } - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - tmp |= AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - } - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - tmp &= ~AUREON_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - tmp |= AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(50); - tmp |= AUREON_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(100); -} - -static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"}; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct aureon_spec *spec = ice->spec; - ucontrol->value.enumerated.item[0] = spec->pca9554_out; - return 0; -} - -static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct aureon_spec *spec = ice->spec; - unsigned char oval, nval; - int change; - - nval = ucontrol->value.enumerated.item[0]; - if (nval >= 3) - return -EINVAL; - snd_ice1712_save_gpio_status(ice); - oval = spec->pca9554_out; - change = (oval != nval); - if (change) { - aureon_pca9554_write(ice, PCA9554_OUT, nval); - spec->pca9554_out = nval; - } - snd_ice1712_restore_gpio_status(ice); - return change; -} - - -static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, - unsigned short val) -{ - struct aureon_spec *spec = ice->spec; - unsigned int tmp; - - /* Send address to XILINX chip */ - tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F); - snd_ice1712_gpio_write(ice, tmp); - udelay(10); - tmp |= AUREON_AC97_ADDR; - snd_ice1712_gpio_write(ice, tmp); - udelay(10); - tmp &= ~AUREON_AC97_ADDR; - snd_ice1712_gpio_write(ice, tmp); - udelay(10); - - /* Send low-order byte to XILINX chip */ - tmp &= ~AUREON_AC97_DATA_MASK; - tmp |= val & AUREON_AC97_DATA_MASK; - snd_ice1712_gpio_write(ice, tmp); - udelay(10); - tmp |= AUREON_AC97_DATA_LOW; - snd_ice1712_gpio_write(ice, tmp); - udelay(10); - tmp &= ~AUREON_AC97_DATA_LOW; - snd_ice1712_gpio_write(ice, tmp); - udelay(10); - - /* Send high-order byte to XILINX chip */ - tmp &= ~AUREON_AC97_DATA_MASK; - tmp |= (val >> 8) & AUREON_AC97_DATA_MASK; - - snd_ice1712_gpio_write(ice, tmp); - udelay(10); - tmp |= AUREON_AC97_DATA_HIGH; - snd_ice1712_gpio_write(ice, tmp); - udelay(10); - tmp &= ~AUREON_AC97_DATA_HIGH; - snd_ice1712_gpio_write(ice, tmp); - udelay(10); - - /* Instruct XILINX chip to parse the data to the STAC9744 chip */ - tmp |= AUREON_AC97_COMMIT; - snd_ice1712_gpio_write(ice, tmp); - udelay(10); - tmp &= ~AUREON_AC97_COMMIT; - snd_ice1712_gpio_write(ice, tmp); - udelay(10); - - /* Store the data in out private buffer */ - spec->stac9744[(reg & 0x7F) >> 1] = val; -} - -static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg) -{ - struct aureon_spec *spec = ice->spec; - return spec->stac9744[(reg & 0x7F) >> 1]; -} - -/* - * Initialize STAC9744 chip - */ -static int aureon_ac97_init(struct snd_ice1712 *ice) -{ - struct aureon_spec *spec = ice->spec; - int i; - static const unsigned short ac97_defaults[] = { - 0x00, 0x9640, - 0x02, 0x8000, - 0x04, 0x8000, - 0x06, 0x8000, - 0x0C, 0x8008, - 0x0E, 0x8008, - 0x10, 0x8808, - 0x12, 0x8808, - 0x14, 0x8808, - 0x16, 0x8808, - 0x18, 0x8808, - 0x1C, 0x8000, - 0x26, 0x000F, - 0x28, 0x0201, - 0x2C, 0xBB80, - 0x32, 0xBB80, - 0x7C, 0x8384, - 0x7E, 0x7644, - (unsigned short)-1 - }; - unsigned int tmp; - - /* Cold reset */ - tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK; - snd_ice1712_gpio_write(ice, tmp); - udelay(3); - - tmp &= ~AUREON_AC97_RESET; - snd_ice1712_gpio_write(ice, tmp); - udelay(3); - - tmp |= AUREON_AC97_RESET; - snd_ice1712_gpio_write(ice, tmp); - udelay(3); - - memset(&spec->stac9744, 0, sizeof(spec->stac9744)); - for (i = 0; ac97_defaults[i] != (unsigned short)-1; i += 2) - spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1]; - - /* Unmute AC'97 master volume permanently - muting is done by WM8770 */ - aureon_ac97_write(ice, AC97_MASTER, 0x0000); - - return 0; -} - -#define AUREON_AC97_STEREO 0x80 - -/* - * AC'97 volume controls - */ -static int aureon_ac97_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 31; - return 0; -} - -static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short vol; - - mutex_lock(&ice->gpio_mutex); - - vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F); - ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F); - if (kcontrol->private_value & AUREON_AC97_STEREO) - ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F); - - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short ovol, nvol; - int change; - - snd_ice1712_save_gpio_status(ice); - - ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F); - nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F; - if (kcontrol->private_value & AUREON_AC97_STEREO) - nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00; - nvol |= ovol & ~0x1F1F; - - change = (ovol != nvol); - if (change) - aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol); - - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* - * AC'97 mute controls - */ -#define aureon_ac97_mute_info snd_ctl_boolean_mono_info - -static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - mutex_lock(&ice->gpio_mutex); - - ucontrol->value.integer.value[0] = aureon_ac97_read(ice, - kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1; - - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short ovol, nvol; - int change; - - snd_ice1712_save_gpio_status(ice); - - ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F); - nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~0x8000); - - change = (ovol != nvol); - if (change) - aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol); - - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* - * AC'97 mute controls - */ -#define aureon_ac97_micboost_info snd_ctl_boolean_mono_info - -static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - mutex_lock(&ice->gpio_mutex); - - ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1; - - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short ovol, nvol; - int change; - - snd_ice1712_save_gpio_status(ice); - - ovol = aureon_ac97_read(ice, AC97_MIC); - nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020); - - change = (ovol != nvol); - if (change) - aureon_ac97_write(ice, AC97_MIC, nvol); - - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* - * write data in the SPI mode - */ -static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits) -{ - unsigned int tmp; - int i; - unsigned int mosi, clk; - - tmp = snd_ice1712_gpio_read(ice); - - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT || - ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) { - snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS)); - mosi = PRODIGY_SPI_MOSI; - clk = PRODIGY_SPI_CLK; - } else { - snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK| - AUREON_WM_CS|AUREON_CS8415_CS)); - mosi = AUREON_SPI_MOSI; - clk = AUREON_SPI_CLK; - - tmp |= AUREON_WM_RW; - } - - tmp &= ~cs; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - - for (i = bits - 1; i >= 0; i--) { - tmp &= ~clk; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - if (data & (1 << i)) - tmp |= mosi; - else - tmp &= ~mosi; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - tmp |= clk; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - } - - tmp &= ~clk; - tmp |= cs; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - tmp |= clk; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); -} - -/* - * Read data in SPI mode - */ -static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, - unsigned int data, int bits, unsigned char *buffer, int size) -{ - int i, j; - unsigned int tmp; - - tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS; - snd_ice1712_gpio_write(ice, tmp); - tmp &= ~cs; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - - for (i = bits-1; i >= 0; i--) { - if (data & (1 << i)) - tmp |= AUREON_SPI_MOSI; - else - tmp &= ~AUREON_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - - tmp |= AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - } - - for (j = 0; j < size; j++) { - unsigned char outdata = 0; - for (i = 7; i >= 0; i--) { - tmp = snd_ice1712_gpio_read(ice); - outdata <<= 1; - outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0; - udelay(1); - - tmp |= AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - } - buffer[j] = outdata; - } - - tmp |= cs; - snd_ice1712_gpio_write(ice, tmp); -} - -static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg) -{ - unsigned char val; - aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16); - aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1); - return val; -} - -static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg, - unsigned char *buffer, int size) -{ - aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16); - aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size); -} - -static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg, - unsigned char val) -{ - aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24); -} - -/* - * get the current register value of WM codec - */ -static unsigned short wm_get(struct snd_ice1712 *ice, int reg) -{ - reg <<= 1; - return ((unsigned short)ice->akm[0].images[reg] << 8) | - ice->akm[0].images[reg + 1]; -} - -/* - * set the register value of WM codec - */ -static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val) -{ - aureon_spi_write(ice, - ((ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT || - ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) ? - PRODIGY_WM_CS : AUREON_WM_CS), - (reg << 9) | (val & 0x1ff), 16); -} - -/* - * set the register value of WM codec and remember it - */ -static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val) -{ - wm_put_nocache(ice, reg, val); - reg <<= 1; - ice->akm[0].images[reg] = val >> 8; - ice->akm[0].images[reg + 1] = val; -} - -/* - */ -#define aureon_mono_bool_info snd_ctl_boolean_mono_info - -/* - * AC'97 master playback mute controls (Mute on WM8770 chip) - */ -#define aureon_ac97_mmute_info snd_ctl_boolean_mono_info - -static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - mutex_lock(&ice->gpio_mutex); - - ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01; - - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short ovol, nvol; - int change; - - snd_ice1712_save_gpio_status(ice); - - ovol = wm_get(ice, WM_OUT_MUX1); - nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00); - change = (ovol != nvol); - if (change) - wm_put(ice, WM_OUT_MUX1, nvol); - - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -10000, 100, 1); -static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); -static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0); - -#define WM_VOL_MAX 100 -#define WM_VOL_CNT 101 /* 0dB .. -100dB */ -#define WM_VOL_MUTE 0x8000 - -static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master) -{ - unsigned char nvol; - - if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) { - nvol = 0; - } else { - nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) / - WM_VOL_MAX; - nvol += 0x1b; - } - - wm_put(ice, index, nvol); - wm_put_nocache(ice, index, 0x180 | nvol); -} - -/* - * DAC mute control - */ -#define wm_pcm_mute_info snd_ctl_boolean_mono_info - -static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - mutex_lock(&ice->gpio_mutex); - ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short nval, oval; - int change; - - snd_ice1712_save_gpio_status(ice); - oval = wm_get(ice, WM_MUTE); - nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10); - change = (oval != nval); - if (change) - wm_put(ice, WM_MUTE, nval); - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* - * Master volume attenuation mixer control - */ -static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = WM_VOL_MAX; - return 0; -} - -static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct aureon_spec *spec = ice->spec; - int i; - for (i = 0; i < 2; i++) - ucontrol->value.integer.value[i] = - spec->master[i] & ~WM_VOL_MUTE; - return 0; -} - -static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct aureon_spec *spec = ice->spec; - int ch, change = 0; - - snd_ice1712_save_gpio_status(ice); - for (ch = 0; ch < 2; ch++) { - unsigned int vol = ucontrol->value.integer.value[ch]; - if (vol > WM_VOL_MAX) - vol = WM_VOL_MAX; - vol |= spec->master[ch] & WM_VOL_MUTE; - if (vol != spec->master[ch]) { - int dac; - spec->master[ch] = vol; - for (dac = 0; dac < ice->num_total_dacs; dac += 2) - wm_set_vol(ice, WM_DAC_ATTEN + dac + ch, - spec->vol[dac + ch], - spec->master[ch]); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - return change; -} - -/* - * DAC volume attenuation mixer control - */ -static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - int voices = kcontrol->private_value >> 8; - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = voices; - uinfo->value.integer.min = 0; /* mute (-101dB) */ - uinfo->value.integer.max = WM_VOL_MAX; /* 0dB */ - return 0; -} - -static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct aureon_spec *spec = ice->spec; - int i, ofs, voices; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xff; - for (i = 0; i < voices; i++) - ucontrol->value.integer.value[i] = - spec->vol[ofs+i] & ~WM_VOL_MUTE; - return 0; -} - -static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct aureon_spec *spec = ice->spec; - int i, idx, ofs, voices; - int change = 0; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xff; - snd_ice1712_save_gpio_status(ice); - for (i = 0; i < voices; i++) { - unsigned int vol = ucontrol->value.integer.value[i]; - if (vol > WM_VOL_MAX) - vol = WM_VOL_MAX; - vol |= spec->vol[ofs+i] & WM_VOL_MUTE; - if (vol != spec->vol[ofs+i]) { - spec->vol[ofs+i] = vol; - idx = WM_DAC_ATTEN + ofs + i; - wm_set_vol(ice, idx, spec->vol[ofs + i], - spec->master[i]); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - return change; -} - -/* - * WM8770 mute control - */ -static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = kcontrol->private_value >> 8; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct aureon_spec *spec = ice->spec; - int voices, ofs, i; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xFF; - - for (i = 0; i < voices; i++) - ucontrol->value.integer.value[i] = - (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1; - return 0; -} - -static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct aureon_spec *spec = ice->spec; - int change = 0, voices, ofs, i; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xFF; - - snd_ice1712_save_gpio_status(ice); - for (i = 0; i < voices; i++) { - int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1; - if (ucontrol->value.integer.value[i] != val) { - spec->vol[ofs + i] &= ~WM_VOL_MUTE; - spec->vol[ofs + i] |= - ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; - wm_set_vol(ice, ofs + i, spec->vol[ofs + i], - spec->master[i]); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* - * WM8770 master mute control - */ -#define wm_master_mute_info snd_ctl_boolean_stereo_info - -static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct aureon_spec *spec = ice->spec; - - ucontrol->value.integer.value[0] = - (spec->master[0] & WM_VOL_MUTE) ? 0 : 1; - ucontrol->value.integer.value[1] = - (spec->master[1] & WM_VOL_MUTE) ? 0 : 1; - return 0; -} - -static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct aureon_spec *spec = ice->spec; - int change = 0, i; - - snd_ice1712_save_gpio_status(ice); - for (i = 0; i < 2; i++) { - int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1; - if (ucontrol->value.integer.value[i] != val) { - int dac; - spec->master[i] &= ~WM_VOL_MUTE; - spec->master[i] |= - ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; - for (dac = 0; dac < ice->num_total_dacs; dac += 2) - wm_set_vol(ice, WM_DAC_ATTEN + dac + i, - spec->vol[dac + i], - spec->master[i]); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* digital master volume */ -#define PCM_0dB 0xff -#define PCM_RES 128 /* -64dB */ -#define PCM_MIN (PCM_0dB - PCM_RES) -static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; /* mute (-64dB) */ - uinfo->value.integer.max = PCM_RES; /* 0dB */ - return 0; -} - -static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short val; - - mutex_lock(&ice->gpio_mutex); - val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; - val = val > PCM_MIN ? (val - PCM_MIN) : 0; - ucontrol->value.integer.value[0] = val; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short ovol, nvol; - int change = 0; - - nvol = ucontrol->value.integer.value[0]; - if (nvol > PCM_RES) - return -EINVAL; - snd_ice1712_save_gpio_status(ice); - nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff; - ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; - if (ovol != nvol) { - wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */ - wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */ - change = 1; - } - snd_ice1712_restore_gpio_status(ice); - return change; -} - -/* - * ADC mute control - */ -#define wm_adc_mute_info snd_ctl_boolean_stereo_info - -static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short val; - int i; - - mutex_lock(&ice->gpio_mutex); - for (i = 0; i < 2; i++) { - val = wm_get(ice, WM_ADC_GAIN + i); - ucontrol->value.integer.value[i] = ~val>>5 & 0x1; - } - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short new, old; - int i, change = 0; - - snd_ice1712_save_gpio_status(ice); - for (i = 0; i < 2; i++) { - old = wm_get(ice, WM_ADC_GAIN + i); - new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20); - if (new != old) { - wm_put(ice, WM_ADC_GAIN + i, new); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* - * ADC gain mixer control - */ -static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; /* -12dB */ - uinfo->value.integer.max = 0x1f; /* 19dB */ - return 0; -} - -static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int i, idx; - unsigned short vol; - - mutex_lock(&ice->gpio_mutex); - for (i = 0; i < 2; i++) { - idx = WM_ADC_GAIN + i; - vol = wm_get(ice, idx) & 0x1f; - ucontrol->value.integer.value[i] = vol; - } - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int i, idx; - unsigned short ovol, nvol; - int change = 0; - - snd_ice1712_save_gpio_status(ice); - for (i = 0; i < 2; i++) { - idx = WM_ADC_GAIN + i; - nvol = ucontrol->value.integer.value[i] & 0x1f; - ovol = wm_get(ice, idx); - if ((ovol & 0x1f) != nvol) { - wm_put(ice, idx, nvol | (ovol & ~0x1f)); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - return change; -} - -/* - * ADC input mux mixer control - */ -static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - static const char * const texts[] = { - "CD", /* AIN1 */ - "Aux", /* AIN2 */ - "Line", /* AIN3 */ - "Mic", /* AIN4 */ - "AC97" /* AIN5 */ - }; - static const char * const universe_texts[] = { - "Aux1", /* AIN1 */ - "CD", /* AIN2 */ - "Phono", /* AIN3 */ - "Line", /* AIN4 */ - "Aux2", /* AIN5 */ - "Mic", /* AIN6 */ - "Aux3", /* AIN7 */ - "AC97" /* AIN8 */ - }; - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 2; - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) { - uinfo->value.enumerated.items = 8; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]); - } else { - uinfo->value.enumerated.items = 5; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - } - return 0; -} - -static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short val; - - mutex_lock(&ice->gpio_mutex); - val = wm_get(ice, WM_ADC_MUX); - ucontrol->value.enumerated.item[0] = val & 7; - ucontrol->value.enumerated.item[1] = (val >> 4) & 7; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short oval, nval; - int change; - - snd_ice1712_save_gpio_status(ice); - oval = wm_get(ice, WM_ADC_MUX); - nval = oval & ~0x77; - nval |= ucontrol->value.enumerated.item[0] & 7; - nval |= (ucontrol->value.enumerated.item[1] & 7) << 4; - change = (oval != nval); - if (change) - wm_put(ice, WM_ADC_MUX, nval); - snd_ice1712_restore_gpio_status(ice); - return change; -} - -/* - * CS8415 Input mux - */ -static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - static const char * const aureon_texts[] = { - "CD", /* RXP0 */ - "Optical" /* RXP1 */ - }; - static const char * const prodigy_texts[] = { - "CD", - "Coax" - }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71) - strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]); - else - strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]); - return 0; -} - -static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct aureon_spec *spec = ice->spec; - - /* snd_ice1712_save_gpio_status(ice); */ - /* val = aureon_cs8415_get(ice, CS8415_CTRL2); */ - ucontrol->value.enumerated.item[0] = spec->cs8415_mux; - /* snd_ice1712_restore_gpio_status(ice); */ - return 0; -} - -static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct aureon_spec *spec = ice->spec; - unsigned short oval, nval; - int change; - - snd_ice1712_save_gpio_status(ice); - oval = aureon_cs8415_get(ice, CS8415_CTRL2); - nval = oval & ~0x07; - nval |= ucontrol->value.enumerated.item[0] & 7; - change = (oval != nval); - if (change) - aureon_cs8415_put(ice, CS8415_CTRL2, nval); - snd_ice1712_restore_gpio_status(ice); - spec->cs8415_mux = ucontrol->value.enumerated.item[0]; - return change; -} - -static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 192000; - return 0; -} - -static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char ratio; - ratio = aureon_cs8415_get(ice, CS8415_RATIO); - ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750); - return 0; -} - -/* - * CS8415A Mute - */ -#define aureon_cs8415_mute_info snd_ctl_boolean_mono_info - -static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - snd_ice1712_save_gpio_status(ice); - ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1; - snd_ice1712_restore_gpio_status(ice); - return 0; -} - -static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char oval, nval; - int change; - snd_ice1712_save_gpio_status(ice); - oval = aureon_cs8415_get(ice, CS8415_CTRL1); - if (ucontrol->value.integer.value[0]) - nval = oval & ~0x20; - else - nval = oval | 0x20; - change = (oval != nval); - if (change) - aureon_cs8415_put(ice, CS8415_CTRL1, nval); - snd_ice1712_restore_gpio_status(ice); - return change; -} - -/* - * CS8415A Q-Sub info - */ -static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = 10; - return 0; -} - -static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - snd_ice1712_save_gpio_status(ice); - aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10); - snd_ice1712_restore_gpio_status(ice); - - return 0; -} - -static int aureon_cs8415_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; - uinfo->count = 1; - return 0; -} - -static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - memset(ucontrol->value.iec958.status, 0xFF, 24); - return 0; -} - -static int aureon_cs8415_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - snd_ice1712_save_gpio_status(ice); - aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24); - snd_ice1712_restore_gpio_status(ice); - return 0; -} - -/* - * Headphone Amplifier - */ -static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable) -{ - unsigned int tmp, tmp2; - - tmp2 = tmp = snd_ice1712_gpio_read(ice); - if (enable) - if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && - ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) - tmp |= AUREON_HP_SEL; - else - tmp |= PRODIGY_HP_SEL; - else - if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && - ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) - tmp &= ~AUREON_HP_SEL; - else - tmp &= ~PRODIGY_HP_SEL; - if (tmp != tmp2) { - snd_ice1712_gpio_write(ice, tmp); - return 1; - } - return 0; -} - -static int aureon_get_headphone_amp(struct snd_ice1712 *ice) -{ - unsigned int tmp = snd_ice1712_gpio_read(ice); - - return (tmp & AUREON_HP_SEL) != 0; -} - -#define aureon_hpamp_info snd_ctl_boolean_mono_info - -static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice); - return 0; -} - - -static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - return aureon_set_headphone_amp(ice, ucontrol->value.integer.value[0]); -} - -/* - * Deemphasis - */ - -#define aureon_deemp_info snd_ctl_boolean_mono_info - -static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf; - return 0; -} - -static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int temp, temp2; - temp2 = temp = wm_get(ice, WM_DAC_CTRL2); - if (ucontrol->value.integer.value[0]) - temp |= 0xf; - else - temp &= ~0xf; - if (temp != temp2) { - wm_put(ice, WM_DAC_CTRL2, temp); - return 1; - } - return 0; -} - -/* - * ADC Oversampling - */ -static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo) -{ - static const char * const texts[2] = { "128x", "64x" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - - return 0; -} - -static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8; - return 0; -} - -static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - int temp, temp2; - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - temp2 = temp = wm_get(ice, WM_MASTER); - - if (ucontrol->value.enumerated.item[0]) - temp |= 0x8; - else - temp &= ~0x8; - - if (temp != temp2) { - wm_put(ice, WM_MASTER, temp); - return 1; - } - return 0; -} - -/* - * mixers - */ - -static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = wm_master_mute_info, - .get = wm_master_mute_get, - .put = wm_master_mute_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Master Playback Volume", - .info = wm_master_vol_info, - .get = wm_master_vol_get, - .put = wm_master_vol_put, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Front Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (2 << 8) | 0 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Front Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (2 << 8) | 0, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Rear Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (2 << 8) | 2 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Rear Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (2 << 8) | 2, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Center Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (1 << 8) | 4 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Center Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (1 << 8) | 4, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "LFE Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (1 << 8) | 5 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "LFE Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (1 << 8) | 5, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Side Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (2 << 8) | 6 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Side Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (2 << 8) | 6, - .tlv = { .p = db_scale_wm_dac } - } -}; - -static struct snd_kcontrol_new wm_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Switch", - .info = wm_pcm_mute_info, - .get = wm_pcm_mute_get, - .put = wm_pcm_mute_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "PCM Playback Volume", - .info = wm_pcm_vol_info, - .get = wm_pcm_vol_get, - .put = wm_pcm_vol_put, - .tlv = { .p = db_scale_wm_pcm } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Switch", - .info = wm_adc_mute_info, - .get = wm_adc_mute_get, - .put = wm_adc_mute_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Capture Volume", - .info = wm_adc_vol_info, - .get = wm_adc_vol_get, - .put = wm_adc_vol_put, - .tlv = { .p = db_scale_wm_adc } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = wm_adc_mux_info, - .get = wm_adc_mux_get, - .put = wm_adc_mux_put, - .private_value = 5 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "External Amplifier", - .info = aureon_hpamp_info, - .get = aureon_hpamp_get, - .put = aureon_hpamp_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "DAC Deemphasis Switch", - .info = aureon_deemp_info, - .get = aureon_deemp_get, - .put = aureon_deemp_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "ADC Oversampling", - .info = aureon_oversampling_info, - .get = aureon_oversampling_get, - .put = aureon_oversampling_put - } -}; - -static struct snd_kcontrol_new ac97_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "AC97 Playback Switch", - .info = aureon_ac97_mmute_info, - .get = aureon_ac97_mmute_get, - .put = aureon_ac97_mmute_put, - .private_value = AC97_MASTER - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "AC97 Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_MASTER|AUREON_AC97_STEREO, - .tlv = { .p = db_scale_ac97_master } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "CD Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_CD - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "CD Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_CD|AUREON_AC97_STEREO, - .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Aux Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_AUX, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Aux Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_AUX|AUREON_AC97_STEREO, - .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Line Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_LINE - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Line Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_LINE|AUREON_AC97_STEREO, - .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_MIC - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Mic Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_MIC, - .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Boost (+20dB)", - .info = aureon_ac97_micboost_info, - .get = aureon_ac97_micboost_get, - .put = aureon_ac97_micboost_put - } -}; - -static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "AC97 Playback Switch", - .info = aureon_ac97_mmute_info, - .get = aureon_ac97_mmute_get, - .put = aureon_ac97_mmute_put, - .private_value = AC97_MASTER - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "AC97 Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_MASTER|AUREON_AC97_STEREO, - .tlv = { .p = db_scale_ac97_master } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "CD Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_AUX - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "CD Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_AUX|AUREON_AC97_STEREO, - .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Phono Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_CD - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Phono Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_CD|AUREON_AC97_STEREO, - .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Line Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_LINE - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Line Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_LINE|AUREON_AC97_STEREO, - .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_MIC - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Mic Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_MIC, - .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Boost (+20dB)", - .info = aureon_ac97_micboost_info, - .get = aureon_ac97_micboost_get, - .put = aureon_ac97_micboost_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Aux Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_VIDEO, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Aux Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_VIDEO|AUREON_AC97_STEREO, - .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Aux Source", - .info = aureon_universe_inmux_info, - .get = aureon_universe_inmux_get, - .put = aureon_universe_inmux_put - } - -}; - -static struct snd_kcontrol_new cs8415_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH), - .info = aureon_cs8415_mute_info, - .get = aureon_cs8415_mute_get, - .put = aureon_cs8415_mute_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source", - .info = aureon_cs8415_mux_info, - .get = aureon_cs8415_mux_get, - .put = aureon_cs8415_mux_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT), - .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .info = aureon_cs8415_qsub_info, - .get = aureon_cs8415_qsub_get, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK), - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .info = aureon_cs8415_spdif_info, - .get = aureon_cs8415_mask_get - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT), - .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .info = aureon_cs8415_spdif_info, - .get = aureon_cs8415_spdif_get - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate", - .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .info = aureon_cs8415_rate_info, - .get = aureon_cs8415_rate_get - } -}; - -static int __devinit aureon_add_controls(struct snd_ice1712 *ice) -{ - unsigned int i, counts; - int err; - - counts = ARRAY_SIZE(aureon_dac_controls); - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) - counts -= 2; /* no side */ - for (i = 0; i < counts; i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice)); - if (err < 0) - return err; - } - - for (i = 0; i < ARRAY_SIZE(wm_controls); i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice)); - if (err < 0) - return err; - } - - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) { - for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice)); - if (err < 0) - return err; - } - } else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && - ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) { - for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice)); - if (err < 0) - return err; - } - } - - if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && - ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) { - unsigned char id; - snd_ice1712_save_gpio_status(ice); - id = aureon_cs8415_get(ice, CS8415_ID); - if (id != 0x41) - snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n"); - else if ((id & 0x0F) != 0x01) - snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1)); - else { - for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) { - struct snd_kcontrol *kctl; - err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice))); - if (err < 0) - return err; - if (i > 1) - kctl->id.device = ice->pcm->device; - } - } - snd_ice1712_restore_gpio_status(ice); - } - - return 0; -} - -/* - * reset the chip - */ -static int aureon_reset(struct snd_ice1712 *ice) -{ - static const unsigned short wm_inits_aureon[] = { - /* These come first to reduce init pop noise */ - 0x1b, 0x044, /* ADC Mux (AC'97 source) */ - 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */ - 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */ - - 0x18, 0x000, /* All power-up */ - - 0x16, 0x122, /* I2S, normal polarity, 24bit */ - 0x17, 0x022, /* 256fs, slave mode */ - 0x00, 0, /* DAC1 analog mute */ - 0x01, 0, /* DAC2 analog mute */ - 0x02, 0, /* DAC3 analog mute */ - 0x03, 0, /* DAC4 analog mute */ - 0x04, 0, /* DAC5 analog mute */ - 0x05, 0, /* DAC6 analog mute */ - 0x06, 0, /* DAC7 analog mute */ - 0x07, 0, /* DAC8 analog mute */ - 0x08, 0x100, /* master analog mute */ - 0x09, 0xff, /* DAC1 digital full */ - 0x0a, 0xff, /* DAC2 digital full */ - 0x0b, 0xff, /* DAC3 digital full */ - 0x0c, 0xff, /* DAC4 digital full */ - 0x0d, 0xff, /* DAC5 digital full */ - 0x0e, 0xff, /* DAC6 digital full */ - 0x0f, 0xff, /* DAC7 digital full */ - 0x10, 0xff, /* DAC8 digital full */ - 0x11, 0x1ff, /* master digital full */ - 0x12, 0x000, /* phase normal */ - 0x13, 0x090, /* unmute DAC L/R */ - 0x14, 0x000, /* all unmute */ - 0x15, 0x000, /* no deemphasis, no ZFLG */ - 0x19, 0x000, /* -12dB ADC/L */ - 0x1a, 0x000, /* -12dB ADC/R */ - (unsigned short)-1 - }; - static const unsigned short wm_inits_prodigy[] = { - - /* These come first to reduce init pop noise */ - 0x1b, 0x000, /* ADC Mux */ - 0x1c, 0x009, /* Out Mux1 */ - 0x1d, 0x009, /* Out Mux2 */ - - 0x18, 0x000, /* All power-up */ - - 0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */ - 0x17, 0x006, /* 128fs, slave mode */ - - 0x00, 0, /* DAC1 analog mute */ - 0x01, 0, /* DAC2 analog mute */ - 0x02, 0, /* DAC3 analog mute */ - 0x03, 0, /* DAC4 analog mute */ - 0x04, 0, /* DAC5 analog mute */ - 0x05, 0, /* DAC6 analog mute */ - 0x06, 0, /* DAC7 analog mute */ - 0x07, 0, /* DAC8 analog mute */ - 0x08, 0x100, /* master analog mute */ - - 0x09, 0x7f, /* DAC1 digital full */ - 0x0a, 0x7f, /* DAC2 digital full */ - 0x0b, 0x7f, /* DAC3 digital full */ - 0x0c, 0x7f, /* DAC4 digital full */ - 0x0d, 0x7f, /* DAC5 digital full */ - 0x0e, 0x7f, /* DAC6 digital full */ - 0x0f, 0x7f, /* DAC7 digital full */ - 0x10, 0x7f, /* DAC8 digital full */ - 0x11, 0x1FF, /* master digital full */ - - 0x12, 0x000, /* phase normal */ - 0x13, 0x090, /* unmute DAC L/R */ - 0x14, 0x000, /* all unmute */ - 0x15, 0x000, /* no deemphasis, no ZFLG */ - - 0x19, 0x000, /* -12dB ADC/L */ - 0x1a, 0x000, /* -12dB ADC/R */ - (unsigned short)-1 - - }; - static const unsigned short cs_inits[] = { - 0x0441, /* RUN */ - 0x0180, /* no mute, OMCK output on RMCK pin */ - 0x0201, /* S/PDIF source on RXP1 */ - 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */ - (unsigned short)-1 - }; - unsigned int tmp; - const unsigned short *p; - int err; - struct aureon_spec *spec = ice->spec; - - err = aureon_ac97_init(ice); - if (err != 0) - return err; - - snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */ - - /* reset the wm codec as the SPI mode */ - snd_ice1712_save_gpio_status(ice); - snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL)); - - tmp = snd_ice1712_gpio_read(ice); - tmp &= ~AUREON_WM_RESET; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - tmp |= AUREON_WM_CS | AUREON_CS8415_CS; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - tmp |= AUREON_WM_RESET; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - - /* initialize WM8770 codec */ - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 || - ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT || - ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) - p = wm_inits_prodigy; - else - p = wm_inits_aureon; - for (; *p != (unsigned short)-1; p += 2) - wm_put(ice, p[0], p[1]); - - /* initialize CS8415A codec */ - if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && - ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) { - for (p = cs_inits; *p != (unsigned short)-1; p++) - aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24); - spec->cs8415_mux = 1; - - aureon_set_headphone_amp(ice, 1); - } - - snd_ice1712_restore_gpio_status(ice); - - /* initialize PCA9554 pin directions & set default input */ - aureon_pca9554_write(ice, PCA9554_DIR, 0x00); - aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */ - return 0; -} - -/* - * suspend/resume - */ -#ifdef CONFIG_PM -static int aureon_resume(struct snd_ice1712 *ice) -{ - struct aureon_spec *spec = ice->spec; - int err, i; - - err = aureon_reset(ice); - if (err != 0) - return err; - - /* workaround for poking volume with alsamixer after resume: - * just set stored volume again */ - for (i = 0; i < ice->num_total_dacs; i++) - wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]); - return 0; -} -#endif - -/* - * initialize the chip - */ -static int __devinit aureon_init(struct snd_ice1712 *ice) -{ - struct aureon_spec *spec; - int i, err; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - ice->spec = spec; - - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) { - ice->num_total_dacs = 6; - ice->num_total_adcs = 2; - } else { - /* aureon 7.1 and prodigy 7.1 */ - ice->num_total_dacs = 8; - ice->num_total_adcs = 2; - } - - /* to remember the register values of CS8415 */ - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - if (!ice->akm) - return -ENOMEM; - ice->akm_codecs = 1; - - err = aureon_reset(ice); - if (err != 0) - return err; - - spec->master[0] = WM_VOL_MUTE; - spec->master[1] = WM_VOL_MUTE; - for (i = 0; i < ice->num_total_dacs; i++) { - spec->vol[i] = WM_VOL_MUTE; - wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]); - } - -#ifdef CONFIG_PM - ice->pm_resume = aureon_resume; - ice->pm_suspend_enabled = 1; -#endif - - return 0; -} - - -/* - * Aureon boards don't provide the EEPROM data except for the vendor IDs. - * hence the driver needs to sets up it properly. - */ - -static unsigned char aureon51_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x5f, - [ICE_EEP2_GPIO_MASK] = 0x00, - [ICE_EEP2_GPIO_MASK1] = 0x00, - [ICE_EEP2_GPIO_MASK2] = 0x00, - [ICE_EEP2_GPIO_STATE] = 0x00, - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, -}; - -static unsigned char aureon71_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x5f, - [ICE_EEP2_GPIO_MASK] = 0x00, - [ICE_EEP2_GPIO_MASK1] = 0x00, - [ICE_EEP2_GPIO_MASK2] = 0x00, - [ICE_EEP2_GPIO_STATE] = 0x00, - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, -}; -#define prodigy71_eeprom aureon71_eeprom - -static unsigned char aureon71_universe_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC, - * 4DACs - */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x5f, - [ICE_EEP2_GPIO_MASK] = 0x00, - [ICE_EEP2_GPIO_MASK1] = 0x00, - [ICE_EEP2_GPIO_MASK2] = 0x00, - [ICE_EEP2_GPIO_STATE] = 0x00, - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, -}; - -static unsigned char prodigy71lt_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x5f, - [ICE_EEP2_GPIO_MASK] = 0x00, - [ICE_EEP2_GPIO_MASK1] = 0x00, - [ICE_EEP2_GPIO_MASK2] = 0x00, - [ICE_EEP2_GPIO_STATE] = 0x00, - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, -}; -#define prodigy71xt_eeprom prodigy71lt_eeprom - -/* entry point */ -struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_AUREON51_SKY, - .name = "Terratec Aureon 5.1-Sky", - .model = "aureon51", - .chip_init = aureon_init, - .build_controls = aureon_add_controls, - .eeprom_size = sizeof(aureon51_eeprom), - .eeprom_data = aureon51_eeprom, - .driver = "Aureon51", - }, - { - .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE, - .name = "Terratec Aureon 7.1-Space", - .model = "aureon71", - .chip_init = aureon_init, - .build_controls = aureon_add_controls, - .eeprom_size = sizeof(aureon71_eeprom), - .eeprom_data = aureon71_eeprom, - .driver = "Aureon71", - }, - { - .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE, - .name = "Terratec Aureon 7.1-Universe", - .model = "universe", - .chip_init = aureon_init, - .build_controls = aureon_add_controls, - .eeprom_size = sizeof(aureon71_universe_eeprom), - .eeprom_data = aureon71_universe_eeprom, - .driver = "Aureon71Univ", /* keep in 15 letters */ - }, - { - .subvendor = VT1724_SUBDEVICE_PRODIGY71, - .name = "Audiotrak Prodigy 7.1", - .model = "prodigy71", - .chip_init = aureon_init, - .build_controls = aureon_add_controls, - .eeprom_size = sizeof(prodigy71_eeprom), - .eeprom_data = prodigy71_eeprom, - .driver = "Prodigy71", /* should be identical with Aureon71 */ - }, - { - .subvendor = VT1724_SUBDEVICE_PRODIGY71LT, - .name = "Audiotrak Prodigy 7.1 LT", - .model = "prodigy71lt", - .chip_init = aureon_init, - .build_controls = aureon_add_controls, - .eeprom_size = sizeof(prodigy71lt_eeprom), - .eeprom_data = prodigy71lt_eeprom, - .driver = "Prodigy71LT", - }, - { - .subvendor = VT1724_SUBDEVICE_PRODIGY71XT, - .name = "Audiotrak Prodigy 7.1 XT", - .model = "prodigy71xt", - .chip_init = aureon_init, - .build_controls = aureon_add_controls, - .eeprom_size = sizeof(prodigy71xt_eeprom), - .eeprom_data = prodigy71xt_eeprom, - .driver = "Prodigy71LT", - }, - { } /* terminator */ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/aureon.h b/ANDROID_3.4.5/sound/pci/ice1712/aureon.h deleted file mode 100644 index c253b8e2..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/aureon.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef __SOUND_AUREON_H -#define __SOUND_AUREON_H - -/* - * ALSA driver for VIA VT1724 (Envy24HT) - * - * Lowlevel functions for Terratec Aureon cards - * - * Copyright (c) 2003 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define AUREON_DEVICE_DESC "{Terratec,Aureon 5.1 Sky},"\ - "{Terratec,Aureon 7.1 Space},"\ - "{Terratec,Aureon 7.1 Universe}," \ - "{AudioTrak,Prodigy 7.1}," \ - "{AudioTrak,Prodigy 7.1 LT},"\ - "{AudioTrak,Prodigy 7.1 XT}," - -#define VT1724_SUBDEVICE_AUREON51_SKY 0x3b154711 /* Aureon 5.1 Sky */ -#define VT1724_SUBDEVICE_AUREON71_SPACE 0x3b154511 /* Aureon 7.1 Space */ -#define VT1724_SUBDEVICE_AUREON71_UNIVERSE 0x3b155311 /* Aureon 7.1 Universe */ -#define VT1724_SUBDEVICE_PRODIGY71 0x33495345 /* PRODIGY 7.1 */ -#define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */ -#define VT1724_SUBDEVICE_PRODIGY71XT 0x36315441 /* PRODIGY 7.1 XT*/ - -extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; - -/* GPIO bits */ -#define AUREON_CS8415_CS (1 << 22) -#define AUREON_SPI_MISO (1 << 21) -#define AUREON_WM_RESET (1 << 20) -#define AUREON_SPI_CLK (1 << 19) -#define AUREON_SPI_MOSI (1 << 18) -#define AUREON_WM_RW (1 << 17) -#define AUREON_AC97_RESET (1 << 16) -#define AUREON_DIGITAL_SEL1 (1 << 15) -#define AUREON_HP_SEL (1 << 14) -#define AUREON_WM_CS (1 << 12) -#define AUREON_AC97_COMMIT (1 << 11) -#define AUREON_AC97_ADDR (1 << 10) -#define AUREON_AC97_DATA_LOW (1 << 9) -#define AUREON_AC97_DATA_HIGH (1 << 8) -#define AUREON_AC97_DATA_MASK 0xFF - -#define PRODIGY_WM_CS (1 << 8) -#define PRODIGY_SPI_MOSI (1 << 10) -#define PRODIGY_SPI_CLK (1 << 9) -#define PRODIGY_HP_SEL (1 << 5) - -#endif /* __SOUND_AUREON_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/delta.c b/ANDROID_3.4.5/sound/pci/ice1712/delta.c deleted file mode 100644 index 20c6b079..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/delta.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * ALSA driver for ICEnsemble ICE1712 (Envy24) - * - * Lowlevel functions for M-Audio Delta 1010, 1010E, 44, 66, 66E, Dio2496, - * Audiophile, Digigram VX442 - * - * Copyright (c) 2000 Jaroslav Kysela - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "ice1712.h" -#include "delta.h" - -#define SND_CS8403 -#include - - -/* - * CS8427 via SPI mode (for Audiophile), emulated I2C - */ - -/* send 8 bits */ -static void ap_cs8427_write_byte(struct snd_ice1712 *ice, unsigned char data, unsigned char tmp) -{ - int idx; - - for (idx = 7; idx >= 0; idx--) { - tmp &= ~(ICE1712_DELTA_AP_DOUT|ICE1712_DELTA_AP_CCLK); - if (data & (1 << idx)) - tmp |= ICE1712_DELTA_AP_DOUT; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - udelay(5); - tmp |= ICE1712_DELTA_AP_CCLK; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - udelay(5); - } -} - -/* read 8 bits */ -static unsigned char ap_cs8427_read_byte(struct snd_ice1712 *ice, unsigned char tmp) -{ - unsigned char data = 0; - int idx; - - for (idx = 7; idx >= 0; idx--) { - tmp &= ~ICE1712_DELTA_AP_CCLK; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - udelay(5); - if (snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_DELTA_AP_DIN) - data |= 1 << idx; - tmp |= ICE1712_DELTA_AP_CCLK; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - udelay(5); - } - return data; -} - -/* assert chip select */ -static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice) -{ - unsigned char tmp; - tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_DELTA1010E: - case ICE1712_SUBDEVICE_DELTA1010LT: - tmp &= ~ICE1712_DELTA_1010LT_CS; - tmp |= ICE1712_DELTA_1010LT_CCLK | ICE1712_DELTA_1010LT_CS_CS8427; - break; - case ICE1712_SUBDEVICE_AUDIOPHILE: - case ICE1712_SUBDEVICE_DELTA410: - tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC; - tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL; - break; - case ICE1712_SUBDEVICE_DELTA66E: - tmp |= ICE1712_DELTA_66E_CCLK | ICE1712_DELTA_66E_CS_CHIP_A | - ICE1712_DELTA_66E_CS_CHIP_B; - tmp &= ~ICE1712_DELTA_66E_CS_CS8427; - break; - case ICE1712_SUBDEVICE_VX442: - tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B; - tmp &= ~ICE1712_VX442_CS_DIGITAL; - break; - } - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - udelay(5); - return tmp; -} - -/* deassert chip select */ -static void ap_cs8427_codec_deassert(struct snd_ice1712 *ice, unsigned char tmp) -{ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_DELTA1010E: - case ICE1712_SUBDEVICE_DELTA1010LT: - tmp &= ~ICE1712_DELTA_1010LT_CS; - tmp |= ICE1712_DELTA_1010LT_CS_NONE; - break; - case ICE1712_SUBDEVICE_AUDIOPHILE: - case ICE1712_SUBDEVICE_DELTA410: - tmp |= ICE1712_DELTA_AP_CS_DIGITAL; - break; - case ICE1712_SUBDEVICE_DELTA66E: - tmp |= ICE1712_DELTA_66E_CS_CS8427; - break; - case ICE1712_SUBDEVICE_VX442: - tmp |= ICE1712_VX442_CS_DIGITAL; - break; - } - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); -} - -/* sequential write */ -static int ap_cs8427_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count) -{ - struct snd_ice1712 *ice = device->bus->private_data; - int res = count; - unsigned char tmp; - - mutex_lock(&ice->gpio_mutex); - tmp = ap_cs8427_codec_select(ice); - ap_cs8427_write_byte(ice, (device->addr << 1) | 0, tmp); /* address + write mode */ - while (count-- > 0) - ap_cs8427_write_byte(ice, *bytes++, tmp); - ap_cs8427_codec_deassert(ice, tmp); - mutex_unlock(&ice->gpio_mutex); - return res; -} - -/* sequential read */ -static int ap_cs8427_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count) -{ - struct snd_ice1712 *ice = device->bus->private_data; - int res = count; - unsigned char tmp; - - mutex_lock(&ice->gpio_mutex); - tmp = ap_cs8427_codec_select(ice); - ap_cs8427_write_byte(ice, (device->addr << 1) | 1, tmp); /* address + read mode */ - while (count-- > 0) - *bytes++ = ap_cs8427_read_byte(ice, tmp); - ap_cs8427_codec_deassert(ice, tmp); - mutex_unlock(&ice->gpio_mutex); - return res; -} - -static int ap_cs8427_probeaddr(struct snd_i2c_bus *bus, unsigned short addr) -{ - if (addr == 0x10) - return 1; - return -ENOENT; -} - -static struct snd_i2c_ops ap_cs8427_i2c_ops = { - .sendbytes = ap_cs8427_sendbytes, - .readbytes = ap_cs8427_readbytes, - .probeaddr = ap_cs8427_probeaddr, -}; - -/* - */ - -static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsigned char bits) -{ - unsigned char tmp, mask1, mask2; - int idx; - /* send byte to transmitter */ - mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK; - mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA; - mutex_lock(&ice->gpio_mutex); - tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); - for (idx = 7; idx >= 0; idx--) { - tmp &= ~(mask1 | mask2); - if (bits & (1 << idx)) - tmp |= mask2; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - udelay(100); - tmp |= mask1; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - udelay(100); - } - tmp &= ~mask1; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - mutex_unlock(&ice->gpio_mutex); -} - - -static void delta_spdif_default_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol) -{ - snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_bits); -} - -static int delta_spdif_default_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol) -{ - unsigned int val; - int change; - - val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958); - spin_lock_irq(&ice->reg_lock); - change = ice->spdif.cs8403_bits != val; - ice->spdif.cs8403_bits = val; - if (change && ice->playback_pro_substream == NULL) { - spin_unlock_irq(&ice->reg_lock); - snd_ice1712_delta_cs8403_spdif_write(ice, val); - } else { - spin_unlock_irq(&ice->reg_lock); - } - return change; -} - -static void delta_spdif_stream_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol) -{ - snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_stream_bits); -} - -static int delta_spdif_stream_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol) -{ - unsigned int val; - int change; - - val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958); - spin_lock_irq(&ice->reg_lock); - change = ice->spdif.cs8403_stream_bits != val; - ice->spdif.cs8403_stream_bits = val; - if (change && ice->playback_pro_substream != NULL) { - spin_unlock_irq(&ice->reg_lock); - snd_ice1712_delta_cs8403_spdif_write(ice, val); - } else { - spin_unlock_irq(&ice->reg_lock); - } - return change; -} - - -/* - * AK4524 on Delta 44 and 66 to choose the chip mask - */ -static void delta_ak4524_lock(struct snd_akm4xxx *ak, int chip) -{ - struct snd_ak4xxx_private *priv = (void *)ak->private_value[0]; - struct snd_ice1712 *ice = ak->private_data[0]; - - snd_ice1712_save_gpio_status(ice); - priv->cs_mask = - priv->cs_addr = chip == 0 ? ICE1712_DELTA_CODEC_CHIP_A : - ICE1712_DELTA_CODEC_CHIP_B; -} - -/* - * AK4524 on Delta1010LT to choose the chip address - */ -static void delta1010lt_ak4524_lock(struct snd_akm4xxx *ak, int chip) -{ - struct snd_ak4xxx_private *priv = (void *)ak->private_value[0]; - struct snd_ice1712 *ice = ak->private_data[0]; - - snd_ice1712_save_gpio_status(ice); - priv->cs_mask = ICE1712_DELTA_1010LT_CS; - priv->cs_addr = chip << 4; -} - -/* - * AK4524 on Delta66 rev E to choose the chip address - */ -static void delta66e_ak4524_lock(struct snd_akm4xxx *ak, int chip) -{ - struct snd_ak4xxx_private *priv = (void *)ak->private_value[0]; - struct snd_ice1712 *ice = ak->private_data[0]; - - snd_ice1712_save_gpio_status(ice); - priv->cs_mask = - priv->cs_addr = chip == 0 ? ICE1712_DELTA_66E_CS_CHIP_A : - ICE1712_DELTA_66E_CS_CHIP_B; -} - -/* - * AK4528 on VX442 to choose the chip mask - */ -static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip) -{ - struct snd_ak4xxx_private *priv = (void *)ak->private_value[0]; - struct snd_ice1712 *ice = ak->private_data[0]; - - snd_ice1712_save_gpio_status(ice); - priv->cs_mask = - priv->cs_addr = chip == 0 ? ICE1712_VX442_CODEC_CHIP_A : - ICE1712_VX442_CODEC_CHIP_B; -} - -/* - * change the DFS bit according rate for Delta1010 - */ -static void delta_1010_set_rate_val(struct snd_ice1712 *ice, unsigned int rate) -{ - unsigned char tmp, tmp2; - - if (rate == 0) /* no hint - S/PDIF input is master, simply return */ - return; - - mutex_lock(&ice->gpio_mutex); - tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); - tmp2 = tmp & ~ICE1712_DELTA_DFS; - if (rate > 48000) - tmp2 |= ICE1712_DELTA_DFS; - if (tmp != tmp2) - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp2); - mutex_unlock(&ice->gpio_mutex); -} - -/* - * change the rate of AK4524 on Delta 44/66, AP, 1010LT - */ -static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) -{ - unsigned char tmp, tmp2; - struct snd_ice1712 *ice = ak->private_data[0]; - - if (rate == 0) /* no hint - S/PDIF input is master, simply return */ - return; - - /* check before reset ak4524 to avoid unnecessary clicks */ - mutex_lock(&ice->gpio_mutex); - tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); - mutex_unlock(&ice->gpio_mutex); - tmp2 = tmp & ~ICE1712_DELTA_DFS; - if (rate > 48000) - tmp2 |= ICE1712_DELTA_DFS; - if (tmp == tmp2) - return; - - /* do it again */ - snd_akm4xxx_reset(ak, 1); - mutex_lock(&ice->gpio_mutex); - tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS; - if (rate > 48000) - tmp |= ICE1712_DELTA_DFS; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - mutex_unlock(&ice->gpio_mutex); - snd_akm4xxx_reset(ak, 0); -} - -/* - * change the rate of AK4524 on VX442 - */ -static void vx442_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) -{ - unsigned char val; - - val = (rate > 48000) ? 0x65 : 0x60; - if (snd_akm4xxx_get(ak, 0, 0x02) != val || - snd_akm4xxx_get(ak, 1, 0x02) != val) { - snd_akm4xxx_reset(ak, 1); - snd_akm4xxx_write(ak, 0, 0x02, val); - snd_akm4xxx_write(ak, 1, 0x02, val); - snd_akm4xxx_reset(ak, 0); - } -} - - -/* - * SPDIF ops for Delta 1010, Dio, 66 - */ - -/* open callback */ -static void delta_open_spdif(struct snd_ice1712 *ice, struct snd_pcm_substream *substream) -{ - ice->spdif.cs8403_stream_bits = ice->spdif.cs8403_bits; -} - -/* set up */ -static void delta_setup_spdif(struct snd_ice1712 *ice, int rate) -{ - unsigned long flags; - unsigned int tmp; - int change; - - spin_lock_irqsave(&ice->reg_lock, flags); - tmp = ice->spdif.cs8403_stream_bits; - if (tmp & 0x01) /* consumer */ - tmp &= (tmp & 0x01) ? ~0x06 : ~0x18; - switch (rate) { - case 32000: tmp |= (tmp & 0x01) ? 0x04 : 0x00; break; - case 44100: tmp |= (tmp & 0x01) ? 0x00 : 0x10; break; - case 48000: tmp |= (tmp & 0x01) ? 0x02 : 0x08; break; - default: tmp |= (tmp & 0x01) ? 0x00 : 0x18; break; - } - change = ice->spdif.cs8403_stream_bits != tmp; - ice->spdif.cs8403_stream_bits = tmp; - spin_unlock_irqrestore(&ice->reg_lock, flags); - if (change) - snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id); - snd_ice1712_delta_cs8403_spdif_write(ice, tmp); -} - -#define snd_ice1712_delta1010lt_wordclock_status_info \ - snd_ctl_boolean_mono_info - -static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - char reg = 0x10; /* CS8427 receiver error register */ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - if (snd_i2c_sendbytes(ice->cs8427, ®, 1) != 1) - snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg); - snd_i2c_readbytes(ice->cs8427, ®, 1); - ucontrol->value.integer.value[0] = (reg & CS8427_UNLOCK) ? 1 : 0; - return 0; -} - -static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = -{ - .access = (SNDRV_CTL_ELEM_ACCESS_READ), - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Word Clock Status", - .info = snd_ice1712_delta1010lt_wordclock_status_info, - .get = snd_ice1712_delta1010lt_wordclock_status_get, -}; - -/* - * initialize the chips on M-Audio cards - */ - -static struct snd_akm4xxx akm_audiophile __devinitdata = { - .type = SND_AK4528, - .num_adcs = 2, - .num_dacs = 2, - .ops = { - .set_rate_val = delta_ak4524_set_rate_val - } -}; - -static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { - .caddr = 2, - .cif = 0, - .data_mask = ICE1712_DELTA_AP_DOUT, - .clk_mask = ICE1712_DELTA_AP_CCLK, - .cs_mask = ICE1712_DELTA_AP_CS_CODEC, - .cs_addr = ICE1712_DELTA_AP_CS_CODEC, - .cs_none = 0, - .add_flags = ICE1712_DELTA_AP_CS_DIGITAL, - .mask_flags = 0, -}; - -static struct snd_akm4xxx akm_delta410 __devinitdata = { - .type = SND_AK4529, - .num_adcs = 2, - .num_dacs = 8, - .ops = { - .set_rate_val = delta_ak4524_set_rate_val - } -}; - -static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { - .caddr = 0, - .cif = 0, - .data_mask = ICE1712_DELTA_AP_DOUT, - .clk_mask = ICE1712_DELTA_AP_CCLK, - .cs_mask = ICE1712_DELTA_AP_CS_CODEC, - .cs_addr = ICE1712_DELTA_AP_CS_CODEC, - .cs_none = 0, - .add_flags = ICE1712_DELTA_AP_CS_DIGITAL, - .mask_flags = 0, -}; - -static struct snd_akm4xxx akm_delta1010lt __devinitdata = { - .type = SND_AK4524, - .num_adcs = 8, - .num_dacs = 8, - .ops = { - .lock = delta1010lt_ak4524_lock, - .set_rate_val = delta_ak4524_set_rate_val - } -}; - -static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { - .caddr = 2, - .cif = 0, /* the default level of the CIF pin from AK4524 */ - .data_mask = ICE1712_DELTA_1010LT_DOUT, - .clk_mask = ICE1712_DELTA_1010LT_CCLK, - .cs_mask = 0, - .cs_addr = 0, /* set later */ - .cs_none = ICE1712_DELTA_1010LT_CS_NONE, - .add_flags = 0, - .mask_flags = 0, -}; - -static struct snd_akm4xxx akm_delta66e __devinitdata = { - .type = SND_AK4524, - .num_adcs = 4, - .num_dacs = 4, - .ops = { - .lock = delta66e_ak4524_lock, - .set_rate_val = delta_ak4524_set_rate_val - } -}; - -static struct snd_ak4xxx_private akm_delta66e_priv __devinitdata = { - .caddr = 2, - .cif = 0, /* the default level of the CIF pin from AK4524 */ - .data_mask = ICE1712_DELTA_66E_DOUT, - .clk_mask = ICE1712_DELTA_66E_CCLK, - .cs_mask = 0, - .cs_addr = 0, /* set later */ - .cs_none = 0, - .add_flags = 0, - .mask_flags = 0, -}; - - -static struct snd_akm4xxx akm_delta44 __devinitdata = { - .type = SND_AK4524, - .num_adcs = 4, - .num_dacs = 4, - .ops = { - .lock = delta_ak4524_lock, - .set_rate_val = delta_ak4524_set_rate_val - } -}; - -static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { - .caddr = 2, - .cif = 0, /* the default level of the CIF pin from AK4524 */ - .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA, - .clk_mask = ICE1712_DELTA_CODEC_SERIAL_CLOCK, - .cs_mask = 0, - .cs_addr = 0, /* set later */ - .cs_none = 0, - .add_flags = 0, - .mask_flags = 0, -}; - -static struct snd_akm4xxx akm_vx442 __devinitdata = { - .type = SND_AK4524, - .num_adcs = 4, - .num_dacs = 4, - .ops = { - .lock = vx442_ak4524_lock, - .set_rate_val = vx442_ak4524_set_rate_val - } -}; - -static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = { - .caddr = 2, - .cif = 0, - .data_mask = ICE1712_VX442_DOUT, - .clk_mask = ICE1712_VX442_CCLK, - .cs_mask = 0, - .cs_addr = 0, /* set later */ - .cs_none = 0, - .add_flags = 0, - .mask_flags = 0, -}; - -static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) -{ - int err; - struct snd_akm4xxx *ak; - unsigned char tmp; - - if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA1010 && - ice->eeprom.gpiodir == 0x7b) - ice->eeprom.subvendor = ICE1712_SUBDEVICE_DELTA1010E; - - if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA66 && - ice->eeprom.gpiodir == 0xfb) - ice->eeprom.subvendor = ICE1712_SUBDEVICE_DELTA66E; - - /* determine I2C, DACs and ADCs */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_AUDIOPHILE: - ice->num_total_dacs = 2; - ice->num_total_adcs = 2; - break; - case ICE1712_SUBDEVICE_DELTA410: - ice->num_total_dacs = 8; - ice->num_total_adcs = 2; - break; - case ICE1712_SUBDEVICE_DELTA44: - case ICE1712_SUBDEVICE_DELTA66: - ice->num_total_dacs = ice->omni ? 8 : 4; - ice->num_total_adcs = ice->omni ? 8 : 4; - break; - case ICE1712_SUBDEVICE_DELTA1010: - case ICE1712_SUBDEVICE_DELTA1010E: - case ICE1712_SUBDEVICE_DELTA1010LT: - case ICE1712_SUBDEVICE_MEDIASTATION: - case ICE1712_SUBDEVICE_EDIROLDA2496: - ice->num_total_dacs = 8; - ice->num_total_adcs = 8; - break; - case ICE1712_SUBDEVICE_DELTADIO2496: - ice->num_total_dacs = 4; /* two AK4324 codecs */ - break; - case ICE1712_SUBDEVICE_VX442: - case ICE1712_SUBDEVICE_DELTA66E: /* omni not suported yet */ - ice->num_total_dacs = 4; - ice->num_total_adcs = 4; - break; - } - - /* initialize the SPI clock to high */ - tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); - tmp |= ICE1712_DELTA_AP_CCLK; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - udelay(5); - - /* initialize spdif */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_AUDIOPHILE: - case ICE1712_SUBDEVICE_DELTA410: - case ICE1712_SUBDEVICE_DELTA1010E: - case ICE1712_SUBDEVICE_DELTA1010LT: - case ICE1712_SUBDEVICE_VX442: - case ICE1712_SUBDEVICE_DELTA66E: - if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) { - snd_printk(KERN_ERR "unable to create I2C bus\n"); - return err; - } - ice->i2c->private_data = ice; - ice->i2c->ops = &ap_cs8427_i2c_ops; - if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0) - return err; - break; - case ICE1712_SUBDEVICE_DELTA1010: - case ICE1712_SUBDEVICE_MEDIASTATION: - ice->gpio.set_pro_rate = delta_1010_set_rate_val; - break; - case ICE1712_SUBDEVICE_DELTADIO2496: - ice->gpio.set_pro_rate = delta_1010_set_rate_val; - /* fall thru */ - case ICE1712_SUBDEVICE_DELTA66: - ice->spdif.ops.open = delta_open_spdif; - ice->spdif.ops.setup_rate = delta_setup_spdif; - ice->spdif.ops.default_get = delta_spdif_default_get; - ice->spdif.ops.default_put = delta_spdif_default_put; - ice->spdif.ops.stream_get = delta_spdif_stream_get; - ice->spdif.ops.stream_put = delta_spdif_stream_put; - /* Set spdif defaults */ - snd_ice1712_delta_cs8403_spdif_write(ice, ice->spdif.cs8403_bits); - break; - } - - /* no analog? */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_DELTA1010: - case ICE1712_SUBDEVICE_DELTA1010E: - case ICE1712_SUBDEVICE_DELTADIO2496: - case ICE1712_SUBDEVICE_MEDIASTATION: - return 0; - } - - /* second stage of initialization, analog parts and others */ - ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - if (! ak) - return -ENOMEM; - ice->akm_codecs = 1; - - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_AUDIOPHILE: - err = snd_ice1712_akm4xxx_init(ak, &akm_audiophile, &akm_audiophile_priv, ice); - break; - case ICE1712_SUBDEVICE_DELTA410: - err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice); - break; - case ICE1712_SUBDEVICE_DELTA1010LT: - case ICE1712_SUBDEVICE_EDIROLDA2496: - err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice); - break; - case ICE1712_SUBDEVICE_DELTA66: - case ICE1712_SUBDEVICE_DELTA44: - err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice); - break; - case ICE1712_SUBDEVICE_VX442: - err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice); - break; - case ICE1712_SUBDEVICE_DELTA66E: - err = snd_ice1712_akm4xxx_init(ak, &akm_delta66e, &akm_delta66e_priv, ice); - break; - default: - snd_BUG(); - return -EINVAL; - } - - return err; -} - - -/* - * additional controls for M-Audio cards - */ - -static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = -ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); -static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = -ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0); -static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = -ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); -static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = -ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); -static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata = -ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); - - -static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice) -{ - int err; - - /* 1010 and dio specific controls */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_DELTA1010: - case ICE1712_SUBDEVICE_MEDIASTATION: - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_select, ice)); - if (err < 0) - return err; - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_status, ice)); - if (err < 0) - return err; - break; - case ICE1712_SUBDEVICE_DELTADIO2496: - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_deltadio2496_spdif_in_select, ice)); - if (err < 0) - return err; - break; - case ICE1712_SUBDEVICE_DELTA1010E: - case ICE1712_SUBDEVICE_DELTA1010LT: - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_select, ice)); - if (err < 0) - return err; - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_status, ice)); - if (err < 0) - return err; - break; - } - - /* normal spdif controls */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_DELTA1010: - case ICE1712_SUBDEVICE_DELTADIO2496: - case ICE1712_SUBDEVICE_DELTA66: - case ICE1712_SUBDEVICE_MEDIASTATION: - err = snd_ice1712_spdif_build_controls(ice); - if (err < 0) - return err; - break; - } - - /* spdif status in */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_DELTA1010: - case ICE1712_SUBDEVICE_DELTADIO2496: - case ICE1712_SUBDEVICE_DELTA66: - case ICE1712_SUBDEVICE_MEDIASTATION: - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta_spdif_in_status, ice)); - if (err < 0) - return err; - break; - } - - /* ak4524 controls */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_DELTA1010LT: - case ICE1712_SUBDEVICE_AUDIOPHILE: - case ICE1712_SUBDEVICE_DELTA410: - case ICE1712_SUBDEVICE_DELTA44: - case ICE1712_SUBDEVICE_DELTA66: - case ICE1712_SUBDEVICE_VX442: - case ICE1712_SUBDEVICE_DELTA66E: - case ICE1712_SUBDEVICE_EDIROLDA2496: - err = snd_ice1712_akm4xxx_build_controls(ice); - if (err < 0) - return err; - break; - } - - return 0; -} - - -/* entry point */ -struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = { - { - .subvendor = ICE1712_SUBDEVICE_DELTA1010, - .name = "M Audio Delta 1010", - .model = "delta1010", - .chip_init = snd_ice1712_delta_init, - .build_controls = snd_ice1712_delta_add_controls, - }, - { - .subvendor = ICE1712_SUBDEVICE_DELTADIO2496, - .name = "M Audio Delta DiO 2496", - .model = "dio2496", - .chip_init = snd_ice1712_delta_init, - .build_controls = snd_ice1712_delta_add_controls, - .no_mpu401 = 1, - }, - { - .subvendor = ICE1712_SUBDEVICE_DELTA66, - .name = "M Audio Delta 66", - .model = "delta66", - .chip_init = snd_ice1712_delta_init, - .build_controls = snd_ice1712_delta_add_controls, - .no_mpu401 = 1, - }, - { - .subvendor = ICE1712_SUBDEVICE_DELTA44, - .name = "M Audio Delta 44", - .model = "delta44", - .chip_init = snd_ice1712_delta_init, - .build_controls = snd_ice1712_delta_add_controls, - .no_mpu401 = 1, - }, - { - .subvendor = ICE1712_SUBDEVICE_AUDIOPHILE, - .name = "M Audio Audiophile 24/96", - .model = "audiophile", - .chip_init = snd_ice1712_delta_init, - .build_controls = snd_ice1712_delta_add_controls, - }, - { - .subvendor = ICE1712_SUBDEVICE_DELTA410, - .name = "M Audio Delta 410", - .model = "delta410", - .chip_init = snd_ice1712_delta_init, - .build_controls = snd_ice1712_delta_add_controls, - }, - { - .subvendor = ICE1712_SUBDEVICE_DELTA1010LT, - .name = "M Audio Delta 1010LT", - .model = "delta1010lt", - .chip_init = snd_ice1712_delta_init, - .build_controls = snd_ice1712_delta_add_controls, - }, - { - .subvendor = ICE1712_SUBDEVICE_VX442, - .name = "Digigram VX442", - .model = "vx442", - .chip_init = snd_ice1712_delta_init, - .build_controls = snd_ice1712_delta_add_controls, - .no_mpu401 = 1, - }, - { - .subvendor = ICE1712_SUBDEVICE_MEDIASTATION, - .name = "Lionstracs Mediastation", - .model = "mediastation", - .chip_init = snd_ice1712_delta_init, - .build_controls = snd_ice1712_delta_add_controls, - }, - { - .subvendor = ICE1712_SUBDEVICE_EDIROLDA2496, - .name = "Edirol DA2496", - .model = "da2496", - .chip_init = snd_ice1712_delta_init, - .build_controls = snd_ice1712_delta_add_controls, - }, - { } /* terminator */ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/delta.h b/ANDROID_3.4.5/sound/pci/ice1712/delta.h deleted file mode 100644 index 11a9c3a7..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/delta.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef __SOUND_DELTA_H -#define __SOUND_DELTA_H - -/* - * ALSA driver for ICEnsemble ICE1712 (Envy24) - * - * Lowlevel functions for M-Audio Delta 1010, 44, 66, Dio2496, Audiophile - * Digigram VX442 - * - * Copyright (c) 2000 Jaroslav Kysela - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define DELTA_DEVICE_DESC \ - "{MidiMan M Audio,Delta 1010},"\ - "{MidiMan M Audio,Delta 1010LT},"\ - "{MidiMan M Audio,Delta DiO 2496},"\ - "{MidiMan M Audio,Delta 66},"\ - "{MidiMan M Audio,Delta 44},"\ - "{MidiMan M Audio,Delta 410},"\ - "{MidiMan M Audio,Audiophile 24/96},"\ - "{Digigram,VX442},"\ - "{Lionstracs,Mediastation},"\ - "{Edirol,DA2496}," - -#define ICE1712_SUBDEVICE_DELTA1010 0x121430d6 -#define ICE1712_SUBDEVICE_DELTA1010E 0xff1430d6 -#define ICE1712_SUBDEVICE_DELTADIO2496 0x121431d6 -#define ICE1712_SUBDEVICE_DELTA66 0x121432d6 -#define ICE1712_SUBDEVICE_DELTA66E 0xff1432d6 -#define ICE1712_SUBDEVICE_DELTA44 0x121433d6 -#define ICE1712_SUBDEVICE_AUDIOPHILE 0x121434d6 -#define ICE1712_SUBDEVICE_DELTA410 0x121438d6 -#define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6 -#define ICE1712_SUBDEVICE_VX442 0x12143cd6 -#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100 -#define ICE1712_SUBDEVICE_EDIROLDA2496 0xce164010 - -/* entry point */ -extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; - - -/* - * MidiMan M-Audio Delta GPIO definitions - */ - -/* MidiMan M-Audio Delta shared pins */ -#define ICE1712_DELTA_DFS 0x01 /* fast/slow sample rate mode */ - /* (>48kHz must be 1) */ -#define ICE1712_DELTA_SPDIF_IN_STAT 0x02 - /* S/PDIF input status */ - /* 0 = valid signal is present */ - /* all except Delta44 */ - /* look to CS8414 datasheet */ -#define ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK 0x04 - /* S/PDIF output status clock */ - /* (writing on rising edge - 0->1) */ - /* all except Delta44 */ - /* look to CS8404A datasheet */ -#define ICE1712_DELTA_SPDIF_OUT_STAT_DATA 0x08 - /* S/PDIF output status data */ - /* all except Delta44 */ - /* look to CS8404A datasheet */ -/* MidiMan M-Audio DeltaDiO */ -/* 0x01 = DFS */ -/* 0x02 = SPDIF_IN_STAT */ -/* 0x04 = SPDIF_OUT_STAT_CLOCK */ -/* 0x08 = SPDIF_OUT_STAT_DATA */ -#define ICE1712_DELTA_SPDIF_INPUT_SELECT 0x10 - /* coaxial (0), optical (1) */ - /* S/PDIF input select*/ - -/* MidiMan M-Audio Delta1010 */ -/* 0x01 = DFS */ -/* 0x02 = SPDIF_IN_STAT */ -/* 0x04 = SPDIF_OUT_STAT_CLOCK */ -/* 0x08 = SPDIF_OUT_STAT_DATA */ -#define ICE1712_DELTA_WORD_CLOCK_SELECT 0x10 - /* 1 - clock are taken from S/PDIF input */ - /* 0 - clock are taken from Word Clock input */ - /* affected SPMCLKIN pin of Envy24 */ -#define ICE1712_DELTA_WORD_CLOCK_STATUS 0x20 - /* 0 = valid word clock signal is present */ - -/* MidiMan M-Audio Delta66 */ -/* 0x01 = DFS */ -/* 0x02 = SPDIF_IN_STAT */ -/* 0x04 = SPDIF_OUT_STAT_CLOCK */ -/* 0x08 = SPDIF_OUT_STAT_DATA */ -#define ICE1712_DELTA_CODEC_SERIAL_DATA 0x10 - /* AKM4524 serial data */ -#define ICE1712_DELTA_CODEC_SERIAL_CLOCK 0x20 - /* AKM4524 serial clock */ - /* (writing on rising edge - 0->1 */ -#define ICE1712_DELTA_CODEC_CHIP_A 0x40 -#define ICE1712_DELTA_CODEC_CHIP_B 0x80 - /* 1 - select chip A or B */ - -/* MidiMan M-Audio Delta44 */ -/* 0x01 = DFS */ -/* 0x10 = CODEC_SERIAL_DATA */ -/* 0x20 = CODEC_SERIAL_CLOCK */ -/* 0x40 = CODEC_CHIP_A */ -/* 0x80 = CODEC_CHIP_B */ - -/* MidiMan M-Audio Audiophile/Delta410 definitions */ -/* thanks to Kristof Pelckmans for Delta410 info */ -/* 0x01 = DFS */ -#define ICE1712_DELTA_AP_CCLK 0x02 /* SPI clock */ - /* (clocking on rising edge - 0->1) */ -#define ICE1712_DELTA_AP_DIN 0x04 /* data input */ -#define ICE1712_DELTA_AP_DOUT 0x08 /* data output */ -#define ICE1712_DELTA_AP_CS_DIGITAL 0x10 /* CS8427 chip select */ - /* low signal = select */ -#define ICE1712_DELTA_AP_CS_CODEC 0x20 /* AK4528 (audiophile), AK4529 (Delta410) chip select */ - /* low signal = select */ - -/* MidiMan M-Audio Delta1010LT definitions */ -/* thanks to Anders Johansson */ -/* 0x01 = DFS */ -#define ICE1712_DELTA_1010LT_CCLK 0x02 /* SPI clock (AK4524 + CS8427) */ -#define ICE1712_DELTA_1010LT_DIN 0x04 /* data input (CS8427) */ -#define ICE1712_DELTA_1010LT_DOUT 0x08 /* data output (AK4524 + CS8427) */ -#define ICE1712_DELTA_1010LT_CS 0x70 /* mask for CS address */ -#define ICE1712_DELTA_1010LT_CS_CHIP_A 0x00 /* AK4524 #0 */ -#define ICE1712_DELTA_1010LT_CS_CHIP_B 0x10 /* AK4524 #1 */ -#define ICE1712_DELTA_1010LT_CS_CHIP_C 0x20 /* AK4524 #2 */ -#define ICE1712_DELTA_1010LT_CS_CHIP_D 0x30 /* AK4524 #3 */ -#define ICE1712_DELTA_1010LT_CS_CS8427 0x40 /* CS8427 */ -#define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */ -#define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */ - -/* M-Audio Delta 66 rev. E definitions. - * Newer revisions of Delta 66 have CS8427 over SPI for - * S/PDIF transceiver instead of CS8404/CS8414. */ -/* 0x01 = DFS */ -#define ICE1712_DELTA_66E_CCLK 0x02 /* SPI clock */ -#define ICE1712_DELTA_66E_DIN 0x04 /* data input */ -#define ICE1712_DELTA_66E_DOUT 0x08 /* data output */ -#define ICE1712_DELTA_66E_CS_CS8427 0x10 /* chip select, low = CS8427 */ -#define ICE1712_DELTA_66E_CS_CHIP_A 0x20 /* AK4524 #0 */ -#define ICE1712_DELTA_66E_CS_CHIP_B 0x40 /* AK4524 #1 */ - -/* Digigram VX442 definitions */ -#define ICE1712_VX442_CCLK 0x02 /* SPI clock */ -#define ICE1712_VX442_DIN 0x04 /* data input */ -#define ICE1712_VX442_DOUT 0x08 /* data output */ -#define ICE1712_VX442_CS_DIGITAL 0x10 /* chip select, low = CS8427 */ -#define ICE1712_VX442_CODEC_CHIP_A 0x20 /* select chip A */ -#define ICE1712_VX442_CODEC_CHIP_B 0x40 /* select chip B */ - -#endif /* __SOUND_DELTA_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/envy24ht.h b/ANDROID_3.4.5/sound/pci/ice1712/envy24ht.h deleted file mode 100644 index 4ca33a80..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/envy24ht.h +++ /dev/null @@ -1,220 +0,0 @@ -#ifndef __SOUND_VT1724_H -#define __SOUND_VT1724_H - -/* - * ALSA driver for ICEnsemble VT1724 (Envy24) - * - * Copyright (c) 2000 Jaroslav Kysela - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include - -#include "ice1712.h" - -enum { - ICE_EEP2_SYSCONF = 0, /* 06 */ - ICE_EEP2_ACLINK, /* 07 */ - ICE_EEP2_I2S, /* 08 */ - ICE_EEP2_SPDIF, /* 09 */ - ICE_EEP2_GPIO_DIR, /* 0a */ - ICE_EEP2_GPIO_DIR1, /* 0b */ - ICE_EEP2_GPIO_DIR2, /* 0c */ - ICE_EEP2_GPIO_MASK, /* 0d */ - ICE_EEP2_GPIO_MASK1, /* 0e */ - ICE_EEP2_GPIO_MASK2, /* 0f */ - ICE_EEP2_GPIO_STATE, /* 10 */ - ICE_EEP2_GPIO_STATE1, /* 11 */ - ICE_EEP2_GPIO_STATE2 /* 12 */ -}; - -/* - * Direct registers - */ - -#define ICEREG1724(ice, x) ((ice)->port + VT1724_REG_##x) - -#define VT1724_REG_CONTROL 0x00 /* byte */ -#define VT1724_RESET 0x80 /* reset whole chip */ -#define VT1724_REG_IRQMASK 0x01 /* byte */ -#define VT1724_IRQ_MPU_RX 0x80 -#define VT1724_IRQ_MPU_TX 0x20 -#define VT1724_IRQ_MTPCM 0x10 -#define VT1724_REG_IRQSTAT 0x02 /* byte */ -/* look to VT1724_IRQ_* */ -#define VT1724_REG_SYS_CFG 0x04 /* byte - system configuration PCI60 on Envy24*/ -#define VT1724_CFG_CLOCK 0xc0 -#define VT1724_CFG_CLOCK512 0x00 /* 22.5692Mhz, 44.1kHz*512 */ -#define VT1724_CFG_CLOCK384 0x40 /* 16.9344Mhz, 44.1kHz*384 */ -#define VT1724_CFG_MPU401 0x20 /* MPU401 UARTs */ -#define VT1724_CFG_ADC_MASK 0x0c /* one, two or one and S/PDIF, stereo ADCs */ -#define VT1724_CFG_ADC_NONE 0x0c /* no ADCs */ -#define VT1724_CFG_DAC_MASK 0x03 /* one, two, three, four stereo DACs */ - -#define VT1724_REG_AC97_CFG 0x05 /* byte */ -#define VT1724_CFG_PRO_I2S 0x80 /* multitrack converter: I2S or AC'97 */ -#define VT1724_CFG_AC97_PACKED 0x01 /* split or packed mode - AC'97 */ - -#define VT1724_REG_I2S_FEATURES 0x06 /* byte */ -#define VT1724_CFG_I2S_VOLUME 0x80 /* volume/mute capability */ -#define VT1724_CFG_I2S_96KHZ 0x40 /* supports 96kHz sampling */ -#define VT1724_CFG_I2S_RESMASK 0x30 /* resolution mask, 16,18,20,24-bit */ -#define VT1724_CFG_I2S_192KHZ 0x08 /* supports 192kHz sampling */ -#define VT1724_CFG_I2S_OTHER 0x07 /* other I2S IDs */ - -#define VT1724_REG_SPDIF_CFG 0x07 /* byte */ -#define VT1724_CFG_SPDIF_OUT_EN 0x80 /*Internal S/PDIF output is enabled*/ -#define VT1724_CFG_SPDIF_OUT_INT 0x40 /*Internal S/PDIF output is implemented*/ -#define VT1724_CFG_I2S_CHIPID 0x3c /* I2S chip ID */ -#define VT1724_CFG_SPDIF_IN 0x02 /* S/PDIF input is present */ -#define VT1724_CFG_SPDIF_OUT 0x01 /* External S/PDIF output is present */ - -/*there is no consumer AC97 codec with the VT1724*/ -//#define VT1724_REG_AC97_INDEX 0x08 /* byte */ -//#define VT1724_REG_AC97_CMD 0x09 /* byte */ - -#define VT1724_REG_MPU_TXFIFO 0x0a /*byte ro. number of bytes in TX fifo*/ -#define VT1724_REG_MPU_RXFIFO 0x0b /*byte ro. number of bytes in RX fifo*/ - -#define VT1724_REG_MPU_DATA 0x0c /* byte */ -#define VT1724_REG_MPU_CTRL 0x0d /* byte */ -#define VT1724_MPU_UART 0x01 -#define VT1724_MPU_TX_EMPTY 0x02 -#define VT1724_MPU_TX_FULL 0x04 -#define VT1724_MPU_RX_EMPTY 0x08 -#define VT1724_MPU_RX_FULL 0x10 - -#define VT1724_REG_MPU_FIFO_WM 0x0e /*byte set the high/low watermarks for RX/TX fifos*/ -#define VT1724_MPU_RX_FIFO 0x20 //1=rx fifo watermark 0=tx fifo watermark -#define VT1724_MPU_FIFO_MASK 0x1f - -#define VT1724_REG_I2C_DEV_ADDR 0x10 /* byte */ -#define VT1724_I2C_WRITE 0x01 /* write direction */ -#define VT1724_REG_I2C_BYTE_ADDR 0x11 /* byte */ -#define VT1724_REG_I2C_DATA 0x12 /* byte */ -#define VT1724_REG_I2C_CTRL 0x13 /* byte */ -#define VT1724_I2C_EEPROM 0x80 /* 1 = EEPROM exists */ -#define VT1724_I2C_BUSY 0x01 /* busy bit */ - -#define VT1724_REG_GPIO_DATA 0x14 /* word */ -#define VT1724_REG_GPIO_WRITE_MASK 0x16 /* word */ -#define VT1724_REG_GPIO_DIRECTION 0x18 /* dword? (3 bytes) 0=input 1=output. - bit3 - during reset used for Eeprom power-on strapping - if TESTEN# pin active, bit 2 always input*/ -#define VT1724_REG_POWERDOWN 0x1c -#define VT1724_REG_GPIO_DATA_22 0x1e /* byte direction for GPIO 16:22 */ -#define VT1724_REG_GPIO_WRITE_MASK_22 0x1f /* byte write mask for GPIO 16:22 */ - - -/* - * Professional multi-track direct control registers - */ - -#define ICEMT1724(ice, x) ((ice)->profi_port + VT1724_MT_##x) - -#define VT1724_MT_IRQ 0x00 /* byte - interrupt mask */ -#define VT1724_MULTI_PDMA4 0x80 /* SPDIF Out / PDMA4 */ -#define VT1724_MULTI_PDMA3 0x40 /* PDMA3 */ -#define VT1724_MULTI_PDMA2 0x20 /* PDMA2 */ -#define VT1724_MULTI_PDMA1 0x10 /* PDMA1 */ -#define VT1724_MULTI_FIFO_ERR 0x08 /* DMA FIFO underrun/overrun. */ -#define VT1724_MULTI_RDMA1 0x04 /* RDMA1 (S/PDIF input) */ -#define VT1724_MULTI_RDMA0 0x02 /* RMDA0 */ -#define VT1724_MULTI_PDMA0 0x01 /* MC Interleave/PDMA0 */ - -#define VT1724_MT_RATE 0x01 /* byte - sampling rate select */ -#define VT1724_SPDIF_MASTER 0x10 /* S/PDIF input is master clock */ -#define VT1724_MT_I2S_FORMAT 0x02 /* byte - I2S data format */ -#define VT1724_MT_I2S_MCLK_128X 0x08 -#define VT1724_MT_I2S_FORMAT_MASK 0x03 -#define VT1724_MT_I2S_FORMAT_I2S 0x00 -#define VT1724_MT_DMA_INT_MASK 0x03 /* byte -DMA Interrupt Mask */ -/* lool to VT1724_MULTI_* */ -#define VT1724_MT_AC97_INDEX 0x04 /* byte - AC'97 index */ -#define VT1724_MT_AC97_CMD 0x05 /* byte - AC'97 command & status */ -#define VT1724_AC97_COLD 0x80 /* cold reset */ -#define VT1724_AC97_WARM 0x40 /* warm reset */ -#define VT1724_AC97_WRITE 0x20 /* W: write, R: write in progress */ -#define VT1724_AC97_READ 0x10 /* W: read, R: read in progress */ -#define VT1724_AC97_READY 0x08 /* codec ready status bit */ -#define VT1724_AC97_ID_MASK 0x03 /* codec id mask */ -#define VT1724_MT_AC97_DATA 0x06 /* word - AC'97 data */ -#define VT1724_MT_PLAYBACK_ADDR 0x10 /* dword - playback address */ -#define VT1724_MT_PLAYBACK_SIZE 0x14 /* dword - playback size */ -#define VT1724_MT_DMA_CONTROL 0x18 /* byte - control */ -#define VT1724_PDMA4_START 0x80 /* SPDIF out / PDMA4 start */ -#define VT1724_PDMA3_START 0x40 /* PDMA3 start */ -#define VT1724_PDMA2_START 0x20 /* PDMA2 start */ -#define VT1724_PDMA1_START 0x10 /* PDMA1 start */ -#define VT1724_RDMA1_START 0x04 /* RDMA1 start */ -#define VT1724_RDMA0_START 0x02 /* RMDA0 start */ -#define VT1724_PDMA0_START 0x01 /* MC Interleave / PDMA0 start */ -#define VT1724_MT_BURST 0x19 /* Interleaved playback DMA Active streams / PCI burst size */ -#define VT1724_MT_DMA_FIFO_ERR 0x1a /*Global playback and record DMA FIFO Underrun/Overrun */ -#define VT1724_PDMA4_UNDERRUN 0x80 -#define VT1724_PDMA2_UNDERRUN 0x40 -#define VT1724_PDMA3_UNDERRUN 0x20 -#define VT1724_PDMA1_UNDERRUN 0x10 -#define VT1724_RDMA1_UNDERRUN 0x04 -#define VT1724_RDMA0_UNDERRUN 0x02 -#define VT1724_PDMA0_UNDERRUN 0x01 -#define VT1724_MT_DMA_PAUSE 0x1b /*Global playback and record DMA FIFO pause/resume */ -#define VT1724_PDMA4_PAUSE 0x80 -#define VT1724_PDMA3_PAUSE 0x40 -#define VT1724_PDMA2_PAUSE 0x20 -#define VT1724_PDMA1_PAUSE 0x10 -#define VT1724_RDMA1_PAUSE 0x04 -#define VT1724_RDMA0_PAUSE 0x02 -#define VT1724_PDMA0_PAUSE 0x01 -#define VT1724_MT_PLAYBACK_COUNT 0x1c /* word - playback count */ -#define VT1724_MT_CAPTURE_ADDR 0x20 /* dword - capture address */ -#define VT1724_MT_CAPTURE_SIZE 0x24 /* word - capture size */ -#define VT1724_MT_CAPTURE_COUNT 0x26 /* word - capture count */ - -#define VT1724_MT_ROUTE_PLAYBACK 0x2c /* word */ - -#define VT1724_MT_RDMA1_ADDR 0x30 /* dword - RDMA1 capture address */ -#define VT1724_MT_RDMA1_SIZE 0x34 /* word - RDMA1 capture size */ -#define VT1724_MT_RDMA1_COUNT 0x36 /* word - RDMA1 capture count */ - -#define VT1724_MT_SPDIF_CTRL 0x3c /* word */ -#define VT1724_MT_MONITOR_PEAKINDEX 0x3e /* byte */ -#define VT1724_MT_MONITOR_PEAKDATA 0x3f /* byte */ - -/* concurrent stereo channels */ -#define VT1724_MT_PDMA4_ADDR 0x40 /* dword */ -#define VT1724_MT_PDMA4_SIZE 0x44 /* word */ -#define VT1724_MT_PDMA4_COUNT 0x46 /* word */ -#define VT1724_MT_PDMA3_ADDR 0x50 /* dword */ -#define VT1724_MT_PDMA3_SIZE 0x54 /* word */ -#define VT1724_MT_PDMA3_COUNT 0x56 /* word */ -#define VT1724_MT_PDMA2_ADDR 0x60 /* dword */ -#define VT1724_MT_PDMA2_SIZE 0x64 /* word */ -#define VT1724_MT_PDMA2_COUNT 0x66 /* word */ -#define VT1724_MT_PDMA1_ADDR 0x70 /* dword */ -#define VT1724_MT_PDMA1_SIZE 0x74 /* word */ -#define VT1724_MT_PDMA1_COUNT 0x76 /* word */ - - -unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice, unsigned char dev, unsigned char addr); -void snd_vt1724_write_i2c(struct snd_ice1712 *ice, unsigned char dev, unsigned char addr, unsigned char data); - -#endif /* __SOUND_VT1724_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/ews.c b/ANDROID_3.4.5/sound/pci/ice1712/ews.c deleted file mode 100644 index 6fe35b81..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/ews.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* - * ALSA driver for ICEnsemble ICE1712 (Envy24) - * - * Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire - * - * Copyright (c) 2000 Jaroslav Kysela - * 2002 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ice1712.h" -#include "ews.h" - -#define SND_CS8404 -#include - -enum { - EWS_I2C_CS8404 = 0, EWS_I2C_PCF1, EWS_I2C_PCF2, - EWS_I2C_88D = 0, - EWS_I2C_6FIRE = 0 -}; - - -/* additional i2c devices for EWS boards */ -struct ews_spec { - struct snd_i2c_device *i2cdevs[3]; -}; - -/* - * access via i2c mode (for EWX 24/96, EWS 88MT&D) - */ - -/* send SDA and SCL */ -static void ewx_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data) -{ - struct snd_ice1712 *ice = bus->private_data; - unsigned char tmp = 0; - if (clk) - tmp |= ICE1712_EWX2496_SERIAL_CLOCK; - if (data) - tmp |= ICE1712_EWX2496_SERIAL_DATA; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - udelay(5); -} - -static int ewx_i2c_getclock(struct snd_i2c_bus *bus) -{ - struct snd_ice1712 *ice = bus->private_data; - return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_CLOCK ? 1 : 0; -} - -static int ewx_i2c_getdata(struct snd_i2c_bus *bus, int ack) -{ - struct snd_ice1712 *ice = bus->private_data; - int bit; - /* set RW pin to low */ - snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_RW); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, 0); - if (ack) - udelay(5); - bit = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_DATA ? 1 : 0; - /* set RW pin to high */ - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ICE1712_EWX2496_RW); - /* reset write mask */ - snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_SERIAL_CLOCK); - return bit; -} - -static void ewx_i2c_start(struct snd_i2c_bus *bus) -{ - struct snd_ice1712 *ice = bus->private_data; - unsigned char mask; - - snd_ice1712_save_gpio_status(ice); - /* set RW high */ - mask = ICE1712_EWX2496_RW; - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_EWX2496: - mask |= ICE1712_EWX2496_AK4524_CS; /* CS high also */ - break; - case ICE1712_SUBDEVICE_DMX6FIRE: - mask |= ICE1712_6FIRE_AK4524_CS_MASK; /* CS high also */ - break; - } - snd_ice1712_gpio_write_bits(ice, mask, mask); -} - -static void ewx_i2c_stop(struct snd_i2c_bus *bus) -{ - struct snd_ice1712 *ice = bus->private_data; - snd_ice1712_restore_gpio_status(ice); -} - -static void ewx_i2c_direction(struct snd_i2c_bus *bus, int clock, int data) -{ - struct snd_ice1712 *ice = bus->private_data; - unsigned char mask = 0; - - if (clock) - mask |= ICE1712_EWX2496_SERIAL_CLOCK; /* write SCL */ - if (data) - mask |= ICE1712_EWX2496_SERIAL_DATA; /* write SDA */ - ice->gpio.direction &= ~(ICE1712_EWX2496_SERIAL_CLOCK|ICE1712_EWX2496_SERIAL_DATA); - ice->gpio.direction |= mask; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->gpio.direction); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~mask); -} - -static struct snd_i2c_bit_ops snd_ice1712_ewx_cs8427_bit_ops = { - .start = ewx_i2c_start, - .stop = ewx_i2c_stop, - .direction = ewx_i2c_direction, - .setlines = ewx_i2c_setlines, - .getclock = ewx_i2c_getclock, - .getdata = ewx_i2c_getdata, -}; - - -/* - * AK4524 access - */ - -/* AK4524 chip select; address 0x48 bit 0-3 */ -static int snd_ice1712_ews88mt_chip_select(struct snd_ice1712 *ice, int chip_mask) -{ - struct ews_spec *spec = ice->spec; - unsigned char data, ndata; - - if (snd_BUG_ON(chip_mask < 0 || chip_mask > 0x0f)) - return -EINVAL; - snd_i2c_lock(ice->i2c); - if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) - goto __error; - ndata = (data & 0xf0) | chip_mask; - if (ndata != data) - if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF2], &ndata, 1) - != 1) - goto __error; - snd_i2c_unlock(ice->i2c); - return 0; - - __error: - snd_i2c_unlock(ice->i2c); - snd_printk(KERN_ERR "AK4524 chip select failed, check cable to the front module\n"); - return -EIO; -} - -/* start callback for EWS88MT, needs to select a certain chip mask */ -static void ews88mt_ak4524_lock(struct snd_akm4xxx *ak, int chip) -{ - struct snd_ice1712 *ice = ak->private_data[0]; - unsigned char tmp; - /* assert AK4524 CS */ - if (snd_ice1712_ews88mt_chip_select(ice, ~(1 << chip) & 0x0f) < 0) - snd_printk(KERN_ERR "fatal error (ews88mt chip select)\n"); - snd_ice1712_save_gpio_status(ice); - tmp = ICE1712_EWS88_SERIAL_DATA | - ICE1712_EWS88_SERIAL_CLOCK | - ICE1712_EWS88_RW; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, - ice->gpio.direction | tmp); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp); -} - -/* stop callback for EWS88MT, needs to deselect chip mask */ -static void ews88mt_ak4524_unlock(struct snd_akm4xxx *ak, int chip) -{ - struct snd_ice1712 *ice = ak->private_data[0]; - snd_ice1712_restore_gpio_status(ice); - udelay(1); - snd_ice1712_ews88mt_chip_select(ice, 0x0f); -} - -/* start callback for EWX24/96 */ -static void ewx2496_ak4524_lock(struct snd_akm4xxx *ak, int chip) -{ - struct snd_ice1712 *ice = ak->private_data[0]; - unsigned char tmp; - snd_ice1712_save_gpio_status(ice); - tmp = ICE1712_EWX2496_SERIAL_DATA | - ICE1712_EWX2496_SERIAL_CLOCK | - ICE1712_EWX2496_AK4524_CS | - ICE1712_EWX2496_RW; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, - ice->gpio.direction | tmp); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp); -} - -/* start callback for DMX 6fire */ -static void dmx6fire_ak4524_lock(struct snd_akm4xxx *ak, int chip) -{ - struct snd_ak4xxx_private *priv = (void *)ak->private_value[0]; - struct snd_ice1712 *ice = ak->private_data[0]; - unsigned char tmp; - snd_ice1712_save_gpio_status(ice); - tmp = priv->cs_mask = priv->cs_addr = (1 << chip) & ICE1712_6FIRE_AK4524_CS_MASK; - tmp |= ICE1712_6FIRE_SERIAL_DATA | - ICE1712_6FIRE_SERIAL_CLOCK | - ICE1712_6FIRE_RW; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, - ice->gpio.direction | tmp); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp); -} - -/* - * CS8404 interface on EWS88MT/D - */ - -static void snd_ice1712_ews_cs8404_spdif_write(struct snd_ice1712 *ice, unsigned char bits) -{ - struct ews_spec *spec = ice->spec; - unsigned char bytes[2]; - - snd_i2c_lock(ice->i2c); - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_EWS88MT: - case ICE1712_SUBDEVICE_EWS88MT_NEW: - case ICE1712_SUBDEVICE_PHASE88: - case ICE1712_SUBDEVICE_TS88: - if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_CS8404], &bits, 1) - != 1) - goto _error; - break; - case ICE1712_SUBDEVICE_EWS88D: - if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], bytes, 2) - != 2) - goto _error; - if (bits != bytes[1]) { - bytes[1] = bits; - if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D], - bytes, 2) != 2) - goto _error; - } - break; - } - _error: - snd_i2c_unlock(ice->i2c); -} - -/* - */ - -static void ews88_spdif_default_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol) -{ - snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_bits); -} - -static int ews88_spdif_default_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol) -{ - unsigned int val; - int change; - - val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958); - spin_lock_irq(&ice->reg_lock); - change = ice->spdif.cs8403_bits != val; - ice->spdif.cs8403_bits = val; - if (change && ice->playback_pro_substream == NULL) { - spin_unlock_irq(&ice->reg_lock); - snd_ice1712_ews_cs8404_spdif_write(ice, val); - } else { - spin_unlock_irq(&ice->reg_lock); - } - return change; -} - -static void ews88_spdif_stream_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol) -{ - snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_stream_bits); -} - -static int ews88_spdif_stream_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol) -{ - unsigned int val; - int change; - - val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958); - spin_lock_irq(&ice->reg_lock); - change = ice->spdif.cs8403_stream_bits != val; - ice->spdif.cs8403_stream_bits = val; - if (change && ice->playback_pro_substream != NULL) { - spin_unlock_irq(&ice->reg_lock); - snd_ice1712_ews_cs8404_spdif_write(ice, val); - } else { - spin_unlock_irq(&ice->reg_lock); - } - return change; -} - - -/* open callback */ -static void ews88_open_spdif(struct snd_ice1712 *ice, struct snd_pcm_substream *substream) -{ - ice->spdif.cs8403_stream_bits = ice->spdif.cs8403_bits; -} - -/* set up SPDIF for EWS88MT / EWS88D */ -static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate) -{ - unsigned long flags; - unsigned char tmp; - int change; - - spin_lock_irqsave(&ice->reg_lock, flags); - tmp = ice->spdif.cs8403_stream_bits; - if (tmp & 0x10) /* consumer */ - tmp &= (tmp & 0x01) ? ~0x06 : ~0x60; - switch (rate) { - case 32000: tmp |= (tmp & 0x01) ? 0x02 : 0x00; break; - case 44100: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break; - case 48000: tmp |= (tmp & 0x01) ? 0x04 : 0x20; break; - default: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break; - } - change = ice->spdif.cs8403_stream_bits != tmp; - ice->spdif.cs8403_stream_bits = tmp; - spin_unlock_irqrestore(&ice->reg_lock, flags); - if (change) - snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id); - snd_ice1712_ews_cs8404_spdif_write(ice, tmp); -} - - -/* - */ -static struct snd_akm4xxx akm_ews88mt __devinitdata = { - .num_adcs = 8, - .num_dacs = 8, - .type = SND_AK4524, - .ops = { - .lock = ews88mt_ak4524_lock, - .unlock = ews88mt_ak4524_unlock - } -}; - -static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { - .caddr = 2, - .cif = 1, /* CIF high */ - .data_mask = ICE1712_EWS88_SERIAL_DATA, - .clk_mask = ICE1712_EWS88_SERIAL_CLOCK, - .cs_mask = 0, - .cs_addr = 0, - .cs_none = 0, /* no chip select on gpio */ - .add_flags = ICE1712_EWS88_RW, /* set rw bit high */ - .mask_flags = 0, -}; - -static struct snd_akm4xxx akm_ewx2496 __devinitdata = { - .num_adcs = 2, - .num_dacs = 2, - .type = SND_AK4524, - .ops = { - .lock = ewx2496_ak4524_lock - } -}; - -static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { - .caddr = 2, - .cif = 1, /* CIF high */ - .data_mask = ICE1712_EWS88_SERIAL_DATA, - .clk_mask = ICE1712_EWS88_SERIAL_CLOCK, - .cs_mask = ICE1712_EWX2496_AK4524_CS, - .cs_addr = ICE1712_EWX2496_AK4524_CS, - .cs_none = 0, - .add_flags = ICE1712_EWS88_RW, /* set rw bit high */ - .mask_flags = 0, -}; - -static struct snd_akm4xxx akm_6fire __devinitdata = { - .num_adcs = 6, - .num_dacs = 6, - .type = SND_AK4524, - .ops = { - .lock = dmx6fire_ak4524_lock - } -}; - -static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = { - .caddr = 2, - .cif = 1, /* CIF high */ - .data_mask = ICE1712_6FIRE_SERIAL_DATA, - .clk_mask = ICE1712_6FIRE_SERIAL_CLOCK, - .cs_mask = 0, - .cs_addr = 0, /* set later */ - .cs_none = 0, - .add_flags = ICE1712_6FIRE_RW, /* set rw bit high */ - .mask_flags = 0, -}; - -/* - * initialize the chip - */ - -/* 6fire specific */ -#define PCF9554_REG_INPUT 0 -#define PCF9554_REG_OUTPUT 1 -#define PCF9554_REG_POLARITY 2 -#define PCF9554_REG_CONFIG 3 - -static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data); - -static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice) -{ - int err; - struct snd_akm4xxx *ak; - struct ews_spec *spec; - - /* set the analog DACs */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_EWX2496: - ice->num_total_dacs = 2; - ice->num_total_adcs = 2; - break; - case ICE1712_SUBDEVICE_EWS88MT: - case ICE1712_SUBDEVICE_EWS88MT_NEW: - case ICE1712_SUBDEVICE_PHASE88: - case ICE1712_SUBDEVICE_TS88: - ice->num_total_dacs = 8; - ice->num_total_adcs = 8; - break; - case ICE1712_SUBDEVICE_EWS88D: - /* Note: not analog but ADAT I/O */ - ice->num_total_dacs = 8; - ice->num_total_adcs = 8; - break; - case ICE1712_SUBDEVICE_DMX6FIRE: - ice->num_total_dacs = 6; - ice->num_total_adcs = 6; - break; - } - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - ice->spec = spec; - - /* create i2c */ - if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) { - snd_printk(KERN_ERR "unable to create I2C bus\n"); - return err; - } - ice->i2c->private_data = ice; - ice->i2c->hw_ops.bit = &snd_ice1712_ewx_cs8427_bit_ops; - - /* create i2c devices */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_DMX6FIRE: - err = snd_i2c_device_create(ice->i2c, "PCF9554", - ICE1712_6FIRE_PCF9554_ADDR, - &spec->i2cdevs[EWS_I2C_6FIRE]); - if (err < 0) { - snd_printk(KERN_ERR "PCF9554 initialization failed\n"); - return err; - } - snd_ice1712_6fire_write_pca(ice, PCF9554_REG_CONFIG, 0x80); - break; - case ICE1712_SUBDEVICE_EWS88MT: - case ICE1712_SUBDEVICE_EWS88MT_NEW: - case ICE1712_SUBDEVICE_PHASE88: - case ICE1712_SUBDEVICE_TS88: - - err = snd_i2c_device_create(ice->i2c, "CS8404", - ICE1712_EWS88MT_CS8404_ADDR, - &spec->i2cdevs[EWS_I2C_CS8404]); - if (err < 0) - return err; - err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)", - ICE1712_EWS88MT_INPUT_ADDR, - &spec->i2cdevs[EWS_I2C_PCF1]); - if (err < 0) - return err; - err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)", - ICE1712_EWS88MT_OUTPUT_ADDR, - &spec->i2cdevs[EWS_I2C_PCF2]); - if (err < 0) - return err; - /* Check if the front module is connected */ - if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0) - return err; - break; - case ICE1712_SUBDEVICE_EWS88D: - err = snd_i2c_device_create(ice->i2c, "PCF8575", - ICE1712_EWS88D_PCF_ADDR, - &spec->i2cdevs[EWS_I2C_88D]); - if (err < 0) - return err; - break; - } - - /* set up SPDIF interface */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_EWX2496: - if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0) - return err; - snd_cs8427_reg_write(ice->cs8427, CS8427_REG_RECVERRMASK, CS8427_UNLOCK | CS8427_CONF | CS8427_BIP | CS8427_PAR); - break; - case ICE1712_SUBDEVICE_DMX6FIRE: - if ((err = snd_ice1712_init_cs8427(ice, ICE1712_6FIRE_CS8427_ADDR)) < 0) - return err; - snd_cs8427_reg_write(ice->cs8427, CS8427_REG_RECVERRMASK, CS8427_UNLOCK | CS8427_CONF | CS8427_BIP | CS8427_PAR); - break; - case ICE1712_SUBDEVICE_EWS88MT: - case ICE1712_SUBDEVICE_EWS88MT_NEW: - case ICE1712_SUBDEVICE_PHASE88: - case ICE1712_SUBDEVICE_TS88: - case ICE1712_SUBDEVICE_EWS88D: - /* set up CS8404 */ - ice->spdif.ops.open = ews88_open_spdif; - ice->spdif.ops.setup_rate = ews88_setup_spdif; - ice->spdif.ops.default_get = ews88_spdif_default_get; - ice->spdif.ops.default_put = ews88_spdif_default_put; - ice->spdif.ops.stream_get = ews88_spdif_stream_get; - ice->spdif.ops.stream_put = ews88_spdif_stream_put; - /* Set spdif defaults */ - snd_ice1712_ews_cs8404_spdif_write(ice, ice->spdif.cs8403_bits); - break; - } - - /* no analog? */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_EWS88D: - return 0; - } - - /* analog section */ - ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - if (! ak) - return -ENOMEM; - ice->akm_codecs = 1; - - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_EWS88MT: - case ICE1712_SUBDEVICE_EWS88MT_NEW: - case ICE1712_SUBDEVICE_PHASE88: - case ICE1712_SUBDEVICE_TS88: - err = snd_ice1712_akm4xxx_init(ak, &akm_ews88mt, &akm_ews88mt_priv, ice); - break; - case ICE1712_SUBDEVICE_EWX2496: - err = snd_ice1712_akm4xxx_init(ak, &akm_ewx2496, &akm_ewx2496_priv, ice); - break; - case ICE1712_SUBDEVICE_DMX6FIRE: - err = snd_ice1712_akm4xxx_init(ak, &akm_6fire, &akm_6fire_priv, ice); - break; - default: - err = 0; - } - - return err; -} - -/* - * EWX 24/96 specific controls - */ - -/* i/o sensitivity - this callback is shared among other devices, too */ -static int snd_ice1712_ewx_io_sense_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){ - - static char *texts[2] = { - "+4dBu", "-10dBV", - }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= 2) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_ice1712_ewx_io_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char mask = kcontrol->private_value & 0xff; - - snd_ice1712_save_gpio_status(ice); - ucontrol->value.enumerated.item[0] = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & mask ? 1 : 0; - snd_ice1712_restore_gpio_status(ice); - return 0; -} - -static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char mask = kcontrol->private_value & 0xff; - int val, nval; - - if (kcontrol->private_value & (1 << 31)) - return -EPERM; - nval = ucontrol->value.enumerated.item[0] ? mask : 0; - snd_ice1712_save_gpio_status(ice); - val = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); - nval |= val & ~mask; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, nval); - snd_ice1712_restore_gpio_status(ice); - return val != nval; -} - -static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Sensitivity Switch", - .info = snd_ice1712_ewx_io_sense_info, - .get = snd_ice1712_ewx_io_sense_get, - .put = snd_ice1712_ewx_io_sense_put, - .private_value = ICE1712_EWX2496_AIN_SEL, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Output Sensitivity Switch", - .info = snd_ice1712_ewx_io_sense_info, - .get = snd_ice1712_ewx_io_sense_get, - .put = snd_ice1712_ewx_io_sense_put, - .private_value = ICE1712_EWX2496_AOUT_SEL, - }, -}; - - -/* - * EWS88MT specific controls - */ -/* analog output sensitivity;; address 0x48 bit 6 */ -static int snd_ice1712_ews88mt_output_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct ews_spec *spec = ice->spec; - unsigned char data; - - snd_i2c_lock(ice->i2c); - if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) { - snd_i2c_unlock(ice->i2c); - return -EIO; - } - snd_i2c_unlock(ice->i2c); - ucontrol->value.enumerated.item[0] = data & ICE1712_EWS88MT_OUTPUT_SENSE ? 1 : 0; /* high = -10dBV, low = +4dBu */ - return 0; -} - -/* analog output sensitivity;; address 0x48 bit 6 */ -static int snd_ice1712_ews88mt_output_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct ews_spec *spec = ice->spec; - unsigned char data, ndata; - - snd_i2c_lock(ice->i2c); - if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) { - snd_i2c_unlock(ice->i2c); - return -EIO; - } - ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0); - if (ndata != data && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF2], - &ndata, 1) != 1) { - snd_i2c_unlock(ice->i2c); - return -EIO; - } - snd_i2c_unlock(ice->i2c); - return ndata != data; -} - -/* analog input sensitivity; address 0x46 */ -static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct ews_spec *spec = ice->spec; - int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - unsigned char data; - - if (snd_BUG_ON(channel < 0 || channel > 7)) - return 0; - snd_i2c_lock(ice->i2c); - if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) { - snd_i2c_unlock(ice->i2c); - return -EIO; - } - /* reversed; high = +4dBu, low = -10dBV */ - ucontrol->value.enumerated.item[0] = data & (1 << channel) ? 0 : 1; - snd_i2c_unlock(ice->i2c); - return 0; -} - -/* analog output sensitivity; address 0x46 */ -static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct ews_spec *spec = ice->spec; - int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - unsigned char data, ndata; - - if (snd_BUG_ON(channel < 0 || channel > 7)) - return 0; - snd_i2c_lock(ice->i2c); - if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) { - snd_i2c_unlock(ice->i2c); - return -EIO; - } - ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel)); - if (ndata != data && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF1], - &ndata, 1) != 1) { - snd_i2c_unlock(ice->i2c); - return -EIO; - } - snd_i2c_unlock(ice->i2c); - return ndata != data; -} - -static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Sensitivity Switch", - .info = snd_ice1712_ewx_io_sense_info, - .get = snd_ice1712_ews88mt_input_sense_get, - .put = snd_ice1712_ews88mt_input_sense_put, - .count = 8, -}; - -static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Output Sensitivity Switch", - .info = snd_ice1712_ewx_io_sense_info, - .get = snd_ice1712_ews88mt_output_sense_get, - .put = snd_ice1712_ews88mt_output_sense_put, -}; - - -/* - * EWS88D specific controls - */ - -#define snd_ice1712_ews88d_control_info snd_ctl_boolean_mono_info - -static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct ews_spec *spec = ice->spec; - int shift = kcontrol->private_value & 0xff; - int invert = (kcontrol->private_value >> 8) & 1; - unsigned char data[2]; - - snd_i2c_lock(ice->i2c); - if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) { - snd_i2c_unlock(ice->i2c); - return -EIO; - } - snd_i2c_unlock(ice->i2c); - data[0] = (data[shift >> 3] >> (shift & 7)) & 0x01; - if (invert) - data[0] ^= 0x01; - ucontrol->value.integer.value[0] = data[0]; - return 0; -} - -static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct ews_spec *spec = ice->spec; - int shift = kcontrol->private_value & 0xff; - int invert = (kcontrol->private_value >> 8) & 1; - unsigned char data[2], ndata[2]; - int change; - - snd_i2c_lock(ice->i2c); - if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) { - snd_i2c_unlock(ice->i2c); - return -EIO; - } - ndata[shift >> 3] = data[shift >> 3] & ~(1 << (shift & 7)); - if (invert) { - if (! ucontrol->value.integer.value[0]) - ndata[shift >> 3] |= (1 << (shift & 7)); - } else { - if (ucontrol->value.integer.value[0]) - ndata[shift >> 3] |= (1 << (shift & 7)); - } - change = (data[shift >> 3] != ndata[shift >> 3]); - if (change && - snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) { - snd_i2c_unlock(ice->i2c); - return -EIO; - } - snd_i2c_unlock(ice->i2c); - return change; -} - -#define EWS88D_CONTROL(xiface, xname, xshift, xinvert, xaccess) \ -{ .iface = xiface,\ - .name = xname,\ - .access = xaccess,\ - .info = snd_ice1712_ews88d_control_info,\ - .get = snd_ice1712_ews88d_control_get,\ - .put = snd_ice1712_ews88d_control_put,\ - .private_value = xshift | (xinvert << 8),\ -} - -static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { - EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */ - EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0), - EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0), - EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "Enable ADAT", 3, 0, 0), - EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Through", 4, 1, 0), -}; - - -/* - * DMX 6Fire specific controls - */ - -static int snd_ice1712_6fire_read_pca(struct snd_ice1712 *ice, unsigned char reg) -{ - unsigned char byte; - struct ews_spec *spec = ice->spec; - - snd_i2c_lock(ice->i2c); - byte = reg; - snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1); - byte = 0; - if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) { - snd_i2c_unlock(ice->i2c); - printk(KERN_ERR "cannot read pca\n"); - return -EIO; - } - snd_i2c_unlock(ice->i2c); - return byte; -} - -static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data) -{ - unsigned char bytes[2]; - struct ews_spec *spec = ice->spec; - - snd_i2c_lock(ice->i2c); - bytes[0] = reg; - bytes[1] = data; - if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) { - snd_i2c_unlock(ice->i2c); - return -EIO; - } - snd_i2c_unlock(ice->i2c); - return 0; -} - -#define snd_ice1712_6fire_control_info snd_ctl_boolean_mono_info - -static int snd_ice1712_6fire_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int shift = kcontrol->private_value & 0xff; - int invert = (kcontrol->private_value >> 8) & 1; - int data; - - if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0) - return data; - data = (data >> shift) & 1; - if (invert) - data ^= 1; - ucontrol->value.integer.value[0] = data; - return 0; -} - -static int snd_ice1712_6fire_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int shift = kcontrol->private_value & 0xff; - int invert = (kcontrol->private_value >> 8) & 1; - int data, ndata; - - if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0) - return data; - ndata = data & ~(1 << shift); - if (ucontrol->value.integer.value[0]) - ndata |= (1 << shift); - if (invert) - ndata ^= (1 << shift); - if (data != ndata) { - snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata); - return 1; - } - return 0; -} - -static int snd_ice1712_6fire_select_input_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - static char *texts[4] = { - "Internal", "Front Input", "Rear Input", "Wave Table" - }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item >= 4) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_ice1712_6fire_select_input_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int data; - - if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0) - return data; - ucontrol->value.integer.value[0] = data & 3; - return 0; -} - -static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int data, ndata; - - if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0) - return data; - ndata = data & ~3; - ndata |= (ucontrol->value.integer.value[0] & 3); - if (data != ndata) { - snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata); - return 1; - } - return 0; -} - - -#define DMX6FIRE_CONTROL(xname, xshift, xinvert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\ - .name = xname,\ - .info = snd_ice1712_6fire_control_info,\ - .get = snd_ice1712_6fire_control_get,\ - .put = snd_ice1712_6fire_control_put,\ - .private_value = xshift | (xinvert << 8),\ -} - -static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Input Select", - .info = snd_ice1712_6fire_select_input_info, - .get = snd_ice1712_6fire_select_input_get, - .put = snd_ice1712_6fire_select_input_put, - }, - DMX6FIRE_CONTROL("Front Digital Input Switch", 2, 1), - // DMX6FIRE_CONTROL("Master Clock Select", 3, 0), - DMX6FIRE_CONTROL("Optical Digital Input Switch", 4, 0), - DMX6FIRE_CONTROL("Phono Analog Input Switch", 5, 0), - DMX6FIRE_CONTROL("Breakbox LED", 6, 0), -}; - - -static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice) -{ - unsigned int idx; - int err; - - /* all terratec cards have spdif, but cs8427 module builds it's own controls */ - if (ice->cs8427 == NULL) { - err = snd_ice1712_spdif_build_controls(ice); - if (err < 0) - return err; - } - - /* ak4524 controls */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_EWX2496: - case ICE1712_SUBDEVICE_EWS88MT: - case ICE1712_SUBDEVICE_EWS88MT_NEW: - case ICE1712_SUBDEVICE_PHASE88: - case ICE1712_SUBDEVICE_TS88: - case ICE1712_SUBDEVICE_DMX6FIRE: - err = snd_ice1712_akm4xxx_build_controls(ice); - if (err < 0) - return err; - break; - } - - /* card specific controls */ - switch (ice->eeprom.subvendor) { - case ICE1712_SUBDEVICE_EWX2496: - for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ewx2496_controls); idx++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ewx2496_controls[idx], ice)); - if (err < 0) - return err; - } - break; - case ICE1712_SUBDEVICE_EWS88MT: - case ICE1712_SUBDEVICE_EWS88MT_NEW: - case ICE1712_SUBDEVICE_PHASE88: - case ICE1712_SUBDEVICE_TS88: - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_input_sense, ice)); - if (err < 0) - return err; - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_output_sense, ice)); - if (err < 0) - return err; - break; - case ICE1712_SUBDEVICE_EWS88D: - for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ews88d_controls); idx++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88d_controls[idx], ice)); - if (err < 0) - return err; - } - break; - case ICE1712_SUBDEVICE_DMX6FIRE: - for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_6fire_controls); idx++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_6fire_controls[idx], ice)); - if (err < 0) - return err; - } - break; - } - return 0; -} - - -/* entry point */ -struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = { - { - .subvendor = ICE1712_SUBDEVICE_EWX2496, - .name = "TerraTec EWX24/96", - .model = "ewx2496", - .chip_init = snd_ice1712_ews_init, - .build_controls = snd_ice1712_ews_add_controls, - }, - { - .subvendor = ICE1712_SUBDEVICE_EWS88MT, - .name = "TerraTec EWS88MT", - .model = "ews88mt", - .chip_init = snd_ice1712_ews_init, - .build_controls = snd_ice1712_ews_add_controls, - }, - { - .subvendor = ICE1712_SUBDEVICE_EWS88MT_NEW, - .name = "TerraTec EWS88MT", - .model = "ews88mt_new", - .chip_init = snd_ice1712_ews_init, - .build_controls = snd_ice1712_ews_add_controls, - }, - { - .subvendor = ICE1712_SUBDEVICE_PHASE88, - .name = "TerraTec Phase88", - .model = "phase88", - .chip_init = snd_ice1712_ews_init, - .build_controls = snd_ice1712_ews_add_controls, - }, - { - .subvendor = ICE1712_SUBDEVICE_TS88, - .name = "terrasoniq TS88", - .model = "phase88", - .chip_init = snd_ice1712_ews_init, - .build_controls = snd_ice1712_ews_add_controls, - }, - { - .subvendor = ICE1712_SUBDEVICE_EWS88D, - .name = "TerraTec EWS88D", - .model = "ews88d", - .chip_init = snd_ice1712_ews_init, - .build_controls = snd_ice1712_ews_add_controls, - }, - { - .subvendor = ICE1712_SUBDEVICE_DMX6FIRE, - .name = "TerraTec DMX6Fire", - .model = "dmx6fire", - .chip_init = snd_ice1712_ews_init, - .build_controls = snd_ice1712_ews_add_controls, - .mpu401_1_name = "MIDI-Front DMX6fire", - .mpu401_2_name = "Wavetable DMX6fire", - .mpu401_2_info_flags = MPU401_INFO_OUTPUT, - }, - { } /* terminator */ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/ews.h b/ANDROID_3.4.5/sound/pci/ice1712/ews.h deleted file mode 100644 index 1c443718..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/ews.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef __SOUND_EWS_H -#define __SOUND_EWS_H - -/* - * ALSA driver for ICEnsemble ICE1712 (Envy24) - * - * Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire - * - * Copyright (c) 2000 Jaroslav Kysela - * 2002 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define EWS_DEVICE_DESC \ - "{TerraTec,EWX 24/96},"\ - "{TerraTec,EWS 88MT},"\ - "{TerraTec,EWS 88D},"\ - "{TerraTec,DMX 6Fire},"\ - "{TerraTec,Phase 88}," \ - "{terrasoniq,TS 88}," - -#define ICE1712_SUBDEVICE_EWX2496 0x3b153011 -#define ICE1712_SUBDEVICE_EWS88MT 0x3b151511 -#define ICE1712_SUBDEVICE_EWS88MT_NEW 0x3b152511 -#define ICE1712_SUBDEVICE_EWS88D 0x3b152b11 -#define ICE1712_SUBDEVICE_DMX6FIRE 0x3b153811 -#define ICE1712_SUBDEVICE_PHASE88 0x3b155111 -#define ICE1712_SUBDEVICE_TS88 0x3b157c11 - -/* entry point */ -extern struct snd_ice1712_card_info snd_ice1712_ews_cards[]; - - -/* TerraTec EWX 24/96 configuration definitions */ - -#define ICE1712_EWX2496_AK4524_CS 0x01 /* AK4524 chip select; low = active */ -#define ICE1712_EWX2496_AIN_SEL 0x02 /* input sensitivity switch; high = louder */ -#define ICE1712_EWX2496_AOUT_SEL 0x04 /* output sensitivity switch; high = louder */ -#define ICE1712_EWX2496_RW 0x08 /* read/write switch for i2c; high = write */ -#define ICE1712_EWX2496_SERIAL_DATA 0x10 /* i2c & ak4524 data */ -#define ICE1712_EWX2496_SERIAL_CLOCK 0x20 /* i2c & ak4524 clock */ -#define ICE1712_EWX2496_TX2 0x40 /* MIDI2 (not used) */ -#define ICE1712_EWX2496_RX2 0x80 /* MIDI2 (not used) */ - -/* TerraTec EWS 88MT/D configuration definitions */ -/* RW, SDA snd SCLK are identical with EWX24/96 */ -#define ICE1712_EWS88_CS8414_RATE 0x07 /* CS8414 sample rate: gpio 0-2 */ -#define ICE1712_EWS88_RW 0x08 /* read/write switch for i2c; high = write */ -#define ICE1712_EWS88_SERIAL_DATA 0x10 /* i2c & ak4524 data */ -#define ICE1712_EWS88_SERIAL_CLOCK 0x20 /* i2c & ak4524 clock */ -#define ICE1712_EWS88_TX2 0x40 /* MIDI2 (only on 88D) */ -#define ICE1712_EWS88_RX2 0x80 /* MIDI2 (only on 88D) */ - -/* i2c address */ -#define ICE1712_EWS88MT_CS8404_ADDR (0x40>>1) -#define ICE1712_EWS88MT_INPUT_ADDR (0x46>>1) -#define ICE1712_EWS88MT_OUTPUT_ADDR (0x48>>1) -#define ICE1712_EWS88MT_OUTPUT_SENSE 0x40 /* mask */ -#define ICE1712_EWS88D_PCF_ADDR (0x40>>1) - -/* TerraTec DMX 6Fire configuration definitions */ -#define ICE1712_6FIRE_AK4524_CS_MASK 0x07 /* AK4524 chip select #1-#3 */ -#define ICE1712_6FIRE_RW 0x08 /* read/write switch for i2c; high = write */ -#define ICE1712_6FIRE_SERIAL_DATA 0x10 /* i2c & ak4524 data */ -#define ICE1712_6FIRE_SERIAL_CLOCK 0x20 /* i2c & ak4524 clock */ -#define ICE1712_6FIRE_TX2 0x40 /* MIDI2 */ -#define ICE1712_6FIRE_RX2 0x80 /* MIDI2 */ - -#define ICE1712_6FIRE_PCF9554_ADDR (0x40>>1) -#define ICE1712_6FIRE_CS8427_ADDR (0x22) - -#endif /* __SOUND_EWS_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/hoontech.c b/ANDROID_3.4.5/sound/pci/ice1712/hoontech.c deleted file mode 100644 index 69141890..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/hoontech.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * ALSA driver for ICEnsemble ICE1712 (Envy24) - * - * Lowlevel functions for Hoontech STDSP24 - * - * Copyright (c) 2000 Jaroslav Kysela - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "ice1712.h" -#include "hoontech.h" - -/* Hoontech-specific setting */ -struct hoontech_spec { - unsigned char boxbits[4]; - unsigned int config; - unsigned short boxconfig[4]; -}; - -static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte) -{ - byte |= ICE1712_STDSP24_CLOCK_BIT; - udelay(100); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte); - byte &= ~ICE1712_STDSP24_CLOCK_BIT; - udelay(100); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte); - byte |= ICE1712_STDSP24_CLOCK_BIT; - udelay(100); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte); -} - -static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate) -{ - struct hoontech_spec *spec = ice->spec; - mutex_lock(&ice->gpio_mutex); - ICE1712_STDSP24_0_DAREAR(spec->boxbits, activate); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]); - mutex_unlock(&ice->gpio_mutex); -} - -static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate) -{ - struct hoontech_spec *spec = ice->spec; - mutex_lock(&ice->gpio_mutex); - ICE1712_STDSP24_3_MUTE(spec->boxbits, activate); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); - mutex_unlock(&ice->gpio_mutex); -} - -static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate) -{ - struct hoontech_spec *spec = ice->spec; - mutex_lock(&ice->gpio_mutex); - ICE1712_STDSP24_3_INSEL(spec->boxbits, activate); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); - mutex_unlock(&ice->gpio_mutex); -} - -static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate) -{ - struct hoontech_spec *spec = ice->spec; - - mutex_lock(&ice->gpio_mutex); - - /* select box */ - ICE1712_STDSP24_0_BOX(spec->boxbits, box); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]); - - /* prepare for write */ - if (chn == 3) - ICE1712_STDSP24_2_CHN4(spec->boxbits, 0); - ICE1712_STDSP24_2_MIDI1(spec->boxbits, activate); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); - - ICE1712_STDSP24_1_CHN1(spec->boxbits, 1); - ICE1712_STDSP24_1_CHN2(spec->boxbits, 1); - ICE1712_STDSP24_1_CHN3(spec->boxbits, 1); - ICE1712_STDSP24_2_CHN4(spec->boxbits, 1); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); - udelay(100); - if (chn == 3) { - ICE1712_STDSP24_2_CHN4(spec->boxbits, 0); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); - } else { - switch (chn) { - case 0: ICE1712_STDSP24_1_CHN1(spec->boxbits, 0); break; - case 1: ICE1712_STDSP24_1_CHN2(spec->boxbits, 0); break; - case 2: ICE1712_STDSP24_1_CHN3(spec->boxbits, 0); break; - } - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]); - } - udelay(100); - ICE1712_STDSP24_1_CHN1(spec->boxbits, 1); - ICE1712_STDSP24_1_CHN2(spec->boxbits, 1); - ICE1712_STDSP24_1_CHN3(spec->boxbits, 1); - ICE1712_STDSP24_2_CHN4(spec->boxbits, 1); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); - udelay(100); - - ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); - - mutex_unlock(&ice->gpio_mutex); -} - -static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master) -{ - struct hoontech_spec *spec = ice->spec; - - mutex_lock(&ice->gpio_mutex); - - /* select box */ - ICE1712_STDSP24_0_BOX(spec->boxbits, box); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]); - - ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1); - ICE1712_STDSP24_2_MIDI1(spec->boxbits, master); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); - - udelay(100); - - ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 0); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); - - mdelay(10); - - ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); - - mutex_unlock(&ice->gpio_mutex); -} - -static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate) -{ - struct hoontech_spec *spec = ice->spec; - mutex_lock(&ice->gpio_mutex); - ICE1712_STDSP24_3_MIDI2(spec->boxbits, activate); - snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); - mutex_unlock(&ice->gpio_mutex); -} - -static int __devinit snd_ice1712_hoontech_init(struct snd_ice1712 *ice) -{ - struct hoontech_spec *spec; - int box, chn; - - ice->num_total_dacs = 8; - ice->num_total_adcs = 8; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - ice->spec = spec; - - ICE1712_STDSP24_SET_ADDR(spec->boxbits, 0); - ICE1712_STDSP24_CLOCK(spec->boxbits, 0, 1); - ICE1712_STDSP24_0_BOX(spec->boxbits, 0); - ICE1712_STDSP24_0_DAREAR(spec->boxbits, 0); - - ICE1712_STDSP24_SET_ADDR(spec->boxbits, 1); - ICE1712_STDSP24_CLOCK(spec->boxbits, 1, 1); - ICE1712_STDSP24_1_CHN1(spec->boxbits, 1); - ICE1712_STDSP24_1_CHN2(spec->boxbits, 1); - ICE1712_STDSP24_1_CHN3(spec->boxbits, 1); - - ICE1712_STDSP24_SET_ADDR(spec->boxbits, 2); - ICE1712_STDSP24_CLOCK(spec->boxbits, 2, 1); - ICE1712_STDSP24_2_CHN4(spec->boxbits, 1); - ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1); - ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0); - - ICE1712_STDSP24_SET_ADDR(spec->boxbits, 3); - ICE1712_STDSP24_CLOCK(spec->boxbits, 3, 1); - ICE1712_STDSP24_3_MIDI2(spec->boxbits, 0); - ICE1712_STDSP24_3_MUTE(spec->boxbits, 1); - ICE1712_STDSP24_3_INSEL(spec->boxbits, 0); - - /* let's go - activate only functions in first box */ - spec->config = 0; - /* ICE1712_STDSP24_MUTE | - ICE1712_STDSP24_INSEL | - ICE1712_STDSP24_DAREAR; */ - /* These boxconfigs have caused problems in the past. - * The code is not optimal, but should now enable a working config to - * be achieved. - * ** MIDI IN can only be configured on one box ** - * ICE1712_STDSP24_BOX_MIDI1 needs to be set for that box. - * Tests on a ADAC2000 box suggest the box config flags do not - * work as would be expected, and the inputs are crossed. - * Setting ICE1712_STDSP24_BOX_MIDI1 and ICE1712_STDSP24_BOX_MIDI2 - * on the same box connects MIDI-In to both 401 uarts; both outputs - * are then active on all boxes. - * The default config here sets up everything on the first box. - * Alan Horstmann 5.2.2008 - */ - spec->boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 | - ICE1712_STDSP24_BOX_CHN2 | - ICE1712_STDSP24_BOX_CHN3 | - ICE1712_STDSP24_BOX_CHN4 | - ICE1712_STDSP24_BOX_MIDI1 | - ICE1712_STDSP24_BOX_MIDI2; - spec->boxconfig[1] = - spec->boxconfig[2] = - spec->boxconfig[3] = 0; - snd_ice1712_stdsp24_darear(ice, - (spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0); - snd_ice1712_stdsp24_mute(ice, - (spec->config & ICE1712_STDSP24_MUTE) ? 1 : 0); - snd_ice1712_stdsp24_insel(ice, - (spec->config & ICE1712_STDSP24_INSEL) ? 1 : 0); - for (box = 0; box < 4; box++) { - if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2) - snd_ice1712_stdsp24_midi2(ice, 1); - for (chn = 0; chn < 4; chn++) - snd_ice1712_stdsp24_box_channel(ice, box, chn, - (spec->boxconfig[box] & (1 << chn)) ? 1 : 0); - if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) - snd_ice1712_stdsp24_box_midi(ice, box, 1); - } - - return 0; -} - -/* - * AK4524 access - */ - -/* start callback for STDSP24 with modified hardware */ -static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip) -{ - struct snd_ice1712 *ice = ak->private_data[0]; - unsigned char tmp; - snd_ice1712_save_gpio_status(ice); - tmp = ICE1712_STDSP24_SERIAL_DATA | - ICE1712_STDSP24_SERIAL_CLOCK | - ICE1712_STDSP24_AK4524_CS; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, - ice->gpio.direction | tmp); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp); -} - -static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice) -{ - /* Hoontech STDSP24 with modified hardware */ - static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = { - .num_adcs = 2, - .num_dacs = 2, - .type = SND_AK4524, - .ops = { - .lock = stdsp24_ak4524_lock - } - }; - - static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = { - .caddr = 2, - .cif = 1, /* CIF high */ - .data_mask = ICE1712_STDSP24_SERIAL_DATA, - .clk_mask = ICE1712_STDSP24_SERIAL_CLOCK, - .cs_mask = ICE1712_STDSP24_AK4524_CS, - .cs_addr = ICE1712_STDSP24_AK4524_CS, - .cs_none = 0, - .add_flags = 0, - }; - - int err; - struct snd_akm4xxx *ak; - - /* set the analog DACs */ - ice->num_total_dacs = 2; - - /* set the analog ADCs */ - ice->num_total_adcs = 2; - - /* analog section */ - ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - if (! ak) - return -ENOMEM; - ice->akm_codecs = 1; - - err = snd_ice1712_akm4xxx_init(ak, &akm_stdsp24_mv, &akm_stdsp24_mv_priv, ice); - if (err < 0) - return err; - - /* ak4524 controls */ - err = snd_ice1712_akm4xxx_build_controls(ice); - if (err < 0) - return err; - - return 0; -} - -static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice) -{ - ice->gpio.write_mask = ice->eeprom.gpiomask; - ice->gpio.direction = ice->eeprom.gpiodir; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate); - return 0; -} - - -/* entry point */ -struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = { - { - .subvendor = ICE1712_SUBDEVICE_STDSP24, - .name = "Hoontech SoundTrack Audio DSP24", - .model = "dsp24", - .chip_init = snd_ice1712_hoontech_init, - .mpu401_1_name = "MIDI-1 Hoontech/STA DSP24", - .mpu401_2_name = "MIDI-2 Hoontech/STA DSP24", - }, - { - .subvendor = ICE1712_SUBDEVICE_STDSP24_VALUE, /* a dummy id */ - .name = "Hoontech SoundTrack Audio DSP24 Value", - .model = "dsp24_value", - .chip_init = snd_ice1712_value_init, - }, - { - .subvendor = ICE1712_SUBDEVICE_STDSP24_MEDIA7_1, - .name = "Hoontech STA DSP24 Media 7.1", - .model = "dsp24_71", - .chip_init = snd_ice1712_hoontech_init, - }, - { - .subvendor = ICE1712_SUBDEVICE_EVENT_EZ8, /* a dummy id */ - .name = "Event Electronics EZ8", - .model = "ez8", - .chip_init = snd_ice1712_ez8_init, - }, - { } /* terminator */ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/hoontech.h b/ANDROID_3.4.5/sound/pci/ice1712/hoontech.h deleted file mode 100644 index cc1da1e6..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/hoontech.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __SOUND_HOONTECH_H -#define __SOUND_HOONTECH_H - -/* - * ALSA driver for ICEnsemble ICE1712 (Envy24) - * - * Lowlevel functions for Hoontech STDSP24 - * - * Copyright (c) 2000 Jaroslav Kysela - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define HOONTECH_DEVICE_DESC \ - "{Hoontech,SoundTrack DSP 24}," \ - "{Hoontech,SoundTrack DSP 24 Value}," \ - "{Hoontech,SoundTrack DSP 24 Media 7.1}," \ - "{Event Electronics,EZ8}," - -#define ICE1712_SUBDEVICE_STDSP24 0x12141217 /* Hoontech SoundTrack Audio DSP 24 */ -#define ICE1712_SUBDEVICE_STDSP24_VALUE 0x00010010 /* A dummy id for Hoontech SoundTrack Audio DSP 24 Value */ -#define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */ -#define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */ - -extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[]; - - -/* Hoontech SoundTrack Audio DSP 24 GPIO definitions */ - -#define ICE1712_STDSP24_0_BOX(r, x) r[0] = ((r[0] & ~3) | ((x)&3)) -#define ICE1712_STDSP24_0_DAREAR(r, x) r[0] = ((r[0] & ~4) | (((x)&1)<<2)) -#define ICE1712_STDSP24_1_CHN1(r, x) r[1] = ((r[1] & ~1) | ((x)&1)) -#define ICE1712_STDSP24_1_CHN2(r, x) r[1] = ((r[1] & ~2) | (((x)&1)<<1)) -#define ICE1712_STDSP24_1_CHN3(r, x) r[1] = ((r[1] & ~4) | (((x)&1)<<2)) -#define ICE1712_STDSP24_2_CHN4(r, x) r[2] = ((r[2] & ~1) | ((x)&1)) -#define ICE1712_STDSP24_2_MIDIIN(r, x) r[2] = ((r[2] & ~2) | (((x)&1)<<1)) -#define ICE1712_STDSP24_2_MIDI1(r, x) r[2] = ((r[2] & ~4) | (((x)&1)<<2)) -#define ICE1712_STDSP24_3_MIDI2(r, x) r[3] = ((r[3] & ~1) | ((x)&1)) -#define ICE1712_STDSP24_3_MUTE(r, x) r[3] = ((r[3] & ~2) | (((x)&1)<<1)) -#define ICE1712_STDSP24_3_INSEL(r, x) r[3] = ((r[3] & ~4) | (((x)&1)<<2)) -#define ICE1712_STDSP24_SET_ADDR(r, a) r[a&3] = ((r[a&3] & ~0x18) | (((a)&3)<<3)) -#define ICE1712_STDSP24_CLOCK(r, a, c) r[a&3] = ((r[a&3] & ~0x20) | (((c)&1)<<5)) -#define ICE1712_STDSP24_CLOCK_BIT (1<<5) - -/* Hoontech SoundTrack Audio DSP 24 box configuration definitions */ - -#define ICE1712_STDSP24_DAREAR (1<<0) -#define ICE1712_STDSP24_MUTE (1<<1) -#define ICE1712_STDSP24_INSEL (1<<2) - -#define ICE1712_STDSP24_BOX_CHN1 (1<<0) /* input channel 1 */ -#define ICE1712_STDSP24_BOX_CHN2 (1<<1) /* input channel 2 */ -#define ICE1712_STDSP24_BOX_CHN3 (1<<2) /* input channel 3 */ -#define ICE1712_STDSP24_BOX_CHN4 (1<<3) /* input channel 4 */ -#define ICE1712_STDSP24_BOX_MIDI1 (1<<8) -#define ICE1712_STDSP24_BOX_MIDI2 (1<<9) - -/* Hoontech SoundTrack Audio DSP 24 Value definitions for modified hardware */ - -#define ICE1712_STDSP24_AK4524_CS 0x03 /* AK4524 chip select; low = active */ -#define ICE1712_STDSP24_SERIAL_DATA 0x0c /* ak4524 data */ -#define ICE1712_STDSP24_SERIAL_CLOCK 0x30 /* ak4524 clock */ - -#endif /* __SOUND_HOONTECH_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/ice1712.c b/ANDROID_3.4.5/sound/pci/ice1712/ice1712.c deleted file mode 100644 index 132a86e0..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/ice1712.c +++ /dev/null @@ -1,2824 +0,0 @@ -/* - * ALSA driver for ICEnsemble ICE1712 (Envy24) - * - * Copyright (c) 2000 Jaroslav Kysela - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* - NOTES: - - spdif nonaudio consumer mode does not work (at least with my - Sony STR-DB830) -*/ - -/* - * Changes: - * - * 2002.09.09 Takashi Iwai - * split the code to several files. each low-level routine - * is stored in the local file and called from registration - * function from card_info struct. - * - * 2002.11.26 James Stafford - * Added support for VT1724 (Envy24HT) - * I have left out support for 176.4 and 192 KHz for the moment. - * I also haven't done anything with the internal S/PDIF transmitter or the MPU-401 - * - * 2003.02.20 Taksahi Iwai - * Split vt1724 part to an independent driver. - * The GPIO is accessed through the callback functions now. - * - * 2004.03.31 Doug McLain - * Added support for Event Electronics EZ8 card to hoontech.c. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "ice1712.h" - -/* lowlevel routines */ -#include "delta.h" -#include "ews.h" -#include "hoontech.h" - -MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("ICEnsemble ICE1712 (Envy24)"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{" - HOONTECH_DEVICE_DESC - DELTA_DEVICE_DESC - EWS_DEVICE_DESC - "{ICEnsemble,Generic ICE1712}," - "{ICEnsemble,Generic Envy24}}"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ -static char *model[SNDRV_CARDS]; -static bool omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */ -static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transceiver reset timeout value in msec */ -static int dxr_enable[SNDRV_CARDS]; /* DXR enable for DMX6FIRE */ - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for ICE1712 soundcard."); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for ICE1712 soundcard."); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable ICE1712 soundcard."); -module_param_array(omni, bool, NULL, 0444); -MODULE_PARM_DESC(omni, "Enable Midiman M-Audio Delta Omni I/O support."); -module_param_array(cs8427_timeout, int, NULL, 0444); -MODULE_PARM_DESC(cs8427_timeout, "Define reset timeout for cs8427 chip in msec resolution."); -module_param_array(model, charp, NULL, 0444); -MODULE_PARM_DESC(model, "Use the given board model."); -module_param_array(dxr_enable, int, NULL, 0444); -MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); - - -static DEFINE_PCI_DEVICE_TABLE(snd_ice1712_ids) = { - { PCI_VDEVICE(ICE, PCI_DEVICE_ID_ICE_1712), 0 }, /* ICE1712 */ - { 0, } -}; - -MODULE_DEVICE_TABLE(pci, snd_ice1712_ids); - -static int snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice); -static int snd_ice1712_build_controls(struct snd_ice1712 *ice); - -static int PRO_RATE_LOCKED; -static int PRO_RATE_RESET = 1; -static unsigned int PRO_RATE_DEFAULT = 44100; - -/* - * Basic I/O - */ - -/* check whether the clock mode is spdif-in */ -static inline int is_spdif_master(struct snd_ice1712 *ice) -{ - return (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER) ? 1 : 0; -} - -static inline int is_pro_rate_locked(struct snd_ice1712 *ice) -{ - return is_spdif_master(ice) || PRO_RATE_LOCKED; -} - -static inline void snd_ice1712_ds_write(struct snd_ice1712 *ice, u8 channel, u8 addr, u32 data) -{ - outb((channel << 4) | addr, ICEDS(ice, INDEX)); - outl(data, ICEDS(ice, DATA)); -} - -static inline u32 snd_ice1712_ds_read(struct snd_ice1712 *ice, u8 channel, u8 addr) -{ - outb((channel << 4) | addr, ICEDS(ice, INDEX)); - return inl(ICEDS(ice, DATA)); -} - -static void snd_ice1712_ac97_write(struct snd_ac97 *ac97, - unsigned short reg, - unsigned short val) -{ - struct snd_ice1712 *ice = ac97->private_data; - int tm; - unsigned char old_cmd = 0; - - for (tm = 0; tm < 0x10000; tm++) { - old_cmd = inb(ICEREG(ice, AC97_CMD)); - if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ)) - continue; - if (!(old_cmd & ICE1712_AC97_READY)) - continue; - break; - } - outb(reg, ICEREG(ice, AC97_INDEX)); - outw(val, ICEREG(ice, AC97_DATA)); - old_cmd &= ~(ICE1712_AC97_PBK_VSR | ICE1712_AC97_CAP_VSR); - outb(old_cmd | ICE1712_AC97_WRITE, ICEREG(ice, AC97_CMD)); - for (tm = 0; tm < 0x10000; tm++) - if ((inb(ICEREG(ice, AC97_CMD)) & ICE1712_AC97_WRITE) == 0) - break; -} - -static unsigned short snd_ice1712_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - struct snd_ice1712 *ice = ac97->private_data; - int tm; - unsigned char old_cmd = 0; - - for (tm = 0; tm < 0x10000; tm++) { - old_cmd = inb(ICEREG(ice, AC97_CMD)); - if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ)) - continue; - if (!(old_cmd & ICE1712_AC97_READY)) - continue; - break; - } - outb(reg, ICEREG(ice, AC97_INDEX)); - outb(old_cmd | ICE1712_AC97_READ, ICEREG(ice, AC97_CMD)); - for (tm = 0; tm < 0x10000; tm++) - if ((inb(ICEREG(ice, AC97_CMD)) & ICE1712_AC97_READ) == 0) - break; - if (tm >= 0x10000) /* timeout */ - return ~0; - return inw(ICEREG(ice, AC97_DATA)); -} - -/* - * pro ac97 section - */ - -static void snd_ice1712_pro_ac97_write(struct snd_ac97 *ac97, - unsigned short reg, - unsigned short val) -{ - struct snd_ice1712 *ice = ac97->private_data; - int tm; - unsigned char old_cmd = 0; - - for (tm = 0; tm < 0x10000; tm++) { - old_cmd = inb(ICEMT(ice, AC97_CMD)); - if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ)) - continue; - if (!(old_cmd & ICE1712_AC97_READY)) - continue; - break; - } - outb(reg, ICEMT(ice, AC97_INDEX)); - outw(val, ICEMT(ice, AC97_DATA)); - old_cmd &= ~(ICE1712_AC97_PBK_VSR | ICE1712_AC97_CAP_VSR); - outb(old_cmd | ICE1712_AC97_WRITE, ICEMT(ice, AC97_CMD)); - for (tm = 0; tm < 0x10000; tm++) - if ((inb(ICEMT(ice, AC97_CMD)) & ICE1712_AC97_WRITE) == 0) - break; -} - - -static unsigned short snd_ice1712_pro_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - struct snd_ice1712 *ice = ac97->private_data; - int tm; - unsigned char old_cmd = 0; - - for (tm = 0; tm < 0x10000; tm++) { - old_cmd = inb(ICEMT(ice, AC97_CMD)); - if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ)) - continue; - if (!(old_cmd & ICE1712_AC97_READY)) - continue; - break; - } - outb(reg, ICEMT(ice, AC97_INDEX)); - outb(old_cmd | ICE1712_AC97_READ, ICEMT(ice, AC97_CMD)); - for (tm = 0; tm < 0x10000; tm++) - if ((inb(ICEMT(ice, AC97_CMD)) & ICE1712_AC97_READ) == 0) - break; - if (tm >= 0x10000) /* timeout */ - return ~0; - return inw(ICEMT(ice, AC97_DATA)); -} - -/* - * consumer ac97 digital mix - */ -#define snd_ice1712_digmix_route_ac97_info snd_ctl_boolean_mono_info - -static int snd_ice1712_digmix_route_ac97_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_ROUTECTRL)) & ICE1712_ROUTE_AC97 ? 1 : 0; - return 0; -} - -static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char val, nval; - - spin_lock_irq(&ice->reg_lock); - val = inb(ICEMT(ice, MONITOR_ROUTECTRL)); - nval = val & ~ICE1712_ROUTE_AC97; - if (ucontrol->value.integer.value[0]) - nval |= ICE1712_ROUTE_AC97; - outb(nval, ICEMT(ice, MONITOR_ROUTECTRL)); - spin_unlock_irq(&ice->reg_lock); - return val != nval; -} - -static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Digital Mixer To AC97", - .info = snd_ice1712_digmix_route_ac97_info, - .get = snd_ice1712_digmix_route_ac97_get, - .put = snd_ice1712_digmix_route_ac97_put, -}; - - -/* - * gpio operations - */ -static void snd_ice1712_set_gpio_dir(struct snd_ice1712 *ice, unsigned int data) -{ - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, data); - inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */ -} - -static unsigned int snd_ice1712_get_gpio_dir(struct snd_ice1712 *ice) -{ - return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION); -} - -static unsigned int snd_ice1712_get_gpio_mask(struct snd_ice1712 *ice) -{ - return snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK); -} - -static void snd_ice1712_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data) -{ - snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, data); - inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */ -} - -static unsigned int snd_ice1712_get_gpio_data(struct snd_ice1712 *ice) -{ - return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); -} - -static void snd_ice1712_set_gpio_data(struct snd_ice1712 *ice, unsigned int val) -{ - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, val); - inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */ -} - -/* - * - * CS8427 interface - * - */ - -/* - * change the input clock selection - * spdif_clock = 1 - IEC958 input, 0 - Envy24 - */ -static int snd_ice1712_cs8427_set_input_clock(struct snd_ice1712 *ice, int spdif_clock) -{ - unsigned char reg[2] = { 0x80 | 4, 0 }; /* CS8427 auto increment | register number 4 + data */ - unsigned char val, nval; - int res = 0; - - snd_i2c_lock(ice->i2c); - if (snd_i2c_sendbytes(ice->cs8427, reg, 1) != 1) { - snd_i2c_unlock(ice->i2c); - return -EIO; - } - if (snd_i2c_readbytes(ice->cs8427, &val, 1) != 1) { - snd_i2c_unlock(ice->i2c); - return -EIO; - } - nval = val & 0xf0; - if (spdif_clock) - nval |= 0x01; - else - nval |= 0x04; - if (val != nval) { - reg[1] = nval; - if (snd_i2c_sendbytes(ice->cs8427, reg, 2) != 2) { - res = -EIO; - } else { - res++; - } - } - snd_i2c_unlock(ice->i2c); - return res; -} - -/* - * spdif callbacks - */ -static void open_cs8427(struct snd_ice1712 *ice, struct snd_pcm_substream *substream) -{ - snd_cs8427_iec958_active(ice->cs8427, 1); -} - -static void close_cs8427(struct snd_ice1712 *ice, struct snd_pcm_substream *substream) -{ - snd_cs8427_iec958_active(ice->cs8427, 0); -} - -static void setup_cs8427(struct snd_ice1712 *ice, int rate) -{ - snd_cs8427_iec958_pcm(ice->cs8427, rate); -} - -/* - * create and initialize callbacks for cs8427 interface - */ -int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr) -{ - int err; - - err = snd_cs8427_create(ice->i2c, addr, - (ice->cs8427_timeout * HZ) / 1000, &ice->cs8427); - if (err < 0) { - snd_printk(KERN_ERR "CS8427 initialization failed\n"); - return err; - } - ice->spdif.ops.open = open_cs8427; - ice->spdif.ops.close = close_cs8427; - ice->spdif.ops.setup_rate = setup_cs8427; - return 0; -} - -static void snd_ice1712_set_input_clock_source(struct snd_ice1712 *ice, int spdif_is_master) -{ - /* change CS8427 clock source too */ - if (ice->cs8427) - snd_ice1712_cs8427_set_input_clock(ice, spdif_is_master); - /* notify ak4524 chip as well */ - if (spdif_is_master) { - unsigned int i; - for (i = 0; i < ice->akm_codecs; i++) { - if (ice->akm[i].ops.set_rate_val) - ice->akm[i].ops.set_rate_val(&ice->akm[i], 0); - } - } -} - -/* - * Interrupt handler - */ - -static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id) -{ - struct snd_ice1712 *ice = dev_id; - unsigned char status; - int handled = 0; - - while (1) { - status = inb(ICEREG(ice, IRQSTAT)); - if (status == 0) - break; - handled = 1; - if (status & ICE1712_IRQ_MPU1) { - if (ice->rmidi[0]) - snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data); - outb(ICE1712_IRQ_MPU1, ICEREG(ice, IRQSTAT)); - status &= ~ICE1712_IRQ_MPU1; - } - if (status & ICE1712_IRQ_TIMER) - outb(ICE1712_IRQ_TIMER, ICEREG(ice, IRQSTAT)); - if (status & ICE1712_IRQ_MPU2) { - if (ice->rmidi[1]) - snd_mpu401_uart_interrupt(irq, ice->rmidi[1]->private_data); - outb(ICE1712_IRQ_MPU2, ICEREG(ice, IRQSTAT)); - status &= ~ICE1712_IRQ_MPU2; - } - if (status & ICE1712_IRQ_PROPCM) { - unsigned char mtstat = inb(ICEMT(ice, IRQ)); - if (mtstat & ICE1712_MULTI_PBKSTATUS) { - if (ice->playback_pro_substream) - snd_pcm_period_elapsed(ice->playback_pro_substream); - outb(ICE1712_MULTI_PBKSTATUS, ICEMT(ice, IRQ)); - } - if (mtstat & ICE1712_MULTI_CAPSTATUS) { - if (ice->capture_pro_substream) - snd_pcm_period_elapsed(ice->capture_pro_substream); - outb(ICE1712_MULTI_CAPSTATUS, ICEMT(ice, IRQ)); - } - } - if (status & ICE1712_IRQ_FM) - outb(ICE1712_IRQ_FM, ICEREG(ice, IRQSTAT)); - if (status & ICE1712_IRQ_PBKDS) { - u32 idx; - u16 pbkstatus; - struct snd_pcm_substream *substream; - pbkstatus = inw(ICEDS(ice, INTSTAT)); - /* printk(KERN_DEBUG "pbkstatus = 0x%x\n", pbkstatus); */ - for (idx = 0; idx < 6; idx++) { - if ((pbkstatus & (3 << (idx * 2))) == 0) - continue; - substream = ice->playback_con_substream_ds[idx]; - if (substream != NULL) - snd_pcm_period_elapsed(substream); - outw(3 << (idx * 2), ICEDS(ice, INTSTAT)); - } - outb(ICE1712_IRQ_PBKDS, ICEREG(ice, IRQSTAT)); - } - if (status & ICE1712_IRQ_CONCAP) { - if (ice->capture_con_substream) - snd_pcm_period_elapsed(ice->capture_con_substream); - outb(ICE1712_IRQ_CONCAP, ICEREG(ice, IRQSTAT)); - } - if (status & ICE1712_IRQ_CONPBK) { - if (ice->playback_con_substream) - snd_pcm_period_elapsed(ice->playback_con_substream); - outb(ICE1712_IRQ_CONPBK, ICEREG(ice, IRQSTAT)); - } - } - return IRQ_RETVAL(handled); -} - - -/* - * PCM part - misc - */ - -static int snd_ice1712_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); -} - -static int snd_ice1712_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - -/* - * PCM part - consumer I/O - */ - -static int snd_ice1712_playback_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - int result = 0; - u32 tmp; - - spin_lock(&ice->reg_lock); - tmp = snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL); - if (cmd == SNDRV_PCM_TRIGGER_START) { - tmp |= 1; - } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { - tmp &= ~1; - } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) { - tmp |= 2; - } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) { - tmp &= ~2; - } else { - result = -EINVAL; - } - snd_ice1712_write(ice, ICE1712_IREG_PBK_CTRL, tmp); - spin_unlock(&ice->reg_lock); - return result; -} - -static int snd_ice1712_playback_ds_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - int result = 0; - u32 tmp; - - spin_lock(&ice->reg_lock); - tmp = snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL); - if (cmd == SNDRV_PCM_TRIGGER_START) { - tmp |= 1; - } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { - tmp &= ~1; - } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) { - tmp |= 2; - } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) { - tmp &= ~2; - } else { - result = -EINVAL; - } - snd_ice1712_ds_write(ice, substream->number * 2, ICE1712_DSC_CONTROL, tmp); - spin_unlock(&ice->reg_lock); - return result; -} - -static int snd_ice1712_capture_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - int result = 0; - u8 tmp; - - spin_lock(&ice->reg_lock); - tmp = snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL); - if (cmd == SNDRV_PCM_TRIGGER_START) { - tmp |= 1; - } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { - tmp &= ~1; - } else { - result = -EINVAL; - } - snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp); - spin_unlock(&ice->reg_lock); - return result; -} - -static int snd_ice1712_playback_prepare(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - u32 period_size, buf_size, rate, tmp; - - period_size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1; - buf_size = snd_pcm_lib_buffer_bytes(substream) - 1; - tmp = 0x0000; - if (snd_pcm_format_width(runtime->format) == 16) - tmp |= 0x10; - if (runtime->channels == 2) - tmp |= 0x08; - rate = (runtime->rate * 8192) / 375; - if (rate > 0x000fffff) - rate = 0x000fffff; - spin_lock_irq(&ice->reg_lock); - outb(0, ice->ddma_port + 15); - outb(ICE1712_DMA_MODE_WRITE | ICE1712_DMA_AUTOINIT, ice->ddma_port + 0x0b); - outl(runtime->dma_addr, ice->ddma_port + 0); - outw(buf_size, ice->ddma_port + 4); - snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_LO, rate & 0xff); - snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_MID, (rate >> 8) & 0xff); - snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_HI, (rate >> 16) & 0xff); - snd_ice1712_write(ice, ICE1712_IREG_PBK_CTRL, tmp); - snd_ice1712_write(ice, ICE1712_IREG_PBK_COUNT_LO, period_size & 0xff); - snd_ice1712_write(ice, ICE1712_IREG_PBK_COUNT_HI, period_size >> 8); - snd_ice1712_write(ice, ICE1712_IREG_PBK_LEFT, 0); - snd_ice1712_write(ice, ICE1712_IREG_PBK_RIGHT, 0); - spin_unlock_irq(&ice->reg_lock); - return 0; -} - -static int snd_ice1712_playback_ds_prepare(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - u32 period_size, buf_size, rate, tmp, chn; - - period_size = snd_pcm_lib_period_bytes(substream) - 1; - buf_size = snd_pcm_lib_buffer_bytes(substream) - 1; - tmp = 0x0064; - if (snd_pcm_format_width(runtime->format) == 16) - tmp &= ~0x04; - if (runtime->channels == 2) - tmp |= 0x08; - rate = (runtime->rate * 8192) / 375; - if (rate > 0x000fffff) - rate = 0x000fffff; - ice->playback_con_active_buf[substream->number] = 0; - ice->playback_con_virt_addr[substream->number] = runtime->dma_addr; - chn = substream->number * 2; - spin_lock_irq(&ice->reg_lock); - snd_ice1712_ds_write(ice, chn, ICE1712_DSC_ADDR0, runtime->dma_addr); - snd_ice1712_ds_write(ice, chn, ICE1712_DSC_COUNT0, period_size); - snd_ice1712_ds_write(ice, chn, ICE1712_DSC_ADDR1, runtime->dma_addr + (runtime->periods > 1 ? period_size + 1 : 0)); - snd_ice1712_ds_write(ice, chn, ICE1712_DSC_COUNT1, period_size); - snd_ice1712_ds_write(ice, chn, ICE1712_DSC_RATE, rate); - snd_ice1712_ds_write(ice, chn, ICE1712_DSC_VOLUME, 0); - snd_ice1712_ds_write(ice, chn, ICE1712_DSC_CONTROL, tmp); - if (runtime->channels == 2) { - snd_ice1712_ds_write(ice, chn + 1, ICE1712_DSC_RATE, rate); - snd_ice1712_ds_write(ice, chn + 1, ICE1712_DSC_VOLUME, 0); - } - spin_unlock_irq(&ice->reg_lock); - return 0; -} - -static int snd_ice1712_capture_prepare(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - u32 period_size, buf_size; - u8 tmp; - - period_size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1; - buf_size = snd_pcm_lib_buffer_bytes(substream) - 1; - tmp = 0x06; - if (snd_pcm_format_width(runtime->format) == 16) - tmp &= ~0x04; - if (runtime->channels == 2) - tmp &= ~0x02; - spin_lock_irq(&ice->reg_lock); - outl(ice->capture_con_virt_addr = runtime->dma_addr, ICEREG(ice, CONCAP_ADDR)); - outw(buf_size, ICEREG(ice, CONCAP_COUNT)); - snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_HI, period_size >> 8); - snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_LO, period_size & 0xff); - snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp); - spin_unlock_irq(&ice->reg_lock); - snd_ac97_set_rate(ice->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate); - return 0; -} - -static snd_pcm_uframes_t snd_ice1712_playback_pointer(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - size_t ptr; - - if (!(snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL) & 1)) - return 0; - ptr = runtime->buffer_size - inw(ice->ddma_port + 4); - if (ptr == runtime->buffer_size) - ptr = 0; - return bytes_to_frames(substream->runtime, ptr); -} - -static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - u8 addr; - size_t ptr; - - if (!(snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL) & 1)) - return 0; - if (ice->playback_con_active_buf[substream->number]) - addr = ICE1712_DSC_ADDR1; - else - addr = ICE1712_DSC_ADDR0; - ptr = snd_ice1712_ds_read(ice, substream->number * 2, addr) - - ice->playback_con_virt_addr[substream->number]; - if (ptr == substream->runtime->buffer_size) - ptr = 0; - return bytes_to_frames(substream->runtime, ptr); -} - -static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - size_t ptr; - - if (!(snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL) & 1)) - return 0; - ptr = inl(ICEREG(ice, CONCAP_ADDR)) - ice->capture_con_virt_addr; - if (ptr == substream->runtime->buffer_size) - ptr = 0; - return bytes_to_frames(substream->runtime, ptr); -} - -static const struct snd_pcm_hardware snd_ice1712_playback = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE), - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, - .rate_min = 4000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (64*1024), - .period_bytes_min = 64, - .period_bytes_max = (64*1024), - .periods_min = 1, - .periods_max = 1024, - .fifo_size = 0, -}; - -static const struct snd_pcm_hardware snd_ice1712_playback_ds = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE), - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, - .rate_min = 4000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (128*1024), - .period_bytes_min = 64, - .period_bytes_max = (128*1024), - .periods_min = 2, - .periods_max = 2, - .fifo_size = 0, -}; - -static const struct snd_pcm_hardware snd_ice1712_capture = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, - .rate_min = 4000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (64*1024), - .period_bytes_min = 64, - .period_bytes_max = (64*1024), - .periods_min = 1, - .periods_max = 1024, - .fifo_size = 0, -}; - -static int snd_ice1712_playback_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - ice->playback_con_substream = substream; - runtime->hw = snd_ice1712_playback; - return 0; -} - -static int snd_ice1712_playback_ds_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - u32 tmp; - - ice->playback_con_substream_ds[substream->number] = substream; - runtime->hw = snd_ice1712_playback_ds; - spin_lock_irq(&ice->reg_lock); - tmp = inw(ICEDS(ice, INTMASK)) & ~(1 << (substream->number * 2)); - outw(tmp, ICEDS(ice, INTMASK)); - spin_unlock_irq(&ice->reg_lock); - return 0; -} - -static int snd_ice1712_capture_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - ice->capture_con_substream = substream; - runtime->hw = snd_ice1712_capture; - runtime->hw.rates = ice->ac97->rates[AC97_RATES_ADC]; - if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000)) - runtime->hw.rate_min = 48000; - return 0; -} - -static int snd_ice1712_playback_close(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - ice->playback_con_substream = NULL; - return 0; -} - -static int snd_ice1712_playback_ds_close(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - u32 tmp; - - spin_lock_irq(&ice->reg_lock); - tmp = inw(ICEDS(ice, INTMASK)) | (3 << (substream->number * 2)); - outw(tmp, ICEDS(ice, INTMASK)); - spin_unlock_irq(&ice->reg_lock); - ice->playback_con_substream_ds[substream->number] = NULL; - return 0; -} - -static int snd_ice1712_capture_close(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - ice->capture_con_substream = NULL; - return 0; -} - -static struct snd_pcm_ops snd_ice1712_playback_ops = { - .open = snd_ice1712_playback_open, - .close = snd_ice1712_playback_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_ice1712_hw_params, - .hw_free = snd_ice1712_hw_free, - .prepare = snd_ice1712_playback_prepare, - .trigger = snd_ice1712_playback_trigger, - .pointer = snd_ice1712_playback_pointer, -}; - -static struct snd_pcm_ops snd_ice1712_playback_ds_ops = { - .open = snd_ice1712_playback_ds_open, - .close = snd_ice1712_playback_ds_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_ice1712_hw_params, - .hw_free = snd_ice1712_hw_free, - .prepare = snd_ice1712_playback_ds_prepare, - .trigger = snd_ice1712_playback_ds_trigger, - .pointer = snd_ice1712_playback_ds_pointer, -}; - -static struct snd_pcm_ops snd_ice1712_capture_ops = { - .open = snd_ice1712_capture_open, - .close = snd_ice1712_capture_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_ice1712_hw_params, - .hw_free = snd_ice1712_hw_free, - .prepare = snd_ice1712_capture_prepare, - .trigger = snd_ice1712_capture_trigger, - .pointer = snd_ice1712_capture_pointer, -}; - -static int __devinit snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) -{ - struct snd_pcm *pcm; - int err; - - if (rpcm) - *rpcm = NULL; - err = snd_pcm_new(ice->card, "ICE1712 consumer", device, 1, 1, &pcm); - if (err < 0) - return err; - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_ops); - - pcm->private_data = ice; - pcm->info_flags = 0; - strcpy(pcm->name, "ICE1712 consumer"); - ice->pcm = pcm; - - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(ice->pci), 64*1024, 64*1024); - - if (rpcm) - *rpcm = pcm; - - printk(KERN_WARNING "Consumer PCM code does not work well at the moment --jk\n"); - - return 0; -} - -static int __devinit snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) -{ - struct snd_pcm *pcm; - int err; - - if (rpcm) - *rpcm = NULL; - err = snd_pcm_new(ice->card, "ICE1712 consumer (DS)", device, 6, 0, &pcm); - if (err < 0) - return err; - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_ds_ops); - - pcm->private_data = ice; - pcm->info_flags = 0; - strcpy(pcm->name, "ICE1712 consumer (DS)"); - ice->pcm_ds = pcm; - - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(ice->pci), 64*1024, 128*1024); - - if (rpcm) - *rpcm = pcm; - - return 0; -} - -/* - * PCM code - professional part (multitrack) - */ - -static unsigned int rates[] = { 8000, 9600, 11025, 12000, 16000, 22050, 24000, - 32000, 44100, 48000, 64000, 88200, 96000 }; - -static struct snd_pcm_hw_constraint_list hw_constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static int snd_ice1712_pro_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - switch (cmd) { - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - { - unsigned int what; - unsigned int old; - if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) - return -EINVAL; - what = ICE1712_PLAYBACK_PAUSE; - snd_pcm_trigger_done(substream, substream); - spin_lock(&ice->reg_lock); - old = inl(ICEMT(ice, PLAYBACK_CONTROL)); - if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) - old |= what; - else - old &= ~what; - outl(old, ICEMT(ice, PLAYBACK_CONTROL)); - spin_unlock(&ice->reg_lock); - break; - } - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_STOP: - { - unsigned int what = 0; - unsigned int old; - struct snd_pcm_substream *s; - - snd_pcm_group_for_each_entry(s, substream) { - if (s == ice->playback_pro_substream) { - what |= ICE1712_PLAYBACK_START; - snd_pcm_trigger_done(s, substream); - } else if (s == ice->capture_pro_substream) { - what |= ICE1712_CAPTURE_START_SHADOW; - snd_pcm_trigger_done(s, substream); - } - } - spin_lock(&ice->reg_lock); - old = inl(ICEMT(ice, PLAYBACK_CONTROL)); - if (cmd == SNDRV_PCM_TRIGGER_START) - old |= what; - else - old &= ~what; - outl(old, ICEMT(ice, PLAYBACK_CONTROL)); - spin_unlock(&ice->reg_lock); - break; - } - default: - return -EINVAL; - } - return 0; -} - -/* - */ -static void snd_ice1712_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, int force) -{ - unsigned long flags; - unsigned char val, old; - unsigned int i; - - switch (rate) { - case 8000: val = 6; break; - case 9600: val = 3; break; - case 11025: val = 10; break; - case 12000: val = 2; break; - case 16000: val = 5; break; - case 22050: val = 9; break; - case 24000: val = 1; break; - case 32000: val = 4; break; - case 44100: val = 8; break; - case 48000: val = 0; break; - case 64000: val = 15; break; - case 88200: val = 11; break; - case 96000: val = 7; break; - default: - snd_BUG(); - val = 0; - rate = 48000; - break; - } - - spin_lock_irqsave(&ice->reg_lock, flags); - if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW| - ICE1712_PLAYBACK_PAUSE| - ICE1712_PLAYBACK_START)) { -__out: - spin_unlock_irqrestore(&ice->reg_lock, flags); - return; - } - if (!force && is_pro_rate_locked(ice)) - goto __out; - - old = inb(ICEMT(ice, RATE)); - if (!force && old == val) - goto __out; - outb(val, ICEMT(ice, RATE)); - spin_unlock_irqrestore(&ice->reg_lock, flags); - - if (ice->gpio.set_pro_rate) - ice->gpio.set_pro_rate(ice, rate); - for (i = 0; i < ice->akm_codecs; i++) { - if (ice->akm[i].ops.set_rate_val) - ice->akm[i].ops.set_rate_val(&ice->akm[i], rate); - } - if (ice->spdif.ops.setup_rate) - ice->spdif.ops.setup_rate(ice, rate); -} - -static int snd_ice1712_playback_pro_prepare(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - ice->playback_pro_size = snd_pcm_lib_buffer_bytes(substream); - spin_lock_irq(&ice->reg_lock); - outl(substream->runtime->dma_addr, ICEMT(ice, PLAYBACK_ADDR)); - outw((ice->playback_pro_size >> 2) - 1, ICEMT(ice, PLAYBACK_SIZE)); - outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, PLAYBACK_COUNT)); - spin_unlock_irq(&ice->reg_lock); - - return 0; -} - -static int snd_ice1712_playback_pro_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0); - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); -} - -static int snd_ice1712_capture_pro_prepare(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - ice->capture_pro_size = snd_pcm_lib_buffer_bytes(substream); - spin_lock_irq(&ice->reg_lock); - outl(substream->runtime->dma_addr, ICEMT(ice, CAPTURE_ADDR)); - outw((ice->capture_pro_size >> 2) - 1, ICEMT(ice, CAPTURE_SIZE)); - outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, CAPTURE_COUNT)); - spin_unlock_irq(&ice->reg_lock); - return 0; -} - -static int snd_ice1712_capture_pro_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0); - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); -} - -static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - size_t ptr; - - if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START)) - return 0; - ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2); - if (ptr == substream->runtime->buffer_size) - ptr = 0; - return bytes_to_frames(substream->runtime, ptr); -} - -static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - size_t ptr; - - if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW)) - return 0; - ptr = ice->capture_pro_size - (inw(ICEMT(ice, CAPTURE_SIZE)) << 2); - if (ptr == substream->runtime->buffer_size) - ptr = 0; - return bytes_to_frames(substream->runtime, ptr); -} - -static const struct snd_pcm_hardware snd_ice1712_playback_pro = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START), - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000, - .rate_min = 4000, - .rate_max = 96000, - .channels_min = 10, - .channels_max = 10, - .buffer_bytes_max = (256*1024), - .period_bytes_min = 10 * 4 * 2, - .period_bytes_max = 131040, - .periods_min = 1, - .periods_max = 1024, - .fifo_size = 0, -}; - -static const struct snd_pcm_hardware snd_ice1712_capture_pro = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START), - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000, - .rate_min = 4000, - .rate_max = 96000, - .channels_min = 12, - .channels_max = 12, - .buffer_bytes_max = (256*1024), - .period_bytes_min = 12 * 4 * 2, - .period_bytes_max = 131040, - .periods_min = 1, - .periods_max = 1024, - .fifo_size = 0, -}; - -static int snd_ice1712_playback_pro_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - ice->playback_pro_substream = substream; - runtime->hw = snd_ice1712_playback_pro; - snd_pcm_set_sync(substream); - snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); - if (is_pro_rate_locked(ice)) { - runtime->hw.rate_min = PRO_RATE_DEFAULT; - runtime->hw.rate_max = PRO_RATE_DEFAULT; - } - - if (ice->spdif.ops.open) - ice->spdif.ops.open(ice, substream); - - return 0; -} - -static int snd_ice1712_capture_pro_open(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - - ice->capture_pro_substream = substream; - runtime->hw = snd_ice1712_capture_pro; - snd_pcm_set_sync(substream); - snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); - if (is_pro_rate_locked(ice)) { - runtime->hw.rate_min = PRO_RATE_DEFAULT; - runtime->hw.rate_max = PRO_RATE_DEFAULT; - } - - return 0; -} - -static int snd_ice1712_playback_pro_close(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - if (PRO_RATE_RESET) - snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 0); - ice->playback_pro_substream = NULL; - if (ice->spdif.ops.close) - ice->spdif.ops.close(ice, substream); - - return 0; -} - -static int snd_ice1712_capture_pro_close(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - if (PRO_RATE_RESET) - snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 0); - ice->capture_pro_substream = NULL; - return 0; -} - -static struct snd_pcm_ops snd_ice1712_playback_pro_ops = { - .open = snd_ice1712_playback_pro_open, - .close = snd_ice1712_playback_pro_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_ice1712_playback_pro_hw_params, - .hw_free = snd_ice1712_hw_free, - .prepare = snd_ice1712_playback_pro_prepare, - .trigger = snd_ice1712_pro_trigger, - .pointer = snd_ice1712_playback_pro_pointer, -}; - -static struct snd_pcm_ops snd_ice1712_capture_pro_ops = { - .open = snd_ice1712_capture_pro_open, - .close = snd_ice1712_capture_pro_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_ice1712_capture_pro_hw_params, - .hw_free = snd_ice1712_hw_free, - .prepare = snd_ice1712_capture_pro_prepare, - .trigger = snd_ice1712_pro_trigger, - .pointer = snd_ice1712_capture_pro_pointer, -}; - -static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) -{ - struct snd_pcm *pcm; - int err; - - if (rpcm) - *rpcm = NULL; - err = snd_pcm_new(ice->card, "ICE1712 multi", device, 1, 1, &pcm); - if (err < 0) - return err; - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_pro_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_pro_ops); - - pcm->private_data = ice; - pcm->info_flags = 0; - strcpy(pcm->name, "ICE1712 multi"); - - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(ice->pci), 256*1024, 256*1024); - - ice->pcm_pro = pcm; - if (rpcm) - *rpcm = pcm; - - if (ice->cs8427) { - /* assign channels to iec958 */ - err = snd_cs8427_iec958_build(ice->cs8427, - pcm->streams[0].substream, - pcm->streams[1].substream); - if (err < 0) - return err; - } - - err = snd_ice1712_build_pro_mixer(ice); - if (err < 0) - return err; - return 0; -} - -/* - * Mixer section - */ - -static void snd_ice1712_update_volume(struct snd_ice1712 *ice, int index) -{ - unsigned int vol = ice->pro_volumes[index]; - unsigned short val = 0; - - val |= (vol & 0x8000) == 0 ? (96 - (vol & 0x7f)) : 0x7f; - val |= ((vol & 0x80000000) == 0 ? (96 - ((vol >> 16) & 0x7f)) : 0x7f) << 8; - outb(index, ICEMT(ice, MONITOR_INDEX)); - outw(val, ICEMT(ice, MONITOR_VOLUME)); -} - -#define snd_ice1712_pro_mixer_switch_info snd_ctl_boolean_stereo_info - -static int snd_ice1712_pro_mixer_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + - kcontrol->private_value; - - spin_lock_irq(&ice->reg_lock); - ucontrol->value.integer.value[0] = - !((ice->pro_volumes[priv_idx] >> 15) & 1); - ucontrol->value.integer.value[1] = - !((ice->pro_volumes[priv_idx] >> 31) & 1); - spin_unlock_irq(&ice->reg_lock); - return 0; -} - -static int snd_ice1712_pro_mixer_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + - kcontrol->private_value; - unsigned int nval, change; - - nval = (ucontrol->value.integer.value[0] ? 0 : 0x00008000) | - (ucontrol->value.integer.value[1] ? 0 : 0x80000000); - spin_lock_irq(&ice->reg_lock); - nval |= ice->pro_volumes[priv_idx] & ~0x80008000; - change = nval != ice->pro_volumes[priv_idx]; - ice->pro_volumes[priv_idx] = nval; - snd_ice1712_update_volume(ice, priv_idx); - spin_unlock_irq(&ice->reg_lock); - return change; -} - -static int snd_ice1712_pro_mixer_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 96; - return 0; -} - -static int snd_ice1712_pro_mixer_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + - kcontrol->private_value; - - spin_lock_irq(&ice->reg_lock); - ucontrol->value.integer.value[0] = - (ice->pro_volumes[priv_idx] >> 0) & 127; - ucontrol->value.integer.value[1] = - (ice->pro_volumes[priv_idx] >> 16) & 127; - spin_unlock_irq(&ice->reg_lock); - return 0; -} - -static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + - kcontrol->private_value; - unsigned int nval, change; - - nval = (ucontrol->value.integer.value[0] & 127) | - ((ucontrol->value.integer.value[1] & 127) << 16); - spin_lock_irq(&ice->reg_lock); - nval |= ice->pro_volumes[priv_idx] & ~0x007f007f; - change = nval != ice->pro_volumes[priv_idx]; - ice->pro_volumes[priv_idx] = nval; - snd_ice1712_update_volume(ice, priv_idx); - spin_unlock_irq(&ice->reg_lock); - return change; -} - -static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0); - -static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Multi Playback Switch", - .info = snd_ice1712_pro_mixer_switch_info, - .get = snd_ice1712_pro_mixer_switch_get, - .put = snd_ice1712_pro_mixer_switch_put, - .private_value = 0, - .count = 10, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Multi Playback Volume", - .info = snd_ice1712_pro_mixer_volume_info, - .get = snd_ice1712_pro_mixer_volume_get, - .put = snd_ice1712_pro_mixer_volume_put, - .private_value = 0, - .count = 10, - .tlv = { .p = db_scale_playback } - }, -}; - -static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "H/W Multi Capture Switch", - .info = snd_ice1712_pro_mixer_switch_info, - .get = snd_ice1712_pro_mixer_switch_get, - .put = snd_ice1712_pro_mixer_switch_put, - .private_value = 10, -}; - -static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH), - .info = snd_ice1712_pro_mixer_switch_info, - .get = snd_ice1712_pro_mixer_switch_get, - .put = snd_ice1712_pro_mixer_switch_put, - .private_value = 18, - .count = 2, -}; - -static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "H/W Multi Capture Volume", - .info = snd_ice1712_pro_mixer_volume_info, - .get = snd_ice1712_pro_mixer_volume_get, - .put = snd_ice1712_pro_mixer_volume_put, - .private_value = 10, - .tlv = { .p = db_scale_playback } -}; - -static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME), - .info = snd_ice1712_pro_mixer_volume_info, - .get = snd_ice1712_pro_mixer_volume_get, - .put = snd_ice1712_pro_mixer_volume_put, - .private_value = 18, - .count = 2, -}; - -static int __devinit snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice) -{ - struct snd_card *card = ice->card; - unsigned int idx; - int err; - - /* multi-channel mixer */ - for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_multi_playback_ctrls); idx++) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_playback_ctrls[idx], ice)); - if (err < 0) - return err; - } - - if (ice->num_total_adcs > 0) { - struct snd_kcontrol_new tmp = snd_ice1712_multi_capture_analog_switch; - tmp.count = ice->num_total_adcs; - err = snd_ctl_add(card, snd_ctl_new1(&tmp, ice)); - if (err < 0) - return err; - } - - err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_capture_spdif_switch, ice)); - if (err < 0) - return err; - - if (ice->num_total_adcs > 0) { - struct snd_kcontrol_new tmp = snd_ice1712_multi_capture_analog_volume; - tmp.count = ice->num_total_adcs; - err = snd_ctl_add(card, snd_ctl_new1(&tmp, ice)); - if (err < 0) - return err; - } - - err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_capture_spdif_volume, ice)); - if (err < 0) - return err; - - /* initialize volumes */ - for (idx = 0; idx < 10; idx++) { - ice->pro_volumes[idx] = 0x80008000; /* mute */ - snd_ice1712_update_volume(ice, idx); - } - for (idx = 10; idx < 10 + ice->num_total_adcs; idx++) { - ice->pro_volumes[idx] = 0x80008000; /* mute */ - snd_ice1712_update_volume(ice, idx); - } - for (idx = 18; idx < 20; idx++) { - ice->pro_volumes[idx] = 0x80008000; /* mute */ - snd_ice1712_update_volume(ice, idx); - } - return 0; -} - -static void snd_ice1712_mixer_free_ac97(struct snd_ac97 *ac97) -{ - struct snd_ice1712 *ice = ac97->private_data; - ice->ac97 = NULL; -} - -static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 *ice) -{ - int err, bus_num = 0; - struct snd_ac97_template ac97; - struct snd_ac97_bus *pbus; - static struct snd_ac97_bus_ops con_ops = { - .write = snd_ice1712_ac97_write, - .read = snd_ice1712_ac97_read, - }; - static struct snd_ac97_bus_ops pro_ops = { - .write = snd_ice1712_pro_ac97_write, - .read = snd_ice1712_pro_ac97_read, - }; - - if (ice_has_con_ac97(ice)) { - err = snd_ac97_bus(ice->card, bus_num++, &con_ops, NULL, &pbus); - if (err < 0) - return err; - memset(&ac97, 0, sizeof(ac97)); - ac97.private_data = ice; - ac97.private_free = snd_ice1712_mixer_free_ac97; - err = snd_ac97_mixer(pbus, &ac97, &ice->ac97); - if (err < 0) - printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n"); - else { - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice)); - if (err < 0) - return err; - return 0; - } - } - - if (!(ice->eeprom.data[ICE_EEP1_ACLINK] & ICE1712_CFG_PRO_I2S)) { - err = snd_ac97_bus(ice->card, bus_num, &pro_ops, NULL, &pbus); - if (err < 0) - return err; - memset(&ac97, 0, sizeof(ac97)); - ac97.private_data = ice; - ac97.private_free = snd_ice1712_mixer_free_ac97; - err = snd_ac97_mixer(pbus, &ac97, &ice->ac97); - if (err < 0) - printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n"); - else - return 0; - } - /* I2S mixer only */ - strcat(ice->card->mixername, "ICE1712 - multitrack"); - return 0; -} - -/* - * - */ - -static inline unsigned int eeprom_double(struct snd_ice1712 *ice, int idx) -{ - return (unsigned int)ice->eeprom.data[idx] | ((unsigned int)ice->eeprom.data[idx + 1] << 8); -} - -static void snd_ice1712_proc_read(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) -{ - struct snd_ice1712 *ice = entry->private_data; - unsigned int idx; - - snd_iprintf(buffer, "%s\n\n", ice->card->longname); - snd_iprintf(buffer, "EEPROM:\n"); - - snd_iprintf(buffer, " Subvendor : 0x%x\n", ice->eeprom.subvendor); - snd_iprintf(buffer, " Size : %i bytes\n", ice->eeprom.size); - snd_iprintf(buffer, " Version : %i\n", ice->eeprom.version); - snd_iprintf(buffer, " Codec : 0x%x\n", ice->eeprom.data[ICE_EEP1_CODEC]); - snd_iprintf(buffer, " ACLink : 0x%x\n", ice->eeprom.data[ICE_EEP1_ACLINK]); - snd_iprintf(buffer, " I2S ID : 0x%x\n", ice->eeprom.data[ICE_EEP1_I2SID]); - snd_iprintf(buffer, " S/PDIF : 0x%x\n", ice->eeprom.data[ICE_EEP1_SPDIF]); - snd_iprintf(buffer, " GPIO mask : 0x%x\n", ice->eeprom.gpiomask); - snd_iprintf(buffer, " GPIO state : 0x%x\n", ice->eeprom.gpiostate); - snd_iprintf(buffer, " GPIO direction : 0x%x\n", ice->eeprom.gpiodir); - snd_iprintf(buffer, " AC'97 main : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_MAIN_LO)); - snd_iprintf(buffer, " AC'97 pcm : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_PCM_LO)); - snd_iprintf(buffer, " AC'97 record : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_REC_LO)); - snd_iprintf(buffer, " AC'97 record src : 0x%x\n", ice->eeprom.data[ICE_EEP1_AC97_RECSRC]); - for (idx = 0; idx < 4; idx++) - snd_iprintf(buffer, " DAC ID #%i : 0x%x\n", idx, ice->eeprom.data[ICE_EEP1_DAC_ID + idx]); - for (idx = 0; idx < 4; idx++) - snd_iprintf(buffer, " ADC ID #%i : 0x%x\n", idx, ice->eeprom.data[ICE_EEP1_ADC_ID + idx]); - for (idx = 0x1c; idx < ice->eeprom.size; idx++) - snd_iprintf(buffer, " Extra #%02i : 0x%x\n", idx, ice->eeprom.data[idx]); - - snd_iprintf(buffer, "\nRegisters:\n"); - snd_iprintf(buffer, " PSDOUT03 : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_PSDOUT03))); - snd_iprintf(buffer, " CAPTURE : 0x%08x\n", inl(ICEMT(ice, ROUTE_CAPTURE))); - snd_iprintf(buffer, " SPDOUT : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT))); - snd_iprintf(buffer, " RATE : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE))); - snd_iprintf(buffer, " GPIO_DATA : 0x%02x\n", (unsigned)snd_ice1712_get_gpio_data(ice)); - snd_iprintf(buffer, " GPIO_WRITE_MASK : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK)); - snd_iprintf(buffer, " GPIO_DIRECTION : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION)); -} - -static void __devinit snd_ice1712_proc_init(struct snd_ice1712 *ice) -{ - struct snd_info_entry *entry; - - if (!snd_card_proc_new(ice->card, "ice1712", &entry)) - snd_info_set_text_ops(entry, ice, snd_ice1712_proc_read); -} - -/* - * - */ - -static int snd_ice1712_eeprom_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = sizeof(struct snd_ice1712_eeprom); - return 0; -} - -static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom)); - return 0; -} - -static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - .name = "ICE1712 EEPROM", - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .info = snd_ice1712_eeprom_info, - .get = snd_ice1712_eeprom_get -}; - -/* - */ -static int snd_ice1712_spdif_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; - uinfo->count = 1; - return 0; -} - -static int snd_ice1712_spdif_default_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - if (ice->spdif.ops.default_get) - ice->spdif.ops.default_get(ice, ucontrol); - return 0; -} - -static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - if (ice->spdif.ops.default_put) - return ice->spdif.ops.default_put(ice, ucontrol); - return 0; -} - -static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = -{ - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), - .info = snd_ice1712_spdif_info, - .get = snd_ice1712_spdif_default_get, - .put = snd_ice1712_spdif_default_put -}; - -static int snd_ice1712_spdif_maskc_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - if (ice->spdif.ops.default_get) { - ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO | - IEC958_AES0_PROFESSIONAL | - IEC958_AES0_CON_NOT_COPYRIGHT | - IEC958_AES0_CON_EMPHASIS; - ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL | - IEC958_AES1_CON_CATEGORY; - ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS; - } else { - ucontrol->value.iec958.status[0] = 0xff; - ucontrol->value.iec958.status[1] = 0xff; - ucontrol->value.iec958.status[2] = 0xff; - ucontrol->value.iec958.status[3] = 0xff; - ucontrol->value.iec958.status[4] = 0xff; - } - return 0; -} - -static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - if (ice->spdif.ops.default_get) { - ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO | - IEC958_AES0_PROFESSIONAL | - IEC958_AES0_PRO_FS | - IEC958_AES0_PRO_EMPHASIS; - ucontrol->value.iec958.status[1] = IEC958_AES1_PRO_MODE; - } else { - ucontrol->value.iec958.status[0] = 0xff; - ucontrol->value.iec958.status[1] = 0xff; - ucontrol->value.iec958.status[2] = 0xff; - ucontrol->value.iec958.status[3] = 0xff; - ucontrol->value.iec958.status[4] = 0xff; - } - return 0; -} - -static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = -{ - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK), - .info = snd_ice1712_spdif_info, - .get = snd_ice1712_spdif_maskc_get, -}; - -static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = -{ - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK), - .info = snd_ice1712_spdif_info, - .get = snd_ice1712_spdif_maskp_get, -}; - -static int snd_ice1712_spdif_stream_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - if (ice->spdif.ops.stream_get) - ice->spdif.ops.stream_get(ice, ucontrol); - return 0; -} - -static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - if (ice->spdif.ops.stream_put) - return ice->spdif.ops.stream_put(ice, ucontrol); - return 0; -} - -static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = -{ - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_INACTIVE), - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM), - .info = snd_ice1712_spdif_info, - .get = snd_ice1712_spdif_stream_get, - .put = snd_ice1712_spdif_stream_put -}; - -int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char mask = kcontrol->private_value & 0xff; - int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0; - - snd_ice1712_save_gpio_status(ice); - ucontrol->value.integer.value[0] = - (snd_ice1712_gpio_read(ice) & mask ? 1 : 0) ^ invert; - snd_ice1712_restore_gpio_status(ice); - return 0; -} - -int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char mask = kcontrol->private_value & 0xff; - int invert = (kcontrol->private_value & (1<<24)) ? mask : 0; - unsigned int val, nval; - - if (kcontrol->private_value & (1 << 31)) - return -EPERM; - nval = (ucontrol->value.integer.value[0] ? mask : 0) ^ invert; - snd_ice1712_save_gpio_status(ice); - val = snd_ice1712_gpio_read(ice); - nval |= val & ~mask; - if (val != nval) - snd_ice1712_gpio_write(ice, nval); - snd_ice1712_restore_gpio_status(ice); - return val != nval; -} - -/* - * rate - */ -static int snd_ice1712_pro_internal_clock_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static const char * const texts[] = { - "8000", /* 0: 6 */ - "9600", /* 1: 3 */ - "11025", /* 2: 10 */ - "12000", /* 3: 2 */ - "16000", /* 4: 5 */ - "22050", /* 5: 9 */ - "24000", /* 6: 1 */ - "32000", /* 7: 4 */ - "44100", /* 8: 8 */ - "48000", /* 9: 0 */ - "64000", /* 10: 15 */ - "88200", /* 11: 11 */ - "96000", /* 12: 7 */ - "IEC958 Input", /* 13: -- */ - }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 14; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - static const unsigned char xlate[16] = { - 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10 - }; - unsigned char val; - - spin_lock_irq(&ice->reg_lock); - if (is_spdif_master(ice)) { - ucontrol->value.enumerated.item[0] = 13; - } else { - val = xlate[inb(ICEMT(ice, RATE)) & 15]; - if (val == 255) { - snd_BUG(); - val = 0; - } - ucontrol->value.enumerated.item[0] = val; - } - spin_unlock_irq(&ice->reg_lock); - return 0; -} - -static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - static const unsigned int xrate[13] = { - 8000, 9600, 11025, 12000, 16000, 22050, 24000, - 32000, 44100, 48000, 64000, 88200, 96000 - }; - unsigned char oval; - int change = 0; - - spin_lock_irq(&ice->reg_lock); - oval = inb(ICEMT(ice, RATE)); - if (ucontrol->value.enumerated.item[0] == 13) { - outb(oval | ICE1712_SPDIF_MASTER, ICEMT(ice, RATE)); - } else { - PRO_RATE_DEFAULT = xrate[ucontrol->value.integer.value[0] % 13]; - spin_unlock_irq(&ice->reg_lock); - snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 1); - spin_lock_irq(&ice->reg_lock); - } - change = inb(ICEMT(ice, RATE)) != oval; - spin_unlock_irq(&ice->reg_lock); - - if ((oval & ICE1712_SPDIF_MASTER) != - (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)) - snd_ice1712_set_input_clock_source(ice, is_spdif_master(ice)); - - return change; -} - -static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Multi Track Internal Clock", - .info = snd_ice1712_pro_internal_clock_info, - .get = snd_ice1712_pro_internal_clock_get, - .put = snd_ice1712_pro_internal_clock_put -}; - -static int snd_ice1712_pro_internal_clock_default_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static const char * const texts[] = { - "8000", /* 0: 6 */ - "9600", /* 1: 3 */ - "11025", /* 2: 10 */ - "12000", /* 3: 2 */ - "16000", /* 4: 5 */ - "22050", /* 5: 9 */ - "24000", /* 6: 1 */ - "32000", /* 7: 4 */ - "44100", /* 8: 8 */ - "48000", /* 9: 0 */ - "64000", /* 10: 15 */ - "88200", /* 11: 11 */ - "96000", /* 12: 7 */ - /* "IEC958 Input", 13: -- */ - }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 13; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_ice1712_pro_internal_clock_default_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int val; - static const unsigned int xrate[13] = { - 8000, 9600, 11025, 12000, 16000, 22050, 24000, - 32000, 44100, 48000, 64000, 88200, 96000 - }; - - for (val = 0; val < 13; val++) { - if (xrate[val] == PRO_RATE_DEFAULT) - break; - } - - ucontrol->value.enumerated.item[0] = val; - return 0; -} - -static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - static const unsigned int xrate[13] = { - 8000, 9600, 11025, 12000, 16000, 22050, 24000, - 32000, 44100, 48000, 64000, 88200, 96000 - }; - unsigned char oval; - int change = 0; - - oval = PRO_RATE_DEFAULT; - PRO_RATE_DEFAULT = xrate[ucontrol->value.integer.value[0] % 13]; - change = PRO_RATE_DEFAULT != oval; - - return change; -} - -static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Multi Track Internal Clock Default", - .info = snd_ice1712_pro_internal_clock_default_info, - .get = snd_ice1712_pro_internal_clock_default_get, - .put = snd_ice1712_pro_internal_clock_default_put -}; - -#define snd_ice1712_pro_rate_locking_info snd_ctl_boolean_mono_info - -static int snd_ice1712_pro_rate_locking_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = PRO_RATE_LOCKED; - return 0; -} - -static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int change = 0, nval; - - nval = ucontrol->value.integer.value[0] ? 1 : 0; - spin_lock_irq(&ice->reg_lock); - change = PRO_RATE_LOCKED != nval; - PRO_RATE_LOCKED = nval; - spin_unlock_irq(&ice->reg_lock); - return change; -} - -static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Multi Track Rate Locking", - .info = snd_ice1712_pro_rate_locking_info, - .get = snd_ice1712_pro_rate_locking_get, - .put = snd_ice1712_pro_rate_locking_put -}; - -#define snd_ice1712_pro_rate_reset_info snd_ctl_boolean_mono_info - -static int snd_ice1712_pro_rate_reset_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = PRO_RATE_RESET; - return 0; -} - -static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int change = 0, nval; - - nval = ucontrol->value.integer.value[0] ? 1 : 0; - spin_lock_irq(&ice->reg_lock); - change = PRO_RATE_RESET != nval; - PRO_RATE_RESET = nval; - spin_unlock_irq(&ice->reg_lock); - return change; -} - -static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Multi Track Rate Reset", - .info = snd_ice1712_pro_rate_reset_info, - .get = snd_ice1712_pro_rate_reset_get, - .put = snd_ice1712_pro_rate_reset_put -}; - -/* - * routing - */ -static int snd_ice1712_pro_route_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static const char * const texts[] = { - "PCM Out", /* 0 */ - "H/W In 0", "H/W In 1", "H/W In 2", "H/W In 3", /* 1-4 */ - "H/W In 4", "H/W In 5", "H/W In 6", "H/W In 7", /* 5-8 */ - "IEC958 In L", "IEC958 In R", /* 9-10 */ - "Digital Mixer", /* 11 - optional */ - }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = - snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_ice1712_pro_route_analog_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - unsigned int val, cval; - - spin_lock_irq(&ice->reg_lock); - val = inw(ICEMT(ice, ROUTE_PSDOUT03)); - cval = inl(ICEMT(ice, ROUTE_CAPTURE)); - spin_unlock_irq(&ice->reg_lock); - - val >>= ((idx % 2) * 8) + ((idx / 2) * 2); - val &= 3; - cval >>= ((idx / 2) * 8) + ((idx % 2) * 4); - if (val == 1 && idx < 2) - ucontrol->value.enumerated.item[0] = 11; - else if (val == 2) - ucontrol->value.enumerated.item[0] = (cval & 7) + 1; - else if (val == 3) - ucontrol->value.enumerated.item[0] = ((cval >> 3) & 1) + 9; - else - ucontrol->value.enumerated.item[0] = 0; - return 0; -} - -static int snd_ice1712_pro_route_analog_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int change, shift; - int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - unsigned int val, old_val, nval; - - /* update PSDOUT */ - if (ucontrol->value.enumerated.item[0] >= 11) - nval = idx < 2 ? 1 : 0; /* dig mixer (or pcm) */ - else if (ucontrol->value.enumerated.item[0] >= 9) - nval = 3; /* spdif in */ - else if (ucontrol->value.enumerated.item[0] >= 1) - nval = 2; /* analog in */ - else - nval = 0; /* pcm */ - shift = ((idx % 2) * 8) + ((idx / 2) * 2); - spin_lock_irq(&ice->reg_lock); - val = old_val = inw(ICEMT(ice, ROUTE_PSDOUT03)); - val &= ~(0x03 << shift); - val |= nval << shift; - change = val != old_val; - if (change) - outw(val, ICEMT(ice, ROUTE_PSDOUT03)); - spin_unlock_irq(&ice->reg_lock); - if (nval < 2) /* dig mixer of pcm */ - return change; - - /* update CAPTURE */ - spin_lock_irq(&ice->reg_lock); - val = old_val = inl(ICEMT(ice, ROUTE_CAPTURE)); - shift = ((idx / 2) * 8) + ((idx % 2) * 4); - if (nval == 2) { /* analog in */ - nval = ucontrol->value.enumerated.item[0] - 1; - val &= ~(0x07 << shift); - val |= nval << shift; - } else { /* spdif in */ - nval = (ucontrol->value.enumerated.item[0] - 9) << 3; - val &= ~(0x08 << shift); - val |= nval << shift; - } - if (val != old_val) { - change = 1; - outl(val, ICEMT(ice, ROUTE_CAPTURE)); - } - spin_unlock_irq(&ice->reg_lock); - return change; -} - -static int snd_ice1712_pro_route_spdif_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - unsigned int val, cval; - val = inw(ICEMT(ice, ROUTE_SPDOUT)); - cval = (val >> (idx * 4 + 8)) & 0x0f; - val = (val >> (idx * 2)) & 0x03; - if (val == 1) - ucontrol->value.enumerated.item[0] = 11; - else if (val == 2) - ucontrol->value.enumerated.item[0] = (cval & 7) + 1; - else if (val == 3) - ucontrol->value.enumerated.item[0] = ((cval >> 3) & 1) + 9; - else - ucontrol->value.enumerated.item[0] = 0; - return 0; -} - -static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int change, shift; - int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - unsigned int val, old_val, nval; - - /* update SPDOUT */ - spin_lock_irq(&ice->reg_lock); - val = old_val = inw(ICEMT(ice, ROUTE_SPDOUT)); - if (ucontrol->value.enumerated.item[0] >= 11) - nval = 1; - else if (ucontrol->value.enumerated.item[0] >= 9) - nval = 3; - else if (ucontrol->value.enumerated.item[0] >= 1) - nval = 2; - else - nval = 0; - shift = idx * 2; - val &= ~(0x03 << shift); - val |= nval << shift; - shift = idx * 4 + 8; - if (nval == 2) { - nval = ucontrol->value.enumerated.item[0] - 1; - val &= ~(0x07 << shift); - val |= nval << shift; - } else if (nval == 3) { - nval = (ucontrol->value.enumerated.item[0] - 9) << 3; - val &= ~(0x08 << shift); - val |= nval << shift; - } - change = val != old_val; - if (change) - outw(val, ICEMT(ice, ROUTE_SPDOUT)); - spin_unlock_irq(&ice->reg_lock); - return change; -} - -static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "H/W Playback Route", - .info = snd_ice1712_pro_route_info, - .get = snd_ice1712_pro_route_analog_get, - .put = snd_ice1712_pro_route_analog_put, -}; - -static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route", - .info = snd_ice1712_pro_route_info, - .get = snd_ice1712_pro_route_spdif_get, - .put = snd_ice1712_pro_route_spdif_put, - .count = 2, -}; - - -static int snd_ice1712_pro_volume_rate_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 255; - return 0; -} - -static int snd_ice1712_pro_volume_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_RATE)); - return 0; -} - -static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int change; - - spin_lock_irq(&ice->reg_lock); - change = inb(ICEMT(ice, MONITOR_RATE)) != ucontrol->value.integer.value[0]; - outb(ucontrol->value.integer.value[0], ICEMT(ice, MONITOR_RATE)); - spin_unlock_irq(&ice->reg_lock); - return change; -} - -static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Multi Track Volume Rate", - .info = snd_ice1712_pro_volume_rate_info, - .get = snd_ice1712_pro_volume_rate_get, - .put = snd_ice1712_pro_volume_rate_put -}; - -static int snd_ice1712_pro_peak_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 22; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 255; - return 0; -} - -static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx; - - spin_lock_irq(&ice->reg_lock); - for (idx = 0; idx < 22; idx++) { - outb(idx, ICEMT(ice, MONITOR_PEAKINDEX)); - ucontrol->value.integer.value[idx] = inb(ICEMT(ice, MONITOR_PEAKDATA)); - } - spin_unlock_irq(&ice->reg_lock); - return 0; -} - -static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "Multi Track Peak", - .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .info = snd_ice1712_pro_peak_info, - .get = snd_ice1712_pro_peak_get -}; - -/* - * - */ - -/* - * list of available boards - */ -static struct snd_ice1712_card_info *card_tables[] __devinitdata = { - snd_ice1712_hoontech_cards, - snd_ice1712_delta_cards, - snd_ice1712_ews_cards, - NULL, -}; - -static unsigned char __devinit snd_ice1712_read_i2c(struct snd_ice1712 *ice, - unsigned char dev, - unsigned char addr) -{ - long t = 0x10000; - - outb(addr, ICEREG(ice, I2C_BYTE_ADDR)); - outb(dev & ~ICE1712_I2C_WRITE, ICEREG(ice, I2C_DEV_ADDR)); - while (t-- > 0 && (inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_BUSY)) ; - return inb(ICEREG(ice, I2C_DATA)); -} - -static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice, - const char *modelname) -{ - int dev = 0xa0; /* EEPROM device address */ - unsigned int i, size; - struct snd_ice1712_card_info * const *tbl, *c; - - if (!modelname || !*modelname) { - ice->eeprom.subvendor = 0; - if ((inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_EEPROM) != 0) - ice->eeprom.subvendor = (snd_ice1712_read_i2c(ice, dev, 0x00) << 0) | - (snd_ice1712_read_i2c(ice, dev, 0x01) << 8) | - (snd_ice1712_read_i2c(ice, dev, 0x02) << 16) | - (snd_ice1712_read_i2c(ice, dev, 0x03) << 24); - if (ice->eeprom.subvendor == 0 || - ice->eeprom.subvendor == (unsigned int)-1) { - /* invalid subvendor from EEPROM, try the PCI subststem ID instead */ - u16 vendor, device; - pci_read_config_word(ice->pci, PCI_SUBSYSTEM_VENDOR_ID, &vendor); - pci_read_config_word(ice->pci, PCI_SUBSYSTEM_ID, &device); - ice->eeprom.subvendor = ((unsigned int)swab16(vendor) << 16) | swab16(device); - if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) { - printk(KERN_ERR "ice1712: No valid ID is found\n"); - return -ENXIO; - } - } - } - for (tbl = card_tables; *tbl; tbl++) { - for (c = *tbl; c->subvendor; c++) { - if (modelname && c->model && !strcmp(modelname, c->model)) { - printk(KERN_INFO "ice1712: Using board model %s\n", c->name); - ice->eeprom.subvendor = c->subvendor; - } else if (c->subvendor != ice->eeprom.subvendor) - continue; - if (!c->eeprom_size || !c->eeprom_data) - goto found; - /* if the EEPROM is given by the driver, use it */ - snd_printdd("using the defined eeprom..\n"); - ice->eeprom.version = 1; - ice->eeprom.size = c->eeprom_size + 6; - memcpy(ice->eeprom.data, c->eeprom_data, c->eeprom_size); - goto read_skipped; - } - } - printk(KERN_WARNING "ice1712: No matching model found for ID 0x%x\n", - ice->eeprom.subvendor); - - found: - ice->eeprom.size = snd_ice1712_read_i2c(ice, dev, 0x04); - if (ice->eeprom.size < 6) - ice->eeprom.size = 32; /* FIXME: any cards without the correct size? */ - else if (ice->eeprom.size > 32) { - snd_printk(KERN_ERR "invalid EEPROM (size = %i)\n", ice->eeprom.size); - return -EIO; - } - ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05); - if (ice->eeprom.version != 1) { - snd_printk(KERN_ERR "invalid EEPROM version %i\n", - ice->eeprom.version); - /* return -EIO; */ - } - size = ice->eeprom.size - 6; - for (i = 0; i < size; i++) - ice->eeprom.data[i] = snd_ice1712_read_i2c(ice, dev, i + 6); - - read_skipped: - ice->eeprom.gpiomask = ice->eeprom.data[ICE_EEP1_GPIO_MASK]; - ice->eeprom.gpiostate = ice->eeprom.data[ICE_EEP1_GPIO_STATE]; - ice->eeprom.gpiodir = ice->eeprom.data[ICE_EEP1_GPIO_DIR]; - - return 0; -} - - - -static int __devinit snd_ice1712_chip_init(struct snd_ice1712 *ice) -{ - outb(ICE1712_RESET | ICE1712_NATIVE, ICEREG(ice, CONTROL)); - udelay(200); - outb(ICE1712_NATIVE, ICEREG(ice, CONTROL)); - udelay(200); - if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DMX6FIRE && - !ice->dxr_enable) - /* Set eeprom value to limit active ADCs and DACs to 6; - * Also disable AC97 as no hardware in standard 6fire card/box - * Note: DXR extensions are not currently supported - */ - ice->eeprom.data[ICE_EEP1_CODEC] = 0x3a; - pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]); - pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]); - pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]); - pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]); - if (ice->eeprom.subvendor != ICE1712_SUBDEVICE_STDSP24) { - ice->gpio.write_mask = ice->eeprom.gpiomask; - ice->gpio.direction = ice->eeprom.gpiodir; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, - ice->eeprom.gpiomask); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, - ice->eeprom.gpiodir); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, - ice->eeprom.gpiostate); - } else { - ice->gpio.write_mask = 0xc0; - ice->gpio.direction = 0xff; - snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, 0xc0); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, 0xff); - snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, - ICE1712_STDSP24_CLOCK_BIT); - } - snd_ice1712_write(ice, ICE1712_IREG_PRO_POWERDOWN, 0); - if (!(ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97)) { - outb(ICE1712_AC97_WARM, ICEREG(ice, AC97_CMD)); - udelay(100); - outb(0, ICEREG(ice, AC97_CMD)); - udelay(200); - snd_ice1712_write(ice, ICE1712_IREG_CONSUMER_POWERDOWN, 0); - } - snd_ice1712_set_pro_rate(ice, 48000, 1); - - return 0; -} - -int __devinit snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice) -{ - int err; - struct snd_kcontrol *kctl; - - if (snd_BUG_ON(!ice->pcm_pro)) - return -EIO; - err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice)); - if (err < 0) - return err; - kctl->id.device = ice->pcm_pro->device; - err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_maskc, ice)); - if (err < 0) - return err; - kctl->id.device = ice->pcm_pro->device; - err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_maskp, ice)); - if (err < 0) - return err; - kctl->id.device = ice->pcm_pro->device; - err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_stream, ice)); - if (err < 0) - return err; - kctl->id.device = ice->pcm_pro->device; - ice->spdif.stream_ctl = kctl; - return 0; -} - - -static int __devinit snd_ice1712_build_controls(struct snd_ice1712 *ice) -{ - int err; - - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_eeprom, ice)); - if (err < 0) - return err; - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_internal_clock, ice)); - if (err < 0) - return err; - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_internal_clock_default, ice)); - if (err < 0) - return err; - - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_rate_locking, ice)); - if (err < 0) - return err; - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_rate_reset, ice)); - if (err < 0) - return err; - - if (ice->num_total_dacs > 0) { - struct snd_kcontrol_new tmp = snd_ice1712_mixer_pro_analog_route; - tmp.count = ice->num_total_dacs; - err = snd_ctl_add(ice->card, snd_ctl_new1(&tmp, ice)); - if (err < 0) - return err; - } - - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_spdif_route, ice)); - if (err < 0) - return err; - - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_volume_rate, ice)); - if (err < 0) - return err; - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice)); - if (err < 0) - return err; - - return 0; -} - -static int snd_ice1712_free(struct snd_ice1712 *ice) -{ - if (!ice->port) - goto __hw_end; - /* mask all interrupts */ - outb(0xc0, ICEMT(ice, IRQ)); - outb(0xff, ICEREG(ice, IRQMASK)); - /* --- */ -__hw_end: - if (ice->irq >= 0) - free_irq(ice->irq, ice); - - if (ice->port) - pci_release_regions(ice->pci); - snd_ice1712_akm4xxx_free(ice); - pci_disable_device(ice->pci); - kfree(ice->spec); - kfree(ice); - return 0; -} - -static int snd_ice1712_dev_free(struct snd_device *device) -{ - struct snd_ice1712 *ice = device->device_data; - return snd_ice1712_free(ice); -} - -static int __devinit snd_ice1712_create(struct snd_card *card, - struct pci_dev *pci, - const char *modelname, - int omni, - int cs8427_timeout, - int dxr_enable, - struct snd_ice1712 **r_ice1712) -{ - struct snd_ice1712 *ice; - int err; - static struct snd_device_ops ops = { - .dev_free = snd_ice1712_dev_free, - }; - - *r_ice1712 = NULL; - - /* enable PCI device */ - err = pci_enable_device(pci); - if (err < 0) - return err; - /* check, if we can restrict PCI DMA transfers to 28 bits */ - if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || - pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { - snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); - pci_disable_device(pci); - return -ENXIO; - } - - ice = kzalloc(sizeof(*ice), GFP_KERNEL); - if (ice == NULL) { - pci_disable_device(pci); - return -ENOMEM; - } - ice->omni = omni ? 1 : 0; - if (cs8427_timeout < 1) - cs8427_timeout = 1; - else if (cs8427_timeout > 1000) - cs8427_timeout = 1000; - ice->cs8427_timeout = cs8427_timeout; - ice->dxr_enable = dxr_enable; - spin_lock_init(&ice->reg_lock); - mutex_init(&ice->gpio_mutex); - mutex_init(&ice->i2c_mutex); - mutex_init(&ice->open_mutex); - ice->gpio.set_mask = snd_ice1712_set_gpio_mask; - ice->gpio.get_mask = snd_ice1712_get_gpio_mask; - ice->gpio.set_dir = snd_ice1712_set_gpio_dir; - ice->gpio.get_dir = snd_ice1712_get_gpio_dir; - ice->gpio.set_data = snd_ice1712_set_gpio_data; - ice->gpio.get_data = snd_ice1712_get_gpio_data; - - ice->spdif.cs8403_bits = - ice->spdif.cs8403_stream_bits = (0x01 | /* consumer format */ - 0x10 | /* no emphasis */ - 0x20); /* PCM encoder/decoder */ - ice->card = card; - ice->pci = pci; - ice->irq = -1; - pci_set_master(pci); - pci_write_config_word(ice->pci, 0x40, 0x807f); - pci_write_config_word(ice->pci, 0x42, 0x0006); - snd_ice1712_proc_init(ice); - synchronize_irq(pci->irq); - - err = pci_request_regions(pci, "ICE1712"); - if (err < 0) { - kfree(ice); - pci_disable_device(pci); - return err; - } - ice->port = pci_resource_start(pci, 0); - ice->ddma_port = pci_resource_start(pci, 1); - ice->dmapath_port = pci_resource_start(pci, 2); - ice->profi_port = pci_resource_start(pci, 3); - - if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_SHARED, - KBUILD_MODNAME, ice)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); - snd_ice1712_free(ice); - return -EIO; - } - - ice->irq = pci->irq; - - if (snd_ice1712_read_eeprom(ice, modelname) < 0) { - snd_ice1712_free(ice); - return -EIO; - } - if (snd_ice1712_chip_init(ice) < 0) { - snd_ice1712_free(ice); - return -EIO; - } - - /* unmask used interrupts */ - outb(((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) == 0 ? - ICE1712_IRQ_MPU2 : 0) | - ((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97) ? - ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0), - ICEREG(ice, IRQMASK)); - outb(0x00, ICEMT(ice, IRQ)); - - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops); - if (err < 0) { - snd_ice1712_free(ice); - return err; - } - - snd_card_set_dev(card, &pci->dev); - - *r_ice1712 = ice; - return 0; -} - - -/* - * - * Registration - * - */ - -static struct snd_ice1712_card_info no_matched __devinitdata; - -static int __devinit snd_ice1712_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - static int dev; - struct snd_card *card; - struct snd_ice1712 *ice; - int pcm_dev = 0, err; - struct snd_ice1712_card_info * const *tbl, *c; - - if (dev >= SNDRV_CARDS) - return -ENODEV; - if (!enable[dev]) { - dev++; - return -ENOENT; - } - - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; - - strcpy(card->driver, "ICE1712"); - strcpy(card->shortname, "ICEnsemble ICE1712"); - - err = snd_ice1712_create(card, pci, model[dev], omni[dev], - cs8427_timeout[dev], dxr_enable[dev], &ice); - if (err < 0) { - snd_card_free(card); - return err; - } - - for (tbl = card_tables; *tbl; tbl++) { - for (c = *tbl; c->subvendor; c++) { - if (c->subvendor == ice->eeprom.subvendor) { - strcpy(card->shortname, c->name); - if (c->driver) /* specific driver? */ - strcpy(card->driver, c->driver); - if (c->chip_init) { - err = c->chip_init(ice); - if (err < 0) { - snd_card_free(card); - return err; - } - } - goto __found; - } - } - } - c = &no_matched; - __found: - - err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL); - if (err < 0) { - snd_card_free(card); - return err; - } - - if (ice_has_con_ac97(ice)) { - err = snd_ice1712_pcm(ice, pcm_dev++, NULL); - if (err < 0) { - snd_card_free(card); - return err; - } - } - - err = snd_ice1712_ac97_mixer(ice); - if (err < 0) { - snd_card_free(card); - return err; - } - - err = snd_ice1712_build_controls(ice); - if (err < 0) { - snd_card_free(card); - return err; - } - - if (c->build_controls) { - err = c->build_controls(ice); - if (err < 0) { - snd_card_free(card); - return err; - } - } - - if (ice_has_con_ac97(ice)) { - err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL); - if (err < 0) { - snd_card_free(card); - return err; - } - } - - if (!c->no_mpu401) { - err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, - ICEREG(ice, MPU1_CTRL), - c->mpu401_1_info_flags | - MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK, - -1, &ice->rmidi[0]); - if (err < 0) { - snd_card_free(card); - return err; - } - if (c->mpu401_1_name) - /* Preferred name available in card_info */ - snprintf(ice->rmidi[0]->name, - sizeof(ice->rmidi[0]->name), - "%s %d", c->mpu401_1_name, card->number); - - if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) { - /* 2nd port used */ - err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712, - ICEREG(ice, MPU2_CTRL), - c->mpu401_2_info_flags | - MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK, - -1, &ice->rmidi[1]); - - if (err < 0) { - snd_card_free(card); - return err; - } - if (c->mpu401_2_name) - /* Preferred name available in card_info */ - snprintf(ice->rmidi[1]->name, - sizeof(ice->rmidi[1]->name), - "%s %d", c->mpu401_2_name, - card->number); - } - } - - snd_ice1712_set_input_clock_source(ice, 0); - - sprintf(card->longname, "%s at 0x%lx, irq %i", - card->shortname, ice->port, ice->irq); - - err = snd_card_register(card); - if (err < 0) { - snd_card_free(card); - return err; - } - pci_set_drvdata(pci, card); - dev++; - return 0; -} - -static void __devexit snd_ice1712_remove(struct pci_dev *pci) -{ - snd_card_free(pci_get_drvdata(pci)); - pci_set_drvdata(pci, NULL); -} - -static struct pci_driver driver = { - .name = KBUILD_MODNAME, - .id_table = snd_ice1712_ids, - .probe = snd_ice1712_probe, - .remove = __devexit_p(snd_ice1712_remove), -}; - -static int __init alsa_card_ice1712_init(void) -{ - return pci_register_driver(&driver); -} - -static void __exit alsa_card_ice1712_exit(void) -{ - pci_unregister_driver(&driver); -} - -module_init(alsa_card_ice1712_init) -module_exit(alsa_card_ice1712_exit) diff --git a/ANDROID_3.4.5/sound/pci/ice1712/ice1712.h b/ANDROID_3.4.5/sound/pci/ice1712/ice1712.h deleted file mode 100644 index 0da778a6..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/ice1712.h +++ /dev/null @@ -1,531 +0,0 @@ -#ifndef __SOUND_ICE1712_H -#define __SOUND_ICE1712_H - -/* - * ALSA driver for ICEnsemble ICE1712 (Envy24) - * - * Copyright (c) 2000 Jaroslav Kysela - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - * Direct registers - */ - -#define ICEREG(ice, x) ((ice)->port + ICE1712_REG_##x) - -#define ICE1712_REG_CONTROL 0x00 /* byte */ -#define ICE1712_RESET 0x80 /* reset whole chip */ -#define ICE1712_SERR_LEVEL 0x04 /* SERR# level otherwise edge */ -#define ICE1712_NATIVE 0x01 /* native mode otherwise SB */ -#define ICE1712_REG_IRQMASK 0x01 /* byte */ -#define ICE1712_IRQ_MPU1 0x80 -#define ICE1712_IRQ_TIMER 0x40 -#define ICE1712_IRQ_MPU2 0x20 -#define ICE1712_IRQ_PROPCM 0x10 -#define ICE1712_IRQ_FM 0x08 /* FM/MIDI - legacy */ -#define ICE1712_IRQ_PBKDS 0x04 /* playback DS channels */ -#define ICE1712_IRQ_CONCAP 0x02 /* consumer capture */ -#define ICE1712_IRQ_CONPBK 0x01 /* consumer playback */ -#define ICE1712_REG_IRQSTAT 0x02 /* byte */ -/* look to ICE1712_IRQ_* */ -#define ICE1712_REG_INDEX 0x03 /* byte - indirect CCIxx regs */ -#define ICE1712_REG_DATA 0x04 /* byte - indirect CCIxx regs */ -#define ICE1712_REG_NMI_STAT1 0x05 /* byte */ -#define ICE1712_REG_NMI_DATA 0x06 /* byte */ -#define ICE1712_REG_NMI_INDEX 0x07 /* byte */ -#define ICE1712_REG_AC97_INDEX 0x08 /* byte */ -#define ICE1712_REG_AC97_CMD 0x09 /* byte */ -#define ICE1712_AC97_COLD 0x80 /* cold reset */ -#define ICE1712_AC97_WARM 0x40 /* warm reset */ -#define ICE1712_AC97_WRITE 0x20 /* W: write, R: write in progress */ -#define ICE1712_AC97_READ 0x10 /* W: read, R: read in progress */ -#define ICE1712_AC97_READY 0x08 /* codec ready status bit */ -#define ICE1712_AC97_PBK_VSR 0x02 /* playback VSR */ -#define ICE1712_AC97_CAP_VSR 0x01 /* capture VSR */ -#define ICE1712_REG_AC97_DATA 0x0a /* word (little endian) */ -#define ICE1712_REG_MPU1_CTRL 0x0c /* byte */ -#define ICE1712_REG_MPU1_DATA 0x0d /* byte */ -#define ICE1712_REG_I2C_DEV_ADDR 0x10 /* byte */ -#define ICE1712_I2C_WRITE 0x01 /* write direction */ -#define ICE1712_REG_I2C_BYTE_ADDR 0x11 /* byte */ -#define ICE1712_REG_I2C_DATA 0x12 /* byte */ -#define ICE1712_REG_I2C_CTRL 0x13 /* byte */ -#define ICE1712_I2C_EEPROM 0x80 /* EEPROM exists */ -#define ICE1712_I2C_BUSY 0x01 /* busy bit */ -#define ICE1712_REG_CONCAP_ADDR 0x14 /* dword - consumer capture */ -#define ICE1712_REG_CONCAP_COUNT 0x18 /* word - current/base count */ -#define ICE1712_REG_SERR_SHADOW 0x1b /* byte */ -#define ICE1712_REG_MPU2_CTRL 0x1c /* byte */ -#define ICE1712_REG_MPU2_DATA 0x1d /* byte */ -#define ICE1712_REG_TIMER 0x1e /* word */ - -/* - * Indirect registers - */ - -#define ICE1712_IREG_PBK_COUNT_LO 0x00 -#define ICE1712_IREG_PBK_COUNT_HI 0x01 -#define ICE1712_IREG_PBK_CTRL 0x02 -#define ICE1712_IREG_PBK_LEFT 0x03 /* left volume */ -#define ICE1712_IREG_PBK_RIGHT 0x04 /* right volume */ -#define ICE1712_IREG_PBK_SOFT 0x05 /* soft volume */ -#define ICE1712_IREG_PBK_RATE_LO 0x06 -#define ICE1712_IREG_PBK_RATE_MID 0x07 -#define ICE1712_IREG_PBK_RATE_HI 0x08 -#define ICE1712_IREG_CAP_COUNT_LO 0x10 -#define ICE1712_IREG_CAP_COUNT_HI 0x11 -#define ICE1712_IREG_CAP_CTRL 0x12 -#define ICE1712_IREG_GPIO_DATA 0x20 -#define ICE1712_IREG_GPIO_WRITE_MASK 0x21 -#define ICE1712_IREG_GPIO_DIRECTION 0x22 -#define ICE1712_IREG_CONSUMER_POWERDOWN 0x30 -#define ICE1712_IREG_PRO_POWERDOWN 0x31 - -/* - * Consumer section direct DMA registers - */ - -#define ICEDS(ice, x) ((ice)->dmapath_port + ICE1712_DS_##x) - -#define ICE1712_DS_INTMASK 0x00 /* word - interrupt mask */ -#define ICE1712_DS_INTSTAT 0x02 /* word - interrupt status */ -#define ICE1712_DS_DATA 0x04 /* dword - channel data */ -#define ICE1712_DS_INDEX 0x08 /* dword - channel index */ - -/* - * Consumer section channel registers - */ - -#define ICE1712_DSC_ADDR0 0x00 /* dword - base address 0 */ -#define ICE1712_DSC_COUNT0 0x01 /* word - count 0 */ -#define ICE1712_DSC_ADDR1 0x02 /* dword - base address 1 */ -#define ICE1712_DSC_COUNT1 0x03 /* word - count 1 */ -#define ICE1712_DSC_CONTROL 0x04 /* byte - control & status */ -#define ICE1712_BUFFER1 0x80 /* buffer1 is active */ -#define ICE1712_BUFFER1_AUTO 0x40 /* buffer1 auto init */ -#define ICE1712_BUFFER0_AUTO 0x20 /* buffer0 auto init */ -#define ICE1712_FLUSH 0x10 /* flush FIFO */ -#define ICE1712_STEREO 0x08 /* stereo */ -#define ICE1712_16BIT 0x04 /* 16-bit data */ -#define ICE1712_PAUSE 0x02 /* pause */ -#define ICE1712_START 0x01 /* start */ -#define ICE1712_DSC_RATE 0x05 /* dword - rate */ -#define ICE1712_DSC_VOLUME 0x06 /* word - volume control */ - -/* - * Professional multi-track direct control registers - */ - -#define ICEMT(ice, x) ((ice)->profi_port + ICE1712_MT_##x) - -#define ICE1712_MT_IRQ 0x00 /* byte - interrupt mask */ -#define ICE1712_MULTI_CAPTURE 0x80 /* capture IRQ */ -#define ICE1712_MULTI_PLAYBACK 0x40 /* playback IRQ */ -#define ICE1712_MULTI_CAPSTATUS 0x02 /* capture IRQ status */ -#define ICE1712_MULTI_PBKSTATUS 0x01 /* playback IRQ status */ -#define ICE1712_MT_RATE 0x01 /* byte - sampling rate select */ -#define ICE1712_SPDIF_MASTER 0x10 /* S/PDIF input is master clock */ -#define ICE1712_MT_I2S_FORMAT 0x02 /* byte - I2S data format */ -#define ICE1712_MT_AC97_INDEX 0x04 /* byte - AC'97 index */ -#define ICE1712_MT_AC97_CMD 0x05 /* byte - AC'97 command & status */ -/* look to ICE1712_AC97_* */ -#define ICE1712_MT_AC97_DATA 0x06 /* word - AC'97 data */ -#define ICE1712_MT_PLAYBACK_ADDR 0x10 /* dword - playback address */ -#define ICE1712_MT_PLAYBACK_SIZE 0x14 /* word - playback size */ -#define ICE1712_MT_PLAYBACK_COUNT 0x16 /* word - playback count */ -#define ICE1712_MT_PLAYBACK_CONTROL 0x18 /* byte - control */ -#define ICE1712_CAPTURE_START_SHADOW 0x04 /* capture start */ -#define ICE1712_PLAYBACK_PAUSE 0x02 /* playback pause */ -#define ICE1712_PLAYBACK_START 0x01 /* playback start */ -#define ICE1712_MT_CAPTURE_ADDR 0x20 /* dword - capture address */ -#define ICE1712_MT_CAPTURE_SIZE 0x24 /* word - capture size */ -#define ICE1712_MT_CAPTURE_COUNT 0x26 /* word - capture count */ -#define ICE1712_MT_CAPTURE_CONTROL 0x28 /* byte - control */ -#define ICE1712_CAPTURE_START 0x01 /* capture start */ -#define ICE1712_MT_ROUTE_PSDOUT03 0x30 /* word */ -#define ICE1712_MT_ROUTE_SPDOUT 0x32 /* word */ -#define ICE1712_MT_ROUTE_CAPTURE 0x34 /* dword */ -#define ICE1712_MT_MONITOR_VOLUME 0x38 /* word */ -#define ICE1712_MT_MONITOR_INDEX 0x3a /* byte */ -#define ICE1712_MT_MONITOR_RATE 0x3b /* byte */ -#define ICE1712_MT_MONITOR_ROUTECTRL 0x3c /* byte */ -#define ICE1712_ROUTE_AC97 0x01 /* route digital mixer output to AC'97 */ -#define ICE1712_MT_MONITOR_PEAKINDEX 0x3e /* byte */ -#define ICE1712_MT_MONITOR_PEAKDATA 0x3f /* byte */ - -/* - * Codec configuration bits - */ - -/* PCI[60] System Configuration */ -#define ICE1712_CFG_CLOCK 0xc0 -#define ICE1712_CFG_CLOCK512 0x00 /* 22.5692Mhz, 44.1kHz*512 */ -#define ICE1712_CFG_CLOCK384 0x40 /* 16.9344Mhz, 44.1kHz*384 */ -#define ICE1712_CFG_EXT 0x80 /* external clock */ -#define ICE1712_CFG_2xMPU401 0x20 /* two MPU401 UARTs */ -#define ICE1712_CFG_NO_CON_AC97 0x10 /* consumer AC'97 codec is not present */ -#define ICE1712_CFG_ADC_MASK 0x0c /* one, two, three, four stereo ADCs */ -#define ICE1712_CFG_DAC_MASK 0x03 /* one, two, three, four stereo DACs */ -/* PCI[61] AC-Link Configuration */ -#define ICE1712_CFG_PRO_I2S 0x80 /* multitrack converter: I2S or AC'97 */ -#define ICE1712_CFG_AC97_PACKED 0x01 /* split or packed mode - AC'97 */ -/* PCI[62] I2S Features */ -#define ICE1712_CFG_I2S_VOLUME 0x80 /* volume/mute capability */ -#define ICE1712_CFG_I2S_96KHZ 0x40 /* supports 96kHz sampling */ -#define ICE1712_CFG_I2S_RESMASK 0x30 /* resolution mask, 16,18,20,24-bit */ -#define ICE1712_CFG_I2S_OTHER 0x0f /* other I2S IDs */ -/* PCI[63] S/PDIF Configuration */ -#define ICE1712_CFG_I2S_CHIPID 0xfc /* I2S chip ID */ -#define ICE1712_CFG_SPDIF_IN 0x02 /* S/PDIF input is present */ -#define ICE1712_CFG_SPDIF_OUT 0x01 /* S/PDIF output is present */ - -/* - * DMA mode values - * identical with DMA_XXX on i386 architecture. - */ -#define ICE1712_DMA_MODE_WRITE 0x48 -#define ICE1712_DMA_AUTOINIT 0x10 - - -/* - * - */ - -struct snd_ice1712; - -struct snd_ice1712_eeprom { - unsigned int subvendor; /* PCI[2c-2f] */ - unsigned char size; /* size of EEPROM image in bytes */ - unsigned char version; /* must be 1 (or 2 for vt1724) */ - unsigned char data[32]; - unsigned int gpiomask; - unsigned int gpiostate; - unsigned int gpiodir; -}; - -enum { - ICE_EEP1_CODEC = 0, /* 06 */ - ICE_EEP1_ACLINK, /* 07 */ - ICE_EEP1_I2SID, /* 08 */ - ICE_EEP1_SPDIF, /* 09 */ - ICE_EEP1_GPIO_MASK, /* 0a */ - ICE_EEP1_GPIO_STATE, /* 0b */ - ICE_EEP1_GPIO_DIR, /* 0c */ - ICE_EEP1_AC97_MAIN_LO, /* 0d */ - ICE_EEP1_AC97_MAIN_HI, /* 0e */ - ICE_EEP1_AC97_PCM_LO, /* 0f */ - ICE_EEP1_AC97_PCM_HI, /* 10 */ - ICE_EEP1_AC97_REC_LO, /* 11 */ - ICE_EEP1_AC97_REC_HI, /* 12 */ - ICE_EEP1_AC97_RECSRC, /* 13 */ - ICE_EEP1_DAC_ID, /* 14 */ - ICE_EEP1_DAC_ID1, - ICE_EEP1_DAC_ID2, - ICE_EEP1_DAC_ID3, - ICE_EEP1_ADC_ID, /* 18 */ - ICE_EEP1_ADC_ID1, - ICE_EEP1_ADC_ID2, - ICE_EEP1_ADC_ID3 -}; - -#define ice_has_con_ac97(ice) (!((ice)->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97)) - - -struct snd_ak4xxx_private { - unsigned int cif:1; /* CIF mode */ - unsigned char caddr; /* C0 and C1 bits */ - unsigned int data_mask; /* DATA gpio bit */ - unsigned int clk_mask; /* CLK gpio bit */ - unsigned int cs_mask; /* bit mask for select/deselect address */ - unsigned int cs_addr; /* bits to select address */ - unsigned int cs_none; /* bits to deselect address */ - unsigned int add_flags; /* additional bits at init */ - unsigned int mask_flags; /* total mask bits */ - struct snd_akm4xxx_ops { - void (*set_rate_val)(struct snd_akm4xxx *ak, unsigned int rate); - } ops; -}; - -struct snd_ice1712_spdif { - unsigned char cs8403_bits; - unsigned char cs8403_stream_bits; - struct snd_kcontrol *stream_ctl; - - struct snd_ice1712_spdif_ops { - void (*open)(struct snd_ice1712 *, struct snd_pcm_substream *); - void (*setup_rate)(struct snd_ice1712 *, int rate); - void (*close)(struct snd_ice1712 *, struct snd_pcm_substream *); - void (*default_get)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol); - int (*default_put)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol); - void (*stream_get)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol); - int (*stream_put)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol); - } ops; -}; - - -struct snd_ice1712 { - unsigned long conp_dma_size; - unsigned long conc_dma_size; - unsigned long prop_dma_size; - unsigned long proc_dma_size; - int irq; - - unsigned long port; - unsigned long ddma_port; - unsigned long dmapath_port; - unsigned long profi_port; - - struct pci_dev *pci; - struct snd_card *card; - struct snd_pcm *pcm; - struct snd_pcm *pcm_ds; - struct snd_pcm *pcm_pro; - struct snd_pcm_substream *playback_con_substream; - struct snd_pcm_substream *playback_con_substream_ds[6]; - struct snd_pcm_substream *capture_con_substream; - struct snd_pcm_substream *playback_pro_substream; - struct snd_pcm_substream *capture_pro_substream; - unsigned int playback_pro_size; - unsigned int capture_pro_size; - unsigned int playback_con_virt_addr[6]; - unsigned int playback_con_active_buf[6]; - unsigned int capture_con_virt_addr; - unsigned int ac97_ext_id; - struct snd_ac97 *ac97; - struct snd_rawmidi *rmidi[2]; - - spinlock_t reg_lock; - struct snd_info_entry *proc_entry; - - struct snd_ice1712_eeprom eeprom; - - unsigned int pro_volumes[20]; - unsigned int omni:1; /* Delta Omni I/O */ - unsigned int dxr_enable:1; /* Terratec DXR enable for DMX6FIRE */ - unsigned int vt1724:1; - unsigned int vt1720:1; - unsigned int has_spdif:1; /* VT1720/4 - has SPDIF I/O */ - unsigned int force_pdma4:1; /* VT1720/4 - PDMA4 as non-spdif */ - unsigned int force_rdma1:1; /* VT1720/4 - RDMA1 as non-spdif */ - unsigned int midi_output:1; /* VT1720/4: MIDI output triggered */ - unsigned int midi_input:1; /* VT1720/4: MIDI input triggered */ - unsigned int own_routing:1; /* VT1720/4: use own routing ctls */ - unsigned int num_total_dacs; /* total DACs */ - unsigned int num_total_adcs; /* total ADCs */ - unsigned int cur_rate; /* current rate */ - - struct mutex open_mutex; - struct snd_pcm_substream *pcm_reserved[4]; - struct snd_pcm_hw_constraint_list *hw_rates; /* card-specific rate constraints */ - - unsigned int akm_codecs; - struct snd_akm4xxx *akm; - struct snd_ice1712_spdif spdif; - - struct mutex i2c_mutex; /* I2C mutex for ICE1724 registers */ - struct snd_i2c_bus *i2c; /* I2C bus */ - struct snd_i2c_device *cs8427; /* CS8427 I2C device */ - unsigned int cs8427_timeout; /* CS8427 reset timeout in HZ/100 */ - - struct ice1712_gpio { - unsigned int direction; /* current direction bits */ - unsigned int write_mask; /* current mask bits */ - unsigned int saved[2]; /* for ewx_i2c */ - /* operators */ - void (*set_mask)(struct snd_ice1712 *ice, unsigned int data); - unsigned int (*get_mask)(struct snd_ice1712 *ice); - void (*set_dir)(struct snd_ice1712 *ice, unsigned int data); - unsigned int (*get_dir)(struct snd_ice1712 *ice); - void (*set_data)(struct snd_ice1712 *ice, unsigned int data); - unsigned int (*get_data)(struct snd_ice1712 *ice); - /* misc operators - move to another place? */ - void (*set_pro_rate)(struct snd_ice1712 *ice, unsigned int rate); - void (*i2s_mclk_changed)(struct snd_ice1712 *ice); - } gpio; - struct mutex gpio_mutex; - - /* other board-specific data */ - void *spec; - - /* VT172x specific */ - int pro_rate_default; - int (*is_spdif_master)(struct snd_ice1712 *ice); - unsigned int (*get_rate)(struct snd_ice1712 *ice); - void (*set_rate)(struct snd_ice1712 *ice, unsigned int rate); - unsigned char (*set_mclk)(struct snd_ice1712 *ice, unsigned int rate); - int (*set_spdif_clock)(struct snd_ice1712 *ice, int type); - int (*get_spdif_master_type)(struct snd_ice1712 *ice); - char **ext_clock_names; - int ext_clock_count; - void (*pro_open)(struct snd_ice1712 *, struct snd_pcm_substream *); -#ifdef CONFIG_PM - int (*pm_suspend)(struct snd_ice1712 *); - int (*pm_resume)(struct snd_ice1712 *); - unsigned int pm_suspend_enabled:1; - unsigned int pm_saved_is_spdif_master:1; - unsigned int pm_saved_spdif_ctrl; - unsigned char pm_saved_spdif_cfg; - unsigned int pm_saved_route; -#endif -}; - - -/* - * gpio access functions - */ -static inline void snd_ice1712_gpio_set_dir(struct snd_ice1712 *ice, unsigned int bits) -{ - ice->gpio.set_dir(ice, bits); -} - -static inline unsigned int snd_ice1712_gpio_get_dir(struct snd_ice1712 *ice) -{ - return ice->gpio.get_dir(ice); -} - -static inline void snd_ice1712_gpio_set_mask(struct snd_ice1712 *ice, unsigned int bits) -{ - ice->gpio.set_mask(ice, bits); -} - -static inline void snd_ice1712_gpio_write(struct snd_ice1712 *ice, unsigned int val) -{ - ice->gpio.set_data(ice, val); -} - -static inline unsigned int snd_ice1712_gpio_read(struct snd_ice1712 *ice) -{ - return ice->gpio.get_data(ice); -} - -/* - * save and restore gpio status - * The access to gpio will be protected by mutex, so don't forget to - * restore! - */ -static inline void snd_ice1712_save_gpio_status(struct snd_ice1712 *ice) -{ - mutex_lock(&ice->gpio_mutex); - ice->gpio.saved[0] = ice->gpio.direction; - ice->gpio.saved[1] = ice->gpio.write_mask; -} - -static inline void snd_ice1712_restore_gpio_status(struct snd_ice1712 *ice) -{ - ice->gpio.set_dir(ice, ice->gpio.saved[0]); - ice->gpio.set_mask(ice, ice->gpio.saved[1]); - ice->gpio.direction = ice->gpio.saved[0]; - ice->gpio.write_mask = ice->gpio.saved[1]; - mutex_unlock(&ice->gpio_mutex); -} - -/* for bit controls */ -#define ICE1712_GPIO(xiface, xname, xindex, mask, invert, xaccess) \ -{ .iface = xiface, .name = xname, .access = xaccess, .info = snd_ctl_boolean_mono_info, \ - .get = snd_ice1712_gpio_get, .put = snd_ice1712_gpio_put, \ - .private_value = mask | (invert << 24) } - -int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); - -/* - * set gpio direction, write mask and data - */ -static inline void snd_ice1712_gpio_write_bits(struct snd_ice1712 *ice, - unsigned int mask, unsigned int bits) -{ - unsigned val; - - ice->gpio.direction |= mask; - snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); - val = snd_ice1712_gpio_read(ice); - val &= ~mask; - val |= mask & bits; - snd_ice1712_gpio_write(ice, val); -} - -static inline int snd_ice1712_gpio_read_bits(struct snd_ice1712 *ice, - unsigned int mask) -{ - ice->gpio.direction &= ~mask; - snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); - return snd_ice1712_gpio_read(ice) & mask; -} - -/* route access functions */ -int snd_ice1724_get_route_val(struct snd_ice1712 *ice, int shift); -int snd_ice1724_put_route_val(struct snd_ice1712 *ice, unsigned int val, - int shift); - -int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice); - -int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak, - const struct snd_akm4xxx *template, - const struct snd_ak4xxx_private *priv, - struct snd_ice1712 *ice); -void snd_ice1712_akm4xxx_free(struct snd_ice1712 *ice); -int snd_ice1712_akm4xxx_build_controls(struct snd_ice1712 *ice); - -int snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr); - -static inline void snd_ice1712_write(struct snd_ice1712 *ice, u8 addr, u8 data) -{ - outb(addr, ICEREG(ice, INDEX)); - outb(data, ICEREG(ice, DATA)); -} - -static inline u8 snd_ice1712_read(struct snd_ice1712 *ice, u8 addr) -{ - outb(addr, ICEREG(ice, INDEX)); - return inb(ICEREG(ice, DATA)); -} - - -/* - * entry pointer - */ - -struct snd_ice1712_card_info { - unsigned int subvendor; - char *name; - char *model; - char *driver; - int (*chip_init)(struct snd_ice1712 *); - int (*build_controls)(struct snd_ice1712 *); - unsigned int no_mpu401:1; - unsigned int mpu401_1_info_flags; - unsigned int mpu401_2_info_flags; - const char *mpu401_1_name; - const char *mpu401_2_name; - const unsigned int eeprom_size; - const unsigned char *eeprom_data; -}; - - -#endif /* __SOUND_ICE1712_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/ice1724.c b/ANDROID_3.4.5/sound/pci/ice1712/ice1724.c deleted file mode 100644 index 812d10e4..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/ice1724.c +++ /dev/null @@ -1,2898 +0,0 @@ -/* - * ALSA driver for VT1724 ICEnsemble ICE1724 / VIA VT1724 (Envy24HT) - * VIA VT1720 (Envy24PT) - * - * Copyright (c) 2000 Jaroslav Kysela - * 2002 James Stafford - * 2003 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "ice1712.h" -#include "envy24ht.h" - -/* lowlevel routines */ -#include "amp.h" -#include "revo.h" -#include "aureon.h" -#include "vt1720_mobo.h" -#include "pontis.h" -#include "prodigy192.h" -#include "prodigy_hifi.h" -#include "juli.h" -#include "maya44.h" -#include "phase.h" -#include "wtm.h" -#include "se.h" -#include "quartet.h" - -MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{" - REVO_DEVICE_DESC - AMP_AUDIO2000_DEVICE_DESC - AUREON_DEVICE_DESC - VT1720_MOBO_DEVICE_DESC - PONTIS_DEVICE_DESC - PRODIGY192_DEVICE_DESC - PRODIGY_HIFI_DEVICE_DESC - JULI_DEVICE_DESC - MAYA44_DEVICE_DESC - PHASE_DEVICE_DESC - WTM_DEVICE_DESC - SE_DEVICE_DESC - QTET_DEVICE_DESC - "{VIA,VT1720}," - "{VIA,VT1724}," - "{ICEnsemble,Generic ICE1724}," - "{ICEnsemble,Generic Envy24HT}" - "{ICEnsemble,Generic Envy24PT}}"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ -static char *model[SNDRV_CARDS]; - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for ICE1724 soundcard."); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for ICE1724 soundcard."); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable ICE1724 soundcard."); -module_param_array(model, charp, NULL, 0444); -MODULE_PARM_DESC(model, "Use the given board model."); - - -/* Both VT1720 and VT1724 have the same PCI IDs */ -static DEFINE_PCI_DEVICE_TABLE(snd_vt1724_ids) = { - { PCI_VDEVICE(ICE, PCI_DEVICE_ID_VT1724), 0 }, - { 0, } -}; - -MODULE_DEVICE_TABLE(pci, snd_vt1724_ids); - - -static int PRO_RATE_LOCKED; -static int PRO_RATE_RESET = 1; -static unsigned int PRO_RATE_DEFAULT = 44100; - -static char *ext_clock_names[1] = { "IEC958 In" }; - -/* - * Basic I/O - */ - -/* - * default rates, default clock routines - */ - -/* check whether the clock mode is spdif-in */ -static inline int stdclock_is_spdif_master(struct snd_ice1712 *ice) -{ - return (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER) ? 1 : 0; -} - -/* - * locking rate makes sense only for internal clock mode - */ -static inline int is_pro_rate_locked(struct snd_ice1712 *ice) -{ - return (!ice->is_spdif_master(ice)) && PRO_RATE_LOCKED; -} - -/* - * ac97 section - */ - -static unsigned char snd_vt1724_ac97_ready(struct snd_ice1712 *ice) -{ - unsigned char old_cmd; - int tm; - for (tm = 0; tm < 0x10000; tm++) { - old_cmd = inb(ICEMT1724(ice, AC97_CMD)); - if (old_cmd & (VT1724_AC97_WRITE | VT1724_AC97_READ)) - continue; - if (!(old_cmd & VT1724_AC97_READY)) - continue; - return old_cmd; - } - snd_printd(KERN_ERR "snd_vt1724_ac97_ready: timeout\n"); - return old_cmd; -} - -static int snd_vt1724_ac97_wait_bit(struct snd_ice1712 *ice, unsigned char bit) -{ - int tm; - for (tm = 0; tm < 0x10000; tm++) - if ((inb(ICEMT1724(ice, AC97_CMD)) & bit) == 0) - return 0; - snd_printd(KERN_ERR "snd_vt1724_ac97_wait_bit: timeout\n"); - return -EIO; -} - -static void snd_vt1724_ac97_write(struct snd_ac97 *ac97, - unsigned short reg, - unsigned short val) -{ - struct snd_ice1712 *ice = ac97->private_data; - unsigned char old_cmd; - - old_cmd = snd_vt1724_ac97_ready(ice); - old_cmd &= ~VT1724_AC97_ID_MASK; - old_cmd |= ac97->num; - outb(reg, ICEMT1724(ice, AC97_INDEX)); - outw(val, ICEMT1724(ice, AC97_DATA)); - outb(old_cmd | VT1724_AC97_WRITE, ICEMT1724(ice, AC97_CMD)); - snd_vt1724_ac97_wait_bit(ice, VT1724_AC97_WRITE); -} - -static unsigned short snd_vt1724_ac97_read(struct snd_ac97 *ac97, unsigned short reg) -{ - struct snd_ice1712 *ice = ac97->private_data; - unsigned char old_cmd; - - old_cmd = snd_vt1724_ac97_ready(ice); - old_cmd &= ~VT1724_AC97_ID_MASK; - old_cmd |= ac97->num; - outb(reg, ICEMT1724(ice, AC97_INDEX)); - outb(old_cmd | VT1724_AC97_READ, ICEMT1724(ice, AC97_CMD)); - if (snd_vt1724_ac97_wait_bit(ice, VT1724_AC97_READ) < 0) - return ~0; - return inw(ICEMT1724(ice, AC97_DATA)); -} - - -/* - * GPIO operations - */ - -/* set gpio direction 0 = read, 1 = write */ -static void snd_vt1724_set_gpio_dir(struct snd_ice1712 *ice, unsigned int data) -{ - outl(data, ICEREG1724(ice, GPIO_DIRECTION)); - inw(ICEREG1724(ice, GPIO_DIRECTION)); /* dummy read for pci-posting */ -} - -/* get gpio direction 0 = read, 1 = write */ -static unsigned int snd_vt1724_get_gpio_dir(struct snd_ice1712 *ice) -{ - return inl(ICEREG1724(ice, GPIO_DIRECTION)); -} - -/* set the gpio mask (0 = writable) */ -static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data) -{ - outw(data, ICEREG1724(ice, GPIO_WRITE_MASK)); - if (!ice->vt1720) /* VT1720 supports only 16 GPIO bits */ - outb((data >> 16) & 0xff, ICEREG1724(ice, GPIO_WRITE_MASK_22)); - inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */ -} - -static unsigned int snd_vt1724_get_gpio_mask(struct snd_ice1712 *ice) -{ - unsigned int mask; - if (!ice->vt1720) - mask = (unsigned int)inb(ICEREG1724(ice, GPIO_WRITE_MASK_22)); - else - mask = 0; - mask = (mask << 16) | inw(ICEREG1724(ice, GPIO_WRITE_MASK)); - return mask; -} - -static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data) -{ - outw(data, ICEREG1724(ice, GPIO_DATA)); - if (!ice->vt1720) - outb(data >> 16, ICEREG1724(ice, GPIO_DATA_22)); - inw(ICEREG1724(ice, GPIO_DATA)); /* dummy read for pci-posting */ -} - -static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice) -{ - unsigned int data; - if (!ice->vt1720) - data = (unsigned int)inb(ICEREG1724(ice, GPIO_DATA_22)); - else - data = 0; - data = (data << 16) | inw(ICEREG1724(ice, GPIO_DATA)); - return data; -} - -/* - * MIDI - */ - -static void vt1724_midi_clear_rx(struct snd_ice1712 *ice) -{ - unsigned int count; - - for (count = inb(ICEREG1724(ice, MPU_RXFIFO)); count > 0; --count) - inb(ICEREG1724(ice, MPU_DATA)); -} - -static inline struct snd_rawmidi_substream * -get_rawmidi_substream(struct snd_ice1712 *ice, unsigned int stream) -{ - return list_first_entry(&ice->rmidi[0]->streams[stream].substreams, - struct snd_rawmidi_substream, list); -} - -static void enable_midi_irq(struct snd_ice1712 *ice, u8 flag, int enable); - -static void vt1724_midi_write(struct snd_ice1712 *ice) -{ - struct snd_rawmidi_substream *s; - int count, i; - u8 buffer[32]; - - s = get_rawmidi_substream(ice, SNDRV_RAWMIDI_STREAM_OUTPUT); - count = 31 - inb(ICEREG1724(ice, MPU_TXFIFO)); - if (count > 0) { - count = snd_rawmidi_transmit(s, buffer, count); - for (i = 0; i < count; ++i) - outb(buffer[i], ICEREG1724(ice, MPU_DATA)); - } - /* mask irq when all bytes have been transmitted. - * enabled again in output_trigger when the new data comes in. - */ - enable_midi_irq(ice, VT1724_IRQ_MPU_TX, - !snd_rawmidi_transmit_empty(s)); -} - -static void vt1724_midi_read(struct snd_ice1712 *ice) -{ - struct snd_rawmidi_substream *s; - int count, i; - u8 buffer[32]; - - s = get_rawmidi_substream(ice, SNDRV_RAWMIDI_STREAM_INPUT); - count = inb(ICEREG1724(ice, MPU_RXFIFO)); - if (count > 0) { - count = min(count, 32); - for (i = 0; i < count; ++i) - buffer[i] = inb(ICEREG1724(ice, MPU_DATA)); - snd_rawmidi_receive(s, buffer, count); - } -} - -/* call with ice->reg_lock */ -static void enable_midi_irq(struct snd_ice1712 *ice, u8 flag, int enable) -{ - u8 mask = inb(ICEREG1724(ice, IRQMASK)); - if (enable) - mask &= ~flag; - else - mask |= flag; - outb(mask, ICEREG1724(ice, IRQMASK)); -} - -static void vt1724_enable_midi_irq(struct snd_rawmidi_substream *substream, - u8 flag, int enable) -{ - struct snd_ice1712 *ice = substream->rmidi->private_data; - - spin_lock_irq(&ice->reg_lock); - enable_midi_irq(ice, flag, enable); - spin_unlock_irq(&ice->reg_lock); -} - -static int vt1724_midi_output_open(struct snd_rawmidi_substream *s) -{ - return 0; -} - -static int vt1724_midi_output_close(struct snd_rawmidi_substream *s) -{ - return 0; -} - -static void vt1724_midi_output_trigger(struct snd_rawmidi_substream *s, int up) -{ - struct snd_ice1712 *ice = s->rmidi->private_data; - unsigned long flags; - - spin_lock_irqsave(&ice->reg_lock, flags); - if (up) { - ice->midi_output = 1; - vt1724_midi_write(ice); - } else { - ice->midi_output = 0; - enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0); - } - spin_unlock_irqrestore(&ice->reg_lock, flags); -} - -static void vt1724_midi_output_drain(struct snd_rawmidi_substream *s) -{ - struct snd_ice1712 *ice = s->rmidi->private_data; - unsigned long timeout; - - vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_TX, 0); - /* 32 bytes should be transmitted in less than about 12 ms */ - timeout = jiffies + msecs_to_jiffies(15); - do { - if (inb(ICEREG1724(ice, MPU_CTRL)) & VT1724_MPU_TX_EMPTY) - break; - schedule_timeout_uninterruptible(1); - } while (time_after(timeout, jiffies)); -} - -static struct snd_rawmidi_ops vt1724_midi_output_ops = { - .open = vt1724_midi_output_open, - .close = vt1724_midi_output_close, - .trigger = vt1724_midi_output_trigger, - .drain = vt1724_midi_output_drain, -}; - -static int vt1724_midi_input_open(struct snd_rawmidi_substream *s) -{ - vt1724_midi_clear_rx(s->rmidi->private_data); - vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_RX, 1); - return 0; -} - -static int vt1724_midi_input_close(struct snd_rawmidi_substream *s) -{ - vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_RX, 0); - return 0; -} - -static void vt1724_midi_input_trigger(struct snd_rawmidi_substream *s, int up) -{ - struct snd_ice1712 *ice = s->rmidi->private_data; - unsigned long flags; - - spin_lock_irqsave(&ice->reg_lock, flags); - if (up) { - ice->midi_input = 1; - vt1724_midi_read(ice); - } else { - ice->midi_input = 0; - } - spin_unlock_irqrestore(&ice->reg_lock, flags); -} - -static struct snd_rawmidi_ops vt1724_midi_input_ops = { - .open = vt1724_midi_input_open, - .close = vt1724_midi_input_close, - .trigger = vt1724_midi_input_trigger, -}; - - -/* - * Interrupt handler - */ - -static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id) -{ - struct snd_ice1712 *ice = dev_id; - unsigned char status; - unsigned char status_mask = - VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM; - int handled = 0; - int timeout = 0; - - while (1) { - status = inb(ICEREG1724(ice, IRQSTAT)); - status &= status_mask; - if (status == 0) - break; - spin_lock(&ice->reg_lock); - if (++timeout > 10) { - status = inb(ICEREG1724(ice, IRQSTAT)); - printk(KERN_ERR "ice1724: Too long irq loop, " - "status = 0x%x\n", status); - if (status & VT1724_IRQ_MPU_TX) { - printk(KERN_ERR "ice1724: Disabling MPU_TX\n"); - enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0); - } - spin_unlock(&ice->reg_lock); - break; - } - handled = 1; - if (status & VT1724_IRQ_MPU_TX) { - if (ice->midi_output) - vt1724_midi_write(ice); - else - enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0); - /* Due to mysterical reasons, MPU_TX is always - * generated (and can't be cleared) when a PCM - * playback is going. So let's ignore at the - * next loop. - */ - status_mask &= ~VT1724_IRQ_MPU_TX; - } - if (status & VT1724_IRQ_MPU_RX) { - if (ice->midi_input) - vt1724_midi_read(ice); - else - vt1724_midi_clear_rx(ice); - } - /* ack MPU irq */ - outb(status, ICEREG1724(ice, IRQSTAT)); - spin_unlock(&ice->reg_lock); - if (status & VT1724_IRQ_MTPCM) { - /* - * Multi-track PCM - * PCM assignment are: - * Playback DMA0 (M/C) = playback_pro_substream - * Playback DMA1 = playback_con_substream_ds[0] - * Playback DMA2 = playback_con_substream_ds[1] - * Playback DMA3 = playback_con_substream_ds[2] - * Playback DMA4 (SPDIF) = playback_con_substream - * Record DMA0 = capture_pro_substream - * Record DMA1 = capture_con_substream - */ - unsigned char mtstat = inb(ICEMT1724(ice, IRQ)); - if (mtstat & VT1724_MULTI_PDMA0) { - if (ice->playback_pro_substream) - snd_pcm_period_elapsed(ice->playback_pro_substream); - } - if (mtstat & VT1724_MULTI_RDMA0) { - if (ice->capture_pro_substream) - snd_pcm_period_elapsed(ice->capture_pro_substream); - } - if (mtstat & VT1724_MULTI_PDMA1) { - if (ice->playback_con_substream_ds[0]) - snd_pcm_period_elapsed(ice->playback_con_substream_ds[0]); - } - if (mtstat & VT1724_MULTI_PDMA2) { - if (ice->playback_con_substream_ds[1]) - snd_pcm_period_elapsed(ice->playback_con_substream_ds[1]); - } - if (mtstat & VT1724_MULTI_PDMA3) { - if (ice->playback_con_substream_ds[2]) - snd_pcm_period_elapsed(ice->playback_con_substream_ds[2]); - } - if (mtstat & VT1724_MULTI_PDMA4) { - if (ice->playback_con_substream) - snd_pcm_period_elapsed(ice->playback_con_substream); - } - if (mtstat & VT1724_MULTI_RDMA1) { - if (ice->capture_con_substream) - snd_pcm_period_elapsed(ice->capture_con_substream); - } - /* ack anyway to avoid freeze */ - outb(mtstat, ICEMT1724(ice, IRQ)); - /* ought to really handle this properly */ - if (mtstat & VT1724_MULTI_FIFO_ERR) { - unsigned char fstat = inb(ICEMT1724(ice, DMA_FIFO_ERR)); - outb(fstat, ICEMT1724(ice, DMA_FIFO_ERR)); - outb(VT1724_MULTI_FIFO_ERR | inb(ICEMT1724(ice, DMA_INT_MASK)), ICEMT1724(ice, DMA_INT_MASK)); - /* If I don't do this, I get machine lockup due to continual interrupts */ - } - - } - } - return IRQ_RETVAL(handled); -} - -/* - * PCM code - professional part (multitrack) - */ - -static unsigned int rates[] = { - 8000, 9600, 11025, 12000, 16000, 22050, 24000, - 32000, 44100, 48000, 64000, 88200, 96000, - 176400, 192000, -}; - -static struct snd_pcm_hw_constraint_list hw_constraints_rates_96 = { - .count = ARRAY_SIZE(rates) - 2, /* up to 96000 */ - .list = rates, - .mask = 0, -}; - -static struct snd_pcm_hw_constraint_list hw_constraints_rates_48 = { - .count = ARRAY_SIZE(rates) - 5, /* up to 48000 */ - .list = rates, - .mask = 0, -}; - -static struct snd_pcm_hw_constraint_list hw_constraints_rates_192 = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -struct vt1724_pcm_reg { - unsigned int addr; /* ADDR register offset */ - unsigned int size; /* SIZE register offset */ - unsigned int count; /* COUNT register offset */ - unsigned int start; /* start & pause bit */ -}; - -static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - unsigned char what; - unsigned char old; - struct snd_pcm_substream *s; - - what = 0; - snd_pcm_group_for_each_entry(s, substream) { - if (snd_pcm_substream_chip(s) == ice) { - const struct vt1724_pcm_reg *reg; - reg = s->runtime->private_data; - what |= reg->start; - snd_pcm_trigger_done(s, substream); - } - } - - switch (cmd) { - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - spin_lock(&ice->reg_lock); - old = inb(ICEMT1724(ice, DMA_PAUSE)); - if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) - old |= what; - else - old &= ~what; - outb(old, ICEMT1724(ice, DMA_PAUSE)); - spin_unlock(&ice->reg_lock); - break; - - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - spin_lock(&ice->reg_lock); - old = inb(ICEMT1724(ice, DMA_CONTROL)); - if (cmd == SNDRV_PCM_TRIGGER_START) - old |= what; - else - old &= ~what; - outb(old, ICEMT1724(ice, DMA_CONTROL)); - spin_unlock(&ice->reg_lock); - break; - - case SNDRV_PCM_TRIGGER_RESUME: - /* apps will have to restart stream */ - break; - - default: - return -EINVAL; - } - return 0; -} - -/* - */ - -#define DMA_STARTS (VT1724_RDMA0_START|VT1724_PDMA0_START|VT1724_RDMA1_START|\ - VT1724_PDMA1_START|VT1724_PDMA2_START|VT1724_PDMA3_START|VT1724_PDMA4_START) -#define DMA_PAUSES (VT1724_RDMA0_PAUSE|VT1724_PDMA0_PAUSE|VT1724_RDMA1_PAUSE|\ - VT1724_PDMA1_PAUSE|VT1724_PDMA2_PAUSE|VT1724_PDMA3_PAUSE|VT1724_PDMA4_PAUSE) - -static const unsigned int stdclock_rate_list[16] = { - 48000, 24000, 12000, 9600, 32000, 16000, 8000, 96000, 44100, - 22050, 11025, 88200, 176400, 0, 192000, 64000 -}; - -static unsigned int stdclock_get_rate(struct snd_ice1712 *ice) -{ - unsigned int rate; - rate = stdclock_rate_list[inb(ICEMT1724(ice, RATE)) & 15]; - return rate; -} - -static void stdclock_set_rate(struct snd_ice1712 *ice, unsigned int rate) -{ - int i; - for (i = 0; i < ARRAY_SIZE(stdclock_rate_list); i++) { - if (stdclock_rate_list[i] == rate) { - outb(i, ICEMT1724(ice, RATE)); - return; - } - } -} - -static unsigned char stdclock_set_mclk(struct snd_ice1712 *ice, - unsigned int rate) -{ - unsigned char val, old; - /* check MT02 */ - if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) { - val = old = inb(ICEMT1724(ice, I2S_FORMAT)); - if (rate > 96000) - val |= VT1724_MT_I2S_MCLK_128X; /* 128x MCLK */ - else - val &= ~VT1724_MT_I2S_MCLK_128X; /* 256x MCLK */ - if (val != old) { - outb(val, ICEMT1724(ice, I2S_FORMAT)); - /* master clock changed */ - return 1; - } - } - /* no change in master clock */ - return 0; -} - -static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, - int force) -{ - unsigned long flags; - unsigned char mclk_change; - unsigned int i, old_rate; - - if (rate > ice->hw_rates->list[ice->hw_rates->count - 1]) - return -EINVAL; - - spin_lock_irqsave(&ice->reg_lock, flags); - if ((inb(ICEMT1724(ice, DMA_CONTROL)) & DMA_STARTS) || - (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) { - /* running? we cannot change the rate now... */ - spin_unlock_irqrestore(&ice->reg_lock, flags); - return ((rate == ice->cur_rate) && !force) ? 0 : -EBUSY; - } - if (!force && is_pro_rate_locked(ice)) { - /* comparing required and current rate - makes sense for - * internal clock only */ - spin_unlock_irqrestore(&ice->reg_lock, flags); - return (rate == ice->cur_rate) ? 0 : -EBUSY; - } - - if (force || !ice->is_spdif_master(ice)) { - /* force means the rate was switched by ucontrol, otherwise - * setting clock rate for internal clock mode */ - old_rate = ice->get_rate(ice); - if (force || (old_rate != rate)) - ice->set_rate(ice, rate); - else if (rate == ice->cur_rate) { - spin_unlock_irqrestore(&ice->reg_lock, flags); - return 0; - } - } - - ice->cur_rate = rate; - - /* setting master clock */ - mclk_change = ice->set_mclk(ice, rate); - - spin_unlock_irqrestore(&ice->reg_lock, flags); - - if (mclk_change && ice->gpio.i2s_mclk_changed) - ice->gpio.i2s_mclk_changed(ice); - if (ice->gpio.set_pro_rate) - ice->gpio.set_pro_rate(ice, rate); - - /* set up codecs */ - for (i = 0; i < ice->akm_codecs; i++) { - if (ice->akm[i].ops.set_rate_val) - ice->akm[i].ops.set_rate_val(&ice->akm[i], rate); - } - if (ice->spdif.ops.setup_rate) - ice->spdif.ops.setup_rate(ice, rate); - - return 0; -} - -static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - int i, chs, err; - - chs = params_channels(hw_params); - mutex_lock(&ice->open_mutex); - /* mark surround channels */ - if (substream == ice->playback_pro_substream) { - /* PDMA0 can be multi-channel up to 8 */ - chs = chs / 2 - 1; - for (i = 0; i < chs; i++) { - if (ice->pcm_reserved[i] && - ice->pcm_reserved[i] != substream) { - mutex_unlock(&ice->open_mutex); - return -EBUSY; - } - ice->pcm_reserved[i] = substream; - } - for (; i < 3; i++) { - if (ice->pcm_reserved[i] == substream) - ice->pcm_reserved[i] = NULL; - } - } else { - for (i = 0; i < 3; i++) { - /* check individual playback stream */ - if (ice->playback_con_substream_ds[i] == substream) { - if (ice->pcm_reserved[i] && - ice->pcm_reserved[i] != substream) { - mutex_unlock(&ice->open_mutex); - return -EBUSY; - } - ice->pcm_reserved[i] = substream; - break; - } - } - } - mutex_unlock(&ice->open_mutex); - - err = snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0); - if (err < 0) - return err; - - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); -} - -static int snd_vt1724_pcm_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - int i; - - mutex_lock(&ice->open_mutex); - /* unmark surround channels */ - for (i = 0; i < 3; i++) - if (ice->pcm_reserved[i] == substream) - ice->pcm_reserved[i] = NULL; - mutex_unlock(&ice->open_mutex); - return snd_pcm_lib_free_pages(substream); -} - -static int snd_vt1724_playback_pro_prepare(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - unsigned char val; - unsigned int size; - - spin_lock_irq(&ice->reg_lock); - val = (8 - substream->runtime->channels) >> 1; - outb(val, ICEMT1724(ice, BURST)); - - outl(substream->runtime->dma_addr, ICEMT1724(ice, PLAYBACK_ADDR)); - - size = (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1; - /* outl(size, ICEMT1724(ice, PLAYBACK_SIZE)); */ - outw(size, ICEMT1724(ice, PLAYBACK_SIZE)); - outb(size >> 16, ICEMT1724(ice, PLAYBACK_SIZE) + 2); - size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1; - /* outl(size, ICEMT1724(ice, PLAYBACK_COUNT)); */ - outw(size, ICEMT1724(ice, PLAYBACK_COUNT)); - outb(size >> 16, ICEMT1724(ice, PLAYBACK_COUNT) + 2); - - spin_unlock_irq(&ice->reg_lock); - - /* - printk(KERN_DEBUG "pro prepare: ch = %d, addr = 0x%x, " - "buffer = 0x%x, period = 0x%x\n", - substream->runtime->channels, - (unsigned int)substream->runtime->dma_addr, - snd_pcm_lib_buffer_bytes(substream), - snd_pcm_lib_period_bytes(substream)); - */ - return 0; -} - -static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - size_t ptr; - - if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & VT1724_PDMA0_START)) - return 0; -#if 0 /* read PLAYBACK_ADDR */ - ptr = inl(ICEMT1724(ice, PLAYBACK_ADDR)); - if (ptr < substream->runtime->dma_addr) { - snd_printd("ice1724: invalid negative ptr\n"); - return 0; - } - ptr -= substream->runtime->dma_addr; - ptr = bytes_to_frames(substream->runtime, ptr); - if (ptr >= substream->runtime->buffer_size) { - snd_printd("ice1724: invalid ptr %d (size=%d)\n", - (int)ptr, (int)substream->runtime->period_size); - return 0; - } -#else /* read PLAYBACK_SIZE */ - ptr = inl(ICEMT1724(ice, PLAYBACK_SIZE)) & 0xffffff; - ptr = (ptr + 1) << 2; - ptr = bytes_to_frames(substream->runtime, ptr); - if (!ptr) - ; - else if (ptr <= substream->runtime->buffer_size) - ptr = substream->runtime->buffer_size - ptr; - else { - snd_printd("ice1724: invalid ptr %d (size=%d)\n", - (int)ptr, (int)substream->runtime->buffer_size); - ptr = 0; - } -#endif - return ptr; -} - -static int snd_vt1724_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - const struct vt1724_pcm_reg *reg = substream->runtime->private_data; - - spin_lock_irq(&ice->reg_lock); - outl(substream->runtime->dma_addr, ice->profi_port + reg->addr); - outw((snd_pcm_lib_buffer_bytes(substream) >> 2) - 1, - ice->profi_port + reg->size); - outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, - ice->profi_port + reg->count); - spin_unlock_irq(&ice->reg_lock); - return 0; -} - -static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - const struct vt1724_pcm_reg *reg = substream->runtime->private_data; - size_t ptr; - - if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & reg->start)) - return 0; -#if 0 /* use ADDR register */ - ptr = inl(ice->profi_port + reg->addr); - ptr -= substream->runtime->dma_addr; - return bytes_to_frames(substream->runtime, ptr); -#else /* use SIZE register */ - ptr = inw(ice->profi_port + reg->size); - ptr = (ptr + 1) << 2; - ptr = bytes_to_frames(substream->runtime, ptr); - if (!ptr) - ; - else if (ptr <= substream->runtime->buffer_size) - ptr = substream->runtime->buffer_size - ptr; - else { - snd_printd("ice1724: invalid ptr %d (size=%d)\n", - (int)ptr, (int)substream->runtime->buffer_size); - ptr = 0; - } - return ptr; -#endif -} - -static const struct vt1724_pcm_reg vt1724_pdma0_reg = { - .addr = VT1724_MT_PLAYBACK_ADDR, - .size = VT1724_MT_PLAYBACK_SIZE, - .count = VT1724_MT_PLAYBACK_COUNT, - .start = VT1724_PDMA0_START, -}; - -static const struct vt1724_pcm_reg vt1724_pdma4_reg = { - .addr = VT1724_MT_PDMA4_ADDR, - .size = VT1724_MT_PDMA4_SIZE, - .count = VT1724_MT_PDMA4_COUNT, - .start = VT1724_PDMA4_START, -}; - -static const struct vt1724_pcm_reg vt1724_rdma0_reg = { - .addr = VT1724_MT_CAPTURE_ADDR, - .size = VT1724_MT_CAPTURE_SIZE, - .count = VT1724_MT_CAPTURE_COUNT, - .start = VT1724_RDMA0_START, -}; - -static const struct vt1724_pcm_reg vt1724_rdma1_reg = { - .addr = VT1724_MT_RDMA1_ADDR, - .size = VT1724_MT_RDMA1_SIZE, - .count = VT1724_MT_RDMA1_COUNT, - .start = VT1724_RDMA1_START, -}; - -#define vt1724_playback_pro_reg vt1724_pdma0_reg -#define vt1724_playback_spdif_reg vt1724_pdma4_reg -#define vt1724_capture_pro_reg vt1724_rdma0_reg -#define vt1724_capture_spdif_reg vt1724_rdma1_reg - -static const struct snd_pcm_hardware snd_vt1724_playback_pro = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START), - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000, - .rate_min = 8000, - .rate_max = 192000, - .channels_min = 2, - .channels_max = 8, - .buffer_bytes_max = (1UL << 21), /* 19bits dword */ - .period_bytes_min = 8 * 4 * 2, /* FIXME: constraints needed */ - .period_bytes_max = (1UL << 21), - .periods_min = 2, - .periods_max = 1024, -}; - -static const struct snd_pcm_hardware snd_vt1724_spdif = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START), - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .rates = (SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100| - SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_88200| - SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_176400| - SNDRV_PCM_RATE_192000), - .rate_min = 32000, - .rate_max = 192000, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = (1UL << 18), /* 16bits dword */ - .period_bytes_min = 2 * 4 * 2, - .period_bytes_max = (1UL << 18), - .periods_min = 2, - .periods_max = 1024, -}; - -static const struct snd_pcm_hardware snd_vt1724_2ch_stereo = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START), - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000, - .rate_min = 8000, - .rate_max = 192000, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = (1UL << 18), /* 16bits dword */ - .period_bytes_min = 2 * 4 * 2, - .period_bytes_max = (1UL << 18), - .periods_min = 2, - .periods_max = 1024, -}; - -/* - * set rate constraints - */ -static void set_std_hw_rates(struct snd_ice1712 *ice) -{ - if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) { - /* I2S */ - /* VT1720 doesn't support more than 96kHz */ - if ((ice->eeprom.data[ICE_EEP2_I2S] & 0x08) && !ice->vt1720) - ice->hw_rates = &hw_constraints_rates_192; - else - ice->hw_rates = &hw_constraints_rates_96; - } else { - /* ACLINK */ - ice->hw_rates = &hw_constraints_rates_48; - } -} - -static int set_rate_constraints(struct snd_ice1712 *ice, - struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw.rate_min = ice->hw_rates->list[0]; - runtime->hw.rate_max = ice->hw_rates->list[ice->hw_rates->count - 1]; - runtime->hw.rates = SNDRV_PCM_RATE_KNOT; - return snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - ice->hw_rates); -} - -/* if the card has the internal rate locked (is_pro_locked), limit runtime - hw rates to the current internal rate only. -*/ -static void constrain_rate_if_locked(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned int rate; - if (is_pro_rate_locked(ice)) { - rate = ice->get_rate(ice); - if (rate >= runtime->hw.rate_min - && rate <= runtime->hw.rate_max) { - runtime->hw.rate_min = rate; - runtime->hw.rate_max = rate; - } - } -} - - -/* multi-channel playback needs alignment 8x32bit regardless of the channels - * actually used - */ -#define VT1724_BUFFER_ALIGN 0x20 - -static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - int chs, num_indeps; - - runtime->private_data = (void *)&vt1724_playback_pro_reg; - ice->playback_pro_substream = substream; - runtime->hw = snd_vt1724_playback_pro; - snd_pcm_set_sync(substream); - snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); - set_rate_constraints(ice, substream); - mutex_lock(&ice->open_mutex); - /* calculate the currently available channels */ - num_indeps = ice->num_total_dacs / 2 - 1; - for (chs = 0; chs < num_indeps; chs++) { - if (ice->pcm_reserved[chs]) - break; - } - chs = (chs + 1) * 2; - runtime->hw.channels_max = chs; - if (chs > 2) /* channels must be even */ - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2); - mutex_unlock(&ice->open_mutex); - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, - VT1724_BUFFER_ALIGN); - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - VT1724_BUFFER_ALIGN); - constrain_rate_if_locked(substream); - if (ice->pro_open) - ice->pro_open(ice, substream); - return 0; -} - -static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->private_data = (void *)&vt1724_capture_pro_reg; - ice->capture_pro_substream = substream; - runtime->hw = snd_vt1724_2ch_stereo; - snd_pcm_set_sync(substream); - snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); - set_rate_constraints(ice, substream); - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, - VT1724_BUFFER_ALIGN); - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - VT1724_BUFFER_ALIGN); - constrain_rate_if_locked(substream); - if (ice->pro_open) - ice->pro_open(ice, substream); - return 0; -} - -static int snd_vt1724_playback_pro_close(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - if (PRO_RATE_RESET) - snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 0); - ice->playback_pro_substream = NULL; - - return 0; -} - -static int snd_vt1724_capture_pro_close(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - if (PRO_RATE_RESET) - snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 0); - ice->capture_pro_substream = NULL; - return 0; -} - -static struct snd_pcm_ops snd_vt1724_playback_pro_ops = { - .open = snd_vt1724_playback_pro_open, - .close = snd_vt1724_playback_pro_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_vt1724_pcm_hw_params, - .hw_free = snd_vt1724_pcm_hw_free, - .prepare = snd_vt1724_playback_pro_prepare, - .trigger = snd_vt1724_pcm_trigger, - .pointer = snd_vt1724_playback_pro_pointer, -}; - -static struct snd_pcm_ops snd_vt1724_capture_pro_ops = { - .open = snd_vt1724_capture_pro_open, - .close = snd_vt1724_capture_pro_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_vt1724_pcm_hw_params, - .hw_free = snd_vt1724_pcm_hw_free, - .prepare = snd_vt1724_pcm_prepare, - .trigger = snd_vt1724_pcm_trigger, - .pointer = snd_vt1724_pcm_pointer, -}; - -static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 *ice, int device) -{ - struct snd_pcm *pcm; - int capt, err; - - if ((ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_ADC_MASK) == - VT1724_CFG_ADC_NONE) - capt = 0; - else - capt = 1; - err = snd_pcm_new(ice->card, "ICE1724", device, 1, capt, &pcm); - if (err < 0) - return err; - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_vt1724_playback_pro_ops); - if (capt) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, - &snd_vt1724_capture_pro_ops); - - pcm->private_data = ice; - pcm->info_flags = 0; - strcpy(pcm->name, "ICE1724"); - - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(ice->pci), - 256*1024, 256*1024); - - ice->pcm_pro = pcm; - - return 0; -} - - -/* - * SPDIF PCM - */ - -/* update spdif control bits; call with reg_lock */ -static void update_spdif_bits(struct snd_ice1712 *ice, unsigned int val) -{ - unsigned char cbit, disabled; - - cbit = inb(ICEREG1724(ice, SPDIF_CFG)); - disabled = cbit & ~VT1724_CFG_SPDIF_OUT_EN; - if (cbit != disabled) - outb(disabled, ICEREG1724(ice, SPDIF_CFG)); - outw(val, ICEMT1724(ice, SPDIF_CTRL)); - if (cbit != disabled) - outb(cbit, ICEREG1724(ice, SPDIF_CFG)); - outw(val, ICEMT1724(ice, SPDIF_CTRL)); -} - -/* update SPDIF control bits according to the given rate */ -static void update_spdif_rate(struct snd_ice1712 *ice, unsigned int rate) -{ - unsigned int val, nval; - unsigned long flags; - - spin_lock_irqsave(&ice->reg_lock, flags); - nval = val = inw(ICEMT1724(ice, SPDIF_CTRL)); - nval &= ~(7 << 12); - switch (rate) { - case 44100: break; - case 48000: nval |= 2 << 12; break; - case 32000: nval |= 3 << 12; break; - case 88200: nval |= 4 << 12; break; - case 96000: nval |= 5 << 12; break; - case 192000: nval |= 6 << 12; break; - case 176400: nval |= 7 << 12; break; - } - if (val != nval) - update_spdif_bits(ice, nval); - spin_unlock_irqrestore(&ice->reg_lock, flags); -} - -static int snd_vt1724_playback_spdif_prepare(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - if (!ice->force_pdma4) - update_spdif_rate(ice, substream->runtime->rate); - return snd_vt1724_pcm_prepare(substream); -} - -static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->private_data = (void *)&vt1724_playback_spdif_reg; - ice->playback_con_substream = substream; - if (ice->force_pdma4) { - runtime->hw = snd_vt1724_2ch_stereo; - set_rate_constraints(ice, substream); - } else - runtime->hw = snd_vt1724_spdif; - snd_pcm_set_sync(substream); - snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, - VT1724_BUFFER_ALIGN); - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - VT1724_BUFFER_ALIGN); - constrain_rate_if_locked(substream); - if (ice->spdif.ops.open) - ice->spdif.ops.open(ice, substream); - return 0; -} - -static int snd_vt1724_playback_spdif_close(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - if (PRO_RATE_RESET) - snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 0); - ice->playback_con_substream = NULL; - if (ice->spdif.ops.close) - ice->spdif.ops.close(ice, substream); - - return 0; -} - -static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->private_data = (void *)&vt1724_capture_spdif_reg; - ice->capture_con_substream = substream; - if (ice->force_rdma1) { - runtime->hw = snd_vt1724_2ch_stereo; - set_rate_constraints(ice, substream); - } else - runtime->hw = snd_vt1724_spdif; - snd_pcm_set_sync(substream); - snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, - VT1724_BUFFER_ALIGN); - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - VT1724_BUFFER_ALIGN); - constrain_rate_if_locked(substream); - if (ice->spdif.ops.open) - ice->spdif.ops.open(ice, substream); - return 0; -} - -static int snd_vt1724_capture_spdif_close(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - if (PRO_RATE_RESET) - snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 0); - ice->capture_con_substream = NULL; - if (ice->spdif.ops.close) - ice->spdif.ops.close(ice, substream); - - return 0; -} - -static struct snd_pcm_ops snd_vt1724_playback_spdif_ops = { - .open = snd_vt1724_playback_spdif_open, - .close = snd_vt1724_playback_spdif_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_vt1724_pcm_hw_params, - .hw_free = snd_vt1724_pcm_hw_free, - .prepare = snd_vt1724_playback_spdif_prepare, - .trigger = snd_vt1724_pcm_trigger, - .pointer = snd_vt1724_pcm_pointer, -}; - -static struct snd_pcm_ops snd_vt1724_capture_spdif_ops = { - .open = snd_vt1724_capture_spdif_open, - .close = snd_vt1724_capture_spdif_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_vt1724_pcm_hw_params, - .hw_free = snd_vt1724_pcm_hw_free, - .prepare = snd_vt1724_pcm_prepare, - .trigger = snd_vt1724_pcm_trigger, - .pointer = snd_vt1724_pcm_pointer, -}; - - -static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device) -{ - char *name; - struct snd_pcm *pcm; - int play, capt; - int err; - - if (ice->force_pdma4 || - (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_OUT_INT)) { - play = 1; - ice->has_spdif = 1; - } else - play = 0; - if (ice->force_rdma1 || - (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_IN)) { - capt = 1; - ice->has_spdif = 1; - } else - capt = 0; - if (!play && !capt) - return 0; /* no spdif device */ - - if (ice->force_pdma4 || ice->force_rdma1) - name = "ICE1724 Secondary"; - else - name = "ICE1724 IEC958"; - err = snd_pcm_new(ice->card, name, device, play, capt, &pcm); - if (err < 0) - return err; - - if (play) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_vt1724_playback_spdif_ops); - if (capt) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, - &snd_vt1724_capture_spdif_ops); - - pcm->private_data = ice; - pcm->info_flags = 0; - strcpy(pcm->name, name); - - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(ice->pci), - 256*1024, 256*1024); - - ice->pcm = pcm; - - return 0; -} - - -/* - * independent surround PCMs - */ - -static const struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = { - { - .addr = VT1724_MT_PDMA1_ADDR, - .size = VT1724_MT_PDMA1_SIZE, - .count = VT1724_MT_PDMA1_COUNT, - .start = VT1724_PDMA1_START, - }, - { - .addr = VT1724_MT_PDMA2_ADDR, - .size = VT1724_MT_PDMA2_SIZE, - .count = VT1724_MT_PDMA2_COUNT, - .start = VT1724_PDMA2_START, - }, - { - .addr = VT1724_MT_PDMA3_ADDR, - .size = VT1724_MT_PDMA3_SIZE, - .count = VT1724_MT_PDMA3_COUNT, - .start = VT1724_PDMA3_START, - }, -}; - -static int snd_vt1724_playback_indep_prepare(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - unsigned char val; - - spin_lock_irq(&ice->reg_lock); - val = 3 - substream->number; - if (inb(ICEMT1724(ice, BURST)) < val) - outb(val, ICEMT1724(ice, BURST)); - spin_unlock_irq(&ice->reg_lock); - return snd_vt1724_pcm_prepare(substream); -} - -static int snd_vt1724_playback_indep_open(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - - mutex_lock(&ice->open_mutex); - /* already used by PDMA0? */ - if (ice->pcm_reserved[substream->number]) { - mutex_unlock(&ice->open_mutex); - return -EBUSY; /* FIXME: should handle blocking mode properly */ - } - mutex_unlock(&ice->open_mutex); - runtime->private_data = (void *)&vt1724_playback_dma_regs[substream->number]; - ice->playback_con_substream_ds[substream->number] = substream; - runtime->hw = snd_vt1724_2ch_stereo; - snd_pcm_set_sync(substream); - snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); - set_rate_constraints(ice, substream); - return 0; -} - -static int snd_vt1724_playback_indep_close(struct snd_pcm_substream *substream) -{ - struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - - if (PRO_RATE_RESET) - snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 0); - ice->playback_con_substream_ds[substream->number] = NULL; - ice->pcm_reserved[substream->number] = NULL; - - return 0; -} - -static struct snd_pcm_ops snd_vt1724_playback_indep_ops = { - .open = snd_vt1724_playback_indep_open, - .close = snd_vt1724_playback_indep_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_vt1724_pcm_hw_params, - .hw_free = snd_vt1724_pcm_hw_free, - .prepare = snd_vt1724_playback_indep_prepare, - .trigger = snd_vt1724_pcm_trigger, - .pointer = snd_vt1724_pcm_pointer, -}; - - -static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device) -{ - struct snd_pcm *pcm; - int play; - int err; - - play = ice->num_total_dacs / 2 - 1; - if (play <= 0) - return 0; - - err = snd_pcm_new(ice->card, "ICE1724 Surrounds", device, play, 0, &pcm); - if (err < 0) - return err; - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_vt1724_playback_indep_ops); - - pcm->private_data = ice; - pcm->info_flags = 0; - strcpy(pcm->name, "ICE1724 Surround PCM"); - - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(ice->pci), - 256*1024, 256*1024); - - ice->pcm_ds = pcm; - - return 0; -} - - -/* - * Mixer section - */ - -static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 *ice) -{ - int err; - - if (!(ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S)) { - struct snd_ac97_bus *pbus; - struct snd_ac97_template ac97; - static struct snd_ac97_bus_ops ops = { - .write = snd_vt1724_ac97_write, - .read = snd_vt1724_ac97_read, - }; - - /* cold reset */ - outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD)); - mdelay(5); /* FIXME */ - outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD)); - - err = snd_ac97_bus(ice->card, 0, &ops, NULL, &pbus); - if (err < 0) - return err; - memset(&ac97, 0, sizeof(ac97)); - ac97.private_data = ice; - err = snd_ac97_mixer(pbus, &ac97, &ice->ac97); - if (err < 0) - printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n"); - else - return 0; - } - /* I2S mixer only */ - strcat(ice->card->mixername, "ICE1724 - multitrack"); - return 0; -} - -/* - * - */ - -static inline unsigned int eeprom_triple(struct snd_ice1712 *ice, int idx) -{ - return (unsigned int)ice->eeprom.data[idx] | \ - ((unsigned int)ice->eeprom.data[idx + 1] << 8) | \ - ((unsigned int)ice->eeprom.data[idx + 2] << 16); -} - -static void snd_vt1724_proc_read(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) -{ - struct snd_ice1712 *ice = entry->private_data; - unsigned int idx; - - snd_iprintf(buffer, "%s\n\n", ice->card->longname); - snd_iprintf(buffer, "EEPROM:\n"); - - snd_iprintf(buffer, " Subvendor : 0x%x\n", ice->eeprom.subvendor); - snd_iprintf(buffer, " Size : %i bytes\n", ice->eeprom.size); - snd_iprintf(buffer, " Version : %i\n", ice->eeprom.version); - snd_iprintf(buffer, " System Config : 0x%x\n", - ice->eeprom.data[ICE_EEP2_SYSCONF]); - snd_iprintf(buffer, " ACLink : 0x%x\n", - ice->eeprom.data[ICE_EEP2_ACLINK]); - snd_iprintf(buffer, " I2S : 0x%x\n", - ice->eeprom.data[ICE_EEP2_I2S]); - snd_iprintf(buffer, " S/PDIF : 0x%x\n", - ice->eeprom.data[ICE_EEP2_SPDIF]); - snd_iprintf(buffer, " GPIO direction : 0x%x\n", - ice->eeprom.gpiodir); - snd_iprintf(buffer, " GPIO mask : 0x%x\n", - ice->eeprom.gpiomask); - snd_iprintf(buffer, " GPIO state : 0x%x\n", - ice->eeprom.gpiostate); - for (idx = 0x12; idx < ice->eeprom.size; idx++) - snd_iprintf(buffer, " Extra #%02i : 0x%x\n", - idx, ice->eeprom.data[idx]); - - snd_iprintf(buffer, "\nRegisters:\n"); - - snd_iprintf(buffer, " PSDOUT03 : 0x%08x\n", - (unsigned)inl(ICEMT1724(ice, ROUTE_PLAYBACK))); - for (idx = 0x0; idx < 0x20 ; idx++) - snd_iprintf(buffer, " CCS%02x : 0x%02x\n", - idx, inb(ice->port+idx)); - for (idx = 0x0; idx < 0x30 ; idx++) - snd_iprintf(buffer, " MT%02x : 0x%02x\n", - idx, inb(ice->profi_port+idx)); -} - -static void __devinit snd_vt1724_proc_init(struct snd_ice1712 *ice) -{ - struct snd_info_entry *entry; - - if (!snd_card_proc_new(ice->card, "ice1724", &entry)) - snd_info_set_text_ops(entry, ice, snd_vt1724_proc_read); -} - -/* - * - */ - -static int snd_vt1724_eeprom_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = sizeof(struct snd_ice1712_eeprom); - return 0; -} - -static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom)); - return 0; -} - -static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - .name = "ICE1724 EEPROM", - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .info = snd_vt1724_eeprom_info, - .get = snd_vt1724_eeprom_get -}; - -/* - */ -static int snd_vt1724_spdif_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; - uinfo->count = 1; - return 0; -} - -static unsigned int encode_spdif_bits(struct snd_aes_iec958 *diga) -{ - unsigned int val, rbits; - - val = diga->status[0] & 0x03; /* professional, non-audio */ - if (val & 0x01) { - /* professional */ - if ((diga->status[0] & IEC958_AES0_PRO_EMPHASIS) == - IEC958_AES0_PRO_EMPHASIS_5015) - val |= 1U << 3; - rbits = (diga->status[4] >> 3) & 0x0f; - if (rbits) { - switch (rbits) { - case 2: val |= 5 << 12; break; /* 96k */ - case 3: val |= 6 << 12; break; /* 192k */ - case 10: val |= 4 << 12; break; /* 88.2k */ - case 11: val |= 7 << 12; break; /* 176.4k */ - } - } else { - switch (diga->status[0] & IEC958_AES0_PRO_FS) { - case IEC958_AES0_PRO_FS_44100: - break; - case IEC958_AES0_PRO_FS_32000: - val |= 3U << 12; - break; - default: - val |= 2U << 12; - break; - } - } - } else { - /* consumer */ - val |= diga->status[1] & 0x04; /* copyright */ - if ((diga->status[0] & IEC958_AES0_CON_EMPHASIS) == - IEC958_AES0_CON_EMPHASIS_5015) - val |= 1U << 3; - val |= (unsigned int)(diga->status[1] & 0x3f) << 4; /* category */ - val |= (unsigned int)(diga->status[3] & IEC958_AES3_CON_FS) << 12; /* fs */ - } - return val; -} - -static void decode_spdif_bits(struct snd_aes_iec958 *diga, unsigned int val) -{ - memset(diga->status, 0, sizeof(diga->status)); - diga->status[0] = val & 0x03; /* professional, non-audio */ - if (val & 0x01) { - /* professional */ - if (val & (1U << 3)) - diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015; - switch ((val >> 12) & 0x7) { - case 0: - break; - case 2: - diga->status[0] |= IEC958_AES0_PRO_FS_32000; - break; - default: - diga->status[0] |= IEC958_AES0_PRO_FS_48000; - break; - } - } else { - /* consumer */ - diga->status[0] |= val & (1U << 2); /* copyright */ - if (val & (1U << 3)) - diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015; - diga->status[1] |= (val >> 4) & 0x3f; /* category */ - diga->status[3] |= (val >> 12) & 0x07; /* fs */ - } -} - -static int snd_vt1724_spdif_default_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int val; - val = inw(ICEMT1724(ice, SPDIF_CTRL)); - decode_spdif_bits(&ucontrol->value.iec958, val); - return 0; -} - -static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int val, old; - - val = encode_spdif_bits(&ucontrol->value.iec958); - spin_lock_irq(&ice->reg_lock); - old = inw(ICEMT1724(ice, SPDIF_CTRL)); - if (val != old) - update_spdif_bits(ice, val); - spin_unlock_irq(&ice->reg_lock); - return val != old; -} - -static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = -{ - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), - .info = snd_vt1724_spdif_info, - .get = snd_vt1724_spdif_default_get, - .put = snd_vt1724_spdif_default_put -}; - -static int snd_vt1724_spdif_maskc_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO | - IEC958_AES0_PROFESSIONAL | - IEC958_AES0_CON_NOT_COPYRIGHT | - IEC958_AES0_CON_EMPHASIS; - ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL | - IEC958_AES1_CON_CATEGORY; - ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS; - return 0; -} - -static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO | - IEC958_AES0_PROFESSIONAL | - IEC958_AES0_PRO_FS | - IEC958_AES0_PRO_EMPHASIS; - return 0; -} - -static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = -{ - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK), - .info = snd_vt1724_spdif_info, - .get = snd_vt1724_spdif_maskc_get, -}; - -static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = -{ - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK), - .info = snd_vt1724_spdif_info, - .get = snd_vt1724_spdif_maskp_get, -}; - -#define snd_vt1724_spdif_sw_info snd_ctl_boolean_mono_info - -static int snd_vt1724_spdif_sw_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = inb(ICEREG1724(ice, SPDIF_CFG)) & - VT1724_CFG_SPDIF_OUT_EN ? 1 : 0; - return 0; -} - -static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char old, val; - - spin_lock_irq(&ice->reg_lock); - old = val = inb(ICEREG1724(ice, SPDIF_CFG)); - val &= ~VT1724_CFG_SPDIF_OUT_EN; - if (ucontrol->value.integer.value[0]) - val |= VT1724_CFG_SPDIF_OUT_EN; - if (old != val) - outb(val, ICEREG1724(ice, SPDIF_CFG)); - spin_unlock_irq(&ice->reg_lock); - return old != val; -} - -static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = -{ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* FIXME: the following conflict with IEC958 Playback Route */ - /* .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH), */ - .name = SNDRV_CTL_NAME_IEC958("Output ", NONE, SWITCH), - .info = snd_vt1724_spdif_sw_info, - .get = snd_vt1724_spdif_sw_get, - .put = snd_vt1724_spdif_sw_put -}; - - -#if 0 /* NOT USED YET */ -/* - * GPIO access from extern - */ - -#define snd_vt1724_gpio_info snd_ctl_boolean_mono_info - -int snd_vt1724_gpio_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int shift = kcontrol->private_value & 0xff; - int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0; - - snd_ice1712_save_gpio_status(ice); - ucontrol->value.integer.value[0] = - (snd_ice1712_gpio_read(ice) & (1 << shift) ? 1 : 0) ^ invert; - snd_ice1712_restore_gpio_status(ice); - return 0; -} - -int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int shift = kcontrol->private_value & 0xff; - int invert = (kcontrol->private_value & (1<<24)) ? mask : 0; - unsigned int val, nval; - - if (kcontrol->private_value & (1 << 31)) - return -EPERM; - nval = (ucontrol->value.integer.value[0] ? (1 << shift) : 0) ^ invert; - snd_ice1712_save_gpio_status(ice); - val = snd_ice1712_gpio_read(ice); - nval |= val & ~(1 << shift); - if (val != nval) - snd_ice1712_gpio_write(ice, nval); - snd_ice1712_restore_gpio_status(ice); - return val != nval; -} -#endif /* NOT USED YET */ - -/* - * rate - */ -static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int hw_rates_count = ice->hw_rates->count; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - - /* internal clocks */ - uinfo->value.enumerated.items = hw_rates_count; - /* external clocks */ - if (ice->force_rdma1 || - (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_IN)) - uinfo->value.enumerated.items += ice->ext_clock_count; - /* upper limit - keep at top */ - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - if (uinfo->value.enumerated.item >= hw_rates_count) - /* ext_clock items */ - strcpy(uinfo->value.enumerated.name, - ice->ext_clock_names[ - uinfo->value.enumerated.item - hw_rates_count]); - else - /* int clock items */ - sprintf(uinfo->value.enumerated.name, "%d", - ice->hw_rates->list[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int i, rate; - - spin_lock_irq(&ice->reg_lock); - if (ice->is_spdif_master(ice)) { - ucontrol->value.enumerated.item[0] = ice->hw_rates->count + - ice->get_spdif_master_type(ice); - } else { - rate = ice->get_rate(ice); - ucontrol->value.enumerated.item[0] = 0; - for (i = 0; i < ice->hw_rates->count; i++) { - if (ice->hw_rates->list[i] == rate) { - ucontrol->value.enumerated.item[0] = i; - break; - } - } - } - spin_unlock_irq(&ice->reg_lock); - return 0; -} - -static int stdclock_get_spdif_master_type(struct snd_ice1712 *ice) -{ - /* standard external clock - only single type - SPDIF IN */ - return 0; -} - -/* setting clock to external - SPDIF */ -static int stdclock_set_spdif_clock(struct snd_ice1712 *ice, int type) -{ - unsigned char oval; - unsigned char i2s_oval; - oval = inb(ICEMT1724(ice, RATE)); - outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE)); - /* setting 256fs */ - i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT)); - outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X, ICEMT1724(ice, I2S_FORMAT)); - return 0; -} - - -static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int old_rate, new_rate; - unsigned int item = ucontrol->value.enumerated.item[0]; - unsigned int first_ext_clock = ice->hw_rates->count; - - if (item > first_ext_clock + ice->ext_clock_count - 1) - return -EINVAL; - - /* if rate = 0 => external clock */ - spin_lock_irq(&ice->reg_lock); - if (ice->is_spdif_master(ice)) - old_rate = 0; - else - old_rate = ice->get_rate(ice); - if (item >= first_ext_clock) { - /* switching to external clock */ - ice->set_spdif_clock(ice, item - first_ext_clock); - new_rate = 0; - } else { - /* internal on-card clock */ - new_rate = ice->hw_rates->list[item]; - ice->pro_rate_default = new_rate; - spin_unlock_irq(&ice->reg_lock); - snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1); - spin_lock_irq(&ice->reg_lock); - } - spin_unlock_irq(&ice->reg_lock); - - /* the first switch to the ext. clock mode? */ - if (old_rate != new_rate && !new_rate) { - /* notify akm chips as well */ - unsigned int i; - if (ice->gpio.set_pro_rate) - ice->gpio.set_pro_rate(ice, 0); - for (i = 0; i < ice->akm_codecs; i++) { - if (ice->akm[i].ops.set_rate_val) - ice->akm[i].ops.set_rate_val(&ice->akm[i], 0); - } - } - return old_rate != new_rate; -} - -static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Multi Track Internal Clock", - .info = snd_vt1724_pro_internal_clock_info, - .get = snd_vt1724_pro_internal_clock_get, - .put = snd_vt1724_pro_internal_clock_put -}; - -#define snd_vt1724_pro_rate_locking_info snd_ctl_boolean_mono_info - -static int snd_vt1724_pro_rate_locking_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = PRO_RATE_LOCKED; - return 0; -} - -static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int change = 0, nval; - - nval = ucontrol->value.integer.value[0] ? 1 : 0; - spin_lock_irq(&ice->reg_lock); - change = PRO_RATE_LOCKED != nval; - PRO_RATE_LOCKED = nval; - spin_unlock_irq(&ice->reg_lock); - return change; -} - -static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Multi Track Rate Locking", - .info = snd_vt1724_pro_rate_locking_info, - .get = snd_vt1724_pro_rate_locking_get, - .put = snd_vt1724_pro_rate_locking_put -}; - -#define snd_vt1724_pro_rate_reset_info snd_ctl_boolean_mono_info - -static int snd_vt1724_pro_rate_reset_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = PRO_RATE_RESET ? 1 : 0; - return 0; -} - -static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int change = 0, nval; - - nval = ucontrol->value.integer.value[0] ? 1 : 0; - spin_lock_irq(&ice->reg_lock); - change = PRO_RATE_RESET != nval; - PRO_RATE_RESET = nval; - spin_unlock_irq(&ice->reg_lock); - return change; -} - -static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Multi Track Rate Reset", - .info = snd_vt1724_pro_rate_reset_info, - .get = snd_vt1724_pro_rate_reset_get, - .put = snd_vt1724_pro_rate_reset_put -}; - - -/* - * routing - */ -static int snd_vt1724_pro_route_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *texts[] = { - "PCM Out", /* 0 */ - "H/W In 0", "H/W In 1", /* 1-2 */ - "IEC958 In L", "IEC958 In R", /* 3-4 */ - }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 5; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static inline int analog_route_shift(int idx) -{ - return (idx % 2) * 12 + ((idx / 2) * 3) + 8; -} - -static inline int digital_route_shift(int idx) -{ - return idx * 3; -} - -int snd_ice1724_get_route_val(struct snd_ice1712 *ice, int shift) -{ - unsigned long val; - unsigned char eitem; - static const unsigned char xlate[8] = { - 0, 255, 1, 2, 255, 255, 3, 4, - }; - - val = inl(ICEMT1724(ice, ROUTE_PLAYBACK)); - val >>= shift; - val &= 7; /* we now have 3 bits per output */ - eitem = xlate[val]; - if (eitem == 255) { - snd_BUG(); - return 0; - } - return eitem; -} - -int snd_ice1724_put_route_val(struct snd_ice1712 *ice, unsigned int val, - int shift) -{ - unsigned int old_val, nval; - int change; - static const unsigned char xroute[8] = { - 0, /* PCM */ - 2, /* PSDIN0 Left */ - 3, /* PSDIN0 Right */ - 6, /* SPDIN Left */ - 7, /* SPDIN Right */ - }; - - nval = xroute[val % 5]; - val = old_val = inl(ICEMT1724(ice, ROUTE_PLAYBACK)); - val &= ~(0x07 << shift); - val |= nval << shift; - change = val != old_val; - if (change) - outl(val, ICEMT1724(ice, ROUTE_PLAYBACK)); - return change; -} - -static int snd_vt1724_pro_route_analog_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - ucontrol->value.enumerated.item[0] = - snd_ice1724_get_route_val(ice, analog_route_shift(idx)); - return 0; -} - -static int snd_vt1724_pro_route_analog_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - return snd_ice1724_put_route_val(ice, - ucontrol->value.enumerated.item[0], - analog_route_shift(idx)); -} - -static int snd_vt1724_pro_route_spdif_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - ucontrol->value.enumerated.item[0] = - snd_ice1724_get_route_val(ice, digital_route_shift(idx)); - return 0; -} - -static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - return snd_ice1724_put_route_val(ice, - ucontrol->value.enumerated.item[0], - digital_route_shift(idx)); -} - -static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = -{ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "H/W Playback Route", - .info = snd_vt1724_pro_route_info, - .get = snd_vt1724_pro_route_analog_get, - .put = snd_vt1724_pro_route_analog_put, -}; - -static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route", - .info = snd_vt1724_pro_route_info, - .get = snd_vt1724_pro_route_spdif_get, - .put = snd_vt1724_pro_route_spdif_put, - .count = 2, -}; - - -static int snd_vt1724_pro_peak_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 22; /* FIXME: for compatibility with ice1712... */ - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 255; - return 0; -} - -static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx; - - spin_lock_irq(&ice->reg_lock); - for (idx = 0; idx < 22; idx++) { - outb(idx, ICEMT1724(ice, MONITOR_PEAKINDEX)); - ucontrol->value.integer.value[idx] = - inb(ICEMT1724(ice, MONITOR_PEAKDATA)); - } - spin_unlock_irq(&ice->reg_lock); - return 0; -} - -static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "Multi Track Peak", - .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .info = snd_vt1724_pro_peak_info, - .get = snd_vt1724_pro_peak_get -}; - -/* - * - */ - -static struct snd_ice1712_card_info no_matched __devinitdata; - - -/* - ooAoo cards with no controls -*/ -static unsigned char ooaoo_sq210_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x4c, /* 49MHz crystal, no mpu401, no ADC, - 1xDACs */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0x78, /* no volume, 96k, 24bit, 192k */ - [ICE_EEP2_SPDIF] = 0xc1, /* out-en, out-int, out-ext */ - [ICE_EEP2_GPIO_DIR] = 0x00, /* no GPIOs are used */ - [ICE_EEP2_GPIO_DIR1] = 0x00, - [ICE_EEP2_GPIO_DIR2] = 0x00, - [ICE_EEP2_GPIO_MASK] = 0xff, - [ICE_EEP2_GPIO_MASK1] = 0xff, - [ICE_EEP2_GPIO_MASK2] = 0xff, - - [ICE_EEP2_GPIO_STATE] = 0x00, /* inputs */ - [ICE_EEP2_GPIO_STATE1] = 0x00, /* all 1, but GPIO_CPLD_RW - and GPIO15 always zero */ - [ICE_EEP2_GPIO_STATE2] = 0x00, /* inputs */ -}; - - -struct snd_ice1712_card_info snd_vt1724_ooaoo_cards[] __devinitdata = { - { - .name = "ooAoo SQ210a", - .model = "sq210a", - .eeprom_size = sizeof(ooaoo_sq210_eeprom), - .eeprom_data = ooaoo_sq210_eeprom, - }, - { } /* terminator */ -}; - -static struct snd_ice1712_card_info *card_tables[] __devinitdata = { - snd_vt1724_revo_cards, - snd_vt1724_amp_cards, - snd_vt1724_aureon_cards, - snd_vt1720_mobo_cards, - snd_vt1720_pontis_cards, - snd_vt1724_prodigy_hifi_cards, - snd_vt1724_prodigy192_cards, - snd_vt1724_juli_cards, - snd_vt1724_maya44_cards, - snd_vt1724_phase_cards, - snd_vt1724_wtm_cards, - snd_vt1724_se_cards, - snd_vt1724_qtet_cards, - snd_vt1724_ooaoo_cards, - NULL, -}; - - -/* - */ - -static void wait_i2c_busy(struct snd_ice1712 *ice) -{ - int t = 0x10000; - while ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_BUSY) && t--) - ; - if (t == -1) - printk(KERN_ERR "ice1724: i2c busy timeout\n"); -} - -unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice, - unsigned char dev, unsigned char addr) -{ - unsigned char val; - - mutex_lock(&ice->i2c_mutex); - wait_i2c_busy(ice); - outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR)); - outb(dev & ~VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR)); - wait_i2c_busy(ice); - val = inb(ICEREG1724(ice, I2C_DATA)); - mutex_unlock(&ice->i2c_mutex); - /* - printk(KERN_DEBUG "i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val); - */ - return val; -} - -void snd_vt1724_write_i2c(struct snd_ice1712 *ice, - unsigned char dev, unsigned char addr, unsigned char data) -{ - mutex_lock(&ice->i2c_mutex); - wait_i2c_busy(ice); - /* - printk(KERN_DEBUG "i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data); - */ - outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR)); - outb(data, ICEREG1724(ice, I2C_DATA)); - outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR)); - wait_i2c_busy(ice); - mutex_unlock(&ice->i2c_mutex); -} - -static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, - const char *modelname) -{ - const int dev = 0xa0; /* EEPROM device address */ - unsigned int i, size; - struct snd_ice1712_card_info * const *tbl, *c; - - if (!modelname || !*modelname) { - ice->eeprom.subvendor = 0; - if ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_EEPROM) != 0) - ice->eeprom.subvendor = - (snd_vt1724_read_i2c(ice, dev, 0x00) << 0) | - (snd_vt1724_read_i2c(ice, dev, 0x01) << 8) | - (snd_vt1724_read_i2c(ice, dev, 0x02) << 16) | - (snd_vt1724_read_i2c(ice, dev, 0x03) << 24); - if (ice->eeprom.subvendor == 0 || - ice->eeprom.subvendor == (unsigned int)-1) { - /* invalid subvendor from EEPROM, try the PCI - * subststem ID instead - */ - u16 vendor, device; - pci_read_config_word(ice->pci, PCI_SUBSYSTEM_VENDOR_ID, - &vendor); - pci_read_config_word(ice->pci, PCI_SUBSYSTEM_ID, &device); - ice->eeprom.subvendor = - ((unsigned int)swab16(vendor) << 16) | swab16(device); - if (ice->eeprom.subvendor == 0 || - ice->eeprom.subvendor == (unsigned int)-1) { - printk(KERN_ERR "ice1724: No valid ID is found\n"); - return -ENXIO; - } - } - } - for (tbl = card_tables; *tbl; tbl++) { - for (c = *tbl; c->name; c++) { - if (modelname && c->model && - !strcmp(modelname, c->model)) { - printk(KERN_INFO "ice1724: Using board model %s\n", - c->name); - ice->eeprom.subvendor = c->subvendor; - } else if (c->subvendor != ice->eeprom.subvendor) - continue; - if (!c->eeprom_size || !c->eeprom_data) - goto found; - /* if the EEPROM is given by the driver, use it */ - snd_printdd("using the defined eeprom..\n"); - ice->eeprom.version = 2; - ice->eeprom.size = c->eeprom_size + 6; - memcpy(ice->eeprom.data, c->eeprom_data, c->eeprom_size); - goto read_skipped; - } - } - printk(KERN_WARNING "ice1724: No matching model found for ID 0x%x\n", - ice->eeprom.subvendor); - - found: - ice->eeprom.size = snd_vt1724_read_i2c(ice, dev, 0x04); - if (ice->eeprom.size < 6) - ice->eeprom.size = 32; - else if (ice->eeprom.size > 32) { - printk(KERN_ERR "ice1724: Invalid EEPROM (size = %i)\n", - ice->eeprom.size); - return -EIO; - } - ice->eeprom.version = snd_vt1724_read_i2c(ice, dev, 0x05); - if (ice->eeprom.version != 2) - printk(KERN_WARNING "ice1724: Invalid EEPROM version %i\n", - ice->eeprom.version); - size = ice->eeprom.size - 6; - for (i = 0; i < size; i++) - ice->eeprom.data[i] = snd_vt1724_read_i2c(ice, dev, i + 6); - - read_skipped: - ice->eeprom.gpiomask = eeprom_triple(ice, ICE_EEP2_GPIO_MASK); - ice->eeprom.gpiostate = eeprom_triple(ice, ICE_EEP2_GPIO_STATE); - ice->eeprom.gpiodir = eeprom_triple(ice, ICE_EEP2_GPIO_DIR); - - return 0; -} - - - -static void snd_vt1724_chip_reset(struct snd_ice1712 *ice) -{ - outb(VT1724_RESET , ICEREG1724(ice, CONTROL)); - inb(ICEREG1724(ice, CONTROL)); /* pci posting flush */ - msleep(10); - outb(0, ICEREG1724(ice, CONTROL)); - inb(ICEREG1724(ice, CONTROL)); /* pci posting flush */ - msleep(10); -} - -static int snd_vt1724_chip_init(struct snd_ice1712 *ice) -{ - outb(ice->eeprom.data[ICE_EEP2_SYSCONF], ICEREG1724(ice, SYS_CFG)); - outb(ice->eeprom.data[ICE_EEP2_ACLINK], ICEREG1724(ice, AC97_CFG)); - outb(ice->eeprom.data[ICE_EEP2_I2S], ICEREG1724(ice, I2S_FEATURES)); - outb(ice->eeprom.data[ICE_EEP2_SPDIF], ICEREG1724(ice, SPDIF_CFG)); - - ice->gpio.write_mask = ice->eeprom.gpiomask; - ice->gpio.direction = ice->eeprom.gpiodir; - snd_vt1724_set_gpio_mask(ice, ice->eeprom.gpiomask); - snd_vt1724_set_gpio_dir(ice, ice->eeprom.gpiodir); - snd_vt1724_set_gpio_data(ice, ice->eeprom.gpiostate); - - outb(0, ICEREG1724(ice, POWERDOWN)); - - /* MPU_RX and TX irq masks are cleared later dynamically */ - outb(VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX , ICEREG1724(ice, IRQMASK)); - - /* don't handle FIFO overrun/underruns (just yet), - * since they cause machine lockups - */ - outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK)); - - return 0; -} - -static int __devinit snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice) -{ - int err; - struct snd_kcontrol *kctl; - - if (snd_BUG_ON(!ice->pcm)) - return -EIO; - - if (!ice->own_routing) { - err = snd_ctl_add(ice->card, - snd_ctl_new1(&snd_vt1724_mixer_pro_spdif_route, ice)); - if (err < 0) - return err; - } - - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_spdif_switch, ice)); - if (err < 0) - return err; - - err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_default, ice)); - if (err < 0) - return err; - kctl->id.device = ice->pcm->device; - err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_maskc, ice)); - if (err < 0) - return err; - kctl->id.device = ice->pcm->device; - err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_maskp, ice)); - if (err < 0) - return err; - kctl->id.device = ice->pcm->device; -#if 0 /* use default only */ - err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_stream, ice)); - if (err < 0) - return err; - kctl->id.device = ice->pcm->device; - ice->spdif.stream_ctl = kctl; -#endif - return 0; -} - - -static int __devinit snd_vt1724_build_controls(struct snd_ice1712 *ice) -{ - int err; - - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_eeprom, ice)); - if (err < 0) - return err; - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_internal_clock, ice)); - if (err < 0) - return err; - - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_rate_locking, ice)); - if (err < 0) - return err; - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_rate_reset, ice)); - if (err < 0) - return err; - - if (!ice->own_routing && ice->num_total_dacs > 0) { - struct snd_kcontrol_new tmp = snd_vt1724_mixer_pro_analog_route; - tmp.count = ice->num_total_dacs; - if (ice->vt1720 && tmp.count > 2) - tmp.count = 2; - err = snd_ctl_add(ice->card, snd_ctl_new1(&tmp, ice)); - if (err < 0) - return err; - } - - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_peak, ice)); - if (err < 0) - return err; - - return 0; -} - -static int snd_vt1724_free(struct snd_ice1712 *ice) -{ - if (!ice->port) - goto __hw_end; - /* mask all interrupts */ - outb(0xff, ICEMT1724(ice, DMA_INT_MASK)); - outb(0xff, ICEREG1724(ice, IRQMASK)); - /* --- */ -__hw_end: - if (ice->irq >= 0) - free_irq(ice->irq, ice); - pci_release_regions(ice->pci); - snd_ice1712_akm4xxx_free(ice); - pci_disable_device(ice->pci); - kfree(ice->spec); - kfree(ice); - return 0; -} - -static int snd_vt1724_dev_free(struct snd_device *device) -{ - struct snd_ice1712 *ice = device->device_data; - return snd_vt1724_free(ice); -} - -static int __devinit snd_vt1724_create(struct snd_card *card, - struct pci_dev *pci, - const char *modelname, - struct snd_ice1712 **r_ice1712) -{ - struct snd_ice1712 *ice; - int err; - static struct snd_device_ops ops = { - .dev_free = snd_vt1724_dev_free, - }; - - *r_ice1712 = NULL; - - /* enable PCI device */ - err = pci_enable_device(pci); - if (err < 0) - return err; - - ice = kzalloc(sizeof(*ice), GFP_KERNEL); - if (ice == NULL) { - pci_disable_device(pci); - return -ENOMEM; - } - ice->vt1724 = 1; - spin_lock_init(&ice->reg_lock); - mutex_init(&ice->gpio_mutex); - mutex_init(&ice->open_mutex); - mutex_init(&ice->i2c_mutex); - ice->gpio.set_mask = snd_vt1724_set_gpio_mask; - ice->gpio.get_mask = snd_vt1724_get_gpio_mask; - ice->gpio.set_dir = snd_vt1724_set_gpio_dir; - ice->gpio.get_dir = snd_vt1724_get_gpio_dir; - ice->gpio.set_data = snd_vt1724_set_gpio_data; - ice->gpio.get_data = snd_vt1724_get_gpio_data; - ice->card = card; - ice->pci = pci; - ice->irq = -1; - pci_set_master(pci); - snd_vt1724_proc_init(ice); - synchronize_irq(pci->irq); - - card->private_data = ice; - - err = pci_request_regions(pci, "ICE1724"); - if (err < 0) { - kfree(ice); - pci_disable_device(pci); - return err; - } - ice->port = pci_resource_start(pci, 0); - ice->profi_port = pci_resource_start(pci, 1); - - if (request_irq(pci->irq, snd_vt1724_interrupt, - IRQF_SHARED, KBUILD_MODNAME, ice)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); - snd_vt1724_free(ice); - return -EIO; - } - - ice->irq = pci->irq; - - snd_vt1724_chip_reset(ice); - if (snd_vt1724_read_eeprom(ice, modelname) < 0) { - snd_vt1724_free(ice); - return -EIO; - } - if (snd_vt1724_chip_init(ice) < 0) { - snd_vt1724_free(ice); - return -EIO; - } - - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops); - if (err < 0) { - snd_vt1724_free(ice); - return err; - } - - snd_card_set_dev(card, &pci->dev); - - *r_ice1712 = ice; - return 0; -} - - -/* - * - * Registration - * - */ - -static int __devinit snd_vt1724_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - static int dev; - struct snd_card *card; - struct snd_ice1712 *ice; - int pcm_dev = 0, err; - struct snd_ice1712_card_info * const *tbl, *c; - - if (dev >= SNDRV_CARDS) - return -ENODEV; - if (!enable[dev]) { - dev++; - return -ENOENT; - } - - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; - - strcpy(card->driver, "ICE1724"); - strcpy(card->shortname, "ICEnsemble ICE1724"); - - err = snd_vt1724_create(card, pci, model[dev], &ice); - if (err < 0) { - snd_card_free(card); - return err; - } - - /* field init before calling chip_init */ - ice->ext_clock_count = 0; - - for (tbl = card_tables; *tbl; tbl++) { - for (c = *tbl; c->name; c++) { - if ((model[dev] && c->model && - !strcmp(model[dev], c->model)) || - (c->subvendor == ice->eeprom.subvendor)) { - strcpy(card->shortname, c->name); - if (c->driver) /* specific driver? */ - strcpy(card->driver, c->driver); - if (c->chip_init) { - err = c->chip_init(ice); - if (err < 0) { - snd_card_free(card); - return err; - } - } - goto __found; - } - } - } - c = &no_matched; -__found: - /* - * VT1724 has separate DMAs for the analog and the SPDIF streams while - * ICE1712 has only one for both (mixed up). - * - * Confusingly the analog PCM is named "professional" here because it - * was called so in ice1712 driver, and vt1724 driver is derived from - * ice1712 driver. - */ - ice->pro_rate_default = PRO_RATE_DEFAULT; - if (!ice->is_spdif_master) - ice->is_spdif_master = stdclock_is_spdif_master; - if (!ice->get_rate) - ice->get_rate = stdclock_get_rate; - if (!ice->set_rate) - ice->set_rate = stdclock_set_rate; - if (!ice->set_mclk) - ice->set_mclk = stdclock_set_mclk; - if (!ice->set_spdif_clock) - ice->set_spdif_clock = stdclock_set_spdif_clock; - if (!ice->get_spdif_master_type) - ice->get_spdif_master_type = stdclock_get_spdif_master_type; - if (!ice->ext_clock_names) - ice->ext_clock_names = ext_clock_names; - if (!ice->ext_clock_count) - ice->ext_clock_count = ARRAY_SIZE(ext_clock_names); - - if (!ice->hw_rates) - set_std_hw_rates(ice); - - err = snd_vt1724_pcm_profi(ice, pcm_dev++); - if (err < 0) { - snd_card_free(card); - return err; - } - - err = snd_vt1724_pcm_spdif(ice, pcm_dev++); - if (err < 0) { - snd_card_free(card); - return err; - } - - err = snd_vt1724_pcm_indep(ice, pcm_dev++); - if (err < 0) { - snd_card_free(card); - return err; - } - - err = snd_vt1724_ac97_mixer(ice); - if (err < 0) { - snd_card_free(card); - return err; - } - - err = snd_vt1724_build_controls(ice); - if (err < 0) { - snd_card_free(card); - return err; - } - - if (ice->pcm && ice->has_spdif) { /* has SPDIF I/O */ - err = snd_vt1724_spdif_build_controls(ice); - if (err < 0) { - snd_card_free(card); - return err; - } - } - - if (c->build_controls) { - err = c->build_controls(ice); - if (err < 0) { - snd_card_free(card); - return err; - } - } - - if (!c->no_mpu401) { - if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) { - struct snd_rawmidi *rmidi; - - err = snd_rawmidi_new(card, "MIDI", 0, 1, 1, &rmidi); - if (err < 0) { - snd_card_free(card); - return err; - } - ice->rmidi[0] = rmidi; - rmidi->private_data = ice; - strcpy(rmidi->name, "ICE1724 MIDI"); - rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | - SNDRV_RAWMIDI_INFO_INPUT | - SNDRV_RAWMIDI_INFO_DUPLEX; - snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, - &vt1724_midi_output_ops); - snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, - &vt1724_midi_input_ops); - - /* set watermarks */ - outb(VT1724_MPU_RX_FIFO | 0x1, - ICEREG1724(ice, MPU_FIFO_WM)); - outb(0x1, ICEREG1724(ice, MPU_FIFO_WM)); - /* set UART mode */ - outb(VT1724_MPU_UART, ICEREG1724(ice, MPU_CTRL)); - } - } - - sprintf(card->longname, "%s at 0x%lx, irq %i", - card->shortname, ice->port, ice->irq); - - err = snd_card_register(card); - if (err < 0) { - snd_card_free(card); - return err; - } - pci_set_drvdata(pci, card); - dev++; - return 0; -} - -static void __devexit snd_vt1724_remove(struct pci_dev *pci) -{ - snd_card_free(pci_get_drvdata(pci)); - pci_set_drvdata(pci, NULL); -} - -#ifdef CONFIG_PM -static int snd_vt1724_suspend(struct pci_dev *pci, pm_message_t state) -{ - struct snd_card *card = pci_get_drvdata(pci); - struct snd_ice1712 *ice = card->private_data; - - if (!ice->pm_suspend_enabled) - return 0; - - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - - snd_pcm_suspend_all(ice->pcm); - snd_pcm_suspend_all(ice->pcm_pro); - snd_pcm_suspend_all(ice->pcm_ds); - snd_ac97_suspend(ice->ac97); - - spin_lock_irq(&ice->reg_lock); - ice->pm_saved_is_spdif_master = ice->is_spdif_master(ice); - ice->pm_saved_spdif_ctrl = inw(ICEMT1724(ice, SPDIF_CTRL)); - ice->pm_saved_spdif_cfg = inb(ICEREG1724(ice, SPDIF_CFG)); - ice->pm_saved_route = inl(ICEMT1724(ice, ROUTE_PLAYBACK)); - spin_unlock_irq(&ice->reg_lock); - - if (ice->pm_suspend) - ice->pm_suspend(ice); - - pci_disable_device(pci); - pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); - return 0; -} - -static int snd_vt1724_resume(struct pci_dev *pci) -{ - struct snd_card *card = pci_get_drvdata(pci); - struct snd_ice1712 *ice = card->private_data; - - if (!ice->pm_suspend_enabled) - return 0; - - pci_set_power_state(pci, PCI_D0); - pci_restore_state(pci); - - if (pci_enable_device(pci) < 0) { - snd_card_disconnect(card); - return -EIO; - } - - pci_set_master(pci); - - snd_vt1724_chip_reset(ice); - - if (snd_vt1724_chip_init(ice) < 0) { - snd_card_disconnect(card); - return -EIO; - } - - if (ice->pm_resume) - ice->pm_resume(ice); - - if (ice->pm_saved_is_spdif_master) { - /* switching to external clock via SPDIF */ - ice->set_spdif_clock(ice, 0); - } else { - /* internal on-card clock */ - snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1); - } - - update_spdif_bits(ice, ice->pm_saved_spdif_ctrl); - - outb(ice->pm_saved_spdif_cfg, ICEREG1724(ice, SPDIF_CFG)); - outl(ice->pm_saved_route, ICEMT1724(ice, ROUTE_PLAYBACK)); - - if (ice->ac97) - snd_ac97_resume(ice->ac97); - - snd_power_change_state(card, SNDRV_CTL_POWER_D0); - return 0; -} -#endif - -static struct pci_driver driver = { - .name = KBUILD_MODNAME, - .id_table = snd_vt1724_ids, - .probe = snd_vt1724_probe, - .remove = __devexit_p(snd_vt1724_remove), -#ifdef CONFIG_PM - .suspend = snd_vt1724_suspend, - .resume = snd_vt1724_resume, -#endif -}; - -static int __init alsa_card_ice1724_init(void) -{ - return pci_register_driver(&driver); -} - -static void __exit alsa_card_ice1724_exit(void) -{ - pci_unregister_driver(&driver); -} - -module_init(alsa_card_ice1724_init) -module_exit(alsa_card_ice1724_exit) diff --git a/ANDROID_3.4.5/sound/pci/ice1712/juli.c b/ANDROID_3.4.5/sound/pci/ice1712/juli.c deleted file mode 100644 index 98bc3b76..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/juli.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * ALSA driver for ICEnsemble VT1724 (Envy24HT) - * - * Lowlevel functions for ESI Juli@ cards - * - * Copyright (c) 2004 Jaroslav Kysela - * 2008 Pavel Hofman - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "juli.h" - -struct juli_spec { - struct ak4114 *ak4114; - unsigned int analog:1; -}; - -/* - * chip addresses on I2C bus - */ -#define AK4114_ADDR 0x20 /* S/PDIF receiver */ -#define AK4358_ADDR 0x22 /* DAC */ - -/* - * Juli does not use the standard ICE1724 clock scheme. Juli's ice1724 chip is - * supplied by external clock provided by Xilinx array and MK73-1 PLL frequency - * multiplier. Actual frequency is set by ice1724 GPIOs hooked to the Xilinx. - * - * The clock circuitry is supplied by the two ice1724 crystals. This - * arrangement allows to generate independent clock signal for AK4114's input - * rate detection circuit. As a result, Juli, unlike most other - * ice1724+ak4114-based cards, detects spdif input rate correctly. - * This fact is applied in the driver, allowing to modify PCM stream rate - * parameter according to the actual input rate. - * - * Juli uses the remaining three stereo-channels of its DAC to optionally - * monitor analog input, digital input, and digital output. The corresponding - * I2S signals are routed by Xilinx, controlled by GPIOs. - * - * The master mute is implemented using output muting transistors (GPIO) in - * combination with smuting the DAC. - * - * The card itself has no HW master volume control, implemented using the - * vmaster control. - * - * TODO: - * researching and fixing the input monitors - */ - -/* - * GPIO pins - */ -#define GPIO_FREQ_MASK (3<<0) -#define GPIO_FREQ_32KHZ (0<<0) -#define GPIO_FREQ_44KHZ (1<<0) -#define GPIO_FREQ_48KHZ (2<<0) -#define GPIO_MULTI_MASK (3<<2) -#define GPIO_MULTI_4X (0<<2) -#define GPIO_MULTI_2X (1<<2) -#define GPIO_MULTI_1X (2<<2) /* also external */ -#define GPIO_MULTI_HALF (3<<2) -#define GPIO_INTERNAL_CLOCK (1<<4) /* 0 = external, 1 = internal */ -#define GPIO_CLOCK_MASK (1<<4) -#define GPIO_ANALOG_PRESENT (1<<5) /* RO only: 0 = present */ -#define GPIO_RXMCLK_SEL (1<<7) /* must be 0 */ -#define GPIO_AK5385A_CKS0 (1<<8) -#define GPIO_AK5385A_DFS1 (1<<9) -#define GPIO_AK5385A_DFS0 (1<<10) -#define GPIO_DIGOUT_MONITOR (1<<11) /* 1 = active */ -#define GPIO_DIGIN_MONITOR (1<<12) /* 1 = active */ -#define GPIO_ANAIN_MONITOR (1<<13) /* 1 = active */ -#define GPIO_AK5385A_CKS1 (1<<14) /* must be 0 */ -#define GPIO_MUTE_CONTROL (1<<15) /* output mute, 1 = muted */ - -#define GPIO_RATE_MASK (GPIO_FREQ_MASK | GPIO_MULTI_MASK | \ - GPIO_CLOCK_MASK) -#define GPIO_AK5385A_MASK (GPIO_AK5385A_CKS0 | GPIO_AK5385A_DFS0 | \ - GPIO_AK5385A_DFS1 | GPIO_AK5385A_CKS1) - -#define JULI_PCM_RATE (SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \ - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000) - -#define GPIO_RATE_16000 (GPIO_FREQ_32KHZ | GPIO_MULTI_HALF | \ - GPIO_INTERNAL_CLOCK) -#define GPIO_RATE_22050 (GPIO_FREQ_44KHZ | GPIO_MULTI_HALF | \ - GPIO_INTERNAL_CLOCK) -#define GPIO_RATE_24000 (GPIO_FREQ_48KHZ | GPIO_MULTI_HALF | \ - GPIO_INTERNAL_CLOCK) -#define GPIO_RATE_32000 (GPIO_FREQ_32KHZ | GPIO_MULTI_1X | \ - GPIO_INTERNAL_CLOCK) -#define GPIO_RATE_44100 (GPIO_FREQ_44KHZ | GPIO_MULTI_1X | \ - GPIO_INTERNAL_CLOCK) -#define GPIO_RATE_48000 (GPIO_FREQ_48KHZ | GPIO_MULTI_1X | \ - GPIO_INTERNAL_CLOCK) -#define GPIO_RATE_64000 (GPIO_FREQ_32KHZ | GPIO_MULTI_2X | \ - GPIO_INTERNAL_CLOCK) -#define GPIO_RATE_88200 (GPIO_FREQ_44KHZ | GPIO_MULTI_2X | \ - GPIO_INTERNAL_CLOCK) -#define GPIO_RATE_96000 (GPIO_FREQ_48KHZ | GPIO_MULTI_2X | \ - GPIO_INTERNAL_CLOCK) -#define GPIO_RATE_176400 (GPIO_FREQ_44KHZ | GPIO_MULTI_4X | \ - GPIO_INTERNAL_CLOCK) -#define GPIO_RATE_192000 (GPIO_FREQ_48KHZ | GPIO_MULTI_4X | \ - GPIO_INTERNAL_CLOCK) - -/* - * Initial setup of the conversion array GPIO <-> rate - */ -static unsigned int juli_rates[] = { - 16000, 22050, 24000, 32000, - 44100, 48000, 64000, 88200, - 96000, 176400, 192000, -}; - -static unsigned int gpio_vals[] = { - GPIO_RATE_16000, GPIO_RATE_22050, GPIO_RATE_24000, GPIO_RATE_32000, - GPIO_RATE_44100, GPIO_RATE_48000, GPIO_RATE_64000, GPIO_RATE_88200, - GPIO_RATE_96000, GPIO_RATE_176400, GPIO_RATE_192000, -}; - -static struct snd_pcm_hw_constraint_list juli_rates_info = { - .count = ARRAY_SIZE(juli_rates), - .list = juli_rates, - .mask = 0, -}; - -static int get_gpio_val(int rate) -{ - int i; - for (i = 0; i < ARRAY_SIZE(juli_rates); i++) - if (juli_rates[i] == rate) - return gpio_vals[i]; - return 0; -} - -static void juli_ak4114_write(void *private_data, unsigned char reg, - unsigned char val) -{ - snd_vt1724_write_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR, - reg, val); -} - -static unsigned char juli_ak4114_read(void *private_data, unsigned char reg) -{ - return snd_vt1724_read_i2c((struct snd_ice1712 *)private_data, - AK4114_ADDR, reg); -} - -/* - * If SPDIF capture and slaved to SPDIF-IN, setting runtime rate - * to the external rate - */ -static void juli_spdif_in_open(struct snd_ice1712 *ice, - struct snd_pcm_substream *substream) -{ - struct juli_spec *spec = ice->spec; - struct snd_pcm_runtime *runtime = substream->runtime; - int rate; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || - !ice->is_spdif_master(ice)) - return; - rate = snd_ak4114_external_rate(spec->ak4114); - if (rate >= runtime->hw.rate_min && rate <= runtime->hw.rate_max) { - runtime->hw.rate_min = rate; - runtime->hw.rate_max = rate; - } -} - -/* - * AK4358 section - */ - -static void juli_akm_lock(struct snd_akm4xxx *ak, int chip) -{ -} - -static void juli_akm_unlock(struct snd_akm4xxx *ak, int chip) -{ -} - -static void juli_akm_write(struct snd_akm4xxx *ak, int chip, - unsigned char addr, unsigned char data) -{ - struct snd_ice1712 *ice = ak->private_data[0]; - - if (snd_BUG_ON(chip)) - return; - snd_vt1724_write_i2c(ice, AK4358_ADDR, addr, data); -} - -/* - * change the rate of envy24HT, AK4358, AK5385 - */ -static void juli_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) -{ - unsigned char old, tmp, ak4358_dfs; - unsigned int ak5385_pins, old_gpio, new_gpio; - struct snd_ice1712 *ice = ak->private_data[0]; - struct juli_spec *spec = ice->spec; - - if (rate == 0) /* no hint - S/PDIF input is master or the new spdif - input rate undetected, simply return */ - return; - - /* adjust DFS on codecs */ - if (rate > 96000) { - ak4358_dfs = 2; - ak5385_pins = GPIO_AK5385A_DFS1 | GPIO_AK5385A_CKS0; - } else if (rate > 48000) { - ak4358_dfs = 1; - ak5385_pins = GPIO_AK5385A_DFS0; - } else { - ak4358_dfs = 0; - ak5385_pins = 0; - } - /* AK5385 first, since it requires cold reset affecting both codecs */ - old_gpio = ice->gpio.get_data(ice); - new_gpio = (old_gpio & ~GPIO_AK5385A_MASK) | ak5385_pins; - /* printk(KERN_DEBUG "JULI - ak5385 set_rate_val: new gpio 0x%x\n", - new_gpio); */ - ice->gpio.set_data(ice, new_gpio); - - /* cold reset */ - old = inb(ICEMT1724(ice, AC97_CMD)); - outb(old | VT1724_AC97_COLD, ICEMT1724(ice, AC97_CMD)); - udelay(1); - outb(old & ~VT1724_AC97_COLD, ICEMT1724(ice, AC97_CMD)); - - /* AK4358 */ - /* set new value, reset DFS */ - tmp = snd_akm4xxx_get(ak, 0, 2); - snd_akm4xxx_reset(ak, 1); - tmp = snd_akm4xxx_get(ak, 0, 2); - tmp &= ~(0x03 << 4); - tmp |= ak4358_dfs << 4; - snd_akm4xxx_set(ak, 0, 2, tmp); - snd_akm4xxx_reset(ak, 0); - - /* reinit ak4114 */ - snd_ak4114_reinit(spec->ak4114); -} - -#define AK_DAC(xname, xch) { .name = xname, .num_channels = xch } -#define PCM_VOLUME "PCM Playback Volume" -#define MONITOR_AN_IN_VOLUME "Monitor Analog In Volume" -#define MONITOR_DIG_IN_VOLUME "Monitor Digital In Volume" -#define MONITOR_DIG_OUT_VOLUME "Monitor Digital Out Volume" - -static const struct snd_akm4xxx_dac_channel juli_dac[] = { - AK_DAC(PCM_VOLUME, 2), - AK_DAC(MONITOR_AN_IN_VOLUME, 2), - AK_DAC(MONITOR_DIG_OUT_VOLUME, 2), - AK_DAC(MONITOR_DIG_IN_VOLUME, 2), -}; - - -static struct snd_akm4xxx akm_juli_dac __devinitdata = { - .type = SND_AK4358, - .num_dacs = 8, /* DAC1 - analog out - DAC2 - analog in monitor - DAC3 - digital out monitor - DAC4 - digital in monitor - */ - .ops = { - .lock = juli_akm_lock, - .unlock = juli_akm_unlock, - .write = juli_akm_write, - .set_rate_val = juli_akm_set_rate_val - }, - .dac_info = juli_dac, -}; - -#define juli_mute_info snd_ctl_boolean_mono_info - -static int juli_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int val; - val = ice->gpio.get_data(ice) & (unsigned int) kcontrol->private_value; - if (kcontrol->private_value == GPIO_MUTE_CONTROL) - /* val 0 = signal on */ - ucontrol->value.integer.value[0] = (val) ? 0 : 1; - else - /* val 1 = signal on */ - ucontrol->value.integer.value[0] = (val) ? 1 : 0; - return 0; -} - -static int juli_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int old_gpio, new_gpio; - old_gpio = ice->gpio.get_data(ice); - if (ucontrol->value.integer.value[0]) { - /* unmute */ - if (kcontrol->private_value == GPIO_MUTE_CONTROL) { - /* 0 = signal on */ - new_gpio = old_gpio & ~GPIO_MUTE_CONTROL; - /* un-smuting DAC */ - snd_akm4xxx_write(ice->akm, 0, 0x01, 0x01); - } else - /* 1 = signal on */ - new_gpio = old_gpio | - (unsigned int) kcontrol->private_value; - } else { - /* mute */ - if (kcontrol->private_value == GPIO_MUTE_CONTROL) { - /* 1 = signal off */ - new_gpio = old_gpio | GPIO_MUTE_CONTROL; - /* smuting DAC */ - snd_akm4xxx_write(ice->akm, 0, 0x01, 0x03); - } else - /* 0 = signal off */ - new_gpio = old_gpio & - ~((unsigned int) kcontrol->private_value); - } - /* printk(KERN_DEBUG - "JULI - mute/unmute: control_value: 0x%x, old_gpio: 0x%x, " - "new_gpio 0x%x\n", - (unsigned int)ucontrol->value.integer.value[0], old_gpio, - new_gpio); */ - if (old_gpio != new_gpio) { - ice->gpio.set_data(ice, new_gpio); - return 1; - } - /* no change */ - return 0; -} - -static struct snd_kcontrol_new juli_mute_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = juli_mute_info, - .get = juli_mute_get, - .put = juli_mute_put, - .private_value = GPIO_MUTE_CONTROL, - }, - /* Although the following functionality respects the succint NDA'd - * documentation from the card manufacturer, and the same way of - * operation is coded in OSS Juli driver, only Digital Out monitor - * seems to work. Surprisingly, Analog input monitor outputs Digital - * output data. The two are independent, as enabling both doubles - * volume of the monitor sound. - * - * Checking traces on the board suggests the functionality described - * by the manufacturer is correct - I2S from ADC and AK4114 - * go to ICE as well as to Xilinx, I2S inputs of DAC2,3,4 (the monitor - * inputs) are fed from Xilinx. - * - * I even checked traces on board and coded a support in driver for - * an alternative possibility - the unused I2S ICE output channels - * switched to HW-IN/SPDIF-IN and providing the monitoring signal to - * the DAC - to no avail. The I2S outputs seem to be unconnected. - * - * The windows driver supports the monitoring correctly. - */ - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Monitor Analog In Switch", - .info = juli_mute_info, - .get = juli_mute_get, - .put = juli_mute_put, - .private_value = GPIO_ANAIN_MONITOR, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Monitor Digital Out Switch", - .info = juli_mute_info, - .get = juli_mute_get, - .put = juli_mute_put, - .private_value = GPIO_DIGOUT_MONITOR, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Monitor Digital In Switch", - .info = juli_mute_info, - .get = juli_mute_get, - .put = juli_mute_put, - .private_value = GPIO_DIGIN_MONITOR, - }, -}; - -static char *slave_vols[] __devinitdata = { - PCM_VOLUME, - MONITOR_AN_IN_VOLUME, - MONITOR_DIG_IN_VOLUME, - MONITOR_DIG_OUT_VOLUME, - NULL -}; - -static __devinitdata -DECLARE_TLV_DB_SCALE(juli_master_db_scale, -6350, 50, 1); - -static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card, - const char *name) -{ - struct snd_ctl_elem_id sid; - memset(&sid, 0, sizeof(sid)); - /* FIXME: strcpy is bad. */ - strcpy(sid.name, name); - sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - return snd_ctl_find_id(card, &sid); -} - -static void __devinit add_slaves(struct snd_card *card, - struct snd_kcontrol *master, char **list) -{ - for (; *list; list++) { - struct snd_kcontrol *slave = ctl_find(card, *list); - /* printk(KERN_DEBUG "add_slaves - %s\n", *list); */ - if (slave) { - /* printk(KERN_DEBUG "slave %s found\n", *list); */ - snd_ctl_add_slave(master, slave); - } - } -} - -static int __devinit juli_add_controls(struct snd_ice1712 *ice) -{ - struct juli_spec *spec = ice->spec; - int err; - unsigned int i; - struct snd_kcontrol *vmaster; - - err = snd_ice1712_akm4xxx_build_controls(ice); - if (err < 0) - return err; - - for (i = 0; i < ARRAY_SIZE(juli_mute_controls); i++) { - err = snd_ctl_add(ice->card, - snd_ctl_new1(&juli_mute_controls[i], ice)); - if (err < 0) - return err; - } - /* Create virtual master control */ - vmaster = snd_ctl_make_virtual_master("Master Playback Volume", - juli_master_db_scale); - if (!vmaster) - return -ENOMEM; - add_slaves(ice->card, vmaster, slave_vols); - err = snd_ctl_add(ice->card, vmaster); - if (err < 0) - return err; - - /* only capture SPDIF over AK4114 */ - err = snd_ak4114_build(spec->ak4114, NULL, - ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); - if (err < 0) - return err; - return 0; -} - -/* - * suspend/resume - * */ - -#ifdef CONFIG_PM -static int juli_resume(struct snd_ice1712 *ice) -{ - struct snd_akm4xxx *ak = ice->akm; - struct juli_spec *spec = ice->spec; - /* akm4358 un-reset, un-mute */ - snd_akm4xxx_reset(ak, 0); - /* reinit ak4114 */ - snd_ak4114_reinit(spec->ak4114); - return 0; -} - -static int juli_suspend(struct snd_ice1712 *ice) -{ - struct snd_akm4xxx *ak = ice->akm; - /* akm4358 reset and soft-mute */ - snd_akm4xxx_reset(ak, 1); - return 0; -} -#endif - -/* - * initialize the chip - */ - -static inline int juli_is_spdif_master(struct snd_ice1712 *ice) -{ - return (ice->gpio.get_data(ice) & GPIO_INTERNAL_CLOCK) ? 0 : 1; -} - -static unsigned int juli_get_rate(struct snd_ice1712 *ice) -{ - int i; - unsigned char result; - - result = ice->gpio.get_data(ice) & GPIO_RATE_MASK; - for (i = 0; i < ARRAY_SIZE(gpio_vals); i++) - if (gpio_vals[i] == result) - return juli_rates[i]; - return 0; -} - -/* setting new rate */ -static void juli_set_rate(struct snd_ice1712 *ice, unsigned int rate) -{ - unsigned int old, new; - unsigned char val; - - old = ice->gpio.get_data(ice); - new = (old & ~GPIO_RATE_MASK) | get_gpio_val(rate); - /* printk(KERN_DEBUG "JULI - set_rate: old %x, new %x\n", - old & GPIO_RATE_MASK, - new & GPIO_RATE_MASK); */ - - ice->gpio.set_data(ice, new); - /* switching to external clock - supplied by external circuits */ - val = inb(ICEMT1724(ice, RATE)); - outb(val | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE)); -} - -static inline unsigned char juli_set_mclk(struct snd_ice1712 *ice, - unsigned int rate) -{ - /* no change in master clock */ - return 0; -} - -/* setting clock to external - SPDIF */ -static int juli_set_spdif_clock(struct snd_ice1712 *ice, int type) -{ - unsigned int old; - old = ice->gpio.get_data(ice); - /* external clock (= 0), multiply 1x, 48kHz */ - ice->gpio.set_data(ice, (old & ~GPIO_RATE_MASK) | GPIO_MULTI_1X | - GPIO_FREQ_48KHZ); - return 0; -} - -/* Called when ak4114 detects change in the input SPDIF stream */ -static void juli_ak4114_change(struct ak4114 *ak4114, unsigned char c0, - unsigned char c1) -{ - struct snd_ice1712 *ice = ak4114->change_callback_private; - int rate; - if (ice->is_spdif_master(ice) && c1) { - /* only for SPDIF master mode, rate was changed */ - rate = snd_ak4114_external_rate(ak4114); - /* printk(KERN_DEBUG "ak4114 - input rate changed to %d\n", - rate); */ - juli_akm_set_rate_val(ice->akm, rate); - } -} - -static int __devinit juli_init(struct snd_ice1712 *ice) -{ - static const unsigned char ak4114_init_vals[] = { - /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN | - AK4114_OCKS0 | AK4114_OCKS1, - /* AK4114_REQ_FORMAT */ AK4114_DIF_I24I2S, - /* AK4114_REG_IO0 */ AK4114_TX1E, - /* AK4114_REG_IO1 */ AK4114_EFH_1024 | AK4114_DIT | - AK4114_IPS(1), - /* AK4114_REG_INT0_MASK */ 0, - /* AK4114_REG_INT1_MASK */ 0 - }; - static const unsigned char ak4114_init_txcsb[] = { - 0x41, 0x02, 0x2c, 0x00, 0x00 - }; - int err; - struct juli_spec *spec; - struct snd_akm4xxx *ak; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - ice->spec = spec; - - err = snd_ak4114_create(ice->card, - juli_ak4114_read, - juli_ak4114_write, - ak4114_init_vals, ak4114_init_txcsb, - ice, &spec->ak4114); - if (err < 0) - return err; - /* callback for codecs rate setting */ - spec->ak4114->change_callback = juli_ak4114_change; - spec->ak4114->change_callback_private = ice; - /* AK4114 in Juli can detect external rate correctly */ - spec->ak4114->check_flags = 0; - -#if 0 -/* - * it seems that the analog doughter board detection does not work reliably, so - * force the analog flag; it should be very rare (if ever) to come at Juli@ - * used without the analog daughter board - */ - spec->analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1; -#else - spec->analog = 1; -#endif - - if (spec->analog) { - printk(KERN_INFO "juli@: analog I/O detected\n"); - ice->num_total_dacs = 2; - ice->num_total_adcs = 2; - - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - ak = ice->akm; - if (!ak) - return -ENOMEM; - ice->akm_codecs = 1; - err = snd_ice1712_akm4xxx_init(ak, &akm_juli_dac, NULL, ice); - if (err < 0) - return err; - } - - /* juli is clocked by Xilinx array */ - ice->hw_rates = &juli_rates_info; - ice->is_spdif_master = juli_is_spdif_master; - ice->get_rate = juli_get_rate; - ice->set_rate = juli_set_rate; - ice->set_mclk = juli_set_mclk; - ice->set_spdif_clock = juli_set_spdif_clock; - - ice->spdif.ops.open = juli_spdif_in_open; - -#ifdef CONFIG_PM - ice->pm_resume = juli_resume; - ice->pm_suspend = juli_suspend; - ice->pm_suspend_enabled = 1; -#endif - - return 0; -} - - -/* - * Juli@ boards don't provide the EEPROM data except for the vendor IDs. - * hence the driver needs to sets up it properly. - */ - -static unsigned char juli_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, 1xADC, 1xDACs, - SPDIF in */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0x9f, /* 5, 6:inputs; 7, 4-0 outputs*/ - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x7f, - [ICE_EEP2_GPIO_MASK] = 0x60, /* 5, 6: locked; 7, 4-0 writable */ - [ICE_EEP2_GPIO_MASK1] = 0x00, /* 0-7 writable */ - [ICE_EEP2_GPIO_MASK2] = 0x7f, - [ICE_EEP2_GPIO_STATE] = GPIO_FREQ_48KHZ | GPIO_MULTI_1X | - GPIO_INTERNAL_CLOCK, /* internal clock, multiple 1x, 48kHz*/ - [ICE_EEP2_GPIO_STATE1] = 0x00, /* unmuted */ - [ICE_EEP2_GPIO_STATE2] = 0x00, -}; - -/* entry point */ -struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_JULI, - .name = "ESI Juli@", - .model = "juli", - .chip_init = juli_init, - .build_controls = juli_add_controls, - .eeprom_size = sizeof(juli_eeprom), - .eeprom_data = juli_eeprom, - }, - { } /* terminator */ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/juli.h b/ANDROID_3.4.5/sound/pci/ice1712/juli.h deleted file mode 100644 index d9f8534f..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/juli.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __SOUND_JULI_H -#define __SOUND_JULI_H - -#define JULI_DEVICE_DESC "{ESI,Juli@}," - -#define VT1724_SUBDEVICE_JULI 0x31305345 /* Juli@ */ - -extern struct snd_ice1712_card_info snd_vt1724_juli_cards[]; - -#endif /* __SOUND_JULI_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/maya44.c b/ANDROID_3.4.5/sound/pci/ice1712/maya44.c deleted file mode 100644 index 726fd4b9..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/maya44.c +++ /dev/null @@ -1,779 +0,0 @@ -/* - * ALSA driver for ICEnsemble VT1724 (Envy24HT) - * - * Lowlevel functions for ESI Maya44 cards - * - * Copyright (c) 2009 Takashi Iwai - * Based on the patches by Rainer Zimmermann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "maya44.h" - -/* WM8776 register indexes */ -#define WM8776_REG_HEADPHONE_L 0x00 -#define WM8776_REG_HEADPHONE_R 0x01 -#define WM8776_REG_HEADPHONE_MASTER 0x02 -#define WM8776_REG_DAC_ATTEN_L 0x03 -#define WM8776_REG_DAC_ATTEN_R 0x04 -#define WM8776_REG_DAC_ATTEN_MASTER 0x05 -#define WM8776_REG_DAC_PHASE 0x06 -#define WM8776_REG_DAC_CONTROL 0x07 -#define WM8776_REG_DAC_MUTE 0x08 -#define WM8776_REG_DAC_DEEMPH 0x09 -#define WM8776_REG_DAC_IF_CONTROL 0x0a -#define WM8776_REG_ADC_IF_CONTROL 0x0b -#define WM8776_REG_MASTER_MODE_CONTROL 0x0c -#define WM8776_REG_POWERDOWN 0x0d -#define WM8776_REG_ADC_ATTEN_L 0x0e -#define WM8776_REG_ADC_ATTEN_R 0x0f -#define WM8776_REG_ADC_ALC1 0x10 -#define WM8776_REG_ADC_ALC2 0x11 -#define WM8776_REG_ADC_ALC3 0x12 -#define WM8776_REG_ADC_NOISE_GATE 0x13 -#define WM8776_REG_ADC_LIMITER 0x14 -#define WM8776_REG_ADC_MUX 0x15 -#define WM8776_REG_OUTPUT_MUX 0x16 -#define WM8776_REG_RESET 0x17 - -#define WM8776_NUM_REGS 0x18 - -/* clock ratio identifiers for snd_wm8776_set_rate() */ -#define WM8776_CLOCK_RATIO_128FS 0 -#define WM8776_CLOCK_RATIO_192FS 1 -#define WM8776_CLOCK_RATIO_256FS 2 -#define WM8776_CLOCK_RATIO_384FS 3 -#define WM8776_CLOCK_RATIO_512FS 4 -#define WM8776_CLOCK_RATIO_768FS 5 - -enum { WM_VOL_HP, WM_VOL_DAC, WM_VOL_ADC, WM_NUM_VOLS }; -enum { WM_SW_DAC, WM_SW_BYPASS, WM_NUM_SWITCHES }; - -struct snd_wm8776 { - unsigned char addr; - unsigned short regs[WM8776_NUM_REGS]; - unsigned char volumes[WM_NUM_VOLS][2]; - unsigned int switch_bits; -}; - -struct snd_maya44 { - struct snd_ice1712 *ice; - struct snd_wm8776 wm[2]; - struct mutex mutex; -}; - - -/* write the given register and save the data to the cache */ -static void wm8776_write(struct snd_ice1712 *ice, struct snd_wm8776 *wm, - unsigned char reg, unsigned short val) -{ - /* - * WM8776 registers are up to 9 bits wide, bit 8 is placed in the LSB - * of the address field - */ - snd_vt1724_write_i2c(ice, wm->addr, - (reg << 1) | ((val >> 8) & 1), - val & 0xff); - wm->regs[reg] = val; -} - -/* - * update the given register with and/or mask and save the data to the cache - */ -static int wm8776_write_bits(struct snd_ice1712 *ice, struct snd_wm8776 *wm, - unsigned char reg, - unsigned short mask, unsigned short val) -{ - val |= wm->regs[reg] & ~mask; - if (val != wm->regs[reg]) { - wm8776_write(ice, wm, reg, val); - return 1; - } - return 0; -} - - -/* - * WM8776 volume controls - */ - -struct maya_vol_info { - unsigned int maxval; /* volume range: 0..maxval */ - unsigned char regs[2]; /* left and right registers */ - unsigned short mask; /* value mask */ - unsigned short offset; /* zero-value offset */ - unsigned short mute; /* mute bit */ - unsigned short update; /* update bits */ - unsigned char mux_bits[2]; /* extra bits for ADC mute */ -}; - -static struct maya_vol_info vol_info[WM_NUM_VOLS] = { - [WM_VOL_HP] = { - .maxval = 80, - .regs = { WM8776_REG_HEADPHONE_L, WM8776_REG_HEADPHONE_R }, - .mask = 0x7f, - .offset = 0x30, - .mute = 0x00, - .update = 0x180, /* update and zero-cross enable */ - }, - [WM_VOL_DAC] = { - .maxval = 255, - .regs = { WM8776_REG_DAC_ATTEN_L, WM8776_REG_DAC_ATTEN_R }, - .mask = 0xff, - .offset = 0x01, - .mute = 0x00, - .update = 0x100, /* zero-cross enable */ - }, - [WM_VOL_ADC] = { - .maxval = 91, - .regs = { WM8776_REG_ADC_ATTEN_L, WM8776_REG_ADC_ATTEN_R }, - .mask = 0xff, - .offset = 0xa5, - .mute = 0xa5, - .update = 0x100, /* update */ - .mux_bits = { 0x80, 0x40 }, /* ADCMUX bits */ - }, -}; - -/* - * dB tables - */ -/* headphone output: mute, -73..+6db (1db step) */ -static const DECLARE_TLV_DB_SCALE(db_scale_hp, -7400, 100, 1); -/* DAC output: mute, -127..0db (0.5db step) */ -static const DECLARE_TLV_DB_SCALE(db_scale_dac, -12750, 50, 1); -/* ADC gain: mute, -21..+24db (0.5db step) */ -static const DECLARE_TLV_DB_SCALE(db_scale_adc, -2100, 50, 1); - -static int maya_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - unsigned int idx = kcontrol->private_value; - struct maya_vol_info *vol = &vol_info[idx]; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = vol->maxval; - return 0; -} - -static int maya_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol); - struct snd_wm8776 *wm = - &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)]; - unsigned int idx = kcontrol->private_value; - - mutex_lock(&chip->mutex); - ucontrol->value.integer.value[0] = wm->volumes[idx][0]; - ucontrol->value.integer.value[1] = wm->volumes[idx][1]; - mutex_unlock(&chip->mutex); - return 0; -} - -static int maya_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol); - struct snd_wm8776 *wm = - &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)]; - unsigned int idx = kcontrol->private_value; - struct maya_vol_info *vol = &vol_info[idx]; - unsigned int val, data; - int ch, changed = 0; - - mutex_lock(&chip->mutex); - for (ch = 0; ch < 2; ch++) { - val = ucontrol->value.integer.value[ch]; - if (val > vol->maxval) - val = vol->maxval; - if (val == wm->volumes[idx][ch]) - continue; - if (!val) - data = vol->mute; - else - data = (val - 1) + vol->offset; - data |= vol->update; - changed |= wm8776_write_bits(chip->ice, wm, vol->regs[ch], - vol->mask | vol->update, data); - if (vol->mux_bits[ch]) - wm8776_write_bits(chip->ice, wm, WM8776_REG_ADC_MUX, - vol->mux_bits[ch], - val ? 0 : vol->mux_bits[ch]); - wm->volumes[idx][ch] = val; - } - mutex_unlock(&chip->mutex); - return changed; -} - -/* - * WM8776 switch controls - */ - -#define COMPOSE_SW_VAL(idx, reg, mask) ((idx) | ((reg) << 8) | ((mask) << 16)) -#define GET_SW_VAL_IDX(val) ((val) & 0xff) -#define GET_SW_VAL_REG(val) (((val) >> 8) & 0xff) -#define GET_SW_VAL_MASK(val) (((val) >> 16) & 0xff) - -#define maya_sw_info snd_ctl_boolean_mono_info - -static int maya_sw_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol); - struct snd_wm8776 *wm = - &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)]; - unsigned int idx = GET_SW_VAL_IDX(kcontrol->private_value); - - ucontrol->value.integer.value[0] = (wm->switch_bits >> idx) & 1; - return 0; -} - -static int maya_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol); - struct snd_wm8776 *wm = - &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)]; - unsigned int idx = GET_SW_VAL_IDX(kcontrol->private_value); - unsigned int mask, val; - int changed; - - mutex_lock(&chip->mutex); - mask = 1 << idx; - wm->switch_bits &= ~mask; - val = ucontrol->value.integer.value[0]; - if (val) - wm->switch_bits |= mask; - mask = GET_SW_VAL_MASK(kcontrol->private_value); - changed = wm8776_write_bits(chip->ice, wm, - GET_SW_VAL_REG(kcontrol->private_value), - mask, val ? mask : 0); - mutex_unlock(&chip->mutex); - return changed; -} - -/* - * GPIO pins (known ones for maya44) - */ -#define GPIO_PHANTOM_OFF 2 -#define GPIO_MIC_RELAY 4 -#define GPIO_SPDIF_IN_INV 5 -#define GPIO_MUST_BE_0 7 - -/* - * GPIO switch controls - */ - -#define COMPOSE_GPIO_VAL(shift, inv) ((shift) | ((inv) << 8)) -#define GET_GPIO_VAL_SHIFT(val) ((val) & 0xff) -#define GET_GPIO_VAL_INV(val) (((val) >> 8) & 1) - -static int maya_set_gpio_bits(struct snd_ice1712 *ice, unsigned int mask, - unsigned int bits) -{ - unsigned int data; - data = snd_ice1712_gpio_read(ice); - if ((data & mask) == bits) - return 0; - snd_ice1712_gpio_write(ice, (data & ~mask) | bits); - return 1; -} - -#define maya_gpio_sw_info snd_ctl_boolean_mono_info - -static int maya_gpio_sw_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol); - unsigned int shift = GET_GPIO_VAL_SHIFT(kcontrol->private_value); - unsigned int val; - - val = (snd_ice1712_gpio_read(chip->ice) >> shift) & 1; - if (GET_GPIO_VAL_INV(kcontrol->private_value)) - val = !val; - ucontrol->value.integer.value[0] = val; - return 0; -} - -static int maya_gpio_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol); - unsigned int shift = GET_GPIO_VAL_SHIFT(kcontrol->private_value); - unsigned int val, mask; - int changed; - - mutex_lock(&chip->mutex); - mask = 1 << shift; - val = ucontrol->value.integer.value[0]; - if (GET_GPIO_VAL_INV(kcontrol->private_value)) - val = !val; - val = val ? mask : 0; - changed = maya_set_gpio_bits(chip->ice, mask, val); - mutex_unlock(&chip->mutex); - return changed; -} - -/* - * capture source selection - */ - -/* known working input slots (0-4) */ -#define MAYA_LINE_IN 1 /* in-2 */ -#define MAYA_MIC_IN 3 /* in-4 */ - -static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line) -{ - wm8776_write_bits(chip->ice, &chip->wm[idx], WM8776_REG_ADC_MUX, - 0x1f, 1 << line); -} - -static int maya_rec_src_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *texts[] = { "Line", "Mic" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = ARRAY_SIZE(texts); - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; -} - -static int maya_rec_src_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol); - int sel; - - if (snd_ice1712_gpio_read(chip->ice) & (1 << GPIO_MIC_RELAY)) - sel = 1; - else - sel = 0; - ucontrol->value.enumerated.item[0] = sel; - return 0; -} - -static int maya_rec_src_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol); - int sel = ucontrol->value.enumerated.item[0]; - int changed; - - mutex_lock(&chip->mutex); - changed = maya_set_gpio_bits(chip->ice, 1 << GPIO_MIC_RELAY, - sel ? (1 << GPIO_MIC_RELAY) : 0); - wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN); - mutex_unlock(&chip->mutex); - return changed; -} - -/* - * Maya44 routing switch settings have different meanings than the standard - * ice1724 switches as defined in snd_vt1724_pro_route_info (ice1724.c). - */ -static int maya_pb_route_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *texts[] = { - "PCM Out", /* 0 */ - "Input 1", "Input 2", "Input 3", "Input 4" - }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = ARRAY_SIZE(texts); - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; -} - -static int maya_pb_route_shift(int idx) -{ - static const unsigned char shift[10] = - { 8, 20, 0, 3, 11, 23, 14, 26, 17, 29 }; - return shift[idx % 10]; -} - -static int maya_pb_route_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol); - int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - ucontrol->value.enumerated.item[0] = - snd_ice1724_get_route_val(chip->ice, maya_pb_route_shift(idx)); - return 0; -} - -static int maya_pb_route_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol); - int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - return snd_ice1724_put_route_val(chip->ice, - ucontrol->value.enumerated.item[0], - maya_pb_route_shift(idx)); -} - - -/* - * controls to be added - */ - -static struct snd_kcontrol_new maya_controls[] __devinitdata = { - { - .name = "Crossmix Playback Volume", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .info = maya_vol_info, - .get = maya_vol_get, - .put = maya_vol_put, - .tlv = { .p = db_scale_hp }, - .private_value = WM_VOL_HP, - .count = 2, - }, - { - .name = "PCM Playback Volume", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .info = maya_vol_info, - .get = maya_vol_get, - .put = maya_vol_put, - .tlv = { .p = db_scale_dac }, - .private_value = WM_VOL_DAC, - .count = 2, - }, - { - .name = "Line Capture Volume", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .info = maya_vol_info, - .get = maya_vol_get, - .put = maya_vol_put, - .tlv = { .p = db_scale_adc }, - .private_value = WM_VOL_ADC, - .count = 2, - }, - { - .name = "PCM Playback Switch", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = maya_sw_info, - .get = maya_sw_get, - .put = maya_sw_put, - .private_value = COMPOSE_SW_VAL(WM_SW_DAC, - WM8776_REG_OUTPUT_MUX, 0x01), - .count = 2, - }, - { - .name = "Bypass Playback Switch", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = maya_sw_info, - .get = maya_sw_get, - .put = maya_sw_put, - .private_value = COMPOSE_SW_VAL(WM_SW_BYPASS, - WM8776_REG_OUTPUT_MUX, 0x04), - .count = 2, - }, - { - .name = "Capture Source", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = maya_rec_src_info, - .get = maya_rec_src_get, - .put = maya_rec_src_put, - }, - { - .name = "Mic Phantom Power Switch", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = maya_gpio_sw_info, - .get = maya_gpio_sw_get, - .put = maya_gpio_sw_put, - .private_value = COMPOSE_GPIO_VAL(GPIO_PHANTOM_OFF, 1), - }, - { - .name = "SPDIF Capture Switch", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = maya_gpio_sw_info, - .get = maya_gpio_sw_get, - .put = maya_gpio_sw_put, - .private_value = COMPOSE_GPIO_VAL(GPIO_SPDIF_IN_INV, 1), - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "H/W Playback Route", - .info = maya_pb_route_info, - .get = maya_pb_route_get, - .put = maya_pb_route_put, - .count = 4, /* FIXME: do controls 5-9 have any meaning? */ - }, -}; - -static int __devinit maya44_add_controls(struct snd_ice1712 *ice) -{ - int err, i; - - for (i = 0; i < ARRAY_SIZE(maya_controls); i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&maya_controls[i], - ice->spec)); - if (err < 0) - return err; - } - return 0; -} - - -/* - * initialize a wm8776 chip - */ -static void __devinit wm8776_init(struct snd_ice1712 *ice, - struct snd_wm8776 *wm, unsigned int addr) -{ - static const unsigned short inits_wm8776[] = { - 0x02, 0x100, /* R2: headphone L+R muted + update */ - 0x05, 0x100, /* R5: DAC output L+R muted + update */ - 0x06, 0x000, /* R6: DAC output phase normal */ - 0x07, 0x091, /* R7: DAC enable zero cross detection, - normal output */ - 0x08, 0x000, /* R8: DAC soft mute off */ - 0x09, 0x000, /* R9: no deemph, DAC zero detect disabled */ - 0x0a, 0x022, /* R10: DAC I2C mode, std polarities, 24bit */ - 0x0b, 0x022, /* R11: ADC I2C mode, std polarities, 24bit, - highpass filter enabled */ - 0x0c, 0x042, /* R12: ADC+DAC slave, ADC+DAC 44,1kHz */ - 0x0d, 0x000, /* R13: all power up */ - 0x0e, 0x100, /* R14: ADC left muted, - enable zero cross detection */ - 0x0f, 0x100, /* R15: ADC right muted, - enable zero cross detection */ - /* R16: ALC...*/ - 0x11, 0x000, /* R17: disable ALC */ - /* R18: ALC...*/ - /* R19: noise gate...*/ - 0x15, 0x000, /* R21: ADC input mux init, mute all inputs */ - 0x16, 0x001, /* R22: output mux, select DAC */ - 0xff, 0xff - }; - - const unsigned short *ptr; - unsigned char reg; - unsigned short data; - - wm->addr = addr; - /* enable DAC output; mute bypass, aux & all inputs */ - wm->switch_bits = (1 << WM_SW_DAC); - - ptr = inits_wm8776; - while (*ptr != 0xff) { - reg = *ptr++; - data = *ptr++; - wm8776_write(ice, wm, reg, data); - } -} - - -/* - * change the rate on the WM8776 codecs. - * this assumes that the VT17xx's rate is changed by the calling function. - * NOTE: even though the WM8776's are running in slave mode and rate - * selection is automatic, we need to call snd_wm8776_set_rate() here - * to make sure some flags are set correctly. - */ -static void set_rate(struct snd_ice1712 *ice, unsigned int rate) -{ - struct snd_maya44 *chip = ice->spec; - unsigned int ratio, adc_ratio, val; - int i; - - switch (rate) { - case 192000: - ratio = WM8776_CLOCK_RATIO_128FS; - break; - case 176400: - ratio = WM8776_CLOCK_RATIO_128FS; - break; - case 96000: - ratio = WM8776_CLOCK_RATIO_256FS; - break; - case 88200: - ratio = WM8776_CLOCK_RATIO_384FS; - break; - case 48000: - ratio = WM8776_CLOCK_RATIO_512FS; - break; - case 44100: - ratio = WM8776_CLOCK_RATIO_512FS; - break; - case 32000: - ratio = WM8776_CLOCK_RATIO_768FS; - break; - case 0: - /* no hint - S/PDIF input is master, simply return */ - return; - default: - snd_BUG(); - return; - } - - /* - * this currently sets the same rate for ADC and DAC, but limits - * ADC rate to 256X (96kHz). For 256X mode (96kHz), this sets ADC - * oversampling to 64x, as recommended by WM8776 datasheet. - * Setting the rate is not really necessary in slave mode. - */ - adc_ratio = ratio; - if (adc_ratio < WM8776_CLOCK_RATIO_256FS) - adc_ratio = WM8776_CLOCK_RATIO_256FS; - - val = adc_ratio; - if (adc_ratio == WM8776_CLOCK_RATIO_256FS) - val |= 8; - val |= ratio << 4; - - mutex_lock(&chip->mutex); - for (i = 0; i < 2; i++) - wm8776_write_bits(ice, &chip->wm[i], - WM8776_REG_MASTER_MODE_CONTROL, - 0x180, val); - mutex_unlock(&chip->mutex); -} - -/* - * supported sample rates (to override the default one) - */ - -static unsigned int rates[] = { - 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000 -}; - -/* playback rates: 32..192 kHz */ -static struct snd_pcm_hw_constraint_list dac_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0 -}; - - -/* - * chip addresses on I2C bus - */ -static unsigned char wm8776_addr[2] __devinitdata = { - 0x34, 0x36, /* codec 0 & 1 */ -}; - -/* - * initialize the chip - */ -static int __devinit maya44_init(struct snd_ice1712 *ice) -{ - int i; - struct snd_maya44 *chip; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - mutex_init(&chip->mutex); - chip->ice = ice; - ice->spec = chip; - - /* initialise codecs */ - ice->num_total_dacs = 4; - ice->num_total_adcs = 4; - ice->akm_codecs = 0; - - for (i = 0; i < 2; i++) { - wm8776_init(ice, &chip->wm[i], wm8776_addr[i]); - wm8776_select_input(chip, i, MAYA_LINE_IN); - } - - /* set card specific rates */ - ice->hw_rates = &dac_rates; - - /* register change rate notifier */ - ice->gpio.set_pro_rate = set_rate; - - /* RDMA1 (2nd input channel) is used for ADC by default */ - ice->force_rdma1 = 1; - - /* have an own routing control */ - ice->own_routing = 1; - - return 0; -} - - -/* - * Maya44 boards don't provide the EEPROM data except for the vendor IDs. - * hence the driver needs to sets up it properly. - */ - -static unsigned char maya44_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x45, - /* clock xin1=49.152MHz, mpu401, 2 stereo ADCs+DACs */ - [ICE_EEP2_ACLINK] = 0x80, - /* I2S */ - [ICE_EEP2_I2S] = 0xf8, - /* vol, 96k, 24bit, 192k */ - [ICE_EEP2_SPDIF] = 0xc3, - /* enable spdif out, spdif out supp, spdif-in, ext spdif out */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0xff, - [ICE_EEP2_GPIO_MASK] = 0/*0x9f*/, - [ICE_EEP2_GPIO_MASK1] = 0/*0xff*/, - [ICE_EEP2_GPIO_MASK2] = 0/*0x7f*/, - [ICE_EEP2_GPIO_STATE] = (1 << GPIO_PHANTOM_OFF) | - (1 << GPIO_SPDIF_IN_INV), - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, -}; - -/* entry point */ -struct snd_ice1712_card_info snd_vt1724_maya44_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_MAYA44, - .name = "ESI Maya44", - .model = "maya44", - .chip_init = maya44_init, - .build_controls = maya44_add_controls, - .eeprom_size = sizeof(maya44_eeprom), - .eeprom_data = maya44_eeprom, - }, - { } /* terminator */ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/maya44.h b/ANDROID_3.4.5/sound/pci/ice1712/maya44.h deleted file mode 100644 index eafd03a8..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/maya44.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __SOUND_MAYA44_H -#define __SOUND_MAYA44_H - -#define MAYA44_DEVICE_DESC "{ESI,Maya44}," - -#define VT1724_SUBDEVICE_MAYA44 0x34315441 /* Maya44 */ - -extern struct snd_ice1712_card_info snd_vt1724_maya44_cards[]; - -#endif /* __SOUND_MAYA44_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/phase.c b/ANDROID_3.4.5/sound/pci/ice1712/phase.c deleted file mode 100644 index de29be8c..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/phase.c +++ /dev/null @@ -1,975 +0,0 @@ -/* - * ALSA driver for ICEnsemble ICE1724 (Envy24) - * - * Lowlevel functions for Terratec PHASE 22 - * - * Copyright (c) 2005 Misha Zhilin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* PHASE 22 overview: - * Audio controller: VIA Envy24HT-S (slightly trimmed down Envy24HT, 4in/4out) - * Analog chip: AK4524 (partially via Philip's 74HCT125) - * Digital receiver: CS8414-CS (supported in this release) - * PHASE 22 revision 2.0 and Terrasoniq/Musonik TS22PCI have CS8416 - * (support status unknown, please test and report) - * - * Envy connects to AK4524 - * - CS directly from GPIO 10 - * - CCLK via 74HCT125's gate #4 from GPIO 4 - * - CDTI via 74HCT125's gate #2 from GPIO 5 - * CDTI may be completely blocked by 74HCT125's gate #1 - * controlled by GPIO 3 - */ - -/* PHASE 28 overview: - * Audio controller: VIA Envy24HT (full untrimmed version, 4in/8out) - * Analog chip: WM8770 (8 channel 192k DAC, 2 channel 96k ADC) - * Digital receiver: CS8414-CS (supported in this release) - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "phase.h" -#include - -/* AC97 register cache for Phase28 */ -struct phase28_spec { - unsigned short master[2]; - unsigned short vol[8]; -}; - -/* WM8770 registers */ -#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */ -#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */ -#define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */ -#define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */ -#define WM_PHASE_SWAP 0x12 /* DAC phase */ -#define WM_DAC_CTRL1 0x13 /* DAC control bits */ -#define WM_MUTE 0x14 /* mute controls */ -#define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */ -#define WM_INT_CTRL 0x16 /* interface control */ -#define WM_MASTER 0x17 /* master clock and mode */ -#define WM_POWERDOWN 0x18 /* power-down controls */ -#define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */ -#define WM_ADC_MUX 0x1b /* input MUX */ -#define WM_OUT_MUX1 0x1c /* output MUX */ -#define WM_OUT_MUX2 0x1e /* output MUX */ -#define WM_RESET 0x1f /* software reset */ - - -/* - * Logarithmic volume values for WM8770 - * Computed as 20 * Log10(255 / x) - */ -static const unsigned char wm_vol[256] = { - 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, - 24, 23, 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, - 17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, - 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -#define WM_VOL_MAX (sizeof(wm_vol) - 1) -#define WM_VOL_MUTE 0x8000 - -static struct snd_akm4xxx akm_phase22 __devinitdata = { - .type = SND_AK4524, - .num_dacs = 2, - .num_adcs = 2, -}; - -static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { - .caddr = 2, - .cif = 1, - .data_mask = 1 << 4, - .clk_mask = 1 << 5, - .cs_mask = 1 << 10, - .cs_addr = 1 << 10, - .cs_none = 0, - .add_flags = 1 << 3, - .mask_flags = 0, -}; - -static int __devinit phase22_init(struct snd_ice1712 *ice) -{ - struct snd_akm4xxx *ak; - int err; - - /* Configure DAC/ADC description for generic part of ice1724 */ - switch (ice->eeprom.subvendor) { - case VT1724_SUBDEVICE_PHASE22: - case VT1724_SUBDEVICE_TS22: - ice->num_total_dacs = 2; - ice->num_total_adcs = 2; - ice->vt1720 = 1; /* Envy24HT-S have 16 bit wide GPIO */ - break; - default: - snd_BUG(); - return -EINVAL; - } - - /* Initialize analog chips */ - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - ak = ice->akm; - if (!ak) - return -ENOMEM; - ice->akm_codecs = 1; - switch (ice->eeprom.subvendor) { - case VT1724_SUBDEVICE_PHASE22: - case VT1724_SUBDEVICE_TS22: - err = snd_ice1712_akm4xxx_init(ak, &akm_phase22, - &akm_phase22_priv, ice); - if (err < 0) - return err; - break; - } - - return 0; -} - -static int __devinit phase22_add_controls(struct snd_ice1712 *ice) -{ - int err = 0; - - switch (ice->eeprom.subvendor) { - case VT1724_SUBDEVICE_PHASE22: - case VT1724_SUBDEVICE_TS22: - err = snd_ice1712_akm4xxx_build_controls(ice); - if (err < 0) - return err; - } - return 0; -} - -static unsigned char phase22_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x28, /* clock 512, mpu 401, - spdif-in/1xADC, 1xDACs */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0xf0, /* vol, 96k, 24bit */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0xff, - [ICE_EEP2_GPIO_MASK] = 0x00, - [ICE_EEP2_GPIO_MASK1] = 0x00, - [ICE_EEP2_GPIO_MASK2] = 0x00, - [ICE_EEP2_GPIO_STATE] = 0x00, - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, -}; - -static unsigned char phase28_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, - spdif-in/1xADC, 4xDACs */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x5f, - [ICE_EEP2_GPIO_MASK] = 0x00, - [ICE_EEP2_GPIO_MASK1] = 0x00, - [ICE_EEP2_GPIO_MASK2] = 0x00, - [ICE_EEP2_GPIO_STATE] = 0x00, - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, -}; - -/* - * write data in the SPI mode - */ -static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs, - unsigned int data, int bits) -{ - unsigned int tmp; - int i; - - tmp = snd_ice1712_gpio_read(ice); - - snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI| - PHASE28_SPI_CLK|PHASE28_WM_CS)); - tmp |= PHASE28_WM_RW; - tmp &= ~cs; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - - for (i = bits - 1; i >= 0; i--) { - tmp &= ~PHASE28_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - if (data & (1 << i)) - tmp |= PHASE28_SPI_MOSI; - else - tmp &= ~PHASE28_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - tmp |= PHASE28_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - } - - tmp &= ~PHASE28_SPI_CLK; - tmp |= cs; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - tmp |= PHASE28_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); -} - -/* - * get the current register value of WM codec - */ -static unsigned short wm_get(struct snd_ice1712 *ice, int reg) -{ - reg <<= 1; - return ((unsigned short)ice->akm[0].images[reg] << 8) | - ice->akm[0].images[reg + 1]; -} - -/* - * set the register value of WM codec - */ -static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val) -{ - phase28_spi_write(ice, PHASE28_WM_CS, (reg << 9) | (val & 0x1ff), 16); -} - -/* - * set the register value of WM codec and remember it - */ -static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val) -{ - wm_put_nocache(ice, reg, val); - reg <<= 1; - ice->akm[0].images[reg] = val >> 8; - ice->akm[0].images[reg + 1] = val; -} - -static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, - unsigned short vol, unsigned short master) -{ - unsigned char nvol; - - if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) - nvol = 0; - else - nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * - (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX]; - - wm_put(ice, index, nvol); - wm_put_nocache(ice, index, 0x180 | nvol); -} - -/* - * DAC mute control - */ -#define wm_pcm_mute_info snd_ctl_boolean_mono_info - -static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - mutex_lock(&ice->gpio_mutex); - ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? - 0 : 1; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short nval, oval; - int change; - - snd_ice1712_save_gpio_status(ice); - oval = wm_get(ice, WM_MUTE); - nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10); - change = (nval != oval); - if (change) - wm_put(ice, WM_MUTE, nval); - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* - * Master volume attenuation mixer control - */ -static int wm_master_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = WM_VOL_MAX; - return 0; -} - -static int wm_master_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct phase28_spec *spec = ice->spec; - int i; - for (i = 0; i < 2; i++) - ucontrol->value.integer.value[i] = spec->master[i] & - ~WM_VOL_MUTE; - return 0; -} - -static int wm_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct phase28_spec *spec = ice->spec; - int ch, change = 0; - - snd_ice1712_save_gpio_status(ice); - for (ch = 0; ch < 2; ch++) { - unsigned int vol = ucontrol->value.integer.value[ch]; - if (vol > WM_VOL_MAX) - continue; - vol |= spec->master[ch] & WM_VOL_MUTE; - if (vol != spec->master[ch]) { - int dac; - spec->master[ch] = vol; - for (dac = 0; dac < ice->num_total_dacs; dac += 2) - wm_set_vol(ice, WM_DAC_ATTEN + dac + ch, - spec->vol[dac + ch], - spec->master[ch]); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - return change; -} - -static int __devinit phase28_init(struct snd_ice1712 *ice) -{ - static const unsigned short wm_inits_phase28[] = { - /* These come first to reduce init pop noise */ - 0x1b, 0x044, /* ADC Mux (AC'97 source) */ - 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */ - 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */ - - 0x18, 0x000, /* All power-up */ - - 0x16, 0x122, /* I2S, normal polarity, 24bit */ - 0x17, 0x022, /* 256fs, slave mode */ - 0x00, 0, /* DAC1 analog mute */ - 0x01, 0, /* DAC2 analog mute */ - 0x02, 0, /* DAC3 analog mute */ - 0x03, 0, /* DAC4 analog mute */ - 0x04, 0, /* DAC5 analog mute */ - 0x05, 0, /* DAC6 analog mute */ - 0x06, 0, /* DAC7 analog mute */ - 0x07, 0, /* DAC8 analog mute */ - 0x08, 0x100, /* master analog mute */ - 0x09, 0xff, /* DAC1 digital full */ - 0x0a, 0xff, /* DAC2 digital full */ - 0x0b, 0xff, /* DAC3 digital full */ - 0x0c, 0xff, /* DAC4 digital full */ - 0x0d, 0xff, /* DAC5 digital full */ - 0x0e, 0xff, /* DAC6 digital full */ - 0x0f, 0xff, /* DAC7 digital full */ - 0x10, 0xff, /* DAC8 digital full */ - 0x11, 0x1ff, /* master digital full */ - 0x12, 0x000, /* phase normal */ - 0x13, 0x090, /* unmute DAC L/R */ - 0x14, 0x000, /* all unmute */ - 0x15, 0x000, /* no deemphasis, no ZFLG */ - 0x19, 0x000, /* -12dB ADC/L */ - 0x1a, 0x000, /* -12dB ADC/R */ - (unsigned short)-1 - }; - - unsigned int tmp; - struct snd_akm4xxx *ak; - struct phase28_spec *spec; - const unsigned short *p; - int i; - - ice->num_total_dacs = 8; - ice->num_total_adcs = 2; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - ice->spec = spec; - - /* Initialize analog chips */ - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - ak = ice->akm; - if (!ak) - return -ENOMEM; - ice->akm_codecs = 1; - - snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for time being */ - - /* reset the wm codec as the SPI mode */ - snd_ice1712_save_gpio_status(ice); - snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS| - PHASE28_HP_SEL)); - - tmp = snd_ice1712_gpio_read(ice); - tmp &= ~PHASE28_WM_RESET; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - tmp |= PHASE28_WM_CS; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - tmp |= PHASE28_WM_RESET; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - - p = wm_inits_phase28; - for (; *p != (unsigned short)-1; p += 2) - wm_put(ice, p[0], p[1]); - - snd_ice1712_restore_gpio_status(ice); - - spec->master[0] = WM_VOL_MUTE; - spec->master[1] = WM_VOL_MUTE; - for (i = 0; i < ice->num_total_dacs; i++) { - spec->vol[i] = WM_VOL_MUTE; - wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]); - } - - return 0; -} - -/* - * DAC volume attenuation mixer control - */ -static int wm_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - int voices = kcontrol->private_value >> 8; - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = voices; - uinfo->value.integer.min = 0; /* mute (-101dB) */ - uinfo->value.integer.max = 0x7F; /* 0dB */ - return 0; -} - -static int wm_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct phase28_spec *spec = ice->spec; - int i, ofs, voices; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xff; - for (i = 0; i < voices; i++) - ucontrol->value.integer.value[i] = - spec->vol[ofs+i] & ~WM_VOL_MUTE; - return 0; -} - -static int wm_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct phase28_spec *spec = ice->spec; - int i, idx, ofs, voices; - int change = 0; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xff; - snd_ice1712_save_gpio_status(ice); - for (i = 0; i < voices; i++) { - unsigned int vol; - vol = ucontrol->value.integer.value[i]; - if (vol > 0x7f) - continue; - vol |= spec->vol[ofs+i] & WM_VOL_MUTE; - if (vol != spec->vol[ofs+i]) { - spec->vol[ofs+i] = vol; - idx = WM_DAC_ATTEN + ofs + i; - wm_set_vol(ice, idx, spec->vol[ofs+i], - spec->master[i]); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - return change; -} - -/* - * WM8770 mute control - */ -static int wm_mute_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = kcontrol->private_value >> 8; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int wm_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct phase28_spec *spec = ice->spec; - int voices, ofs, i; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xFF; - - for (i = 0; i < voices; i++) - ucontrol->value.integer.value[i] = - (spec->vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1; - return 0; -} - -static int wm_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct phase28_spec *spec = ice->spec; - int change = 0, voices, ofs, i; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xFF; - - snd_ice1712_save_gpio_status(ice); - for (i = 0; i < voices; i++) { - int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1; - if (ucontrol->value.integer.value[i] != val) { - spec->vol[ofs + i] &= ~WM_VOL_MUTE; - spec->vol[ofs + i] |= - ucontrol->value.integer.value[i] ? 0 : - WM_VOL_MUTE; - wm_set_vol(ice, ofs + i, spec->vol[ofs + i], - spec->master[i]); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* - * WM8770 master mute control - */ -#define wm_master_mute_info snd_ctl_boolean_stereo_info - -static int wm_master_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct phase28_spec *spec = ice->spec; - - ucontrol->value.integer.value[0] = - (spec->master[0] & WM_VOL_MUTE) ? 0 : 1; - ucontrol->value.integer.value[1] = - (spec->master[1] & WM_VOL_MUTE) ? 0 : 1; - return 0; -} - -static int wm_master_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct phase28_spec *spec = ice->spec; - int change = 0, i; - - snd_ice1712_save_gpio_status(ice); - for (i = 0; i < 2; i++) { - int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1; - if (ucontrol->value.integer.value[i] != val) { - int dac; - spec->master[i] &= ~WM_VOL_MUTE; - spec->master[i] |= - ucontrol->value.integer.value[i] ? 0 : - WM_VOL_MUTE; - for (dac = 0; dac < ice->num_total_dacs; dac += 2) - wm_set_vol(ice, WM_DAC_ATTEN + dac + i, - spec->vol[dac + i], - spec->master[i]); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* digital master volume */ -#define PCM_0dB 0xff -#define PCM_RES 128 /* -64dB */ -#define PCM_MIN (PCM_0dB - PCM_RES) -static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; /* mute (-64dB) */ - uinfo->value.integer.max = PCM_RES; /* 0dB */ - return 0; -} - -static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short val; - - mutex_lock(&ice->gpio_mutex); - val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; - val = val > PCM_MIN ? (val - PCM_MIN) : 0; - ucontrol->value.integer.value[0] = val; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short ovol, nvol; - int change = 0; - - nvol = ucontrol->value.integer.value[0]; - if (nvol > PCM_RES) - return -EINVAL; - snd_ice1712_save_gpio_status(ice); - nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff; - ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; - if (ovol != nvol) { - wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */ - /* update */ - wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); - change = 1; - } - snd_ice1712_restore_gpio_status(ice); - return change; -} - -/* - * Deemphasis - */ -#define phase28_deemp_info snd_ctl_boolean_mono_info - -static int phase28_deemp_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == - 0xf; - return 0; -} - -static int phase28_deemp_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int temp, temp2; - temp = wm_get(ice, WM_DAC_CTRL2); - temp2 = temp; - if (ucontrol->value.integer.value[0]) - temp |= 0xf; - else - temp &= ~0xf; - if (temp != temp2) { - wm_put(ice, WM_DAC_CTRL2, temp); - return 1; - } - return 0; -} - -/* - * ADC Oversampling - */ -static int phase28_oversampling_info(struct snd_kcontrol *k, - struct snd_ctl_elem_info *uinfo) -{ - static char *texts[2] = { "128x", "64x" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - - return 0; -} - -static int phase28_oversampling_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == - 0x8; - return 0; -} - -static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int temp, temp2; - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - temp = wm_get(ice, WM_MASTER); - temp2 = temp; - - if (ucontrol->value.enumerated.item[0]) - temp |= 0x8; - else - temp &= ~0x8; - - if (temp != temp2) { - wm_put(ice, WM_MASTER, temp); - return 1; - } - return 0; -} - -static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); -static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); - -static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = wm_master_mute_info, - .get = wm_master_mute_get, - .put = wm_master_mute_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Master Playback Volume", - .info = wm_master_vol_info, - .get = wm_master_vol_get, - .put = wm_master_vol_put, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Front Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (2 << 8) | 0 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Front Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (2 << 8) | 0, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Rear Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (2 << 8) | 2 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Rear Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (2 << 8) | 2, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Center Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (1 << 8) | 4 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Center Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (1 << 8) | 4, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "LFE Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (1 << 8) | 5 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "LFE Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (1 << 8) | 5, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Side Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (2 << 8) | 6 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Side Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (2 << 8) | 6, - .tlv = { .p = db_scale_wm_dac } - } -}; - -static struct snd_kcontrol_new wm_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Switch", - .info = wm_pcm_mute_info, - .get = wm_pcm_mute_get, - .put = wm_pcm_mute_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "PCM Playback Volume", - .info = wm_pcm_vol_info, - .get = wm_pcm_vol_get, - .put = wm_pcm_vol_put, - .tlv = { .p = db_scale_wm_pcm } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "DAC Deemphasis Switch", - .info = phase28_deemp_info, - .get = phase28_deemp_get, - .put = phase28_deemp_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "ADC Oversampling", - .info = phase28_oversampling_info, - .get = phase28_oversampling_get, - .put = phase28_oversampling_put - } -}; - -static int __devinit phase28_add_controls(struct snd_ice1712 *ice) -{ - unsigned int i, counts; - int err; - - counts = ARRAY_SIZE(phase28_dac_controls); - for (i = 0; i < counts; i++) { - err = snd_ctl_add(ice->card, - snd_ctl_new1(&phase28_dac_controls[i], - ice)); - if (err < 0) - return err; - } - - for (i = 0; i < ARRAY_SIZE(wm_controls); i++) { - err = snd_ctl_add(ice->card, - snd_ctl_new1(&wm_controls[i], ice)); - if (err < 0) - return err; - } - - return 0; -} - -struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_PHASE22, - .name = "Terratec PHASE 22", - .model = "phase22", - .chip_init = phase22_init, - .build_controls = phase22_add_controls, - .eeprom_size = sizeof(phase22_eeprom), - .eeprom_data = phase22_eeprom, - }, - { - .subvendor = VT1724_SUBDEVICE_PHASE28, - .name = "Terratec PHASE 28", - .model = "phase28", - .chip_init = phase28_init, - .build_controls = phase28_add_controls, - .eeprom_size = sizeof(phase28_eeprom), - .eeprom_data = phase28_eeprom, - }, - { - .subvendor = VT1724_SUBDEVICE_TS22, - .name = "Terrasoniq TS22 PCI", - .model = "TS22", - .chip_init = phase22_init, - .build_controls = phase22_add_controls, - .eeprom_size = sizeof(phase22_eeprom), - .eeprom_data = phase22_eeprom, - }, - { } /* terminator */ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/phase.h b/ANDROID_3.4.5/sound/pci/ice1712/phase.h deleted file mode 100644 index 7fc22d9d..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/phase.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __SOUND_PHASE_H -#define __SOUND_PHASE_H - -/* - * ALSA driver for ICEnsemble ICE1712 (Envy24) - * - * Lowlevel functions for Terratec PHASE 22 - * - * Copyright (c) 2005 Misha Zhilin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"\ - "{Terratec,Phase 28},"\ - "{Terrasoniq,TS22}," - -#define VT1724_SUBDEVICE_PHASE22 0x3b155011 -#define VT1724_SUBDEVICE_PHASE28 0x3b154911 -#define VT1724_SUBDEVICE_TS22 0x3b157b11 - -/* entry point */ -extern struct snd_ice1712_card_info snd_vt1724_phase_cards[]; - -/* PHASE28 GPIO bits */ -#define PHASE28_SPI_MISO (1 << 21) -#define PHASE28_WM_RESET (1 << 20) -#define PHASE28_SPI_CLK (1 << 19) -#define PHASE28_SPI_MOSI (1 << 18) -#define PHASE28_WM_RW (1 << 17) -#define PHASE28_AC97_RESET (1 << 16) -#define PHASE28_DIGITAL_SEL1 (1 << 15) -#define PHASE28_HP_SEL (1 << 14) -#define PHASE28_WM_CS (1 << 12) -#define PHASE28_AC97_COMMIT (1 << 11) -#define PHASE28_AC97_ADDR (1 << 10) -#define PHASE28_AC97_DATA_LOW (1 << 9) -#define PHASE28_AC97_DATA_HIGH (1 << 8) -#define PHASE28_AC97_DATA_MASK 0xFF -#endif /* __SOUND_PHASE */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/pontis.c b/ANDROID_3.4.5/sound/pci/ice1712/pontis.c deleted file mode 100644 index 92c1160d..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/pontis.c +++ /dev/null @@ -1,836 +0,0 @@ -/* - * ALSA driver for ICEnsemble VT1724 (Envy24HT) - * - * Lowlevel functions for Pontis MS300 - * - * Copyright (c) 2004 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "pontis.h" - -/* I2C addresses */ -#define WM_DEV 0x34 -#define CS_DEV 0x20 - -/* WM8776 registers */ -#define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */ -#define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */ -#define WM_HP_MASTER 0x02 /* headphone master (both channels) */ - /* override LLR */ -#define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */ -#define WM_DAC_ATTEN_R 0x04 -#define WM_DAC_MASTER 0x05 -#define WM_PHASE_SWAP 0x06 /* DAC phase swap */ -#define WM_DAC_CTRL1 0x07 -#define WM_DAC_MUTE 0x08 -#define WM_DAC_CTRL2 0x09 -#define WM_DAC_INT 0x0a -#define WM_ADC_INT 0x0b -#define WM_MASTER_CTRL 0x0c -#define WM_POWERDOWN 0x0d -#define WM_ADC_ATTEN_L 0x0e -#define WM_ADC_ATTEN_R 0x0f -#define WM_ALC_CTRL1 0x10 -#define WM_ALC_CTRL2 0x11 -#define WM_ALC_CTRL3 0x12 -#define WM_NOISE_GATE 0x13 -#define WM_LIMITER 0x14 -#define WM_ADC_MUX 0x15 -#define WM_OUT_MUX 0x16 -#define WM_RESET 0x17 - -/* - * GPIO - */ -#define PONTIS_CS_CS (1<<4) /* CS */ -#define PONTIS_CS_CLK (1<<5) /* CLK */ -#define PONTIS_CS_RDATA (1<<6) /* CS8416 -> VT1720 */ -#define PONTIS_CS_WDATA (1<<7) /* VT1720 -> CS8416 */ - - -/* - * get the current register value of WM codec - */ -static unsigned short wm_get(struct snd_ice1712 *ice, int reg) -{ - reg <<= 1; - return ((unsigned short)ice->akm[0].images[reg] << 8) | - ice->akm[0].images[reg + 1]; -} - -/* - * set the register value of WM codec and remember it - */ -static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val) -{ - unsigned short cval; - cval = (reg << 9) | val; - snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff); -} - -static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val) -{ - wm_put_nocache(ice, reg, val); - reg <<= 1; - ice->akm[0].images[reg] = val >> 8; - ice->akm[0].images[reg + 1] = val; -} - -/* - * DAC volume attenuation mixer control (-64dB to 0dB) - */ - -#define DAC_0dB 0xff -#define DAC_RES 128 -#define DAC_MIN (DAC_0dB - DAC_RES) - -static int wm_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; /* mute */ - uinfo->value.integer.max = DAC_RES; /* 0dB, 0.5dB step */ - return 0; -} - -static int wm_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short val; - int i; - - mutex_lock(&ice->gpio_mutex); - for (i = 0; i < 2; i++) { - val = wm_get(ice, WM_DAC_ATTEN_L + i) & 0xff; - val = val > DAC_MIN ? (val - DAC_MIN) : 0; - ucontrol->value.integer.value[i] = val; - } - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short oval, nval; - int i, idx, change = 0; - - mutex_lock(&ice->gpio_mutex); - for (i = 0; i < 2; i++) { - nval = ucontrol->value.integer.value[i]; - nval = (nval ? (nval + DAC_MIN) : 0) & 0xff; - idx = WM_DAC_ATTEN_L + i; - oval = wm_get(ice, idx) & 0xff; - if (oval != nval) { - wm_put(ice, idx, nval); - wm_put_nocache(ice, idx, nval | 0x100); - change = 1; - } - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - -/* - * ADC gain mixer control (-64dB to 0dB) - */ - -#define ADC_0dB 0xcf -#define ADC_RES 128 -#define ADC_MIN (ADC_0dB - ADC_RES) - -static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; /* mute (-64dB) */ - uinfo->value.integer.max = ADC_RES; /* 0dB, 0.5dB step */ - return 0; -} - -static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short val; - int i; - - mutex_lock(&ice->gpio_mutex); - for (i = 0; i < 2; i++) { - val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff; - val = val > ADC_MIN ? (val - ADC_MIN) : 0; - ucontrol->value.integer.value[i] = val; - } - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short ovol, nvol; - int i, idx, change = 0; - - mutex_lock(&ice->gpio_mutex); - for (i = 0; i < 2; i++) { - nvol = ucontrol->value.integer.value[i]; - nvol = nvol ? (nvol + ADC_MIN) : 0; - idx = WM_ADC_ATTEN_L + i; - ovol = wm_get(ice, idx) & 0xff; - if (ovol != nvol) { - wm_put(ice, idx, nvol); - change = 1; - } - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - -/* - * ADC input mux mixer control - */ -#define wm_adc_mux_info snd_ctl_boolean_mono_info - -static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int bit = kcontrol->private_value; - - mutex_lock(&ice->gpio_mutex); - ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int bit = kcontrol->private_value; - unsigned short oval, nval; - int change; - - mutex_lock(&ice->gpio_mutex); - nval = oval = wm_get(ice, WM_ADC_MUX); - if (ucontrol->value.integer.value[0]) - nval |= (1 << bit); - else - nval &= ~(1 << bit); - change = nval != oval; - if (change) { - wm_put(ice, WM_ADC_MUX, nval); - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - -/* - * Analog bypass (In -> Out) - */ -#define wm_bypass_info snd_ctl_boolean_mono_info - -static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - mutex_lock(&ice->gpio_mutex); - ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short val, oval; - int change = 0; - - mutex_lock(&ice->gpio_mutex); - val = oval = wm_get(ice, WM_OUT_MUX); - if (ucontrol->value.integer.value[0]) - val |= 0x04; - else - val &= ~0x04; - if (val != oval) { - wm_put(ice, WM_OUT_MUX, val); - change = 1; - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - -/* - * Left/Right swap - */ -#define wm_chswap_info snd_ctl_boolean_mono_info - -static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - mutex_lock(&ice->gpio_mutex); - ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short val, oval; - int change = 0; - - mutex_lock(&ice->gpio_mutex); - oval = wm_get(ice, WM_DAC_CTRL1); - val = oval & 0x0f; - if (ucontrol->value.integer.value[0]) - val |= 0x60; - else - val |= 0x90; - if (val != oval) { - wm_put(ice, WM_DAC_CTRL1, val); - wm_put_nocache(ice, WM_DAC_CTRL1, val); - change = 1; - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - -/* - * write data in the SPI mode - */ -static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val) -{ - unsigned int tmp = snd_ice1712_gpio_read(ice); - if (val) - tmp |= bit; - else - tmp &= ~bit; - snd_ice1712_gpio_write(ice, tmp); -} - -static void spi_send_byte(struct snd_ice1712 *ice, unsigned char data) -{ - int i; - for (i = 0; i < 8; i++) { - set_gpio_bit(ice, PONTIS_CS_CLK, 0); - udelay(1); - set_gpio_bit(ice, PONTIS_CS_WDATA, data & 0x80); - udelay(1); - set_gpio_bit(ice, PONTIS_CS_CLK, 1); - udelay(1); - data <<= 1; - } -} - -static unsigned int spi_read_byte(struct snd_ice1712 *ice) -{ - int i; - unsigned int val = 0; - - for (i = 0; i < 8; i++) { - val <<= 1; - set_gpio_bit(ice, PONTIS_CS_CLK, 0); - udelay(1); - if (snd_ice1712_gpio_read(ice) & PONTIS_CS_RDATA) - val |= 1; - udelay(1); - set_gpio_bit(ice, PONTIS_CS_CLK, 1); - udelay(1); - } - return val; -} - - -static void spi_write(struct snd_ice1712 *ice, unsigned int dev, unsigned int reg, unsigned int data) -{ - snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK); - snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK)); - set_gpio_bit(ice, PONTIS_CS_CS, 0); - spi_send_byte(ice, dev & ~1); /* WRITE */ - spi_send_byte(ice, reg); /* MAP */ - spi_send_byte(ice, data); /* DATA */ - /* trigger */ - set_gpio_bit(ice, PONTIS_CS_CS, 1); - udelay(1); - /* restore */ - snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask); - snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); -} - -static unsigned int spi_read(struct snd_ice1712 *ice, unsigned int dev, unsigned int reg) -{ - unsigned int val; - snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK); - snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK)); - set_gpio_bit(ice, PONTIS_CS_CS, 0); - spi_send_byte(ice, dev & ~1); /* WRITE */ - spi_send_byte(ice, reg); /* MAP */ - /* trigger */ - set_gpio_bit(ice, PONTIS_CS_CS, 1); - udelay(1); - set_gpio_bit(ice, PONTIS_CS_CS, 0); - spi_send_byte(ice, dev | 1); /* READ */ - val = spi_read_byte(ice); - /* trigger */ - set_gpio_bit(ice, PONTIS_CS_CS, 1); - udelay(1); - /* restore */ - snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask); - snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); - return val; -} - - -/* - * SPDIF input source - */ -static int cs_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - static const char * const texts[] = { - "Coax", /* RXP0 */ - "Optical", /* RXP1 */ - "CD", /* RXP2 */ - }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int cs_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - mutex_lock(&ice->gpio_mutex); - ucontrol->value.enumerated.item[0] = ice->gpio.saved[0]; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int cs_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char val; - int change = 0; - - mutex_lock(&ice->gpio_mutex); - if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) { - ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3; - val = 0x80 | (ice->gpio.saved[0] << 3); - spi_write(ice, CS_DEV, 0x04, val); - change = 1; - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - - -/* - * GPIO controls - */ -static int pontis_gpio_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 0xffff; /* 16bit */ - return 0; -} - -static int pontis_gpio_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); - /* 4-7 reserved */ - ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int pontis_gpio_mask_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int val; - int changed; - mutex_lock(&ice->gpio_mutex); - /* 4-7 reserved */ - val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0; - changed = val != ice->gpio.write_mask; - ice->gpio.write_mask = val; - mutex_unlock(&ice->gpio_mutex); - return changed; -} - -static int pontis_gpio_dir_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); - /* 4-7 reserved */ - ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int pontis_gpio_dir_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int val; - int changed; - mutex_lock(&ice->gpio_mutex); - /* 4-7 reserved */ - val = ucontrol->value.integer.value[0] & 0xff0f; - changed = (val != ice->gpio.direction); - ice->gpio.direction = val; - mutex_unlock(&ice->gpio_mutex); - return changed; -} - -static int pontis_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); - snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); - snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask); - ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int val, nval; - int changed = 0; - mutex_lock(&ice->gpio_mutex); - snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); - snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask); - val = snd_ice1712_gpio_read(ice) & 0xffff; - nval = ucontrol->value.integer.value[0] & 0xffff; - if (val != nval) { - snd_ice1712_gpio_write(ice, nval); - changed = 1; - } - mutex_unlock(&ice->gpio_mutex); - return changed; -} - -static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1); - -/* - * mixers - */ - -static struct snd_kcontrol_new pontis_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "PCM Playback Volume", - .info = wm_dac_vol_info, - .get = wm_dac_vol_get, - .put = wm_dac_vol_put, - .tlv = { .p = db_scale_volume }, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Capture Volume", - .info = wm_adc_vol_info, - .get = wm_adc_vol_get, - .put = wm_adc_vol_put, - .tlv = { .p = db_scale_volume }, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "CD Capture Switch", - .info = wm_adc_mux_info, - .get = wm_adc_mux_get, - .put = wm_adc_mux_put, - .private_value = 0, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Line Capture Switch", - .info = wm_adc_mux_info, - .get = wm_adc_mux_get, - .put = wm_adc_mux_put, - .private_value = 1, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Bypass Switch", - .info = wm_bypass_info, - .get = wm_bypass_get, - .put = wm_bypass_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Swap Output Channels", - .info = wm_chswap_info, - .get = wm_chswap_get, - .put = wm_chswap_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Input Source", - .info = cs_source_info, - .get = cs_source_get, - .put = cs_source_put, - }, - /* FIXME: which interface? */ - { - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - .name = "GPIO Mask", - .info = pontis_gpio_mask_info, - .get = pontis_gpio_mask_get, - .put = pontis_gpio_mask_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - .name = "GPIO Direction", - .info = pontis_gpio_mask_info, - .get = pontis_gpio_dir_get, - .put = pontis_gpio_dir_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - .name = "GPIO Data", - .info = pontis_gpio_mask_info, - .get = pontis_gpio_data_get, - .put = pontis_gpio_data_put, - }, -}; - - -/* - * WM codec registers - */ -static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer) -{ - struct snd_ice1712 *ice = entry->private_data; - char line[64]; - unsigned int reg, val; - mutex_lock(&ice->gpio_mutex); - while (!snd_info_get_line(buffer, line, sizeof(line))) { - if (sscanf(line, "%x %x", ®, &val) != 2) - continue; - if (reg <= 0x17 && val <= 0xffff) - wm_put(ice, reg, val); - } - mutex_unlock(&ice->gpio_mutex); -} - -static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) -{ - struct snd_ice1712 *ice = entry->private_data; - int reg, val; - - mutex_lock(&ice->gpio_mutex); - for (reg = 0; reg <= 0x17; reg++) { - val = wm_get(ice, reg); - snd_iprintf(buffer, "%02x = %04x\n", reg, val); - } - mutex_unlock(&ice->gpio_mutex); -} - -static void wm_proc_init(struct snd_ice1712 *ice) -{ - struct snd_info_entry *entry; - if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) { - snd_info_set_text_ops(entry, ice, wm_proc_regs_read); - entry->mode |= S_IWUSR; - entry->c.text.write = wm_proc_regs_write; - } -} - -static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) -{ - struct snd_ice1712 *ice = entry->private_data; - int reg, val; - - mutex_lock(&ice->gpio_mutex); - for (reg = 0; reg <= 0x26; reg++) { - val = spi_read(ice, CS_DEV, reg); - snd_iprintf(buffer, "%02x = %02x\n", reg, val); - } - val = spi_read(ice, CS_DEV, 0x7f); - snd_iprintf(buffer, "%02x = %02x\n", 0x7f, val); - mutex_unlock(&ice->gpio_mutex); -} - -static void cs_proc_init(struct snd_ice1712 *ice) -{ - struct snd_info_entry *entry; - if (! snd_card_proc_new(ice->card, "cs_codec", &entry)) - snd_info_set_text_ops(entry, ice, cs_proc_regs_read); -} - - -static int __devinit pontis_add_controls(struct snd_ice1712 *ice) -{ - unsigned int i; - int err; - - for (i = 0; i < ARRAY_SIZE(pontis_controls); i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&pontis_controls[i], ice)); - if (err < 0) - return err; - } - - wm_proc_init(ice); - cs_proc_init(ice); - - return 0; -} - - -/* - * initialize the chip - */ -static int __devinit pontis_init(struct snd_ice1712 *ice) -{ - static const unsigned short wm_inits[] = { - /* These come first to reduce init pop noise */ - WM_ADC_MUX, 0x00c0, /* ADC mute */ - WM_DAC_MUTE, 0x0001, /* DAC softmute */ - WM_DAC_CTRL1, 0x0000, /* DAC mute */ - - WM_POWERDOWN, 0x0008, /* All power-up except HP */ - WM_RESET, 0x0000, /* reset */ - }; - static const unsigned short wm_inits2[] = { - WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */ - WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */ - WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */ - WM_DAC_CTRL1, 0x0090, /* DAC L/R */ - WM_OUT_MUX, 0x0001, /* OUT DAC */ - WM_HP_ATTEN_L, 0x0179, /* HP 0dB */ - WM_HP_ATTEN_R, 0x0179, /* HP 0dB */ - WM_DAC_ATTEN_L, 0x0000, /* DAC 0dB */ - WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */ - WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */ - WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */ - /* WM_DAC_MASTER, 0x0100, */ /* DAC master muted */ - WM_PHASE_SWAP, 0x0000, /* phase normal */ - WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */ - WM_ADC_ATTEN_L, 0x0000, /* ADC muted */ - WM_ADC_ATTEN_R, 0x0000, /* ADC muted */ -#if 0 - WM_ALC_CTRL1, 0x007b, /* */ - WM_ALC_CTRL2, 0x0000, /* */ - WM_ALC_CTRL3, 0x0000, /* */ - WM_NOISE_GATE, 0x0000, /* */ -#endif - WM_DAC_MUTE, 0x0000, /* DAC unmute */ - WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */ - }; - static const unsigned char cs_inits[] = { - 0x04, 0x80, /* RUN, RXP0 */ - 0x05, 0x05, /* slave, 24bit */ - 0x01, 0x00, - 0x02, 0x00, - 0x03, 0x00, - }; - unsigned int i; - - ice->vt1720 = 1; - ice->num_total_dacs = 2; - ice->num_total_adcs = 2; - - /* to remember the register values */ - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - if (! ice->akm) - return -ENOMEM; - ice->akm_codecs = 1; - - /* HACK - use this as the SPDIF source. - * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten - */ - ice->gpio.saved[0] = 0; - - /* initialize WM8776 codec */ - for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2) - wm_put(ice, wm_inits[i], wm_inits[i+1]); - schedule_timeout_uninterruptible(1); - for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2) - wm_put(ice, wm_inits2[i], wm_inits2[i+1]); - - /* initialize CS8416 codec */ - /* assert PRST#; MT05 bit 7 */ - outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD)); - mdelay(5); - /* deassert PRST# */ - outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD)); - - for (i = 0; i < ARRAY_SIZE(cs_inits); i += 2) - spi_write(ice, CS_DEV, cs_inits[i], cs_inits[i+1]); - - return 0; -} - - -/* - * Pontis boards don't provide the EEPROM data at all. - * hence the driver needs to sets up it properly. - */ - -static unsigned char pontis_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x08, /* clock 256, mpu401, spdif-in/ADC, 1DAC */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0x07, - [ICE_EEP2_GPIO_DIR1] = 0x00, - [ICE_EEP2_GPIO_DIR2] = 0x00, /* ignored */ - [ICE_EEP2_GPIO_MASK] = 0x0f, /* 4-7 reserved for CS8416 */ - [ICE_EEP2_GPIO_MASK1] = 0xff, - [ICE_EEP2_GPIO_MASK2] = 0x00, /* ignored */ - [ICE_EEP2_GPIO_STATE] = 0x06, /* 0-low, 1-high, 2-high */ - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, /* ignored */ -}; - -/* entry point */ -struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = { - { - .subvendor = VT1720_SUBDEVICE_PONTIS_MS300, - .name = "Pontis MS300", - .model = "ms300", - .chip_init = pontis_init, - .build_controls = pontis_add_controls, - .eeprom_size = sizeof(pontis_eeprom), - .eeprom_data = pontis_eeprom, - }, - { } /* terminator */ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/pontis.h b/ANDROID_3.4.5/sound/pci/ice1712/pontis.h deleted file mode 100644 index d0d1378b..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/pontis.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __SOUND_PONTIS_H -#define __SOUND_PONTIS_H - -/* - * ALSA driver for VIA VT1724 (Envy24HT) - * - * Lowlevel functions for Pontis MS300 boards - * - * Copyright (c) 2004 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define PONTIS_DEVICE_DESC "{Pontis,MS300}," - -#define VT1720_SUBDEVICE_PONTIS_MS300 0x00020002 /* a dummy id for MS300 */ - -extern struct snd_ice1712_card_info snd_vt1720_pontis_cards[]; - -#endif /* __SOUND_PONTIS_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/prodigy192.c b/ANDROID_3.4.5/sound/pci/ice1712/prodigy192.c deleted file mode 100644 index e36ddb94..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/prodigy192.c +++ /dev/null @@ -1,822 +0,0 @@ -/* - * ALSA driver for ICEnsemble VT1724 (Envy24HT) - * - * Lowlevel functions for AudioTrak Prodigy 192 cards - * Supported IEC958 input from optional MI/ODI/O add-on card. - * - * Specifics (SW, HW): - * ------------------- - * * 49.5MHz crystal - * * SPDIF-OUT on the card: - * - coax (through isolation transformer)/toslink supplied by - * 74HC04 gates - 3 in parallel - * - output switched between on-board CD drive dig-out connector - * and ice1724 SPDTX pin, using 74HC02 NOR gates, controlled - * by GPIO20 (0 = CD dig-out, 1 = SPDTX) - * * SPDTX goes straight to MI/ODI/O card's SPDIF-OUT coax - * - * * MI/ODI/O card: AK4114 based, used for iec958 input only - * - toslink input -> RX0 - * - coax input -> RX1 - * - 4wire protocol: - * AK4114 ICE1724 - * ------------------------------ - * CDTO (pin 32) -- GPIO11 pin 86 - * CDTI (pin 33) -- GPIO10 pin 77 - * CCLK (pin 34) -- GPIO9 pin 76 - * CSN (pin 35) -- GPIO8 pin 75 - * - output data Mode 7 (24bit, I2S, slave) - * - both MCKO1 and MCKO2 of ak4114 are fed to FPGA, which - * outputs master clock to SPMCLKIN of ice1724. - * Experimentally I found out that only a combination of - * OCKS0=1, OCKS1=1 (128fs, 64fs output) and ice1724 - - * VT1724_MT_I2S_MCLK_128X=0 (256fs input) yields correct - * sampling rate. That means the the FPGA doubles the - * MCK01 rate. - * - * Copyright (c) 2003 Takashi Iwai - * Copyright (c) 2003 Dimitromanolakis Apostolos - * Copyright (c) 2004 Kouichi ONO - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "prodigy192.h" -#include "stac946x.h" -#include - -struct prodigy192_spec { - struct ak4114 *ak4114; - /* rate change needs atomic mute/unmute of all dacs*/ - struct mutex mute_mutex; -}; - -static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val) -{ - snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val); -} - -static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg) -{ - return snd_vt1724_read_i2c(ice, PRODIGY192_STAC9460_ADDR, reg); -} - -/* - * DAC mute control - */ - -/* - * idx = STAC9460 volume register number, mute: 0 = mute, 1 = unmute - */ -static int stac9460_dac_mute(struct snd_ice1712 *ice, int idx, - unsigned char mute) -{ - unsigned char new, old; - int change; - old = stac9460_get(ice, idx); - new = (~mute << 7 & 0x80) | (old & ~0x80); - change = (new != old); - if (change) - /*printk ("Volume register 0x%02x: 0x%02x\n", idx, new);*/ - stac9460_put(ice, idx, new); - return change; -} - -#define stac9460_dac_mute_info snd_ctl_boolean_mono_info - -static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char val; - int idx; - - if (kcontrol->private_value) - idx = STAC946X_MASTER_VOLUME; - else - idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; - val = stac9460_get(ice, idx); - ucontrol->value.integer.value[0] = (~val >> 7) & 0x1; - return 0; -} - -static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct prodigy192_spec *spec = ice->spec; - int idx, change; - - if (kcontrol->private_value) - idx = STAC946X_MASTER_VOLUME; - else - idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; - /* due to possible conflicts with stac9460_set_rate_val, mutexing */ - mutex_lock(&spec->mute_mutex); - /* - printk(KERN_DEBUG "Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx, - ucontrol->value.integer.value[0]); - */ - change = stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]); - mutex_unlock(&spec->mute_mutex); - return change; -} - -/* - * DAC volume attenuation mixer control - */ -static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; /* mute */ - uinfo->value.integer.max = 0x7f; /* 0dB */ - return 0; -} - -static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx; - unsigned char vol; - - if (kcontrol->private_value) - idx = STAC946X_MASTER_VOLUME; - else - idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; - vol = stac9460_get(ice, idx) & 0x7f; - ucontrol->value.integer.value[0] = 0x7f - vol; - - return 0; -} - -static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx; - unsigned char tmp, ovol, nvol; - int change; - - if (kcontrol->private_value) - idx = STAC946X_MASTER_VOLUME; - else - idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; - nvol = ucontrol->value.integer.value[0]; - tmp = stac9460_get(ice, idx); - ovol = 0x7f - (tmp & 0x7f); - change = (ovol != nvol); - if (change) { - ovol = (0x7f - nvol) | (tmp & 0x80); - /* - printk(KERN_DEBUG "DAC Volume: reg 0x%02x: 0x%02x\n", - idx, ovol); - */ - stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); - } - return change; -} - -/* - * ADC mute control - */ -#define stac9460_adc_mute_info snd_ctl_boolean_stereo_info - -static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char val; - int i; - - for (i = 0; i < 2; ++i) { - val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i); - ucontrol->value.integer.value[i] = ~val>>7 & 0x1; - } - - return 0; -} - -static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char new, old; - int i, reg; - int change; - - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - old = stac9460_get(ice, reg); - new = (~ucontrol->value.integer.value[i]<<7&0x80) | (old&~0x80); - change = (new != old); - if (change) - stac9460_put(ice, reg, new); - } - - return change; -} - -/* - * ADC gain mixer control - */ -static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; /* 0dB */ - uinfo->value.integer.max = 0x0f; /* 22.5dB */ - return 0; -} - -static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int i, reg; - unsigned char vol; - - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - vol = stac9460_get(ice, reg) & 0x0f; - ucontrol->value.integer.value[i] = 0x0f - vol; - } - - return 0; -} - -static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int i, reg; - unsigned char ovol, nvol; - int change; - - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - nvol = ucontrol->value.integer.value[i] & 0x0f; - ovol = 0x0f - stac9460_get(ice, reg); - change = ((ovol & 0x0f) != nvol); - if (change) - stac9460_put(ice, reg, (0x0f - nvol) | (ovol & ~0x0f)); - } - - return change; -} - -static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *texts[2] = { "Line In", "Mic" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - - return 0; -} - - -static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char val; - - val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); - ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1; - return 0; -} - -static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char new, old; - int change; - old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); - new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80); - change = (new != old); - if (change) - stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); - return change; -} -/* - * Handler for setting correct codec rate - called when rate change is detected - */ -static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate) -{ - unsigned char old, new; - int idx; - unsigned char changed[7]; - struct prodigy192_spec *spec = ice->spec; - - if (rate == 0) /* no hint - S/PDIF input is master, simply return */ - return; - else if (rate <= 48000) - new = 0x08; /* 256x, base rate mode */ - else if (rate <= 96000) - new = 0x11; /* 256x, mid rate mode */ - else - new = 0x12; /* 128x, high rate mode */ - old = stac9460_get(ice, STAC946X_MASTER_CLOCKING); - if (old == new) - return; - /* change detected, setting master clock, muting first */ - /* due to possible conflicts with mute controls - mutexing */ - mutex_lock(&spec->mute_mutex); - /* we have to remember current mute status for each DAC */ - for (idx = 0; idx < 7 ; ++idx) - changed[idx] = stac9460_dac_mute(ice, - STAC946X_MASTER_VOLUME + idx, 0); - /*printk(KERN_DEBUG "Rate change: %d, new MC: 0x%02x\n", rate, new);*/ - stac9460_put(ice, STAC946X_MASTER_CLOCKING, new); - udelay(10); - /* unmuting - only originally unmuted dacs - - * i.e. those changed when muting */ - for (idx = 0; idx < 7 ; ++idx) { - if (changed[idx]) - stac9460_dac_mute(ice, STAC946X_MASTER_VOLUME + idx, 1); - } - mutex_unlock(&spec->mute_mutex); -} - - -static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); - -/* - * mixers - */ - -static struct snd_kcontrol_new stac_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = stac9460_dac_mute_info, - .get = stac9460_dac_mute_get, - .put = stac9460_dac_mute_put, - .private_value = 1, - .tlv = { .p = db_scale_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Master Playback Volume", - .info = stac9460_dac_vol_info, - .get = stac9460_dac_vol_get, - .put = stac9460_dac_vol_put, - .private_value = 1, - .tlv = { .p = db_scale_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "DAC Switch", - .count = 6, - .info = stac9460_dac_mute_info, - .get = stac9460_dac_mute_get, - .put = stac9460_dac_mute_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "DAC Volume", - .count = 6, - .info = stac9460_dac_vol_info, - .get = stac9460_dac_vol_get, - .put = stac9460_dac_vol_put, - .tlv = { .p = db_scale_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "ADC Capture Switch", - .count = 1, - .info = stac9460_adc_mute_info, - .get = stac9460_adc_mute_get, - .put = stac9460_adc_mute_put, - - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "ADC Capture Volume", - .count = 1, - .info = stac9460_adc_vol_info, - .get = stac9460_adc_vol_get, - .put = stac9460_adc_vol_put, - .tlv = { .p = db_scale_adc } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Capture Input", - .info = stac9460_mic_sw_info, - .get = stac9460_mic_sw_get, - .put = stac9460_mic_sw_put, - - }, -}; - -/* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */ -/* CDTO (pin 32) -- GPIO11 pin 86 - * CDTI (pin 33) -- GPIO10 pin 77 - * CCLK (pin 34) -- GPIO9 pin 76 - * CSN (pin 35) -- GPIO8 pin 75 - */ -#define AK4114_ADDR 0x00 /* C1-C0: Chip Address - * (According to datasheet fixed to “00”) - */ - -/* - * 4wire ak4114 protocol - writing data - */ -static void write_data(struct snd_ice1712 *ice, unsigned int gpio, - unsigned int data, int idx) -{ - for (; idx >= 0; idx--) { - /* drop clock */ - gpio &= ~VT1724_PRODIGY192_CCLK; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - /* set data */ - if (data & (1 << idx)) - gpio |= VT1724_PRODIGY192_CDOUT; - else - gpio &= ~VT1724_PRODIGY192_CDOUT; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - /* raise clock */ - gpio |= VT1724_PRODIGY192_CCLK; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - } -} - -/* - * 4wire ak4114 protocol - reading data - */ -static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, - int idx) -{ - unsigned char data = 0; - - for (; idx >= 0; idx--) { - /* drop clock */ - gpio &= ~VT1724_PRODIGY192_CCLK; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - /* read data */ - if (snd_ice1712_gpio_read(ice) & VT1724_PRODIGY192_CDIN) - data |= (1 << idx); - udelay(1); - /* raise clock */ - gpio |= VT1724_PRODIGY192_CCLK; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - } - return data; -} -/* - * 4wire ak4114 protocol - starting sequence - */ -static unsigned int prodigy192_4wire_start(struct snd_ice1712 *ice) -{ - unsigned int tmp; - - snd_ice1712_save_gpio_status(ice); - tmp = snd_ice1712_gpio_read(ice); - - tmp |= VT1724_PRODIGY192_CCLK; /* high at init */ - tmp &= ~VT1724_PRODIGY192_CS; /* drop chip select */ - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - return tmp; -} - -/* - * 4wire ak4114 protocol - final sequence - */ -static void prodigy192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) -{ - tmp |= VT1724_PRODIGY192_CS; /* raise chip select */ - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - snd_ice1712_restore_gpio_status(ice); -} - -/* - * Write data to addr register of ak4114 - */ -static void prodigy192_ak4114_write(void *private_data, unsigned char addr, - unsigned char data) -{ - struct snd_ice1712 *ice = private_data; - unsigned int tmp, addrdata; - tmp = prodigy192_4wire_start(ice); - addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f); - addrdata = (addrdata << 8) | data; - write_data(ice, tmp, addrdata, 15); - prodigy192_4wire_finish(ice, tmp); -} - -/* - * Read data from addr register of ak4114 - */ -static unsigned char prodigy192_ak4114_read(void *private_data, - unsigned char addr) -{ - struct snd_ice1712 *ice = private_data; - unsigned int tmp; - unsigned char data; - - tmp = prodigy192_4wire_start(ice); - write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7); - data = read_data(ice, tmp, 7); - prodigy192_4wire_finish(ice, tmp); - return data; -} - - -static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *texts[2] = { "Toslink", "Coax" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - - -static int ak4114_input_sw_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char val; - - val = prodigy192_ak4114_read(ice, AK4114_REG_IO1); - /* AK4114_IPS0 bit = 0 -> RX0 = Toslink - * AK4114_IPS0 bit = 1 -> RX1 = Coax - */ - ucontrol->value.enumerated.item[0] = (val & AK4114_IPS0) ? 1 : 0; - return 0; -} - -static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char new, old, itemvalue; - int change; - - old = prodigy192_ak4114_read(ice, AK4114_REG_IO1); - /* AK4114_IPS0 could be any bit */ - itemvalue = (ucontrol->value.enumerated.item[0]) ? 0xff : 0x00; - - new = (itemvalue & AK4114_IPS0) | (old & ~AK4114_IPS0); - change = (new != old); - if (change) - prodigy192_ak4114_write(ice, AK4114_REG_IO1, new); - return change; -} - - -static struct snd_kcontrol_new ak4114_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "MIODIO IEC958 Capture Input", - .info = ak4114_input_sw_info, - .get = ak4114_input_sw_get, - .put = ak4114_input_sw_put, - - } -}; - - -static int prodigy192_ak4114_init(struct snd_ice1712 *ice) -{ - static const unsigned char ak4114_init_vals[] = { - AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, - /* ice1724 expects I2S and provides clock, - * DEM0 disables the deemphasis filter - */ - AK4114_DIF_I24I2S | AK4114_DEM0 , - AK4114_TX1E, - AK4114_EFH_1024 | AK4114_DIT, /* default input RX0 */ - 0, - 0 - }; - static const unsigned char ak4114_init_txcsb[] = { - 0x41, 0x02, 0x2c, 0x00, 0x00 - }; - struct prodigy192_spec *spec = ice->spec; - int err; - - err = snd_ak4114_create(ice->card, - prodigy192_ak4114_read, - prodigy192_ak4114_write, - ak4114_init_vals, ak4114_init_txcsb, - ice, &spec->ak4114); - if (err < 0) - return err; - /* AK4114 in Prodigy192 cannot detect external rate correctly. - * No reason to stop capture stream due to incorrect checks */ - spec->ak4114->check_flags = AK4114_CHECK_NO_RATE; - return 0; -} - -static void stac9460_proc_regs_read(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) -{ - struct snd_ice1712 *ice = entry->private_data; - int reg, val; - /* registers 0x0 - 0x14 */ - for (reg = 0; reg <= 0x15; reg++) { - val = stac9460_get(ice, reg); - snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val); - } -} - - -static void stac9460_proc_init(struct snd_ice1712 *ice) -{ - struct snd_info_entry *entry; - if (!snd_card_proc_new(ice->card, "stac9460_codec", &entry)) - snd_info_set_text_ops(entry, ice, stac9460_proc_regs_read); -} - - -static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) -{ - struct prodigy192_spec *spec = ice->spec; - unsigned int i; - int err; - - for (i = 0; i < ARRAY_SIZE(stac_controls); i++) { - err = snd_ctl_add(ice->card, - snd_ctl_new1(&stac_controls[i], ice)); - if (err < 0) - return err; - } - if (spec->ak4114) { - /* ak4114 is connected */ - for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) { - err = snd_ctl_add(ice->card, - snd_ctl_new1(&ak4114_controls[i], - ice)); - if (err < 0) - return err; - } - err = snd_ak4114_build(spec->ak4114, - NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */ - ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); - if (err < 0) - return err; - } - stac9460_proc_init(ice); - return 0; -} - -/* - * check for presence of MI/ODI/O add-on card with digital inputs - */ -static int prodigy192_miodio_exists(struct snd_ice1712 *ice) -{ - - unsigned char orig_value; - const unsigned char test_data = 0xd1; /* random value */ - unsigned char addr = AK4114_REG_INT0_MASK; /* random SAFE address */ - int exists = 0; - - orig_value = prodigy192_ak4114_read(ice, addr); - prodigy192_ak4114_write(ice, addr, test_data); - if (prodigy192_ak4114_read(ice, addr) == test_data) { - /* ak4114 seems to communicate, apparently exists */ - /* writing back original value */ - prodigy192_ak4114_write(ice, addr, orig_value); - exists = 1; - } - return exists; -} - -/* - * initialize the chip - */ -static int __devinit prodigy192_init(struct snd_ice1712 *ice) -{ - static const unsigned short stac_inits_prodigy[] = { - STAC946X_RESET, 0, - STAC946X_MASTER_CLOCKING, 0x11, -/* STAC946X_MASTER_VOLUME, 0, - STAC946X_LF_VOLUME, 0, - STAC946X_RF_VOLUME, 0, - STAC946X_LR_VOLUME, 0, - STAC946X_RR_VOLUME, 0, - STAC946X_CENTER_VOLUME, 0, - STAC946X_LFE_VOLUME, 0,*/ - (unsigned short)-1 - }; - const unsigned short *p; - int err = 0; - struct prodigy192_spec *spec; - - /* prodigy 192 */ - ice->num_total_dacs = 6; - ice->num_total_adcs = 2; - ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */ - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - ice->spec = spec; - mutex_init(&spec->mute_mutex); - - /* initialize codec */ - p = stac_inits_prodigy; - for (; *p != (unsigned short)-1; p += 2) - stac9460_put(ice, p[0], p[1]); - ice->gpio.set_pro_rate = stac9460_set_rate_val; - - /* MI/ODI/O add on card with AK4114 */ - if (prodigy192_miodio_exists(ice)) { - err = prodigy192_ak4114_init(ice); - /* from this moment if err = 0 then - * spec->ak4114 should not be null - */ - snd_printdd("AK4114 initialized with status %d\n", err); - } else - snd_printdd("AK4114 not found\n"); - if (err < 0) - return err; - - return 0; -} - - -/* - * Aureon boards don't provide the EEPROM data except for the vendor IDs. - * hence the driver needs to sets up it properly. - */ - -static unsigned char prodigy71_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x6a, /* 49MHz crystal, mpu401, - * spdif-in+ 1 stereo ADC, - * 3 stereo DACs - */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = ~(VT1724_PRODIGY192_CDIN >> 8) , - [ICE_EEP2_GPIO_DIR2] = 0xbf, - [ICE_EEP2_GPIO_MASK] = 0x00, - [ICE_EEP2_GPIO_MASK1] = 0x00, - [ICE_EEP2_GPIO_MASK2] = 0x00, - [ICE_EEP2_GPIO_STATE] = 0x00, - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x10, /* GPIO20: 0 = CD drive dig. input - * passthrough, - * 1 = SPDIF-OUT from ice1724 - */ -}; - - -/* entry point */ -struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_PRODIGY192VE, - .name = "Audiotrak Prodigy 192", - .model = "prodigy192", - .chip_init = prodigy192_init, - .build_controls = prodigy192_add_controls, - .eeprom_size = sizeof(prodigy71_eeprom), - .eeprom_data = prodigy71_eeprom, - }, - { } /* terminator */ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/prodigy192.h b/ANDROID_3.4.5/sound/pci/ice1712/prodigy192.h deleted file mode 100644 index 16a53b45..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/prodigy192.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __SOUND_PRODIGY192_H -#define __SOUND_PRODIGY192_H - -#define PRODIGY192_DEVICE_DESC "{AudioTrak,Prodigy 192}," -#define PRODIGY192_STAC9460_ADDR 0x54 - -#define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */ -/* - * AudioTrak Prodigy192 GPIO definitions for MI/ODI/O card with - * AK4114 (SPDIF-IN) - */ -#define VT1724_PRODIGY192_CS (1 << 8) /* GPIO8, pin 75 */ -#define VT1724_PRODIGY192_CCLK (1 << 9) /* GPIO9, pin 76 */ -#define VT1724_PRODIGY192_CDOUT (1 << 10) /* GPIO10, pin 77 */ -#define VT1724_PRODIGY192_CDIN (1 << 11) /* GPIO11, pin 86 */ - -extern struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[]; - -#endif /* __SOUND_PRODIGY192_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.c b/ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.c deleted file mode 100644 index 764cc93d..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.c +++ /dev/null @@ -1,1236 +0,0 @@ -/* - * ALSA driver for ICEnsemble VT1724 (Envy24HT) - * - * Lowlevel functions for Audiotrak Prodigy 7.1 Hifi - * based on pontis.c - * - * Copyright (c) 2007 Julian Scheel - * Copyright (c) 2007 allank - * Copyright (c) 2004 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "prodigy_hifi.h" - -struct prodigy_hifi_spec { - unsigned short master[2]; - unsigned short vol[8]; -}; - -/* I2C addresses */ -#define WM_DEV 0x34 - -/* WM8776 registers */ -#define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */ -#define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */ -#define WM_HP_MASTER 0x02 /* headphone master (both channels), - override LLR */ -#define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */ -#define WM_DAC_ATTEN_R 0x04 -#define WM_DAC_MASTER 0x05 -#define WM_PHASE_SWAP 0x06 /* DAC phase swap */ -#define WM_DAC_CTRL1 0x07 -#define WM_DAC_MUTE 0x08 -#define WM_DAC_CTRL2 0x09 -#define WM_DAC_INT 0x0a -#define WM_ADC_INT 0x0b -#define WM_MASTER_CTRL 0x0c -#define WM_POWERDOWN 0x0d -#define WM_ADC_ATTEN_L 0x0e -#define WM_ADC_ATTEN_R 0x0f -#define WM_ALC_CTRL1 0x10 -#define WM_ALC_CTRL2 0x11 -#define WM_ALC_CTRL3 0x12 -#define WM_NOISE_GATE 0x13 -#define WM_LIMITER 0x14 -#define WM_ADC_MUX 0x15 -#define WM_OUT_MUX 0x16 -#define WM_RESET 0x17 - -/* Analog Recording Source :- Mic, LineIn, CD/Video, */ - -/* implement capture source select control for WM8776 */ - -#define WM_AIN1 "AIN1" -#define WM_AIN2 "AIN2" -#define WM_AIN3 "AIN3" -#define WM_AIN4 "AIN4" -#define WM_AIN5 "AIN5" - -/* GPIO pins of envy24ht connected to wm8766 */ -#define WM8766_SPI_CLK (1<<17) /* CLK, Pin97 on ICE1724 */ -#define WM8766_SPI_MD (1<<16) /* DATA VT1724 -> WM8766, Pin96 */ -#define WM8766_SPI_ML (1<<18) /* Latch, Pin98 */ - -/* WM8766 registers */ -#define WM8766_DAC_CTRL 0x02 /* DAC Control */ -#define WM8766_INT_CTRL 0x03 /* Interface Control */ -#define WM8766_DAC_CTRL2 0x09 -#define WM8766_DAC_CTRL3 0x0a -#define WM8766_RESET 0x1f -#define WM8766_LDA1 0x00 -#define WM8766_LDA2 0x04 -#define WM8766_LDA3 0x06 -#define WM8766_RDA1 0x01 -#define WM8766_RDA2 0x05 -#define WM8766_RDA3 0x07 -#define WM8766_MUTE1 0x0C -#define WM8766_MUTE2 0x0F - - -/* - * Prodigy HD2 - */ -#define AK4396_ADDR 0x00 -#define AK4396_CSN (1 << 8) /* CSN->GPIO8, pin 75 */ -#define AK4396_CCLK (1 << 9) /* CCLK->GPIO9, pin 76 */ -#define AK4396_CDTI (1 << 10) /* CDTI->GPIO10, pin 77 */ - -/* ak4396 registers */ -#define AK4396_CTRL1 0x00 -#define AK4396_CTRL2 0x01 -#define AK4396_CTRL3 0x02 -#define AK4396_LCH_ATT 0x03 -#define AK4396_RCH_ATT 0x04 - - -/* - * get the current register value of WM codec - */ -static unsigned short wm_get(struct snd_ice1712 *ice, int reg) -{ - reg <<= 1; - return ((unsigned short)ice->akm[0].images[reg] << 8) | - ice->akm[0].images[reg + 1]; -} - -/* - * set the register value of WM codec and remember it - */ -static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val) -{ - unsigned short cval; - cval = (reg << 9) | val; - snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff); -} - -static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val) -{ - wm_put_nocache(ice, reg, val); - reg <<= 1; - ice->akm[0].images[reg] = val >> 8; - ice->akm[0].images[reg + 1] = val; -} - -/* - * write data in the SPI mode - */ - -static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val) -{ - unsigned int tmp = snd_ice1712_gpio_read(ice); - if (val) - tmp |= bit; - else - tmp &= ~bit; - snd_ice1712_gpio_write(ice, tmp); -} - -/* - * SPI implementation for WM8766 codec - only writing supported, no readback - */ - -static void wm8766_spi_send_word(struct snd_ice1712 *ice, unsigned int data) -{ - int i; - for (i = 0; i < 16; i++) { - set_gpio_bit(ice, WM8766_SPI_CLK, 0); - udelay(1); - set_gpio_bit(ice, WM8766_SPI_MD, data & 0x8000); - udelay(1); - set_gpio_bit(ice, WM8766_SPI_CLK, 1); - udelay(1); - data <<= 1; - } -} - -static void wm8766_spi_write(struct snd_ice1712 *ice, unsigned int reg, - unsigned int data) -{ - unsigned int block; - - snd_ice1712_gpio_set_dir(ice, WM8766_SPI_MD| - WM8766_SPI_CLK|WM8766_SPI_ML); - snd_ice1712_gpio_set_mask(ice, ~(WM8766_SPI_MD| - WM8766_SPI_CLK|WM8766_SPI_ML)); - /* latch must be low when writing */ - set_gpio_bit(ice, WM8766_SPI_ML, 0); - block = (reg << 9) | (data & 0x1ff); - wm8766_spi_send_word(ice, block); /* REGISTER ADDRESS */ - /* release latch */ - set_gpio_bit(ice, WM8766_SPI_ML, 1); - udelay(1); - /* restore */ - snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask); - snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); -} - - -/* - * serial interface for ak4396 - only writing supported, no readback - */ - -static void ak4396_send_word(struct snd_ice1712 *ice, unsigned int data) -{ - int i; - for (i = 0; i < 16; i++) { - set_gpio_bit(ice, AK4396_CCLK, 0); - udelay(1); - set_gpio_bit(ice, AK4396_CDTI, data & 0x8000); - udelay(1); - set_gpio_bit(ice, AK4396_CCLK, 1); - udelay(1); - data <<= 1; - } -} - -static void ak4396_write(struct snd_ice1712 *ice, unsigned int reg, - unsigned int data) -{ - unsigned int block; - - snd_ice1712_gpio_set_dir(ice, AK4396_CSN|AK4396_CCLK|AK4396_CDTI); - snd_ice1712_gpio_set_mask(ice, ~(AK4396_CSN|AK4396_CCLK|AK4396_CDTI)); - /* latch must be low when writing */ - set_gpio_bit(ice, AK4396_CSN, 0); - block = ((AK4396_ADDR & 0x03) << 14) | (1 << 13) | - ((reg & 0x1f) << 8) | (data & 0xff); - ak4396_send_word(ice, block); /* REGISTER ADDRESS */ - /* release latch */ - set_gpio_bit(ice, AK4396_CSN, 1); - udelay(1); - /* restore */ - snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask); - snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); -} - - -/* - * ak4396 mixers - */ - - - -/* - * DAC volume attenuation mixer control (-64dB to 0dB) - */ - -static int ak4396_dac_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; /* mute */ - uinfo->value.integer.max = 0xFF; /* linear */ - return 0; -} - -static int ak4396_dac_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct prodigy_hifi_spec *spec = ice->spec; - int i; - - for (i = 0; i < 2; i++) - ucontrol->value.integer.value[i] = spec->vol[i]; - - return 0; -} - -static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct prodigy_hifi_spec *spec = ice->spec; - int i; - int change = 0; - - mutex_lock(&ice->gpio_mutex); - for (i = 0; i < 2; i++) { - if (ucontrol->value.integer.value[i] != spec->vol[i]) { - spec->vol[i] = ucontrol->value.integer.value[i]; - ak4396_write(ice, AK4396_LCH_ATT + i, - spec->vol[i] & 0xff); - change = 1; - } - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - -static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); - -static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Front Playback Volume", - .info = ak4396_dac_vol_info, - .get = ak4396_dac_vol_get, - .put = ak4396_dac_vol_put, - .tlv = { .p = db_scale_wm_dac }, - }, -}; - - -/* --------------- */ - -/* - * Logarithmic volume values for WM87*6 - * Computed as 20 * Log10(255 / x) - */ -static const unsigned char wm_vol[256] = { - 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23, - 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, - 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, - 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 -}; - -#define WM_VOL_MAX (sizeof(wm_vol) - 1) -#define WM_VOL_MUTE 0x8000 - - -#define DAC_0dB 0xff -#define DAC_RES 128 -#define DAC_MIN (DAC_0dB - DAC_RES) - - -static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, - unsigned short vol, unsigned short master) -{ - unsigned char nvol; - - if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) - nvol = 0; - else { - nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128) - & WM_VOL_MAX; - nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff; - } - - wm_put(ice, index, nvol); - wm_put_nocache(ice, index, 0x100 | nvol); -} - -static void wm8766_set_vol(struct snd_ice1712 *ice, unsigned int index, - unsigned short vol, unsigned short master) -{ - unsigned char nvol; - - if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) - nvol = 0; - else { - nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128) - & WM_VOL_MAX; - nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff; - } - - wm8766_spi_write(ice, index, (0x0100 | nvol)); -} - - -/* - * DAC volume attenuation mixer control (-64dB to 0dB) - */ - -static int wm_dac_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; /* mute */ - uinfo->value.integer.max = DAC_RES; /* 0dB, 0.5dB step */ - return 0; -} - -static int wm_dac_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct prodigy_hifi_spec *spec = ice->spec; - int i; - - for (i = 0; i < 2; i++) - ucontrol->value.integer.value[i] = - spec->vol[2 + i] & ~WM_VOL_MUTE; - return 0; -} - -static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct prodigy_hifi_spec *spec = ice->spec; - int i, idx, change = 0; - - mutex_lock(&ice->gpio_mutex); - for (i = 0; i < 2; i++) { - if (ucontrol->value.integer.value[i] != spec->vol[2 + i]) { - idx = WM_DAC_ATTEN_L + i; - spec->vol[2 + i] &= WM_VOL_MUTE; - spec->vol[2 + i] |= ucontrol->value.integer.value[i]; - wm_set_vol(ice, idx, spec->vol[2 + i], spec->master[i]); - change = 1; - } - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - - -/* - * WM8766 DAC volume attenuation mixer control - */ -static int wm8766_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - int voices = kcontrol->private_value >> 8; - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = voices; - uinfo->value.integer.min = 0; /* mute */ - uinfo->value.integer.max = DAC_RES; /* 0dB */ - return 0; -} - -static int wm8766_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct prodigy_hifi_spec *spec = ice->spec; - int i, ofs, voices; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xff; - for (i = 0; i < voices; i++) - ucontrol->value.integer.value[i] = spec->vol[ofs + i]; - return 0; -} - -static int wm8766_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct prodigy_hifi_spec *spec = ice->spec; - int i, idx, ofs, voices; - int change = 0; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xff; - mutex_lock(&ice->gpio_mutex); - for (i = 0; i < voices; i++) { - if (ucontrol->value.integer.value[i] != spec->vol[ofs + i]) { - idx = WM8766_LDA1 + ofs + i; - spec->vol[ofs + i] &= WM_VOL_MUTE; - spec->vol[ofs + i] |= ucontrol->value.integer.value[i]; - wm8766_set_vol(ice, idx, - spec->vol[ofs + i], spec->master[i]); - change = 1; - } - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - -/* - * Master volume attenuation mixer control / applied to WM8776+WM8766 - */ -static int wm_master_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = DAC_RES; - return 0; -} - -static int wm_master_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct prodigy_hifi_spec *spec = ice->spec; - int i; - for (i = 0; i < 2; i++) - ucontrol->value.integer.value[i] = spec->master[i]; - return 0; -} - -static int wm_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - struct prodigy_hifi_spec *spec = ice->spec; - int ch, change = 0; - - mutex_lock(&ice->gpio_mutex); - for (ch = 0; ch < 2; ch++) { - if (ucontrol->value.integer.value[ch] != spec->master[ch]) { - spec->master[ch] = ucontrol->value.integer.value[ch]; - - /* Apply to front DAC */ - wm_set_vol(ice, WM_DAC_ATTEN_L + ch, - spec->vol[2 + ch], spec->master[ch]); - - wm8766_set_vol(ice, WM8766_LDA1 + ch, - spec->vol[0 + ch], spec->master[ch]); - - wm8766_set_vol(ice, WM8766_LDA2 + ch, - spec->vol[4 + ch], spec->master[ch]); - - wm8766_set_vol(ice, WM8766_LDA3 + ch, - spec->vol[6 + ch], spec->master[ch]); - change = 1; - } - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - - -/* KONSTI */ - -static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char* texts[32] = { - "NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2, - WM_AIN3, WM_AIN1 "+" WM_AIN3, WM_AIN2 "+" WM_AIN3, - WM_AIN1 "+" WM_AIN2 "+" WM_AIN3, - WM_AIN4, WM_AIN1 "+" WM_AIN4, WM_AIN2 "+" WM_AIN4, - WM_AIN1 "+" WM_AIN2 "+" WM_AIN4, - WM_AIN3 "+" WM_AIN4, WM_AIN1 "+" WM_AIN3 "+" WM_AIN4, - WM_AIN2 "+" WM_AIN3 "+" WM_AIN4, - WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4, - WM_AIN5, WM_AIN1 "+" WM_AIN5, WM_AIN2 "+" WM_AIN5, - WM_AIN1 "+" WM_AIN2 "+" WM_AIN5, - WM_AIN3 "+" WM_AIN5, WM_AIN1 "+" WM_AIN3 "+" WM_AIN5, - WM_AIN2 "+" WM_AIN3 "+" WM_AIN5, - WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN5, - WM_AIN4 "+" WM_AIN5, WM_AIN1 "+" WM_AIN4 "+" WM_AIN5, - WM_AIN2 "+" WM_AIN4 "+" WM_AIN5, - WM_AIN1 "+" WM_AIN2 "+" WM_AIN4 "+" WM_AIN5, - WM_AIN3 "+" WM_AIN4 "+" WM_AIN5, - WM_AIN1 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5, - WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5, - WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5 - }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 32; - if (uinfo->value.enumerated.item > 31) - uinfo->value.enumerated.item = 31; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; -} - -static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - mutex_lock(&ice->gpio_mutex); - ucontrol->value.integer.value[0] = wm_get(ice, WM_ADC_MUX) & 0x1f; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short oval, nval; - int change = 0; - - mutex_lock(&ice->gpio_mutex); - oval = wm_get(ice, WM_ADC_MUX); - nval = (oval & 0xe0) | ucontrol->value.integer.value[0]; - if (nval != oval) { - wm_put(ice, WM_ADC_MUX, nval); - change = 1; - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - -/* KONSTI */ - -/* - * ADC gain mixer control (-64dB to 0dB) - */ - -#define ADC_0dB 0xcf -#define ADC_RES 128 -#define ADC_MIN (ADC_0dB - ADC_RES) - -static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; /* mute (-64dB) */ - uinfo->value.integer.max = ADC_RES; /* 0dB, 0.5dB step */ - return 0; -} - -static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short val; - int i; - - mutex_lock(&ice->gpio_mutex); - for (i = 0; i < 2; i++) { - val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff; - val = val > ADC_MIN ? (val - ADC_MIN) : 0; - ucontrol->value.integer.value[i] = val; - } - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short ovol, nvol; - int i, idx, change = 0; - - mutex_lock(&ice->gpio_mutex); - for (i = 0; i < 2; i++) { - nvol = ucontrol->value.integer.value[i]; - nvol = nvol ? (nvol + ADC_MIN) : 0; - idx = WM_ADC_ATTEN_L + i; - ovol = wm_get(ice, idx) & 0xff; - if (ovol != nvol) { - wm_put(ice, idx, nvol); - change = 1; - } - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - -/* - * ADC input mux mixer control - */ -#define wm_adc_mux_info snd_ctl_boolean_mono_info - -static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int bit = kcontrol->private_value; - - mutex_lock(&ice->gpio_mutex); - ucontrol->value.integer.value[0] = - (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int bit = kcontrol->private_value; - unsigned short oval, nval; - int change; - - mutex_lock(&ice->gpio_mutex); - nval = oval = wm_get(ice, WM_ADC_MUX); - if (ucontrol->value.integer.value[0]) - nval |= (1 << bit); - else - nval &= ~(1 << bit); - change = nval != oval; - if (change) { - wm_put(ice, WM_ADC_MUX, nval); - } - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -/* - * Analog bypass (In -> Out) - */ -#define wm_bypass_info snd_ctl_boolean_mono_info - -static int wm_bypass_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - mutex_lock(&ice->gpio_mutex); - ucontrol->value.integer.value[0] = - (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_bypass_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short val, oval; - int change = 0; - - mutex_lock(&ice->gpio_mutex); - val = oval = wm_get(ice, WM_OUT_MUX); - if (ucontrol->value.integer.value[0]) - val |= 0x04; - else - val &= ~0x04; - if (val != oval) { - wm_put(ice, WM_OUT_MUX, val); - change = 1; - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - -/* - * Left/Right swap - */ -#define wm_chswap_info snd_ctl_boolean_mono_info - -static int wm_chswap_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - mutex_lock(&ice->gpio_mutex); - ucontrol->value.integer.value[0] = - (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90; - mutex_unlock(&ice->gpio_mutex); - return 0; -} - -static int wm_chswap_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned short val, oval; - int change = 0; - - mutex_lock(&ice->gpio_mutex); - oval = wm_get(ice, WM_DAC_CTRL1); - val = oval & 0x0f; - if (ucontrol->value.integer.value[0]) - val |= 0x60; - else - val |= 0x90; - if (val != oval) { - wm_put(ice, WM_DAC_CTRL1, val); - wm_put_nocache(ice, WM_DAC_CTRL1, val); - change = 1; - } - mutex_unlock(&ice->gpio_mutex); - return change; -} - - -/* - * mixers - */ - -static struct snd_kcontrol_new prodigy_hifi_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Master Playback Volume", - .info = wm_master_vol_info, - .get = wm_master_vol_get, - .put = wm_master_vol_put, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Front Playback Volume", - .info = wm_dac_vol_info, - .get = wm_dac_vol_get, - .put = wm_dac_vol_put, - .tlv = { .p = db_scale_wm_dac }, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Rear Playback Volume", - .info = wm8766_vol_info, - .get = wm8766_vol_get, - .put = wm8766_vol_put, - .private_value = (2 << 8) | 0, - .tlv = { .p = db_scale_wm_dac }, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Center Playback Volume", - .info = wm8766_vol_info, - .get = wm8766_vol_get, - .put = wm8766_vol_put, - .private_value = (1 << 8) | 4, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "LFE Playback Volume", - .info = wm8766_vol_info, - .get = wm8766_vol_get, - .put = wm8766_vol_put, - .private_value = (1 << 8) | 5, - .tlv = { .p = db_scale_wm_dac } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Side Playback Volume", - .info = wm8766_vol_info, - .get = wm8766_vol_get, - .put = wm8766_vol_put, - .private_value = (2 << 8) | 6, - .tlv = { .p = db_scale_wm_dac }, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Capture Volume", - .info = wm_adc_vol_info, - .get = wm_adc_vol_get, - .put = wm_adc_vol_put, - .tlv = { .p = db_scale_wm_dac }, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "CD Capture Switch", - .info = wm_adc_mux_info, - .get = wm_adc_mux_get, - .put = wm_adc_mux_put, - .private_value = 0, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Line Capture Switch", - .info = wm_adc_mux_info, - .get = wm_adc_mux_get, - .put = wm_adc_mux_put, - .private_value = 1, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Bypass Switch", - .info = wm_bypass_info, - .get = wm_bypass_get, - .put = wm_bypass_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Swap Output Channels", - .info = wm_chswap_info, - .get = wm_chswap_get, - .put = wm_chswap_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Capture Source", - .info = wm_adc_mux_enum_info, - .get = wm_adc_mux_enum_get, - .put = wm_adc_mux_enum_put, - }, -}; - -/* - * WM codec registers - */ -static void wm_proc_regs_write(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) -{ - struct snd_ice1712 *ice = entry->private_data; - char line[64]; - unsigned int reg, val; - mutex_lock(&ice->gpio_mutex); - while (!snd_info_get_line(buffer, line, sizeof(line))) { - if (sscanf(line, "%x %x", ®, &val) != 2) - continue; - if (reg <= 0x17 && val <= 0xffff) - wm_put(ice, reg, val); - } - mutex_unlock(&ice->gpio_mutex); -} - -static void wm_proc_regs_read(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) -{ - struct snd_ice1712 *ice = entry->private_data; - int reg, val; - - mutex_lock(&ice->gpio_mutex); - for (reg = 0; reg <= 0x17; reg++) { - val = wm_get(ice, reg); - snd_iprintf(buffer, "%02x = %04x\n", reg, val); - } - mutex_unlock(&ice->gpio_mutex); -} - -static void wm_proc_init(struct snd_ice1712 *ice) -{ - struct snd_info_entry *entry; - if (!snd_card_proc_new(ice->card, "wm_codec", &entry)) { - snd_info_set_text_ops(entry, ice, wm_proc_regs_read); - entry->mode |= S_IWUSR; - entry->c.text.write = wm_proc_regs_write; - } -} - -static int __devinit prodigy_hifi_add_controls(struct snd_ice1712 *ice) -{ - unsigned int i; - int err; - - for (i = 0; i < ARRAY_SIZE(prodigy_hifi_controls); i++) { - err = snd_ctl_add(ice->card, - snd_ctl_new1(&prodigy_hifi_controls[i], ice)); - if (err < 0) - return err; - } - - wm_proc_init(ice); - - return 0; -} - -static int __devinit prodigy_hd2_add_controls(struct snd_ice1712 *ice) -{ - unsigned int i; - int err; - - for (i = 0; i < ARRAY_SIZE(prodigy_hd2_controls); i++) { - err = snd_ctl_add(ice->card, - snd_ctl_new1(&prodigy_hd2_controls[i], ice)); - if (err < 0) - return err; - } - - wm_proc_init(ice); - - return 0; -} - - -/* - * initialize the chip - */ -static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice) -{ - static unsigned short wm_inits[] = { - /* These come first to reduce init pop noise */ - WM_ADC_MUX, 0x0003, /* ADC mute */ - /* 0x00c0 replaced by 0x0003 */ - - WM_DAC_MUTE, 0x0001, /* DAC softmute */ - WM_DAC_CTRL1, 0x0000, /* DAC mute */ - - WM_POWERDOWN, 0x0008, /* All power-up except HP */ - WM_RESET, 0x0000, /* reset */ - }; - static unsigned short wm_inits2[] = { - WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */ - WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */ - WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */ - WM_DAC_CTRL1, 0x0090, /* DAC L/R */ - WM_OUT_MUX, 0x0001, /* OUT DAC */ - WM_HP_ATTEN_L, 0x0179, /* HP 0dB */ - WM_HP_ATTEN_R, 0x0179, /* HP 0dB */ - WM_DAC_ATTEN_L, 0x0000, /* DAC 0dB */ - WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */ - WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */ - WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */ - WM_PHASE_SWAP, 0x0000, /* phase normal */ -#if 0 - WM_DAC_MASTER, 0x0100, /* DAC master muted */ -#endif - WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */ - WM_ADC_ATTEN_L, 0x0000, /* ADC muted */ - WM_ADC_ATTEN_R, 0x0000, /* ADC muted */ -#if 1 - WM_ALC_CTRL1, 0x007b, /* */ - WM_ALC_CTRL2, 0x0000, /* */ - WM_ALC_CTRL3, 0x0000, /* */ - WM_NOISE_GATE, 0x0000, /* */ -#endif - WM_DAC_MUTE, 0x0000, /* DAC unmute */ - WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */ - }; - static unsigned short wm8766_inits[] = { - WM8766_RESET, 0x0000, - WM8766_DAC_CTRL, 0x0120, - WM8766_INT_CTRL, 0x0022, /* I2S Normal Mode, 24 bit */ - WM8766_DAC_CTRL2, 0x0001, - WM8766_DAC_CTRL3, 0x0080, - WM8766_LDA1, 0x0100, - WM8766_LDA2, 0x0100, - WM8766_LDA3, 0x0100, - WM8766_RDA1, 0x0100, - WM8766_RDA2, 0x0100, - WM8766_RDA3, 0x0100, - WM8766_MUTE1, 0x0000, - WM8766_MUTE2, 0x0000, - }; - - struct prodigy_hifi_spec *spec; - unsigned int i; - - ice->vt1720 = 0; - ice->vt1724 = 1; - - ice->num_total_dacs = 8; - ice->num_total_adcs = 1; - - /* HACK - use this as the SPDIF source. - * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten - */ - ice->gpio.saved[0] = 0; - /* to remember the register values */ - - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - if (! ice->akm) - return -ENOMEM; - ice->akm_codecs = 1; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - ice->spec = spec; - - /* initialize WM8776 codec */ - for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2) - wm_put(ice, wm_inits[i], wm_inits[i+1]); - schedule_timeout_uninterruptible(1); - for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2) - wm_put(ice, wm_inits2[i], wm_inits2[i+1]); - - /* initialize WM8766 codec */ - for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2) - wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]); - - - return 0; -} - - -/* - * initialize the chip - */ -static void ak4396_init(struct snd_ice1712 *ice) -{ - static unsigned short ak4396_inits[] = { - AK4396_CTRL1, 0x87, /* I2S Normal Mode, 24 bit */ - AK4396_CTRL2, 0x02, - AK4396_CTRL3, 0x00, - AK4396_LCH_ATT, 0x00, - AK4396_RCH_ATT, 0x00, - }; - - unsigned int i; - - /* initialize ak4396 codec */ - /* reset codec */ - ak4396_write(ice, AK4396_CTRL1, 0x86); - msleep(100); - ak4396_write(ice, AK4396_CTRL1, 0x87); - - for (i = 0; i < ARRAY_SIZE(ak4396_inits); i += 2) - ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]); -} - -#ifdef CONFIG_PM -static int prodigy_hd2_resume(struct snd_ice1712 *ice) -{ - /* initialize ak4396 codec and restore previous mixer volumes */ - struct prodigy_hifi_spec *spec = ice->spec; - int i; - mutex_lock(&ice->gpio_mutex); - ak4396_init(ice); - for (i = 0; i < 2; i++) - ak4396_write(ice, AK4396_LCH_ATT + i, spec->vol[i] & 0xff); - mutex_unlock(&ice->gpio_mutex); - return 0; -} -#endif - -static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice) -{ - struct prodigy_hifi_spec *spec; - - ice->vt1720 = 0; - ice->vt1724 = 1; - - ice->num_total_dacs = 1; - ice->num_total_adcs = 1; - - /* HACK - use this as the SPDIF source. - * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten - */ - ice->gpio.saved[0] = 0; - /* to remember the register values */ - - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - if (! ice->akm) - return -ENOMEM; - ice->akm_codecs = 1; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - ice->spec = spec; - -#ifdef CONFIG_PM - ice->pm_resume = &prodigy_hd2_resume; - ice->pm_suspend_enabled = 1; -#endif - - ak4396_init(ice); - - return 0; -} - - -static unsigned char prodigy71hifi_eeprom[] __devinitdata = { - 0x4b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */ - 0x80, /* ACLINK: I2S */ - 0xfc, /* I2S: vol, 96k, 24bit, 192k */ - 0xc3, /* SPDIF: out-en, out-int, spdif-in */ - 0xff, /* GPIO_DIR */ - 0xff, /* GPIO_DIR1 */ - 0x5f, /* GPIO_DIR2 */ - 0x00, /* GPIO_MASK */ - 0x00, /* GPIO_MASK1 */ - 0x00, /* GPIO_MASK2 */ - 0x00, /* GPIO_STATE */ - 0x00, /* GPIO_STATE1 */ - 0x00, /* GPIO_STATE2 */ -}; - -static unsigned char prodigyhd2_eeprom[] __devinitdata = { - 0x4b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */ - 0x80, /* ACLINK: I2S */ - 0xfc, /* I2S: vol, 96k, 24bit, 192k */ - 0xc3, /* SPDIF: out-en, out-int, spdif-in */ - 0xff, /* GPIO_DIR */ - 0xff, /* GPIO_DIR1 */ - 0x5f, /* GPIO_DIR2 */ - 0x00, /* GPIO_MASK */ - 0x00, /* GPIO_MASK1 */ - 0x00, /* GPIO_MASK2 */ - 0x00, /* GPIO_STATE */ - 0x00, /* GPIO_STATE1 */ - 0x00, /* GPIO_STATE2 */ -}; - -static unsigned char fortissimo4_eeprom[] __devinitdata = { - 0x43, /* SYSCONF: clock 512, ADC, 4DACs */ - 0x80, /* ACLINK: I2S */ - 0xfc, /* I2S: vol, 96k, 24bit, 192k */ - 0xc1, /* SPDIF: out-en, out-int */ - 0xff, /* GPIO_DIR */ - 0xff, /* GPIO_DIR1 */ - 0x5f, /* GPIO_DIR2 */ - 0x00, /* GPIO_MASK */ - 0x00, /* GPIO_MASK1 */ - 0x00, /* GPIO_MASK2 */ - 0x00, /* GPIO_STATE */ - 0x00, /* GPIO_STATE1 */ - 0x00, /* GPIO_STATE2 */ -}; - -/* entry point */ -struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_PRODIGY_HIFI, - .name = "Audiotrak Prodigy 7.1 HiFi", - .model = "prodigy71hifi", - .chip_init = prodigy_hifi_init, - .build_controls = prodigy_hifi_add_controls, - .eeprom_size = sizeof(prodigy71hifi_eeprom), - .eeprom_data = prodigy71hifi_eeprom, - .driver = "Prodigy71HIFI", - }, - { - .subvendor = VT1724_SUBDEVICE_PRODIGY_HD2, - .name = "Audiotrak Prodigy HD2", - .model = "prodigyhd2", - .chip_init = prodigy_hd2_init, - .build_controls = prodigy_hd2_add_controls, - .eeprom_size = sizeof(prodigyhd2_eeprom), - .eeprom_data = prodigyhd2_eeprom, - .driver = "Prodigy71HD2", - }, - { - .subvendor = VT1724_SUBDEVICE_FORTISSIMO4, - .name = "Hercules Fortissimo IV", - .model = "fortissimo4", - .chip_init = prodigy_hifi_init, - .build_controls = prodigy_hifi_add_controls, - .eeprom_size = sizeof(fortissimo4_eeprom), - .eeprom_data = fortissimo4_eeprom, - .driver = "Fortissimo4", - }, - { } /* terminator */ -}; - diff --git a/ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.h b/ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.h deleted file mode 100644 index a4415d45..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __SOUND_PRODIGY_HIFI_H -#define __SOUND_PRODIGY_HIFI_H - -/* - * ALSA driver for VIA VT1724 (Envy24HT) - * - * Lowlevel functions for Audiotrak Prodigy Hifi - * - * Copyright (c) 2004 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define PRODIGY_HIFI_DEVICE_DESC "{Audiotrak,Prodigy 7.1 HIFI},"\ - "{Audiotrak Prodigy HD2},"\ - "{Hercules Fortissimo IV}," - -#define VT1724_SUBDEVICE_PRODIGY_HIFI 0x38315441 /* PRODIGY 7.1 HIFI */ -#define VT1724_SUBDEVICE_PRODIGY_HD2 0x37315441 /* PRODIGY HD2 */ -#define VT1724_SUBDEVICE_FORTISSIMO4 0x81160100 /* Fortissimo IV */ - - -extern struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[]; - -#endif /* __SOUND_PRODIGY_HIFI_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/quartet.c b/ANDROID_3.4.5/sound/pci/ice1712/quartet.c deleted file mode 100644 index 19486327..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/quartet.c +++ /dev/null @@ -1,1130 +0,0 @@ -/* - * ALSA driver for ICEnsemble VT1724 (Envy24HT) - * - * Lowlevel functions for Infrasonic Quartet - * - * Copyright (c) 2009 Pavel Hofman - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include -#include "quartet.h" - -struct qtet_spec { - struct ak4113 *ak4113; - unsigned int scr; /* system control register */ - unsigned int mcr; /* monitoring control register */ - unsigned int cpld; /* cpld register */ -}; - -struct qtet_kcontrol_private { - unsigned int bit; - void (*set_register)(struct snd_ice1712 *ice, unsigned int val); - unsigned int (*get_register)(struct snd_ice1712 *ice); - unsigned char *texts[2]; -}; - -enum { - IN12_SEL = 0, - IN34_SEL, - AIN34_SEL, - COAX_OUT, - IN12_MON12, - IN12_MON34, - IN34_MON12, - IN34_MON34, - OUT12_MON34, - OUT34_MON12, -}; - -static char *ext_clock_names[3] = {"IEC958 In", "Word Clock 1xFS", - "Word Clock 256xFS"}; - -/* chip address on I2C bus */ -#define AK4113_ADDR 0x26 /* S/PDIF receiver */ - -/* chip address on SPI bus */ -#define AK4620_ADDR 0x02 /* ADC/DAC */ - - -/* - * GPIO pins - */ - -/* GPIO0 - O - DATA0, def. 0 */ -#define GPIO_D0 (1<<0) -/* GPIO1 - I/O - DATA1, Jack Detect Input0 (0:present, 1:missing), def. 1 */ -#define GPIO_D1_JACKDTC0 (1<<1) -/* GPIO2 - I/O - DATA2, Jack Detect Input1 (0:present, 1:missing), def. 1 */ -#define GPIO_D2_JACKDTC1 (1<<2) -/* GPIO3 - I/O - DATA3, def. 1 */ -#define GPIO_D3 (1<<3) -/* GPIO4 - I/O - DATA4, SPI CDTO, def. 1 */ -#define GPIO_D4_SPI_CDTO (1<<4) -/* GPIO5 - I/O - DATA5, SPI CCLK, def. 1 */ -#define GPIO_D5_SPI_CCLK (1<<5) -/* GPIO6 - I/O - DATA6, Cable Detect Input (0:detected, 1:not detected */ -#define GPIO_D6_CD (1<<6) -/* GPIO7 - I/O - DATA7, Device Detect Input (0:detected, 1:not detected */ -#define GPIO_D7_DD (1<<7) -/* GPIO8 - O - CPLD Chip Select, def. 1 */ -#define GPIO_CPLD_CSN (1<<8) -/* GPIO9 - O - CPLD register read/write (0:write, 1:read), def. 0 */ -#define GPIO_CPLD_RW (1<<9) -/* GPIO10 - O - SPI Chip Select for CODEC#0, def. 1 */ -#define GPIO_SPI_CSN0 (1<<10) -/* GPIO11 - O - SPI Chip Select for CODEC#1, def. 1 */ -#define GPIO_SPI_CSN1 (1<<11) -/* GPIO12 - O - Ex. Register Output Enable (0:enable, 1:disable), def. 1, - * init 0 */ -#define GPIO_EX_GPIOE (1<<12) -/* GPIO13 - O - Ex. Register0 Chip Select for System Control Register, - * def. 1 */ -#define GPIO_SCR (1<<13) -/* GPIO14 - O - Ex. Register1 Chip Select for Monitor Control Register, - * def. 1 */ -#define GPIO_MCR (1<<14) - -#define GPIO_SPI_ALL (GPIO_D4_SPI_CDTO | GPIO_D5_SPI_CCLK |\ - GPIO_SPI_CSN0 | GPIO_SPI_CSN1) - -#define GPIO_DATA_MASK (GPIO_D0 | GPIO_D1_JACKDTC0 | \ - GPIO_D2_JACKDTC1 | GPIO_D3 | \ - GPIO_D4_SPI_CDTO | GPIO_D5_SPI_CCLK | \ - GPIO_D6_CD | GPIO_D7_DD) - -/* System Control Register GPIO_SCR data bits */ -/* Mic/Line select relay (0:line, 1:mic) */ -#define SCR_RELAY GPIO_D0 -/* Phantom power drive control (0:5V, 1:48V) */ -#define SCR_PHP_V GPIO_D1_JACKDTC0 -/* H/W mute control (0:Normal, 1:Mute) */ -#define SCR_MUTE GPIO_D2_JACKDTC1 -/* Phantom power control (0:Phantom on, 1:off) */ -#define SCR_PHP GPIO_D3 -/* Analog input 1/2 Source Select */ -#define SCR_AIN12_SEL0 GPIO_D4_SPI_CDTO -#define SCR_AIN12_SEL1 GPIO_D5_SPI_CCLK -/* Analog input 3/4 Source Select (0:line, 1:hi-z) */ -#define SCR_AIN34_SEL GPIO_D6_CD -/* Codec Power Down (0:power down, 1:normal) */ -#define SCR_CODEC_PDN GPIO_D7_DD - -#define SCR_AIN12_LINE (0) -#define SCR_AIN12_MIC (SCR_AIN12_SEL0) -#define SCR_AIN12_LOWCUT (SCR_AIN12_SEL1 | SCR_AIN12_SEL0) - -/* Monitor Control Register GPIO_MCR data bits */ -/* Input 1/2 to Monitor 1/2 (0:off, 1:on) */ -#define MCR_IN12_MON12 GPIO_D0 -/* Input 1/2 to Monitor 3/4 (0:off, 1:on) */ -#define MCR_IN12_MON34 GPIO_D1_JACKDTC0 -/* Input 3/4 to Monitor 1/2 (0:off, 1:on) */ -#define MCR_IN34_MON12 GPIO_D2_JACKDTC1 -/* Input 3/4 to Monitor 3/4 (0:off, 1:on) */ -#define MCR_IN34_MON34 GPIO_D3 -/* Output to Monitor 1/2 (0:off, 1:on) */ -#define MCR_OUT34_MON12 GPIO_D4_SPI_CDTO -/* Output to Monitor 3/4 (0:off, 1:on) */ -#define MCR_OUT12_MON34 GPIO_D5_SPI_CCLK - -/* CPLD Register DATA bits */ -/* Clock Rate Select */ -#define CPLD_CKS0 GPIO_D0 -#define CPLD_CKS1 GPIO_D1_JACKDTC0 -#define CPLD_CKS2 GPIO_D2_JACKDTC1 -/* Sync Source Select (0:Internal, 1:External) */ -#define CPLD_SYNC_SEL GPIO_D3 -/* Word Clock FS Select (0:FS, 1:256FS) */ -#define CPLD_WORD_SEL GPIO_D4_SPI_CDTO -/* Coaxial Output Source (IS-Link) (0:SPDIF, 1:I2S) */ -#define CPLD_COAX_OUT GPIO_D5_SPI_CCLK -/* Input 1/2 Source Select (0:Analog12, 1:An34) */ -#define CPLD_IN12_SEL GPIO_D6_CD -/* Input 3/4 Source Select (0:Analog34, 1:Digital In) */ -#define CPLD_IN34_SEL GPIO_D7_DD - -/* internal clock (CPLD_SYNC_SEL = 0) options */ -#define CPLD_CKS_44100HZ (0) -#define CPLD_CKS_48000HZ (CPLD_CKS0) -#define CPLD_CKS_88200HZ (CPLD_CKS1) -#define CPLD_CKS_96000HZ (CPLD_CKS1 | CPLD_CKS0) -#define CPLD_CKS_176400HZ (CPLD_CKS2) -#define CPLD_CKS_192000HZ (CPLD_CKS2 | CPLD_CKS0) - -#define CPLD_CKS_MASK (CPLD_CKS0 | CPLD_CKS1 | CPLD_CKS2) - -/* external clock (CPLD_SYNC_SEL = 1) options */ -/* external clock - SPDIF */ -#define CPLD_EXT_SPDIF (0 | CPLD_SYNC_SEL) -/* external clock - WordClock 1xfs */ -#define CPLD_EXT_WORDCLOCK_1FS (CPLD_CKS1 | CPLD_SYNC_SEL) -/* external clock - WordClock 256xfs */ -#define CPLD_EXT_WORDCLOCK_256FS (CPLD_CKS1 | CPLD_WORD_SEL |\ - CPLD_SYNC_SEL) - -#define EXT_SPDIF_TYPE 0 -#define EXT_WORDCLOCK_1FS_TYPE 1 -#define EXT_WORDCLOCK_256FS_TYPE 2 - -#define AK4620_DFS0 (1<<0) -#define AK4620_DFS1 (1<<1) -#define AK4620_CKS0 (1<<2) -#define AK4620_CKS1 (1<<3) -/* Clock and Format Control register */ -#define AK4620_DFS_REG 0x02 - -/* Deem and Volume Control register */ -#define AK4620_DEEMVOL_REG 0x03 -#define AK4620_SMUTE (1<<7) - -/* - * Conversion from int value to its binary form. Used for debugging. - * The output buffer must be allocated prior to calling the function. - */ -static char *get_binary(char *buffer, int value) -{ - int i, j, pos; - pos = 0; - for (i = 0; i < 4; ++i) { - for (j = 0; j < 8; ++j) { - if (value & (1 << (31-(i*8 + j)))) - buffer[pos] = '1'; - else - buffer[pos] = '0'; - pos++; - } - if (i < 3) { - buffer[pos] = ' '; - pos++; - } - } - buffer[pos] = '\0'; - return buffer; -} - -/* - * Initial setup of the conversion array GPIO <-> rate - */ -static unsigned int qtet_rates[] = { - 44100, 48000, 88200, - 96000, 176400, 192000, -}; - -static unsigned int cks_vals[] = { - CPLD_CKS_44100HZ, CPLD_CKS_48000HZ, CPLD_CKS_88200HZ, - CPLD_CKS_96000HZ, CPLD_CKS_176400HZ, CPLD_CKS_192000HZ, -}; - -static struct snd_pcm_hw_constraint_list qtet_rates_info = { - .count = ARRAY_SIZE(qtet_rates), - .list = qtet_rates, - .mask = 0, -}; - -static void qtet_ak4113_write(void *private_data, unsigned char reg, - unsigned char val) -{ - snd_vt1724_write_i2c((struct snd_ice1712 *)private_data, AK4113_ADDR, - reg, val); -} - -static unsigned char qtet_ak4113_read(void *private_data, unsigned char reg) -{ - return snd_vt1724_read_i2c((struct snd_ice1712 *)private_data, - AK4113_ADDR, reg); -} - - -/* - * AK4620 section - */ - -/* - * Write data to addr register of ak4620 - */ -static void qtet_akm_write(struct snd_akm4xxx *ak, int chip, - unsigned char addr, unsigned char data) -{ - unsigned int tmp, orig_dir; - int idx; - unsigned int addrdata; - struct snd_ice1712 *ice = ak->private_data[0]; - - if (snd_BUG_ON(chip < 0 || chip >= 4)) - return; - /*printk(KERN_DEBUG "Writing to AK4620: chip=%d, addr=0x%x, - data=0x%x\n", chip, addr, data);*/ - orig_dir = ice->gpio.get_dir(ice); - ice->gpio.set_dir(ice, orig_dir | GPIO_SPI_ALL); - /* set mask - only SPI bits */ - ice->gpio.set_mask(ice, ~GPIO_SPI_ALL); - - tmp = ice->gpio.get_data(ice); - /* high all */ - tmp |= GPIO_SPI_ALL; - ice->gpio.set_data(ice, tmp); - udelay(100); - /* drop chip select */ - if (chip) - /* CODEC 1 */ - tmp &= ~GPIO_SPI_CSN1; - else - tmp &= ~GPIO_SPI_CSN0; - ice->gpio.set_data(ice, tmp); - udelay(100); - - /* build I2C address + data byte */ - addrdata = (AK4620_ADDR << 6) | 0x20 | (addr & 0x1f); - addrdata = (addrdata << 8) | data; - for (idx = 15; idx >= 0; idx--) { - /* drop clock */ - tmp &= ~GPIO_D5_SPI_CCLK; - ice->gpio.set_data(ice, tmp); - udelay(100); - /* set data */ - if (addrdata & (1 << idx)) - tmp |= GPIO_D4_SPI_CDTO; - else - tmp &= ~GPIO_D4_SPI_CDTO; - ice->gpio.set_data(ice, tmp); - udelay(100); - /* raise clock */ - tmp |= GPIO_D5_SPI_CCLK; - ice->gpio.set_data(ice, tmp); - udelay(100); - } - /* all back to 1 */ - tmp |= GPIO_SPI_ALL; - ice->gpio.set_data(ice, tmp); - udelay(100); - - /* return all gpios to non-writable */ - ice->gpio.set_mask(ice, 0xffffff); - /* restore GPIOs direction */ - ice->gpio.set_dir(ice, orig_dir); -} - -static void qtet_akm_set_regs(struct snd_akm4xxx *ak, unsigned char addr, - unsigned char mask, unsigned char value) -{ - unsigned char tmp; - int chip; - for (chip = 0; chip < ak->num_chips; chip++) { - tmp = snd_akm4xxx_get(ak, chip, addr); - /* clear the bits */ - tmp &= ~mask; - /* set the new bits */ - tmp |= value; - snd_akm4xxx_write(ak, chip, addr, tmp); - } -} - -/* - * change the rate of AK4620 - */ -static void qtet_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) -{ - unsigned char ak4620_dfs; - - if (rate == 0) /* no hint - S/PDIF input is master or the new spdif - input rate undetected, simply return */ - return; - - /* adjust DFS on codecs - see datasheet */ - if (rate > 108000) - ak4620_dfs = AK4620_DFS1 | AK4620_CKS1; - else if (rate > 54000) - ak4620_dfs = AK4620_DFS0 | AK4620_CKS0; - else - ak4620_dfs = 0; - - /* set new value */ - qtet_akm_set_regs(ak, AK4620_DFS_REG, AK4620_DFS0 | AK4620_DFS1 | - AK4620_CKS0 | AK4620_CKS1, ak4620_dfs); -} - -#define AK_CONTROL(xname, xch) { .name = xname, .num_channels = xch } - -#define PCM_12_PLAYBACK_VOLUME "PCM 1/2 Playback Volume" -#define PCM_34_PLAYBACK_VOLUME "PCM 3/4 Playback Volume" -#define PCM_12_CAPTURE_VOLUME "PCM 1/2 Capture Volume" -#define PCM_34_CAPTURE_VOLUME "PCM 3/4 Capture Volume" - -static const struct snd_akm4xxx_dac_channel qtet_dac[] = { - AK_CONTROL(PCM_12_PLAYBACK_VOLUME, 2), - AK_CONTROL(PCM_34_PLAYBACK_VOLUME, 2), -}; - -static const struct snd_akm4xxx_adc_channel qtet_adc[] = { - AK_CONTROL(PCM_12_CAPTURE_VOLUME, 2), - AK_CONTROL(PCM_34_CAPTURE_VOLUME, 2), -}; - -static struct snd_akm4xxx akm_qtet_dac __devinitdata = { - .type = SND_AK4620, - .num_dacs = 4, /* DAC1 - Output 12 - */ - .num_adcs = 4, /* ADC1 - Input 12 - */ - .ops = { - .write = qtet_akm_write, - .set_rate_val = qtet_akm_set_rate_val, - }, - .dac_info = qtet_dac, - .adc_info = qtet_adc, -}; - -/* Communication routines with the CPLD */ - - -/* Writes data to external register reg, both reg and data are - * GPIO representations */ -static void reg_write(struct snd_ice1712 *ice, unsigned int reg, - unsigned int data) -{ - unsigned int tmp; - - mutex_lock(&ice->gpio_mutex); - /* set direction of used GPIOs*/ - /* all outputs */ - tmp = 0x00ffff; - ice->gpio.set_dir(ice, tmp); - /* mask - writable bits */ - ice->gpio.set_mask(ice, ~(tmp)); - /* write the data */ - tmp = ice->gpio.get_data(ice); - tmp &= ~GPIO_DATA_MASK; - tmp |= data; - ice->gpio.set_data(ice, tmp); - udelay(100); - /* drop output enable */ - tmp &= ~GPIO_EX_GPIOE; - ice->gpio.set_data(ice, tmp); - udelay(100); - /* drop the register gpio */ - tmp &= ~reg; - ice->gpio.set_data(ice, tmp); - udelay(100); - /* raise the register GPIO */ - tmp |= reg; - ice->gpio.set_data(ice, tmp); - udelay(100); - - /* raise all data gpios */ - tmp |= GPIO_DATA_MASK; - ice->gpio.set_data(ice, tmp); - /* mask - immutable bits */ - ice->gpio.set_mask(ice, 0xffffff); - /* outputs only 8-15 */ - ice->gpio.set_dir(ice, 0x00ff00); - mutex_unlock(&ice->gpio_mutex); -} - -static unsigned int get_scr(struct snd_ice1712 *ice) -{ - struct qtet_spec *spec = ice->spec; - return spec->scr; -} - -static unsigned int get_mcr(struct snd_ice1712 *ice) -{ - struct qtet_spec *spec = ice->spec; - return spec->mcr; -} - -static unsigned int get_cpld(struct snd_ice1712 *ice) -{ - struct qtet_spec *spec = ice->spec; - return spec->cpld; -} - -static void set_scr(struct snd_ice1712 *ice, unsigned int val) -{ - struct qtet_spec *spec = ice->spec; - reg_write(ice, GPIO_SCR, val); - spec->scr = val; -} - -static void set_mcr(struct snd_ice1712 *ice, unsigned int val) -{ - struct qtet_spec *spec = ice->spec; - reg_write(ice, GPIO_MCR, val); - spec->mcr = val; -} - -static void set_cpld(struct snd_ice1712 *ice, unsigned int val) -{ - struct qtet_spec *spec = ice->spec; - reg_write(ice, GPIO_CPLD_CSN, val); - spec->cpld = val; -} -#ifdef CONFIG_PROC_FS -static void proc_regs_read(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) -{ - struct snd_ice1712 *ice = entry->private_data; - char bin_buffer[36]; - - snd_iprintf(buffer, "SCR: %s\n", get_binary(bin_buffer, - get_scr(ice))); - snd_iprintf(buffer, "MCR: %s\n", get_binary(bin_buffer, - get_mcr(ice))); - snd_iprintf(buffer, "CPLD: %s\n", get_binary(bin_buffer, - get_cpld(ice))); -} - -static void proc_init(struct snd_ice1712 *ice) -{ - struct snd_info_entry *entry; - if (!snd_card_proc_new(ice->card, "quartet", &entry)) - snd_info_set_text_ops(entry, ice, proc_regs_read); -} -#else /* !CONFIG_PROC_FS */ -static void proc_init(struct snd_ice1712 *ice) {} -#endif - -static int qtet_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int val; - val = get_scr(ice) & SCR_MUTE; - ucontrol->value.integer.value[0] = (val) ? 0 : 1; - return 0; -} - -static int qtet_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int old, new, smute; - old = get_scr(ice) & SCR_MUTE; - if (ucontrol->value.integer.value[0]) { - /* unmute */ - new = 0; - /* un-smuting DAC */ - smute = 0; - } else { - /* mute */ - new = SCR_MUTE; - /* smuting DAC */ - smute = AK4620_SMUTE; - } - if (old != new) { - struct snd_akm4xxx *ak = ice->akm; - set_scr(ice, (get_scr(ice) & ~SCR_MUTE) | new); - /* set smute */ - qtet_akm_set_regs(ak, AK4620_DEEMVOL_REG, AK4620_SMUTE, smute); - return 1; - } - /* no change */ - return 0; -} - -static int qtet_ain12_enum_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *texts[3] = {"Line In 1/2", "Mic", "Mic + Low-cut"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = ARRAY_SIZE(texts); - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - - return 0; -} - -static int qtet_ain12_sw_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int val, result; - val = get_scr(ice) & (SCR_AIN12_SEL1 | SCR_AIN12_SEL0); - switch (val) { - case SCR_AIN12_LINE: - result = 0; - break; - case SCR_AIN12_MIC: - result = 1; - break; - case SCR_AIN12_LOWCUT: - result = 2; - break; - default: - /* BUG - no other combinations allowed */ - snd_BUG(); - result = 0; - } - ucontrol->value.integer.value[0] = result; - return 0; -} - -static int qtet_ain12_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int old, new, tmp, masked_old; - old = new = get_scr(ice); - masked_old = old & (SCR_AIN12_SEL1 | SCR_AIN12_SEL0); - tmp = ucontrol->value.integer.value[0]; - if (tmp == 2) - tmp = 3; /* binary 10 is not supported */ - tmp <<= 4; /* shifting to SCR_AIN12_SEL0 */ - if (tmp != masked_old) { - /* change requested */ - switch (tmp) { - case SCR_AIN12_LINE: - new = old & ~(SCR_AIN12_SEL1 | SCR_AIN12_SEL0); - set_scr(ice, new); - /* turn off relay */ - new &= ~SCR_RELAY; - set_scr(ice, new); - break; - case SCR_AIN12_MIC: - /* turn on relay */ - new = old | SCR_RELAY; - set_scr(ice, new); - new = (new & ~SCR_AIN12_SEL1) | SCR_AIN12_SEL0; - set_scr(ice, new); - break; - case SCR_AIN12_LOWCUT: - /* turn on relay */ - new = old | SCR_RELAY; - set_scr(ice, new); - new |= SCR_AIN12_SEL1 | SCR_AIN12_SEL0; - set_scr(ice, new); - break; - default: - snd_BUG(); - } - return 1; - } - /* no change */ - return 0; -} - -static int qtet_php_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int val; - /* if phantom voltage =48V, phantom on */ - val = get_scr(ice) & SCR_PHP_V; - ucontrol->value.integer.value[0] = val ? 1 : 0; - return 0; -} - -static int qtet_php_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int old, new; - old = new = get_scr(ice); - if (ucontrol->value.integer.value[0] /* phantom on requested */ - && (~old & SCR_PHP_V)) /* 0 = voltage 5V */ { - /* is off, turn on */ - /* turn voltage on first, = 1 */ - new = old | SCR_PHP_V; - set_scr(ice, new); - /* turn phantom on, = 0 */ - new &= ~SCR_PHP; - set_scr(ice, new); - } else if (!ucontrol->value.integer.value[0] && (old & SCR_PHP_V)) { - /* phantom off requested and 1 = voltage 48V */ - /* is on, turn off */ - /* turn voltage off first, = 0 */ - new = old & ~SCR_PHP_V; - set_scr(ice, new); - /* turn phantom off, = 1 */ - new |= SCR_PHP; - set_scr(ice, new); - } - if (old != new) - return 1; - /* no change */ - return 0; -} - -#define PRIV_SW(xid, xbit, xreg) [xid] = {.bit = xbit,\ - .set_register = set_##xreg,\ - .get_register = get_##xreg, } - - -#define PRIV_ENUM2(xid, xbit, xreg, xtext1, xtext2) [xid] = {.bit = xbit,\ - .set_register = set_##xreg,\ - .get_register = get_##xreg,\ - .texts = {xtext1, xtext2} } - -static struct qtet_kcontrol_private qtet_privates[] = { - PRIV_ENUM2(IN12_SEL, CPLD_IN12_SEL, cpld, "An In 1/2", "An In 3/4"), - PRIV_ENUM2(IN34_SEL, CPLD_IN34_SEL, cpld, "An In 3/4", "IEC958 In"), - PRIV_ENUM2(AIN34_SEL, SCR_AIN34_SEL, scr, "Line In 3/4", "Hi-Z"), - PRIV_ENUM2(COAX_OUT, CPLD_COAX_OUT, cpld, "IEC958", "I2S"), - PRIV_SW(IN12_MON12, MCR_IN12_MON12, mcr), - PRIV_SW(IN12_MON34, MCR_IN12_MON34, mcr), - PRIV_SW(IN34_MON12, MCR_IN34_MON12, mcr), - PRIV_SW(IN34_MON34, MCR_IN34_MON34, mcr), - PRIV_SW(OUT12_MON34, MCR_OUT12_MON34, mcr), - PRIV_SW(OUT34_MON12, MCR_OUT34_MON12, mcr), -}; - -static int qtet_enum_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct qtet_kcontrol_private private = - qtet_privates[kcontrol->private_value]; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = ARRAY_SIZE(private.texts); - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - private.texts[uinfo->value.enumerated.item]); - - return 0; -} - -static int qtet_sw_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct qtet_kcontrol_private private = - qtet_privates[kcontrol->private_value]; - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = - (private.get_register(ice) & private.bit) ? 1 : 0; - return 0; -} - -static int qtet_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct qtet_kcontrol_private private = - qtet_privates[kcontrol->private_value]; - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned int old, new; - old = private.get_register(ice); - if (ucontrol->value.integer.value[0]) - new = old | private.bit; - else - new = old & ~private.bit; - if (old != new) { - private.set_register(ice, new); - return 1; - } - /* no change */ - return 0; -} - -#define qtet_sw_info snd_ctl_boolean_mono_info - -#define QTET_CONTROL(xname, xtype, xpriv) \ - {.iface = SNDRV_CTL_ELEM_IFACE_MIXER,\ - .name = xname,\ - .info = qtet_##xtype##_info,\ - .get = qtet_sw_get,\ - .put = qtet_sw_put,\ - .private_value = xpriv } - -static struct snd_kcontrol_new qtet_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = qtet_sw_info, - .get = qtet_mute_get, - .put = qtet_mute_put, - .private_value = 0 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Phantom Power", - .info = qtet_sw_info, - .get = qtet_php_get, - .put = qtet_php_put, - .private_value = 0 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog In 1/2 Capture Switch", - .info = qtet_ain12_enum_info, - .get = qtet_ain12_sw_get, - .put = qtet_ain12_sw_put, - .private_value = 0 - }, - QTET_CONTROL("Analog In 3/4 Capture Switch", enum, AIN34_SEL), - QTET_CONTROL("PCM In 1/2 Capture Switch", enum, IN12_SEL), - QTET_CONTROL("PCM In 3/4 Capture Switch", enum, IN34_SEL), - QTET_CONTROL("Coax Output Source", enum, COAX_OUT), - QTET_CONTROL("Analog In 1/2 to Monitor 1/2", sw, IN12_MON12), - QTET_CONTROL("Analog In 1/2 to Monitor 3/4", sw, IN12_MON34), - QTET_CONTROL("Analog In 3/4 to Monitor 1/2", sw, IN34_MON12), - QTET_CONTROL("Analog In 3/4 to Monitor 3/4", sw, IN34_MON34), - QTET_CONTROL("Output 1/2 to Monitor 3/4", sw, OUT12_MON34), - QTET_CONTROL("Output 3/4 to Monitor 1/2", sw, OUT34_MON12), -}; - -static char *slave_vols[] __devinitdata = { - PCM_12_PLAYBACK_VOLUME, - PCM_34_PLAYBACK_VOLUME, - NULL -}; - -static __devinitdata -DECLARE_TLV_DB_SCALE(qtet_master_db_scale, -6350, 50, 1); - -static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card, - const char *name) -{ - struct snd_ctl_elem_id sid; - memset(&sid, 0, sizeof(sid)); - /* FIXME: strcpy is bad. */ - strcpy(sid.name, name); - sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - return snd_ctl_find_id(card, &sid); -} - -static void __devinit add_slaves(struct snd_card *card, - struct snd_kcontrol *master, char **list) -{ - for (; *list; list++) { - struct snd_kcontrol *slave = ctl_find(card, *list); - if (slave) - snd_ctl_add_slave(master, slave); - } -} - -static int __devinit qtet_add_controls(struct snd_ice1712 *ice) -{ - struct qtet_spec *spec = ice->spec; - int err, i; - struct snd_kcontrol *vmaster; - err = snd_ice1712_akm4xxx_build_controls(ice); - if (err < 0) - return err; - for (i = 0; i < ARRAY_SIZE(qtet_controls); i++) { - err = snd_ctl_add(ice->card, - snd_ctl_new1(&qtet_controls[i], ice)); - if (err < 0) - return err; - } - - /* Create virtual master control */ - vmaster = snd_ctl_make_virtual_master("Master Playback Volume", - qtet_master_db_scale); - if (!vmaster) - return -ENOMEM; - add_slaves(ice->card, vmaster, slave_vols); - err = snd_ctl_add(ice->card, vmaster); - if (err < 0) - return err; - /* only capture SPDIF over AK4113 */ - err = snd_ak4113_build(spec->ak4113, - ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); - if (err < 0) - return err; - return 0; -} - -static inline int qtet_is_spdif_master(struct snd_ice1712 *ice) -{ - /* CPLD_SYNC_SEL: 0 = internal, 1 = external (i.e. spdif master) */ - return (get_cpld(ice) & CPLD_SYNC_SEL) ? 1 : 0; -} - -static unsigned int qtet_get_rate(struct snd_ice1712 *ice) -{ - int i; - unsigned char result; - - result = get_cpld(ice) & CPLD_CKS_MASK; - for (i = 0; i < ARRAY_SIZE(cks_vals); i++) - if (cks_vals[i] == result) - return qtet_rates[i]; - return 0; -} - -static int get_cks_val(int rate) -{ - int i; - for (i = 0; i < ARRAY_SIZE(qtet_rates); i++) - if (qtet_rates[i] == rate) - return cks_vals[i]; - return 0; -} - -/* setting new rate */ -static void qtet_set_rate(struct snd_ice1712 *ice, unsigned int rate) -{ - unsigned int new; - unsigned char val; - /* switching ice1724 to external clock - supplied by ext. circuits */ - val = inb(ICEMT1724(ice, RATE)); - outb(val | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE)); - - new = (get_cpld(ice) & ~CPLD_CKS_MASK) | get_cks_val(rate); - /* switch to internal clock, drop CPLD_SYNC_SEL */ - new &= ~CPLD_SYNC_SEL; - /* printk(KERN_DEBUG "QT - set_rate: old %x, new %x\n", - get_cpld(ice), new); */ - set_cpld(ice, new); -} - -static inline unsigned char qtet_set_mclk(struct snd_ice1712 *ice, - unsigned int rate) -{ - /* no change in master clock */ - return 0; -} - -/* setting clock to external - SPDIF */ -static int qtet_set_spdif_clock(struct snd_ice1712 *ice, int type) -{ - unsigned int old, new; - - old = new = get_cpld(ice); - new &= ~(CPLD_CKS_MASK | CPLD_WORD_SEL); - switch (type) { - case EXT_SPDIF_TYPE: - new |= CPLD_EXT_SPDIF; - break; - case EXT_WORDCLOCK_1FS_TYPE: - new |= CPLD_EXT_WORDCLOCK_1FS; - break; - case EXT_WORDCLOCK_256FS_TYPE: - new |= CPLD_EXT_WORDCLOCK_256FS; - break; - default: - snd_BUG(); - } - if (old != new) { - set_cpld(ice, new); - /* changed */ - return 1; - } - return 0; -} - -static int qtet_get_spdif_master_type(struct snd_ice1712 *ice) -{ - unsigned int val; - int result; - val = get_cpld(ice); - /* checking only rate/clock-related bits */ - val &= (CPLD_CKS_MASK | CPLD_WORD_SEL | CPLD_SYNC_SEL); - if (!(val & CPLD_SYNC_SEL)) { - /* switched to internal clock, is not any external type */ - result = -1; - } else { - switch (val) { - case (CPLD_EXT_SPDIF): - result = EXT_SPDIF_TYPE; - break; - case (CPLD_EXT_WORDCLOCK_1FS): - result = EXT_WORDCLOCK_1FS_TYPE; - break; - case (CPLD_EXT_WORDCLOCK_256FS): - result = EXT_WORDCLOCK_256FS_TYPE; - break; - default: - /* undefined combination of external clock setup */ - snd_BUG(); - result = 0; - } - } - return result; -} - -/* Called when ak4113 detects change in the input SPDIF stream */ -static void qtet_ak4113_change(struct ak4113 *ak4113, unsigned char c0, - unsigned char c1) -{ - struct snd_ice1712 *ice = ak4113->change_callback_private; - int rate; - if ((qtet_get_spdif_master_type(ice) == EXT_SPDIF_TYPE) && - c1) { - /* only for SPDIF master mode, rate was changed */ - rate = snd_ak4113_external_rate(ak4113); - /* printk(KERN_DEBUG "ak4113 - input rate changed to %d\n", - rate); */ - qtet_akm_set_rate_val(ice->akm, rate); - } -} - -/* - * If clock slaved to SPDIF-IN, setting runtime rate - * to the detected external rate - */ -static void qtet_spdif_in_open(struct snd_ice1712 *ice, - struct snd_pcm_substream *substream) -{ - struct qtet_spec *spec = ice->spec; - struct snd_pcm_runtime *runtime = substream->runtime; - int rate; - - if (qtet_get_spdif_master_type(ice) != EXT_SPDIF_TYPE) - /* not external SPDIF, no rate limitation */ - return; - /* only external SPDIF can detect incoming sample rate */ - rate = snd_ak4113_external_rate(spec->ak4113); - if (rate >= runtime->hw.rate_min && rate <= runtime->hw.rate_max) { - runtime->hw.rate_min = rate; - runtime->hw.rate_max = rate; - } -} - -/* - * initialize the chip - */ -static int __devinit qtet_init(struct snd_ice1712 *ice) -{ - static const unsigned char ak4113_init_vals[] = { - /* AK4113_REG_PWRDN */ AK4113_RST | AK4113_PWN | - AK4113_OCKS0 | AK4113_OCKS1, - /* AK4113_REQ_FORMAT */ AK4113_DIF_I24I2S | AK4113_VTX | - AK4113_DEM_OFF | AK4113_DEAU, - /* AK4113_REG_IO0 */ AK4113_OPS2 | AK4113_TXE | - AK4113_XTL_24_576M, - /* AK4113_REG_IO1 */ AK4113_EFH_1024LRCLK | AK4113_IPS(0), - /* AK4113_REG_INT0_MASK */ 0, - /* AK4113_REG_INT1_MASK */ 0, - /* AK4113_REG_DATDTS */ 0, - }; - int err; - struct qtet_spec *spec; - struct snd_akm4xxx *ak; - unsigned char val; - - /* switching ice1724 to external clock - supplied by ext. circuits */ - val = inb(ICEMT1724(ice, RATE)); - outb(val | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE)); - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - /* qtet is clocked by Xilinx array */ - ice->hw_rates = &qtet_rates_info; - ice->is_spdif_master = qtet_is_spdif_master; - ice->get_rate = qtet_get_rate; - ice->set_rate = qtet_set_rate; - ice->set_mclk = qtet_set_mclk; - ice->set_spdif_clock = qtet_set_spdif_clock; - ice->get_spdif_master_type = qtet_get_spdif_master_type; - ice->ext_clock_names = ext_clock_names; - ice->ext_clock_count = ARRAY_SIZE(ext_clock_names); - /* since Qtet can detect correct SPDIF-in rate, all streams can be - * limited to this specific rate */ - ice->spdif.ops.open = ice->pro_open = qtet_spdif_in_open; - ice->spec = spec; - - /* Mute Off */ - /* SCR Initialize*/ - /* keep codec power down first */ - set_scr(ice, SCR_PHP); - udelay(1); - /* codec power up */ - set_scr(ice, SCR_PHP | SCR_CODEC_PDN); - - /* MCR Initialize */ - set_mcr(ice, 0); - - /* CPLD Initialize */ - set_cpld(ice, 0); - - - ice->num_total_dacs = 2; - ice->num_total_adcs = 2; - - ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL); - ak = ice->akm; - if (!ak) - return -ENOMEM; - /* only one codec with two chips */ - ice->akm_codecs = 1; - err = snd_ice1712_akm4xxx_init(ak, &akm_qtet_dac, NULL, ice); - if (err < 0) - return err; - err = snd_ak4113_create(ice->card, - qtet_ak4113_read, - qtet_ak4113_write, - ak4113_init_vals, - ice, &spec->ak4113); - if (err < 0) - return err; - /* callback for codecs rate setting */ - spec->ak4113->change_callback = qtet_ak4113_change; - spec->ak4113->change_callback_private = ice; - /* AK41143 in Quartet can detect external rate correctly - * (i.e. check_flags = 0) */ - spec->ak4113->check_flags = 0; - - proc_init(ice); - - qtet_set_rate(ice, 44100); - return 0; -} - -static unsigned char qtet_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x28, /* clock 256(24MHz), mpu401, 1xADC, - 1xDACs, SPDIF in */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0x78, /* 96k, 24bit, 192k */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, in, out-ext */ - [ICE_EEP2_GPIO_DIR] = 0x00, /* 0-7 inputs, switched to output - only during output operations */ - [ICE_EEP2_GPIO_DIR1] = 0xff, /* 8-15 outputs */ - [ICE_EEP2_GPIO_DIR2] = 0x00, - [ICE_EEP2_GPIO_MASK] = 0xff, /* changed only for OUT operations */ - [ICE_EEP2_GPIO_MASK1] = 0x00, - [ICE_EEP2_GPIO_MASK2] = 0xff, - - [ICE_EEP2_GPIO_STATE] = 0x00, /* inputs */ - [ICE_EEP2_GPIO_STATE1] = 0x7d, /* all 1, but GPIO_CPLD_RW - and GPIO15 always zero */ - [ICE_EEP2_GPIO_STATE2] = 0x00, /* inputs */ -}; - -/* entry point */ -struct snd_ice1712_card_info snd_vt1724_qtet_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_QTET, - .name = "Infrasonic Quartet", - .model = "quartet", - .chip_init = qtet_init, - .build_controls = qtet_add_controls, - .eeprom_size = sizeof(qtet_eeprom), - .eeprom_data = qtet_eeprom, - }, - { } /* terminator */ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/quartet.h b/ANDROID_3.4.5/sound/pci/ice1712/quartet.h deleted file mode 100644 index 80809b72..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/quartet.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __SOUND_QTET_H -#define __SOUND_QTET_H - -#define QTET_DEVICE_DESC "{Infrasonic,Quartet}," - -#define VT1724_SUBDEVICE_QTET 0x30305349 /* Infrasonic Quartet */ - -extern struct snd_ice1712_card_info snd_vt1724_qtet_cards[]; - -#endif /* __SOUND_QTET_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/revo.c b/ANDROID_3.4.5/sound/pci/ice1712/revo.c deleted file mode 100644 index b508bb36..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/revo.c +++ /dev/null @@ -1,633 +0,0 @@ -/* - * ALSA driver for ICEnsemble ICE1712 (Envy24) - * - * Lowlevel functions for M-Audio Audiophile 192, Revolution 7.1 and 5.1 - * - * Copyright (c) 2003 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "revo.h" - -/* a non-standard I2C device for revo51 */ -struct revo51_spec { - struct snd_i2c_device *dev; - struct snd_pt2258 *pt2258; -}; - -static void revo_i2s_mclk_changed(struct snd_ice1712 *ice) -{ - /* assert PRST# to converters; MT05 bit 7 */ - outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD)); - mdelay(5); - /* deassert PRST# */ - outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD)); -} - -/* - * change the rate of Envy24HT, AK4355 and AK4381 - */ -static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) -{ - unsigned char old, tmp, dfs; - int reg, shift; - - if (rate == 0) /* no hint - S/PDIF input is master, simply return */ - return; - - /* adjust DFS on codecs */ - if (rate > 96000) - dfs = 2; - else if (rate > 48000) - dfs = 1; - else - dfs = 0; - - if (ak->type == SND_AK4355 || ak->type == SND_AK4358) { - reg = 2; - shift = 4; - } else { - reg = 1; - shift = 3; - } - tmp = snd_akm4xxx_get(ak, 0, reg); - old = (tmp >> shift) & 0x03; - if (old == dfs) - return; - - /* reset DFS */ - snd_akm4xxx_reset(ak, 1); - tmp = snd_akm4xxx_get(ak, 0, reg); - tmp &= ~(0x03 << shift); - tmp |= dfs << shift; - /* snd_akm4xxx_write(ak, 0, reg, tmp); */ - snd_akm4xxx_set(ak, 0, reg, tmp); /* value is written in reset(0) */ - snd_akm4xxx_reset(ak, 0); -} - -/* - * I2C access to the PT2258 volume controller on GPIO 6/7 (Revolution 5.1) - */ - -static void revo_i2c_start(struct snd_i2c_bus *bus) -{ - struct snd_ice1712 *ice = bus->private_data; - snd_ice1712_save_gpio_status(ice); -} - -static void revo_i2c_stop(struct snd_i2c_bus *bus) -{ - struct snd_ice1712 *ice = bus->private_data; - snd_ice1712_restore_gpio_status(ice); -} - -static void revo_i2c_direction(struct snd_i2c_bus *bus, int clock, int data) -{ - struct snd_ice1712 *ice = bus->private_data; - unsigned int mask, val; - - val = 0; - if (clock) - val |= VT1724_REVO_I2C_CLOCK; /* write SCL */ - if (data) - val |= VT1724_REVO_I2C_DATA; /* write SDA */ - mask = VT1724_REVO_I2C_CLOCK | VT1724_REVO_I2C_DATA; - ice->gpio.direction &= ~mask; - ice->gpio.direction |= val; - snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); - snd_ice1712_gpio_set_mask(ice, ~mask); -} - -static void revo_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data) -{ - struct snd_ice1712 *ice = bus->private_data; - unsigned int val = 0; - - if (clk) - val |= VT1724_REVO_I2C_CLOCK; - if (data) - val |= VT1724_REVO_I2C_DATA; - snd_ice1712_gpio_write_bits(ice, - VT1724_REVO_I2C_DATA | - VT1724_REVO_I2C_CLOCK, val); - udelay(5); -} - -static int revo_i2c_getdata(struct snd_i2c_bus *bus, int ack) -{ - struct snd_ice1712 *ice = bus->private_data; - int bit; - - if (ack) - udelay(5); - bit = snd_ice1712_gpio_read_bits(ice, VT1724_REVO_I2C_DATA) ? 1 : 0; - return bit; -} - -static struct snd_i2c_bit_ops revo51_bit_ops = { - .start = revo_i2c_start, - .stop = revo_i2c_stop, - .direction = revo_i2c_direction, - .setlines = revo_i2c_setlines, - .getdata = revo_i2c_getdata, -}; - -static int revo51_i2c_init(struct snd_ice1712 *ice, - struct snd_pt2258 *pt) -{ - struct revo51_spec *spec; - int err; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - ice->spec = spec; - - /* create the I2C bus */ - err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c); - if (err < 0) - return err; - - ice->i2c->private_data = ice; - ice->i2c->hw_ops.bit = &revo51_bit_ops; - - /* create the I2C device */ - err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, &spec->dev); - if (err < 0) - return err; - - pt->card = ice->card; - pt->i2c_bus = ice->i2c; - pt->i2c_dev = spec->dev; - spec->pt2258 = pt; - - snd_pt2258_reset(pt); - - return 0; -} - -/* - * initialize the chips on M-Audio Revolution cards - */ - -#define AK_DAC(xname,xch) { .name = xname, .num_channels = xch } - -static const struct snd_akm4xxx_dac_channel revo71_front[] = { - { - .name = "PCM Playback Volume", - .num_channels = 2, - /* front channels DAC supports muting */ - .switch_name = "PCM Playback Switch", - }, -}; - -static const struct snd_akm4xxx_dac_channel revo71_surround[] = { - AK_DAC("PCM Center Playback Volume", 1), - AK_DAC("PCM LFE Playback Volume", 1), - AK_DAC("PCM Side Playback Volume", 2), - AK_DAC("PCM Rear Playback Volume", 2), -}; - -static const struct snd_akm4xxx_dac_channel revo51_dac[] = { - AK_DAC("PCM Playback Volume", 2), - AK_DAC("PCM Center Playback Volume", 1), - AK_DAC("PCM LFE Playback Volume", 1), - AK_DAC("PCM Rear Playback Volume", 2), - AK_DAC("PCM Headphone Volume", 2), -}; - -static const char *revo51_adc_input_names[] = { - "Mic", - "Line", - "CD", - NULL -}; - -static const struct snd_akm4xxx_adc_channel revo51_adc[] = { - { - .name = "PCM Capture Volume", - .switch_name = "PCM Capture Switch", - .num_channels = 2, - .input_names = revo51_adc_input_names - }, -}; - -static struct snd_akm4xxx akm_revo_front __devinitdata = { - .type = SND_AK4381, - .num_dacs = 2, - .ops = { - .set_rate_val = revo_set_rate_val - }, - .dac_info = revo71_front, -}; - -static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { - .caddr = 1, - .cif = 0, - .data_mask = VT1724_REVO_CDOUT, - .clk_mask = VT1724_REVO_CCLK, - .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, - .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2, - .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, - .add_flags = VT1724_REVO_CCLK, /* high at init */ - .mask_flags = 0, -}; - -static struct snd_akm4xxx akm_revo_surround __devinitdata = { - .type = SND_AK4355, - .idx_offset = 1, - .num_dacs = 6, - .ops = { - .set_rate_val = revo_set_rate_val - }, - .dac_info = revo71_surround, -}; - -static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { - .caddr = 3, - .cif = 0, - .data_mask = VT1724_REVO_CDOUT, - .clk_mask = VT1724_REVO_CCLK, - .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, - .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS1, - .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, - .add_flags = VT1724_REVO_CCLK, /* high at init */ - .mask_flags = 0, -}; - -static struct snd_akm4xxx akm_revo51 __devinitdata = { - .type = SND_AK4358, - .num_dacs = 8, - .ops = { - .set_rate_val = revo_set_rate_val - }, - .dac_info = revo51_dac, -}; - -static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { - .caddr = 2, - .cif = 0, - .data_mask = VT1724_REVO_CDOUT, - .clk_mask = VT1724_REVO_CCLK, - .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1, - .cs_addr = VT1724_REVO_CS1, - .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1, - .add_flags = VT1724_REVO_CCLK, /* high at init */ - .mask_flags = 0, -}; - -static struct snd_akm4xxx akm_revo51_adc __devinitdata = { - .type = SND_AK5365, - .num_adcs = 2, - .adc_info = revo51_adc, -}; - -static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { - .caddr = 2, - .cif = 0, - .data_mask = VT1724_REVO_CDOUT, - .clk_mask = VT1724_REVO_CCLK, - .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1, - .cs_addr = VT1724_REVO_CS0, - .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1, - .add_flags = VT1724_REVO_CCLK, /* high at init */ - .mask_flags = 0, -}; - -static struct snd_pt2258 ptc_revo51_volume; - -/* AK4358 for AP192 DAC, AK5385A for ADC */ -static void ap192_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) -{ - struct snd_ice1712 *ice = ak->private_data[0]; - int dfs; - - revo_set_rate_val(ak, rate); - - /* reset CKS */ - snd_ice1712_gpio_write_bits(ice, 1 << 8, rate > 96000 ? 1 << 8 : 0); - /* reset DFS pins of AK5385A for ADC, too */ - if (rate > 96000) - dfs = 2; - else if (rate > 48000) - dfs = 1; - else - dfs = 0; - snd_ice1712_gpio_write_bits(ice, 3 << 9, dfs << 9); - /* reset ADC */ - snd_ice1712_gpio_write_bits(ice, 1 << 11, 0); - snd_ice1712_gpio_write_bits(ice, 1 << 11, 1 << 11); -} - -static const struct snd_akm4xxx_dac_channel ap192_dac[] = { - AK_DAC("PCM Playback Volume", 2) -}; - -static struct snd_akm4xxx akm_ap192 __devinitdata = { - .type = SND_AK4358, - .num_dacs = 2, - .ops = { - .set_rate_val = ap192_set_rate_val - }, - .dac_info = ap192_dac, -}; - -static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { - .caddr = 2, - .cif = 0, - .data_mask = VT1724_REVO_CDOUT, - .clk_mask = VT1724_REVO_CCLK, - .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1, - .cs_addr = VT1724_REVO_CS1, - .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1, - .add_flags = VT1724_REVO_CCLK, /* high at init */ - .mask_flags = 0, -}; - -/* AK4114 support on Audiophile 192 */ -/* CDTO (pin 32) -- GPIO2 pin 52 - * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358) - * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358) - * CSN (pin 35) -- GPIO7 pin 59 - */ -#define AK4114_ADDR 0x02 - -static void write_data(struct snd_ice1712 *ice, unsigned int gpio, - unsigned int data, int idx) -{ - for (; idx >= 0; idx--) { - /* drop clock */ - gpio &= ~VT1724_REVO_CCLK; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - /* set data */ - if (data & (1 << idx)) - gpio |= VT1724_REVO_CDOUT; - else - gpio &= ~VT1724_REVO_CDOUT; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - /* raise clock */ - gpio |= VT1724_REVO_CCLK; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - } -} - -static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, - int idx) -{ - unsigned char data = 0; - - for (; idx >= 0; idx--) { - /* drop clock */ - gpio &= ~VT1724_REVO_CCLK; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - /* read data */ - if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN) - data |= (1 << idx); - udelay(1); - /* raise clock */ - gpio |= VT1724_REVO_CCLK; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - } - return data; -} - -static unsigned int ap192_4wire_start(struct snd_ice1712 *ice) -{ - unsigned int tmp; - - snd_ice1712_save_gpio_status(ice); - tmp = snd_ice1712_gpio_read(ice); - tmp |= VT1724_REVO_CCLK; /* high at init */ - tmp |= VT1724_REVO_CS0; - tmp &= ~VT1724_REVO_CS1; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - return tmp; -} - -static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) -{ - tmp |= VT1724_REVO_CS1; - tmp |= VT1724_REVO_CS0; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - snd_ice1712_restore_gpio_status(ice); -} - -static void ap192_ak4114_write(void *private_data, unsigned char addr, - unsigned char data) -{ - struct snd_ice1712 *ice = private_data; - unsigned int tmp, addrdata; - - tmp = ap192_4wire_start(ice); - addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f); - addrdata = (addrdata << 8) | data; - write_data(ice, tmp, addrdata, 15); - ap192_4wire_finish(ice, tmp); -} - -static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr) -{ - struct snd_ice1712 *ice = private_data; - unsigned int tmp; - unsigned char data; - - tmp = ap192_4wire_start(ice); - write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7); - data = read_data(ice, tmp, 7); - ap192_4wire_finish(ice, tmp); - return data; -} - -static int __devinit ap192_ak4114_init(struct snd_ice1712 *ice) -{ - static const unsigned char ak4114_init_vals[] = { - AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, - AK4114_DIF_I24I2S, - AK4114_TX1E, - AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1), - 0, - 0 - }; - static const unsigned char ak4114_init_txcsb[] = { - 0x41, 0x02, 0x2c, 0x00, 0x00 - }; - struct ak4114 *ak; - int err; - - err = snd_ak4114_create(ice->card, - ap192_ak4114_read, - ap192_ak4114_write, - ak4114_init_vals, ak4114_init_txcsb, - ice, &ak); - /* AK4114 in Revo cannot detect external rate correctly. - * No reason to stop capture stream due to incorrect checks */ - ak->check_flags = AK4114_CHECK_NO_RATE; - - return 0; /* error ignored; it's no fatal error */ -} - -static int __devinit revo_init(struct snd_ice1712 *ice) -{ - struct snd_akm4xxx *ak; - int err; - - /* determine I2C, DACs and ADCs */ - switch (ice->eeprom.subvendor) { - case VT1724_SUBDEVICE_REVOLUTION71: - ice->num_total_dacs = 8; - ice->num_total_adcs = 2; - ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed; - break; - case VT1724_SUBDEVICE_REVOLUTION51: - ice->num_total_dacs = 8; - ice->num_total_adcs = 2; - break; - case VT1724_SUBDEVICE_AUDIOPHILE192: - ice->num_total_dacs = 2; - ice->num_total_adcs = 2; - break; - default: - snd_BUG(); - return -EINVAL; - } - - /* second stage of initialization, analog parts and others */ - ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL); - if (! ak) - return -ENOMEM; - switch (ice->eeprom.subvendor) { - case VT1724_SUBDEVICE_REVOLUTION71: - ice->akm_codecs = 2; - err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, - &akm_revo_front_priv, ice); - if (err < 0) - return err; - err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo_surround, - &akm_revo_surround_priv, ice); - if (err < 0) - return err; - /* unmute all codecs */ - snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, - VT1724_REVO_MUTE); - break; - case VT1724_SUBDEVICE_REVOLUTION51: - ice->akm_codecs = 2; - err = snd_ice1712_akm4xxx_init(ak, &akm_revo51, - &akm_revo51_priv, ice); - if (err < 0) - return err; - err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo51_adc, - &akm_revo51_adc_priv, ice); - if (err < 0) - return err; - err = revo51_i2c_init(ice, &ptc_revo51_volume); - if (err < 0) - return err; - /* unmute all codecs */ - snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, - VT1724_REVO_MUTE); - break; - case VT1724_SUBDEVICE_AUDIOPHILE192: - ice->akm_codecs = 1; - err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv, - ice); - if (err < 0) - return err; - - /* unmute all codecs */ - snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, - VT1724_REVO_MUTE); - break; - } - - return 0; -} - - -static int __devinit revo_add_controls(struct snd_ice1712 *ice) -{ - struct revo51_spec *spec; - int err; - - switch (ice->eeprom.subvendor) { - case VT1724_SUBDEVICE_REVOLUTION71: - err = snd_ice1712_akm4xxx_build_controls(ice); - if (err < 0) - return err; - break; - case VT1724_SUBDEVICE_REVOLUTION51: - err = snd_ice1712_akm4xxx_build_controls(ice); - if (err < 0) - return err; - spec = ice->spec; - err = snd_pt2258_build_controls(spec->pt2258); - if (err < 0) - return err; - break; - case VT1724_SUBDEVICE_AUDIOPHILE192: - err = snd_ice1712_akm4xxx_build_controls(ice); - if (err < 0) - return err; - err = ap192_ak4114_init(ice); - if (err < 0) - return err; - break; - } - return 0; -} - -/* entry point */ -struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_REVOLUTION71, - .name = "M Audio Revolution-7.1", - .model = "revo71", - .chip_init = revo_init, - .build_controls = revo_add_controls, - }, - { - .subvendor = VT1724_SUBDEVICE_REVOLUTION51, - .name = "M Audio Revolution-5.1", - .model = "revo51", - .chip_init = revo_init, - .build_controls = revo_add_controls, - }, - { - .subvendor = VT1724_SUBDEVICE_AUDIOPHILE192, - .name = "M Audio Audiophile192", - .model = "ap192", - .chip_init = revo_init, - .build_controls = revo_add_controls, - }, - { } /* terminator */ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/revo.h b/ANDROID_3.4.5/sound/pci/ice1712/revo.h deleted file mode 100644 index a3ba4259..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/revo.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __SOUND_REVO_H -#define __SOUND_REVO_H - -/* - * ALSA driver for ICEnsemble ICE1712 (Envy24) - * - * Lowlevel functions for M-Audio Revolution 7.1 - * - * Copyright (c) 2003 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define REVO_DEVICE_DESC \ - "{MidiMan M Audio,Revolution 7.1},"\ - "{MidiMan M Audio,Revolution 5.1},"\ - "{MidiMan M Audio,Audiophile 192}," - -#define VT1724_SUBDEVICE_REVOLUTION71 0x12143036 -#define VT1724_SUBDEVICE_REVOLUTION51 0x12143136 -#define VT1724_SUBDEVICE_AUDIOPHILE192 0x12143236 - -/* entry point */ -extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; - - -/* - * MidiMan M-Audio Revolution GPIO definitions - */ - -#define VT1724_REVO_CCLK 0x02 -#define VT1724_REVO_CDIN 0x04 /* not used */ -#define VT1724_REVO_CDOUT 0x08 -#define VT1724_REVO_CS0 0x10 /* AK5365 chipselect for (revo51) */ -#define VT1724_REVO_CS1 0x20 /* front AKM4381 chipselect */ -#define VT1724_REVO_CS2 0x40 /* surround AKM4355 CS (revo71) */ -#define VT1724_REVO_I2C_DATA 0x40 /* I2C: PT 2258 SDA (on revo51) */ -#define VT1724_REVO_I2C_CLOCK 0x80 /* I2C: PT 2258 SCL (on revo51) */ -#define VT1724_REVO_CS3 0x80 /* AK4114 for AP192 */ -#define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */ - -#endif /* __SOUND_REVO_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/se.c b/ANDROID_3.4.5/sound/pci/ice1712/se.c deleted file mode 100644 index 69673b95..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/se.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - * ALSA driver for ICEnsemble VT1724 (Envy24HT) - * - * Lowlevel functions for ONKYO WAVIO SE-90PCI and SE-200PCI - * - * Copyright (c) 2007 Shin-ya Okada sh_okada(at)d4.dion.ne.jp - * (at) -> @ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "se.h" - -struct se_spec { - struct { - unsigned char ch1, ch2; - } vol[8]; -}; - -/****************************************************************************/ -/* ONKYO WAVIO SE-200PCI */ -/****************************************************************************/ -/* - * system configuration ICE_EEP2_SYSCONF=0x4b - * XIN1 49.152MHz - * not have UART - * one stereo ADC and a S/PDIF receiver connected - * four stereo DACs connected - * - * AC-Link configuration ICE_EEP2_ACLINK=0x80 - * use I2C, not use AC97 - * - * I2S converters feature ICE_EEP2_I2S=0x78 - * I2S codec has no volume/mute control feature - * I2S codec supports 96KHz and 192KHz - * I2S codec 24bits - * - * S/PDIF configuration ICE_EEP2_SPDIF=0xc3 - * Enable integrated S/PDIF transmitter - * internal S/PDIF out implemented - * S/PDIF is stereo - * External S/PDIF out implemented - * - * - * ** connected chips ** - * - * WM8740 - * A 2ch-DAC of main outputs. - * It setuped as I2S mode by wire, so no way to setup from software. - * The sample-rate are automatically changed. - * ML/I2S (28pin) --------+ - * MC/DM1 (27pin) -- 5V | - * MD/DM0 (26pin) -- GND | - * MUTEB (25pin) -- NC | - * MODE (24pin) -- GND | - * CSBIW (23pin) --------+ - * | - * RSTB (22pin) --R(1K)-+ - * Probably it reduce the noise from the control line. - * - * WM8766 - * A 6ch-DAC for surrounds. - * It's control wire was connected to GPIOxx (3-wire serial interface) - * ML/I2S (11pin) -- GPIO18 - * MC/IWL (12pin) -- GPIO17 - * MD/DM (13pin) -- GPIO16 - * MUTE (14pin) -- GPIO01 - * - * WM8776 - * A 2ch-ADC(with 10ch-selector) plus 2ch-DAC. - * It's control wire was connected to SDA/SCLK (2-wire serial interface) - * MODE (16pin) -- R(1K) -- GND - * CE (17pin) -- R(1K) -- GND 2-wire mode (address=0x34) - * DI (18pin) -- SDA - * CL (19pin) -- SCLK - * - * - * ** output pins and device names ** - * - * 7.1ch name -- output connector color -- device (-D option) - * - * FRONT 2ch -- green -- plughw:0,0 - * CENTER(Lch) SUBWOOFER(Rch) -- black -- plughw:0,2,0 - * SURROUND 2ch -- orange -- plughw:0,2,1 - * SURROUND BACK 2ch -- white -- plughw:0,2,2 - * - */ - - -/****************************************************************************/ -/* WM8740 interface */ -/****************************************************************************/ - -static void __devinit se200pci_WM8740_init(struct snd_ice1712 *ice) -{ - /* nothing to do */ -} - - -static void se200pci_WM8740_set_pro_rate(struct snd_ice1712 *ice, - unsigned int rate) -{ - /* nothing to do */ -} - - -/****************************************************************************/ -/* WM8766 interface */ -/****************************************************************************/ - -static void se200pci_WM8766_write(struct snd_ice1712 *ice, - unsigned int addr, unsigned int data) -{ - unsigned int st; - unsigned int bits; - int i; - const unsigned int DATA = 0x010000; - const unsigned int CLOCK = 0x020000; - const unsigned int LOAD = 0x040000; - const unsigned int ALL_MASK = (DATA | CLOCK | LOAD); - - snd_ice1712_save_gpio_status(ice); - - st = ((addr & 0x7f) << 9) | (data & 0x1ff); - snd_ice1712_gpio_set_dir(ice, ice->gpio.direction | ALL_MASK); - snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask & ~ALL_MASK); - bits = snd_ice1712_gpio_read(ice) & ~ALL_MASK; - - snd_ice1712_gpio_write(ice, bits); - for (i = 0; i < 16; i++) { - udelay(1); - bits &= ~CLOCK; - st = (st << 1); - if (st & 0x10000) - bits |= DATA; - else - bits &= ~DATA; - - snd_ice1712_gpio_write(ice, bits); - - udelay(1); - bits |= CLOCK; - snd_ice1712_gpio_write(ice, bits); - } - - udelay(1); - bits |= LOAD; - snd_ice1712_gpio_write(ice, bits); - - udelay(1); - bits |= (DATA | CLOCK); - snd_ice1712_gpio_write(ice, bits); - - snd_ice1712_restore_gpio_status(ice); -} - -static void se200pci_WM8766_set_volume(struct snd_ice1712 *ice, int ch, - unsigned int vol1, unsigned int vol2) -{ - switch (ch) { - case 0: - se200pci_WM8766_write(ice, 0x000, vol1); - se200pci_WM8766_write(ice, 0x001, vol2 | 0x100); - break; - case 1: - se200pci_WM8766_write(ice, 0x004, vol1); - se200pci_WM8766_write(ice, 0x005, vol2 | 0x100); - break; - case 2: - se200pci_WM8766_write(ice, 0x006, vol1); - se200pci_WM8766_write(ice, 0x007, vol2 | 0x100); - break; - } -} - -static void __devinit se200pci_WM8766_init(struct snd_ice1712 *ice) -{ - se200pci_WM8766_write(ice, 0x1f, 0x000); /* RESET ALL */ - udelay(10); - - se200pci_WM8766_set_volume(ice, 0, 0, 0); /* volume L=0 R=0 */ - se200pci_WM8766_set_volume(ice, 1, 0, 0); /* volume L=0 R=0 */ - se200pci_WM8766_set_volume(ice, 2, 0, 0); /* volume L=0 R=0 */ - - se200pci_WM8766_write(ice, 0x03, 0x022); /* serial mode I2S-24bits */ - se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */ - se200pci_WM8766_write(ice, 0x12, 0x000); /* MDP=0 */ - se200pci_WM8766_write(ice, 0x15, 0x000); /* MDP=0 */ - se200pci_WM8766_write(ice, 0x09, 0x000); /* demp=off mute=off */ - - se200pci_WM8766_write(ice, 0x02, 0x124); /* ch-assign L=L R=R RESET */ - se200pci_WM8766_write(ice, 0x02, 0x120); /* ch-assign L=L R=R */ -} - -static void se200pci_WM8766_set_pro_rate(struct snd_ice1712 *ice, - unsigned int rate) -{ - if (rate > 96000) - se200pci_WM8766_write(ice, 0x0a, 0x000); /* MCLK=128fs */ - else - se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */ -} - - -/****************************************************************************/ -/* WM8776 interface */ -/****************************************************************************/ - -static void se200pci_WM8776_write(struct snd_ice1712 *ice, - unsigned int addr, unsigned int data) -{ - unsigned int val; - - val = (addr << 9) | data; - snd_vt1724_write_i2c(ice, 0x34, val >> 8, val & 0xff); -} - - -static void se200pci_WM8776_set_output_volume(struct snd_ice1712 *ice, - unsigned int vol1, unsigned int vol2) -{ - se200pci_WM8776_write(ice, 0x03, vol1); - se200pci_WM8776_write(ice, 0x04, vol2 | 0x100); -} - -static void se200pci_WM8776_set_input_volume(struct snd_ice1712 *ice, - unsigned int vol1, unsigned int vol2) -{ - se200pci_WM8776_write(ice, 0x0e, vol1); - se200pci_WM8776_write(ice, 0x0f, vol2 | 0x100); -} - -static const char *se200pci_sel[] = { - "LINE-IN", "CD-IN", "MIC-IN", "ALL-MIX", NULL -}; - -static void se200pci_WM8776_set_input_selector(struct snd_ice1712 *ice, - unsigned int sel) -{ - static unsigned char vals[] = { - /* LINE, CD, MIC, ALL, GND */ - 0x10, 0x04, 0x08, 0x1c, 0x03 - }; - if (sel > 4) - sel = 4; - se200pci_WM8776_write(ice, 0x15, vals[sel]); -} - -static void se200pci_WM8776_set_afl(struct snd_ice1712 *ice, unsigned int afl) -{ - /* AFL -- After Fader Listening */ - if (afl) - se200pci_WM8776_write(ice, 0x16, 0x005); - else - se200pci_WM8776_write(ice, 0x16, 0x001); -} - -static const char *se200pci_agc[] = { - "Off", "LimiterMode", "ALCMode", NULL -}; - -static void se200pci_WM8776_set_agc(struct snd_ice1712 *ice, unsigned int agc) -{ - /* AGC -- Auto Gain Control of the input */ - switch (agc) { - case 0: - se200pci_WM8776_write(ice, 0x11, 0x000); /* Off */ - break; - case 1: - se200pci_WM8776_write(ice, 0x10, 0x07b); - se200pci_WM8776_write(ice, 0x11, 0x100); /* LimiterMode */ - break; - case 2: - se200pci_WM8776_write(ice, 0x10, 0x1fb); - se200pci_WM8776_write(ice, 0x11, 0x100); /* ALCMode */ - break; - } -} - -static void __devinit se200pci_WM8776_init(struct snd_ice1712 *ice) -{ - int i; - static unsigned short __devinitdata default_values[] = { - 0x100, 0x100, 0x100, - 0x100, 0x100, 0x100, - 0x000, 0x090, 0x000, 0x000, - 0x022, 0x022, 0x022, - 0x008, 0x0cf, 0x0cf, 0x07b, 0x000, - 0x032, 0x000, 0x0a6, 0x001, 0x001 - }; - - se200pci_WM8776_write(ice, 0x17, 0x000); /* reset all */ - /* ADC and DAC interface is I2S 24bits mode */ - /* The sample-rate are automatically changed */ - udelay(10); - /* BUT my board can not do reset all, so I load all by manually. */ - for (i = 0; i < ARRAY_SIZE(default_values); i++) - se200pci_WM8776_write(ice, i, default_values[i]); - - se200pci_WM8776_set_input_selector(ice, 0); - se200pci_WM8776_set_afl(ice, 0); - se200pci_WM8776_set_agc(ice, 0); - se200pci_WM8776_set_input_volume(ice, 0, 0); - se200pci_WM8776_set_output_volume(ice, 0, 0); - - /* head phone mute and power down */ - se200pci_WM8776_write(ice, 0x00, 0); - se200pci_WM8776_write(ice, 0x01, 0); - se200pci_WM8776_write(ice, 0x02, 0x100); - se200pci_WM8776_write(ice, 0x0d, 0x080); -} - -static void se200pci_WM8776_set_pro_rate(struct snd_ice1712 *ice, - unsigned int rate) -{ - /* nothing to do */ -} - - -/****************************************************************************/ -/* runtime interface */ -/****************************************************************************/ - -static void se200pci_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate) -{ - se200pci_WM8740_set_pro_rate(ice, rate); - se200pci_WM8766_set_pro_rate(ice, rate); - se200pci_WM8776_set_pro_rate(ice, rate); -} - -struct se200pci_control { - char *name; - enum { - WM8766, - WM8776in, - WM8776out, - WM8776sel, - WM8776agc, - WM8776afl - } target; - enum { VOLUME1, VOLUME2, BOOLEAN, ENUM } type; - int ch; - const char **member; - const char *comment; -}; - -static const struct se200pci_control se200pci_cont[] = { - { - .name = "Front Playback Volume", - .target = WM8776out, - .type = VOLUME1, - .comment = "Front(green)" - }, - { - .name = "Side Playback Volume", - .target = WM8766, - .type = VOLUME1, - .ch = 1, - .comment = "Surround(orange)" - }, - { - .name = "Surround Playback Volume", - .target = WM8766, - .type = VOLUME1, - .ch = 2, - .comment = "SurroundBack(white)" - }, - { - .name = "CLFE Playback Volume", - .target = WM8766, - .type = VOLUME1, - .ch = 0, - .comment = "Center(Lch)&SubWoofer(Rch)(black)" - }, - { - .name = "Capture Volume", - .target = WM8776in, - .type = VOLUME2 - }, - { - .name = "Capture Select", - .target = WM8776sel, - .type = ENUM, - .member = se200pci_sel - }, - { - .name = "AGC Capture Mode", - .target = WM8776agc, - .type = ENUM, - .member = se200pci_agc - }, - { - .name = "AFL Bypass Playback Switch", - .target = WM8776afl, - .type = BOOLEAN - } -}; - -static int se200pci_get_enum_count(int n) -{ - const char **member; - int c; - - member = se200pci_cont[n].member; - if (!member) - return 0; - for (c = 0; member[c]; c++) - ; - return c; -} - -static int se200pci_cont_volume_info(struct snd_kcontrol *kc, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; /* mute */ - uinfo->value.integer.max = 0xff; /* 0dB */ - return 0; -} - -#define se200pci_cont_boolean_info snd_ctl_boolean_mono_info - -static int se200pci_cont_enum_info(struct snd_kcontrol *kc, - struct snd_ctl_elem_info *uinfo) -{ - int n, c; - - n = kc->private_value; - c = se200pci_get_enum_count(n); - if (!c) - return -EINVAL; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = c; - if (uinfo->value.enumerated.item >= c) - uinfo->value.enumerated.item = c - 1; - strcpy(uinfo->value.enumerated.name, - se200pci_cont[n].member[uinfo->value.enumerated.item]); - return 0; -} - -static int se200pci_cont_volume_get(struct snd_kcontrol *kc, - struct snd_ctl_elem_value *uc) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kc); - struct se_spec *spec = ice->spec; - int n = kc->private_value; - uc->value.integer.value[0] = spec->vol[n].ch1; - uc->value.integer.value[1] = spec->vol[n].ch2; - return 0; -} - -static int se200pci_cont_boolean_get(struct snd_kcontrol *kc, - struct snd_ctl_elem_value *uc) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kc); - struct se_spec *spec = ice->spec; - int n = kc->private_value; - uc->value.integer.value[0] = spec->vol[n].ch1; - return 0; -} - -static int se200pci_cont_enum_get(struct snd_kcontrol *kc, - struct snd_ctl_elem_value *uc) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kc); - struct se_spec *spec = ice->spec; - int n = kc->private_value; - uc->value.enumerated.item[0] = spec->vol[n].ch1; - return 0; -} - -static void se200pci_cont_update(struct snd_ice1712 *ice, int n) -{ - struct se_spec *spec = ice->spec; - switch (se200pci_cont[n].target) { - case WM8766: - se200pci_WM8766_set_volume(ice, - se200pci_cont[n].ch, - spec->vol[n].ch1, - spec->vol[n].ch2); - break; - - case WM8776in: - se200pci_WM8776_set_input_volume(ice, - spec->vol[n].ch1, - spec->vol[n].ch2); - break; - - case WM8776out: - se200pci_WM8776_set_output_volume(ice, - spec->vol[n].ch1, - spec->vol[n].ch2); - break; - - case WM8776sel: - se200pci_WM8776_set_input_selector(ice, - spec->vol[n].ch1); - break; - - case WM8776agc: - se200pci_WM8776_set_agc(ice, spec->vol[n].ch1); - break; - - case WM8776afl: - se200pci_WM8776_set_afl(ice, spec->vol[n].ch1); - break; - - default: - break; - } -} - -static int se200pci_cont_volume_put(struct snd_kcontrol *kc, - struct snd_ctl_elem_value *uc) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kc); - struct se_spec *spec = ice->spec; - int n = kc->private_value; - unsigned int vol1, vol2; - int changed; - - changed = 0; - vol1 = uc->value.integer.value[0] & 0xff; - vol2 = uc->value.integer.value[1] & 0xff; - if (spec->vol[n].ch1 != vol1) { - spec->vol[n].ch1 = vol1; - changed = 1; - } - if (spec->vol[n].ch2 != vol2) { - spec->vol[n].ch2 = vol2; - changed = 1; - } - if (changed) - se200pci_cont_update(ice, n); - - return changed; -} - -static int se200pci_cont_boolean_put(struct snd_kcontrol *kc, - struct snd_ctl_elem_value *uc) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kc); - struct se_spec *spec = ice->spec; - int n = kc->private_value; - unsigned int vol1; - - vol1 = !!uc->value.integer.value[0]; - if (spec->vol[n].ch1 != vol1) { - spec->vol[n].ch1 = vol1; - se200pci_cont_update(ice, n); - return 1; - } - return 0; -} - -static int se200pci_cont_enum_put(struct snd_kcontrol *kc, - struct snd_ctl_elem_value *uc) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kc); - struct se_spec *spec = ice->spec; - int n = kc->private_value; - unsigned int vol1; - - vol1 = uc->value.enumerated.item[0]; - if (vol1 >= se200pci_get_enum_count(n)) - return -EINVAL; - if (spec->vol[n].ch1 != vol1) { - spec->vol[n].ch1 = vol1; - se200pci_cont_update(ice, n); - return 1; - } - return 0; -} - -static const DECLARE_TLV_DB_SCALE(db_scale_gain1, -12750, 50, 1); -static const DECLARE_TLV_DB_SCALE(db_scale_gain2, -10350, 50, 1); - -static int __devinit se200pci_add_controls(struct snd_ice1712 *ice) -{ - int i; - struct snd_kcontrol_new cont; - int err; - - memset(&cont, 0, sizeof(cont)); - cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - for (i = 0; i < ARRAY_SIZE(se200pci_cont); i++) { - cont.private_value = i; - cont.name = se200pci_cont[i].name; - cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; - cont.tlv.p = NULL; - switch (se200pci_cont[i].type) { - case VOLUME1: - case VOLUME2: - cont.info = se200pci_cont_volume_info; - cont.get = se200pci_cont_volume_get; - cont.put = se200pci_cont_volume_put; - cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; - if (se200pci_cont[i].type == VOLUME1) - cont.tlv.p = db_scale_gain1; - else - cont.tlv.p = db_scale_gain2; - break; - case BOOLEAN: - cont.info = se200pci_cont_boolean_info; - cont.get = se200pci_cont_boolean_get; - cont.put = se200pci_cont_boolean_put; - break; - case ENUM: - cont.info = se200pci_cont_enum_info; - cont.get = se200pci_cont_enum_get; - cont.put = se200pci_cont_enum_put; - break; - default: - snd_BUG(); - return -EINVAL; - } - err = snd_ctl_add(ice->card, snd_ctl_new1(&cont, ice)); - if (err < 0) - return err; - } - - return 0; -} - - -/****************************************************************************/ -/* ONKYO WAVIO SE-90PCI */ -/****************************************************************************/ -/* - * system configuration ICE_EEP2_SYSCONF=0x4b - * AC-Link configuration ICE_EEP2_ACLINK=0x80 - * I2S converters feature ICE_EEP2_I2S=0x78 - * S/PDIF configuration ICE_EEP2_SPDIF=0xc3 - * - * ** connected chip ** - * - * WM8716 - * A 2ch-DAC of main outputs. - * It setuped as I2S mode by wire, so no way to setup from software. - * ML/I2S (28pin) -- +5V - * MC/DM1 (27pin) -- GND - * MC/DM0 (26pin) -- GND - * MUTEB (25pin) -- open (internal pull-up) - * MODE (24pin) -- GND - * CSBIWO (23pin) -- +5V - * - */ - - /* Nothing to do for this chip. */ - - -/****************************************************************************/ -/* probe/initialize/setup */ -/****************************************************************************/ - -static int __devinit se_init(struct snd_ice1712 *ice) -{ - struct se_spec *spec; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - ice->spec = spec; - - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE90PCI) { - ice->num_total_dacs = 2; - ice->num_total_adcs = 0; - ice->vt1720 = 1; - return 0; - - } else if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI) { - ice->num_total_dacs = 8; - ice->num_total_adcs = 2; - se200pci_WM8740_init(ice); - se200pci_WM8766_init(ice); - se200pci_WM8776_init(ice); - ice->gpio.set_pro_rate = se200pci_set_pro_rate; - return 0; - } - - return -ENOENT; -} - -static int __devinit se_add_controls(struct snd_ice1712 *ice) -{ - int err; - - err = 0; - /* nothing to do for VT1724_SUBDEVICE_SE90PCI */ - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI) - err = se200pci_add_controls(ice); - - return err; -} - - -/****************************************************************************/ -/* entry point */ -/****************************************************************************/ - -static unsigned char se200pci_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - - [ICE_EEP2_GPIO_DIR] = 0x02, /* WM8766 mute 1=output */ - [ICE_EEP2_GPIO_DIR1] = 0x00, /* not used */ - [ICE_EEP2_GPIO_DIR2] = 0x07, /* WM8766 ML/MC/MD 1=output */ - - [ICE_EEP2_GPIO_MASK] = 0x00, /* 0=writable */ - [ICE_EEP2_GPIO_MASK1] = 0x00, /* 0=writable */ - [ICE_EEP2_GPIO_MASK2] = 0x00, /* 0=writable */ - - [ICE_EEP2_GPIO_STATE] = 0x00, /* WM8766 mute=0 */ - [ICE_EEP2_GPIO_STATE1] = 0x00, /* not used */ - [ICE_EEP2_GPIO_STATE2] = 0x07, /* WM8766 ML/MC/MD */ -}; - -static unsigned char se90pci_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - - /* ALL GPIO bits are in input mode */ -}; - -struct snd_ice1712_card_info snd_vt1724_se_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_SE200PCI, - .name = "ONKYO SE200PCI", - .model = "se200pci", - .chip_init = se_init, - .build_controls = se_add_controls, - .eeprom_size = sizeof(se200pci_eeprom), - .eeprom_data = se200pci_eeprom, - }, - { - .subvendor = VT1724_SUBDEVICE_SE90PCI, - .name = "ONKYO SE90PCI", - .model = "se90pci", - .chip_init = se_init, - .build_controls = se_add_controls, - .eeprom_size = sizeof(se90pci_eeprom), - .eeprom_data = se90pci_eeprom, - }, - {} /*terminator*/ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/se.h b/ANDROID_3.4.5/sound/pci/ice1712/se.h deleted file mode 100644 index 0b0a9dab..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/se.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __SOUND_SE_H -#define __SOUND_SE_H - -/* ID */ -#define SE_DEVICE_DESC \ - "{ONKYO INC,SE-90PCI},"\ - "{ONKYO INC,SE-200PCI}," - -#define VT1724_SUBDEVICE_SE90PCI 0xb161000 -#define VT1724_SUBDEVICE_SE200PCI 0xb160100 - -/* entry struct */ -extern struct snd_ice1712_card_info snd_vt1724_se_cards[]; - -#endif /* __SOUND_SE_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/stac946x.h b/ANDROID_3.4.5/sound/pci/ice1712/stac946x.h deleted file mode 100644 index 5b390952..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/stac946x.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __SOUND_STAC946X_H -#define __SOUND_STAC946X_H - -#define STAC946X_RESET 0x00 -#define STAC946X_STATUS 0x01 -#define STAC946X_MASTER_VOLUME 0x02 -#define STAC946X_LF_VOLUME 0x03 -#define STAC946X_RF_VOLUME 0x04 -#define STAC946X_LR_VOLUME 0x05 -#define STAC946X_RR_VOLUME 0x06 -#define STAC946X_CENTER_VOLUME 0x07 -#define STAC946X_LFE_VOLUME 0x08 -#define STAC946X_MIC_L_VOLUME 0x09 -#define STAC946X_MIC_R_VOLUME 0x0a -#define STAC946X_DEEMPHASIS 0x0c -#define STAC946X_GENERAL_PURPOSE 0x0d -#define STAC946X_AUDIO_PORT_CONTROL 0x0e -#define STAC946X_MASTER_CLOCKING 0x0f -#define STAC946X_POWERDOWN_CTRL1 0x10 -#define STAC946X_POWERDOWN_CTRL2 0x11 -#define STAC946X_REVISION_CODE 0x12 -#define STAC946X_ADDRESS_CONTROL 0x13 -#define STAC946X_ADDRESS 0x14 - -#endif /* __SOUND_STAC946X_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.c b/ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.c deleted file mode 100644 index 4c551e14..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * ALSA driver for VT1720/VT1724 (Envy24PT/Envy24HT) - * - * Lowlevel functions for VT1720-based motherboards - * - * Copyright (c) 2004 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "vt1720_mobo.h" - - -static int __devinit k8x800_init(struct snd_ice1712 *ice) -{ - ice->vt1720 = 1; - - /* VT1616 codec */ - ice->num_total_dacs = 6; - ice->num_total_adcs = 2; - - /* WM8728 codec */ - /* FIXME: TODO */ - - return 0; -} - -static int __devinit k8x800_add_controls(struct snd_ice1712 *ice) -{ - /* FIXME: needs some quirks for VT1616? */ - return 0; -} - -/* EEPROM image */ - -static unsigned char k8x800_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ - [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ - [ICE_EEP2_I2S] = 0x00, /* - */ - [ICE_EEP2_SPDIF] = 0x00, /* - */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x00, /* - */ - [ICE_EEP2_GPIO_MASK] = 0xff, - [ICE_EEP2_GPIO_MASK1] = 0xff, - [ICE_EEP2_GPIO_MASK2] = 0x00, /* - */ - [ICE_EEP2_GPIO_STATE] = 0x00, - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */ -}; - -static unsigned char sn25p_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ - [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ - [ICE_EEP2_I2S] = 0x00, /* - */ - [ICE_EEP2_SPDIF] = 0x41, /* - */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x00, /* - */ - [ICE_EEP2_GPIO_MASK] = 0xff, - [ICE_EEP2_GPIO_MASK1] = 0xff, - [ICE_EEP2_GPIO_MASK2] = 0x00, /* - */ - [ICE_EEP2_GPIO_STATE] = 0x00, - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */ -}; - - -/* entry point */ -struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { - { - .subvendor = VT1720_SUBDEVICE_K8X800, - .name = "Albatron K8X800 Pro II", - .model = "k8x800", - .chip_init = k8x800_init, - .build_controls = k8x800_add_controls, - .eeprom_size = sizeof(k8x800_eeprom), - .eeprom_data = k8x800_eeprom, - }, - { - .subvendor = VT1720_SUBDEVICE_ZNF3_150, - .name = "Chaintech ZNF3-150", - /* identical with k8x800 */ - .chip_init = k8x800_init, - .build_controls = k8x800_add_controls, - .eeprom_size = sizeof(k8x800_eeprom), - .eeprom_data = k8x800_eeprom, - }, - { - .subvendor = VT1720_SUBDEVICE_ZNF3_250, - .name = "Chaintech ZNF3-250", - /* identical with k8x800 */ - .chip_init = k8x800_init, - .build_controls = k8x800_add_controls, - .eeprom_size = sizeof(k8x800_eeprom), - .eeprom_data = k8x800_eeprom, - }, - { - .subvendor = VT1720_SUBDEVICE_9CJS, - .name = "Chaintech 9CJS", - /* identical with k8x800 */ - .chip_init = k8x800_init, - .build_controls = k8x800_add_controls, - .eeprom_size = sizeof(k8x800_eeprom), - .eeprom_data = k8x800_eeprom, - }, - { - .subvendor = VT1720_SUBDEVICE_SN25P, - .name = "Shuttle SN25P", - .model = "sn25p", - .chip_init = k8x800_init, - .build_controls = k8x800_add_controls, - .eeprom_size = sizeof(k8x800_eeprom), - .eeprom_data = sn25p_eeprom, - }, - { } /* terminator */ -}; - diff --git a/ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.h b/ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.h deleted file mode 100644 index 0b1b0ee1..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __SOUND_VT1720_MOBO_H -#define __SOUND_VT1720_MOBO_H - -/* - * ALSA driver for VT1720/VT1724 (Envy24PT/Envy24HT) - * - * Lowlevel functions for VT1720-based motherboards - * - * Copyright (c) 2004 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define VT1720_MOBO_DEVICE_DESC "{Albatron,K8X800 Pro II},"\ - "{Chaintech,ZNF3-150},"\ - "{Chaintech,ZNF3-250},"\ - "{Chaintech,9CJS},"\ - "{Shuttle,SN25P}," - -#define VT1720_SUBDEVICE_K8X800 0xf217052c -#define VT1720_SUBDEVICE_ZNF3_150 0x0f2741f6 -#define VT1720_SUBDEVICE_ZNF3_250 0x0f2745f6 -#define VT1720_SUBDEVICE_9CJS 0x0f272327 -#define VT1720_SUBDEVICE_SN25P 0x97123650 - -extern struct snd_ice1712_card_info snd_vt1720_mobo_cards[]; - -#endif /* __SOUND_VT1720_MOBO_H */ diff --git a/ANDROID_3.4.5/sound/pci/ice1712/wtm.c b/ANDROID_3.4.5/sound/pci/ice1712/wtm.c deleted file mode 100644 index e618f789..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/wtm.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * ALSA driver for ICEnsemble VT1724 (Envy24HT) - * - * Lowlevel functions for Ego Sys Waveterminal 192M - * - * Copyright (c) 2006 Guedez Clement - * Some functions are taken from the Prodigy192 driver - * source - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - - - -#include -#include -#include -#include -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "wtm.h" -#include "stac946x.h" - - -/* - * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus - */ -static inline void stac9460_put(struct snd_ice1712 *ice, int reg, - unsigned char val) -{ - snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val); -} - -static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg) -{ - return snd_vt1724_read_i2c(ice, STAC9460_I2C_ADDR, reg); -} - -/* - * 2*ADC 2*DAC no2 ringbuffer r/w on i2c bus - */ -static inline void stac9460_2_put(struct snd_ice1712 *ice, int reg, - unsigned char val) -{ - snd_vt1724_write_i2c(ice, STAC9460_2_I2C_ADDR, reg, val); -} - -static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg) -{ - return snd_vt1724_read_i2c(ice, STAC9460_2_I2C_ADDR, reg); -} - - -/* - * DAC mute control - */ -#define stac9460_dac_mute_info snd_ctl_boolean_mono_info - -static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char val; - int idx, id; - - if (kcontrol->private_value) { - idx = STAC946X_MASTER_VOLUME; - id = 0; - } else { - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - idx = id + STAC946X_LF_VOLUME; - } - if (id < 6) - val = stac9460_get(ice, idx); - else - val = stac9460_2_get(ice, idx - 6); - ucontrol->value.integer.value[0] = (~val >> 7) & 0x1; - return 0; -} - -static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char new, old; - int id, idx; - int change; - - if (kcontrol->private_value) { - idx = STAC946X_MASTER_VOLUME; - old = stac9460_get(ice, idx); - new = (~ucontrol->value.integer.value[0] << 7 & 0x80) | - (old & ~0x80); - change = (new != old); - if (change) { - stac9460_put(ice, idx, new); - stac9460_2_put(ice, idx, new); - } - } else { - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - idx = id + STAC946X_LF_VOLUME; - if (id < 6) - old = stac9460_get(ice, idx); - else - old = stac9460_2_get(ice, idx - 6); - new = (~ucontrol->value.integer.value[0] << 7 & 0x80) | - (old & ~0x80); - change = (new != old); - if (change) { - if (id < 6) - stac9460_put(ice, idx, new); - else - stac9460_2_put(ice, idx - 6, new); - } - } - return change; -} - -/* - * DAC volume attenuation mixer control - */ -static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; /* mute */ - uinfo->value.integer.max = 0x7f; /* 0dB */ - return 0; -} - -static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx, id; - unsigned char vol; - - if (kcontrol->private_value) { - idx = STAC946X_MASTER_VOLUME; - id = 0; - } else { - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - idx = id + STAC946X_LF_VOLUME; - } - if (id < 6) - vol = stac9460_get(ice, idx) & 0x7f; - else - vol = stac9460_2_get(ice, idx - 6) & 0x7f; - ucontrol->value.integer.value[0] = 0x7f - vol; - return 0; -} - -static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx, id; - unsigned char tmp, ovol, nvol; - int change; - - if (kcontrol->private_value) { - idx = STAC946X_MASTER_VOLUME; - nvol = ucontrol->value.integer.value[0] & 0x7f; - tmp = stac9460_get(ice, idx); - ovol = 0x7f - (tmp & 0x7f); - change = (ovol != nvol); - if (change) { - stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); - stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); - } - } else { - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - idx = id + STAC946X_LF_VOLUME; - nvol = ucontrol->value.integer.value[0] & 0x7f; - if (id < 6) - tmp = stac9460_get(ice, idx); - else - tmp = stac9460_2_get(ice, idx - 6); - ovol = 0x7f - (tmp & 0x7f); - change = (ovol != nvol); - if (change) { - if (id < 6) - stac9460_put(ice, idx, (0x7f - nvol) | - (tmp & 0x80)); - else - stac9460_2_put(ice, idx-6, (0x7f - nvol) | - (tmp & 0x80)); - } - } - return change; -} - -/* - * ADC mute control - */ -#define stac9460_adc_mute_info snd_ctl_boolean_stereo_info - -static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char val; - int i, id; - - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (id == 0) { - for (i = 0; i < 2; ++i) { - val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i); - ucontrol->value.integer.value[i] = ~val>>7 & 0x1; - } - } else { - for (i = 0; i < 2; ++i) { - val = stac9460_2_get(ice, STAC946X_MIC_L_VOLUME + i); - ucontrol->value.integer.value[i] = ~val>>7 & 0x1; - } - } - return 0; -} - -static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char new, old; - int i, reg, id; - int change; - - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (id == 0) { - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - old = stac9460_get(ice, reg); - new = (~ucontrol->value.integer.value[i]<<7&0x80) | - (old&~0x80); - change = (new != old); - if (change) - stac9460_put(ice, reg, new); - } - } else { - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - old = stac9460_2_get(ice, reg); - new = (~ucontrol->value.integer.value[i]<<7&0x80) | - (old&~0x80); - change = (new != old); - if (change) - stac9460_2_put(ice, reg, new); - } - } - return change; -} - -/* - *ADC gain mixer control - */ -static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; /* 0dB */ - uinfo->value.integer.max = 0x0f; /* 22.5dB */ - return 0; -} - -static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int i, reg, id; - unsigned char vol; - - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (id == 0) { - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - vol = stac9460_get(ice, reg) & 0x0f; - ucontrol->value.integer.value[i] = 0x0f - vol; - } - } else { - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - vol = stac9460_2_get(ice, reg) & 0x0f; - ucontrol->value.integer.value[i] = 0x0f - vol; - } - } - return 0; -} - -static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int i, reg, id; - unsigned char ovol, nvol; - int change; - - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (id == 0) { - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - nvol = ucontrol->value.integer.value[i] & 0x0f; - ovol = 0x0f - stac9460_get(ice, reg); - change = ((ovol & 0x0f) != nvol); - if (change) - stac9460_put(ice, reg, (0x0f - nvol) | - (ovol & ~0x0f)); - } - } else { - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - nvol = ucontrol->value.integer.value[i] & 0x0f; - ovol = 0x0f - stac9460_2_get(ice, reg); - change = ((ovol & 0x0f) != nvol); - if (change) - stac9460_2_put(ice, reg, (0x0f - nvol) | - (ovol & ~0x0f)); - } - } - return change; -} - -/* - * MIC / LINE switch fonction - */ - -#define stac9460_mic_sw_info snd_ctl_boolean_mono_info - -static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char val; - int id; - - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (id == 0) - val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); - else - val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE); - ucontrol->value.integer.value[0] = ~val>>7 & 0x1; - return 0; -} - -static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char new, old; - int change, id; - - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (id == 0) - old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); - else - old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE); - new = (~ucontrol->value.integer.value[0] << 7 & 0x80) | (old & ~0x80); - change = (new != old); - if (change) { - if (id == 0) - stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); - else - stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new); - } - return change; -} - -/* - * Control tabs - */ -static struct snd_kcontrol_new stac9640_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = stac9460_dac_mute_info, - .get = stac9460_dac_mute_get, - .put = stac9460_dac_mute_put, - .private_value = 1 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = stac9460_dac_vol_info, - .get = stac9460_dac_vol_get, - .put = stac9460_dac_vol_put, - .private_value = 1, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "MIC/Line switch", - .count = 2, - .info = stac9460_mic_sw_info, - .get = stac9460_mic_sw_get, - .put = stac9460_mic_sw_put, - - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "DAC Switch", - .count = 8, - .info = stac9460_dac_mute_info, - .get = stac9460_dac_mute_get, - .put = stac9460_dac_mute_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "DAC Volume", - .count = 8, - .info = stac9460_dac_vol_info, - .get = stac9460_dac_vol_get, - .put = stac9460_dac_vol_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "ADC Switch", - .count = 2, - .info = stac9460_adc_mute_info, - .get = stac9460_adc_mute_get, - .put = stac9460_adc_mute_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "ADC Volume", - .count = 2, - .info = stac9460_adc_vol_info, - .get = stac9460_adc_vol_get, - .put = stac9460_adc_vol_put, - - } -}; - - - -/*INIT*/ -static int __devinit wtm_add_controls(struct snd_ice1712 *ice) -{ - unsigned int i; - int err; - - for (i = 0; i < ARRAY_SIZE(stac9640_controls); i++) { - err = snd_ctl_add(ice->card, - snd_ctl_new1(&stac9640_controls[i], ice)); - if (err < 0) - return err; - } - return 0; -} - -static int __devinit wtm_init(struct snd_ice1712 *ice) -{ - static unsigned short stac_inits_prodigy[] = { - STAC946X_RESET, 0, - (unsigned short)-1 - }; - unsigned short *p; - - /*WTM 192M*/ - ice->num_total_dacs = 8; - ice->num_total_adcs = 4; - ice->force_rdma1 = 1; - - /*initialize codec*/ - p = stac_inits_prodigy; - for (; *p != (unsigned short)-1; p += 2) { - stac9460_put(ice, p[0], p[1]); - stac9460_2_put(ice, p[0], p[1]); - } - return 0; -} - - -static unsigned char wtm_eeprom[] __devinitdata = { - 0x47, /*SYSCONF: clock 192KHz, 4ADC, 8DAC */ - 0x80, /* ACLINK : I2S */ - 0xf8, /* I2S: vol; 96k, 24bit, 192k */ - 0xc1 /*SPDIF: out-en, spidf ext out*/, - 0x9f, /* GPIO_DIR */ - 0xff, /* GPIO_DIR1 */ - 0x7f, /* GPIO_DIR2 */ - 0x9f, /* GPIO_MASK */ - 0xff, /* GPIO_MASK1 */ - 0x7f, /* GPIO_MASK2 */ - 0x16, /* GPIO_STATE */ - 0x80, /* GPIO_STATE1 */ - 0x00, /* GPIO_STATE2 */ -}; - - -/*entry point*/ -struct snd_ice1712_card_info snd_vt1724_wtm_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_WTM, - .name = "ESI Waveterminal 192M", - .model = "WT192M", - .chip_init = wtm_init, - .build_controls = wtm_add_controls, - .eeprom_size = sizeof(wtm_eeprom), - .eeprom_data = wtm_eeprom, - }, - {} /*terminator*/ -}; diff --git a/ANDROID_3.4.5/sound/pci/ice1712/wtm.h b/ANDROID_3.4.5/sound/pci/ice1712/wtm.h deleted file mode 100644 index 423c1a20..00000000 --- a/ANDROID_3.4.5/sound/pci/ice1712/wtm.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __SOUND_WTM_H -#define __SOUND_WTM_H - -/* ID */ -#define WTM_DEVICE_DESC "{EGO SYS INC,WaveTerminal 192M}," -#define VT1724_SUBDEVICE_WTM 0x36495345 /* WT192M ver1.0 */ - -/* - *chip addresses on I2C bus - */ - -#define AK4114_ADDR 0x20 /*S/PDIF receiver*/ -#define STAC9460_I2C_ADDR 0x54 /* ADC*2 | DAC*6 */ -#define STAC9460_2_I2C_ADDR 0x56 /* ADC|DAC *2 */ - - -extern struct snd_ice1712_card_info snd_vt1724_wtm_cards[]; - -#endif /* __SOUND_WTM_H */ - -- cgit