Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: ALSA: usb-audio: automatically detect feedback format ASoC: sound/wm9090: add missing __devexit marker ASoC: sound/max98088: add missing __devexit marker ASoC: sound/ad73311: add missing __devexit marker ASoC: fsl - fix build error in pcm030-audio-fabric.c sound/oss/sb_ess.c: delete double assignment ALSA: hda - Change BTL amp level on some HP notebooks
This commit is contained in:
commit
7c5814c719
10 changed files with 151 additions and 120 deletions
|
@ -1721,7 +1721,6 @@ printk (KERN_INFO "FKS: es_rec_set_recmask mask = %x\n", mask);
|
|||
left = value & 0x000000ff;
|
||||
right = (value & 0x0000ff00) >> 8;
|
||||
} else { /* Turn it off (3) */
|
||||
left = 0;
|
||||
left = 0;
|
||||
right = 0;
|
||||
}
|
||||
|
|
|
@ -5326,6 +5326,82 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int stac92hd83xxx_set_system_btl_amp(struct hda_codec *codec)
|
||||
{
|
||||
if (codec->vendor_id != 0x111d7605 &&
|
||||
codec->vendor_id != 0x111d76d1)
|
||||
return 0;
|
||||
|
||||
switch (codec->subsystem_id) {
|
||||
case 0x103c1618:
|
||||
case 0x103c1619:
|
||||
case 0x103c161a:
|
||||
case 0x103c161b:
|
||||
case 0x103c161c:
|
||||
case 0x103c161d:
|
||||
case 0x103c161e:
|
||||
case 0x103c161f:
|
||||
case 0x103c1620:
|
||||
case 0x103c1621:
|
||||
case 0x103c1622:
|
||||
case 0x103c1623:
|
||||
|
||||
case 0x103c162a:
|
||||
case 0x103c162b:
|
||||
|
||||
case 0x103c1630:
|
||||
case 0x103c1631:
|
||||
|
||||
case 0x103c1633:
|
||||
|
||||
case 0x103c1635:
|
||||
|
||||
case 0x103c164f:
|
||||
|
||||
case 0x103c1676:
|
||||
case 0x103c1677:
|
||||
case 0x103c1678:
|
||||
case 0x103c1679:
|
||||
case 0x103c167a:
|
||||
case 0x103c167b:
|
||||
case 0x103c167c:
|
||||
case 0x103c167d:
|
||||
case 0x103c167e:
|
||||
case 0x103c167f:
|
||||
case 0x103c1680:
|
||||
case 0x103c1681:
|
||||
case 0x103c1682:
|
||||
case 0x103c1683:
|
||||
case 0x103c1684:
|
||||
case 0x103c1685:
|
||||
case 0x103c1686:
|
||||
case 0x103c1687:
|
||||
case 0x103c1688:
|
||||
case 0x103c1689:
|
||||
case 0x103c168a:
|
||||
case 0x103c168b:
|
||||
case 0x103c168c:
|
||||
case 0x103c168d:
|
||||
case 0x103c168e:
|
||||
case 0x103c168f:
|
||||
case 0x103c1690:
|
||||
case 0x103c1691:
|
||||
case 0x103c1692:
|
||||
|
||||
case 0x103c3587:
|
||||
case 0x103c3588:
|
||||
case 0x103c3589:
|
||||
case 0x103c358a:
|
||||
|
||||
case 0x103c3667:
|
||||
case 0x103c3668:
|
||||
/* set BTL amp level to 13.43dB for louder speaker output */
|
||||
return snd_hda_codec_write_cache(codec, codec->afg, 0,
|
||||
0x7F4, 0x14);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int patch_stac92hd83xxx(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec;
|
||||
|
@ -5452,6 +5528,8 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
|
|||
AC_VERB_SET_CONNECT_SEL, num_dacs);
|
||||
}
|
||||
|
||||
stac92hd83xxx_set_system_btl_amp(codec);
|
||||
|
||||
codec->proc_widget_hook = stac92hd_proc_hook;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -47,7 +47,7 @@ static int ad73311_probe(struct platform_device *pdev)
|
|||
&soc_codec_dev_ad73311, &ad73311_dai, 1);
|
||||
}
|
||||
|
||||
static int ad73311_remove(struct platform_device *pdev)
|
||||
static int __devexit ad73311_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
return 0;
|
||||
|
|
|
@ -2051,7 +2051,7 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int max98088_i2c_remove(struct i2c_client *client)
|
||||
static int __devexit max98088_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
kfree(i2c_get_clientdata(client));
|
||||
|
|
|
@ -665,7 +665,7 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int wm9090_i2c_remove(struct i2c_client *i2c)
|
||||
static int __devexit wm9090_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <sound/pcm_params.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/soc-of-simple.h>
|
||||
|
||||
#include "mpc5200_dma.h"
|
||||
#include "mpc5200_psc_ac97.h"
|
||||
|
@ -49,7 +48,7 @@ static struct snd_soc_dai_link pcm030_fabric_dai[] = {
|
|||
.codec_dai_name = "wm9712-aux",
|
||||
.cpu_dai_name = "mpc5200-psc-ac97.1",
|
||||
.platform_name = "mpc5200-pcm-audio",
|
||||
..codec_name = "wm9712-codec",
|
||||
.codec_name = "wm9712-codec",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -62,12 +62,14 @@ struct snd_usb_substream {
|
|||
unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
|
||||
unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */
|
||||
unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */
|
||||
int freqshift; /* how much to shift the feedback value to get Q16.16 */
|
||||
unsigned int freqmax; /* maximum sampling rate, used for buffer management */
|
||||
unsigned int phase; /* phase accumulator */
|
||||
unsigned int maxpacksize; /* max packet size in bytes */
|
||||
unsigned int maxframesize; /* max packet size in frames */
|
||||
unsigned int curpacksize; /* current packet size in bytes (for capture) */
|
||||
unsigned int curframesize; /* current packet size in frames (for capture) */
|
||||
unsigned int syncmaxsize; /* sync endpoint packet size */
|
||||
unsigned int fill_max: 1; /* fill max packet size always */
|
||||
unsigned int txfr_quirk:1; /* allow sub-frame alignment */
|
||||
unsigned int fmt_type; /* USB audio format type (1-3) */
|
||||
|
|
|
@ -237,6 +237,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
|
|||
subs->datainterval = fmt->datainterval;
|
||||
subs->syncpipe = subs->syncinterval = 0;
|
||||
subs->maxpacksize = fmt->maxpacksize;
|
||||
subs->syncmaxsize = 0;
|
||||
subs->fill_max = 0;
|
||||
|
||||
/* we need a sync pipe in async OUT or adaptive IN mode */
|
||||
|
@ -283,6 +284,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
|
|||
subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
|
||||
else
|
||||
subs->syncinterval = 3;
|
||||
subs->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize);
|
||||
}
|
||||
|
||||
/* always fill max packet size */
|
||||
|
|
|
@ -132,6 +132,11 @@ static void proc_dump_substream_status(struct snd_usb_substream *subs, struct sn
|
|||
? get_full_speed_hz(subs->freqm)
|
||||
: get_high_speed_hz(subs->freqm),
|
||||
subs->freqm >> 16, subs->freqm & 0xffff);
|
||||
if (subs->freqshift != INT_MIN)
|
||||
snd_iprintf(buffer, " Feedback Format = %d.%d\n",
|
||||
(subs->syncmaxsize > 3 ? 32 : 24)
|
||||
- (16 - subs->freqshift),
|
||||
16 - subs->freqshift);
|
||||
} else {
|
||||
snd_iprintf(buffer, " Status: Stop\n");
|
||||
}
|
||||
|
|
174
sound/usb/urb.c
174
sound/usb/urb.c
|
@ -225,6 +225,7 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
|
|||
else
|
||||
subs->freqn = get_usb_high_speed_rate(rate);
|
||||
subs->freqm = subs->freqn;
|
||||
subs->freqshift = INT_MIN;
|
||||
/* calculate max. frequency */
|
||||
if (subs->maxpacksize) {
|
||||
/* whatever fits into a max. size packet */
|
||||
|
@ -513,11 +514,10 @@ static int retire_paused_capture_urb(struct snd_usb_substream *subs,
|
|||
|
||||
|
||||
/*
|
||||
* prepare urb for full speed playback sync pipe
|
||||
* prepare urb for playback sync pipe
|
||||
*
|
||||
* set up the offset and length to receive the current frequency.
|
||||
*/
|
||||
|
||||
static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
|
||||
struct snd_pcm_runtime *runtime,
|
||||
struct urb *urb)
|
||||
|
@ -525,103 +525,78 @@ static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
|
|||
struct snd_urb_ctx *ctx = urb->context;
|
||||
|
||||
urb->dev = ctx->subs->dev; /* we need to set this at each time */
|
||||
urb->iso_frame_desc[0].length = 3;
|
||||
urb->iso_frame_desc[0].length = min(4u, ctx->subs->syncmaxsize);
|
||||
urb->iso_frame_desc[0].offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* prepare urb for high speed playback sync pipe
|
||||
* process after playback sync complete
|
||||
*
|
||||
* set up the offset and length to receive the current frequency.
|
||||
*/
|
||||
|
||||
static int prepare_playback_sync_urb_hs(struct snd_usb_substream *subs,
|
||||
struct snd_pcm_runtime *runtime,
|
||||
struct urb *urb)
|
||||
{
|
||||
struct snd_urb_ctx *ctx = urb->context;
|
||||
|
||||
urb->dev = ctx->subs->dev; /* we need to set this at each time */
|
||||
urb->iso_frame_desc[0].length = 4;
|
||||
urb->iso_frame_desc[0].offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* process after full speed playback sync complete
|
||||
*
|
||||
* retrieve the current 10.14 frequency from pipe, and set it.
|
||||
* the value is referred in prepare_playback_urb().
|
||||
* Full speed devices report feedback values in 10.14 format as samples per
|
||||
* frame, high speed devices in 16.16 format as samples per microframe.
|
||||
* Because the Audio Class 1 spec was written before USB 2.0, many high speed
|
||||
* devices use a wrong interpretation, some others use an entirely different
|
||||
* format. Therefore, we cannot predict what format any particular device uses
|
||||
* and must detect it automatically.
|
||||
*/
|
||||
static int retire_playback_sync_urb(struct snd_usb_substream *subs,
|
||||
struct snd_pcm_runtime *runtime,
|
||||
struct urb *urb)
|
||||
{
|
||||
unsigned int f;
|
||||
int shift;
|
||||
unsigned long flags;
|
||||
|
||||
if (urb->iso_frame_desc[0].status == 0 &&
|
||||
urb->iso_frame_desc[0].actual_length == 3) {
|
||||
f = combine_triple((u8*)urb->transfer_buffer) << 2;
|
||||
if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
|
||||
spin_lock_irqsave(&subs->lock, flags);
|
||||
subs->freqm = f;
|
||||
spin_unlock_irqrestore(&subs->lock, flags);
|
||||
if (urb->iso_frame_desc[0].status != 0 ||
|
||||
urb->iso_frame_desc[0].actual_length < 3)
|
||||
return 0;
|
||||
|
||||
f = le32_to_cpup(urb->transfer_buffer);
|
||||
if (urb->iso_frame_desc[0].actual_length == 3)
|
||||
f &= 0x00ffffff;
|
||||
else
|
||||
f &= 0x0fffffff;
|
||||
if (f == 0)
|
||||
return 0;
|
||||
|
||||
if (unlikely(subs->freqshift == INT_MIN)) {
|
||||
/*
|
||||
* The first time we see a feedback value, determine its format
|
||||
* by shifting it left or right until it matches the nominal
|
||||
* frequency value. This assumes that the feedback does not
|
||||
* differ from the nominal value more than +50% or -25%.
|
||||
*/
|
||||
shift = 0;
|
||||
while (f < subs->freqn - subs->freqn / 4) {
|
||||
f <<= 1;
|
||||
shift++;
|
||||
}
|
||||
while (f > subs->freqn + subs->freqn / 2) {
|
||||
f >>= 1;
|
||||
shift--;
|
||||
}
|
||||
subs->freqshift = shift;
|
||||
}
|
||||
else if (subs->freqshift >= 0)
|
||||
f <<= subs->freqshift;
|
||||
else
|
||||
f >>= -subs->freqshift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* process after high speed playback sync complete
|
||||
*
|
||||
* retrieve the current 12.13 frequency from pipe, and set it.
|
||||
* the value is referred in prepare_playback_urb().
|
||||
*/
|
||||
static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
|
||||
struct snd_pcm_runtime *runtime,
|
||||
struct urb *urb)
|
||||
{
|
||||
unsigned int f;
|
||||
unsigned long flags;
|
||||
|
||||
if (urb->iso_frame_desc[0].status == 0 &&
|
||||
urb->iso_frame_desc[0].actual_length == 4) {
|
||||
f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
|
||||
if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
|
||||
spin_lock_irqsave(&subs->lock, flags);
|
||||
subs->freqm = f;
|
||||
spin_unlock_irqrestore(&subs->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* process after E-Mu 0202/0404/Tracker Pre high speed playback sync complete
|
||||
*
|
||||
* These devices return the number of samples per packet instead of the number
|
||||
* of samples per microframe.
|
||||
*/
|
||||
static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs,
|
||||
struct snd_pcm_runtime *runtime,
|
||||
struct urb *urb)
|
||||
{
|
||||
unsigned int f;
|
||||
unsigned long flags;
|
||||
|
||||
if (urb->iso_frame_desc[0].status == 0 &&
|
||||
urb->iso_frame_desc[0].actual_length == 4) {
|
||||
f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
|
||||
f >>= subs->datainterval;
|
||||
if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
|
||||
spin_lock_irqsave(&subs->lock, flags);
|
||||
subs->freqm = f;
|
||||
spin_unlock_irqrestore(&subs->lock, flags);
|
||||
}
|
||||
if (likely(f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax)) {
|
||||
/*
|
||||
* If the frequency looks valid, set it.
|
||||
* This value is referred to in prepare_playback_urb().
|
||||
*/
|
||||
spin_lock_irqsave(&subs->lock, flags);
|
||||
subs->freqm = f;
|
||||
spin_unlock_irqrestore(&subs->lock, flags);
|
||||
} else {
|
||||
/*
|
||||
* Out of range; maybe the shift value is wrong.
|
||||
* Reset it so that we autodetect again the next time.
|
||||
*/
|
||||
subs->freqshift = INT_MIN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -878,21 +853,6 @@ static struct snd_urb_ops audio_urb_ops[2] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
|
||||
{
|
||||
.prepare = prepare_nodata_playback_urb,
|
||||
.retire = retire_playback_urb,
|
||||
.prepare_sync = prepare_playback_sync_urb_hs,
|
||||
.retire_sync = retire_playback_sync_urb_hs,
|
||||
},
|
||||
{
|
||||
.prepare = prepare_capture_urb,
|
||||
.retire = retire_capture_urb,
|
||||
.prepare_sync = prepare_capture_sync_urb_hs,
|
||||
.retire_sync = retire_capture_sync_urb,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* initialize the substream instance.
|
||||
*/
|
||||
|
@ -909,23 +869,9 @@ void snd_usb_init_substream(struct snd_usb_stream *as,
|
|||
subs->direction = stream;
|
||||
subs->dev = as->chip->dev;
|
||||
subs->txfr_quirk = as->chip->txfr_quirk;
|
||||
if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) {
|
||||
subs->ops = audio_urb_ops[stream];
|
||||
} else {
|
||||
subs->ops = audio_urb_ops_high_speed[stream];
|
||||
switch (as->chip->usb_id) {
|
||||
case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
|
||||
case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
|
||||
case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
|
||||
subs->ops.retire_sync = retire_playback_sync_urb_hs_emu;
|
||||
break;
|
||||
case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra 8 */
|
||||
case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
|
||||
subs->ops.prepare_sync = prepare_playback_sync_urb;
|
||||
subs->ops.retire_sync = retire_playback_sync_urb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
subs->ops = audio_urb_ops[stream];
|
||||
if (snd_usb_get_speed(subs->dev) >= USB_SPEED_HIGH)
|
||||
subs->ops.prepare_sync = prepare_capture_sync_urb_hs;
|
||||
|
||||
snd_usb_set_pcm_ops(as->pcm, stream);
|
||||
|
||||
|
|
Loading…
Reference in a new issue