Commit 7c5814c7 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 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
parents a042e261 89e1e66d
...@@ -1721,7 +1721,6 @@ printk (KERN_INFO "FKS: es_rec_set_recmask mask = %x\n", mask); ...@@ -1721,7 +1721,6 @@ printk (KERN_INFO "FKS: es_rec_set_recmask mask = %x\n", mask);
left = value & 0x000000ff; left = value & 0x000000ff;
right = (value & 0x0000ff00) >> 8; right = (value & 0x0000ff00) >> 8;
} else { /* Turn it off (3) */ } else { /* Turn it off (3) */
left = 0;
left = 0; left = 0;
right = 0; right = 0;
} }
......
...@@ -5326,6 +5326,82 @@ static int patch_stac92hd73xx(struct hda_codec *codec) ...@@ -5326,6 +5326,82 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
return 0; 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) static int patch_stac92hd83xxx(struct hda_codec *codec)
{ {
struct sigmatel_spec *spec; struct sigmatel_spec *spec;
...@@ -5452,6 +5528,8 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) ...@@ -5452,6 +5528,8 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
AC_VERB_SET_CONNECT_SEL, num_dacs); AC_VERB_SET_CONNECT_SEL, num_dacs);
} }
stac92hd83xxx_set_system_btl_amp(codec);
codec->proc_widget_hook = stac92hd_proc_hook; codec->proc_widget_hook = stac92hd_proc_hook;
return 0; return 0;
......
...@@ -47,7 +47,7 @@ static int ad73311_probe(struct platform_device *pdev) ...@@ -47,7 +47,7 @@ static int ad73311_probe(struct platform_device *pdev)
&soc_codec_dev_ad73311, &ad73311_dai, 1); &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); snd_soc_unregister_codec(&pdev->dev);
return 0; return 0;
......
...@@ -2051,7 +2051,7 @@ static int max98088_i2c_probe(struct i2c_client *i2c, ...@@ -2051,7 +2051,7 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
return ret; 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); snd_soc_unregister_codec(&client->dev);
kfree(i2c_get_clientdata(client)); kfree(i2c_get_clientdata(client));
......
...@@ -665,7 +665,7 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, ...@@ -665,7 +665,7 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
return ret; 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); struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/initval.h> #include <sound/initval.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/soc-of-simple.h>
#include "mpc5200_dma.h" #include "mpc5200_dma.h"
#include "mpc5200_psc_ac97.h" #include "mpc5200_psc_ac97.h"
...@@ -49,7 +48,7 @@ static struct snd_soc_dai_link pcm030_fabric_dai[] = { ...@@ -49,7 +48,7 @@ static struct snd_soc_dai_link pcm030_fabric_dai[] = {
.codec_dai_name = "wm9712-aux", .codec_dai_name = "wm9712-aux",
.cpu_dai_name = "mpc5200-psc-ac97.1", .cpu_dai_name = "mpc5200-psc-ac97.1",
.platform_name = "mpc5200-pcm-audio", .platform_name = "mpc5200-pcm-audio",
..codec_name = "wm9712-codec", .codec_name = "wm9712-codec",
}, },
}; };
......
...@@ -62,12 +62,14 @@ struct snd_usb_substream { ...@@ -62,12 +62,14 @@ struct snd_usb_substream {
unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */ 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 */ 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 freqmax; /* maximum sampling rate, used for buffer management */
unsigned int phase; /* phase accumulator */ unsigned int phase; /* phase accumulator */
unsigned int maxpacksize; /* max packet size in bytes */ unsigned int maxpacksize; /* max packet size in bytes */
unsigned int maxframesize; /* max packet size in frames */ unsigned int maxframesize; /* max packet size in frames */
unsigned int curpacksize; /* current packet size in bytes (for capture) */ unsigned int curpacksize; /* current packet size in bytes (for capture) */
unsigned int curframesize; /* current packet size in frames (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 fill_max: 1; /* fill max packet size always */
unsigned int txfr_quirk:1; /* allow sub-frame alignment */ unsigned int txfr_quirk:1; /* allow sub-frame alignment */
unsigned int fmt_type; /* USB audio format type (1-3) */ 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) ...@@ -237,6 +237,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
subs->datainterval = fmt->datainterval; subs->datainterval = fmt->datainterval;
subs->syncpipe = subs->syncinterval = 0; subs->syncpipe = subs->syncinterval = 0;
subs->maxpacksize = fmt->maxpacksize; subs->maxpacksize = fmt->maxpacksize;
subs->syncmaxsize = 0;
subs->fill_max = 0; subs->fill_max = 0;
/* we need a sync pipe in async OUT or adaptive IN mode */ /* 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) ...@@ -283,6 +284,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1; subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
else else
subs->syncinterval = 3; subs->syncinterval = 3;
subs->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize);
} }
/* always fill max packet size */ /* always fill max packet size */
......
...@@ -132,6 +132,11 @@ static void proc_dump_substream_status(struct snd_usb_substream *subs, struct sn ...@@ -132,6 +132,11 @@ static void proc_dump_substream_status(struct snd_usb_substream *subs, struct sn
? get_full_speed_hz(subs->freqm) ? get_full_speed_hz(subs->freqm)
: get_high_speed_hz(subs->freqm), : get_high_speed_hz(subs->freqm),
subs->freqm >> 16, subs->freqm & 0xffff); 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 { } else {
snd_iprintf(buffer, " Status: Stop\n"); snd_iprintf(buffer, " Status: Stop\n");
} }
......
...@@ -225,6 +225,7 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs, ...@@ -225,6 +225,7 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
else else
subs->freqn = get_usb_high_speed_rate(rate); subs->freqn = get_usb_high_speed_rate(rate);
subs->freqm = subs->freqn; subs->freqm = subs->freqn;
subs->freqshift = INT_MIN;
/* calculate max. frequency */ /* calculate max. frequency */
if (subs->maxpacksize) { if (subs->maxpacksize) {
/* whatever fits into a max. size packet */ /* whatever fits into a max. size packet */
...@@ -513,11 +514,10 @@ static int retire_paused_capture_urb(struct snd_usb_substream *subs, ...@@ -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. * set up the offset and length to receive the current frequency.
*/ */
static int prepare_playback_sync_urb(struct snd_usb_substream *subs, static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
struct snd_pcm_runtime *runtime, struct snd_pcm_runtime *runtime,
struct urb *urb) struct urb *urb)
...@@ -525,103 +525,78 @@ static int prepare_playback_sync_urb(struct snd_usb_substream *subs, ...@@ -525,103 +525,78 @@ static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
struct snd_urb_ctx *ctx = urb->context; struct snd_urb_ctx *ctx = urb->context;
urb->dev = ctx->subs->dev; /* we need to set this at each time */ 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
*
* 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; urb->iso_frame_desc[0].offset = 0;
return 0; return 0;
} }
/* /*
* process after full speed playback sync complete * process after playback sync complete
* *
* retrieve the current 10.14 frequency from pipe, and set it. * Full speed devices report feedback values in 10.14 format as samples per
* the value is referred in prepare_playback_urb(). * 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, static int retire_playback_sync_urb(struct snd_usb_substream *subs,
struct snd_pcm_runtime *runtime, struct snd_pcm_runtime *runtime,
struct urb *urb) struct urb *urb)
{ {
unsigned int f; unsigned int f;
int shift;
unsigned long flags; unsigned long flags;
if (urb->iso_frame_desc[0].status == 0 && if (urb->iso_frame_desc[0].status != 0 ||
urb->iso_frame_desc[0].actual_length == 3) { urb->iso_frame_desc[0].actual_length < 3)
f = combine_triple((u8*)urb->transfer_buffer) << 2; return 0;
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);
}
}
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; return 0;
}
/* if (unlikely(subs->freqshift == INT_MIN)) {
* process after high speed playback sync complete /*
* * The first time we see a feedback value, determine its format
* retrieve the current 12.13 frequency from pipe, and set it. * by shifting it left or right until it matches the nominal
* the value is referred in prepare_playback_urb(). * frequency value. This assumes that the feedback does not
* differ from the nominal value more than +50% or -25%.
*/ */
static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs, shift = 0;
struct snd_pcm_runtime *runtime, while (f < subs->freqn - subs->freqn / 4) {
struct urb *urb) f <<= 1;
{ shift++;
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);
} }
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; 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().
* 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); spin_lock_irqsave(&subs->lock, flags);
subs->freqm = f; subs->freqm = f;
spin_unlock_irqrestore(&subs->lock, flags); 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; return 0;
...@@ -878,21 +853,6 @@ static struct snd_urb_ops audio_urb_ops[2] = { ...@@ -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. * initialize the substream instance.
*/ */
...@@ -909,23 +869,9 @@ void snd_usb_init_substream(struct snd_usb_stream *as, ...@@ -909,23 +869,9 @@ void snd_usb_init_substream(struct snd_usb_stream *as,
subs->direction = stream; subs->direction = stream;
subs->dev = as->chip->dev; subs->dev = as->chip->dev;
subs->txfr_quirk = as->chip->txfr_quirk; subs->txfr_quirk = as->chip->txfr_quirk;
if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) {
subs->ops = audio_urb_ops[stream]; subs->ops = audio_urb_ops[stream];
} else { if (snd_usb_get_speed(subs->dev) >= USB_SPEED_HIGH)
subs->ops = audio_urb_ops_high_speed[stream]; subs->ops.prepare_sync = prepare_capture_sync_urb_hs;
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;
}
}
snd_usb_set_pcm_ops(as->pcm, stream); snd_usb_set_pcm_ops(as->pcm, stream);
......
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