Commit f0a221ef authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6

* 'for-linus' of ssh://master.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (21 commits)
  ALSA: usb - Use strlcat() correctly
  ALSA: Fix invalid __exit in sound/mips/*.c
  ALSA: hda - Fix / improve ALC66x parser
  ALSA: ctxfi: Swapped SURROUND-SIDE mute
  sound: Make keywest_driver static
  ALSA: intel8x0 - Mute External Amplifier by default for Sony VAIO VGN-B1VP
  ALSA: hda - Fix digita/analog mic auto-switching with IDT codecs
  ASoC: fix kconfig order of Blackfin drivers
  ALSA: hda - Added quirk to enable sound on Toshiba NB200
  ASoC: Fix dependency of CONFIG_SND_PXA2XX_SOC_IMOTE2
  ALSA: Don't assume i2c device probing always succeeds
  ALSA: intel8x0 - Mute External Amplifier by default for Sony VAIO VGN-T350P
  ALSA: echoaudio - Re-enable the line-out control for the Mia card
  ALSA: hda - Resurrect input-source mixer of ALC268 model=acer
  ALSA: hda - Analog Devices AD1984A add HP Touchsmart model
  ALSA: hda - Add HP Pavilion dv4t-1300 to MSI whitelist
  ALSA: hda - CD-audio sound for hda-intel conexant benq laptop
  ASoC: DaVinci: Correct McASP FIFO initialization
  ASoC: Davinci: Fix race with cpu_dai->dma_data
  ASoC: DaVinci: Fix divide by zero error during 1st execution
  ...
parents 9117703f 7fa9742b
...@@ -209,6 +209,7 @@ AD1884A / AD1883 / AD1984A / AD1984B ...@@ -209,6 +209,7 @@ AD1884A / AD1883 / AD1984A / AD1984B
laptop laptop with HP jack sensing laptop laptop with HP jack sensing
mobile mobile devices with HP jack sensing mobile mobile devices with HP jack sensing
thinkpad Lenovo Thinkpad X300 thinkpad Lenovo Thinkpad X300
touchsmart HP Touchsmart
AD1884 AD1884
====== ======
......
...@@ -897,6 +897,15 @@ static int tas_create(struct i2c_adapter *adapter, ...@@ -897,6 +897,15 @@ static int tas_create(struct i2c_adapter *adapter,
client = i2c_new_device(adapter, &info); client = i2c_new_device(adapter, &info);
if (!client) if (!client)
return -ENODEV; return -ENODEV;
/*
* We know the driver is already loaded, so the device should be
* already bound. If not it means binding failed, and then there
* is no point in keeping the device instantiated.
*/
if (!client->driver) {
i2c_unregister_device(client);
return -ENODEV;
}
/* /*
* Let i2c-core delete that device on driver removal. * Let i2c-core delete that device on driver removal.
......
...@@ -915,7 +915,7 @@ static int __devinit hal2_probe(struct platform_device *pdev) ...@@ -915,7 +915,7 @@ static int __devinit hal2_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int __exit hal2_remove(struct platform_device *pdev) static int __devexit hal2_remove(struct platform_device *pdev)
{ {
struct snd_card *card = platform_get_drvdata(pdev); struct snd_card *card = platform_get_drvdata(pdev);
......
...@@ -973,7 +973,7 @@ static int __devinit snd_sgio2audio_probe(struct platform_device *pdev) ...@@ -973,7 +973,7 @@ static int __devinit snd_sgio2audio_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int __exit snd_sgio2audio_remove(struct platform_device *pdev) static int __devexit snd_sgio2audio_remove(struct platform_device *pdev)
{ {
struct snd_card *card = platform_get_drvdata(pdev); struct snd_card *card = platform_get_drvdata(pdev);
......
...@@ -1037,7 +1037,7 @@ static int atc_line_front_unmute(struct ct_atc *atc, unsigned char state) ...@@ -1037,7 +1037,7 @@ static int atc_line_front_unmute(struct ct_atc *atc, unsigned char state)
static int atc_line_surround_unmute(struct ct_atc *atc, unsigned char state) static int atc_line_surround_unmute(struct ct_atc *atc, unsigned char state)
{ {
return atc_daio_unmute(atc, state, LINEO4); return atc_daio_unmute(atc, state, LINEO2);
} }
static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state) static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
...@@ -1047,7 +1047,7 @@ static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state) ...@@ -1047,7 +1047,7 @@ static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
static int atc_line_rear_unmute(struct ct_atc *atc, unsigned char state) static int atc_line_rear_unmute(struct ct_atc *atc, unsigned char state)
{ {
return atc_daio_unmute(atc, state, LINEO2); return atc_daio_unmute(atc, state, LINEO4);
} }
static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state) static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state)
......
...@@ -950,7 +950,7 @@ static int __devinit snd_echo_new_pcm(struct echoaudio *chip) ...@@ -950,7 +950,7 @@ static int __devinit snd_echo_new_pcm(struct echoaudio *chip)
Control interface Control interface
******************************************************************************/ ******************************************************************************/
#ifndef ECHOCARD_HAS_VMIXER #if !defined(ECHOCARD_HAS_VMIXER) || defined(ECHOCARD_HAS_LINE_OUT_GAIN)
/******************* PCM output volume *******************/ /******************* PCM output volume *******************/
static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol, static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol,
...@@ -1003,6 +1003,19 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol, ...@@ -1003,6 +1003,19 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
return changed; return changed;
} }
#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
/* On the Mia this one controls the line-out volume */
static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = {
.name = "Line Playback Volume",
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_TLV_READ,
.info = snd_echo_output_gain_info,
.get = snd_echo_output_gain_get,
.put = snd_echo_output_gain_put,
.tlv = {.p = db_scale_output_gain},
};
#else
static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
.name = "PCM Playback Volume", .name = "PCM Playback Volume",
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
...@@ -1012,9 +1025,10 @@ static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { ...@@ -1012,9 +1025,10 @@ static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
.put = snd_echo_output_gain_put, .put = snd_echo_output_gain_put,
.tlv = {.p = db_scale_output_gain}, .tlv = {.p = db_scale_output_gain},
}; };
#endif #endif
#endif /* !ECHOCARD_HAS_VMIXER || ECHOCARD_HAS_LINE_OUT_GAIN */
#ifdef ECHOCARD_HAS_INPUT_GAIN #ifdef ECHOCARD_HAS_INPUT_GAIN
...@@ -2030,10 +2044,18 @@ static int __devinit snd_echo_probe(struct pci_dev *pci, ...@@ -2030,10 +2044,18 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip); snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip);
if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0)
goto ctl_error; goto ctl_error;
#else #ifdef ECHOCARD_HAS_LINE_OUT_GAIN
if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_pcm_output_gain, chip))) < 0) err = snd_ctl_add(chip->card,
snd_ctl_new1(&snd_echo_line_output_gain, chip));
if (err < 0)
goto ctl_error; goto ctl_error;
#endif #endif
#else /* ECHOCARD_HAS_VMIXER */
err = snd_ctl_add(chip->card,
snd_ctl_new1(&snd_echo_pcm_output_gain, chip));
if (err < 0)
goto ctl_error;
#endif /* ECHOCARD_HAS_VMIXER */
#ifdef ECHOCARD_HAS_INPUT_GAIN #ifdef ECHOCARD_HAS_INPUT_GAIN
if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0)
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define ECHOCARD_HAS_ADAT FALSE #define ECHOCARD_HAS_ADAT FALSE
#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
#define ECHOCARD_HAS_MIDI #define ECHOCARD_HAS_MIDI
#define ECHOCARD_HAS_LINE_OUT_GAIN
/* Pipe indexes */ /* Pipe indexes */
#define PX_ANALOG_OUT 0 /* 8 */ #define PX_ANALOG_OUT 0 /* 8 */
......
...@@ -2303,6 +2303,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev) ...@@ -2303,6 +2303,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
* white-list for enable_msi * white-list for enable_msi
*/ */
static struct snd_pci_quirk msi_white_list[] __devinitdata = { static struct snd_pci_quirk msi_white_list[] __devinitdata = {
SND_PCI_QUIRK(0x103c, 0x30f7, "HP Pavilion dv4t-1300", 1),
SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1), SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1),
{} {}
}; };
......
...@@ -4031,6 +4031,127 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec) ...@@ -4031,6 +4031,127 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec)
return 0; return 0;
} }
/*
* HP Touchsmart
* port-A (0x11) - front hp-out
* port-B (0x14) - unused
* port-C (0x15) - unused
* port-D (0x12) - rear line out
* port-E (0x1c) - front mic-in
* port-F (0x16) - Internal speakers
* digital-mic (0x17) - Internal mic
*/
static struct hda_verb ad1984a_touchsmart_verbs[] = {
/* DACs; unmute as default */
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
/* Port-A (HP) mixer - route only from analog mixer */
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
/* Port-A pin */
{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
/* Port-A (HP) pin - always unmuted */
{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
/* Port-E (int speaker) mixer - route only from analog mixer */
{0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
/* Port-E pin */
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
/* Port-F (int speaker) mixer - route only from analog mixer */
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
/* Port-F pin */
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
/* Analog mixer; mute as default */
{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
/* Analog Mix output amp */
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
/* capture sources */
/* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
/* unsolicited event for pin-sense */
{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
{0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
/* allow to touch GPIO1 (for mute control) */
{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
{0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
/* internal mic - dmic */
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
/* set magic COEFs for dmic */
{0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
{0x01, AC_VERB_SET_PROC_COEF, 0x08},
{ } /* end */
};
static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch",
.info = snd_hda_mixer_amp_switch_info,
.get = snd_hda_mixer_amp_switch_get,
.put = ad1884a_mobile_master_sw_put,
.private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
},
HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
{ } /* end */
};
/* switch to external mic if plugged */
static void ad1984a_touchsmart_automic(struct hda_codec *codec)
{
if (snd_hda_codec_read(codec, 0x1c, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000) {
snd_hda_codec_write(codec, 0x0c, 0,
AC_VERB_SET_CONNECT_SEL, 0x4);
} else {
snd_hda_codec_write(codec, 0x0c, 0,
AC_VERB_SET_CONNECT_SEL, 0x5);
}
}
/* unsolicited event for HP jack sensing */
static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
case AD1884A_HP_EVENT:
ad1884a_hp_automute(codec);
break;
case AD1884A_MIC_EVENT:
ad1984a_touchsmart_automic(codec);
break;
}
}
/* initialize jack-sensing, too */
static int ad1984a_touchsmart_init(struct hda_codec *codec)
{
ad198x_init(codec);
ad1884a_hp_automute(codec);
ad1984a_touchsmart_automic(codec);
return 0;
}
/* /*
*/ */
...@@ -4039,6 +4160,7 @@ enum { ...@@ -4039,6 +4160,7 @@ enum {
AD1884A_LAPTOP, AD1884A_LAPTOP,
AD1884A_MOBILE, AD1884A_MOBILE,
AD1884A_THINKPAD, AD1884A_THINKPAD,
AD1984A_TOUCHSMART,
AD1884A_MODELS AD1884A_MODELS
}; };
...@@ -4047,6 +4169,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = { ...@@ -4047,6 +4169,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
[AD1884A_LAPTOP] = "laptop", [AD1884A_LAPTOP] = "laptop",
[AD1884A_MOBILE] = "mobile", [AD1884A_MOBILE] = "mobile",
[AD1884A_THINKPAD] = "thinkpad", [AD1884A_THINKPAD] = "thinkpad",
[AD1984A_TOUCHSMART] = "touchsmart",
}; };
static struct snd_pci_quirk ad1884a_cfg_tbl[] = { static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
...@@ -4059,6 +4182,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = { ...@@ -4059,6 +4182,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP), SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE), SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
{} {}
}; };
...@@ -4142,6 +4266,21 @@ static int patch_ad1884a(struct hda_codec *codec) ...@@ -4142,6 +4266,21 @@ static int patch_ad1884a(struct hda_codec *codec)
codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
codec->patch_ops.init = ad1984a_thinkpad_init; codec->patch_ops.init = ad1984a_thinkpad_init;
break; break;
case AD1984A_TOUCHSMART:
spec->mixers[0] = ad1984a_touchsmart_mixers;
spec->init_verbs[0] = ad1984a_touchsmart_verbs;
spec->multiout.dig_out_nid = 0;
codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
codec->patch_ops.init = ad1984a_touchsmart_init;
/* set the upper-limit for mixer amp to 0dB for avoiding the
* possible damage by overloading
*/
snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
(0x17 << AC_AMPCAP_OFFSET_SHIFT) |
(0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
(0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
(1 << AC_AMPCAP_MUTE_SHIFT));
break;
} }
return 0; return 0;
......
...@@ -682,11 +682,13 @@ static struct hda_input_mux cxt5045_capture_source = { ...@@ -682,11 +682,13 @@ static struct hda_input_mux cxt5045_capture_source = {
}; };
static struct hda_input_mux cxt5045_capture_source_benq = { static struct hda_input_mux cxt5045_capture_source_benq = {
.num_items = 3, .num_items = 5,
.items = { .items = {
{ "IntMic", 0x1 }, { "IntMic", 0x1 },
{ "ExtMic", 0x2 }, { "ExtMic", 0x2 },
{ "LineIn", 0x3 }, { "LineIn", 0x3 },
{ "CD", 0x4 },
{ "Mixer", 0x0 },
} }
}; };
...@@ -811,11 +813,19 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { ...@@ -811,11 +813,19 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
}; };
static struct snd_kcontrol_new cxt5045_benq_mixers[] = { static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT), HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT), HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT), HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT), HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
{} {}
}; };
......
This diff is collapsed.
...@@ -182,8 +182,8 @@ struct sigmatel_jack { ...@@ -182,8 +182,8 @@ struct sigmatel_jack {
struct sigmatel_mic_route { struct sigmatel_mic_route {
hda_nid_t pin; hda_nid_t pin;
unsigned char mux_idx; signed char mux_idx;
unsigned char dmux_idx; signed char dmux_idx;
}; };
struct sigmatel_spec { struct sigmatel_spec {
...@@ -3469,18 +3469,26 @@ static int set_mic_route(struct hda_codec *codec, ...@@ -3469,18 +3469,26 @@ static int set_mic_route(struct hda_codec *codec,
break; break;
if (i <= AUTO_PIN_FRONT_MIC) { if (i <= AUTO_PIN_FRONT_MIC) {
/* analog pin */ /* analog pin */
mic->dmux_idx = 0;
i = get_connection_index(codec, spec->mux_nids[0], pin); i = get_connection_index(codec, spec->mux_nids[0], pin);
if (i < 0) if (i < 0)
return -1; return -1;
mic->mux_idx = i; mic->mux_idx = i;
mic->dmux_idx = -1;
if (spec->dmux_nids)
mic->dmux_idx = get_connection_index(codec,
spec->dmux_nids[0],
spec->mux_nids[0]);
} else if (spec->dmux_nids) { } else if (spec->dmux_nids) {
/* digital pin */ /* digital pin */
mic->mux_idx = 0;
i = get_connection_index(codec, spec->dmux_nids[0], pin); i = get_connection_index(codec, spec->dmux_nids[0], pin);
if (i < 0) if (i < 0)
return -1; return -1;
mic->dmux_idx = i; mic->dmux_idx = i;
mic->mux_idx = -1;
if (spec->mux_nids)
mic->mux_idx = get_connection_index(codec,
spec->mux_nids[0],
spec->dmux_nids[0]);
} }
return 0; return 0;
} }
...@@ -4557,11 +4565,11 @@ static void stac92xx_mic_detect(struct hda_codec *codec) ...@@ -4557,11 +4565,11 @@ static void stac92xx_mic_detect(struct hda_codec *codec)
mic = &spec->ext_mic; mic = &spec->ext_mic;
else else
mic = &spec->int_mic; mic = &spec->int_mic;
if (mic->dmux_idx) if (mic->dmux_idx >= 0)
snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0, snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
AC_VERB_SET_CONNECT_SEL, AC_VERB_SET_CONNECT_SEL,
mic->dmux_idx); mic->dmux_idx);
else if (mic->mux_idx >= 0)
snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0, snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0,
AC_VERB_SET_CONNECT_SEL, AC_VERB_SET_CONNECT_SEL,
mic->mux_idx); mic->mux_idx);
......
...@@ -1954,6 +1954,18 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { ...@@ -1954,6 +1954,18 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.name = "Sony S1XP", .name = "Sony S1XP",
.type = AC97_TUNE_INV_EAPD .type = AC97_TUNE_INV_EAPD
}, },
{
.subvendor = 0x104d,
.subdevice = 0x81c0,
.name = "Sony VAIO VGN-T350P", /*AD1981B*/
.type = AC97_TUNE_INV_EAPD
},
{
.subvendor = 0x104d,
.subdevice = 0x81c5,
.name = "Sony VAIO VGN-B1VP", /*AD1981B*/
.type = AC97_TUNE_INV_EAPD
},
{ {
.subvendor = 0x1043, .subvendor = 0x1043,
.subdevice = 0x80f3, .subdevice = 0x80f3,
......
...@@ -59,6 +59,18 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter) ...@@ -59,6 +59,18 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter)
strlcpy(info.type, "keywest", I2C_NAME_SIZE); strlcpy(info.type, "keywest", I2C_NAME_SIZE);
info.addr = keywest_ctx->addr; info.addr = keywest_ctx->addr;
keywest_ctx->client = i2c_new_device(adapter, &info); keywest_ctx->client = i2c_new_device(adapter, &info);
if (!keywest_ctx->client)
return -ENODEV;
/*
* We know the driver is already loaded, so the device should be
* already bound. If not it means binding failed, and then there
* is no point in keeping the device instantiated.
*/
if (!keywest_ctx->client->driver) {
i2c_unregister_device(keywest_ctx->client);
keywest_ctx->client = NULL;
return -ENODEV;
}
/* /*
* Let i2c-core delete that device on driver removal. * Let i2c-core delete that device on driver removal.
...@@ -86,7 +98,7 @@ static const struct i2c_device_id keywest_i2c_id[] = { ...@@ -86,7 +98,7 @@ static const struct i2c_device_id keywest_i2c_id[] = {
{ } { }
}; };
struct i2c_driver keywest_driver = { static struct i2c_driver keywest_driver = {
.driver = { .driver = {
.name = "PMac Keywest Audio", .name = "PMac Keywest Audio",
}, },
......
...@@ -7,15 +7,6 @@ config SND_BF5XX_I2S ...@@ -7,15 +7,6 @@ config SND_BF5XX_I2S
mode (supports single stereo In/Out). mode (supports single stereo In/Out).
You will also need to select the audio interfaces to support below. You will also need to select the audio interfaces to support below.
config SND_BF5XX_TDM
tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
depends on (BLACKFIN && SND_SOC)
help
Say Y or M if you want to add support for codecs attached to
the Blackfin SPORT (synchronous serial ports) interface in TDM
mode.
You will also need to select the audio interfaces to support below.
config SND_BF5XX_SOC_SSM2602 config SND_BF5XX_SOC_SSM2602
tristate "SoC SSM2602 Audio support for BF52x ezkit" tristate "SoC SSM2602 Audio support for BF52x ezkit"
depends on SND_BF5XX_I2S depends on SND_BF5XX_I2S
...@@ -41,6 +32,31 @@ config SND_BFIN_AD73311_SE ...@@ -41,6 +32,31 @@ config SND_BFIN_AD73311_SE
Enter the GPIO used to control AD73311's SE pin. Acceptable Enter the GPIO used to control AD73311's SE pin. Acceptable
values are 0 to 7 values are 0 to 7
config SND_BF5XX_TDM
tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
depends on (BLACKFIN && SND_SOC)
help
Say Y or M if you want to add support for codecs attached to
the Blackfin SPORT (synchronous serial ports) interface in TDM
mode.
You will also need to select the audio interfaces to support below.
config SND_BF5XX_SOC_AD1836
tristate "SoC AD1836 Audio support for BF5xx"
depends on SND_BF5XX_TDM
select SND_BF5XX_SOC_TDM
select SND_SOC_AD1836
help
Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
config SND_BF5XX_SOC_AD1938
tristate "SoC AD1938 Audio support for Blackfin"
depends on SND_BF5XX_TDM
select SND_BF5XX_SOC_TDM
select SND_SOC_AD1938
help
Say Y if you want to add support for AD1938 codec on Blackfin.
config SND_BF5XX_AC97 config SND_BF5XX_AC97
tristate "SoC AC97 Audio for the ADI BF5xx chip" tristate "SoC AC97 Audio for the ADI BF5xx chip"
depends on BLACKFIN depends on BLACKFIN
...@@ -71,6 +87,30 @@ config SND_BF5XX_MULTICHAN_SUPPORT ...@@ -71,6 +87,30 @@ config SND_BF5XX_MULTICHAN_SUPPORT
Say y if you want AC97 driver to support up to 5.1 channel audio. Say y if you want AC97 driver to support up to 5.1 channel audio.
this mode will consume much more memory for DMA. this mode will consume much more memory for DMA.
config SND_BF5XX_HAVE_COLD_RESET
bool "BOARD has COLD Reset GPIO"
depends on SND_BF5XX_AC97
default y if BFIN548_EZKIT
default n if !BFIN548_EZKIT
config SND_BF5XX_RESET_GPIO_NUM
int "Set a GPIO for cold reset"
depends on SND_BF5XX_HAVE_COLD_RESET
range 0 159
default 19 if BFIN548_EZKIT
default 5 if BFIN537_STAMP
default 0
help
Set the correct GPIO for RESET the sound chip.
config SND_BF5XX_SOC_AD1980
tristate "SoC AD1980/1 Audio support for BF5xx"
depends on SND_BF5XX_AC97
select SND_BF5XX_SOC_AC97
select SND_SOC_AD1980
help
Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
config SND_BF5XX_SOC_SPORT config SND_BF5XX_SOC_SPORT
tristate tristate
...@@ -88,30 +128,6 @@ config SND_BF5XX_SOC_AC97 ...@@ -88,30 +128,6 @@ config SND_BF5XX_SOC_AC97
select SND_SOC_AC97_BUS select SND_SOC_AC97_BUS
select SND_BF5XX_SOC_SPORT select SND_BF5XX_SOC_SPORT
config SND_BF5XX_SOC_AD1836
tristate "SoC AD1836 Audio support for BF5xx"
depends on SND_BF5XX_TDM
select SND_BF5XX_SOC_TDM
select SND_SOC_AD1836
help
Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
config SND_BF5XX_SOC_AD1980
tristate "SoC AD1980/1 Audio support for BF5xx"
depends on SND_BF5XX_AC97
select SND_BF5XX_SOC_AC97
select SND_SOC_AD1980
help
Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
config SND_BF5XX_SOC_AD1938
tristate "SoC AD1938 Audio support for Blackfin"
depends on SND_BF5XX_TDM
select SND_BF5XX_SOC_TDM
select SND_SOC_AD1938
help
Say Y if you want to add support for AD1938 codec on Blackfin.
config SND_BF5XX_SPORT_NUM config SND_BF5XX_SPORT_NUM
int "Set a SPORT for Sound chip" int "Set a SPORT for Sound chip"
depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM) depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM)
...@@ -120,19 +136,3 @@ config SND_BF5XX_SPORT_NUM ...@@ -120,19 +136,3 @@ config SND_BF5XX_SPORT_NUM
default 0 default 0
help help
Set the correct SPORT for sound chip. Set the correct SPORT for sound chip.
config SND_BF5XX_HAVE_COLD_RESET
bool "BOARD has COLD Reset GPIO"
depends on SND_BF5XX_AC97
default y if BFIN548_EZKIT
default n if !BFIN548_EZKIT
config SND_BF5XX_RESET_GPIO_NUM
int "Set a GPIO for cold reset"
depends on SND_BF5XX_HAVE_COLD_RESET
range 0 159
default 19 if BFIN548_EZKIT
default 5 if BFIN537_STAMP
default 0
help
Set the correct GPIO for RESET the sound chip.
...@@ -77,12 +77,12 @@ static struct sport_param sport_params[2] = { ...@@ -77,12 +77,12 @@ static struct sport_param sport_params[2] = {
* TFS. When Port G is selected and EMAC then there is a conflict between * TFS. When Port G is selected and EMAC then there is a conflict between
* the PHY interrupt line and TFS. Current settings prevent the conflict * the PHY interrupt line and TFS. Current settings prevent the conflict
* by ignoring the TFS pin when Port G is selected. This allows both * by ignoring the TFS pin when Port G is selected. This allows both
* ssm2602 using Port G and EMAC concurrently. * codecs and EMAC using Port G concurrently.
*/ */
#ifdef CONFIG_BF527_SPORT0_PORTF #ifdef CONFIG_BF527_SPORT0_PORTG
#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
#else
#define LOCAL_SPORT0_TFS (0) #define LOCAL_SPORT0_TFS (0)
#else
#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
#endif #endif
static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
......
...@@ -78,12 +78,12 @@ static struct sport_param sport_params[2] = { ...@@ -78,12 +78,12 @@ static struct sport_param sport_params[2] = {
* TFS. When Port G is selected and EMAC then there is a conflict between * TFS. When Port G is selected and EMAC then there is a conflict between
* the PHY interrupt line and TFS. Current settings prevent the conflict * the PHY interrupt line and TFS. Current settings prevent the conflict
* by ignoring the TFS pin when Port G is selected. This allows both * by ignoring the TFS pin when Port G is selected. This allows both
* ssm2602 using Port G and EMAC concurrently. * codecs and EMAC using Port G concurrently.
*/ */
#ifdef CONFIG_BF527_SPORT0_PORTF #ifdef CONFIG_BF527_SPORT0_PORTG
#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
#else
#define LOCAL_SPORT0_TFS (0) #define LOCAL_SPORT0_TFS (0)
#else
#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
#endif #endif
static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
......
...@@ -97,22 +97,19 @@ enum { ...@@ -97,22 +97,19 @@ enum {
DAVINCI_MCBSP_WORD_32, DAVINCI_MCBSP_WORD_32,
}; };
static struct davinci_pcm_dma_params davinci_i2s_pcm_out = {
.name = "I2S PCM Stereo out",
};
static struct davinci_pcm_dma_params davinci_i2s_pcm_in = {
.name = "I2S PCM Stereo in",
};
struct davinci_mcbsp_dev { struct davinci_mcbsp_dev {
/*
* dma_params must be first because rtd->dai->cpu_dai->private_data
* is cast to a pointer of an array of struct davinci_pcm_dma_params in
* davinci_pcm_open.
*/
struct davinci_pcm_dma_params dma_params[2];
void __iomem *base; void __iomem *base;
#define MOD_DSP_A 0 #define MOD_DSP_A 0
#define MOD_DSP_B 1 #define MOD_DSP_B 1
int mode; int mode;
u32 pcr; u32 pcr;
struct clk *clk; struct clk *clk;
struct davinci_pcm_dma_params *dma_params[2];
}; };
static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev, static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
...@@ -215,14 +212,6 @@ static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback) ...@@ -215,14 +212,6 @@ static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
toggle_clock(dev, playback); toggle_clock(dev, playback);
} }
static int davinci_i2s_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
cpu_dai->dma_data = dev->dma_params[substream->stream];
return 0;
}
#define DEFAULT_BITPERSAMPLE 16 #define DEFAULT_BITPERSAMPLE 16
static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
...@@ -353,8 +342,9 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -353,8 +342,9 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct davinci_pcm_dma_params *dma_params = dai->dma_data;
struct davinci_mcbsp_dev *dev = dai->private_data; struct davinci_mcbsp_dev *dev = dai->private_data;
struct davinci_pcm_dma_params *dma_params =
&dev->dma_params[substream->stream];
struct snd_interval *i = NULL; struct snd_interval *i = NULL;
int mcbsp_word_length; int mcbsp_word_length;
unsigned int rcr, xcr, srgr; unsigned int rcr, xcr, srgr;
...@@ -472,7 +462,6 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, ...@@ -472,7 +462,6 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 #define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
static struct snd_soc_dai_ops davinci_i2s_dai_ops = { static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
.startup = davinci_i2s_startup,
.shutdown = davinci_i2s_shutdown, .shutdown = davinci_i2s_shutdown,
.prepare = davinci_i2s_prepare, .prepare = davinci_i2s_prepare,
.trigger = davinci_i2s_trigger, .trigger = davinci_i2s_trigger,
...@@ -534,12 +523,10 @@ static int davinci_i2s_probe(struct platform_device *pdev) ...@@ -534,12 +523,10 @@ static int davinci_i2s_probe(struct platform_device *pdev)
dev->base = (void __iomem *)IO_ADDRESS(mem->start); dev->base = (void __iomem *)IO_ADDRESS(mem->start);
dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out; dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr =
(dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG); (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG);
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in; dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr =
(dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG); (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG);
/* first TX, then RX */ /* first TX, then RX */
...@@ -549,7 +536,7 @@ static int davinci_i2s_probe(struct platform_device *pdev) ...@@ -549,7 +536,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
ret = -ENXIO; ret = -ENXIO;
goto err_free_mem; goto err_free_mem;
} }
dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = res->start; dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;
res = platform_get_resource(pdev, IORESOURCE_DMA, 1); res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!res) { if (!res) {
...@@ -557,7 +544,7 @@ static int davinci_i2s_probe(struct platform_device *pdev) ...@@ -557,7 +544,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
ret = -ENXIO; ret = -ENXIO;
goto err_free_mem; goto err_free_mem;
} }
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = res->start; dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
davinci_i2s_dai.private_data = dev; davinci_i2s_dai.private_data = dev;
ret = snd_soc_register_dai(&davinci_i2s_dai); ret = snd_soc_register_dai(&davinci_i2s_dai);
......
...@@ -332,14 +332,6 @@ static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val) ...@@ -332,14 +332,6 @@ static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val)
printk(KERN_ERR "GBLCTL write error\n"); printk(KERN_ERR "GBLCTL write error\n");
} }
static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct davinci_audio_dev *dev = cpu_dai->private_data;
cpu_dai->dma_data = dev->dma_params[substream->stream];
return 0;
}
static void mcasp_start_rx(struct davinci_audio_dev *dev) static void mcasp_start_rx(struct davinci_audio_dev *dev)
{ {
mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST);
...@@ -386,17 +378,17 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev) ...@@ -386,17 +378,17 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev)
static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
{ {
if (stream == SNDRV_PCM_STREAM_PLAYBACK) if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (dev->txnumevt) /* enable FIFO */
mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
FIFO_ENABLE);
mcasp_start_tx(dev); mcasp_start_tx(dev);
else } else {
if (dev->rxnumevt) /* enable FIFO */
mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
FIFO_ENABLE);
mcasp_start_rx(dev); mcasp_start_rx(dev);
}
/* enable FIFO */
if (dev->txnumevt)
mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
if (dev->rxnumevt)
mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
} }
static void mcasp_stop_rx(struct davinci_audio_dev *dev) static void mcasp_stop_rx(struct davinci_audio_dev *dev)
...@@ -413,17 +405,17 @@ static void mcasp_stop_tx(struct davinci_audio_dev *dev) ...@@ -413,17 +405,17 @@ static void mcasp_stop_tx(struct davinci_audio_dev *dev)
static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream) static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
{ {
if (stream == SNDRV_PCM_STREAM_PLAYBACK) if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (dev->txnumevt) /* disable FIFO */
mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
FIFO_ENABLE);
mcasp_stop_tx(dev); mcasp_stop_tx(dev);
else } else {
if (dev->rxnumevt) /* disable FIFO */
mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
FIFO_ENABLE);
mcasp_stop_rx(dev); mcasp_stop_rx(dev);
}
/* disable FIFO */
if (dev->txnumevt)
mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
if (dev->rxnumevt)
mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
} }
static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
...@@ -720,7 +712,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, ...@@ -720,7 +712,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
{ {
struct davinci_audio_dev *dev = cpu_dai->private_data; struct davinci_audio_dev *dev = cpu_dai->private_data;
struct davinci_pcm_dma_params *dma_params = struct davinci_pcm_dma_params *dma_params =
dev->dma_params[substream->stream]; &dev->dma_params[substream->stream];
int word_length; int word_length;
u8 numevt; u8 numevt;
...@@ -798,7 +790,6 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, ...@@ -798,7 +790,6 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
} }
static struct snd_soc_dai_ops davinci_mcasp_dai_ops = { static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
.startup = davinci_mcasp_startup,
.trigger = davinci_mcasp_trigger, .trigger = davinci_mcasp_trigger,
.hw_params = davinci_mcasp_hw_params, .hw_params = davinci_mcasp_hw_params,
.set_fmt = davinci_mcasp_set_dai_fmt, .set_fmt = davinci_mcasp_set_dai_fmt,
...@@ -849,20 +840,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -849,20 +840,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
struct resource *mem, *ioarea, *res; struct resource *mem, *ioarea, *res;
struct snd_platform_data *pdata; struct snd_platform_data *pdata;
struct davinci_audio_dev *dev; struct davinci_audio_dev *dev;
int count = 0;
int ret = 0; int ret = 0;
dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL); dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL);
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
dma_data = kzalloc(sizeof(struct davinci_pcm_dma_params) * 2,
GFP_KERNEL);
if (!dma_data) {
ret = -ENOMEM;
goto err_release_dev;
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) { if (!mem) {
dev_err(&pdev->dev, "no mem resource?\n"); dev_err(&pdev->dev, "no mem resource?\n");
...@@ -897,11 +880,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -897,11 +880,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dev->txnumevt = pdata->txnumevt; dev->txnumevt = pdata->txnumevt;
dev->rxnumevt = pdata->rxnumevt; dev->rxnumevt = pdata->rxnumevt;
dma_data[count].name = "I2S PCM Stereo out"; dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
dma_data[count].eventq_no = pdata->eventq_no; dma_data->eventq_no = pdata->eventq_no;
dma_data[count].dma_addr = (dma_addr_t) (pdata->tx_dma_offset + dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
io_v2p(dev->base)); io_v2p(dev->base));
dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &dma_data[count];
/* first TX, then RX */ /* first TX, then RX */
res = platform_get_resource(pdev, IORESOURCE_DMA, 0); res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
...@@ -910,13 +892,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -910,13 +892,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
goto err_release_region; goto err_release_region;
} }
dma_data[count].channel = res->start; dma_data->channel = res->start;
count++;
dma_data[count].name = "I2S PCM Stereo in"; dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
dma_data[count].eventq_no = pdata->eventq_no; dma_data->eventq_no = pdata->eventq_no;
dma_data[count].dma_addr = (dma_addr_t)(pdata->rx_dma_offset + dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
io_v2p(dev->base)); io_v2p(dev->base));
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &dma_data[count];
res = platform_get_resource(pdev, IORESOURCE_DMA, 1); res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!res) { if (!res) {
...@@ -924,7 +905,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -924,7 +905,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
goto err_release_region; goto err_release_region;
} }
dma_data[count].channel = res->start; dma_data->channel = res->start;
davinci_mcasp_dai[pdata->op_mode].private_data = dev; davinci_mcasp_dai[pdata->op_mode].private_data = dev;
davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev; davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]); ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
...@@ -936,8 +917,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -936,8 +917,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
err_release_region: err_release_region:
release_mem_region(mem->start, (mem->end - mem->start) + 1); release_mem_region(mem->start, (mem->end - mem->start) + 1);
err_release_data: err_release_data:
kfree(dma_data);
err_release_dev:
kfree(dev); kfree(dev);
return ret; return ret;
...@@ -946,7 +925,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -946,7 +925,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
static int davinci_mcasp_remove(struct platform_device *pdev) static int davinci_mcasp_remove(struct platform_device *pdev)
{ {
struct snd_platform_data *pdata = pdev->dev.platform_data; struct snd_platform_data *pdata = pdev->dev.platform_data;
struct davinci_pcm_dma_params *dma_data;
struct davinci_audio_dev *dev; struct davinci_audio_dev *dev;
struct resource *mem; struct resource *mem;
...@@ -959,8 +937,6 @@ static int davinci_mcasp_remove(struct platform_device *pdev) ...@@ -959,8 +937,6 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, (mem->end - mem->start) + 1); release_mem_region(mem->start, (mem->end - mem->start) + 1);
dma_data = dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
kfree(dma_data);
kfree(dev); kfree(dev);
return 0; return 0;
......
...@@ -39,10 +39,15 @@ enum { ...@@ -39,10 +39,15 @@ enum {
}; };
struct davinci_audio_dev { struct davinci_audio_dev {
/*
* dma_params must be first because rtd->dai->cpu_dai->private_data
* is cast to a pointer of an array of struct davinci_pcm_dma_params in
* davinci_pcm_open.
*/
struct davinci_pcm_dma_params dma_params[2];
void __iomem *base; void __iomem *base;
int sample_rate; int sample_rate;
struct clk *clk; struct clk *clk;
struct davinci_pcm_dma_params *dma_params[2];
unsigned int codec_fmt; unsigned int codec_fmt;
/* McASP specific data */ /* McASP specific data */
......
...@@ -126,16 +126,9 @@ static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data) ...@@ -126,16 +126,9 @@ static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data)
static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
{ {
struct davinci_runtime_data *prtd = substream->runtime->private_data; struct davinci_runtime_data *prtd = substream->runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct davinci_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
struct edmacc_param p_ram; struct edmacc_param p_ram;
int ret; int ret;
if (!dma_data)
return -ENODEV;
prtd->params = dma_data;
/* Request master DMA channel */ /* Request master DMA channel */
ret = edma_alloc_channel(prtd->params->channel, ret = edma_alloc_channel(prtd->params->channel,
davinci_pcm_dma_irq, substream, davinci_pcm_dma_irq, substream,
...@@ -244,6 +237,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream) ...@@ -244,6 +237,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct davinci_runtime_data *prtd; struct davinci_runtime_data *prtd;
int ret = 0; int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->private_data;
struct davinci_pcm_dma_params *params = &pa[substream->stream];
if (!params)
return -ENODEV;
snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware); snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware);
/* ensure that buffer size is a multiple of period size */ /* ensure that buffer size is a multiple of period size */
...@@ -257,6 +255,7 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream) ...@@ -257,6 +255,7 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&prtd->lock); spin_lock_init(&prtd->lock);
prtd->params = params;
runtime->private_data = prtd; runtime->private_data = prtd;
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
struct davinci_pcm_dma_params { struct davinci_pcm_dma_params {
char *name; /* stream identifier */
int channel; /* sync dma channel ID */ int channel; /* sync dma channel ID */
unsigned short acnt; unsigned short acnt;
dma_addr_t dma_addr; /* device physical address for DMA */ dma_addr_t dma_addr; /* device physical address for DMA */
......
...@@ -138,7 +138,7 @@ config SND_PXA2XX_SOC_MIOA701 ...@@ -138,7 +138,7 @@ config SND_PXA2XX_SOC_MIOA701
config SND_PXA2XX_SOC_IMOTE2 config SND_PXA2XX_SOC_IMOTE2
tristate "SoC Audio support for IMote 2" tristate "SoC Audio support for IMote 2"
depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 && I2C
select SND_PXA2XX_SOC_I2S select SND_PXA2XX_SOC_I2S
select SND_SOC_WM8940 select SND_SOC_WM8940
help help
......
...@@ -898,6 +898,11 @@ static struct snd_kcontrol_new usb_feature_unit_ctl = { ...@@ -898,6 +898,11 @@ static struct snd_kcontrol_new usb_feature_unit_ctl = {
* build a feature control * build a feature control
*/ */
static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
{
return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
}
static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
unsigned int ctl_mask, int control, unsigned int ctl_mask, int control,
struct usb_audio_term *iterm, int unitid) struct usb_audio_term *iterm, int unitid)
...@@ -978,13 +983,13 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, ...@@ -978,13 +983,13 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
*/ */
if (! mapped_name && ! (state->oterm.type >> 16)) { if (! mapped_name && ! (state->oterm.type >> 16)) {
if ((state->oterm.type & 0xff00) == 0x0100) { if ((state->oterm.type & 0xff00) == 0x0100) {
len = strlcat(kctl->id.name, " Capture", sizeof(kctl->id.name)); len = append_ctl_name(kctl, " Capture");
} else { } else {
len = strlcat(kctl->id.name + len, " Playback", sizeof(kctl->id.name)); len = append_ctl_name(kctl, " Playback");
} }
} }
strlcat(kctl->id.name + len, control == USB_FEATURE_MUTE ? " Switch" : " Volume", append_ctl_name(kctl, control == USB_FEATURE_MUTE ?
sizeof(kctl->id.name)); " Switch" : " Volume");
if (control == USB_FEATURE_VOLUME) { if (control == USB_FEATURE_VOLUME) {
kctl->tlv.c = mixer_vol_tlv; kctl->tlv.c = mixer_vol_tlv;
kctl->vd[0].access |= kctl->vd[0].access |=
...@@ -1143,7 +1148,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc, ...@@ -1143,7 +1148,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0); len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
if (! len) if (! len)
len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1); len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
strlcat(kctl->id.name + len, " Volume", sizeof(kctl->id.name)); append_ctl_name(kctl, " Volume");
snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n", snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n",
cval->id, kctl->id.name, cval->channels, cval->min, cval->max); cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
...@@ -1400,8 +1405,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned ...@@ -1400,8 +1405,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
if (! len) if (! len)
strlcpy(kctl->id.name, name, sizeof(kctl->id.name)); strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
} }
strlcat(kctl->id.name, " ", sizeof(kctl->id.name)); append_ctl_name(kctl, " ");
strlcat(kctl->id.name, valinfo->suffix, sizeof(kctl->id.name)); append_ctl_name(kctl, valinfo->suffix);
snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n", snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n",
cval->id, kctl->id.name, cval->channels, cval->min, cval->max); cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
...@@ -1610,9 +1615,9 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi ...@@ -1610,9 +1615,9 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name)); strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
if ((state->oterm.type & 0xff00) == 0x0100) if ((state->oterm.type & 0xff00) == 0x0100)
strlcat(kctl->id.name, " Capture Source", sizeof(kctl->id.name)); append_ctl_name(kctl, " Capture Source");
else else
strlcat(kctl->id.name, " Playback Source", sizeof(kctl->id.name)); append_ctl_name(kctl, " Playback Source");
} }
snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n", snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment