Merge branch 'master' into for-next

This commit is contained in:
Jiri Kosina
2010-08-04 15:14:38 +02:00
bovenliggende 73b2c7165b 3a09b1be53
commit d790d4d583
1744 gewijzigde bestanden met toevoegingen van 34752 en 212871 verwijderingen

Bestand weergeven

@@ -941,11 +941,11 @@ static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
}
static long outstream_get_space_available(struct hpi_hostbuffer_status
static u32 outstream_get_space_available(struct hpi_hostbuffer_status
*status)
{
return status->size_in_bytes - ((long)(status->host_index) -
(long)(status->dSP_index));
return status->size_in_bytes - (status->host_index -
status->dSP_index);
}
static void outstream_write(struct hpi_adapter_obj *pao,
@@ -954,7 +954,7 @@ static void outstream_write(struct hpi_adapter_obj *pao,
struct hpi_hw_obj *phw = pao->priv;
struct bus_master_interface *interface = phw->p_interface_buffer;
struct hpi_hostbuffer_status *status;
long space_available;
u32 space_available;
if (!phw->outstream_host_buffer_size[phm->obj_index]) {
/* there is no BBM buffer, write via message */
@@ -1007,7 +1007,7 @@ static void outstream_write(struct hpi_adapter_obj *pao,
}
space_available = outstream_get_space_available(status);
if (space_available < (long)phm->u.d.u.data.data_size) {
if (space_available < phm->u.d.u.data.data_size) {
phr->error = HPI_ERROR_INVALID_DATASIZE;
return;
}
@@ -1018,7 +1018,7 @@ static void outstream_write(struct hpi_adapter_obj *pao,
&& hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
obj_index])) {
u8 *p_bbm_data;
long l_first_write;
u32 l_first_write;
u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
if (hpios_locked_mem_get_virt_addr(&phw->
@@ -1248,9 +1248,9 @@ static void instream_start(struct hpi_adapter_obj *pao,
hw_message(pao, phm, phr);
}
static long instream_get_bytes_available(struct hpi_hostbuffer_status *status)
static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status)
{
return (long)(status->dSP_index) - (long)(status->host_index);
return status->dSP_index - status->host_index;
}
static void instream_read(struct hpi_adapter_obj *pao,
@@ -1259,9 +1259,9 @@ static void instream_read(struct hpi_adapter_obj *pao,
struct hpi_hw_obj *phw = pao->priv;
struct bus_master_interface *interface = phw->p_interface_buffer;
struct hpi_hostbuffer_status *status;
long data_available;
u32 data_available;
u8 *p_bbm_data;
long l_first_read;
u32 l_first_read;
u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
if (!phw->instream_host_buffer_size[phm->obj_index]) {
@@ -1272,7 +1272,7 @@ static void instream_read(struct hpi_adapter_obj *pao,
status = &interface->instream_host_buffer_status[phm->obj_index];
data_available = instream_get_bytes_available(status);
if (data_available < (long)phm->u.d.u.data.data_size) {
if (data_available < phm->u.d.u.data.data_size) {
phr->error = HPI_ERROR_INVALID_DATASIZE;
return;
}

Bestand weergeven

@@ -784,6 +784,9 @@ static int read_pin_defaults(struct hda_codec *codec)
pin->nid = nid;
pin->cfg = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_CONFIG_DEFAULT, 0);
pin->ctrl = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_PIN_WIDGET_CONTROL,
0);
}
return 0;
}
@@ -912,15 +915,38 @@ static void restore_pincfgs(struct hda_codec *codec)
void snd_hda_shutup_pins(struct hda_codec *codec)
{
int i;
/* don't shut up pins when unloading the driver; otherwise it breaks
* the default pin setup at the next load of the driver
*/
if (codec->bus->shutdown)
return;
for (i = 0; i < codec->init_pins.used; i++) {
struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
/* use read here for syncing after issuing each verb */
snd_hda_codec_read(codec, pin->nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
}
codec->pins_shutup = 1;
}
EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);
/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */
static void restore_shutup_pins(struct hda_codec *codec)
{
int i;
if (!codec->pins_shutup)
return;
if (codec->bus->shutdown)
return;
for (i = 0; i < codec->init_pins.used; i++) {
struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
snd_hda_codec_write(codec, pin->nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
pin->ctrl);
}
codec->pins_shutup = 0;
}
static void init_hda_cache(struct hda_cache_rec *cache,
unsigned int record_size);
static void free_hda_cache(struct hda_cache_rec *cache);
@@ -2907,6 +2933,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
codec->afg ? codec->afg : codec->mfg,
AC_PWRST_D0);
restore_pincfgs(codec); /* restore all current pin configs */
restore_shutup_pins(codec);
hda_exec_init_verbs(codec);
if (codec->patch_ops.resume)
codec->patch_ops.resume(codec);

Bestand weergeven

@@ -821,6 +821,7 @@ struct hda_codec {
unsigned int pin_amp_workaround:1; /* pin out-amp takes index
* (e.g. Conexant codecs)
*/
unsigned int pins_shutup:1; /* pins are shut up */
unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
#ifdef CONFIG_SND_HDA_POWER_SAVE
unsigned int power_on :1; /* current (global) power-state */
@@ -897,7 +898,9 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec);
/* the struct for codec->pin_configs */
struct hda_pincfg {
hda_nid_t nid;
unsigned int cfg;
unsigned char ctrl; /* current pin control value */
unsigned char pad; /* reserved */
unsigned int cfg; /* default configuration */
};
unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid);

Bestand weergeven

@@ -52,6 +52,10 @@ struct hdmi_spec {
*/
struct hda_multi_out multiout;
unsigned int codec_type;
/* misc flags */
/* PD bit indicates only the update, not the current state */
unsigned int old_pin_detect:1;
};
@@ -616,6 +620,9 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
* Unsolicited events
*/
static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
struct hdmi_eld *eld);
static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
{
struct hdmi_spec *spec = codec->spec;
@@ -632,6 +639,12 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
if (index < 0)
return;
if (spec->old_pin_detect) {
if (pind)
hdmi_present_sense(codec, tag, &spec->sink_eld[index]);
pind = spec->sink_eld[index].monitor_present;
}
spec->sink_eld[index].monitor_present = pind;
spec->sink_eld[index].eld_valid = eldv;

Bestand weergeven

@@ -478,6 +478,7 @@ static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
codec->spec = spec;
spec->codec_type = HDA_CODEC_NVIDIA_MCP89;
spec->old_pin_detect = 1;
if (hdmi_parse_codec(codec) < 0) {
codec->spec = NULL;
@@ -508,6 +509,7 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
spec->multiout.max_channels = 8;
spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
spec->old_pin_detect = 1;
codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
@@ -528,6 +530,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
spec->multiout.max_channels = 2;
spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
spec->old_pin_detect = 1;
codec->patch_ops = nvhdmi_patch_ops_2ch;

Bestand weergeven

@@ -1267,6 +1267,8 @@ static int alc_auto_parse_customize_define(struct hda_codec *codec)
unsigned nid = 0;
struct alc_spec *spec = codec->spec;
spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
ass = codec->subsystem_id & 0xffff;
if (ass != codec->bus->pci->subsystem_device && (ass & 1))
goto do_sku;
@@ -2547,7 +2549,7 @@ static struct snd_kcontrol_new alc_beep_mixer[] = {
static int alc_build_controls(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
struct snd_kcontrol *kctl;
struct snd_kcontrol *kctl = NULL;
struct snd_kcontrol_new *knew;
int i, j, err;
unsigned int u;
@@ -2619,16 +2621,18 @@ static int alc_build_controls(struct hda_codec *codec)
}
/* assign Capture Source enums to NID */
kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
if (!kctl)
kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
for (i = 0; kctl && i < kctl->count; i++) {
hda_nid_t *nids = spec->capsrc_nids;
if (!nids)
nids = spec->adc_nids;
err = snd_hda_add_nid(codec, kctl, i, nids[i]);
if (err < 0)
return err;
if (spec->capsrc_nids || spec->adc_nids) {
kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
if (!kctl)
kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
for (i = 0; kctl && i < kctl->count; i++) {
hda_nid_t *nids = spec->capsrc_nids;
if (!nids)
nids = spec->adc_nids;
err = snd_hda_add_nid(codec, kctl, i, nids[i]);
if (err < 0)
return err;
}
}
if (spec->cap_mixer) {
const char *kname = kctl ? kctl->id.name : NULL;
@@ -5176,8 +5180,24 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
#ifdef CONFIG_SND_HDA_INPUT_BEEP
#define set_beep_amp(spec, nid, idx, dir) \
((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
static struct snd_pci_quirk beep_white_list[] = {
SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
{}
};
static inline int has_cdefine_beep(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
const struct snd_pci_quirk *q;
q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
if (q)
return q->value;
return spec->cdefine.enable_pcbeep;
}
#else
#define set_beep_amp(spec, nid, idx, dir) /* NOP */
#define has_cdefine_beep(codec) 0
#endif
/*
@@ -6948,7 +6968,7 @@ static struct hda_input_mux mb5_capture_source = {
.num_items = 3,
.items = {
{ "Mic", 0x1 },
{ "Line", 0x2 },
{ "Line", 0x7 },
{ "CD", 0x4 },
},
};
@@ -7469,8 +7489,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
@@ -7853,10 +7873,9 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
{ }
};
@@ -9485,6 +9504,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
/* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
* so apparently no perfect solution yet
*/
@@ -10562,10 +10582,12 @@ static int patch_alc882(struct hda_codec *codec)
}
}
err = snd_hda_attach_beep_device(codec, 0x1);
if (err < 0) {
alc_free(codec);
return err;
if (has_cdefine_beep(codec)) {
err = snd_hda_attach_beep_device(codec, 0x1);
if (err < 0) {
alc_free(codec);
return err;
}
}
if (board_config != ALC882_AUTO)
@@ -10615,7 +10637,7 @@ static int patch_alc882(struct hda_codec *codec)
set_capture_mixer(codec);
if (spec->cdefine.enable_pcbeep)
if (has_cdefine_beep(codec))
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
if (board_config == ALC882_AUTO)
@@ -12431,7 +12453,7 @@ static int patch_alc262(struct hda_codec *codec)
}
}
if (!spec->no_analog) {
if (!spec->no_analog && has_cdefine_beep(codec)) {
err = snd_hda_attach_beep_device(codec, 0x1);
if (err < 0) {
alc_free(codec);
@@ -12482,7 +12504,7 @@ static int patch_alc262(struct hda_codec *codec)
}
if (!spec->cap_mixer && !spec->no_analog)
set_capture_mixer(codec);
if (!spec->no_analog && spec->cdefine.enable_pcbeep)
if (!spec->no_analog && has_cdefine_beep(codec))
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
spec->vmaster_nid = 0x0c;
@@ -14454,10 +14476,12 @@ static int patch_alc269(struct hda_codec *codec)
}
}
err = snd_hda_attach_beep_device(codec, 0x1);
if (err < 0) {
alc_free(codec);
return err;
if (has_cdefine_beep(codec)) {
err = snd_hda_attach_beep_device(codec, 0x1);
if (err < 0) {
alc_free(codec);
return err;
}
}
if (board_config != ALC269_AUTO)
@@ -14490,7 +14514,7 @@ static int patch_alc269(struct hda_codec *codec)
if (!spec->cap_mixer)
set_capture_mixer(codec);
if (spec->cdefine.enable_pcbeep)
if (has_cdefine_beep(codec))
set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
if (board_config == ALC269_AUTO)
@@ -18687,10 +18711,12 @@ static int patch_alc662(struct hda_codec *codec)
}
}
err = snd_hda_attach_beep_device(codec, 0x1);
if (err < 0) {
alc_free(codec);
return err;
if (has_cdefine_beep(codec)) {
err = snd_hda_attach_beep_device(codec, 0x1);
if (err < 0) {
alc_free(codec);
return err;
}
}
if (board_config != ALC662_AUTO)
@@ -18712,7 +18738,7 @@ static int patch_alc662(struct hda_codec *codec)
if (!spec->cap_mixer)
set_capture_mixer(codec);
if (spec->cdefine.enable_pcbeep) {
if (has_cdefine_beep(codec)) {
switch (codec->vendor_id) {
case 0x10ec0662:
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);

Bestand weergeven

@@ -300,7 +300,7 @@ struct snd_soc_dai au1xpsc_i2s_dai = {
};
EXPORT_SYMBOL(au1xpsc_i2s_dai);
static int __init au1xpsc_i2s_drvprobe(struct platform_device *pdev)
static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
{
struct resource *r;
unsigned long sel;

Bestand weergeven

@@ -83,8 +83,8 @@ config SND_SOC_ALL_CODECS
config SND_SOC_WM_HUBS
tristate
default y if SND_SOC_WM8993=y
default m if SND_SOC_WM8993=m
default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y
default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m
config SND_SOC_AC97_CODEC
tristate

Bestand weergeven

@@ -127,6 +127,8 @@ static __devinit int wm8727_platform_probe(struct platform_device *pdev)
goto err_codec;
}
return 0;
err_codec:
snd_soc_unregister_codec(codec);
err:

Bestand weergeven

@@ -94,7 +94,6 @@ SOC_DAPM_SINGLE("Bypass Switch", WM8776_OUTMUX, 2, 1, 0),
static const struct snd_soc_dapm_widget wm8776_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("AUX"),
SND_SOC_DAPM_INPUT("AUX"),
SND_SOC_DAPM_INPUT("AIN1"),
SND_SOC_DAPM_INPUT("AIN2"),

Bestand weergeven

@@ -885,7 +885,6 @@ static int wm8988_register(struct wm8988_priv *wm8988,
ret = snd_soc_register_dai(&wm8988_dai);
if (ret != 0) {
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
snd_soc_unregister_codec(codec);
goto err_codec;
}

Bestand weergeven

@@ -612,7 +612,6 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
NUMDMA_MASK);
mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK);
mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
}
if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) {
@@ -623,7 +622,6 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
NUMDMA_MASK);
mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK);
mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
}
}

Bestand weergeven

@@ -73,7 +73,7 @@ struct psc_dma {
};
/* Utility for retrieving psc_dma_stream structure from a substream */
inline struct psc_dma_stream *
static inline struct psc_dma_stream *
to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma)
{
if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)

Bestand weergeven

@@ -683,20 +683,15 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
/* clock inversion (CKG2) */
data = 0;
switch (SH_FSI_INVERSION_MASK & flags) {
case SH_FSI_LRM_INV:
data = 1 << 12;
break;
case SH_FSI_BRM_INV:
data = 1 << 8;
break;
case SH_FSI_LRS_INV:
data = 1 << 4;
break;
case SH_FSI_BRS_INV:
data = 1 << 0;
break;
}
if (SH_FSI_LRM_INV & flags)
data |= 1 << 12;
if (SH_FSI_BRM_INV & flags)
data |= 1 << 8;
if (SH_FSI_LRS_INV & flags)
data |= 1 << 4;
if (SH_FSI_BRS_INV & flags)
data |= 1 << 0;
fsi_reg_write(fsi, CKG2, data);
/* do fmt, di fmt */
@@ -726,15 +721,15 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
break;
case SH_FSI_FMT_TDM:
msg = "TDM";
data = CR_FMT(CR_TDM) | (fsi->chan - 1);
fsi->chan = is_play ?
SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
data = CR_FMT(CR_TDM) | (fsi->chan - 1);
break;
case SH_FSI_FMT_TDM_DELAY:
msg = "TDM Delay";
data = CR_FMT(CR_TDM_D) | (fsi->chan - 1);
fsi->chan = is_play ?
SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
data = CR_FMT(CR_TDM_D) | (fsi->chan - 1);
break;
default:
dev_err(dai->dev, "unknown format.\n");

Bestand weergeven

@@ -103,7 +103,8 @@ static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_i
ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0),
UAC2_CS_CUR,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
UAC2_CX_CLOCK_SELECTOR << 8, selector_id << 8,
UAC2_CX_CLOCK_SELECTOR << 8,
snd_usb_ctrl_intf(chip) | (selector_id << 8),
&buf, sizeof(buf), 1000);
if (ret < 0)
@@ -120,7 +121,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
UAC2_CS_CONTROL_CLOCK_VALID << 8, source_id << 8,
UAC2_CS_CONTROL_CLOCK_VALID << 8,
snd_usb_ctrl_intf(chip) | (source_id << 8),
&data, sizeof(data), 1000);
if (err < 0) {
@@ -269,7 +271,8 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
data[3] = rate >> 24;
if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8,
UAC2_CS_CONTROL_SAM_FREQ << 8,
snd_usb_ctrl_intf(chip) | (clock << 8),
data, sizeof(data), 1000)) < 0) {
snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n",
dev->devnum, iface, fmt->altsetting, rate);
@@ -278,7 +281,8 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8,
UAC2_CS_CONTROL_SAM_FREQ << 8,
snd_usb_ctrl_intf(chip) | (clock << 8),
data, sizeof(data), 1000)) < 0) {
snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
dev->devnum, iface, fmt->altsetting);

Bestand weergeven

@@ -427,6 +427,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
kfree(fp->rate_table);
kfree(fp);
fp = NULL;
continue;
}

Bestand weergeven

@@ -205,6 +205,60 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof
return 0;
}
/*
* Helper function to walk the array of sample rate triplets reported by
* the device. The problem is that we need to parse whole array first to
* get to know how many sample rates we have to expect.
* Then fp->rate_table can be allocated and filled.
*/
static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets,
const unsigned char *data)
{
int i, nr_rates = 0;
fp->rates = fp->rate_min = fp->rate_max = 0;
for (i = 0; i < nr_triplets; i++) {
int min = combine_quad(&data[2 + 12 * i]);
int max = combine_quad(&data[6 + 12 * i]);
int res = combine_quad(&data[10 + 12 * i]);
int rate;
if ((max < 0) || (min < 0) || (res < 0) || (max < min))
continue;
/*
* for ranges with res == 1, we announce a continuous sample
* rate range, and this function should return 0 for no further
* parsing.
*/
if (res == 1) {
fp->rate_min = min;
fp->rate_max = max;
fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
return 0;
}
for (rate = min; rate <= max; rate += res) {
if (fp->rate_table)
fp->rate_table[nr_rates] = rate;
if (!fp->rate_min || rate < fp->rate_min)
fp->rate_min = rate;
if (!fp->rate_max || rate > fp->rate_max)
fp->rate_max = rate;
fp->rates |= snd_pcm_rate_to_rate_bit(rate);
nr_rates++;
/* avoid endless loop */
if (res == 0)
break;
}
}
return nr_rates;
}
/*
* parse the format descriptor and stores the possible sample rates
* on the audioformat table (audio class v2).
@@ -215,13 +269,20 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
{
struct usb_device *dev = chip->dev;
unsigned char tmp[2], *data;
int i, nr_rates, data_size, ret = 0;
int nr_triplets, data_size, ret = 0;
int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fp->clock);
if (clock < 0) {
snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n",
__func__, clock);
goto err;
}
/* get the number of sample rates first by only fetching 2 bytes */
ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8,
UAC2_CS_CONTROL_SAM_FREQ << 8,
snd_usb_ctrl_intf(chip) | (clock << 8),
tmp, sizeof(tmp), 1000);
if (ret < 0) {
@@ -230,8 +291,8 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
goto err;
}
nr_rates = (tmp[1] << 8) | tmp[0];
data_size = 2 + 12 * nr_rates;
nr_triplets = (tmp[1] << 8) | tmp[0];
data_size = 2 + 12 * nr_triplets;
data = kzalloc(data_size, GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
@@ -241,7 +302,8 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
/* now get the full information */
ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8,
UAC2_CS_CONTROL_SAM_FREQ << 8,
snd_usb_ctrl_intf(chip) | (clock << 8),
data, data_size, 1000);
if (ret < 0) {
@@ -251,26 +313,28 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
goto err_free;
}
fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
/* Call the triplet parser, and make sure fp->rate_table is NULL.
* We just use the return value to know how many sample rates we
* will have to deal with. */
kfree(fp->rate_table);
fp->rate_table = NULL;
fp->nr_rates = parse_uac2_sample_rate_range(fp, nr_triplets, data);
if (fp->nr_rates == 0) {
/* SNDRV_PCM_RATE_CONTINUOUS */
ret = 0;
goto err_free;
}
fp->rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
if (!fp->rate_table) {
ret = -ENOMEM;
goto err_free;
}
fp->nr_rates = 0;
fp->rate_min = fp->rate_max = 0;
for (i = 0; i < nr_rates; i++) {
int rate = combine_quad(&data[2 + 12 * i]);
fp->rate_table[fp->nr_rates] = rate;
if (!fp->rate_min || rate < fp->rate_min)
fp->rate_min = rate;
if (!fp->rate_max || rate > fp->rate_max)
fp->rate_max = rate;
fp->rates |= snd_pcm_rate_to_rate_bit(rate);
fp->nr_rates++;
}
/* Call the triplet parser again, but this time, fp->rate_table is
* allocated, so the rates will be stored */
parse_uac2_sample_rate_range(fp, nr_triplets, data);
err_free:
kfree(data);

Bestand weergeven

@@ -28,5 +28,9 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
#define snd_usb_get_speed(dev) ((dev)->speed)
#endif
static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip)
{
return get_iface_desc(chip->ctrl_intf)->bInterfaceNumber;
}
#endif /* __USBAUDIO_HELPER_H */

Bestand weergeven

@@ -297,20 +297,27 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
{
unsigned char buf[14]; /* enough space for one range of 4 bytes */
unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
unsigned char *val;
int ret;
int ret, size;
__u8 bRequest;
bRequest = (request == UAC_GET_CUR) ?
UAC2_CS_CUR : UAC2_CS_RANGE;
if (request == UAC_GET_CUR) {
bRequest = UAC2_CS_CUR;
size = sizeof(__u16);
} else {
bRequest = UAC2_CS_RANGE;
size = sizeof(buf);
}
memset(buf, 0, sizeof(buf));
ret = snd_usb_ctl_msg(cval->mixer->chip->dev,
usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
bRequest,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
validx, cval->mixer->ctrlif | (cval->id << 8),
buf, sizeof(buf), 1000);
buf, size, 1000);
if (ret < 0) {
snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
@@ -318,6 +325,8 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
return ret;
}
/* FIXME: how should we handle multiple triplets here? */
switch (request) {
case UAC_GET_CUR:
val = buf;
@@ -1098,6 +1107,19 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
}
break;
case USB_ID(0x046d, 0x0809):
case USB_ID(0x046d, 0x0991):
/* Most audio usb devices lie about volume resolution.
* Most Logitech webcams have res = 384.
* Proboly there is some logitech magic behind this number --fishor
*/
if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
snd_printk(KERN_INFO
"set resolution quirk: cval->res = 384\n");
cval->res = 384;
}
break;
}
snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",