diff options
Diffstat (limited to 'sound/pci/ice1712/revo.c')
| -rw-r--r-- | sound/pci/ice1712/revo.c | 120 |
1 files changed, 69 insertions, 51 deletions
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 301bf929acd..1112ec1953b 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -1,7 +1,7 @@ /* * ALSA driver for ICEnsemble ICE1712 (Envy24) * - * Lowlevel functions for M-Audio Revolution 7.1 + * Lowlevel functions for M-Audio Audiophile 192, Revolution 7.1 and 5.1 * * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de> * @@ -21,7 +21,6 @@ * */ -#include <asm/io.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/init.h> @@ -36,6 +35,7 @@ struct revo51_spec { struct snd_i2c_device *dev; struct snd_pt2258 *pt2258; + struct ak4114 *ak4114; }; static void revo_i2s_mclk_changed(struct snd_ice1712 *ice) @@ -48,7 +48,7 @@ static void revo_i2s_mclk_changed(struct snd_ice1712 *ice) } /* - * change the rate of envy24HT, AK4355 and AK4381 + * change the rate of Envy24HT, AK4355 and AK4381 */ static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) { @@ -83,8 +83,8 @@ static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) 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); /* the value is written in reset(0) */ + /* 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); } @@ -216,6 +216,7 @@ static const struct snd_akm4xxx_dac_channel revo51_dac[] = { 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[] = { @@ -234,7 +235,7 @@ static const struct snd_akm4xxx_adc_channel revo51_adc[] = { }, }; -static struct snd_akm4xxx akm_revo_front __devinitdata = { +static struct snd_akm4xxx akm_revo_front = { .type = SND_AK4381, .num_dacs = 2, .ops = { @@ -243,7 +244,7 @@ static struct snd_akm4xxx akm_revo_front __devinitdata = { .dac_info = revo71_front, }; -static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo_front_priv = { .caddr = 1, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -255,7 +256,7 @@ static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_revo_surround __devinitdata = { +static struct snd_akm4xxx akm_revo_surround = { .type = SND_AK4355, .idx_offset = 1, .num_dacs = 6, @@ -265,7 +266,7 @@ static struct snd_akm4xxx akm_revo_surround __devinitdata = { .dac_info = revo71_surround, }; -static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo_surround_priv = { .caddr = 3, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -277,16 +278,16 @@ static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_revo51 __devinitdata = { +static struct snd_akm4xxx akm_revo51 = { .type = SND_AK4358, - .num_dacs = 6, + .num_dacs = 8, .ops = { .set_rate_val = revo_set_rate_val }, .dac_info = revo51_dac, }; -static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo51_priv = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -298,13 +299,13 @@ static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_revo51_adc __devinitdata = { +static struct snd_akm4xxx akm_revo51_adc = { .type = SND_AK5365, .num_adcs = 2, .adc_info = revo51_adc, }; -static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo51_adc_priv = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -322,24 +323,30 @@ static struct snd_pt2258 ptc_revo51_volume; 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); -#if 1 /* FIXME: do we need this procedure? */ - /* reset DFS pin of AK5385A for ADC, too */ - /* DFS0 (pin 18) -- GPIO10 pin 77 */ - snd_ice1712_save_gpio_status(ice); - snd_ice1712_gpio_write_bits(ice, 1 << 10, - rate > 48000 ? (1 << 10) : 0); - snd_ice1712_restore_gpio_status(ice); -#endif + /* 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 = { +static struct snd_akm4xxx akm_ap192 = { .type = SND_AK4358, .num_dacs = 2, .ops = { @@ -348,7 +355,7 @@ static struct snd_akm4xxx akm_ap192 __devinitdata = { .dac_info = ap192_dac, }; -static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { +static struct snd_ak4xxx_private akm_ap192_priv = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -360,14 +367,6 @@ static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { .mask_flags = 0, }; -#if 0 -/* FIXME: ak4114 makes the sound much lower due to some confliction, - * so let's disable it right now... - */ -#define BUILD_AK4114_AP192 -#endif - -#ifdef BUILD_AK4114_AP192 /* AK4114 support on Audiophile 192 */ /* CDTO (pin 32) -- GPIO2 pin 52 * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358) @@ -469,31 +468,40 @@ static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr) return data; } -static int __devinit ap192_ak4114_init(struct snd_ice1712 *ice) +static int ap192_ak4114_init(struct snd_ice1712 *ice) { static const unsigned char ak4114_init_vals[] = { - AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, + AK4114_RST | AK4114_PWN | AK4114_OCKS0, AK4114_DIF_I24I2S, AK4114_TX1E, - AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1), + AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(0), 0, 0 }; static const unsigned char ak4114_init_txcsb[] = { 0x41, 0x02, 0x2c, 0x00, 0x00 }; - struct ak4114 *ak; int err; - return snd_ak4114_create(ice->card, + struct revo51_spec *spec; + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return -ENOMEM; + ice->spec = spec; + + err = snd_ak4114_create(ice->card, ap192_ak4114_read, ap192_ak4114_write, ak4114_init_vals, ak4114_init_txcsb, - ice, &ak); + ice, &spec->ak4114); + /* AK4114 in Revo 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; /* error ignored; it's no fatal error */ } -#endif /* BUILD_AK4114_AP192 */ -static int __devinit revo_init(struct snd_ice1712 *ice) +static int revo_init(struct snd_ice1712 *ice) { struct snd_akm4xxx *ak; int err; @@ -506,7 +514,7 @@ static int __devinit revo_init(struct snd_ice1712 *ice) ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed; break; case VT1724_SUBDEVICE_REVOLUTION51: - ice->num_total_dacs = 6; + ice->num_total_dacs = 8; ice->num_total_adcs = 2; break; case VT1724_SUBDEVICE_AUDIOPHILE192: @@ -522,16 +530,20 @@ static int __devinit revo_init(struct snd_ice1712 *ice) ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL); if (! ak) return -ENOMEM; - ice->akm_codecs = 2; switch (ice->eeprom.subvendor) { case VT1724_SUBDEVICE_REVOLUTION71: ice->akm_codecs = 2; - if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, &akm_revo_front_priv, ice)) < 0) + err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, + &akm_revo_front_priv, ice); + if (err < 0) return err; - if ((err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, &akm_revo_surround_priv, ice)) < 0) + 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); + snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, + VT1724_REVO_MUTE); break; case VT1724_SUBDEVICE_REVOLUTION51: ice->akm_codecs = 2; @@ -556,7 +568,13 @@ static int __devinit revo_init(struct snd_ice1712 *ice) ice); if (err < 0) return err; + err = ap192_ak4114_init(ice); + if (err < 0) + return err; + /* unmute all codecs */ + snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, + VT1724_REVO_MUTE); break; } @@ -564,9 +582,9 @@ static int __devinit revo_init(struct snd_ice1712 *ice) } -static int __devinit revo_add_controls(struct snd_ice1712 *ice) +static int revo_add_controls(struct snd_ice1712 *ice) { - struct revo51_spec *spec; + struct revo51_spec *spec = ice->spec; int err; switch (ice->eeprom.subvendor) { @@ -588,18 +606,18 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice) err = snd_ice1712_akm4xxx_build_controls(ice); if (err < 0) return err; -#ifdef BUILD_AK4114_AP192 - err = ap192_ak4114_init(ice); + /* 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; -#endif break; } return 0; } /* entry point */ -struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_revo_cards[] = { { .subvendor = VT1724_SUBDEVICE_REVOLUTION71, .name = "M Audio Revolution-7.1", |
