diff options
Diffstat (limited to 'sound')
189 files changed, 6594 insertions, 1797 deletions
diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index 4e2b4fbf2496..b9737fae656a 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c | |||
@@ -74,10 +74,9 @@ static void i2sbus_release_dev(struct device *dev) | |||
74 | int i; | 74 | int i; |
75 | 75 | ||
76 | i2sdev = container_of(dev, struct i2sbus_dev, sound.ofdev.dev); | 76 | i2sdev = container_of(dev, struct i2sbus_dev, sound.ofdev.dev); |
77 | 77 | iounmap(i2sdev->intfregs); | |
78 | if (i2sdev->intfregs) iounmap(i2sdev->intfregs); | 78 | iounmap(i2sdev->out.dbdma); |
79 | if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma); | 79 | iounmap(i2sdev->in.dbdma); |
80 | if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma); | ||
81 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) | 80 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) |
82 | release_and_free_resource(i2sdev->allocated_resource[i]); | 81 | release_and_free_resource(i2sdev->allocated_resource[i]); |
83 | free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring); | 82 | free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring); |
@@ -318,9 +317,9 @@ static int i2sbus_add_dev(struct macio_dev *macio, | |||
318 | free_irq(dev->interrupts[i], dev); | 317 | free_irq(dev->interrupts[i], dev); |
319 | free_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring); | 318 | free_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring); |
320 | free_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring); | 319 | free_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring); |
321 | if (dev->intfregs) iounmap(dev->intfregs); | 320 | iounmap(dev->intfregs); |
322 | if (dev->out.dbdma) iounmap(dev->out.dbdma); | 321 | iounmap(dev->out.dbdma); |
323 | if (dev->in.dbdma) iounmap(dev->in.dbdma); | 322 | iounmap(dev->in.dbdma); |
324 | for (i=0;i<3;i++) | 323 | for (i=0;i<3;i++) |
325 | release_and_free_resource(dev->allocated_resource[i]); | 324 | release_and_free_resource(dev->allocated_resource[i]); |
326 | mutex_destroy(&dev->lock); | 325 | mutex_destroy(&dev->lock); |
@@ -381,10 +380,8 @@ static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state) | |||
381 | 380 | ||
382 | list_for_each_entry(i2sdev, &control->list, item) { | 381 | list_for_each_entry(i2sdev, &control->list, item) { |
383 | /* Notify Alsa */ | 382 | /* Notify Alsa */ |
384 | if (i2sdev->sound.pcm) { | 383 | /* Suspend PCM streams */ |
385 | /* Suspend PCM streams */ | 384 | snd_pcm_suspend_all(i2sdev->sound.pcm); |
386 | snd_pcm_suspend_all(i2sdev->sound.pcm); | ||
387 | } | ||
388 | 385 | ||
389 | /* Notify codecs */ | 386 | /* Notify codecs */ |
390 | list_for_each_entry(cii, &i2sdev->sound.codec_list, list) { | 387 | list_for_each_entry(cii, &i2sdev->sound.codec_list, list) { |
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 0e83a73efb16..4140b1b95054 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -889,8 +889,8 @@ static int aaci_probe_ac97(struct aaci *aaci) | |||
889 | static void aaci_free_card(struct snd_card *card) | 889 | static void aaci_free_card(struct snd_card *card) |
890 | { | 890 | { |
891 | struct aaci *aaci = card->private_data; | 891 | struct aaci *aaci = card->private_data; |
892 | if (aaci->base) | 892 | |
893 | iounmap(aaci->base); | 893 | iounmap(aaci->base); |
894 | } | 894 | } |
895 | 895 | ||
896 | static struct aaci *aaci_init_card(struct amba_device *dev) | 896 | static struct aaci *aaci_init_card(struct amba_device *dev) |
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 4f6b14d704f3..cf4cedf2b420 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c | |||
@@ -22,6 +22,9 @@ | |||
22 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/of.h> | ||
26 | #include <linux/of_gpio.h> | ||
27 | #include <linux/of_device.h> | ||
25 | 28 | ||
26 | #include <sound/core.h> | 29 | #include <sound/core.h> |
27 | #include <sound/initval.h> | 30 | #include <sound/initval.h> |
@@ -34,10 +37,10 @@ | |||
34 | #include <linux/platform_data/dma-dw.h> | 37 | #include <linux/platform_data/dma-dw.h> |
35 | #include <linux/dma/dw.h> | 38 | #include <linux/dma/dw.h> |
36 | 39 | ||
40 | #ifdef CONFIG_AVR32 | ||
37 | #include <mach/cpu.h> | 41 | #include <mach/cpu.h> |
38 | 42 | #else | |
39 | #ifdef CONFIG_ARCH_AT91 | 43 | #define cpu_is_at32ap7000() 0 |
40 | #include <mach/hardware.h> | ||
41 | #endif | 44 | #endif |
42 | 45 | ||
43 | #include "ac97c.h" | 46 | #include "ac97c.h" |
@@ -902,6 +905,40 @@ static void atmel_ac97c_reset(struct atmel_ac97c *chip) | |||
902 | } | 905 | } |
903 | } | 906 | } |
904 | 907 | ||
908 | #ifdef CONFIG_OF | ||
909 | static const struct of_device_id atmel_ac97c_dt_ids[] = { | ||
910 | { .compatible = "atmel,at91sam9263-ac97c", }, | ||
911 | { } | ||
912 | }; | ||
913 | MODULE_DEVICE_TABLE(of, atmel_ac97c_dt_ids); | ||
914 | |||
915 | static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev) | ||
916 | { | ||
917 | struct ac97c_platform_data *pdata; | ||
918 | struct device_node *node = dev->of_node; | ||
919 | const struct of_device_id *match; | ||
920 | |||
921 | if (!node) { | ||
922 | dev_err(dev, "Device does not have associated DT data\n"); | ||
923 | return ERR_PTR(-EINVAL); | ||
924 | } | ||
925 | |||
926 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
927 | if (!pdata) | ||
928 | return ERR_PTR(-ENOMEM); | ||
929 | |||
930 | pdata->reset_pin = of_get_named_gpio(dev->of_node, "ac97-gpios", 2); | ||
931 | |||
932 | return pdata; | ||
933 | } | ||
934 | #else | ||
935 | static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev) | ||
936 | { | ||
937 | dev_err(dev, "no platform data defined\n"); | ||
938 | return ERR_PTR(-ENXIO); | ||
939 | } | ||
940 | #endif | ||
941 | |||
905 | static int atmel_ac97c_probe(struct platform_device *pdev) | 942 | static int atmel_ac97c_probe(struct platform_device *pdev) |
906 | { | 943 | { |
907 | struct snd_card *card; | 944 | struct snd_card *card; |
@@ -922,10 +959,11 @@ static int atmel_ac97c_probe(struct platform_device *pdev) | |||
922 | return -ENXIO; | 959 | return -ENXIO; |
923 | } | 960 | } |
924 | 961 | ||
925 | pdata = pdev->dev.platform_data; | 962 | pdata = dev_get_platdata(&pdev->dev); |
926 | if (!pdata) { | 963 | if (!pdata) { |
927 | dev_dbg(&pdev->dev, "no platform data\n"); | 964 | pdata = atmel_ac97c_probe_dt(&pdev->dev); |
928 | return -ENXIO; | 965 | if (IS_ERR(pdata)) |
966 | return PTR_ERR(pdata); | ||
929 | } | 967 | } |
930 | 968 | ||
931 | irq = platform_get_irq(pdev, 0); | 969 | irq = platform_get_irq(pdev, 0); |
@@ -1204,6 +1242,7 @@ static struct platform_driver atmel_ac97c_driver = { | |||
1204 | .driver = { | 1242 | .driver = { |
1205 | .name = "atmel_ac97c", | 1243 | .name = "atmel_ac97c", |
1206 | .pm = ATMEL_AC97C_PM_OPS, | 1244 | .pm = ATMEL_AC97C_PM_OPS, |
1245 | .of_match_table = of_match_ptr(atmel_ac97c_dt_ids), | ||
1207 | }, | 1246 | }, |
1208 | }; | 1247 | }; |
1209 | module_platform_driver(atmel_ac97c_driver); | 1248 | module_platform_driver(atmel_ac97c_driver); |
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index ada69d7a8d70..80423a4ccab6 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
@@ -719,7 +719,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, | |||
719 | 719 | ||
720 | oss_buffer_size = snd_pcm_plug_client_size(substream, | 720 | oss_buffer_size = snd_pcm_plug_client_size(substream, |
721 | snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size; | 721 | snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size; |
722 | oss_buffer_size = 1 << ld2(oss_buffer_size); | 722 | oss_buffer_size = rounddown_pow_of_two(oss_buffer_size); |
723 | if (atomic_read(&substream->mmap_count)) { | 723 | if (atomic_read(&substream->mmap_count)) { |
724 | if (oss_buffer_size > runtime->oss.mmap_bytes) | 724 | if (oss_buffer_size > runtime->oss.mmap_bytes) |
725 | oss_buffer_size = runtime->oss.mmap_bytes; | 725 | oss_buffer_size = runtime->oss.mmap_bytes; |
@@ -755,14 +755,14 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, | |||
755 | min_period_size = snd_pcm_plug_client_size(substream, | 755 | min_period_size = snd_pcm_plug_client_size(substream, |
756 | snd_pcm_hw_param_value_min(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL)); | 756 | snd_pcm_hw_param_value_min(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL)); |
757 | min_period_size *= oss_frame_size; | 757 | min_period_size *= oss_frame_size; |
758 | min_period_size = 1 << (ld2(min_period_size - 1) + 1); | 758 | min_period_size = roundup_pow_of_two(min_period_size); |
759 | if (oss_period_size < min_period_size) | 759 | if (oss_period_size < min_period_size) |
760 | oss_period_size = min_period_size; | 760 | oss_period_size = min_period_size; |
761 | 761 | ||
762 | max_period_size = snd_pcm_plug_client_size(substream, | 762 | max_period_size = snd_pcm_plug_client_size(substream, |
763 | snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL)); | 763 | snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL)); |
764 | max_period_size *= oss_frame_size; | 764 | max_period_size *= oss_frame_size; |
765 | max_period_size = 1 << ld2(max_period_size); | 765 | max_period_size = rounddown_pow_of_two(max_period_size); |
766 | if (oss_period_size > max_period_size) | 766 | if (oss_period_size > max_period_size) |
767 | oss_period_size = max_period_size; | 767 | oss_period_size = max_period_size; |
768 | 768 | ||
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index ec9e7866177f..db05e04d0070 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -1299,8 +1299,14 @@ static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, | |||
1299 | int width = l & 0xffff; | 1299 | int width = l & 0xffff; |
1300 | unsigned int msbits = l >> 16; | 1300 | unsigned int msbits = l >> 16; |
1301 | struct snd_interval *i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); | 1301 | struct snd_interval *i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); |
1302 | if (snd_interval_single(i) && snd_interval_value(i) == width) | 1302 | |
1303 | params->msbits = msbits; | 1303 | if (!snd_interval_single(i)) |
1304 | return 0; | ||
1305 | |||
1306 | if ((snd_interval_value(i) == width) || | ||
1307 | (width == 0 && snd_interval_value(i) > msbits)) | ||
1308 | params->msbits = min_not_zero(params->msbits, msbits); | ||
1309 | |||
1304 | return 0; | 1310 | return 0; |
1305 | } | 1311 | } |
1306 | 1312 | ||
@@ -1311,6 +1317,11 @@ static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, | |||
1311 | * @width: sample bits width | 1317 | * @width: sample bits width |
1312 | * @msbits: msbits width | 1318 | * @msbits: msbits width |
1313 | * | 1319 | * |
1320 | * This constraint will set the number of most significant bits (msbits) if a | ||
1321 | * sample format with the specified width has been select. If width is set to 0 | ||
1322 | * the msbits will be set for any sample format with a width larger than the | ||
1323 | * specified msbits. | ||
1324 | * | ||
1314 | * Return: Zero if successful, or a negative error code on failure. | 1325 | * Return: Zero if successful, or a negative error code on failure. |
1315 | */ | 1326 | */ |
1316 | int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, | 1327 | int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 095d9572ad2b..ff3abc3b4ff5 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -420,7 +420,8 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, | |||
420 | 420 | ||
421 | hw = &substream->runtime->hw; | 421 | hw = &substream->runtime->hw; |
422 | if (!params->info) { | 422 | if (!params->info) { |
423 | params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES; | 423 | params->info = hw->info & ~(SNDRV_PCM_INFO_FIFO_IN_FRAMES | |
424 | SNDRV_PCM_INFO_DRAIN_TRIGGER); | ||
424 | if (!hw_support_mmap(substream)) | 425 | if (!hw_support_mmap(substream)) |
425 | params->info &= ~(SNDRV_PCM_INFO_MMAP | | 426 | params->info &= ~(SNDRV_PCM_INFO_MMAP | |
426 | SNDRV_PCM_INFO_MMAP_VALID); | 427 | SNDRV_PCM_INFO_MMAP_VALID); |
@@ -1566,6 +1567,13 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state) | |||
1566 | snd_pcm_post_stop(substream, new_state); | 1567 | snd_pcm_post_stop(substream, new_state); |
1567 | } | 1568 | } |
1568 | } | 1569 | } |
1570 | |||
1571 | if (runtime->status->state == SNDRV_PCM_STATE_DRAINING && | ||
1572 | runtime->trigger_master == substream && | ||
1573 | (runtime->hw.info & SNDRV_PCM_INFO_DRAIN_TRIGGER)) | ||
1574 | return substream->ops->trigger(substream, | ||
1575 | SNDRV_PCM_TRIGGER_DRAIN); | ||
1576 | |||
1569 | return 0; | 1577 | return 0; |
1570 | } | 1578 | } |
1571 | 1579 | ||
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c index 3a4569669efa..e79cc44b1394 100644 --- a/sound/core/seq/oss/seq_oss_midi.c +++ b/sound/core/seq/oss/seq_oss_midi.c | |||
@@ -237,8 +237,7 @@ snd_seq_oss_midi_check_exit_port(int client, int port) | |||
237 | spin_unlock_irqrestore(®ister_lock, flags); | 237 | spin_unlock_irqrestore(®ister_lock, flags); |
238 | snd_use_lock_free(&mdev->use_lock); | 238 | snd_use_lock_free(&mdev->use_lock); |
239 | snd_use_lock_sync(&mdev->use_lock); | 239 | snd_use_lock_sync(&mdev->use_lock); |
240 | if (mdev->coder) | 240 | snd_midi_event_free(mdev->coder); |
241 | snd_midi_event_free(mdev->coder); | ||
242 | kfree(mdev); | 241 | kfree(mdev); |
243 | } | 242 | } |
244 | spin_lock_irqsave(®ister_lock, flags); | 243 | spin_lock_irqsave(®ister_lock, flags); |
@@ -265,8 +264,7 @@ snd_seq_oss_midi_clear_all(void) | |||
265 | spin_lock_irqsave(®ister_lock, flags); | 264 | spin_lock_irqsave(®ister_lock, flags); |
266 | for (i = 0; i < max_midi_devs; i++) { | 265 | for (i = 0; i < max_midi_devs; i++) { |
267 | if ((mdev = midi_devs[i]) != NULL) { | 266 | if ((mdev = midi_devs[i]) != NULL) { |
268 | if (mdev->coder) | 267 | snd_midi_event_free(mdev->coder); |
269 | snd_midi_event_free(mdev->coder); | ||
270 | kfree(mdev); | 268 | kfree(mdev); |
271 | midi_devs[i] = NULL; | 269 | midi_devs[i] = NULL; |
272 | } | 270 | } |
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index a1fd77af6059..68fec776da26 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c | |||
@@ -268,8 +268,7 @@ static void snd_seq_midisynth_delete(struct seq_midisynth *msynth) | |||
268 | snd_seq_event_port_detach(msynth->seq_client, msynth->seq_port); | 268 | snd_seq_event_port_detach(msynth->seq_client, msynth->seq_port); |
269 | } | 269 | } |
270 | 270 | ||
271 | if (msynth->parser) | 271 | snd_midi_event_free(msynth->parser); |
272 | snd_midi_event_free(msynth->parser); | ||
273 | } | 272 | } |
274 | 273 | ||
275 | /* register new midi synth port */ | 274 | /* register new midi synth port */ |
diff --git a/sound/core/timer.c b/sound/core/timer.c index 777a45e08e53..a44235555896 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -1030,9 +1030,7 @@ static int snd_timer_register_system(void) | |||
1030 | snd_timer_free(timer); | 1030 | snd_timer_free(timer); |
1031 | return -ENOMEM; | 1031 | return -ENOMEM; |
1032 | } | 1032 | } |
1033 | init_timer(&priv->tlist); | 1033 | setup_timer(&priv->tlist, snd_timer_s_function, (unsigned long) timer); |
1034 | priv->tlist.function = snd_timer_s_function; | ||
1035 | priv->tlist.data = (unsigned long) timer; | ||
1036 | timer->private_data = priv; | 1034 | timer->private_data = priv; |
1037 | timer->private_free = snd_timer_free_system; | 1035 | timer->private_free = snd_timer_free_system; |
1038 | return snd_timer_global_register(timer); | 1036 | return snd_timer_global_register(timer); |
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 7ea53399404d..7f9126efc1e5 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c | |||
@@ -181,8 +181,7 @@ static void loopback_timer_start(struct loopback_pcm *dpcm) | |||
181 | } | 181 | } |
182 | tick = dpcm->period_size_frac - dpcm->irq_pos; | 182 | tick = dpcm->period_size_frac - dpcm->irq_pos; |
183 | tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps; | 183 | tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps; |
184 | dpcm->timer.expires = jiffies + tick; | 184 | mod_timer(&dpcm->timer, jiffies + tick); |
185 | add_timer(&dpcm->timer); | ||
186 | } | 185 | } |
187 | 186 | ||
188 | /* call in cable->lock */ | 187 | /* call in cable->lock */ |
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 5d0dfb787cec..d11baaf0f0b4 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c | |||
@@ -245,9 +245,8 @@ struct dummy_systimer_pcm { | |||
245 | 245 | ||
246 | static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm) | 246 | static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm) |
247 | { | 247 | { |
248 | dpcm->timer.expires = jiffies + | 248 | mod_timer(&dpcm->timer, jiffies + |
249 | (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate; | 249 | (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate); |
250 | add_timer(&dpcm->timer); | ||
251 | } | 250 | } |
252 | 251 | ||
253 | static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm) | 252 | static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm) |
@@ -340,9 +339,8 @@ static int dummy_systimer_create(struct snd_pcm_substream *substream) | |||
340 | if (!dpcm) | 339 | if (!dpcm) |
341 | return -ENOMEM; | 340 | return -ENOMEM; |
342 | substream->runtime->private_data = dpcm; | 341 | substream->runtime->private_data = dpcm; |
343 | init_timer(&dpcm->timer); | 342 | setup_timer(&dpcm->timer, dummy_systimer_callback, |
344 | dpcm->timer.data = (unsigned long) dpcm; | 343 | (unsigned long) dpcm); |
345 | dpcm->timer.function = dummy_systimer_callback; | ||
346 | spin_lock_init(&dpcm->lock); | 344 | spin_lock_init(&dpcm->lock); |
347 | dpcm->substream = substream; | 345 | dpcm->substream = substream; |
348 | return 0; | 346 | return 0; |
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c index bcca825a1c8d..bdcb5721393b 100644 --- a/sound/drivers/ml403-ac97cr.c +++ b/sound/drivers/ml403-ac97cr.c | |||
@@ -1094,8 +1094,7 @@ static int snd_ml403_ac97cr_free(struct snd_ml403_ac97cr *ml403_ac97cr) | |||
1094 | if (ml403_ac97cr->capture_irq >= 0) | 1094 | if (ml403_ac97cr->capture_irq >= 0) |
1095 | free_irq(ml403_ac97cr->capture_irq, ml403_ac97cr); | 1095 | free_irq(ml403_ac97cr->capture_irq, ml403_ac97cr); |
1096 | /* give back "port" */ | 1096 | /* give back "port" */ |
1097 | if (ml403_ac97cr->port != NULL) | 1097 | iounmap(ml403_ac97cr->port); |
1098 | iounmap(ml403_ac97cr->port); | ||
1099 | kfree(ml403_ac97cr); | 1098 | kfree(ml403_ac97cr); |
1100 | PDEBUG(INIT_INFO, "free(): (done)\n"); | 1099 | PDEBUG(INIT_INFO, "free(): (done)\n"); |
1101 | return 0; | 1100 | return 0; |
@@ -1238,14 +1237,11 @@ snd_ml403_ac97cr_mixer(struct snd_ml403_ac97cr *ml403_ac97cr) | |||
1238 | } | 1237 | } |
1239 | 1238 | ||
1240 | static int | 1239 | static int |
1241 | snd_ml403_ac97cr_pcm(struct snd_ml403_ac97cr *ml403_ac97cr, int device, | 1240 | snd_ml403_ac97cr_pcm(struct snd_ml403_ac97cr *ml403_ac97cr, int device) |
1242 | struct snd_pcm **rpcm) | ||
1243 | { | 1241 | { |
1244 | struct snd_pcm *pcm; | 1242 | struct snd_pcm *pcm; |
1245 | int err; | 1243 | int err; |
1246 | 1244 | ||
1247 | if (rpcm) | ||
1248 | *rpcm = NULL; | ||
1249 | err = snd_pcm_new(ml403_ac97cr->card, "ML403AC97CR/1", device, 1, 1, | 1245 | err = snd_pcm_new(ml403_ac97cr->card, "ML403AC97CR/1", device, 1, 1, |
1250 | &pcm); | 1246 | &pcm); |
1251 | if (err < 0) | 1247 | if (err < 0) |
@@ -1263,8 +1259,6 @@ snd_ml403_ac97cr_pcm(struct snd_ml403_ac97cr *ml403_ac97cr, int device, | |||
1263 | snd_dma_continuous_data(GFP_KERNEL), | 1259 | snd_dma_continuous_data(GFP_KERNEL), |
1264 | 64 * 1024, | 1260 | 64 * 1024, |
1265 | 128 * 1024); | 1261 | 128 * 1024); |
1266 | if (rpcm) | ||
1267 | *rpcm = pcm; | ||
1268 | return 0; | 1262 | return 0; |
1269 | } | 1263 | } |
1270 | 1264 | ||
@@ -1298,7 +1292,7 @@ static int snd_ml403_ac97cr_probe(struct platform_device *pfdev) | |||
1298 | return err; | 1292 | return err; |
1299 | } | 1293 | } |
1300 | PDEBUG(INIT_INFO, "probe(): mixer done\n"); | 1294 | PDEBUG(INIT_INFO, "probe(): mixer done\n"); |
1301 | err = snd_ml403_ac97cr_pcm(ml403_ac97cr, 0, NULL); | 1295 | err = snd_ml403_ac97cr_pcm(ml403_ac97cr, 0); |
1302 | if (err < 0) { | 1296 | if (err < 0) { |
1303 | snd_card_free(card); | 1297 | snd_card_free(card); |
1304 | return err; | 1298 | return err; |
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index e3a90d043f03..1e19eb9e1596 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c | |||
@@ -176,8 +176,7 @@ static void snd_mpu401_uart_timer(unsigned long data) | |||
176 | 176 | ||
177 | spin_lock_irqsave(&mpu->timer_lock, flags); | 177 | spin_lock_irqsave(&mpu->timer_lock, flags); |
178 | /*mpu->mode |= MPU401_MODE_TIMER;*/ | 178 | /*mpu->mode |= MPU401_MODE_TIMER;*/ |
179 | mpu->timer.expires = 1 + jiffies; | 179 | mod_timer(&mpu->timer, 1 + jiffies); |
180 | add_timer(&mpu->timer); | ||
181 | spin_unlock_irqrestore(&mpu->timer_lock, flags); | 180 | spin_unlock_irqrestore(&mpu->timer_lock, flags); |
182 | if (mpu->rmidi) | 181 | if (mpu->rmidi) |
183 | _snd_mpu401_uart_interrupt(mpu); | 182 | _snd_mpu401_uart_interrupt(mpu); |
@@ -192,11 +191,9 @@ static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input) | |||
192 | 191 | ||
193 | spin_lock_irqsave (&mpu->timer_lock, flags); | 192 | spin_lock_irqsave (&mpu->timer_lock, flags); |
194 | if (mpu->timer_invoked == 0) { | 193 | if (mpu->timer_invoked == 0) { |
195 | init_timer(&mpu->timer); | 194 | setup_timer(&mpu->timer, snd_mpu401_uart_timer, |
196 | mpu->timer.data = (unsigned long)mpu; | 195 | (unsigned long)mpu); |
197 | mpu->timer.function = snd_mpu401_uart_timer; | 196 | mod_timer(&mpu->timer, 1 + jiffies); |
198 | mpu->timer.expires = 1 + jiffies; | ||
199 | add_timer(&mpu->timer); | ||
200 | } | 197 | } |
201 | mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER : | 198 | mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER : |
202 | MPU401_MODE_OUTPUT_TIMER; | 199 | MPU401_MODE_OUTPUT_TIMER; |
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c index 15769447688f..30e8a1d5bc87 100644 --- a/sound/drivers/mtpav.c +++ b/sound/drivers/mtpav.c | |||
@@ -414,8 +414,7 @@ static void snd_mtpav_output_timer(unsigned long data) | |||
414 | 414 | ||
415 | spin_lock_irqsave(&chip->spinlock, flags); | 415 | spin_lock_irqsave(&chip->spinlock, flags); |
416 | /* reprogram timer */ | 416 | /* reprogram timer */ |
417 | chip->timer.expires = 1 + jiffies; | 417 | mod_timer(&chip->timer, 1 + jiffies); |
418 | add_timer(&chip->timer); | ||
419 | /* process each port */ | 418 | /* process each port */ |
420 | for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) { | 419 | for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) { |
421 | struct mtpav_port *portp = &chip->ports[p]; | 420 | struct mtpav_port *portp = &chip->ports[p]; |
@@ -428,8 +427,7 @@ static void snd_mtpav_output_timer(unsigned long data) | |||
428 | /* spinlock held! */ | 427 | /* spinlock held! */ |
429 | static void snd_mtpav_add_output_timer(struct mtpav *chip) | 428 | static void snd_mtpav_add_output_timer(struct mtpav *chip) |
430 | { | 429 | { |
431 | chip->timer.expires = 1 + jiffies; | 430 | mod_timer(&chip->timer, 1 + jiffies); |
432 | add_timer(&chip->timer); | ||
433 | } | 431 | } |
434 | 432 | ||
435 | /* spinlock held! */ | 433 | /* spinlock held! */ |
@@ -704,15 +702,13 @@ static int snd_mtpav_probe(struct platform_device *dev) | |||
704 | 702 | ||
705 | mtp_card = card->private_data; | 703 | mtp_card = card->private_data; |
706 | spin_lock_init(&mtp_card->spinlock); | 704 | spin_lock_init(&mtp_card->spinlock); |
707 | init_timer(&mtp_card->timer); | ||
708 | mtp_card->card = card; | 705 | mtp_card->card = card; |
709 | mtp_card->irq = -1; | 706 | mtp_card->irq = -1; |
710 | mtp_card->share_irq = 0; | 707 | mtp_card->share_irq = 0; |
711 | mtp_card->inmidistate = 0; | 708 | mtp_card->inmidistate = 0; |
712 | mtp_card->outmidihwport = 0xffffffff; | 709 | mtp_card->outmidihwport = 0xffffffff; |
713 | init_timer(&mtp_card->timer); | 710 | setup_timer(&mtp_card->timer, snd_mtpav_output_timer, |
714 | mtp_card->timer.function = snd_mtpav_output_timer; | 711 | (unsigned long) mtp_card); |
715 | mtp_card->timer.data = (unsigned long) mtp_card; | ||
716 | 712 | ||
717 | card->private_free = snd_mtpav_free; | 713 | card->private_free = snd_mtpav_free; |
718 | 714 | ||
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c index 6c6d09a51f42..f62780ed64ad 100644 --- a/sound/drivers/opl3/opl3_midi.c +++ b/sound/drivers/opl3/opl3_midi.c | |||
@@ -258,12 +258,10 @@ void snd_opl3_timer_func(unsigned long data) | |||
258 | spin_unlock_irqrestore(&opl3->voice_lock, flags); | 258 | spin_unlock_irqrestore(&opl3->voice_lock, flags); |
259 | 259 | ||
260 | spin_lock_irqsave(&opl3->sys_timer_lock, flags); | 260 | spin_lock_irqsave(&opl3->sys_timer_lock, flags); |
261 | if (again) { | 261 | if (again) |
262 | opl3->tlist.expires = jiffies + 1; /* invoke again */ | 262 | mod_timer(&opl3->tlist, jiffies + 1); /* invoke again */ |
263 | add_timer(&opl3->tlist); | 263 | else |
264 | } else { | ||
265 | opl3->sys_timer_status = 0; | 264 | opl3->sys_timer_status = 0; |
266 | } | ||
267 | spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); | 265 | spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); |
268 | } | 266 | } |
269 | 267 | ||
@@ -275,8 +273,7 @@ static void snd_opl3_start_timer(struct snd_opl3 *opl3) | |||
275 | unsigned long flags; | 273 | unsigned long flags; |
276 | spin_lock_irqsave(&opl3->sys_timer_lock, flags); | 274 | spin_lock_irqsave(&opl3->sys_timer_lock, flags); |
277 | if (! opl3->sys_timer_status) { | 275 | if (! opl3->sys_timer_status) { |
278 | opl3->tlist.expires = jiffies + 1; | 276 | mod_timer(&opl3->tlist, jiffies + 1); |
279 | add_timer(&opl3->tlist); | ||
280 | opl3->sys_timer_status = 1; | 277 | opl3->sys_timer_status = 1; |
281 | } | 278 | } |
282 | spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); | 279 | spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); |
diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c index 68399538e435..a9f618e06a22 100644 --- a/sound/drivers/opl3/opl3_seq.c +++ b/sound/drivers/opl3/opl3_seq.c | |||
@@ -247,9 +247,7 @@ static int snd_opl3_seq_new_device(struct snd_seq_device *dev) | |||
247 | } | 247 | } |
248 | 248 | ||
249 | /* setup system timer */ | 249 | /* setup system timer */ |
250 | init_timer(&opl3->tlist); | 250 | setup_timer(&opl3->tlist, snd_opl3_timer_func, (unsigned long) opl3); |
251 | opl3->tlist.function = snd_opl3_timer_func; | ||
252 | opl3->tlist.data = (unsigned long) opl3; | ||
253 | spin_lock_init(&opl3->sys_timer_lock); | 251 | spin_lock_init(&opl3->sys_timer_lock); |
254 | opl3->sys_timer_status = 0; | 252 | opl3->sys_timer_status = 0; |
255 | 253 | ||
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c index 13a34e3c6382..8c1dc73e14e4 100644 --- a/sound/drivers/serial-u16550.c +++ b/sound/drivers/serial-u16550.c | |||
@@ -174,9 +174,8 @@ static inline void snd_uart16550_add_timer(struct snd_uart16550 *uart) | |||
174 | { | 174 | { |
175 | if (!uart->timer_running) { | 175 | if (!uart->timer_running) { |
176 | /* timer 38600bps * 10bit * 16byte */ | 176 | /* timer 38600bps * 10bit * 16byte */ |
177 | uart->buffer_timer.expires = jiffies + (HZ+255)/256; | 177 | mod_timer(&uart->buffer_timer, jiffies + (HZ + 255) / 256); |
178 | uart->timer_running = 1; | 178 | uart->timer_running = 1; |
179 | add_timer(&uart->buffer_timer); | ||
180 | } | 179 | } |
181 | } | 180 | } |
182 | 181 | ||
@@ -830,9 +829,8 @@ static int snd_uart16550_create(struct snd_card *card, | |||
830 | uart->prev_in = 0; | 829 | uart->prev_in = 0; |
831 | uart->rstatus = 0; | 830 | uart->rstatus = 0; |
832 | memset(uart->prev_status, 0x80, sizeof(unsigned char) * SNDRV_SERIAL_MAX_OUTS); | 831 | memset(uart->prev_status, 0x80, sizeof(unsigned char) * SNDRV_SERIAL_MAX_OUTS); |
833 | init_timer(&uart->buffer_timer); | 832 | setup_timer(&uart->buffer_timer, snd_uart16550_buffer_timer, |
834 | uart->buffer_timer.function = snd_uart16550_buffer_timer; | 833 | (unsigned long)uart); |
835 | uart->buffer_timer.data = (unsigned long)uart; | ||
836 | uart->timer_running = 0; | 834 | uart->timer_running = 0; |
837 | 835 | ||
838 | /* Register device */ | 836 | /* Register device */ |
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c index 88452e899bd9..48848909a5a9 100644 --- a/sound/i2c/other/ak4117.c +++ b/sound/i2c/other/ak4117.c | |||
@@ -91,9 +91,7 @@ int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t | |||
91 | chip->read = read; | 91 | chip->read = read; |
92 | chip->write = write; | 92 | chip->write = write; |
93 | chip->private_data = private_data; | 93 | chip->private_data = private_data; |
94 | init_timer(&chip->timer); | 94 | setup_timer(&chip->timer, snd_ak4117_timer, (unsigned long)chip); |
95 | chip->timer.data = (unsigned long)chip; | ||
96 | chip->timer.function = snd_ak4117_timer; | ||
97 | 95 | ||
98 | for (reg = 0; reg < 5; reg++) | 96 | for (reg = 0; reg < 5; reg++) |
99 | chip->regmap[reg] = pgm[reg]; | 97 | chip->regmap[reg] = pgm[reg]; |
@@ -139,8 +137,7 @@ void snd_ak4117_reinit(struct ak4117 *chip) | |||
139 | /* release powerdown, everything is initialized now */ | 137 | /* release powerdown, everything is initialized now */ |
140 | reg_write(chip, AK4117_REG_PWRDN, old | AK4117_RST | AK4117_PWN); | 138 | reg_write(chip, AK4117_REG_PWRDN, old | AK4117_RST | AK4117_PWN); |
141 | chip->init = 0; | 139 | chip->init = 0; |
142 | chip->timer.expires = 1 + jiffies; | 140 | mod_timer(&chip->timer, 1 + jiffies); |
143 | add_timer(&chip->timer); | ||
144 | } | 141 | } |
145 | 142 | ||
146 | static unsigned int external_rate(unsigned char rcs1) | 143 | static unsigned int external_rate(unsigned char rcs1) |
@@ -540,8 +537,7 @@ static void snd_ak4117_timer(unsigned long data) | |||
540 | if (chip->init) | 537 | if (chip->init) |
541 | return; | 538 | return; |
542 | snd_ak4117_check_rate_and_errors(chip, 0); | 539 | snd_ak4117_check_rate_and_errors(chip, 0); |
543 | chip->timer.expires = 1 + jiffies; | 540 | mod_timer(&chip->timer, 1 + jiffies); |
544 | add_timer(&chip->timer); | ||
545 | } | 541 | } |
546 | 542 | ||
547 | EXPORT_SYMBOL(snd_ak4117_create); | 543 | EXPORT_SYMBOL(snd_ak4117_create); |
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index f481a41e027e..769226515f0d 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c | |||
@@ -142,7 +142,6 @@ static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard, | |||
142 | struct snd_card *card; | 142 | struct snd_card *card; |
143 | struct snd_ad1816a *chip; | 143 | struct snd_ad1816a *chip; |
144 | struct snd_opl3 *opl3; | 144 | struct snd_opl3 *opl3; |
145 | struct snd_timer *timer; | ||
146 | 145 | ||
147 | error = snd_card_new(&pcard->card->dev, | 146 | error = snd_card_new(&pcard->card->dev, |
148 | index[dev], id[dev], THIS_MODULE, | 147 | index[dev], id[dev], THIS_MODULE, |
@@ -172,7 +171,7 @@ static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard, | |||
172 | sprintf(card->longname, "%s, SS at 0x%lx, irq %d, dma %d&%d", | 171 | sprintf(card->longname, "%s, SS at 0x%lx, irq %d, dma %d&%d", |
173 | card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]); | 172 | card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]); |
174 | 173 | ||
175 | if ((error = snd_ad1816a_pcm(chip, 0, NULL)) < 0) { | 174 | if ((error = snd_ad1816a_pcm(chip, 0)) < 0) { |
176 | snd_card_free(card); | 175 | snd_card_free(card); |
177 | return error; | 176 | return error; |
178 | } | 177 | } |
@@ -182,7 +181,7 @@ static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard, | |||
182 | return error; | 181 | return error; |
183 | } | 182 | } |
184 | 183 | ||
185 | error = snd_ad1816a_timer(chip, 0, &timer); | 184 | error = snd_ad1816a_timer(chip, 0); |
186 | if (error < 0) { | 185 | if (error < 0) { |
187 | snd_card_free(card); | 186 | snd_card_free(card); |
188 | return error; | 187 | return error; |
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index 01a07986f4a3..5f99102cc0c1 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c | |||
@@ -675,7 +675,7 @@ static struct snd_pcm_ops snd_ad1816a_capture_ops = { | |||
675 | .pointer = snd_ad1816a_capture_pointer, | 675 | .pointer = snd_ad1816a_capture_pointer, |
676 | }; | 676 | }; |
677 | 677 | ||
678 | int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm) | 678 | int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device) |
679 | { | 679 | { |
680 | int error; | 680 | int error; |
681 | struct snd_pcm *pcm; | 681 | struct snd_pcm *pcm; |
@@ -697,13 +697,10 @@ int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm) | |||
697 | 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); | 697 | 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); |
698 | 698 | ||
699 | chip->pcm = pcm; | 699 | chip->pcm = pcm; |
700 | if (rpcm) | ||
701 | *rpcm = pcm; | ||
702 | return 0; | 700 | return 0; |
703 | } | 701 | } |
704 | 702 | ||
705 | int snd_ad1816a_timer(struct snd_ad1816a *chip, int device, | 703 | int snd_ad1816a_timer(struct snd_ad1816a *chip, int device) |
706 | struct snd_timer **rtimer) | ||
707 | { | 704 | { |
708 | struct snd_timer *timer; | 705 | struct snd_timer *timer; |
709 | struct snd_timer_id tid; | 706 | struct snd_timer_id tid; |
@@ -720,8 +717,6 @@ int snd_ad1816a_timer(struct snd_ad1816a *chip, int device, | |||
720 | timer->private_data = chip; | 717 | timer->private_data = chip; |
721 | chip->timer = timer; | 718 | chip->timer = timer; |
722 | timer->hw = snd_ad1816a_timer_table; | 719 | timer->hw = snd_ad1816a_timer_table; |
723 | if (rtimer) | ||
724 | *rtimer = timer; | ||
725 | return 0; | 720 | return 0; |
726 | } | 721 | } |
727 | 722 | ||
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index 093f22a464d7..f159da4ec890 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c | |||
@@ -88,7 +88,6 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n) | |||
88 | { | 88 | { |
89 | struct snd_card *card; | 89 | struct snd_card *card; |
90 | struct snd_wss *chip; | 90 | struct snd_wss *chip; |
91 | struct snd_pcm *pcm; | ||
92 | int error; | 91 | int error; |
93 | 92 | ||
94 | error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card); | 93 | error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card); |
@@ -103,7 +102,7 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n) | |||
103 | 102 | ||
104 | card->private_data = chip; | 103 | card->private_data = chip; |
105 | 104 | ||
106 | error = snd_wss_pcm(chip, 0, &pcm); | 105 | error = snd_wss_pcm(chip, 0); |
107 | if (error < 0) | 106 | if (error < 0) |
108 | goto out; | 107 | goto out; |
109 | 108 | ||
@@ -112,10 +111,10 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n) | |||
112 | goto out; | 111 | goto out; |
113 | 112 | ||
114 | strcpy(card->driver, "AD1848"); | 113 | strcpy(card->driver, "AD1848"); |
115 | strcpy(card->shortname, pcm->name); | 114 | strcpy(card->shortname, chip->pcm->name); |
116 | 115 | ||
117 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", | 116 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", |
118 | pcm->name, chip->port, irq[n], dma1[n]); | 117 | chip->pcm->name, chip->port, irq[n], dma1[n]); |
119 | if (thinkpad[n]) | 118 | if (thinkpad[n]) |
120 | strcat(card->longname, " [Thinkpad]"); | 119 | strcat(card->longname, " [Thinkpad]"); |
121 | 120 | ||
diff --git a/sound/isa/als100.c b/sound/isa/als100.c index 32d01525211d..bc9ea306ee02 100644 --- a/sound/isa/als100.c +++ b/sound/isa/als100.c | |||
@@ -233,7 +233,7 @@ static int snd_card_als100_probe(int dev, | |||
233 | irq[dev], dma8[dev], dma16[dev]); | 233 | irq[dev], dma8[dev], dma16[dev]); |
234 | } | 234 | } |
235 | 235 | ||
236 | if ((error = snd_sb16dsp_pcm(chip, 0, &chip->pcm)) < 0) { | 236 | if ((error = snd_sb16dsp_pcm(chip, 0)) < 0) { |
237 | snd_card_free(card); | 237 | snd_card_free(card); |
238 | return error; | 238 | return error; |
239 | } | 239 | } |
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c index 0ea75fc62072..b8e768e5ce80 100644 --- a/sound/isa/azt2320.c +++ b/sound/isa/azt2320.c | |||
@@ -215,7 +215,7 @@ static int snd_card_azt2320_probe(int dev, | |||
215 | sprintf(card->longname, "%s, WSS at 0x%lx, irq %i, dma %i&%i", | 215 | sprintf(card->longname, "%s, WSS at 0x%lx, irq %i, dma %i&%i", |
216 | card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]); | 216 | card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]); |
217 | 217 | ||
218 | error = snd_wss_pcm(chip, 0, NULL); | 218 | error = snd_wss_pcm(chip, 0); |
219 | if (error < 0) { | 219 | if (error < 0) { |
220 | snd_card_free(card); | 220 | snd_card_free(card); |
221 | return error; | 221 | return error; |
@@ -225,7 +225,7 @@ static int snd_card_azt2320_probe(int dev, | |||
225 | snd_card_free(card); | 225 | snd_card_free(card); |
226 | return error; | 226 | return error; |
227 | } | 227 | } |
228 | error = snd_wss_timer(chip, 0, NULL); | 228 | error = snd_wss_timer(chip, 0); |
229 | if (error < 0) { | 229 | if (error < 0) { |
230 | snd_card_free(card); | 230 | snd_card_free(card); |
231 | return error; | 231 | return error; |
diff --git a/sound/isa/cmi8328.c b/sound/isa/cmi8328.c index 4778852a1201..2c89d95da674 100644 --- a/sound/isa/cmi8328.c +++ b/sound/isa/cmi8328.c | |||
@@ -307,7 +307,7 @@ static int snd_cmi8328_probe(struct device *pdev, unsigned int ndev) | |||
307 | if (err < 0) | 307 | if (err < 0) |
308 | goto error; | 308 | goto error; |
309 | 309 | ||
310 | err = snd_wss_pcm(cmi->wss, 0, NULL); | 310 | err = snd_wss_pcm(cmi->wss, 0); |
311 | if (err < 0) | 311 | if (err < 0) |
312 | goto error; | 312 | goto error; |
313 | 313 | ||
@@ -318,7 +318,7 @@ static int snd_cmi8328_probe(struct device *pdev, unsigned int ndev) | |||
318 | if (err < 0) | 318 | if (err < 0) |
319 | goto error; | 319 | goto error; |
320 | 320 | ||
321 | if (snd_wss_timer(cmi->wss, 0, NULL) < 0) | 321 | if (snd_wss_timer(cmi->wss, 0) < 0) |
322 | snd_printk(KERN_WARNING "error initializing WSS timer\n"); | 322 | snd_printk(KERN_WARNING "error initializing WSS timer\n"); |
323 | 323 | ||
324 | if (mpuport[ndev] == SNDRV_AUTO_PORT) { | 324 | if (mpuport[ndev] == SNDRV_AUTO_PORT) { |
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index 7dba07a4343a..282cd75d2235 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c | |||
@@ -92,7 +92,6 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n) | |||
92 | { | 92 | { |
93 | struct snd_card *card; | 93 | struct snd_card *card; |
94 | struct snd_wss *chip; | 94 | struct snd_wss *chip; |
95 | struct snd_pcm *pcm; | ||
96 | int error; | 95 | int error; |
97 | 96 | ||
98 | error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card); | 97 | error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card); |
@@ -106,15 +105,15 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n) | |||
106 | 105 | ||
107 | card->private_data = chip; | 106 | card->private_data = chip; |
108 | 107 | ||
109 | error = snd_wss_pcm(chip, 0, &pcm); | 108 | error = snd_wss_pcm(chip, 0); |
110 | if (error < 0) | 109 | if (error < 0) |
111 | goto out; | 110 | goto out; |
112 | 111 | ||
113 | strcpy(card->driver, "CS4231"); | 112 | strcpy(card->driver, "CS4231"); |
114 | strcpy(card->shortname, pcm->name); | 113 | strcpy(card->shortname, chip->pcm->name); |
115 | 114 | ||
116 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", | 115 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", |
117 | pcm->name, chip->port, irq[n], dma1[n]); | 116 | chip->pcm->name, chip->port, irq[n], dma1[n]); |
118 | if (dma2[n] >= 0) | 117 | if (dma2[n] >= 0) |
119 | sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]); | 118 | sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]); |
120 | 119 | ||
@@ -122,7 +121,7 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n) | |||
122 | if (error < 0) | 121 | if (error < 0) |
123 | goto out; | 122 | goto out; |
124 | 123 | ||
125 | error = snd_wss_timer(chip, 0, NULL); | 124 | error = snd_wss_timer(chip, 0); |
126 | if (error < 0) | 125 | if (error < 0) |
127 | goto out; | 126 | goto out; |
128 | 127 | ||
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 750f51c904fc..9d7582c90a95 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c | |||
@@ -382,7 +382,6 @@ static int snd_cs423x_card_new(struct device *pdev, int dev, | |||
382 | static int snd_cs423x_probe(struct snd_card *card, int dev) | 382 | static int snd_cs423x_probe(struct snd_card *card, int dev) |
383 | { | 383 | { |
384 | struct snd_card_cs4236 *acard; | 384 | struct snd_card_cs4236 *acard; |
385 | struct snd_pcm *pcm; | ||
386 | struct snd_wss *chip; | 385 | struct snd_wss *chip; |
387 | struct snd_opl3 *opl3; | 386 | struct snd_opl3 *opl3; |
388 | int err; | 387 | int err; |
@@ -404,7 +403,7 @@ static int snd_cs423x_probe(struct snd_card *card, int dev) | |||
404 | acard->chip = chip; | 403 | acard->chip = chip; |
405 | if (chip->hardware & WSS_HW_CS4236B_MASK) { | 404 | if (chip->hardware & WSS_HW_CS4236B_MASK) { |
406 | 405 | ||
407 | err = snd_cs4236_pcm(chip, 0, &pcm); | 406 | err = snd_cs4236_pcm(chip, 0); |
408 | if (err < 0) | 407 | if (err < 0) |
409 | return err; | 408 | return err; |
410 | 409 | ||
@@ -412,7 +411,7 @@ static int snd_cs423x_probe(struct snd_card *card, int dev) | |||
412 | if (err < 0) | 411 | if (err < 0) |
413 | return err; | 412 | return err; |
414 | } else { | 413 | } else { |
415 | err = snd_wss_pcm(chip, 0, &pcm); | 414 | err = snd_wss_pcm(chip, 0); |
416 | if (err < 0) | 415 | if (err < 0) |
417 | return err; | 416 | return err; |
418 | 417 | ||
@@ -420,17 +419,17 @@ static int snd_cs423x_probe(struct snd_card *card, int dev) | |||
420 | if (err < 0) | 419 | if (err < 0) |
421 | return err; | 420 | return err; |
422 | } | 421 | } |
423 | strcpy(card->driver, pcm->name); | 422 | strcpy(card->driver, chip->pcm->name); |
424 | strcpy(card->shortname, pcm->name); | 423 | strcpy(card->shortname, chip->pcm->name); |
425 | sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", | 424 | sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", |
426 | pcm->name, | 425 | chip->pcm->name, |
427 | chip->port, | 426 | chip->port, |
428 | irq[dev], | 427 | irq[dev], |
429 | dma1[dev]); | 428 | dma1[dev]); |
430 | if (dma2[dev] >= 0) | 429 | if (dma2[dev] >= 0) |
431 | sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]); | 430 | sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]); |
432 | 431 | ||
433 | err = snd_wss_timer(chip, 0, NULL); | 432 | err = snd_wss_timer(chip, 0); |
434 | if (err < 0) | 433 | if (err < 0) |
435 | return err; | 434 | return err; |
436 | 435 | ||
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c index c5adca300632..add7ffc072c5 100644 --- a/sound/isa/cs423x/cs4236_lib.c +++ b/sound/isa/cs423x/cs4236_lib.c | |||
@@ -376,17 +376,14 @@ int snd_cs4236_create(struct snd_card *card, | |||
376 | return 0; | 376 | return 0; |
377 | } | 377 | } |
378 | 378 | ||
379 | int snd_cs4236_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm) | 379 | int snd_cs4236_pcm(struct snd_wss *chip, int device) |
380 | { | 380 | { |
381 | struct snd_pcm *pcm; | ||
382 | int err; | 381 | int err; |
383 | 382 | ||
384 | err = snd_wss_pcm(chip, device, &pcm); | 383 | err = snd_wss_pcm(chip, device); |
385 | if (err < 0) | 384 | if (err < 0) |
386 | return err; | 385 | return err; |
387 | pcm->info_flags &= ~SNDRV_PCM_INFO_JOINT_DUPLEX; | 386 | chip->pcm->info_flags &= ~SNDRV_PCM_INFO_JOINT_DUPLEX; |
388 | if (rpcm) | ||
389 | *rpcm = pcm; | ||
390 | return 0; | 387 | return 0; |
391 | } | 388 | } |
392 | 389 | ||
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 76001fe0579d..1901c2bb6c3b 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c | |||
@@ -138,10 +138,9 @@ static int snd_es1688_probe(struct snd_card *card, unsigned int n) | |||
138 | { | 138 | { |
139 | struct snd_es1688 *chip = card->private_data; | 139 | struct snd_es1688 *chip = card->private_data; |
140 | struct snd_opl3 *opl3; | 140 | struct snd_opl3 *opl3; |
141 | struct snd_pcm *pcm; | ||
142 | int error; | 141 | int error; |
143 | 142 | ||
144 | error = snd_es1688_pcm(card, chip, 0, &pcm); | 143 | error = snd_es1688_pcm(card, chip, 0); |
145 | if (error < 0) | 144 | if (error < 0) |
146 | return error; | 145 | return error; |
147 | 146 | ||
@@ -150,9 +149,9 @@ static int snd_es1688_probe(struct snd_card *card, unsigned int n) | |||
150 | return error; | 149 | return error; |
151 | 150 | ||
152 | strlcpy(card->driver, "ES1688", sizeof(card->driver)); | 151 | strlcpy(card->driver, "ES1688", sizeof(card->driver)); |
153 | strlcpy(card->shortname, pcm->name, sizeof(card->shortname)); | 152 | strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); |
154 | snprintf(card->longname, sizeof(card->longname), | 153 | snprintf(card->longname, sizeof(card->longname), |
155 | "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, | 154 | "%s at 0x%lx, irq %i, dma %i", chip->pcm->name, chip->port, |
156 | chip->irq, chip->dma8); | 155 | chip->irq, chip->dma8); |
157 | 156 | ||
158 | if (fm_port[n] == SNDRV_AUTO_PORT) | 157 | if (fm_port[n] == SNDRV_AUTO_PORT) |
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index b5450143407b..52aac8467178 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c | |||
@@ -728,8 +728,7 @@ static struct snd_pcm_ops snd_es1688_capture_ops = { | |||
728 | .pointer = snd_es1688_capture_pointer, | 728 | .pointer = snd_es1688_capture_pointer, |
729 | }; | 729 | }; |
730 | 730 | ||
731 | int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, | 731 | int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device) |
732 | int device, struct snd_pcm **rpcm) | ||
733 | { | 732 | { |
734 | struct snd_pcm *pcm; | 733 | struct snd_pcm *pcm; |
735 | int err; | 734 | int err; |
@@ -749,9 +748,6 @@ int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, | |||
749 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 748 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
750 | snd_dma_isa_data(), | 749 | snd_dma_isa_data(), |
751 | 64*1024, 64*1024); | 750 | 64*1024, 64*1024); |
752 | |||
753 | if (rpcm) | ||
754 | *rpcm = pcm; | ||
755 | return 0; | 751 | return 0; |
756 | } | 752 | } |
757 | 753 | ||
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index b481bb8c31bc..6cc2d2bbde6a 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c | |||
@@ -1687,16 +1687,13 @@ static struct snd_pcm_ops snd_es18xx_capture_ops = { | |||
1687 | .pointer = snd_es18xx_capture_pointer, | 1687 | .pointer = snd_es18xx_capture_pointer, |
1688 | }; | 1688 | }; |
1689 | 1689 | ||
1690 | static int snd_es18xx_pcm(struct snd_card *card, int device, | 1690 | static int snd_es18xx_pcm(struct snd_card *card, int device) |
1691 | struct snd_pcm **rpcm) | ||
1692 | { | 1691 | { |
1693 | struct snd_es18xx *chip = card->private_data; | 1692 | struct snd_es18xx *chip = card->private_data; |
1694 | struct snd_pcm *pcm; | 1693 | struct snd_pcm *pcm; |
1695 | char str[16]; | 1694 | char str[16]; |
1696 | int err; | 1695 | int err; |
1697 | 1696 | ||
1698 | if (rpcm) | ||
1699 | *rpcm = NULL; | ||
1700 | sprintf(str, "ES%x", chip->version); | 1697 | sprintf(str, "ES%x", chip->version); |
1701 | if (chip->caps & ES18XX_PCM2) | 1698 | if (chip->caps & ES18XX_PCM2) |
1702 | err = snd_pcm_new(card, str, device, 2, 1, &pcm); | 1699 | err = snd_pcm_new(card, str, device, 2, 1, &pcm); |
@@ -1722,9 +1719,6 @@ static int snd_es18xx_pcm(struct snd_card *card, int device, | |||
1722 | snd_dma_isa_data(), | 1719 | snd_dma_isa_data(), |
1723 | 64*1024, | 1720 | 64*1024, |
1724 | chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); | 1721 | chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); |
1725 | |||
1726 | if (rpcm) | ||
1727 | *rpcm = pcm; | ||
1728 | return 0; | 1722 | return 0; |
1729 | } | 1723 | } |
1730 | 1724 | ||
@@ -2154,7 +2148,7 @@ static int snd_audiodrive_probe(struct snd_card *card, int dev) | |||
2154 | chip->port, | 2148 | chip->port, |
2155 | irq[dev], dma1[dev]); | 2149 | irq[dev], dma1[dev]); |
2156 | 2150 | ||
2157 | err = snd_es18xx_pcm(card, 0, NULL); | 2151 | err = snd_es18xx_pcm(card, 0); |
2158 | if (err < 0) | 2152 | if (err < 0) |
2159 | return err; | 2153 | return err; |
2160 | 2154 | ||
diff --git a/sound/isa/galaxy/galaxy.c b/sound/isa/galaxy/galaxy.c index 1eb2b1ec0fd9..32278847884f 100644 --- a/sound/isa/galaxy/galaxy.c +++ b/sound/isa/galaxy/galaxy.c | |||
@@ -569,7 +569,7 @@ static int snd_galaxy_probe(struct device *dev, unsigned int n) | |||
569 | if (err < 0) | 569 | if (err < 0) |
570 | goto error; | 570 | goto error; |
571 | 571 | ||
572 | err = snd_wss_pcm(chip, 0, NULL); | 572 | err = snd_wss_pcm(chip, 0); |
573 | if (err < 0) | 573 | if (err < 0) |
574 | goto error; | 574 | goto error; |
575 | 575 | ||
@@ -577,7 +577,7 @@ static int snd_galaxy_probe(struct device *dev, unsigned int n) | |||
577 | if (err < 0) | 577 | if (err < 0) |
578 | goto error; | 578 | goto error; |
579 | 579 | ||
580 | err = snd_wss_timer(chip, 0, NULL); | 580 | err = snd_wss_timer(chip, 0); |
581 | if (err < 0) | 581 | if (err < 0) |
582 | goto error; | 582 | goto error; |
583 | 583 | ||
diff --git a/sound/isa/gus/gus_instr.c b/sound/isa/gus/gus_instr.c deleted file mode 100644 index 4dc9caf8ddcf..000000000000 --- a/sound/isa/gus/gus_instr.c +++ /dev/null | |||
@@ -1,172 +0,0 @@ | |||
1 | /* | ||
2 | * Routines for Gravis UltraSound soundcards - Synthesizer | ||
3 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> | ||
4 | * | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/time.h> | ||
23 | #include <sound/core.h> | ||
24 | #include <sound/gus.h> | ||
25 | |||
26 | /* | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | int snd_gus_iwffff_put_sample(void *private_data, struct iwffff_wave *wave, | ||
31 | char __user *data, long len, int atomic) | ||
32 | { | ||
33 | struct snd_gus_card *gus = private_data; | ||
34 | struct snd_gf1_mem_block *block; | ||
35 | int err; | ||
36 | |||
37 | if (wave->format & IWFFFF_WAVE_ROM) | ||
38 | return 0; /* it's probably ok - verify the address? */ | ||
39 | if (wave->format & IWFFFF_WAVE_STEREO) | ||
40 | return -EINVAL; /* not supported */ | ||
41 | block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc, | ||
42 | SNDRV_GF1_MEM_OWNER_WAVE_IWFFFF, | ||
43 | NULL, wave->size, | ||
44 | wave->format & IWFFFF_WAVE_16BIT, 1, | ||
45 | wave->share_id); | ||
46 | if (block == NULL) | ||
47 | return -ENOMEM; | ||
48 | err = snd_gus_dram_write(gus, data, | ||
49 | block->ptr, wave->size); | ||
50 | if (err < 0) { | ||
51 | snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0); | ||
52 | snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block); | ||
53 | snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1); | ||
54 | return err; | ||
55 | } | ||
56 | wave->address.memory = block->ptr; | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | int snd_gus_iwffff_get_sample(void *private_data, struct iwffff_wave *wave, | ||
61 | char __user *data, long len, int atomic) | ||
62 | { | ||
63 | struct snd_gus_card *gus = private_data; | ||
64 | |||
65 | return snd_gus_dram_read(gus, data, wave->address.memory, wave->size, | ||
66 | wave->format & IWFFFF_WAVE_ROM ? 1 : 0); | ||
67 | } | ||
68 | |||
69 | int snd_gus_iwffff_remove_sample(void *private_data, struct iwffff_wave *wave, | ||
70 | int atomic) | ||
71 | { | ||
72 | struct snd_gus_card *gus = private_data; | ||
73 | |||
74 | if (wave->format & IWFFFF_WAVE_ROM) | ||
75 | return 0; /* it's probably ok - verify the address? */ | ||
76 | return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory); | ||
77 | } | ||
78 | |||
79 | /* | ||
80 | * | ||
81 | */ | ||
82 | |||
83 | int snd_gus_gf1_put_sample(void *private_data, struct gf1_wave *wave, | ||
84 | char __user *data, long len, int atomic) | ||
85 | { | ||
86 | struct snd_gus_card *gus = private_data; | ||
87 | struct snd_gf1_mem_block *block; | ||
88 | int err; | ||
89 | |||
90 | if (wave->format & GF1_WAVE_STEREO) | ||
91 | return -EINVAL; /* not supported */ | ||
92 | block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc, | ||
93 | SNDRV_GF1_MEM_OWNER_WAVE_GF1, | ||
94 | NULL, wave->size, | ||
95 | wave->format & GF1_WAVE_16BIT, 1, | ||
96 | wave->share_id); | ||
97 | if (block == NULL) | ||
98 | return -ENOMEM; | ||
99 | err = snd_gus_dram_write(gus, data, | ||
100 | block->ptr, wave->size); | ||
101 | if (err < 0) { | ||
102 | snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0); | ||
103 | snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block); | ||
104 | snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1); | ||
105 | return err; | ||
106 | } | ||
107 | wave->address.memory = block->ptr; | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | int snd_gus_gf1_get_sample(void *private_data, struct gf1_wave *wave, | ||
112 | char __user *data, long len, int atomic) | ||
113 | { | ||
114 | struct snd_gus_card *gus = private_data; | ||
115 | |||
116 | return snd_gus_dram_read(gus, data, wave->address.memory, wave->size, 0); | ||
117 | } | ||
118 | |||
119 | int snd_gus_gf1_remove_sample(void *private_data, struct gf1_wave *wave, | ||
120 | int atomic) | ||
121 | { | ||
122 | struct snd_gus_card *gus = private_data; | ||
123 | |||
124 | return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory); | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * | ||
129 | */ | ||
130 | |||
131 | int snd_gus_simple_put_sample(void *private_data, struct simple_instrument *instr, | ||
132 | char __user *data, long len, int atomic) | ||
133 | { | ||
134 | struct snd_gus_card *gus = private_data; | ||
135 | struct snd_gf1_mem_block *block; | ||
136 | int err; | ||
137 | |||
138 | if (instr->format & SIMPLE_WAVE_STEREO) | ||
139 | return -EINVAL; /* not supported */ | ||
140 | block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc, | ||
141 | SNDRV_GF1_MEM_OWNER_WAVE_SIMPLE, | ||
142 | NULL, instr->size, | ||
143 | instr->format & SIMPLE_WAVE_16BIT, 1, | ||
144 | instr->share_id); | ||
145 | if (block == NULL) | ||
146 | return -ENOMEM; | ||
147 | err = snd_gus_dram_write(gus, data, block->ptr, instr->size); | ||
148 | if (err < 0) { | ||
149 | snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0); | ||
150 | snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block); | ||
151 | snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1); | ||
152 | return err; | ||
153 | } | ||
154 | instr->address.memory = block->ptr; | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | int snd_gus_simple_get_sample(void *private_data, struct simple_instrument *instr, | ||
159 | char __user *data, long len, int atomic) | ||
160 | { | ||
161 | struct snd_gus_card *gus = private_data; | ||
162 | |||
163 | return snd_gus_dram_read(gus, data, instr->address.memory, instr->size, 0); | ||
164 | } | ||
165 | |||
166 | int snd_gus_simple_remove_sample(void *private_data, struct simple_instrument *instr, | ||
167 | int atomic) | ||
168 | { | ||
169 | struct snd_gus_card *gus = private_data; | ||
170 | |||
171 | return snd_gf1_mem_free(&gus->gf1.mem_alloc, instr->address.memory); | ||
172 | } | ||
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index 2dcf45bf7293..25f6788ccef3 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c | |||
@@ -849,7 +849,7 @@ static struct snd_pcm_ops snd_gf1_pcm_capture_ops = { | |||
849 | .pointer = snd_gf1_pcm_capture_pointer, | 849 | .pointer = snd_gf1_pcm_capture_pointer, |
850 | }; | 850 | }; |
851 | 851 | ||
852 | int snd_gf1_pcm_new(struct snd_gus_card * gus, int pcm_dev, int control_index, struct snd_pcm ** rpcm) | 852 | int snd_gf1_pcm_new(struct snd_gus_card *gus, int pcm_dev, int control_index) |
853 | { | 853 | { |
854 | struct snd_card *card; | 854 | struct snd_card *card; |
855 | struct snd_kcontrol *kctl; | 855 | struct snd_kcontrol *kctl; |
@@ -857,8 +857,6 @@ int snd_gf1_pcm_new(struct snd_gus_card * gus, int pcm_dev, int control_index, s | |||
857 | struct snd_pcm_substream *substream; | 857 | struct snd_pcm_substream *substream; |
858 | int capture, err; | 858 | int capture, err; |
859 | 859 | ||
860 | if (rpcm) | ||
861 | *rpcm = NULL; | ||
862 | card = gus->card; | 860 | card = gus->card; |
863 | capture = !gus->interwave && !gus->ess_flag && !gus->ace_flag ? 1 : 0; | 861 | capture = !gus->interwave && !gus->ess_flag && !gus->ace_flag ? 1 : 0; |
864 | err = snd_pcm_new(card, | 862 | err = snd_pcm_new(card, |
@@ -903,8 +901,6 @@ int snd_gf1_pcm_new(struct snd_gus_card * gus, int pcm_dev, int control_index, s | |||
903 | return err; | 901 | return err; |
904 | kctl->id.index = control_index; | 902 | kctl->id.index = control_index; |
905 | 903 | ||
906 | if (rpcm) | ||
907 | *rpcm = pcm; | ||
908 | return 0; | 904 | return 0; |
909 | } | 905 | } |
910 | 906 | ||
diff --git a/sound/isa/gus/gus_uart.c b/sound/isa/gus/gus_uart.c index 21cc42e4c4be..3992912743f5 100644 --- a/sound/isa/gus/gus_uart.c +++ b/sound/isa/gus/gus_uart.c | |||
@@ -241,13 +241,11 @@ static struct snd_rawmidi_ops snd_gf1_uart_input = | |||
241 | .trigger = snd_gf1_uart_input_trigger, | 241 | .trigger = snd_gf1_uart_input_trigger, |
242 | }; | 242 | }; |
243 | 243 | ||
244 | int snd_gf1_rawmidi_new(struct snd_gus_card * gus, int device, struct snd_rawmidi ** rrawmidi) | 244 | int snd_gf1_rawmidi_new(struct snd_gus_card *gus, int device) |
245 | { | 245 | { |
246 | struct snd_rawmidi *rmidi; | 246 | struct snd_rawmidi *rmidi; |
247 | int err; | 247 | int err; |
248 | 248 | ||
249 | if (rrawmidi) | ||
250 | *rrawmidi = NULL; | ||
251 | if ((err = snd_rawmidi_new(gus->card, "GF1", device, 1, 1, &rmidi)) < 0) | 249 | if ((err = snd_rawmidi_new(gus->card, "GF1", device, 1, 1, &rmidi)) < 0) |
252 | return err; | 250 | return err; |
253 | strcpy(rmidi->name, gus->interwave ? "AMD InterWave" : "GF1"); | 251 | strcpy(rmidi->name, gus->interwave ? "AMD InterWave" : "GF1"); |
@@ -256,7 +254,5 @@ int snd_gf1_rawmidi_new(struct snd_gus_card * gus, int device, struct snd_rawmid | |||
256 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; | 254 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; |
257 | rmidi->private_data = gus; | 255 | rmidi->private_data = gus; |
258 | gus->midi_uart = rmidi; | 256 | gus->midi_uart = rmidi; |
259 | if (rrawmidi) | ||
260 | *rrawmidi = rmidi; | ||
261 | return err; | 257 | return err; |
262 | } | 258 | } |
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c index 7ce29ffa1af9..f0019715d82e 100644 --- a/sound/isa/gus/gusclassic.c +++ b/sound/isa/gus/gusclassic.c | |||
@@ -181,12 +181,12 @@ static int snd_gusclassic_probe(struct device *dev, unsigned int n) | |||
181 | if (error < 0) | 181 | if (error < 0) |
182 | goto out; | 182 | goto out; |
183 | 183 | ||
184 | error = snd_gf1_pcm_new(gus, 0, 0, NULL); | 184 | error = snd_gf1_pcm_new(gus, 0, 0); |
185 | if (error < 0) | 185 | if (error < 0) |
186 | goto out; | 186 | goto out; |
187 | 187 | ||
188 | if (!gus->ace_flag) { | 188 | if (!gus->ace_flag) { |
189 | error = snd_gf1_rawmidi_new(gus, 0, NULL); | 189 | error = snd_gf1_rawmidi_new(gus, 0); |
190 | if (error < 0) | 190 | if (error < 0) |
191 | goto out; | 191 | goto out; |
192 | } | 192 | } |
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 28a16936a397..693d95f46804 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c | |||
@@ -284,7 +284,7 @@ static int snd_gusextreme_probe(struct device *dev, unsigned int n) | |||
284 | } | 284 | } |
285 | gus->codec_flag = 1; | 285 | gus->codec_flag = 1; |
286 | 286 | ||
287 | error = snd_es1688_pcm(card, es1688, 0, NULL); | 287 | error = snd_es1688_pcm(card, es1688, 0); |
288 | if (error < 0) | 288 | if (error < 0) |
289 | goto out; | 289 | goto out; |
290 | 290 | ||
@@ -295,7 +295,7 @@ static int snd_gusextreme_probe(struct device *dev, unsigned int n) | |||
295 | snd_component_add(card, "ES1688"); | 295 | snd_component_add(card, "ES1688"); |
296 | 296 | ||
297 | if (pcm_channels[n] > 0) { | 297 | if (pcm_channels[n] > 0) { |
298 | error = snd_gf1_pcm_new(gus, 1, 1, NULL); | 298 | error = snd_gf1_pcm_new(gus, 1, 1); |
299 | if (error < 0) | 299 | if (error < 0) |
300 | goto out; | 300 | goto out; |
301 | } | 301 | } |
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index 39df36ca3acb..8216e8d8f017 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c | |||
@@ -309,7 +309,7 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev) | |||
309 | if (err < 0) | 309 | if (err < 0) |
310 | goto _err; | 310 | goto _err; |
311 | 311 | ||
312 | err = snd_wss_pcm(wss, 0, NULL); | 312 | err = snd_wss_pcm(wss, 0); |
313 | if (err < 0) | 313 | if (err < 0) |
314 | goto _err; | 314 | goto _err; |
315 | 315 | ||
@@ -317,19 +317,19 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev) | |||
317 | if (err < 0) | 317 | if (err < 0) |
318 | goto _err; | 318 | goto _err; |
319 | 319 | ||
320 | err = snd_wss_timer(wss, 2, NULL); | 320 | err = snd_wss_timer(wss, 2); |
321 | if (err < 0) | 321 | if (err < 0) |
322 | goto _err; | 322 | goto _err; |
323 | 323 | ||
324 | if (pcm_channels[dev] > 0) { | 324 | if (pcm_channels[dev] > 0) { |
325 | if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) | 325 | if ((err = snd_gf1_pcm_new(gus, 1, 1)) < 0) |
326 | goto _err; | 326 | goto _err; |
327 | } | 327 | } |
328 | err = snd_gusmax_mixer(wss); | 328 | err = snd_gusmax_mixer(wss); |
329 | if (err < 0) | 329 | if (err < 0) |
330 | goto _err; | 330 | goto _err; |
331 | 331 | ||
332 | err = snd_gf1_rawmidi_new(gus, 0, NULL); | 332 | err = snd_gf1_rawmidi_new(gus, 0); |
333 | if (err < 0) | 333 | if (err < 0) |
334 | goto _err; | 334 | goto _err; |
335 | 335 | ||
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index ad55e5cb8e94..70d0040484c8 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c | |||
@@ -647,7 +647,6 @@ static int snd_interwave_probe(struct snd_card *card, int dev) | |||
647 | #ifdef SNDRV_STB | 647 | #ifdef SNDRV_STB |
648 | struct snd_i2c_bus *i2c_bus; | 648 | struct snd_i2c_bus *i2c_bus; |
649 | #endif | 649 | #endif |
650 | struct snd_pcm *pcm; | ||
651 | char *str; | 650 | char *str; |
652 | int err; | 651 | int err; |
653 | 652 | ||
@@ -695,14 +694,15 @@ static int snd_interwave_probe(struct snd_card *card, int dev) | |||
695 | if (err < 0) | 694 | if (err < 0) |
696 | return err; | 695 | return err; |
697 | 696 | ||
698 | err = snd_wss_pcm(wss, 0, &pcm); | 697 | err = snd_wss_pcm(wss, 0); |
699 | if (err < 0) | 698 | if (err < 0) |
700 | return err; | 699 | return err; |
701 | 700 | ||
702 | sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A'); | 701 | sprintf(wss->pcm->name + strlen(wss->pcm->name), " rev %c", |
703 | strcat(pcm->name, " (codec)"); | 702 | gus->revision + 'A'); |
703 | strcat(wss->pcm->name, " (codec)"); | ||
704 | 704 | ||
705 | err = snd_wss_timer(wss, 2, NULL); | 705 | err = snd_wss_timer(wss, 2); |
706 | if (err < 0) | 706 | if (err < 0) |
707 | return err; | 707 | return err; |
708 | 708 | ||
@@ -711,7 +711,7 @@ static int snd_interwave_probe(struct snd_card *card, int dev) | |||
711 | return err; | 711 | return err; |
712 | 712 | ||
713 | if (pcm_channels[dev] > 0) { | 713 | if (pcm_channels[dev] > 0) { |
714 | err = snd_gf1_pcm_new(gus, 1, 1, NULL); | 714 | err = snd_gf1_pcm_new(gus, 1, 1); |
715 | if (err < 0) | 715 | if (err < 0) |
716 | return err; | 716 | return err; |
717 | } | 717 | } |
@@ -740,7 +740,7 @@ static int snd_interwave_probe(struct snd_card *card, int dev) | |||
740 | #endif | 740 | #endif |
741 | 741 | ||
742 | gus->uart_enable = midi[dev]; | 742 | gus->uart_enable = midi[dev]; |
743 | if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) | 743 | if ((err = snd_gf1_rawmidi_new(gus, 0)) < 0) |
744 | return err; | 744 | return err; |
745 | 745 | ||
746 | #ifndef SNDRV_STB | 746 | #ifndef SNDRV_STB |
diff --git a/sound/isa/msnd/msnd.c b/sound/isa/msnd/msnd.c index 1cee18fb28a8..835d4aa26761 100644 --- a/sound/isa/msnd/msnd.c +++ b/sound/isa/msnd/msnd.c | |||
@@ -679,8 +679,7 @@ static struct snd_pcm_ops snd_msnd_capture_ops = { | |||
679 | }; | 679 | }; |
680 | 680 | ||
681 | 681 | ||
682 | int snd_msnd_pcm(struct snd_card *card, int device, | 682 | int snd_msnd_pcm(struct snd_card *card, int device) |
683 | struct snd_pcm **rpcm) | ||
684 | { | 683 | { |
685 | struct snd_msnd *chip = card->private_data; | 684 | struct snd_msnd *chip = card->private_data; |
686 | struct snd_pcm *pcm; | 685 | struct snd_pcm *pcm; |
@@ -696,9 +695,6 @@ int snd_msnd_pcm(struct snd_card *card, int device, | |||
696 | pcm->private_data = chip; | 695 | pcm->private_data = chip; |
697 | strcpy(pcm->name, "Hurricane"); | 696 | strcpy(pcm->name, "Hurricane"); |
698 | 697 | ||
699 | |||
700 | if (rpcm) | ||
701 | *rpcm = pcm; | ||
702 | return 0; | 698 | return 0; |
703 | } | 699 | } |
704 | EXPORT_SYMBOL(snd_msnd_pcm); | 700 | EXPORT_SYMBOL(snd_msnd_pcm); |
diff --git a/sound/isa/msnd/msnd.h b/sound/isa/msnd/msnd.h index dbac3a42347b..5f3c7dcd9f9d 100644 --- a/sound/isa/msnd/msnd.h +++ b/sound/isa/msnd/msnd.h | |||
@@ -297,7 +297,7 @@ int snd_msnd_disable_irq(struct snd_msnd *chip); | |||
297 | void snd_msnd_dsp_halt(struct snd_msnd *chip, struct file *file); | 297 | void snd_msnd_dsp_halt(struct snd_msnd *chip, struct file *file); |
298 | int snd_msnd_DAPQ(struct snd_msnd *chip, int start); | 298 | int snd_msnd_DAPQ(struct snd_msnd *chip, int start); |
299 | int snd_msnd_DARQ(struct snd_msnd *chip, int start); | 299 | int snd_msnd_DARQ(struct snd_msnd *chip, int start); |
300 | int snd_msnd_pcm(struct snd_card *card, int device, struct snd_pcm **rpcm); | 300 | int snd_msnd_pcm(struct snd_card *card, int device); |
301 | 301 | ||
302 | int snd_msndmidi_new(struct snd_card *card, int device); | 302 | int snd_msndmidi_new(struct snd_card *card, int device); |
303 | void snd_msndmidi_input_read(void *mpu); | 303 | void snd_msndmidi_input_read(void *mpu); |
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c index 5016bf957f51..4c072666115d 100644 --- a/sound/isa/msnd/msnd_pinnacle.c +++ b/sound/isa/msnd/msnd_pinnacle.c | |||
@@ -582,7 +582,7 @@ static int snd_msnd_attach(struct snd_card *card) | |||
582 | if (err < 0) | 582 | if (err < 0) |
583 | goto err_release_region; | 583 | goto err_release_region; |
584 | 584 | ||
585 | err = snd_msnd_pcm(card, 0, NULL); | 585 | err = snd_msnd_pcm(card, 0); |
586 | if (err < 0) { | 586 | if (err < 0) { |
587 | printk(KERN_ERR LOGNAME ": error creating new PCM device\n"); | 587 | printk(KERN_ERR LOGNAME ": error creating new PCM device\n"); |
588 | goto err_release_region; | 588 | goto err_release_region; |
@@ -627,8 +627,7 @@ static int snd_msnd_attach(struct snd_card *card) | |||
627 | return 0; | 627 | return 0; |
628 | 628 | ||
629 | err_release_region: | 629 | err_release_region: |
630 | if (chip->mappedbase) | 630 | iounmap(chip->mappedbase); |
631 | iounmap(chip->mappedbase); | ||
632 | release_mem_region(chip->base, BUFFSIZE); | 631 | release_mem_region(chip->base, BUFFSIZE); |
633 | release_region(chip->io, DSP_NUMIO); | 632 | release_region(chip->io, DSP_NUMIO); |
634 | free_irq(chip->irq, chip); | 633 | free_irq(chip->irq, chip); |
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index a219bc37816b..d7aff527da88 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c | |||
@@ -684,7 +684,7 @@ static int snd_opl3sa2_probe(struct snd_card *card, int dev) | |||
684 | return err; | 684 | return err; |
685 | } | 685 | } |
686 | chip->wss = wss; | 686 | chip->wss = wss; |
687 | err = snd_wss_pcm(wss, 0, NULL); | 687 | err = snd_wss_pcm(wss, 0); |
688 | if (err < 0) | 688 | if (err < 0) |
689 | return err; | 689 | return err; |
690 | err = snd_wss_mixer(wss); | 690 | err = snd_wss_mixer(wss); |
@@ -693,7 +693,7 @@ static int snd_opl3sa2_probe(struct snd_card *card, int dev) | |||
693 | err = snd_opl3sa2_mixer(card); | 693 | err = snd_opl3sa2_mixer(card); |
694 | if (err < 0) | 694 | if (err < 0) |
695 | return err; | 695 | return err; |
696 | err = snd_wss_timer(wss, 0, NULL); | 696 | err = snd_wss_timer(wss, 0); |
697 | if (err < 0) | 697 | if (err < 0) |
698 | return err; | 698 | return err; |
699 | if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) { | 699 | if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) { |
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index c2ca681ac51b..546452888aed 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c | |||
@@ -1270,8 +1270,6 @@ static int snd_miro_probe(struct snd_card *card) | |||
1270 | int error; | 1270 | int error; |
1271 | struct snd_miro *miro = card->private_data; | 1271 | struct snd_miro *miro = card->private_data; |
1272 | struct snd_wss *codec; | 1272 | struct snd_wss *codec; |
1273 | struct snd_timer *timer; | ||
1274 | struct snd_pcm *pcm; | ||
1275 | struct snd_rawmidi *rmidi; | 1273 | struct snd_rawmidi *rmidi; |
1276 | 1274 | ||
1277 | if (!miro->res_mc_base) { | 1275 | if (!miro->res_mc_base) { |
@@ -1310,7 +1308,7 @@ static int snd_miro_probe(struct snd_card *card) | |||
1310 | if (error < 0) | 1308 | if (error < 0) |
1311 | return error; | 1309 | return error; |
1312 | 1310 | ||
1313 | error = snd_wss_pcm(codec, 0, &pcm); | 1311 | error = snd_wss_pcm(codec, 0); |
1314 | if (error < 0) | 1312 | if (error < 0) |
1315 | return error; | 1313 | return error; |
1316 | 1314 | ||
@@ -1318,11 +1316,11 @@ static int snd_miro_probe(struct snd_card *card) | |||
1318 | if (error < 0) | 1316 | if (error < 0) |
1319 | return error; | 1317 | return error; |
1320 | 1318 | ||
1321 | error = snd_wss_timer(codec, 0, &timer); | 1319 | error = snd_wss_timer(codec, 0); |
1322 | if (error < 0) | 1320 | if (error < 0) |
1323 | return error; | 1321 | return error; |
1324 | 1322 | ||
1325 | miro->pcm = pcm; | 1323 | miro->pcm = codec->pcm; |
1326 | 1324 | ||
1327 | error = snd_miro_mixer(card, miro); | 1325 | error = snd_miro_mixer(card, miro); |
1328 | if (error < 0) | 1326 | if (error < 0) |
@@ -1356,8 +1354,8 @@ static int snd_miro_probe(struct snd_card *card) | |||
1356 | 1354 | ||
1357 | strcpy(card->driver, "miro"); | 1355 | strcpy(card->driver, "miro"); |
1358 | sprintf(card->longname, "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d", | 1356 | sprintf(card->longname, "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d", |
1359 | card->shortname, miro->name, pcm->name, miro->wss_base + 4, | 1357 | card->shortname, miro->name, codec->pcm->name, |
1360 | miro->irq, miro->dma1, miro->dma2); | 1358 | miro->wss_base + 4, miro->irq, miro->dma1, miro->dma2); |
1361 | 1359 | ||
1362 | if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) | 1360 | if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) |
1363 | rmidi = NULL; | 1361 | rmidi = NULL; |
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index c9b582848603..840831f1dd4e 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c | |||
@@ -820,10 +820,6 @@ static int snd_opti9xx_probe(struct snd_card *card) | |||
820 | int xdma2; | 820 | int xdma2; |
821 | struct snd_opti9xx *chip = card->private_data; | 821 | struct snd_opti9xx *chip = card->private_data; |
822 | struct snd_wss *codec; | 822 | struct snd_wss *codec; |
823 | #ifdef CS4231 | ||
824 | struct snd_timer *timer; | ||
825 | #endif | ||
826 | struct snd_pcm *pcm; | ||
827 | struct snd_rawmidi *rmidi; | 823 | struct snd_rawmidi *rmidi; |
828 | struct snd_hwdep *synth; | 824 | struct snd_hwdep *synth; |
829 | 825 | ||
@@ -855,7 +851,7 @@ static int snd_opti9xx_probe(struct snd_card *card) | |||
855 | if (error < 0) | 851 | if (error < 0) |
856 | return error; | 852 | return error; |
857 | chip->codec = codec; | 853 | chip->codec = codec; |
858 | error = snd_wss_pcm(codec, 0, &pcm); | 854 | error = snd_wss_pcm(codec, 0); |
859 | if (error < 0) | 855 | if (error < 0) |
860 | return error; | 856 | return error; |
861 | error = snd_wss_mixer(codec); | 857 | error = snd_wss_mixer(codec); |
@@ -867,7 +863,7 @@ static int snd_opti9xx_probe(struct snd_card *card) | |||
867 | return error; | 863 | return error; |
868 | #endif | 864 | #endif |
869 | #ifdef CS4231 | 865 | #ifdef CS4231 |
870 | error = snd_wss_timer(codec, 0, &timer); | 866 | error = snd_wss_timer(codec, 0); |
871 | if (error < 0) | 867 | if (error < 0) |
872 | return error; | 868 | return error; |
873 | #endif | 869 | #endif |
@@ -884,11 +880,12 @@ static int snd_opti9xx_probe(struct snd_card *card) | |||
884 | sprintf(card->shortname, "OPTi %s", card->driver); | 880 | sprintf(card->shortname, "OPTi %s", card->driver); |
885 | #if defined(CS4231) || defined(OPTi93X) | 881 | #if defined(CS4231) || defined(OPTi93X) |
886 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", | 882 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", |
887 | card->shortname, pcm->name, | 883 | card->shortname, codec->pcm->name, |
888 | chip->wss_base + 4, irq, dma1, xdma2); | 884 | chip->wss_base + 4, irq, dma1, xdma2); |
889 | #else | 885 | #else |
890 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", | 886 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", |
891 | card->shortname, pcm->name, chip->wss_base + 4, irq, dma1); | 887 | card->shortname, codec->pcm->name, chip->wss_base + 4, irq, |
888 | dma1); | ||
892 | #endif /* CS4231 || OPTi93X */ | 889 | #endif /* CS4231 || OPTi93X */ |
893 | 890 | ||
894 | if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) | 891 | if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) |
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c index 45fcdff611f9..96e9d94d07e4 100644 --- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c | |||
@@ -378,13 +378,12 @@ init_arrays(struct snd_emu8000 *emu) | |||
378 | static void | 378 | static void |
379 | size_dram(struct snd_emu8000 *emu) | 379 | size_dram(struct snd_emu8000 *emu) |
380 | { | 380 | { |
381 | int i, size, detected_size; | 381 | int i, size; |
382 | 382 | ||
383 | if (emu->dram_checked) | 383 | if (emu->dram_checked) |
384 | return; | 384 | return; |
385 | 385 | ||
386 | size = 0; | 386 | size = 0; |
387 | detected_size = 0; | ||
388 | 387 | ||
389 | /* write out a magic number */ | 388 | /* write out a magic number */ |
390 | snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE); | 389 | snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE); |
@@ -392,10 +391,19 @@ size_dram(struct snd_emu8000 *emu) | |||
392 | EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET); | 391 | EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET); |
393 | EMU8000_SMLD_WRITE(emu, UNIQUE_ID1); | 392 | EMU8000_SMLD_WRITE(emu, UNIQUE_ID1); |
394 | snd_emu8000_init_fm(emu); /* This must really be here and not 2 lines back even */ | 393 | snd_emu8000_init_fm(emu); /* This must really be here and not 2 lines back even */ |
394 | snd_emu8000_write_wait(emu); | ||
395 | 395 | ||
396 | while (size < EMU8000_MAX_DRAM) { | 396 | /* |
397 | * Detect first 512 KiB. If a write succeeds at the beginning of a | ||
398 | * 512 KiB page we assume that the whole page is there. | ||
399 | */ | ||
400 | EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET); | ||
401 | EMU8000_SMLD_READ(emu); /* discard stale data */ | ||
402 | if (EMU8000_SMLD_READ(emu) != UNIQUE_ID1) | ||
403 | goto skip_detect; /* No RAM */ | ||
404 | snd_emu8000_read_wait(emu); | ||
397 | 405 | ||
398 | size += 512 * 1024; /* increment 512kbytes */ | 406 | for (size = 512 * 1024; size < EMU8000_MAX_DRAM; size += 512 * 1024) { |
399 | 407 | ||
400 | /* Write a unique data on the test address. | 408 | /* Write a unique data on the test address. |
401 | * if the address is out of range, the data is written on | 409 | * if the address is out of range, the data is written on |
@@ -431,18 +439,9 @@ size_dram(struct snd_emu8000 *emu) | |||
431 | snd_emu8000_read_wait(emu); | 439 | snd_emu8000_read_wait(emu); |
432 | 440 | ||
433 | /* Otherwise, it's valid memory. */ | 441 | /* Otherwise, it's valid memory. */ |
434 | detected_size = size + 512 * 1024; | ||
435 | } | ||
436 | |||
437 | /* Distinguish 512 KiB from 0. */ | ||
438 | if (detected_size == 0) { | ||
439 | snd_emu8000_read_wait(emu); | ||
440 | EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET); | ||
441 | EMU8000_SMLD_READ(emu); /* discard stale data */ | ||
442 | if (EMU8000_SMLD_READ(emu) == UNIQUE_ID1) | ||
443 | detected_size = 512 * 1024; | ||
444 | } | 442 | } |
445 | 443 | ||
444 | skip_detect: | ||
446 | /* wait until FULL bit in SMAxW register is false */ | 445 | /* wait until FULL bit in SMAxW register is false */ |
447 | for (i = 0; i < 10000; i++) { | 446 | for (i = 0; i < 10000; i++) { |
448 | if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0) | 447 | if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0) |
@@ -454,10 +453,10 @@ size_dram(struct snd_emu8000 *emu) | |||
454 | snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_CLOSE); | 453 | snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_CLOSE); |
455 | snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE); | 454 | snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE); |
456 | 455 | ||
457 | snd_printdd("EMU8000 [0x%lx]: %d Kb on-board memory detected\n", | 456 | pr_info("EMU8000 [0x%lx]: %d KiB on-board DRAM detected\n", |
458 | emu->port1, detected_size/1024); | 457 | emu->port1, size/1024); |
459 | 458 | ||
460 | emu->mem_size = detected_size; | 459 | emu->mem_size = size; |
461 | emu->dram_checked = 1; | 460 | emu->dram_checked = 1; |
462 | } | 461 | } |
463 | 462 | ||
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c index 2f85c66f8e38..250fd0006b53 100644 --- a/sound/isa/sb/emu8000_pcm.c +++ b/sound/isa/sb/emu8000_pcm.c | |||
@@ -207,8 +207,7 @@ static void emu8k_pcm_timer_func(unsigned long data) | |||
207 | rec->last_ptr = ptr; | 207 | rec->last_ptr = ptr; |
208 | 208 | ||
209 | /* reprogram timer */ | 209 | /* reprogram timer */ |
210 | rec->timer.expires = jiffies + 1; | 210 | mod_timer(&rec->timer, jiffies + 1); |
211 | add_timer(&rec->timer); | ||
212 | 211 | ||
213 | /* update period */ | 212 | /* update period */ |
214 | if (rec->period_pos >= (int)rec->period_size) { | 213 | if (rec->period_pos >= (int)rec->period_size) { |
@@ -240,9 +239,7 @@ static int emu8k_pcm_open(struct snd_pcm_substream *subs) | |||
240 | runtime->private_data = rec; | 239 | runtime->private_data = rec; |
241 | 240 | ||
242 | spin_lock_init(&rec->timer_lock); | 241 | spin_lock_init(&rec->timer_lock); |
243 | init_timer(&rec->timer); | 242 | setup_timer(&rec->timer, emu8k_pcm_timer_func, (unsigned long)rec); |
244 | rec->timer.function = emu8k_pcm_timer_func; | ||
245 | rec->timer.data = (unsigned long)rec; | ||
246 | 243 | ||
247 | runtime->hw = emu8k_pcm_hw; | 244 | runtime->hw = emu8k_pcm_hw; |
248 | runtime->hw.buffer_bytes_max = emu->mem_size - LOOP_BLANK_SIZE * 3; | 245 | runtime->hw.buffer_bytes_max = emu->mem_size - LOOP_BLANK_SIZE * 3; |
@@ -359,8 +356,7 @@ static void start_voice(struct snd_emu8k_pcm *rec, int ch) | |||
359 | /* start timer */ | 356 | /* start timer */ |
360 | spin_lock_irqsave(&rec->timer_lock, flags); | 357 | spin_lock_irqsave(&rec->timer_lock, flags); |
361 | if (! rec->timer_running) { | 358 | if (! rec->timer_running) { |
362 | rec->timer.expires = jiffies + 1; | 359 | mod_timer(&rec->timer, jiffies + 1); |
363 | add_timer(&rec->timer); | ||
364 | rec->timer_running = 1; | 360 | rec->timer_running = 1; |
365 | } | 361 | } |
366 | spin_unlock_irqrestore(&rec->timer_lock, flags); | 362 | spin_unlock_irqrestore(&rec->timer_lock, flags); |
diff --git a/sound/isa/sb/emu8000_synth.c b/sound/isa/sb/emu8000_synth.c index 95b39beb61c1..72332dfada9a 100644 --- a/sound/isa/sb/emu8000_synth.c +++ b/sound/isa/sb/emu8000_synth.c | |||
@@ -103,8 +103,7 @@ static int snd_emu8000_delete_device(struct snd_seq_device *dev) | |||
103 | hw = dev->driver_data; | 103 | hw = dev->driver_data; |
104 | if (hw->pcm) | 104 | if (hw->pcm) |
105 | snd_device_free(dev->card, hw->pcm); | 105 | snd_device_free(dev->card, hw->pcm); |
106 | if (hw->emu) | 106 | snd_emux_free(hw->emu); |
107 | snd_emux_free(hw->emu); | ||
108 | snd_util_memhdr_free(hw->memhdr); | 107 | snd_util_memhdr_free(hw->memhdr); |
109 | hw->emu = NULL; | 108 | hw->emu = NULL; |
110 | hw->memhdr = NULL; | 109 | hw->memhdr = NULL; |
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c index 90d2eba549e9..6b4884d052a5 100644 --- a/sound/isa/sb/jazz16.c +++ b/sound/isa/sb/jazz16.c | |||
@@ -297,7 +297,7 @@ static int snd_jazz16_probe(struct device *devptr, unsigned int dev) | |||
297 | "Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d", | 297 | "Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d", |
298 | port[dev], xirq, xdma8, xdma16); | 298 | port[dev], xirq, xdma8, xdma16); |
299 | 299 | ||
300 | err = snd_sb8dsp_pcm(chip, 0, NULL); | 300 | err = snd_sb8dsp_pcm(chip, 0); |
301 | if (err < 0) | 301 | if (err < 0) |
302 | goto err_free; | 302 | goto err_free; |
303 | err = snd_sbmixer_new(chip); | 303 | err = snd_sbmixer_new(chip); |
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 3f694543a7ea..4a7d7c89808f 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c | |||
@@ -374,7 +374,7 @@ static int snd_sb16_probe(struct snd_card *card, int dev) | |||
374 | if (! is_isapnp_selected(dev) && (err = snd_sb16dsp_configure(chip)) < 0) | 374 | if (! is_isapnp_selected(dev) && (err = snd_sb16dsp_configure(chip)) < 0) |
375 | return err; | 375 | return err; |
376 | 376 | ||
377 | if ((err = snd_sb16dsp_pcm(chip, 0, &chip->pcm)) < 0) | 377 | if ((err = snd_sb16dsp_pcm(chip, 0)) < 0) |
378 | return err; | 378 | return err; |
379 | 379 | ||
380 | strcpy(card->driver, | 380 | strcpy(card->driver, |
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index 72b10f4f3e70..63d11b7b9fe8 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c | |||
@@ -860,19 +860,18 @@ static struct snd_pcm_ops snd_sb16_capture_ops = { | |||
860 | .pointer = snd_sb16_capture_pointer, | 860 | .pointer = snd_sb16_capture_pointer, |
861 | }; | 861 | }; |
862 | 862 | ||
863 | int snd_sb16dsp_pcm(struct snd_sb * chip, int device, struct snd_pcm ** rpcm) | 863 | int snd_sb16dsp_pcm(struct snd_sb *chip, int device) |
864 | { | 864 | { |
865 | struct snd_card *card = chip->card; | 865 | struct snd_card *card = chip->card; |
866 | struct snd_pcm *pcm; | 866 | struct snd_pcm *pcm; |
867 | int err; | 867 | int err; |
868 | 868 | ||
869 | if (rpcm) | ||
870 | *rpcm = NULL; | ||
871 | if ((err = snd_pcm_new(card, "SB16 DSP", device, 1, 1, &pcm)) < 0) | 869 | if ((err = snd_pcm_new(card, "SB16 DSP", device, 1, 1, &pcm)) < 0) |
872 | return err; | 870 | return err; |
873 | sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff); | 871 | sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff); |
874 | pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; | 872 | pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; |
875 | pcm->private_data = chip; | 873 | pcm->private_data = chip; |
874 | chip->pcm = pcm; | ||
876 | 875 | ||
877 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb16_playback_ops); | 876 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb16_playback_ops); |
878 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb16_capture_ops); | 877 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb16_capture_ops); |
@@ -885,9 +884,6 @@ int snd_sb16dsp_pcm(struct snd_sb * chip, int device, struct snd_pcm ** rpcm) | |||
885 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 884 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
886 | snd_dma_isa_data(), | 885 | snd_dma_isa_data(), |
887 | 64*1024, 128*1024); | 886 | 64*1024, 128*1024); |
888 | |||
889 | if (rpcm) | ||
890 | *rpcm = pcm; | ||
891 | return 0; | 887 | return 0; |
892 | } | 888 | } |
893 | 889 | ||
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index 6c32b3aa34af..b8e2391c33ff 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c | |||
@@ -157,7 +157,7 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev) | |||
157 | goto _err; | 157 | goto _err; |
158 | } | 158 | } |
159 | 159 | ||
160 | if ((err = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) | 160 | if ((err = snd_sb8dsp_pcm(chip, 0)) < 0) |
161 | goto _err; | 161 | goto _err; |
162 | 162 | ||
163 | if ((err = snd_sbmixer_new(chip)) < 0) | 163 | if ((err = snd_sbmixer_new(chip)) < 0) |
@@ -182,7 +182,7 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev) | |||
182 | goto _err; | 182 | goto _err; |
183 | } | 183 | } |
184 | 184 | ||
185 | if ((err = snd_sb8dsp_midi(chip, 0, NULL)) < 0) | 185 | if ((err = snd_sb8dsp_midi(chip, 0)) < 0) |
186 | goto _err; | 186 | goto _err; |
187 | 187 | ||
188 | strcpy(card->driver, chip->hardware == SB_HW_PRO ? "SB Pro" : "SB8"); | 188 | strcpy(card->driver, chip->hardware == SB_HW_PRO ? "SB Pro" : "SB8"); |
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index 24d4121ab0e0..d4d8b0e604ee 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c | |||
@@ -594,15 +594,13 @@ static struct snd_pcm_ops snd_sb8_capture_ops = { | |||
594 | .pointer = snd_sb8_capture_pointer, | 594 | .pointer = snd_sb8_capture_pointer, |
595 | }; | 595 | }; |
596 | 596 | ||
597 | int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm) | 597 | int snd_sb8dsp_pcm(struct snd_sb *chip, int device) |
598 | { | 598 | { |
599 | struct snd_card *card = chip->card; | 599 | struct snd_card *card = chip->card; |
600 | struct snd_pcm *pcm; | 600 | struct snd_pcm *pcm; |
601 | int err; | 601 | int err; |
602 | size_t max_prealloc = 64 * 1024; | 602 | size_t max_prealloc = 64 * 1024; |
603 | 603 | ||
604 | if (rpcm) | ||
605 | *rpcm = NULL; | ||
606 | if ((err = snd_pcm_new(card, "SB8 DSP", device, 1, 1, &pcm)) < 0) | 604 | if ((err = snd_pcm_new(card, "SB8 DSP", device, 1, 1, &pcm)) < 0) |
607 | return err; | 605 | return err; |
608 | sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff); | 606 | sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff); |
@@ -618,8 +616,6 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm) | |||
618 | snd_dma_isa_data(), | 616 | snd_dma_isa_data(), |
619 | 64*1024, max_prealloc); | 617 | 64*1024, max_prealloc); |
620 | 618 | ||
621 | if (rpcm) | ||
622 | *rpcm = pcm; | ||
623 | return 0; | 619 | return 0; |
624 | } | 620 | } |
625 | 621 | ||
diff --git a/sound/isa/sb/sb8_midi.c b/sound/isa/sb/sb8_midi.c index 988a8b73475f..925ea45b3d97 100644 --- a/sound/isa/sb/sb8_midi.c +++ b/sound/isa/sb/sb8_midi.c | |||
@@ -216,8 +216,7 @@ static void snd_sb8dsp_midi_output_timer(unsigned long data) | |||
216 | unsigned long flags; | 216 | unsigned long flags; |
217 | 217 | ||
218 | spin_lock_irqsave(&chip->open_lock, flags); | 218 | spin_lock_irqsave(&chip->open_lock, flags); |
219 | chip->midi_timer.expires = 1 + jiffies; | 219 | mod_timer(&chip->midi_timer, 1 + jiffies); |
220 | add_timer(&chip->midi_timer); | ||
221 | spin_unlock_irqrestore(&chip->open_lock, flags); | 220 | spin_unlock_irqrestore(&chip->open_lock, flags); |
222 | snd_sb8dsp_midi_output_write(substream); | 221 | snd_sb8dsp_midi_output_write(substream); |
223 | } | 222 | } |
@@ -231,11 +230,10 @@ static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substre | |||
231 | spin_lock_irqsave(&chip->open_lock, flags); | 230 | spin_lock_irqsave(&chip->open_lock, flags); |
232 | if (up) { | 231 | if (up) { |
233 | if (!(chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER)) { | 232 | if (!(chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER)) { |
234 | init_timer(&chip->midi_timer); | 233 | setup_timer(&chip->midi_timer, |
235 | chip->midi_timer.function = snd_sb8dsp_midi_output_timer; | 234 | snd_sb8dsp_midi_output_timer, |
236 | chip->midi_timer.data = (unsigned long) substream; | 235 | (unsigned long) substream); |
237 | chip->midi_timer.expires = 1 + jiffies; | 236 | mod_timer(&chip->midi_timer, 1 + jiffies); |
238 | add_timer(&chip->midi_timer); | ||
239 | chip->open |= SB_OPEN_MIDI_OUTPUT_TRIGGER; | 237 | chip->open |= SB_OPEN_MIDI_OUTPUT_TRIGGER; |
240 | } | 238 | } |
241 | } else { | 239 | } else { |
@@ -263,13 +261,11 @@ static struct snd_rawmidi_ops snd_sb8dsp_midi_input = | |||
263 | .trigger = snd_sb8dsp_midi_input_trigger, | 261 | .trigger = snd_sb8dsp_midi_input_trigger, |
264 | }; | 262 | }; |
265 | 263 | ||
266 | int snd_sb8dsp_midi(struct snd_sb *chip, int device, struct snd_rawmidi ** rrawmidi) | 264 | int snd_sb8dsp_midi(struct snd_sb *chip, int device) |
267 | { | 265 | { |
268 | struct snd_rawmidi *rmidi; | 266 | struct snd_rawmidi *rmidi; |
269 | int err; | 267 | int err; |
270 | 268 | ||
271 | if (rrawmidi) | ||
272 | *rrawmidi = NULL; | ||
273 | if ((err = snd_rawmidi_new(chip->card, "SB8 MIDI", device, 1, 1, &rmidi)) < 0) | 269 | if ((err = snd_rawmidi_new(chip->card, "SB8 MIDI", device, 1, 1, &rmidi)) < 0) |
274 | return err; | 270 | return err; |
275 | strcpy(rmidi->name, "SB8 MIDI"); | 271 | strcpy(rmidi->name, "SB8 MIDI"); |
@@ -280,7 +276,5 @@ int snd_sb8dsp_midi(struct snd_sb *chip, int device, struct snd_rawmidi ** rrawm | |||
280 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; | 276 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; |
281 | rmidi->private_data = chip; | 277 | rmidi->private_data = chip; |
282 | chip->rmidi = rmidi; | 278 | chip->rmidi = rmidi; |
283 | if (rrawmidi) | ||
284 | *rrawmidi = rmidi; | ||
285 | return 0; | 279 | return 0; |
286 | } | 280 | } |
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index 15a152eaa2e8..51cfa7615f72 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c | |||
@@ -625,7 +625,7 @@ static int snd_sc6000_probe(struct device *devptr, unsigned int dev) | |||
625 | if (err < 0) | 625 | if (err < 0) |
626 | goto err_unmap2; | 626 | goto err_unmap2; |
627 | 627 | ||
628 | err = snd_wss_pcm(chip, 0, NULL); | 628 | err = snd_wss_pcm(chip, 0); |
629 | if (err < 0) { | 629 | if (err < 0) { |
630 | snd_printk(KERN_ERR PFX | 630 | snd_printk(KERN_ERR PFX |
631 | "error creating new WSS PCM device\n"); | 631 | "error creating new WSS PCM device\n"); |
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 44405df7d4be..018ab140c2be 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c | |||
@@ -877,7 +877,6 @@ static int create_ad1845(struct snd_card *card, unsigned port, | |||
877 | codec_type, WSS_HWSHARE_DMA1, &chip); | 877 | codec_type, WSS_HWSHARE_DMA1, &chip); |
878 | if (!err) { | 878 | if (!err) { |
879 | unsigned long flags; | 879 | unsigned long flags; |
880 | struct snd_pcm *pcm; | ||
881 | 880 | ||
882 | if (sscape->type != SSCAPE_VIVO) { | 881 | if (sscape->type != SSCAPE_VIVO) { |
883 | /* | 882 | /* |
@@ -893,7 +892,7 @@ static int create_ad1845(struct snd_card *card, unsigned port, | |||
893 | 892 | ||
894 | } | 893 | } |
895 | 894 | ||
896 | err = snd_wss_pcm(chip, 0, &pcm); | 895 | err = snd_wss_pcm(chip, 0); |
897 | if (err < 0) { | 896 | if (err < 0) { |
898 | snd_printk(KERN_ERR "sscape: No PCM device " | 897 | snd_printk(KERN_ERR "sscape: No PCM device " |
899 | "for AD1845 chip\n"); | 898 | "for AD1845 chip\n"); |
@@ -907,7 +906,7 @@ static int create_ad1845(struct snd_card *card, unsigned port, | |||
907 | goto _error; | 906 | goto _error; |
908 | } | 907 | } |
909 | if (chip->hardware != WSS_HW_AD1848) { | 908 | if (chip->hardware != WSS_HW_AD1848) { |
910 | err = snd_wss_timer(chip, 0, NULL); | 909 | err = snd_wss_timer(chip, 0); |
911 | if (err < 0) { | 910 | if (err < 0) { |
912 | snd_printk(KERN_ERR "sscape: No timer device " | 911 | snd_printk(KERN_ERR "sscape: No timer device " |
913 | "for AD1845 chip\n"); | 912 | "for AD1845 chip\n"); |
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index bfbf38cf9841..a0987a57c8a9 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c | |||
@@ -380,11 +380,11 @@ snd_wavefront_probe (struct snd_card *card, int dev) | |||
380 | return err; | 380 | return err; |
381 | } | 381 | } |
382 | 382 | ||
383 | err = snd_wss_pcm(chip, 0, NULL); | 383 | err = snd_wss_pcm(chip, 0); |
384 | if (err < 0) | 384 | if (err < 0) |
385 | return err; | 385 | return err; |
386 | 386 | ||
387 | err = snd_wss_timer(chip, 0, NULL); | 387 | err = snd_wss_timer(chip, 0); |
388 | if (err < 0) | 388 | if (err < 0) |
389 | return err; | 389 | return err; |
390 | 390 | ||
diff --git a/sound/isa/wavefront/wavefront_midi.c b/sound/isa/wavefront/wavefront_midi.c index 7dc991682297..b8009cbcd34e 100644 --- a/sound/isa/wavefront/wavefront_midi.c +++ b/sound/isa/wavefront/wavefront_midi.c | |||
@@ -356,8 +356,7 @@ static void snd_wavefront_midi_output_timer(unsigned long data) | |||
356 | unsigned long flags; | 356 | unsigned long flags; |
357 | 357 | ||
358 | spin_lock_irqsave (&midi->virtual, flags); | 358 | spin_lock_irqsave (&midi->virtual, flags); |
359 | midi->timer.expires = 1 + jiffies; | 359 | mod_timer(&midi->timer, 1 + jiffies); |
360 | add_timer(&midi->timer); | ||
361 | spin_unlock_irqrestore (&midi->virtual, flags); | 360 | spin_unlock_irqrestore (&midi->virtual, flags); |
362 | snd_wavefront_midi_output_write(card); | 361 | snd_wavefront_midi_output_write(card); |
363 | } | 362 | } |
@@ -384,11 +383,10 @@ static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *subs | |||
384 | if (up) { | 383 | if (up) { |
385 | if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) { | 384 | if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) { |
386 | if (!midi->istimer) { | 385 | if (!midi->istimer) { |
387 | init_timer(&midi->timer); | 386 | setup_timer(&midi->timer, |
388 | midi->timer.function = snd_wavefront_midi_output_timer; | 387 | snd_wavefront_midi_output_timer, |
389 | midi->timer.data = (unsigned long) substream->rmidi->card->private_data; | 388 | (unsigned long) substream->rmidi->card->private_data); |
390 | midi->timer.expires = 1 + jiffies; | 389 | mod_timer(&midi->timer, 1 + jiffies); |
391 | add_timer(&midi->timer); | ||
392 | } | 390 | } |
393 | midi->istimer++; | 391 | midi->istimer++; |
394 | midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER; | 392 | midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER; |
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 347bb1bda110..6530d32901b9 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c | |||
@@ -1923,7 +1923,7 @@ static struct snd_pcm_ops snd_wss_capture_ops = { | |||
1923 | .pointer = snd_wss_capture_pointer, | 1923 | .pointer = snd_wss_capture_pointer, |
1924 | }; | 1924 | }; |
1925 | 1925 | ||
1926 | int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm) | 1926 | int snd_wss_pcm(struct snd_wss *chip, int device) |
1927 | { | 1927 | { |
1928 | struct snd_pcm *pcm; | 1928 | struct snd_pcm *pcm; |
1929 | int err; | 1929 | int err; |
@@ -1949,8 +1949,6 @@ int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm) | |||
1949 | 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); | 1949 | 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); |
1950 | 1950 | ||
1951 | chip->pcm = pcm; | 1951 | chip->pcm = pcm; |
1952 | if (rpcm) | ||
1953 | *rpcm = pcm; | ||
1954 | return 0; | 1952 | return 0; |
1955 | } | 1953 | } |
1956 | EXPORT_SYMBOL(snd_wss_pcm); | 1954 | EXPORT_SYMBOL(snd_wss_pcm); |
@@ -1961,7 +1959,7 @@ static void snd_wss_timer_free(struct snd_timer *timer) | |||
1961 | chip->timer = NULL; | 1959 | chip->timer = NULL; |
1962 | } | 1960 | } |
1963 | 1961 | ||
1964 | int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer) | 1962 | int snd_wss_timer(struct snd_wss *chip, int device) |
1965 | { | 1963 | { |
1966 | struct snd_timer *timer; | 1964 | struct snd_timer *timer; |
1967 | struct snd_timer_id tid; | 1965 | struct snd_timer_id tid; |
@@ -1980,8 +1978,6 @@ int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer) | |||
1980 | timer->private_free = snd_wss_timer_free; | 1978 | timer->private_free = snd_wss_timer_free; |
1981 | timer->hw = snd_wss_timer_table; | 1979 | timer->hw = snd_wss_timer_table; |
1982 | chip->timer = timer; | 1980 | chip->timer = timer; |
1983 | if (rtimer) | ||
1984 | *rtimer = timer; | ||
1985 | return 0; | 1981 | return 0; |
1986 | } | 1982 | } |
1987 | EXPORT_SYMBOL(snd_wss_timer); | 1983 | EXPORT_SYMBOL(snd_wss_timer); |
diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c index c23f9f95bfa5..a8ceef8d1a8d 100644 --- a/sound/oss/msnd_pinnacle.c +++ b/sound/oss/msnd_pinnacle.c | |||
@@ -675,7 +675,7 @@ static void dsp_write_flush(void) | |||
675 | timeout); | 675 | timeout); |
676 | clear_bit(F_WRITEFLUSH, &dev.flags); | 676 | clear_bit(F_WRITEFLUSH, &dev.flags); |
677 | if (!signal_pending(current)) { | 677 | if (!signal_pending(current)) { |
678 | current->state = TASK_INTERRUPTIBLE; | 678 | __set_current_state(TASK_INTERRUPTIBLE); |
679 | schedule_timeout(get_play_delay_jiffies(DAP_BUFF_SIZE)); | 679 | schedule_timeout(get_play_delay_jiffies(DAP_BUFF_SIZE)); |
680 | } | 680 | } |
681 | clear_bit(F_WRITING, &dev.flags); | 681 | clear_bit(F_WRITING, &dev.flags); |
@@ -1288,7 +1288,7 @@ static int __init calibrate_adc(WORD srate) | |||
1288 | & ~0x0001, dev.SMA + SMA_wCurrHostStatusFlags); | 1288 | & ~0x0001, dev.SMA + SMA_wCurrHostStatusFlags); |
1289 | if (msnd_send_word(&dev, 0, 0, HDEXAR_CAL_A_TO_D) == 0 && | 1289 | if (msnd_send_word(&dev, 0, 0, HDEXAR_CAL_A_TO_D) == 0 && |
1290 | chk_send_dsp_cmd(&dev, HDEX_AUX_REQ) == 0) { | 1290 | chk_send_dsp_cmd(&dev, HDEX_AUX_REQ) == 0) { |
1291 | current->state = TASK_INTERRUPTIBLE; | 1291 | __set_current_state(TASK_INTERRUPTIBLE); |
1292 | schedule_timeout(HZ / 3); | 1292 | schedule_timeout(HZ / 3); |
1293 | return 0; | 1293 | return 0; |
1294 | } | 1294 | } |
diff --git a/sound/oss/pss.c b/sound/oss/pss.c index ca0d6e9f49f5..81314f9e2ccb 100644 --- a/sound/oss/pss.c +++ b/sound/oss/pss.c | |||
@@ -1228,7 +1228,7 @@ static void __exit cleanup_pss(void) | |||
1228 | { | 1228 | { |
1229 | if(!pss_no_sound) | 1229 | if(!pss_no_sound) |
1230 | { | 1230 | { |
1231 | if(fw_load && pss_synth) | 1231 | if (fw_load) |
1232 | vfree(pss_synth); | 1232 | vfree(pss_synth); |
1233 | if(pssmss) | 1233 | if(pssmss) |
1234 | unload_pss_mss(&cfg2); | 1234 | unload_pss_mss(&cfg2); |
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c index a33e8ce8085b..213a416b6e0b 100644 --- a/sound/oss/swarm_cs4297a.c +++ b/sound/oss/swarm_cs4297a.c | |||
@@ -1654,7 +1654,7 @@ static int drain_dac(struct cs4297a_state *s, int nonblock) | |||
1654 | s->dma_dac.hwptr = s->dma_dac.swptr = hwptr; | 1654 | s->dma_dac.hwptr = s->dma_dac.swptr = hwptr; |
1655 | spin_unlock_irqrestore(&s->lock, flags); | 1655 | spin_unlock_irqrestore(&s->lock, flags); |
1656 | remove_wait_queue(&s->dma_dac.wait, &wait); | 1656 | remove_wait_queue(&s->dma_dac.wait, &wait); |
1657 | current->state = TASK_RUNNING; | 1657 | __set_current_state(TASK_RUNNING); |
1658 | return 0; | 1658 | return 0; |
1659 | } | 1659 | } |
1660 | 1660 | ||
diff --git a/sound/oss/trix.c b/sound/oss/trix.c index 944e0c015485..3c494dc93b93 100644 --- a/sound/oss/trix.c +++ b/sound/oss/trix.c | |||
@@ -487,7 +487,7 @@ static int __init init_trix(void) | |||
487 | 487 | ||
488 | static void __exit cleanup_trix(void) | 488 | static void __exit cleanup_trix(void) |
489 | { | 489 | { |
490 | if (fw_load && trix_boot) | 490 | if (fw_load) |
491 | vfree(trix_boot); | 491 | vfree(trix_boot); |
492 | if (sb) | 492 | if (sb) |
493 | unload_trix_sb(&cfg2); | 493 | unload_trix_sb(&cfg2); |
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index 29604a239c44..f2350c1d6ee8 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c | |||
@@ -893,9 +893,7 @@ snd_harmony_free(struct snd_harmony *h) | |||
893 | if (h->irq >= 0) | 893 | if (h->irq >= 0) |
894 | free_irq(h->irq, h); | 894 | free_irq(h->irq, h); |
895 | 895 | ||
896 | if (h->iobase) | 896 | iounmap(h->iobase); |
897 | iounmap(h->iobase); | ||
898 | |||
899 | kfree(h); | 897 | kfree(h); |
900 | return 0; | 898 | return 0; |
901 | } | 899 | } |
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 50dd0086cfb1..edfc1b8d553e 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -793,6 +793,15 @@ config SND_RME9652 | |||
793 | To compile this driver as a module, choose M here: the module | 793 | To compile this driver as a module, choose M here: the module |
794 | will be called snd-rme9652. | 794 | will be called snd-rme9652. |
795 | 795 | ||
796 | config SND_SE6X | ||
797 | tristate "Studio Evolution SE6X" | ||
798 | depends on SND_OXYGEN=n && SND_VIRTUOSO=n # PCI ID conflict | ||
799 | select SND_OXYGEN_LIB | ||
800 | select SND_PCM | ||
801 | select SND_MPU401_UART | ||
802 | help | ||
803 | Say Y or M here only if you actually have this sound card. | ||
804 | |||
796 | config SND_SIS7019 | 805 | config SND_SIS7019 |
797 | tristate "SiS 7019 Audio Accelerator" | 806 | tristate "SiS 7019 Audio Accelerator" |
798 | depends on X86_32 | 807 | depends on X86_32 |
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index 1610c38337af..0de31290411c 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c | |||
@@ -623,14 +623,11 @@ snd_ad1889_interrupt(int irq, void *dev_id) | |||
623 | } | 623 | } |
624 | 624 | ||
625 | static int | 625 | static int |
626 | snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, struct snd_pcm **rpcm) | 626 | snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device) |
627 | { | 627 | { |
628 | int err; | 628 | int err; |
629 | struct snd_pcm *pcm; | 629 | struct snd_pcm *pcm; |
630 | 630 | ||
631 | if (rpcm) | ||
632 | *rpcm = NULL; | ||
633 | |||
634 | err = snd_pcm_new(chip->card, chip->card->driver, device, 1, 1, &pcm); | 631 | err = snd_pcm_new(chip->card, chip->card->driver, device, 1, 1, &pcm); |
635 | if (err < 0) | 632 | if (err < 0) |
636 | return err; | 633 | return err; |
@@ -658,9 +655,6 @@ snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, struct snd_pcm **rpcm) | |||
658 | return err; | 655 | return err; |
659 | } | 656 | } |
660 | 657 | ||
661 | if (rpcm) | ||
662 | *rpcm = pcm; | ||
663 | |||
664 | return 0; | 658 | return 0; |
665 | } | 659 | } |
666 | 660 | ||
@@ -859,12 +853,9 @@ snd_ad1889_free(struct snd_ad1889 *chip) | |||
859 | free_irq(chip->irq, chip); | 853 | free_irq(chip->irq, chip); |
860 | 854 | ||
861 | skip_hw: | 855 | skip_hw: |
862 | if (chip->iobase) | 856 | iounmap(chip->iobase); |
863 | iounmap(chip->iobase); | ||
864 | |||
865 | pci_release_regions(chip->pci); | 857 | pci_release_regions(chip->pci); |
866 | pci_disable_device(chip->pci); | 858 | pci_disable_device(chip->pci); |
867 | |||
868 | kfree(chip); | 859 | kfree(chip); |
869 | return 0; | 860 | return 0; |
870 | } | 861 | } |
@@ -1016,7 +1007,7 @@ snd_ad1889_probe(struct pci_dev *pci, | |||
1016 | if (err < 0) | 1007 | if (err < 0) |
1017 | goto free_and_ret; | 1008 | goto free_and_ret; |
1018 | 1009 | ||
1019 | err = snd_ad1889_pcm_init(chip, 0, NULL); | 1010 | err = snd_ad1889_pcm_init(chip, 0); |
1020 | if (err < 0) | 1011 | if (err < 0) |
1021 | goto free_and_ret; | 1012 | goto free_and_ret; |
1022 | 1013 | ||
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index af89e42b2160..4cd2210fd95c 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
@@ -1873,7 +1873,6 @@ static int snd_ali_mixer(struct snd_ali *codec) | |||
1873 | #ifdef CONFIG_PM_SLEEP | 1873 | #ifdef CONFIG_PM_SLEEP |
1874 | static int ali_suspend(struct device *dev) | 1874 | static int ali_suspend(struct device *dev) |
1875 | { | 1875 | { |
1876 | struct pci_dev *pci = to_pci_dev(dev); | ||
1877 | struct snd_card *card = dev_get_drvdata(dev); | 1876 | struct snd_card *card = dev_get_drvdata(dev); |
1878 | struct snd_ali *chip = card->private_data; | 1877 | struct snd_ali *chip = card->private_data; |
1879 | struct snd_ali_image *im; | 1878 | struct snd_ali_image *im; |
@@ -1914,16 +1913,11 @@ static int ali_suspend(struct device *dev) | |||
1914 | outl(0xffffffff, ALI_REG(chip, ALI_STOP)); | 1913 | outl(0xffffffff, ALI_REG(chip, ALI_STOP)); |
1915 | 1914 | ||
1916 | spin_unlock_irq(&chip->reg_lock); | 1915 | spin_unlock_irq(&chip->reg_lock); |
1917 | |||
1918 | pci_disable_device(pci); | ||
1919 | pci_save_state(pci); | ||
1920 | pci_set_power_state(pci, PCI_D3hot); | ||
1921 | return 0; | 1916 | return 0; |
1922 | } | 1917 | } |
1923 | 1918 | ||
1924 | static int ali_resume(struct device *dev) | 1919 | static int ali_resume(struct device *dev) |
1925 | { | 1920 | { |
1926 | struct pci_dev *pci = to_pci_dev(dev); | ||
1927 | struct snd_card *card = dev_get_drvdata(dev); | 1921 | struct snd_card *card = dev_get_drvdata(dev); |
1928 | struct snd_ali *chip = card->private_data; | 1922 | struct snd_ali *chip = card->private_data; |
1929 | struct snd_ali_image *im; | 1923 | struct snd_ali_image *im; |
@@ -1933,15 +1927,6 @@ static int ali_resume(struct device *dev) | |||
1933 | if (!im) | 1927 | if (!im) |
1934 | return 0; | 1928 | return 0; |
1935 | 1929 | ||
1936 | pci_set_power_state(pci, PCI_D0); | ||
1937 | pci_restore_state(pci); | ||
1938 | if (pci_enable_device(pci) < 0) { | ||
1939 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
1940 | snd_card_disconnect(card); | ||
1941 | return -EIO; | ||
1942 | } | ||
1943 | pci_set_master(pci); | ||
1944 | |||
1945 | spin_lock_irq(&chip->reg_lock); | 1930 | spin_lock_irq(&chip->reg_lock); |
1946 | 1931 | ||
1947 | for (i = 0; i < ALI_CHANNELS; i++) { | 1932 | for (i = 0; i < ALI_CHANNELS; i++) { |
diff --git a/sound/pci/als300.c b/sound/pci/als300.c index 7bb6ac565107..bd01113de39a 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c | |||
@@ -728,35 +728,20 @@ static int snd_als300_create(struct snd_card *card, | |||
728 | #ifdef CONFIG_PM_SLEEP | 728 | #ifdef CONFIG_PM_SLEEP |
729 | static int snd_als300_suspend(struct device *dev) | 729 | static int snd_als300_suspend(struct device *dev) |
730 | { | 730 | { |
731 | struct pci_dev *pci = to_pci_dev(dev); | ||
732 | struct snd_card *card = dev_get_drvdata(dev); | 731 | struct snd_card *card = dev_get_drvdata(dev); |
733 | struct snd_als300 *chip = card->private_data; | 732 | struct snd_als300 *chip = card->private_data; |
734 | 733 | ||
735 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 734 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
736 | snd_pcm_suspend_all(chip->pcm); | 735 | snd_pcm_suspend_all(chip->pcm); |
737 | snd_ac97_suspend(chip->ac97); | 736 | snd_ac97_suspend(chip->ac97); |
738 | |||
739 | pci_disable_device(pci); | ||
740 | pci_save_state(pci); | ||
741 | pci_set_power_state(pci, PCI_D3hot); | ||
742 | return 0; | 737 | return 0; |
743 | } | 738 | } |
744 | 739 | ||
745 | static int snd_als300_resume(struct device *dev) | 740 | static int snd_als300_resume(struct device *dev) |
746 | { | 741 | { |
747 | struct pci_dev *pci = to_pci_dev(dev); | ||
748 | struct snd_card *card = dev_get_drvdata(dev); | 742 | struct snd_card *card = dev_get_drvdata(dev); |
749 | struct snd_als300 *chip = card->private_data; | 743 | struct snd_als300 *chip = card->private_data; |
750 | 744 | ||
751 | pci_set_power_state(pci, PCI_D0); | ||
752 | pci_restore_state(pci); | ||
753 | if (pci_enable_device(pci) < 0) { | ||
754 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
755 | snd_card_disconnect(card); | ||
756 | return -EIO; | ||
757 | } | ||
758 | pci_set_master(pci); | ||
759 | |||
760 | snd_als300_init(chip); | 745 | snd_als300_init(chip); |
761 | snd_ac97_resume(chip->ac97); | 746 | snd_ac97_resume(chip->ac97); |
762 | 747 | ||
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index d3e6424ee656..94608524f3cc 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c | |||
@@ -988,7 +988,6 @@ static void snd_card_als4000_remove(struct pci_dev *pci) | |||
988 | #ifdef CONFIG_PM_SLEEP | 988 | #ifdef CONFIG_PM_SLEEP |
989 | static int snd_als4000_suspend(struct device *dev) | 989 | static int snd_als4000_suspend(struct device *dev) |
990 | { | 990 | { |
991 | struct pci_dev *pci = to_pci_dev(dev); | ||
992 | struct snd_card *card = dev_get_drvdata(dev); | 991 | struct snd_card *card = dev_get_drvdata(dev); |
993 | struct snd_card_als4000 *acard = card->private_data; | 992 | struct snd_card_als4000 *acard = card->private_data; |
994 | struct snd_sb *chip = acard->chip; | 993 | struct snd_sb *chip = acard->chip; |
@@ -997,29 +996,15 @@ static int snd_als4000_suspend(struct device *dev) | |||
997 | 996 | ||
998 | snd_pcm_suspend_all(chip->pcm); | 997 | snd_pcm_suspend_all(chip->pcm); |
999 | snd_sbmixer_suspend(chip); | 998 | snd_sbmixer_suspend(chip); |
1000 | |||
1001 | pci_disable_device(pci); | ||
1002 | pci_save_state(pci); | ||
1003 | pci_set_power_state(pci, PCI_D3hot); | ||
1004 | return 0; | 999 | return 0; |
1005 | } | 1000 | } |
1006 | 1001 | ||
1007 | static int snd_als4000_resume(struct device *dev) | 1002 | static int snd_als4000_resume(struct device *dev) |
1008 | { | 1003 | { |
1009 | struct pci_dev *pci = to_pci_dev(dev); | ||
1010 | struct snd_card *card = dev_get_drvdata(dev); | 1004 | struct snd_card *card = dev_get_drvdata(dev); |
1011 | struct snd_card_als4000 *acard = card->private_data; | 1005 | struct snd_card_als4000 *acard = card->private_data; |
1012 | struct snd_sb *chip = acard->chip; | 1006 | struct snd_sb *chip = acard->chip; |
1013 | 1007 | ||
1014 | pci_set_power_state(pci, PCI_D0); | ||
1015 | pci_restore_state(pci); | ||
1016 | if (pci_enable_device(pci) < 0) { | ||
1017 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
1018 | snd_card_disconnect(card); | ||
1019 | return -EIO; | ||
1020 | } | ||
1021 | pci_set_master(pci); | ||
1022 | |||
1023 | snd_als4000_configure(chip); | 1008 | snd_als4000_configure(chip); |
1024 | snd_sbdsp_reset(chip); | 1009 | snd_sbdsp_reset(chip); |
1025 | snd_sbmixer_resume(chip); | 1010 | snd_sbmixer_resume(chip); |
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index e9273fb2a505..e5cd7be85355 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c | |||
@@ -540,9 +540,8 @@ static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream * | |||
540 | expiry = HZ / 200; | 540 | expiry = HZ / 200; |
541 | 541 | ||
542 | expiry = max(expiry, 1); /* don't let it be zero! */ | 542 | expiry = max(expiry, 1); /* don't let it be zero! */ |
543 | dpcm->timer.expires = jiffies + expiry; | 543 | mod_timer(&dpcm->timer, jiffies + expiry); |
544 | dpcm->respawn_timer = 1; | 544 | dpcm->respawn_timer = 1; |
545 | add_timer(&dpcm->timer); | ||
546 | } | 545 | } |
547 | 546 | ||
548 | static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream) | 547 | static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream) |
@@ -1064,9 +1063,8 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) | |||
1064 | If internal and other stream playing, can't switch | 1063 | If internal and other stream playing, can't switch |
1065 | */ | 1064 | */ |
1066 | 1065 | ||
1067 | init_timer(&dpcm->timer); | 1066 | setup_timer(&dpcm->timer, snd_card_asihpi_timer_function, |
1068 | dpcm->timer.data = (unsigned long) dpcm; | 1067 | (unsigned long) dpcm); |
1069 | dpcm->timer.function = snd_card_asihpi_timer_function; | ||
1070 | dpcm->substream = substream; | 1068 | dpcm->substream = substream; |
1071 | runtime->private_data = dpcm; | 1069 | runtime->private_data = dpcm; |
1072 | runtime->private_free = snd_card_asihpi_runtime_free; | 1070 | runtime->private_free = snd_card_asihpi_runtime_free; |
@@ -1246,9 +1244,8 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) | |||
1246 | if (err) | 1244 | if (err) |
1247 | return -EIO; | 1245 | return -EIO; |
1248 | 1246 | ||
1249 | init_timer(&dpcm->timer); | 1247 | setup_timer(&dpcm->timer, snd_card_asihpi_timer_function, |
1250 | dpcm->timer.data = (unsigned long) dpcm; | 1248 | (unsigned long) dpcm); |
1251 | dpcm->timer.function = snd_card_asihpi_timer_function; | ||
1252 | dpcm->substream = substream; | 1249 | dpcm->substream = substream; |
1253 | runtime->private_data = dpcm; | 1250 | runtime->private_data = dpcm; |
1254 | runtime->private_free = snd_card_asihpi_runtime_free; | 1251 | runtime->private_free = snd_card_asihpi_runtime_free; |
@@ -2832,14 +2829,11 @@ static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file, | |||
2832 | /* results in /dev/snd/hwC#D0 file for each card with index # | 2829 | /* results in /dev/snd/hwC#D0 file for each card with index # |
2833 | also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card' | 2830 | also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card' |
2834 | */ | 2831 | */ |
2835 | static int snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, | 2832 | static int snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, int device) |
2836 | int device, struct snd_hwdep **rhwdep) | ||
2837 | { | 2833 | { |
2838 | struct snd_hwdep *hw; | 2834 | struct snd_hwdep *hw; |
2839 | int err; | 2835 | int err; |
2840 | 2836 | ||
2841 | if (rhwdep) | ||
2842 | *rhwdep = NULL; | ||
2843 | err = snd_hwdep_new(asihpi->card, "HPI", device, &hw); | 2837 | err = snd_hwdep_new(asihpi->card, "HPI", device, &hw); |
2844 | if (err < 0) | 2838 | if (err < 0) |
2845 | return err; | 2839 | return err; |
@@ -2849,8 +2843,6 @@ static int snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, | |||
2849 | hw->ops.ioctl = snd_asihpi_hpi_ioctl; | 2843 | hw->ops.ioctl = snd_asihpi_hpi_ioctl; |
2850 | hw->ops.release = snd_asihpi_hpi_release; | 2844 | hw->ops.release = snd_asihpi_hpi_release; |
2851 | hw->private_data = asihpi; | 2845 | hw->private_data = asihpi; |
2852 | if (rhwdep) | ||
2853 | *rhwdep = hw; | ||
2854 | return 0; | 2846 | return 0; |
2855 | } | 2847 | } |
2856 | 2848 | ||
@@ -2993,7 +2985,7 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2993 | 2985 | ||
2994 | /* always create, can be enabled or disabled dynamically | 2986 | /* always create, can be enabled or disabled dynamically |
2995 | by enable_hwdep module param*/ | 2987 | by enable_hwdep module param*/ |
2996 | snd_asihpi_hpi_new(asihpi, 0, NULL); | 2988 | snd_asihpi_hpi_new(asihpi, 0); |
2997 | 2989 | ||
2998 | strcpy(card->driver, "ASIHPI"); | 2990 | strcpy(card->driver, "ASIHPI"); |
2999 | 2991 | ||
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index 2414d7a2239d..2d6364825d4d 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c | |||
@@ -47,7 +47,7 @@ | |||
47 | 47 | ||
48 | /* operational/messaging errors */ | 48 | /* operational/messaging errors */ |
49 | #define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901 | 49 | #define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901 |
50 | 50 | #define HPI6000_ERROR_RESP_GET_LEN 902 | |
51 | #define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903 | 51 | #define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903 |
52 | #define HPI6000_ERROR_MSG_GET_ADR 904 | 52 | #define HPI6000_ERROR_MSG_GET_ADR 904 |
53 | #define HPI6000_ERROR_RESP_GET_ADR 905 | 53 | #define HPI6000_ERROR_RESP_GET_ADR 905 |
@@ -1365,7 +1365,10 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, | |||
1365 | length = hpi_read_word(pdo, HPI_HIF_ADDR(length)); | 1365 | length = hpi_read_word(pdo, HPI_HIF_ADDR(length)); |
1366 | } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout); | 1366 | } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout); |
1367 | if (!timeout) | 1367 | if (!timeout) |
1368 | length = sizeof(struct hpi_response); | 1368 | return HPI6000_ERROR_RESP_GET_LEN; |
1369 | |||
1370 | if (length > phr->size) | ||
1371 | return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL; | ||
1369 | 1372 | ||
1370 | /* get the response */ | 1373 | /* get the response */ |
1371 | p_data = (u32 *)phr; | 1374 | p_data = (u32 *)phr; |
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index 6aa677e60555..67d113356971 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c | |||
@@ -153,6 +153,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
153 | goto out; | 153 | goto out; |
154 | } | 154 | } |
155 | 155 | ||
156 | res_max_size = min_t(size_t, res_max_size, sizeof(*hr)); | ||
157 | |||
156 | switch (hm->h.function) { | 158 | switch (hm->h.function) { |
157 | case HPI_SUBSYS_CREATE_ADAPTER: | 159 | case HPI_SUBSYS_CREATE_ADAPTER: |
158 | case HPI_ADAPTER_DELETE: | 160 | case HPI_ADAPTER_DELETE: |
@@ -539,10 +541,8 @@ void asihpi_adapter_remove(struct pci_dev *pci_dev) | |||
539 | hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); | 541 | hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); |
540 | 542 | ||
541 | /* unmap PCI memory space, mapped during device init. */ | 543 | /* unmap PCI memory space, mapped during device init. */ |
542 | for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) { | 544 | for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; ++idx) |
543 | if (pci.ap_mem_base[idx]) | 545 | iounmap(pci.ap_mem_base[idx]); |
544 | iounmap(pci.ap_mem_base[idx]); | ||
545 | } | ||
546 | 546 | ||
547 | if (pa->irq) | 547 | if (pa->irq) |
548 | free_irq(pa->irq, pa); | 548 | free_irq(pa->irq, pa); |
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 9c1c4452a8ee..eb4f9ee54f85 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c | |||
@@ -1474,7 +1474,6 @@ static int snd_atiixp_mixer_new(struct atiixp *chip, int clock, | |||
1474 | */ | 1474 | */ |
1475 | static int snd_atiixp_suspend(struct device *dev) | 1475 | static int snd_atiixp_suspend(struct device *dev) |
1476 | { | 1476 | { |
1477 | struct pci_dev *pci = to_pci_dev(dev); | ||
1478 | struct snd_card *card = dev_get_drvdata(dev); | 1477 | struct snd_card *card = dev_get_drvdata(dev); |
1479 | struct atiixp *chip = card->private_data; | 1478 | struct atiixp *chip = card->private_data; |
1480 | int i; | 1479 | int i; |
@@ -1492,29 +1491,15 @@ static int snd_atiixp_suspend(struct device *dev) | |||
1492 | snd_ac97_suspend(chip->ac97[i]); | 1491 | snd_ac97_suspend(chip->ac97[i]); |
1493 | snd_atiixp_aclink_down(chip); | 1492 | snd_atiixp_aclink_down(chip); |
1494 | snd_atiixp_chip_stop(chip); | 1493 | snd_atiixp_chip_stop(chip); |
1495 | |||
1496 | pci_disable_device(pci); | ||
1497 | pci_save_state(pci); | ||
1498 | pci_set_power_state(pci, PCI_D3hot); | ||
1499 | return 0; | 1494 | return 0; |
1500 | } | 1495 | } |
1501 | 1496 | ||
1502 | static int snd_atiixp_resume(struct device *dev) | 1497 | static int snd_atiixp_resume(struct device *dev) |
1503 | { | 1498 | { |
1504 | struct pci_dev *pci = to_pci_dev(dev); | ||
1505 | struct snd_card *card = dev_get_drvdata(dev); | 1499 | struct snd_card *card = dev_get_drvdata(dev); |
1506 | struct atiixp *chip = card->private_data; | 1500 | struct atiixp *chip = card->private_data; |
1507 | int i; | 1501 | int i; |
1508 | 1502 | ||
1509 | pci_set_power_state(pci, PCI_D0); | ||
1510 | pci_restore_state(pci); | ||
1511 | if (pci_enable_device(pci) < 0) { | ||
1512 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
1513 | snd_card_disconnect(card); | ||
1514 | return -EIO; | ||
1515 | } | ||
1516 | pci_set_master(pci); | ||
1517 | |||
1518 | snd_atiixp_aclink_reset(chip); | 1503 | snd_atiixp_aclink_reset(chip); |
1519 | snd_atiixp_chip_start(chip); | 1504 | snd_atiixp_chip_start(chip); |
1520 | 1505 | ||
@@ -1585,8 +1570,7 @@ static int snd_atiixp_free(struct atiixp *chip) | |||
1585 | __hw_end: | 1570 | __hw_end: |
1586 | if (chip->irq >= 0) | 1571 | if (chip->irq >= 0) |
1587 | free_irq(chip->irq, chip); | 1572 | free_irq(chip->irq, chip); |
1588 | if (chip->remap_addr) | 1573 | iounmap(chip->remap_addr); |
1589 | iounmap(chip->remap_addr); | ||
1590 | pci_release_regions(chip->pci); | 1574 | pci_release_regions(chip->pci); |
1591 | pci_disable_device(chip->pci); | 1575 | pci_disable_device(chip->pci); |
1592 | kfree(chip); | 1576 | kfree(chip); |
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index b2f63e0727de..349dd7ba6e43 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c | |||
@@ -1120,7 +1120,6 @@ static int snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock) | |||
1120 | */ | 1120 | */ |
1121 | static int snd_atiixp_suspend(struct device *dev) | 1121 | static int snd_atiixp_suspend(struct device *dev) |
1122 | { | 1122 | { |
1123 | struct pci_dev *pci = to_pci_dev(dev); | ||
1124 | struct snd_card *card = dev_get_drvdata(dev); | 1123 | struct snd_card *card = dev_get_drvdata(dev); |
1125 | struct atiixp_modem *chip = card->private_data; | 1124 | struct atiixp_modem *chip = card->private_data; |
1126 | int i; | 1125 | int i; |
@@ -1132,29 +1131,15 @@ static int snd_atiixp_suspend(struct device *dev) | |||
1132 | snd_ac97_suspend(chip->ac97[i]); | 1131 | snd_ac97_suspend(chip->ac97[i]); |
1133 | snd_atiixp_aclink_down(chip); | 1132 | snd_atiixp_aclink_down(chip); |
1134 | snd_atiixp_chip_stop(chip); | 1133 | snd_atiixp_chip_stop(chip); |
1135 | |||
1136 | pci_disable_device(pci); | ||
1137 | pci_save_state(pci); | ||
1138 | pci_set_power_state(pci, PCI_D3hot); | ||
1139 | return 0; | 1134 | return 0; |
1140 | } | 1135 | } |
1141 | 1136 | ||
1142 | static int snd_atiixp_resume(struct device *dev) | 1137 | static int snd_atiixp_resume(struct device *dev) |
1143 | { | 1138 | { |
1144 | struct pci_dev *pci = to_pci_dev(dev); | ||
1145 | struct snd_card *card = dev_get_drvdata(dev); | 1139 | struct snd_card *card = dev_get_drvdata(dev); |
1146 | struct atiixp_modem *chip = card->private_data; | 1140 | struct atiixp_modem *chip = card->private_data; |
1147 | int i; | 1141 | int i; |
1148 | 1142 | ||
1149 | pci_set_power_state(pci, PCI_D0); | ||
1150 | pci_restore_state(pci); | ||
1151 | if (pci_enable_device(pci) < 0) { | ||
1152 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
1153 | snd_card_disconnect(card); | ||
1154 | return -EIO; | ||
1155 | } | ||
1156 | pci_set_master(pci); | ||
1157 | |||
1158 | snd_atiixp_aclink_reset(chip); | 1143 | snd_atiixp_aclink_reset(chip); |
1159 | snd_atiixp_chip_start(chip); | 1144 | snd_atiixp_chip_start(chip); |
1160 | 1145 | ||
@@ -1211,8 +1196,7 @@ static int snd_atiixp_free(struct atiixp_modem *chip) | |||
1211 | __hw_end: | 1196 | __hw_end: |
1212 | if (chip->irq >= 0) | 1197 | if (chip->irq >= 0) |
1213 | free_irq(chip->irq, chip); | 1198 | free_irq(chip->irq, chip); |
1214 | if (chip->remap_addr) | 1199 | iounmap(chip->remap_addr); |
1215 | iounmap(chip->remap_addr); | ||
1216 | pci_release_regions(chip->pci); | 1200 | pci_release_regions(chip->pci); |
1217 | pci_disable_device(chip->pci); | 1201 | pci_disable_device(chip->pci); |
1218 | kfree(chip); | 1202 | kfree(chip); |
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index e1cf01949fda..8d2fee7b33bd 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c | |||
@@ -229,9 +229,7 @@ static int snd_aw2_dev_free(struct snd_device *device) | |||
229 | if (chip->irq >= 0) | 229 | if (chip->irq >= 0) |
230 | free_irq(chip->irq, (void *)chip); | 230 | free_irq(chip->irq, (void *)chip); |
231 | /* release the i/o ports & memory */ | 231 | /* release the i/o ports & memory */ |
232 | if (chip->iobase_virt) | 232 | iounmap(chip->iobase_virt); |
233 | iounmap(chip->iobase_virt); | ||
234 | |||
235 | pci_release_regions(chip->pci); | 233 | pci_release_regions(chip->pci); |
236 | /* disable the PCI entry */ | 234 | /* disable the PCI entry */ |
237 | pci_disable_device(chip->pci); | 235 | pci_disable_device(chip->pci); |
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index fdbb9c05c77b..bbacc75c902a 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c | |||
@@ -2694,7 +2694,6 @@ snd_azf3328_resume_ac97(const struct snd_azf3328 *chip) | |||
2694 | static int | 2694 | static int |
2695 | snd_azf3328_suspend(struct device *dev) | 2695 | snd_azf3328_suspend(struct device *dev) |
2696 | { | 2696 | { |
2697 | struct pci_dev *pci = to_pci_dev(dev); | ||
2698 | struct snd_card *card = dev_get_drvdata(dev); | 2697 | struct snd_card *card = dev_get_drvdata(dev); |
2699 | struct snd_azf3328 *chip = card->private_data; | 2698 | struct snd_azf3328 *chip = card->private_data; |
2700 | u16 *saved_regs_ctrl_u16; | 2699 | u16 *saved_regs_ctrl_u16; |
@@ -2720,29 +2719,15 @@ snd_azf3328_suspend(struct device *dev) | |||
2720 | ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu); | 2719 | ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu); |
2721 | snd_azf3328_suspend_regs(chip, chip->opl3_io, | 2720 | snd_azf3328_suspend_regs(chip, chip->opl3_io, |
2722 | ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3); | 2721 | ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3); |
2723 | |||
2724 | pci_disable_device(pci); | ||
2725 | pci_save_state(pci); | ||
2726 | pci_set_power_state(pci, PCI_D3hot); | ||
2727 | return 0; | 2722 | return 0; |
2728 | } | 2723 | } |
2729 | 2724 | ||
2730 | static int | 2725 | static int |
2731 | snd_azf3328_resume(struct device *dev) | 2726 | snd_azf3328_resume(struct device *dev) |
2732 | { | 2727 | { |
2733 | struct pci_dev *pci = to_pci_dev(dev); | ||
2734 | struct snd_card *card = dev_get_drvdata(dev); | 2728 | struct snd_card *card = dev_get_drvdata(dev); |
2735 | const struct snd_azf3328 *chip = card->private_data; | 2729 | const struct snd_azf3328 *chip = card->private_data; |
2736 | 2730 | ||
2737 | pci_set_power_state(pci, PCI_D0); | ||
2738 | pci_restore_state(pci); | ||
2739 | if (pci_enable_device(pci) < 0) { | ||
2740 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
2741 | snd_card_disconnect(card); | ||
2742 | return -EIO; | ||
2743 | } | ||
2744 | pci_set_master(pci); | ||
2745 | |||
2746 | snd_azf3328_resume_regs(chip, chip->saved_regs_game, chip->game_io, | 2731 | snd_azf3328_resume_regs(chip, chip->saved_regs_game, chip->game_io, |
2747 | ARRAY_SIZE(chip->saved_regs_game)); | 2732 | ARRAY_SIZE(chip->saved_regs_game)); |
2748 | snd_azf3328_resume_regs(chip, chip->saved_regs_mpu, chip->mpu_io, | 2733 | snd_azf3328_resume_regs(chip, chip->saved_regs_mpu, chip->mpu_io, |
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 058b9973c09c..e82ceacbe64f 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c | |||
@@ -690,8 +690,7 @@ static int snd_bt87x_free(struct snd_bt87x *chip) | |||
690 | snd_bt87x_stop(chip); | 690 | snd_bt87x_stop(chip); |
691 | if (chip->irq >= 0) | 691 | if (chip->irq >= 0) |
692 | free_irq(chip->irq, chip); | 692 | free_irq(chip->irq, chip); |
693 | if (chip->mmio) | 693 | iounmap(chip->mmio); |
694 | iounmap(chip->mmio); | ||
695 | pci_release_regions(chip->pci); | 694 | pci_release_regions(chip->pci); |
696 | pci_disable_device(chip->pci); | 695 | pci_disable_device(chip->pci); |
697 | kfree(chip); | 696 | kfree(chip); |
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 96af33965b51..dd75b7536fa2 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -1910,7 +1910,6 @@ static void snd_ca0106_remove(struct pci_dev *pci) | |||
1910 | #ifdef CONFIG_PM_SLEEP | 1910 | #ifdef CONFIG_PM_SLEEP |
1911 | static int snd_ca0106_suspend(struct device *dev) | 1911 | static int snd_ca0106_suspend(struct device *dev) |
1912 | { | 1912 | { |
1913 | struct pci_dev *pci = to_pci_dev(dev); | ||
1914 | struct snd_card *card = dev_get_drvdata(dev); | 1913 | struct snd_card *card = dev_get_drvdata(dev); |
1915 | struct snd_ca0106 *chip = card->private_data; | 1914 | struct snd_ca0106 *chip = card->private_data; |
1916 | int i; | 1915 | int i; |
@@ -1923,30 +1922,15 @@ static int snd_ca0106_suspend(struct device *dev) | |||
1923 | snd_ca0106_mixer_suspend(chip); | 1922 | snd_ca0106_mixer_suspend(chip); |
1924 | 1923 | ||
1925 | ca0106_stop_chip(chip); | 1924 | ca0106_stop_chip(chip); |
1926 | |||
1927 | pci_disable_device(pci); | ||
1928 | pci_save_state(pci); | ||
1929 | pci_set_power_state(pci, PCI_D3hot); | ||
1930 | return 0; | 1925 | return 0; |
1931 | } | 1926 | } |
1932 | 1927 | ||
1933 | static int snd_ca0106_resume(struct device *dev) | 1928 | static int snd_ca0106_resume(struct device *dev) |
1934 | { | 1929 | { |
1935 | struct pci_dev *pci = to_pci_dev(dev); | ||
1936 | struct snd_card *card = dev_get_drvdata(dev); | 1930 | struct snd_card *card = dev_get_drvdata(dev); |
1937 | struct snd_ca0106 *chip = card->private_data; | 1931 | struct snd_ca0106 *chip = card->private_data; |
1938 | int i; | 1932 | int i; |
1939 | 1933 | ||
1940 | pci_set_power_state(pci, PCI_D0); | ||
1941 | pci_restore_state(pci); | ||
1942 | |||
1943 | if (pci_enable_device(pci) < 0) { | ||
1944 | snd_card_disconnect(card); | ||
1945 | return -EIO; | ||
1946 | } | ||
1947 | |||
1948 | pci_set_master(pci); | ||
1949 | |||
1950 | ca0106_init_chip(chip, 1); | 1934 | ca0106_init_chip(chip, 1); |
1951 | 1935 | ||
1952 | if (chip->details->ac97) | 1936 | if (chip->details->ac97) |
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 85ed40339db9..63d2c8236ec6 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
@@ -3347,7 +3347,6 @@ static unsigned char saved_mixers[] = { | |||
3347 | 3347 | ||
3348 | static int snd_cmipci_suspend(struct device *dev) | 3348 | static int snd_cmipci_suspend(struct device *dev) |
3349 | { | 3349 | { |
3350 | struct pci_dev *pci = to_pci_dev(dev); | ||
3351 | struct snd_card *card = dev_get_drvdata(dev); | 3350 | struct snd_card *card = dev_get_drvdata(dev); |
3352 | struct cmipci *cm = card->private_data; | 3351 | struct cmipci *cm = card->private_data; |
3353 | int i; | 3352 | int i; |
@@ -3366,29 +3365,15 @@ static int snd_cmipci_suspend(struct device *dev) | |||
3366 | 3365 | ||
3367 | /* disable ints */ | 3366 | /* disable ints */ |
3368 | snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); | 3367 | snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); |
3369 | |||
3370 | pci_disable_device(pci); | ||
3371 | pci_save_state(pci); | ||
3372 | pci_set_power_state(pci, PCI_D3hot); | ||
3373 | return 0; | 3368 | return 0; |
3374 | } | 3369 | } |
3375 | 3370 | ||
3376 | static int snd_cmipci_resume(struct device *dev) | 3371 | static int snd_cmipci_resume(struct device *dev) |
3377 | { | 3372 | { |
3378 | struct pci_dev *pci = to_pci_dev(dev); | ||
3379 | struct snd_card *card = dev_get_drvdata(dev); | 3373 | struct snd_card *card = dev_get_drvdata(dev); |
3380 | struct cmipci *cm = card->private_data; | 3374 | struct cmipci *cm = card->private_data; |
3381 | int i; | 3375 | int i; |
3382 | 3376 | ||
3383 | pci_set_power_state(pci, PCI_D0); | ||
3384 | pci_restore_state(pci); | ||
3385 | if (pci_enable_device(pci) < 0) { | ||
3386 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
3387 | snd_card_disconnect(card); | ||
3388 | return -EIO; | ||
3389 | } | ||
3390 | pci_set_master(pci); | ||
3391 | |||
3392 | /* reset / initialize to a sane state */ | 3377 | /* reset / initialize to a sane state */ |
3393 | snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); | 3378 | snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); |
3394 | snd_cmipci_ch_reset(cm, CM_CH_PLAY); | 3379 | snd_cmipci_ch_reset(cm, CM_CH_PLAY); |
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index 4c49b5c8a7b3..754613b772ab 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c | |||
@@ -973,14 +973,11 @@ static struct snd_pcm_ops snd_cs4281_capture_ops = { | |||
973 | .pointer = snd_cs4281_pointer, | 973 | .pointer = snd_cs4281_pointer, |
974 | }; | 974 | }; |
975 | 975 | ||
976 | static int snd_cs4281_pcm(struct cs4281 *chip, int device, | 976 | static int snd_cs4281_pcm(struct cs4281 *chip, int device) |
977 | struct snd_pcm **rpcm) | ||
978 | { | 977 | { |
979 | struct snd_pcm *pcm; | 978 | struct snd_pcm *pcm; |
980 | int err; | 979 | int err; |
981 | 980 | ||
982 | if (rpcm) | ||
983 | *rpcm = NULL; | ||
984 | err = snd_pcm_new(chip->card, "CS4281", device, 1, 1, &pcm); | 981 | err = snd_pcm_new(chip->card, "CS4281", device, 1, 1, &pcm); |
985 | if (err < 0) | 982 | if (err < 0) |
986 | return err; | 983 | return err; |
@@ -996,8 +993,6 @@ static int snd_cs4281_pcm(struct cs4281 *chip, int device, | |||
996 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 993 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
997 | snd_dma_pci_data(chip->pci), 64*1024, 512*1024); | 994 | snd_dma_pci_data(chip->pci), 64*1024, 512*1024); |
998 | 995 | ||
999 | if (rpcm) | ||
1000 | *rpcm = pcm; | ||
1001 | return 0; | 996 | return 0; |
1002 | } | 997 | } |
1003 | 998 | ||
@@ -1321,10 +1316,8 @@ static int snd_cs4281_free(struct cs4281 *chip) | |||
1321 | 1316 | ||
1322 | if (chip->irq >= 0) | 1317 | if (chip->irq >= 0) |
1323 | free_irq(chip->irq, chip); | 1318 | free_irq(chip->irq, chip); |
1324 | if (chip->ba0) | 1319 | iounmap(chip->ba0); |
1325 | iounmap(chip->ba0); | 1320 | iounmap(chip->ba1); |
1326 | if (chip->ba1) | ||
1327 | iounmap(chip->ba1); | ||
1328 | pci_release_regions(chip->pci); | 1321 | pci_release_regions(chip->pci); |
1329 | pci_disable_device(chip->pci); | 1322 | pci_disable_device(chip->pci); |
1330 | 1323 | ||
@@ -1788,14 +1781,11 @@ static struct snd_rawmidi_ops snd_cs4281_midi_input = | |||
1788 | .trigger = snd_cs4281_midi_input_trigger, | 1781 | .trigger = snd_cs4281_midi_input_trigger, |
1789 | }; | 1782 | }; |
1790 | 1783 | ||
1791 | static int snd_cs4281_midi(struct cs4281 *chip, int device, | 1784 | static int snd_cs4281_midi(struct cs4281 *chip, int device) |
1792 | struct snd_rawmidi **rrawmidi) | ||
1793 | { | 1785 | { |
1794 | struct snd_rawmidi *rmidi; | 1786 | struct snd_rawmidi *rmidi; |
1795 | int err; | 1787 | int err; |
1796 | 1788 | ||
1797 | if (rrawmidi) | ||
1798 | *rrawmidi = NULL; | ||
1799 | if ((err = snd_rawmidi_new(chip->card, "CS4281", device, 1, 1, &rmidi)) < 0) | 1789 | if ((err = snd_rawmidi_new(chip->card, "CS4281", device, 1, 1, &rmidi)) < 0) |
1800 | return err; | 1790 | return err; |
1801 | strcpy(rmidi->name, "CS4281"); | 1791 | strcpy(rmidi->name, "CS4281"); |
@@ -1804,8 +1794,6 @@ static int snd_cs4281_midi(struct cs4281 *chip, int device, | |||
1804 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; | 1794 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; |
1805 | rmidi->private_data = chip; | 1795 | rmidi->private_data = chip; |
1806 | chip->rmidi = rmidi; | 1796 | chip->rmidi = rmidi; |
1807 | if (rrawmidi) | ||
1808 | *rrawmidi = rmidi; | ||
1809 | return 0; | 1797 | return 0; |
1810 | } | 1798 | } |
1811 | 1799 | ||
@@ -1941,11 +1929,11 @@ static int snd_cs4281_probe(struct pci_dev *pci, | |||
1941 | snd_card_free(card); | 1929 | snd_card_free(card); |
1942 | return err; | 1930 | return err; |
1943 | } | 1931 | } |
1944 | if ((err = snd_cs4281_pcm(chip, 0, NULL)) < 0) { | 1932 | if ((err = snd_cs4281_pcm(chip, 0)) < 0) { |
1945 | snd_card_free(card); | 1933 | snd_card_free(card); |
1946 | return err; | 1934 | return err; |
1947 | } | 1935 | } |
1948 | if ((err = snd_cs4281_midi(chip, 0, NULL)) < 0) { | 1936 | if ((err = snd_cs4281_midi(chip, 0)) < 0) { |
1949 | snd_card_free(card); | 1937 | snd_card_free(card); |
1950 | return err; | 1938 | return err; |
1951 | } | 1939 | } |
@@ -2008,7 +1996,6 @@ static int saved_regs[SUSPEND_REGISTERS] = { | |||
2008 | 1996 | ||
2009 | static int cs4281_suspend(struct device *dev) | 1997 | static int cs4281_suspend(struct device *dev) |
2010 | { | 1998 | { |
2011 | struct pci_dev *pci = to_pci_dev(dev); | ||
2012 | struct snd_card *card = dev_get_drvdata(dev); | 1999 | struct snd_card *card = dev_get_drvdata(dev); |
2013 | struct cs4281 *chip = card->private_data; | 2000 | struct cs4281 *chip = card->private_data; |
2014 | u32 ulCLK; | 2001 | u32 ulCLK; |
@@ -2047,30 +2034,16 @@ static int cs4281_suspend(struct device *dev) | |||
2047 | ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1); | 2034 | ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1); |
2048 | ulCLK &= ~CLKCR1_CKRA; | 2035 | ulCLK &= ~CLKCR1_CKRA; |
2049 | snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK); | 2036 | snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK); |
2050 | |||
2051 | pci_disable_device(pci); | ||
2052 | pci_save_state(pci); | ||
2053 | pci_set_power_state(pci, PCI_D3hot); | ||
2054 | return 0; | 2037 | return 0; |
2055 | } | 2038 | } |
2056 | 2039 | ||
2057 | static int cs4281_resume(struct device *dev) | 2040 | static int cs4281_resume(struct device *dev) |
2058 | { | 2041 | { |
2059 | struct pci_dev *pci = to_pci_dev(dev); | ||
2060 | struct snd_card *card = dev_get_drvdata(dev); | 2042 | struct snd_card *card = dev_get_drvdata(dev); |
2061 | struct cs4281 *chip = card->private_data; | 2043 | struct cs4281 *chip = card->private_data; |
2062 | unsigned int i; | 2044 | unsigned int i; |
2063 | u32 ulCLK; | 2045 | u32 ulCLK; |
2064 | 2046 | ||
2065 | pci_set_power_state(pci, PCI_D0); | ||
2066 | pci_restore_state(pci); | ||
2067 | if (pci_enable_device(pci) < 0) { | ||
2068 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
2069 | snd_card_disconnect(card); | ||
2070 | return -EIO; | ||
2071 | } | ||
2072 | pci_set_master(pci); | ||
2073 | |||
2074 | ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1); | 2047 | ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1); |
2075 | ulCLK |= CLKCR1_CKRA; | 2048 | ulCLK |= CLKCR1_CKRA; |
2076 | snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK); | 2049 | snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK); |
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c index 6a6858c07826..655fbea1692c 100644 --- a/sound/pci/cs46xx/cs46xx.c +++ b/sound/pci/cs46xx/cs46xx.c | |||
@@ -100,16 +100,16 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci, | |||
100 | } | 100 | } |
101 | card->private_data = chip; | 101 | card->private_data = chip; |
102 | chip->accept_valid = mmap_valid[dev]; | 102 | chip->accept_valid = mmap_valid[dev]; |
103 | if ((err = snd_cs46xx_pcm(chip, 0, NULL)) < 0) { | 103 | if ((err = snd_cs46xx_pcm(chip, 0)) < 0) { |
104 | snd_card_free(card); | 104 | snd_card_free(card); |
105 | return err; | 105 | return err; |
106 | } | 106 | } |
107 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 107 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
108 | if ((err = snd_cs46xx_pcm_rear(chip,1, NULL)) < 0) { | 108 | if ((err = snd_cs46xx_pcm_rear(chip, 1)) < 0) { |
109 | snd_card_free(card); | 109 | snd_card_free(card); |
110 | return err; | 110 | return err; |
111 | } | 111 | } |
112 | if ((err = snd_cs46xx_pcm_iec958(chip,2,NULL)) < 0) { | 112 | if ((err = snd_cs46xx_pcm_iec958(chip, 2)) < 0) { |
113 | snd_card_free(card); | 113 | snd_card_free(card); |
114 | return err; | 114 | return err; |
115 | } | 115 | } |
@@ -120,13 +120,13 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci, | |||
120 | } | 120 | } |
121 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 121 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
122 | if (chip->nr_ac97_codecs ==2) { | 122 | if (chip->nr_ac97_codecs ==2) { |
123 | if ((err = snd_cs46xx_pcm_center_lfe(chip,3,NULL)) < 0) { | 123 | if ((err = snd_cs46xx_pcm_center_lfe(chip, 3)) < 0) { |
124 | snd_card_free(card); | 124 | snd_card_free(card); |
125 | return err; | 125 | return err; |
126 | } | 126 | } |
127 | } | 127 | } |
128 | #endif | 128 | #endif |
129 | if ((err = snd_cs46xx_midi(chip, 0, NULL)) < 0) { | 129 | if ((err = snd_cs46xx_midi(chip, 0)) < 0) { |
130 | snd_card_free(card); | 130 | snd_card_free(card); |
131 | return err; | 131 | return err; |
132 | } | 132 | } |
diff --git a/sound/pci/cs46xx/cs46xx.h b/sound/pci/cs46xx/cs46xx.h index c49a082c378b..9c9f89a8be5f 100644 --- a/sound/pci/cs46xx/cs46xx.h +++ b/sound/pci/cs46xx/cs46xx.h | |||
@@ -1737,12 +1737,12 @@ int snd_cs46xx_create(struct snd_card *card, | |||
1737 | struct snd_cs46xx **rcodec); | 1737 | struct snd_cs46xx **rcodec); |
1738 | extern const struct dev_pm_ops snd_cs46xx_pm; | 1738 | extern const struct dev_pm_ops snd_cs46xx_pm; |
1739 | 1739 | ||
1740 | int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); | 1740 | int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device); |
1741 | int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); | 1741 | int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device); |
1742 | int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); | 1742 | int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device); |
1743 | int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); | 1743 | int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device); |
1744 | int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device); | 1744 | int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device); |
1745 | int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rmidi); | 1745 | int snd_cs46xx_midi(struct snd_cs46xx *chip, int device); |
1746 | int snd_cs46xx_start_dsp(struct snd_cs46xx *chip); | 1746 | int snd_cs46xx_start_dsp(struct snd_cs46xx *chip); |
1747 | int snd_cs46xx_gameport(struct snd_cs46xx *chip); | 1747 | int snd_cs46xx_gameport(struct snd_cs46xx *chip); |
1748 | 1748 | ||
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 32b44f25b5c8..fb3abb2203cd 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c | |||
@@ -1778,13 +1778,11 @@ static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = { | |||
1778 | #define MAX_PLAYBACK_CHANNELS 1 | 1778 | #define MAX_PLAYBACK_CHANNELS 1 |
1779 | #endif | 1779 | #endif |
1780 | 1780 | ||
1781 | int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm) | 1781 | int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device) |
1782 | { | 1782 | { |
1783 | struct snd_pcm *pcm; | 1783 | struct snd_pcm *pcm; |
1784 | int err; | 1784 | int err; |
1785 | 1785 | ||
1786 | if (rpcm) | ||
1787 | *rpcm = NULL; | ||
1788 | if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0) | 1786 | if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0) |
1789 | return err; | 1787 | return err; |
1790 | 1788 | ||
@@ -1801,23 +1799,16 @@ int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm) | |||
1801 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1799 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1802 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); | 1800 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); |
1803 | 1801 | ||
1804 | if (rpcm) | ||
1805 | *rpcm = pcm; | ||
1806 | |||
1807 | return 0; | 1802 | return 0; |
1808 | } | 1803 | } |
1809 | 1804 | ||
1810 | 1805 | ||
1811 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1806 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1812 | int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, | 1807 | int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device) |
1813 | struct snd_pcm **rpcm) | ||
1814 | { | 1808 | { |
1815 | struct snd_pcm *pcm; | 1809 | struct snd_pcm *pcm; |
1816 | int err; | 1810 | int err; |
1817 | 1811 | ||
1818 | if (rpcm) | ||
1819 | *rpcm = NULL; | ||
1820 | |||
1821 | if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) | 1812 | if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) |
1822 | return err; | 1813 | return err; |
1823 | 1814 | ||
@@ -1833,21 +1824,14 @@ int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, | |||
1833 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1824 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1834 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); | 1825 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); |
1835 | 1826 | ||
1836 | if (rpcm) | ||
1837 | *rpcm = pcm; | ||
1838 | |||
1839 | return 0; | 1827 | return 0; |
1840 | } | 1828 | } |
1841 | 1829 | ||
1842 | int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, | 1830 | int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device) |
1843 | struct snd_pcm **rpcm) | ||
1844 | { | 1831 | { |
1845 | struct snd_pcm *pcm; | 1832 | struct snd_pcm *pcm; |
1846 | int err; | 1833 | int err; |
1847 | 1834 | ||
1848 | if (rpcm) | ||
1849 | *rpcm = NULL; | ||
1850 | |||
1851 | if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) | 1835 | if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) |
1852 | return err; | 1836 | return err; |
1853 | 1837 | ||
@@ -1863,21 +1847,14 @@ int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, | |||
1863 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1847 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1864 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); | 1848 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); |
1865 | 1849 | ||
1866 | if (rpcm) | ||
1867 | *rpcm = pcm; | ||
1868 | |||
1869 | return 0; | 1850 | return 0; |
1870 | } | 1851 | } |
1871 | 1852 | ||
1872 | int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, | 1853 | int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device) |
1873 | struct snd_pcm **rpcm) | ||
1874 | { | 1854 | { |
1875 | struct snd_pcm *pcm; | 1855 | struct snd_pcm *pcm; |
1876 | int err; | 1856 | int err; |
1877 | 1857 | ||
1878 | if (rpcm) | ||
1879 | *rpcm = NULL; | ||
1880 | |||
1881 | if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0) | 1858 | if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0) |
1882 | return err; | 1859 | return err; |
1883 | 1860 | ||
@@ -1893,9 +1870,6 @@ int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, | |||
1893 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1870 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1894 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); | 1871 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); |
1895 | 1872 | ||
1896 | if (rpcm) | ||
1897 | *rpcm = pcm; | ||
1898 | |||
1899 | return 0; | 1873 | return 0; |
1900 | } | 1874 | } |
1901 | #endif | 1875 | #endif |
@@ -2724,13 +2698,11 @@ static struct snd_rawmidi_ops snd_cs46xx_midi_input = | |||
2724 | .trigger = snd_cs46xx_midi_input_trigger, | 2698 | .trigger = snd_cs46xx_midi_input_trigger, |
2725 | }; | 2699 | }; |
2726 | 2700 | ||
2727 | int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rrawmidi) | 2701 | int snd_cs46xx_midi(struct snd_cs46xx *chip, int device) |
2728 | { | 2702 | { |
2729 | struct snd_rawmidi *rmidi; | 2703 | struct snd_rawmidi *rmidi; |
2730 | int err; | 2704 | int err; |
2731 | 2705 | ||
2732 | if (rrawmidi) | ||
2733 | *rrawmidi = NULL; | ||
2734 | if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0) | 2706 | if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0) |
2735 | return err; | 2707 | return err; |
2736 | strcpy(rmidi->name, "CS46XX"); | 2708 | strcpy(rmidi->name, "CS46XX"); |
@@ -2739,8 +2711,6 @@ int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rr | |||
2739 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; | 2711 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; |
2740 | rmidi->private_data = chip; | 2712 | rmidi->private_data = chip; |
2741 | chip->rmidi = rmidi; | 2713 | chip->rmidi = rmidi; |
2742 | if (rrawmidi) | ||
2743 | *rrawmidi = NULL; | ||
2744 | return 0; | 2714 | return 0; |
2745 | } | 2715 | } |
2746 | 2716 | ||
@@ -2979,8 +2949,8 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip) | |||
2979 | 2949 | ||
2980 | for (idx = 0; idx < 5; idx++) { | 2950 | for (idx = 0; idx < 5; idx++) { |
2981 | struct snd_cs46xx_region *region = &chip->region.idx[idx]; | 2951 | struct snd_cs46xx_region *region = &chip->region.idx[idx]; |
2982 | if (region->remap_addr) | 2952 | |
2983 | iounmap(region->remap_addr); | 2953 | iounmap(region->remap_addr); |
2984 | release_and_free_resource(region->resource); | 2954 | release_and_free_resource(region->resource); |
2985 | } | 2955 | } |
2986 | 2956 | ||
@@ -3804,7 +3774,6 @@ static unsigned int saved_regs[] = { | |||
3804 | 3774 | ||
3805 | static int snd_cs46xx_suspend(struct device *dev) | 3775 | static int snd_cs46xx_suspend(struct device *dev) |
3806 | { | 3776 | { |
3807 | struct pci_dev *pci = to_pci_dev(dev); | ||
3808 | struct snd_card *card = dev_get_drvdata(dev); | 3777 | struct snd_card *card = dev_get_drvdata(dev); |
3809 | struct snd_cs46xx *chip = card->private_data; | 3778 | struct snd_cs46xx *chip = card->private_data; |
3810 | int i, amp_saved; | 3779 | int i, amp_saved; |
@@ -3829,16 +3798,11 @@ static int snd_cs46xx_suspend(struct device *dev) | |||
3829 | /* disable CLKRUN */ | 3798 | /* disable CLKRUN */ |
3830 | chip->active_ctrl(chip, -chip->amplifier); | 3799 | chip->active_ctrl(chip, -chip->amplifier); |
3831 | chip->amplifier = amp_saved; /* restore the status */ | 3800 | chip->amplifier = amp_saved; /* restore the status */ |
3832 | |||
3833 | pci_disable_device(pci); | ||
3834 | pci_save_state(pci); | ||
3835 | pci_set_power_state(pci, PCI_D3hot); | ||
3836 | return 0; | 3801 | return 0; |
3837 | } | 3802 | } |
3838 | 3803 | ||
3839 | static int snd_cs46xx_resume(struct device *dev) | 3804 | static int snd_cs46xx_resume(struct device *dev) |
3840 | { | 3805 | { |
3841 | struct pci_dev *pci = to_pci_dev(dev); | ||
3842 | struct snd_card *card = dev_get_drvdata(dev); | 3806 | struct snd_card *card = dev_get_drvdata(dev); |
3843 | struct snd_cs46xx *chip = card->private_data; | 3807 | struct snd_cs46xx *chip = card->private_data; |
3844 | int amp_saved; | 3808 | int amp_saved; |
@@ -3847,15 +3811,6 @@ static int snd_cs46xx_resume(struct device *dev) | |||
3847 | #endif | 3811 | #endif |
3848 | unsigned int tmp; | 3812 | unsigned int tmp; |
3849 | 3813 | ||
3850 | pci_set_power_state(pci, PCI_D0); | ||
3851 | pci_restore_state(pci); | ||
3852 | if (pci_enable_device(pci) < 0) { | ||
3853 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
3854 | snd_card_disconnect(card); | ||
3855 | return -EIO; | ||
3856 | } | ||
3857 | pci_set_master(pci); | ||
3858 | |||
3859 | amp_saved = chip->amplifier; | 3814 | amp_saved = chip->amplifier; |
3860 | chip->amplifier = 0; | 3815 | chip->amplifier = 0; |
3861 | chip->active_ctrl(chip, 1); /* force to on */ | 3816 | chip->active_ctrl(chip, 1); /* force to on */ |
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c index b1025507a467..0a8cf94c4858 100644 --- a/sound/pci/cs5530.c +++ b/sound/pci/cs5530.c | |||
@@ -223,7 +223,7 @@ static int snd_cs5530_create(struct snd_card *card, | |||
223 | return err; | 223 | return err; |
224 | } | 224 | } |
225 | 225 | ||
226 | err = snd_sb16dsp_pcm(chip->sb, 0, &chip->sb->pcm); | 226 | err = snd_sb16dsp_pcm(chip->sb, 0); |
227 | if (err < 0) { | 227 | if (err < 0) { |
228 | dev_err(card->dev, "Could not create PCM\n"); | 228 | dev_err(card->dev, "Could not create PCM\n"); |
229 | snd_cs5530_free(chip); | 229 | snd_cs5530_free(chip); |
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c index 34cc60057d0c..06ac5d8da362 100644 --- a/sound/pci/cs5535audio/cs5535audio_pm.c +++ b/sound/pci/cs5535audio/cs5535audio_pm.c | |||
@@ -57,7 +57,6 @@ static void snd_cs5535audio_stop_hardware(struct cs5535audio *cs5535au) | |||
57 | 57 | ||
58 | static int snd_cs5535audio_suspend(struct device *dev) | 58 | static int snd_cs5535audio_suspend(struct device *dev) |
59 | { | 59 | { |
60 | struct pci_dev *pci = to_pci_dev(dev); | ||
61 | struct snd_card *card = dev_get_drvdata(dev); | 60 | struct snd_card *card = dev_get_drvdata(dev); |
62 | struct cs5535audio *cs5535au = card->private_data; | 61 | struct cs5535audio *cs5535au = card->private_data; |
63 | int i; | 62 | int i; |
@@ -72,34 +71,17 @@ static int snd_cs5535audio_suspend(struct device *dev) | |||
72 | } | 71 | } |
73 | /* save important regs, then disable aclink in hw */ | 72 | /* save important regs, then disable aclink in hw */ |
74 | snd_cs5535audio_stop_hardware(cs5535au); | 73 | snd_cs5535audio_stop_hardware(cs5535au); |
75 | |||
76 | if (pci_save_state(pci)) { | ||
77 | dev_err(dev, "pci_save_state failed!\n"); | ||
78 | return -EIO; | ||
79 | } | ||
80 | pci_disable_device(pci); | ||
81 | pci_set_power_state(pci, PCI_D3hot); | ||
82 | return 0; | 74 | return 0; |
83 | } | 75 | } |
84 | 76 | ||
85 | static int snd_cs5535audio_resume(struct device *dev) | 77 | static int snd_cs5535audio_resume(struct device *dev) |
86 | { | 78 | { |
87 | struct pci_dev *pci = to_pci_dev(dev); | ||
88 | struct snd_card *card = dev_get_drvdata(dev); | 79 | struct snd_card *card = dev_get_drvdata(dev); |
89 | struct cs5535audio *cs5535au = card->private_data; | 80 | struct cs5535audio *cs5535au = card->private_data; |
90 | u32 tmp; | 81 | u32 tmp; |
91 | int timeout; | 82 | int timeout; |
92 | int i; | 83 | int i; |
93 | 84 | ||
94 | pci_set_power_state(pci, PCI_D0); | ||
95 | pci_restore_state(pci); | ||
96 | if (pci_enable_device(pci) < 0) { | ||
97 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
98 | snd_card_disconnect(card); | ||
99 | return -EIO; | ||
100 | } | ||
101 | pci_set_master(pci); | ||
102 | |||
103 | /* set LNK_WRM_RST to reset AC link */ | 85 | /* set LNK_WRM_RST to reset AC link */ |
104 | cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_WRM_RST); | 86 | cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_WRM_RST); |
105 | 87 | ||
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index b425aa8ee578..1cac55fd1139 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c | |||
@@ -1985,10 +1985,7 @@ static int hw_card_shutdown(struct hw *hw) | |||
1985 | free_irq(hw->irq, hw); | 1985 | free_irq(hw->irq, hw); |
1986 | 1986 | ||
1987 | hw->irq = -1; | 1987 | hw->irq = -1; |
1988 | 1988 | iounmap(hw->mem_base); | |
1989 | if (hw->mem_base) | ||
1990 | iounmap(hw->mem_base); | ||
1991 | |||
1992 | hw->mem_base = NULL; | 1989 | hw->mem_base = NULL; |
1993 | 1990 | ||
1994 | if (hw->io_base) | 1991 | if (hw->io_base) |
@@ -2099,20 +2096,11 @@ static int hw_suspend(struct hw *hw) | |||
2099 | pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x0); | 2096 | pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x0); |
2100 | } | 2097 | } |
2101 | 2098 | ||
2102 | pci_disable_device(pci); | ||
2103 | pci_save_state(pci); | ||
2104 | pci_set_power_state(pci, PCI_D3hot); | ||
2105 | |||
2106 | return 0; | 2099 | return 0; |
2107 | } | 2100 | } |
2108 | 2101 | ||
2109 | static int hw_resume(struct hw *hw, struct card_conf *info) | 2102 | static int hw_resume(struct hw *hw, struct card_conf *info) |
2110 | { | 2103 | { |
2111 | struct pci_dev *pci = hw->pci; | ||
2112 | |||
2113 | pci_set_power_state(pci, PCI_D0); | ||
2114 | pci_restore_state(pci); | ||
2115 | |||
2116 | /* Re-initialize card hardware. */ | 2104 | /* Re-initialize card hardware. */ |
2117 | return hw_card_init(hw, info); | 2105 | return hw_card_init(hw, info); |
2118 | } | 2106 | } |
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index 253899d13790..955ad871e9a8 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c | |||
@@ -2110,10 +2110,7 @@ static int hw_card_shutdown(struct hw *hw) | |||
2110 | free_irq(hw->irq, hw); | 2110 | free_irq(hw->irq, hw); |
2111 | 2111 | ||
2112 | hw->irq = -1; | 2112 | hw->irq = -1; |
2113 | 2113 | iounmap(hw->mem_base); | |
2114 | if (hw->mem_base) | ||
2115 | iounmap(hw->mem_base); | ||
2116 | |||
2117 | hw->mem_base = NULL; | 2114 | hw->mem_base = NULL; |
2118 | 2115 | ||
2119 | if (hw->io_base) | 2116 | if (hw->io_base) |
@@ -2209,24 +2206,12 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) | |||
2209 | #ifdef CONFIG_PM_SLEEP | 2206 | #ifdef CONFIG_PM_SLEEP |
2210 | static int hw_suspend(struct hw *hw) | 2207 | static int hw_suspend(struct hw *hw) |
2211 | { | 2208 | { |
2212 | struct pci_dev *pci = hw->pci; | ||
2213 | |||
2214 | hw_card_stop(hw); | 2209 | hw_card_stop(hw); |
2215 | |||
2216 | pci_disable_device(pci); | ||
2217 | pci_save_state(pci); | ||
2218 | pci_set_power_state(pci, PCI_D3hot); | ||
2219 | |||
2220 | return 0; | 2210 | return 0; |
2221 | } | 2211 | } |
2222 | 2212 | ||
2223 | static int hw_resume(struct hw *hw, struct card_conf *info) | 2213 | static int hw_resume(struct hw *hw, struct card_conf *info) |
2224 | { | 2214 | { |
2225 | struct pci_dev *pci = hw->pci; | ||
2226 | |||
2227 | pci_set_power_state(pci, PCI_D0); | ||
2228 | pci_restore_state(pci); | ||
2229 | |||
2230 | /* Re-initialize card hardware. */ | 2215 | /* Re-initialize card hardware. */ |
2231 | return hw_card_init(hw, info); | 2216 | return hw_card_init(hw, info); |
2232 | } | 2217 | } |
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 21228adaa70c..a962de03ebb6 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c | |||
@@ -1872,12 +1872,8 @@ static int snd_echo_free(struct echoaudio *chip) | |||
1872 | if (chip->comm_page) | 1872 | if (chip->comm_page) |
1873 | snd_dma_free_pages(&chip->commpage_dma_buf); | 1873 | snd_dma_free_pages(&chip->commpage_dma_buf); |
1874 | 1874 | ||
1875 | if (chip->dsp_registers) | 1875 | iounmap(chip->dsp_registers); |
1876 | iounmap(chip->dsp_registers); | ||
1877 | |||
1878 | release_and_free_resource(chip->iores); | 1876 | release_and_free_resource(chip->iores); |
1879 | |||
1880 | |||
1881 | pci_disable_device(chip->pci); | 1877 | pci_disable_device(chip->pci); |
1882 | 1878 | ||
1883 | /* release chip data */ | 1879 | /* release chip data */ |
@@ -2162,7 +2158,6 @@ ctl_error: | |||
2162 | 2158 | ||
2163 | static int snd_echo_suspend(struct device *dev) | 2159 | static int snd_echo_suspend(struct device *dev) |
2164 | { | 2160 | { |
2165 | struct pci_dev *pci = to_pci_dev(dev); | ||
2166 | struct echoaudio *chip = dev_get_drvdata(dev); | 2161 | struct echoaudio *chip = dev_get_drvdata(dev); |
2167 | 2162 | ||
2168 | snd_pcm_suspend_all(chip->analog_pcm); | 2163 | snd_pcm_suspend_all(chip->analog_pcm); |
@@ -2188,9 +2183,6 @@ static int snd_echo_suspend(struct device *dev) | |||
2188 | chip->dsp_code = NULL; | 2183 | chip->dsp_code = NULL; |
2189 | free_irq(chip->irq, chip); | 2184 | free_irq(chip->irq, chip); |
2190 | chip->irq = -1; | 2185 | chip->irq = -1; |
2191 | pci_save_state(pci); | ||
2192 | pci_disable_device(pci); | ||
2193 | |||
2194 | return 0; | 2186 | return 0; |
2195 | } | 2187 | } |
2196 | 2188 | ||
@@ -2204,7 +2196,6 @@ static int snd_echo_resume(struct device *dev) | |||
2204 | u32 pipe_alloc_mask; | 2196 | u32 pipe_alloc_mask; |
2205 | int err; | 2197 | int err; |
2206 | 2198 | ||
2207 | pci_restore_state(pci); | ||
2208 | commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL); | 2199 | commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL); |
2209 | if (commpage_bak == NULL) | 2200 | if (commpage_bak == NULL) |
2210 | return -ENOMEM; | 2201 | return -ENOMEM; |
diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c index d913749d154a..a8fe58335ddc 100644 --- a/sound/pci/echoaudio/midi.c +++ b/sound/pci/echoaudio/midi.c | |||
@@ -257,9 +257,8 @@ static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream | |||
257 | spin_lock_irq(&chip->lock); | 257 | spin_lock_irq(&chip->lock); |
258 | if (up) { | 258 | if (up) { |
259 | if (!chip->tinuse) { | 259 | if (!chip->tinuse) { |
260 | init_timer(&chip->timer); | 260 | setup_timer(&chip->timer, snd_echo_midi_output_write, |
261 | chip->timer.function = snd_echo_midi_output_write; | 261 | (unsigned long)chip); |
262 | chip->timer.data = (unsigned long)chip; | ||
263 | chip->tinuse = 1; | 262 | chip->tinuse = 1; |
264 | } | 263 | } |
265 | } else { | 264 | } else { |
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index 4c171636efcd..37d0220a094c 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c | |||
@@ -132,11 +132,11 @@ static int snd_card_emu10k1_probe(struct pci_dev *pci, | |||
132 | goto error; | 132 | goto error; |
133 | card->private_data = emu; | 133 | card->private_data = emu; |
134 | emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f; | 134 | emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f; |
135 | if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) | 135 | if ((err = snd_emu10k1_pcm(emu, 0)) < 0) |
136 | goto error; | 136 | goto error; |
137 | if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) | 137 | if ((err = snd_emu10k1_pcm_mic(emu, 1)) < 0) |
138 | goto error; | 138 | goto error; |
139 | if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0) | 139 | if ((err = snd_emu10k1_pcm_efx(emu, 2)) < 0) |
140 | goto error; | 140 | goto error; |
141 | /* This stores the periods table. */ | 141 | /* This stores the periods table. */ |
142 | if (emu->card_capabilities->ca0151_chip) { /* P16V */ | 142 | if (emu->card_capabilities->ca0151_chip) { /* P16V */ |
@@ -151,10 +151,10 @@ static int snd_card_emu10k1_probe(struct pci_dev *pci, | |||
151 | if ((err = snd_emu10k1_timer(emu, 0)) < 0) | 151 | if ((err = snd_emu10k1_timer(emu, 0)) < 0) |
152 | goto error; | 152 | goto error; |
153 | 153 | ||
154 | if ((err = snd_emu10k1_pcm_multi(emu, 3, NULL)) < 0) | 154 | if ((err = snd_emu10k1_pcm_multi(emu, 3)) < 0) |
155 | goto error; | 155 | goto error; |
156 | if (emu->card_capabilities->ca0151_chip) { /* P16V */ | 156 | if (emu->card_capabilities->ca0151_chip) { /* P16V */ |
157 | if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0) | 157 | if ((err = snd_p16v_pcm(emu, 4)) < 0) |
158 | goto error; | 158 | goto error; |
159 | } | 159 | } |
160 | if (emu->audigy) { | 160 | if (emu->audigy) { |
@@ -164,7 +164,7 @@ static int snd_card_emu10k1_probe(struct pci_dev *pci, | |||
164 | if ((err = snd_emu10k1_midi(emu)) < 0) | 164 | if ((err = snd_emu10k1_midi(emu)) < 0) |
165 | goto error; | 165 | goto error; |
166 | } | 166 | } |
167 | if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0) | 167 | if ((err = snd_emu10k1_fx8010_new(emu, 0)) < 0) |
168 | goto error; | 168 | goto error; |
169 | #ifdef ENABLE_SYNTH | 169 | #ifdef ENABLE_SYNTH |
170 | if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, | 170 | if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, |
@@ -210,7 +210,6 @@ static void snd_card_emu10k1_remove(struct pci_dev *pci) | |||
210 | #ifdef CONFIG_PM_SLEEP | 210 | #ifdef CONFIG_PM_SLEEP |
211 | static int snd_emu10k1_suspend(struct device *dev) | 211 | static int snd_emu10k1_suspend(struct device *dev) |
212 | { | 212 | { |
213 | struct pci_dev *pci = to_pci_dev(dev); | ||
214 | struct snd_card *card = dev_get_drvdata(dev); | 213 | struct snd_card *card = dev_get_drvdata(dev); |
215 | struct snd_emu10k1 *emu = card->private_data; | 214 | struct snd_emu10k1 *emu = card->private_data; |
216 | 215 | ||
@@ -232,28 +231,14 @@ static int snd_emu10k1_suspend(struct device *dev) | |||
232 | snd_p16v_suspend(emu); | 231 | snd_p16v_suspend(emu); |
233 | 232 | ||
234 | snd_emu10k1_done(emu); | 233 | snd_emu10k1_done(emu); |
235 | |||
236 | pci_disable_device(pci); | ||
237 | pci_save_state(pci); | ||
238 | pci_set_power_state(pci, PCI_D3hot); | ||
239 | return 0; | 234 | return 0; |
240 | } | 235 | } |
241 | 236 | ||
242 | static int snd_emu10k1_resume(struct device *dev) | 237 | static int snd_emu10k1_resume(struct device *dev) |
243 | { | 238 | { |
244 | struct pci_dev *pci = to_pci_dev(dev); | ||
245 | struct snd_card *card = dev_get_drvdata(dev); | 239 | struct snd_card *card = dev_get_drvdata(dev); |
246 | struct snd_emu10k1 *emu = card->private_data; | 240 | struct snd_emu10k1 *emu = card->private_data; |
247 | 241 | ||
248 | pci_set_power_state(pci, PCI_D0); | ||
249 | pci_restore_state(pci); | ||
250 | if (pci_enable_device(pci) < 0) { | ||
251 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
252 | snd_card_disconnect(card); | ||
253 | return -EIO; | ||
254 | } | ||
255 | pci_set_master(pci); | ||
256 | |||
257 | snd_emu10k1_resume_init(emu); | 242 | snd_emu10k1_resume_init(emu); |
258 | snd_emu10k1_efx_resume(emu); | 243 | snd_emu10k1_efx_resume(emu); |
259 | snd_ac97_resume(emu->ac97); | 244 | snd_ac97_resume(emu->ac97); |
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 15933f92f63a..6d1b98d14327 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c | |||
@@ -847,15 +847,13 @@ static const struct snd_pcm_chmap_elem clfe_map[] = { | |||
847 | { } | 847 | { } |
848 | }; | 848 | }; |
849 | 849 | ||
850 | static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct snd_pcm **rpcm) | 850 | static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device) |
851 | { | 851 | { |
852 | struct snd_pcm *pcm; | 852 | struct snd_pcm *pcm; |
853 | const struct snd_pcm_chmap_elem *map = NULL; | 853 | const struct snd_pcm_chmap_elem *map = NULL; |
854 | int err; | 854 | int err; |
855 | int capture = 0; | 855 | int capture = 0; |
856 | 856 | ||
857 | if (rpcm) | ||
858 | *rpcm = NULL; | ||
859 | if (device == 0) | 857 | if (device == 0) |
860 | capture = 1; | 858 | capture = 1; |
861 | 859 | ||
@@ -896,15 +894,8 @@ static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct snd_pcm **r | |||
896 | snd_dma_pci_data(emu->pci), | 894 | snd_dma_pci_data(emu->pci), |
897 | 32*1024, 32*1024); | 895 | 32*1024, 32*1024); |
898 | 896 | ||
899 | err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2, | 897 | return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2, |
900 | 1 << 2, NULL); | 898 | 1 << 2, NULL); |
901 | if (err < 0) | ||
902 | return err; | ||
903 | |||
904 | if (rpcm) | ||
905 | *rpcm = pcm; | ||
906 | |||
907 | return 0; | ||
908 | } | 899 | } |
909 | 900 | ||
910 | static int snd_emu10k1x_create(struct snd_card *card, | 901 | static int snd_emu10k1x_create(struct snd_card *card, |
@@ -1583,15 +1574,15 @@ static int snd_emu10k1x_probe(struct pci_dev *pci, | |||
1583 | return err; | 1574 | return err; |
1584 | } | 1575 | } |
1585 | 1576 | ||
1586 | if ((err = snd_emu10k1x_pcm(chip, 0, NULL)) < 0) { | 1577 | if ((err = snd_emu10k1x_pcm(chip, 0)) < 0) { |
1587 | snd_card_free(card); | 1578 | snd_card_free(card); |
1588 | return err; | 1579 | return err; |
1589 | } | 1580 | } |
1590 | if ((err = snd_emu10k1x_pcm(chip, 1, NULL)) < 0) { | 1581 | if ((err = snd_emu10k1x_pcm(chip, 1)) < 0) { |
1591 | snd_card_free(card); | 1582 | snd_card_free(card); |
1592 | return err; | 1583 | return err; |
1593 | } | 1584 | } |
1594 | if ((err = snd_emu10k1x_pcm(chip, 2, NULL)) < 0) { | 1585 | if ((err = snd_emu10k1x_pcm(chip, 2)) < 0) { |
1595 | snd_card_free(card); | 1586 | snd_card_free(card); |
1596 | return err; | 1587 | return err; |
1597 | } | 1588 | } |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index eb5c0aba41c1..56fc47bd6dba 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -2641,14 +2641,11 @@ static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file) | |||
2641 | return 0; | 2641 | return 0; |
2642 | } | 2642 | } |
2643 | 2643 | ||
2644 | int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, | 2644 | int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device) |
2645 | struct snd_hwdep **rhwdep) | ||
2646 | { | 2645 | { |
2647 | struct snd_hwdep *hw; | 2646 | struct snd_hwdep *hw; |
2648 | int err; | 2647 | int err; |
2649 | 2648 | ||
2650 | if (rhwdep) | ||
2651 | *rhwdep = NULL; | ||
2652 | if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0) | 2649 | if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0) |
2653 | return err; | 2650 | return err; |
2654 | strcpy(hw->name, "EMU10K1 (FX8010)"); | 2651 | strcpy(hw->name, "EMU10K1 (FX8010)"); |
@@ -2657,8 +2654,6 @@ int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, | |||
2657 | hw->ops.ioctl = snd_emu10k1_fx8010_ioctl; | 2654 | hw->ops.ioctl = snd_emu10k1_fx8010_ioctl; |
2658 | hw->ops.release = snd_emu10k1_fx8010_release; | 2655 | hw->ops.release = snd_emu10k1_fx8010_release; |
2659 | hw->private_data = emu; | 2656 | hw->private_data = emu; |
2660 | if (rhwdep) | ||
2661 | *rhwdep = hw; | ||
2662 | return 0; | 2657 | return 0; |
2663 | } | 2658 | } |
2664 | 2659 | ||
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index f82481bd2542..0dc07385af0e 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c | |||
@@ -1400,15 +1400,12 @@ static struct snd_pcm_ops snd_emu10k1_efx_playback_ops = { | |||
1400 | .page = snd_pcm_sgbuf_ops_page, | 1400 | .page = snd_pcm_sgbuf_ops_page, |
1401 | }; | 1401 | }; |
1402 | 1402 | ||
1403 | int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm) | 1403 | int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device) |
1404 | { | 1404 | { |
1405 | struct snd_pcm *pcm; | 1405 | struct snd_pcm *pcm; |
1406 | struct snd_pcm_substream *substream; | 1406 | struct snd_pcm_substream *substream; |
1407 | int err; | 1407 | int err; |
1408 | 1408 | ||
1409 | if (rpcm) | ||
1410 | *rpcm = NULL; | ||
1411 | |||
1412 | if ((err = snd_pcm_new(emu->card, "emu10k1", device, 32, 1, &pcm)) < 0) | 1409 | if ((err = snd_pcm_new(emu->card, "emu10k1", device, 32, 1, &pcm)) < 0) |
1413 | return err; | 1410 | return err; |
1414 | 1411 | ||
@@ -1429,22 +1426,15 @@ int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm) | |||
1429 | for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next) | 1426 | for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next) |
1430 | snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024); | 1427 | snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024); |
1431 | 1428 | ||
1432 | if (rpcm) | ||
1433 | *rpcm = pcm; | ||
1434 | |||
1435 | return 0; | 1429 | return 0; |
1436 | } | 1430 | } |
1437 | 1431 | ||
1438 | int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device, | 1432 | int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device) |
1439 | struct snd_pcm **rpcm) | ||
1440 | { | 1433 | { |
1441 | struct snd_pcm *pcm; | 1434 | struct snd_pcm *pcm; |
1442 | struct snd_pcm_substream *substream; | 1435 | struct snd_pcm_substream *substream; |
1443 | int err; | 1436 | int err; |
1444 | 1437 | ||
1445 | if (rpcm) | ||
1446 | *rpcm = NULL; | ||
1447 | |||
1448 | if ((err = snd_pcm_new(emu->card, "emu10k1", device, 1, 0, &pcm)) < 0) | 1438 | if ((err = snd_pcm_new(emu->card, "emu10k1", device, 1, 0, &pcm)) < 0) |
1449 | return err; | 1439 | return err; |
1450 | 1440 | ||
@@ -1461,9 +1451,6 @@ int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device, | |||
1461 | if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0) | 1451 | if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0) |
1462 | return err; | 1452 | return err; |
1463 | 1453 | ||
1464 | if (rpcm) | ||
1465 | *rpcm = pcm; | ||
1466 | |||
1467 | return 0; | 1454 | return 0; |
1468 | } | 1455 | } |
1469 | 1456 | ||
@@ -1479,15 +1466,11 @@ static struct snd_pcm_ops snd_emu10k1_capture_mic_ops = { | |||
1479 | .pointer = snd_emu10k1_capture_pointer, | 1466 | .pointer = snd_emu10k1_capture_pointer, |
1480 | }; | 1467 | }; |
1481 | 1468 | ||
1482 | int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device, | 1469 | int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device) |
1483 | struct snd_pcm **rpcm) | ||
1484 | { | 1470 | { |
1485 | struct snd_pcm *pcm; | 1471 | struct snd_pcm *pcm; |
1486 | int err; | 1472 | int err; |
1487 | 1473 | ||
1488 | if (rpcm) | ||
1489 | *rpcm = NULL; | ||
1490 | |||
1491 | if ((err = snd_pcm_new(emu->card, "emu10k1 mic", device, 0, 1, &pcm)) < 0) | 1474 | if ((err = snd_pcm_new(emu->card, "emu10k1 mic", device, 0, 1, &pcm)) < 0) |
1492 | return err; | 1475 | return err; |
1493 | 1476 | ||
@@ -1501,8 +1484,6 @@ int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device, | |||
1501 | 1484 | ||
1502 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024); | 1485 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024); |
1503 | 1486 | ||
1504 | if (rpcm) | ||
1505 | *rpcm = pcm; | ||
1506 | return 0; | 1487 | return 0; |
1507 | } | 1488 | } |
1508 | 1489 | ||
@@ -1822,16 +1803,12 @@ static struct snd_pcm_ops snd_emu10k1_fx8010_playback_ops = { | |||
1822 | .ack = snd_emu10k1_fx8010_playback_transfer, | 1803 | .ack = snd_emu10k1_fx8010_playback_transfer, |
1823 | }; | 1804 | }; |
1824 | 1805 | ||
1825 | int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device, | 1806 | int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device) |
1826 | struct snd_pcm **rpcm) | ||
1827 | { | 1807 | { |
1828 | struct snd_pcm *pcm; | 1808 | struct snd_pcm *pcm; |
1829 | struct snd_kcontrol *kctl; | 1809 | struct snd_kcontrol *kctl; |
1830 | int err; | 1810 | int err; |
1831 | 1811 | ||
1832 | if (rpcm) | ||
1833 | *rpcm = NULL; | ||
1834 | |||
1835 | if ((err = snd_pcm_new(emu->card, "emu10k1 efx", device, 8, 1, &pcm)) < 0) | 1812 | if ((err = snd_pcm_new(emu->card, "emu10k1 efx", device, 8, 1, &pcm)) < 0) |
1836 | return err; | 1813 | return err; |
1837 | 1814 | ||
@@ -1843,8 +1820,6 @@ int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device, | |||
1843 | pcm->info_flags = 0; | 1820 | pcm->info_flags = 0; |
1844 | strcpy(pcm->name, "Multichannel Capture/PT Playback"); | 1821 | strcpy(pcm->name, "Multichannel Capture/PT Playback"); |
1845 | emu->pcm_efx = pcm; | 1822 | emu->pcm_efx = pcm; |
1846 | if (rpcm) | ||
1847 | *rpcm = pcm; | ||
1848 | 1823 | ||
1849 | /* EFX capture - record the "FXBUS2" channels, by default we connect the EXTINs | 1824 | /* EFX capture - record the "FXBUS2" channels, by default we connect the EXTINs |
1850 | * to these | 1825 | * to these |
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index 7ef3898a7806..3c60b433de9f 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c | |||
@@ -166,11 +166,8 @@ static struct snd_pcm_hardware snd_p16v_capture_hw = { | |||
166 | static void snd_p16v_pcm_free_substream(struct snd_pcm_runtime *runtime) | 166 | static void snd_p16v_pcm_free_substream(struct snd_pcm_runtime *runtime) |
167 | { | 167 | { |
168 | struct snd_emu10k1_pcm *epcm = runtime->private_data; | 168 | struct snd_emu10k1_pcm *epcm = runtime->private_data; |
169 | 169 | ||
170 | if (epcm) { | 170 | kfree(epcm); |
171 | /* dev_dbg(emu->card->dev, "epcm free: %p\n", epcm); */ | ||
172 | kfree(epcm); | ||
173 | } | ||
174 | } | 171 | } |
175 | 172 | ||
176 | /* open_playback callback */ | 173 | /* open_playback callback */ |
@@ -640,7 +637,7 @@ int snd_p16v_free(struct snd_emu10k1 *chip) | |||
640 | return 0; | 637 | return 0; |
641 | } | 638 | } |
642 | 639 | ||
643 | int snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm) | 640 | int snd_p16v_pcm(struct snd_emu10k1 *emu, int device) |
644 | { | 641 | { |
645 | struct snd_pcm *pcm; | 642 | struct snd_pcm *pcm; |
646 | struct snd_pcm_substream *substream; | 643 | struct snd_pcm_substream *substream; |
@@ -649,8 +646,6 @@ int snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm) | |||
649 | 646 | ||
650 | /* dev_dbg(emu->card->dev, "snd_p16v_pcm called. device=%d\n", device); */ | 647 | /* dev_dbg(emu->card->dev, "snd_p16v_pcm called. device=%d\n", device); */ |
651 | emu->p16v_device_offset = device; | 648 | emu->p16v_device_offset = device; |
652 | if (rpcm) | ||
653 | *rpcm = NULL; | ||
654 | 649 | ||
655 | if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0) | 650 | if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0) |
656 | return err; | 651 | return err; |
@@ -694,9 +689,6 @@ int snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm) | |||
694 | */ | 689 | */ |
695 | } | 690 | } |
696 | 691 | ||
697 | if (rpcm) | ||
698 | *rpcm = pcm; | ||
699 | |||
700 | return 0; | 692 | return 0; |
701 | } | 693 | } |
702 | 694 | ||
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index d94cb3ca7a64..219b8af29a49 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
@@ -1268,14 +1268,11 @@ static const struct snd_pcm_chmap_elem surround_map[] = { | |||
1268 | { } | 1268 | { } |
1269 | }; | 1269 | }; |
1270 | 1270 | ||
1271 | static int snd_ensoniq_pcm(struct ensoniq *ensoniq, int device, | 1271 | static int snd_ensoniq_pcm(struct ensoniq *ensoniq, int device) |
1272 | struct snd_pcm **rpcm) | ||
1273 | { | 1272 | { |
1274 | struct snd_pcm *pcm; | 1273 | struct snd_pcm *pcm; |
1275 | int err; | 1274 | int err; |
1276 | 1275 | ||
1277 | if (rpcm) | ||
1278 | *rpcm = NULL; | ||
1279 | err = snd_pcm_new(ensoniq->card, CHIP_NAME "/1", device, 1, 1, &pcm); | 1276 | err = snd_pcm_new(ensoniq->card, CHIP_NAME "/1", device, 1, 1, &pcm); |
1280 | if (err < 0) | 1277 | if (err < 0) |
1281 | return err; | 1278 | return err; |
@@ -1302,22 +1299,14 @@ static int snd_ensoniq_pcm(struct ensoniq *ensoniq, int device, | |||
1302 | err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, | 1299 | err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
1303 | snd_pcm_std_chmaps, 2, 0, NULL); | 1300 | snd_pcm_std_chmaps, 2, 0, NULL); |
1304 | #endif | 1301 | #endif |
1305 | if (err < 0) | 1302 | return err; |
1306 | return err; | ||
1307 | |||
1308 | if (rpcm) | ||
1309 | *rpcm = pcm; | ||
1310 | return 0; | ||
1311 | } | 1303 | } |
1312 | 1304 | ||
1313 | static int snd_ensoniq_pcm2(struct ensoniq *ensoniq, int device, | 1305 | static int snd_ensoniq_pcm2(struct ensoniq *ensoniq, int device) |
1314 | struct snd_pcm **rpcm) | ||
1315 | { | 1306 | { |
1316 | struct snd_pcm *pcm; | 1307 | struct snd_pcm *pcm; |
1317 | int err; | 1308 | int err; |
1318 | 1309 | ||
1319 | if (rpcm) | ||
1320 | *rpcm = NULL; | ||
1321 | err = snd_pcm_new(ensoniq->card, CHIP_NAME "/2", device, 1, 0, &pcm); | 1310 | err = snd_pcm_new(ensoniq->card, CHIP_NAME "/2", device, 1, 0, &pcm); |
1322 | if (err < 0) | 1311 | if (err < 0) |
1323 | return err; | 1312 | return err; |
@@ -1342,12 +1331,7 @@ static int snd_ensoniq_pcm2(struct ensoniq *ensoniq, int device, | |||
1342 | err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, | 1331 | err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
1343 | surround_map, 2, 0, NULL); | 1332 | surround_map, 2, 0, NULL); |
1344 | #endif | 1333 | #endif |
1345 | if (err < 0) | 1334 | return err; |
1346 | return err; | ||
1347 | |||
1348 | if (rpcm) | ||
1349 | *rpcm = pcm; | ||
1350 | return 0; | ||
1351 | } | 1335 | } |
1352 | 1336 | ||
1353 | /* | 1337 | /* |
@@ -2049,7 +2033,6 @@ static void snd_ensoniq_chip_init(struct ensoniq *ensoniq) | |||
2049 | #ifdef CONFIG_PM_SLEEP | 2033 | #ifdef CONFIG_PM_SLEEP |
2050 | static int snd_ensoniq_suspend(struct device *dev) | 2034 | static int snd_ensoniq_suspend(struct device *dev) |
2051 | { | 2035 | { |
2052 | struct pci_dev *pci = to_pci_dev(dev); | ||
2053 | struct snd_card *card = dev_get_drvdata(dev); | 2036 | struct snd_card *card = dev_get_drvdata(dev); |
2054 | struct ensoniq *ensoniq = card->private_data; | 2037 | struct ensoniq *ensoniq = card->private_data; |
2055 | 2038 | ||
@@ -2070,28 +2053,14 @@ static int snd_ensoniq_suspend(struct device *dev) | |||
2070 | udelay(100); | 2053 | udelay(100); |
2071 | snd_ak4531_suspend(ensoniq->u.es1370.ak4531); | 2054 | snd_ak4531_suspend(ensoniq->u.es1370.ak4531); |
2072 | #endif | 2055 | #endif |
2073 | |||
2074 | pci_disable_device(pci); | ||
2075 | pci_save_state(pci); | ||
2076 | pci_set_power_state(pci, PCI_D3hot); | ||
2077 | return 0; | 2056 | return 0; |
2078 | } | 2057 | } |
2079 | 2058 | ||
2080 | static int snd_ensoniq_resume(struct device *dev) | 2059 | static int snd_ensoniq_resume(struct device *dev) |
2081 | { | 2060 | { |
2082 | struct pci_dev *pci = to_pci_dev(dev); | ||
2083 | struct snd_card *card = dev_get_drvdata(dev); | 2061 | struct snd_card *card = dev_get_drvdata(dev); |
2084 | struct ensoniq *ensoniq = card->private_data; | 2062 | struct ensoniq *ensoniq = card->private_data; |
2085 | 2063 | ||
2086 | pci_set_power_state(pci, PCI_D0); | ||
2087 | pci_restore_state(pci); | ||
2088 | if (pci_enable_device(pci) < 0) { | ||
2089 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
2090 | snd_card_disconnect(card); | ||
2091 | return -EIO; | ||
2092 | } | ||
2093 | pci_set_master(pci); | ||
2094 | |||
2095 | snd_ensoniq_chip_init(ensoniq); | 2064 | snd_ensoniq_chip_init(ensoniq); |
2096 | 2065 | ||
2097 | #ifdef CHIP1371 | 2066 | #ifdef CHIP1371 |
@@ -2362,14 +2331,11 @@ static struct snd_rawmidi_ops snd_ensoniq_midi_input = | |||
2362 | .trigger = snd_ensoniq_midi_input_trigger, | 2331 | .trigger = snd_ensoniq_midi_input_trigger, |
2363 | }; | 2332 | }; |
2364 | 2333 | ||
2365 | static int snd_ensoniq_midi(struct ensoniq *ensoniq, int device, | 2334 | static int snd_ensoniq_midi(struct ensoniq *ensoniq, int device) |
2366 | struct snd_rawmidi **rrawmidi) | ||
2367 | { | 2335 | { |
2368 | struct snd_rawmidi *rmidi; | 2336 | struct snd_rawmidi *rmidi; |
2369 | int err; | 2337 | int err; |
2370 | 2338 | ||
2371 | if (rrawmidi) | ||
2372 | *rrawmidi = NULL; | ||
2373 | if ((err = snd_rawmidi_new(ensoniq->card, "ES1370/1", device, 1, 1, &rmidi)) < 0) | 2339 | if ((err = snd_rawmidi_new(ensoniq->card, "ES1370/1", device, 1, 1, &rmidi)) < 0) |
2374 | return err; | 2340 | return err; |
2375 | strcpy(rmidi->name, CHIP_NAME); | 2341 | strcpy(rmidi->name, CHIP_NAME); |
@@ -2379,8 +2345,6 @@ static int snd_ensoniq_midi(struct ensoniq *ensoniq, int device, | |||
2379 | SNDRV_RAWMIDI_INFO_DUPLEX; | 2345 | SNDRV_RAWMIDI_INFO_DUPLEX; |
2380 | rmidi->private_data = ensoniq; | 2346 | rmidi->private_data = ensoniq; |
2381 | ensoniq->rmidi = rmidi; | 2347 | ensoniq->rmidi = rmidi; |
2382 | if (rrawmidi) | ||
2383 | *rrawmidi = rmidi; | ||
2384 | return 0; | 2348 | return 0; |
2385 | } | 2349 | } |
2386 | 2350 | ||
@@ -2462,15 +2426,15 @@ static int snd_audiopci_probe(struct pci_dev *pci, | |||
2462 | return err; | 2426 | return err; |
2463 | } | 2427 | } |
2464 | #endif | 2428 | #endif |
2465 | if ((err = snd_ensoniq_pcm(ensoniq, 0, NULL)) < 0) { | 2429 | if ((err = snd_ensoniq_pcm(ensoniq, 0)) < 0) { |
2466 | snd_card_free(card); | 2430 | snd_card_free(card); |
2467 | return err; | 2431 | return err; |
2468 | } | 2432 | } |
2469 | if ((err = snd_ensoniq_pcm2(ensoniq, 1, NULL)) < 0) { | 2433 | if ((err = snd_ensoniq_pcm2(ensoniq, 1)) < 0) { |
2470 | snd_card_free(card); | 2434 | snd_card_free(card); |
2471 | return err; | 2435 | return err; |
2472 | } | 2436 | } |
2473 | if ((err = snd_ensoniq_midi(ensoniq, 0, NULL)) < 0) { | 2437 | if ((err = snd_ensoniq_midi(ensoniq, 0)) < 0) { |
2474 | snd_card_free(card); | 2438 | snd_card_free(card); |
2475 | return err; | 2439 | return err; |
2476 | } | 2440 | } |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 0fc46eb4e251..a01454b545a0 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c | |||
@@ -1454,7 +1454,6 @@ static unsigned char saved_regs[SAVED_REG_SIZE+1] = { | |||
1454 | 1454 | ||
1455 | static int es1938_suspend(struct device *dev) | 1455 | static int es1938_suspend(struct device *dev) |
1456 | { | 1456 | { |
1457 | struct pci_dev *pci = to_pci_dev(dev); | ||
1458 | struct snd_card *card = dev_get_drvdata(dev); | 1457 | struct snd_card *card = dev_get_drvdata(dev); |
1459 | struct es1938 *chip = card->private_data; | 1458 | struct es1938 *chip = card->private_data; |
1460 | unsigned char *s, *d; | 1459 | unsigned char *s, *d; |
@@ -1471,9 +1470,6 @@ static int es1938_suspend(struct device *dev) | |||
1471 | free_irq(chip->irq, chip); | 1470 | free_irq(chip->irq, chip); |
1472 | chip->irq = -1; | 1471 | chip->irq = -1; |
1473 | } | 1472 | } |
1474 | pci_disable_device(pci); | ||
1475 | pci_save_state(pci); | ||
1476 | pci_set_power_state(pci, PCI_D3hot); | ||
1477 | return 0; | 1473 | return 0; |
1478 | } | 1474 | } |
1479 | 1475 | ||
@@ -1484,14 +1480,6 @@ static int es1938_resume(struct device *dev) | |||
1484 | struct es1938 *chip = card->private_data; | 1480 | struct es1938 *chip = card->private_data; |
1485 | unsigned char *s, *d; | 1481 | unsigned char *s, *d; |
1486 | 1482 | ||
1487 | pci_set_power_state(pci, PCI_D0); | ||
1488 | pci_restore_state(pci); | ||
1489 | if (pci_enable_device(pci) < 0) { | ||
1490 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
1491 | snd_card_disconnect(card); | ||
1492 | return -EIO; | ||
1493 | } | ||
1494 | |||
1495 | if (request_irq(pci->irq, snd_es1938_interrupt, | 1483 | if (request_irq(pci->irq, snd_es1938_interrupt, |
1496 | IRQF_SHARED, KBUILD_MODNAME, chip)) { | 1484 | IRQF_SHARED, KBUILD_MODNAME, chip)) { |
1497 | dev_err(dev, "unable to grab IRQ %d, disabling device\n", | 1485 | dev_err(dev, "unable to grab IRQ %d, disabling device\n", |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 6039700f8579..631be029f8c0 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -2383,7 +2383,6 @@ static void snd_es1968_start_irq(struct es1968 *chip) | |||
2383 | */ | 2383 | */ |
2384 | static int es1968_suspend(struct device *dev) | 2384 | static int es1968_suspend(struct device *dev) |
2385 | { | 2385 | { |
2386 | struct pci_dev *pci = to_pci_dev(dev); | ||
2387 | struct snd_card *card = dev_get_drvdata(dev); | 2386 | struct snd_card *card = dev_get_drvdata(dev); |
2388 | struct es1968 *chip = card->private_data; | 2387 | struct es1968 *chip = card->private_data; |
2389 | 2388 | ||
@@ -2396,16 +2395,11 @@ static int es1968_suspend(struct device *dev) | |||
2396 | snd_pcm_suspend_all(chip->pcm); | 2395 | snd_pcm_suspend_all(chip->pcm); |
2397 | snd_ac97_suspend(chip->ac97); | 2396 | snd_ac97_suspend(chip->ac97); |
2398 | snd_es1968_bob_stop(chip); | 2397 | snd_es1968_bob_stop(chip); |
2399 | |||
2400 | pci_disable_device(pci); | ||
2401 | pci_save_state(pci); | ||
2402 | pci_set_power_state(pci, PCI_D3hot); | ||
2403 | return 0; | 2398 | return 0; |
2404 | } | 2399 | } |
2405 | 2400 | ||
2406 | static int es1968_resume(struct device *dev) | 2401 | static int es1968_resume(struct device *dev) |
2407 | { | 2402 | { |
2408 | struct pci_dev *pci = to_pci_dev(dev); | ||
2409 | struct snd_card *card = dev_get_drvdata(dev); | 2403 | struct snd_card *card = dev_get_drvdata(dev); |
2410 | struct es1968 *chip = card->private_data; | 2404 | struct es1968 *chip = card->private_data; |
2411 | struct esschan *es; | 2405 | struct esschan *es; |
@@ -2413,16 +2407,6 @@ static int es1968_resume(struct device *dev) | |||
2413 | if (! chip->do_pm) | 2407 | if (! chip->do_pm) |
2414 | return 0; | 2408 | return 0; |
2415 | 2409 | ||
2416 | /* restore all our config */ | ||
2417 | pci_set_power_state(pci, PCI_D0); | ||
2418 | pci_restore_state(pci); | ||
2419 | if (pci_enable_device(pci) < 0) { | ||
2420 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
2421 | snd_card_disconnect(card); | ||
2422 | return -EIO; | ||
2423 | } | ||
2424 | pci_set_master(pci); | ||
2425 | |||
2426 | snd_es1968_chip_init(chip); | 2410 | snd_es1968_chip_init(chip); |
2427 | 2411 | ||
2428 | /* need to restore the base pointers.. */ | 2412 | /* need to restore the base pointers.. */ |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index d167afffce5f..1fdd92b6f18f 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -2,8 +2,6 @@ | |||
2 | * The driver for the ForteMedia FM801 based soundcards | 2 | * The driver for the ForteMedia FM801 based soundcards |
3 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> | 3 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> |
4 | * | 4 | * |
5 | * Support FM only card by Andy Shevchenko <andy@smile.org.ua> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or | 7 | * the Free Software Foundation; either version 2 of the License, or |
@@ -14,10 +12,6 @@ | |||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
16 | * | 14 | * |
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | 15 | */ |
22 | 16 | ||
23 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
@@ -704,13 +698,11 @@ static struct snd_pcm_ops snd_fm801_capture_ops = { | |||
704 | .pointer = snd_fm801_capture_pointer, | 698 | .pointer = snd_fm801_capture_pointer, |
705 | }; | 699 | }; |
706 | 700 | ||
707 | static int snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pcm **rpcm) | 701 | static int snd_fm801_pcm(struct fm801 *chip, int device) |
708 | { | 702 | { |
709 | struct snd_pcm *pcm; | 703 | struct snd_pcm *pcm; |
710 | int err; | 704 | int err; |
711 | 705 | ||
712 | if (rpcm) | ||
713 | *rpcm = NULL; | ||
714 | if ((err = snd_pcm_new(chip->card, "FM801", device, 1, 1, &pcm)) < 0) | 706 | if ((err = snd_pcm_new(chip->card, "FM801", device, 1, 1, &pcm)) < 0) |
715 | return err; | 707 | return err; |
716 | 708 | ||
@@ -726,16 +718,10 @@ static int snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pcm **rpcm) | |||
726 | snd_dma_pci_data(chip->pci), | 718 | snd_dma_pci_data(chip->pci), |
727 | chip->multichannel ? 128*1024 : 64*1024, 128*1024); | 719 | chip->multichannel ? 128*1024 : 64*1024, 128*1024); |
728 | 720 | ||
729 | err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, | 721 | return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
730 | snd_pcm_alt_chmaps, | 722 | snd_pcm_alt_chmaps, |
731 | chip->multichannel ? 6 : 2, 0, | 723 | chip->multichannel ? 6 : 2, 0, |
732 | NULL); | 724 | NULL); |
733 | if (err < 0) | ||
734 | return err; | ||
735 | |||
736 | if (rpcm) | ||
737 | *rpcm = pcm; | ||
738 | return 0; | ||
739 | } | 725 | } |
740 | 726 | ||
741 | /* | 727 | /* |
@@ -1186,12 +1172,6 @@ static int snd_fm801_free(struct fm801 *chip) | |||
1186 | v4l2_device_unregister(&chip->v4l2_dev); | 1172 | v4l2_device_unregister(&chip->v4l2_dev); |
1187 | } | 1173 | } |
1188 | #endif | 1174 | #endif |
1189 | if (chip->irq >= 0) | ||
1190 | free_irq(chip->irq, chip); | ||
1191 | pci_release_regions(chip->pci); | ||
1192 | pci_disable_device(chip->pci); | ||
1193 | |||
1194 | kfree(chip); | ||
1195 | return 0; | 1175 | return 0; |
1196 | } | 1176 | } |
1197 | 1177 | ||
@@ -1214,28 +1194,23 @@ static int snd_fm801_create(struct snd_card *card, | |||
1214 | }; | 1194 | }; |
1215 | 1195 | ||
1216 | *rchip = NULL; | 1196 | *rchip = NULL; |
1217 | if ((err = pci_enable_device(pci)) < 0) | 1197 | if ((err = pcim_enable_device(pci)) < 0) |
1218 | return err; | 1198 | return err; |
1219 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 1199 | chip = devm_kzalloc(&pci->dev, sizeof(*chip), GFP_KERNEL); |
1220 | if (chip == NULL) { | 1200 | if (chip == NULL) |
1221 | pci_disable_device(pci); | ||
1222 | return -ENOMEM; | 1201 | return -ENOMEM; |
1223 | } | ||
1224 | spin_lock_init(&chip->reg_lock); | 1202 | spin_lock_init(&chip->reg_lock); |
1225 | chip->card = card; | 1203 | chip->card = card; |
1226 | chip->pci = pci; | 1204 | chip->pci = pci; |
1227 | chip->irq = -1; | 1205 | chip->irq = -1; |
1228 | chip->tea575x_tuner = tea575x_tuner; | 1206 | chip->tea575x_tuner = tea575x_tuner; |
1229 | if ((err = pci_request_regions(pci, "FM801")) < 0) { | 1207 | if ((err = pci_request_regions(pci, "FM801")) < 0) |
1230 | kfree(chip); | ||
1231 | pci_disable_device(pci); | ||
1232 | return err; | 1208 | return err; |
1233 | } | ||
1234 | chip->port = pci_resource_start(pci, 0); | 1209 | chip->port = pci_resource_start(pci, 0); |
1235 | if ((tea575x_tuner & TUNER_ONLY) == 0) { | 1210 | if ((tea575x_tuner & TUNER_ONLY) == 0) { |
1236 | if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED, | 1211 | if (devm_request_irq(&pci->dev, pci->irq, snd_fm801_interrupt, |
1237 | KBUILD_MODNAME, chip)) { | 1212 | IRQF_SHARED, KBUILD_MODNAME, chip)) { |
1238 | dev_err(card->dev, "unable to grab IRQ %d\n", chip->irq); | 1213 | dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); |
1239 | snd_fm801_free(chip); | 1214 | snd_fm801_free(chip); |
1240 | return -EBUSY; | 1215 | return -EBUSY; |
1241 | } | 1216 | } |
@@ -1250,12 +1225,6 @@ static int snd_fm801_create(struct snd_card *card, | |||
1250 | /* init might set tuner access method */ | 1225 | /* init might set tuner access method */ |
1251 | tea575x_tuner = chip->tea575x_tuner; | 1226 | tea575x_tuner = chip->tea575x_tuner; |
1252 | 1227 | ||
1253 | if (chip->irq >= 0 && (tea575x_tuner & TUNER_ONLY)) { | ||
1254 | pci_clear_master(pci); | ||
1255 | free_irq(chip->irq, chip); | ||
1256 | chip->irq = -1; | ||
1257 | } | ||
1258 | |||
1259 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | 1228 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { |
1260 | snd_fm801_free(chip); | 1229 | snd_fm801_free(chip); |
1261 | return err; | 1230 | return err; |
@@ -1340,7 +1309,7 @@ static int snd_card_fm801_probe(struct pci_dev *pci, | |||
1340 | if (chip->tea575x_tuner & TUNER_ONLY) | 1309 | if (chip->tea575x_tuner & TUNER_ONLY) |
1341 | goto __fm801_tuner_only; | 1310 | goto __fm801_tuner_only; |
1342 | 1311 | ||
1343 | if ((err = snd_fm801_pcm(chip, 0, NULL)) < 0) { | 1312 | if ((err = snd_fm801_pcm(chip, 0)) < 0) { |
1344 | snd_card_free(card); | 1313 | snd_card_free(card); |
1345 | return err; | 1314 | return err; |
1346 | } | 1315 | } |
@@ -1392,7 +1361,6 @@ static unsigned char saved_regs[] = { | |||
1392 | 1361 | ||
1393 | static int snd_fm801_suspend(struct device *dev) | 1362 | static int snd_fm801_suspend(struct device *dev) |
1394 | { | 1363 | { |
1395 | struct pci_dev *pci = to_pci_dev(dev); | ||
1396 | struct snd_card *card = dev_get_drvdata(dev); | 1364 | struct snd_card *card = dev_get_drvdata(dev); |
1397 | struct fm801 *chip = card->private_data; | 1365 | struct fm801 *chip = card->private_data; |
1398 | int i; | 1366 | int i; |
@@ -1404,29 +1372,15 @@ static int snd_fm801_suspend(struct device *dev) | |||
1404 | for (i = 0; i < ARRAY_SIZE(saved_regs); i++) | 1372 | for (i = 0; i < ARRAY_SIZE(saved_regs); i++) |
1405 | chip->saved_regs[i] = inw(chip->port + saved_regs[i]); | 1373 | chip->saved_regs[i] = inw(chip->port + saved_regs[i]); |
1406 | /* FIXME: tea575x suspend */ | 1374 | /* FIXME: tea575x suspend */ |
1407 | |||
1408 | pci_disable_device(pci); | ||
1409 | pci_save_state(pci); | ||
1410 | pci_set_power_state(pci, PCI_D3hot); | ||
1411 | return 0; | 1375 | return 0; |
1412 | } | 1376 | } |
1413 | 1377 | ||
1414 | static int snd_fm801_resume(struct device *dev) | 1378 | static int snd_fm801_resume(struct device *dev) |
1415 | { | 1379 | { |
1416 | struct pci_dev *pci = to_pci_dev(dev); | ||
1417 | struct snd_card *card = dev_get_drvdata(dev); | 1380 | struct snd_card *card = dev_get_drvdata(dev); |
1418 | struct fm801 *chip = card->private_data; | 1381 | struct fm801 *chip = card->private_data; |
1419 | int i; | 1382 | int i; |
1420 | 1383 | ||
1421 | pci_set_power_state(pci, PCI_D0); | ||
1422 | pci_restore_state(pci); | ||
1423 | if (pci_enable_device(pci) < 0) { | ||
1424 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
1425 | snd_card_disconnect(card); | ||
1426 | return -EIO; | ||
1427 | } | ||
1428 | pci_set_master(pci); | ||
1429 | |||
1430 | snd_fm801_chip_init(chip, 1); | 1384 | snd_fm801_chip_init(chip, 1); |
1431 | snd_ac97_resume(chip->ac97); | 1385 | snd_ac97_resume(chip->ac97); |
1432 | snd_ac97_resume(chip->ac97_sec); | 1386 | snd_ac97_resume(chip->ac97_sec); |
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index ebf4c2fb99df..7f0f2c5a4e97 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig | |||
@@ -107,6 +107,7 @@ config SND_HDA_PATCH_LOADER | |||
107 | config SND_HDA_CODEC_REALTEK | 107 | config SND_HDA_CODEC_REALTEK |
108 | tristate "Build Realtek HD-audio codec support" | 108 | tristate "Build Realtek HD-audio codec support" |
109 | select SND_HDA_GENERIC | 109 | select SND_HDA_GENERIC |
110 | select INPUT | ||
110 | help | 111 | help |
111 | Say Y or M here to include Realtek HD-audio codec support in | 112 | Say Y or M here to include Realtek HD-audio codec support in |
112 | snd-hda-intel driver, such as ALC880. | 113 | snd-hda-intel driver, such as ALC880. |
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 1ede82200ee5..3f8706bb3d16 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c | |||
@@ -409,10 +409,10 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
409 | /* | 409 | /* |
410 | * debug prints of the parsed results | 410 | * debug prints of the parsed results |
411 | */ | 411 | */ |
412 | codec_info(codec, "autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n", | 412 | codec_info(codec, "autoconfig for %s: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n", |
413 | cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], | 413 | codec->chip_name, cfg->line_outs, cfg->line_out_pins[0], |
414 | cfg->line_out_pins[2], cfg->line_out_pins[3], | 414 | cfg->line_out_pins[1], cfg->line_out_pins[2], |
415 | cfg->line_out_pins[4], | 415 | cfg->line_out_pins[3], cfg->line_out_pins[4], |
416 | cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" : | 416 | cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" : |
417 | (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ? | 417 | (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ? |
418 | "speaker" : "line")); | 418 | "speaker" : "line")); |
@@ -920,6 +920,8 @@ void snd_hda_pick_pin_fixup(struct hda_codec *codec, | |||
920 | codec->fixup_id = pq->value; | 920 | codec->fixup_id = pq->value; |
921 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 921 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
922 | codec->fixup_name = pq->name; | 922 | codec->fixup_name = pq->name; |
923 | codec_dbg(codec, "%s: picked fixup %s (pin match)\n", | ||
924 | codec->chip_name, codec->fixup_name); | ||
923 | #endif | 925 | #endif |
924 | codec->fixup_list = fixlist; | 926 | codec->fixup_list = fixlist; |
925 | return; | 927 | return; |
@@ -960,6 +962,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec, | |||
960 | codec->fixup_list = NULL; | 962 | codec->fixup_list = NULL; |
961 | codec->fixup_name = NULL; | 963 | codec->fixup_name = NULL; |
962 | codec->fixup_id = HDA_FIXUP_ID_NO_FIXUP; | 964 | codec->fixup_id = HDA_FIXUP_ID_NO_FIXUP; |
965 | codec_dbg(codec, "%s: picked no fixup (nofixup specified)\n", | ||
966 | codec->chip_name); | ||
963 | return; | 967 | return; |
964 | } | 968 | } |
965 | 969 | ||
@@ -969,6 +973,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec, | |||
969 | codec->fixup_id = models->id; | 973 | codec->fixup_id = models->id; |
970 | codec->fixup_name = models->name; | 974 | codec->fixup_name = models->name; |
971 | codec->fixup_list = fixlist; | 975 | codec->fixup_list = fixlist; |
976 | codec_dbg(codec, "%s: picked fixup %s (model specified)\n", | ||
977 | codec->chip_name, codec->fixup_name); | ||
972 | return; | 978 | return; |
973 | } | 979 | } |
974 | models++; | 980 | models++; |
@@ -980,6 +986,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec, | |||
980 | id = q->value; | 986 | id = q->value; |
981 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 987 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
982 | name = q->name; | 988 | name = q->name; |
989 | codec_dbg(codec, "%s: picked fixup %s (PCI SSID%s)\n", | ||
990 | codec->chip_name, name, q->subdevice_mask ? "" : " - vendor generic"); | ||
983 | #endif | 991 | #endif |
984 | } | 992 | } |
985 | } | 993 | } |
@@ -992,6 +1000,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec, | |||
992 | id = q->value; | 1000 | id = q->value; |
993 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 1001 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
994 | name = q->name; | 1002 | name = q->name; |
1003 | codec_dbg(codec, "%s: picked fixup %s (codec SSID)\n", | ||
1004 | codec->chip_name, name); | ||
995 | #endif | 1005 | #endif |
996 | break; | 1006 | break; |
997 | } | 1007 | } |
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 0cfc9c8c4b4e..657b604e1a2b 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c | |||
@@ -1993,4 +1993,4 @@ void azx_notifier_unregister(struct azx *chip) | |||
1993 | EXPORT_SYMBOL_GPL(azx_notifier_unregister); | 1993 | EXPORT_SYMBOL_GPL(azx_notifier_unregister); |
1994 | 1994 | ||
1995 | MODULE_LICENSE("GPL"); | 1995 | MODULE_LICENSE("GPL"); |
1996 | MODULE_DESCRIPTION("Common HDA driver funcitons"); | 1996 | MODULE_DESCRIPTION("Common HDA driver functions"); |
diff --git a/sound/pci/hda/hda_i915.c b/sound/pci/hda/hda_i915.c index d4d0375ac181..714894527e06 100644 --- a/sound/pci/hda/hda_i915.c +++ b/sound/pci/hda/hda_i915.c | |||
@@ -18,10 +18,12 @@ | |||
18 | 18 | ||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/pci.h> | ||
22 | #include <linux/component.h> | ||
23 | #include <drm/i915_component.h> | ||
21 | #include <sound/core.h> | 24 | #include <sound/core.h> |
22 | #include <drm/i915_powerwell.h> | ||
23 | #include "hda_priv.h" | 25 | #include "hda_priv.h" |
24 | #include "hda_i915.h" | 26 | #include "hda_intel.h" |
25 | 27 | ||
26 | /* Intel HSW/BDW display HDA controller Extended Mode registers. | 28 | /* Intel HSW/BDW display HDA controller Extended Mode registers. |
27 | * EM4 (M value) and EM5 (N Value) are used to convert CDClk (Core Display | 29 | * EM4 (M value) and EM5 (N Value) are used to convert CDClk (Core Display |
@@ -31,32 +33,33 @@ | |||
31 | #define AZX_REG_EM4 0x100c | 33 | #define AZX_REG_EM4 0x100c |
32 | #define AZX_REG_EM5 0x1010 | 34 | #define AZX_REG_EM5 0x1010 |
33 | 35 | ||
34 | static int (*get_power)(void); | 36 | int hda_display_power(struct hda_intel *hda, bool enable) |
35 | static int (*put_power)(void); | ||
36 | static int (*get_cdclk)(void); | ||
37 | |||
38 | int hda_display_power(bool enable) | ||
39 | { | 37 | { |
40 | if (!get_power || !put_power) | 38 | struct i915_audio_component *acomp = &hda->audio_component; |
39 | |||
40 | if (!acomp->ops) | ||
41 | return -ENODEV; | 41 | return -ENODEV; |
42 | 42 | ||
43 | pr_debug("HDA display power %s \n", | 43 | dev_dbg(&hda->chip.pci->dev, "display power %s\n", |
44 | enable ? "Enable" : "Disable"); | 44 | enable ? "enable" : "disable"); |
45 | if (enable) | 45 | if (enable) |
46 | return get_power(); | 46 | acomp->ops->get_power(acomp->dev); |
47 | else | 47 | else |
48 | return put_power(); | 48 | acomp->ops->put_power(acomp->dev); |
49 | |||
50 | return 0; | ||
49 | } | 51 | } |
50 | 52 | ||
51 | void haswell_set_bclk(struct azx *chip) | 53 | void haswell_set_bclk(struct hda_intel *hda) |
52 | { | 54 | { |
53 | int cdclk_freq; | 55 | int cdclk_freq; |
54 | unsigned int bclk_m, bclk_n; | 56 | unsigned int bclk_m, bclk_n; |
57 | struct i915_audio_component *acomp = &hda->audio_component; | ||
55 | 58 | ||
56 | if (!get_cdclk) | 59 | if (!acomp->ops) |
57 | return; | 60 | return; |
58 | 61 | ||
59 | cdclk_freq = get_cdclk(); | 62 | cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev); |
60 | switch (cdclk_freq) { | 63 | switch (cdclk_freq) { |
61 | case 337500: | 64 | case 337500: |
62 | bclk_m = 16; | 65 | bclk_m = 16; |
@@ -80,51 +83,108 @@ void haswell_set_bclk(struct azx *chip) | |||
80 | break; | 83 | break; |
81 | } | 84 | } |
82 | 85 | ||
83 | azx_writew(chip, EM4, bclk_m); | 86 | azx_writew(&hda->chip, EM4, bclk_m); |
84 | azx_writew(chip, EM5, bclk_n); | 87 | azx_writew(&hda->chip, EM5, bclk_n); |
85 | } | 88 | } |
86 | 89 | ||
87 | 90 | static int hda_component_master_bind(struct device *dev) | |
88 | int hda_i915_init(void) | ||
89 | { | 91 | { |
90 | int err = 0; | 92 | struct snd_card *card = dev_get_drvdata(dev); |
91 | 93 | struct azx *chip = card->private_data; | |
92 | get_power = symbol_request(i915_request_power_well); | 94 | struct hda_intel *hda = container_of(chip, struct hda_intel, chip); |
93 | if (!get_power) { | 95 | struct i915_audio_component *acomp = &hda->audio_component; |
94 | pr_warn("hda-i915: get_power symbol get fail\n"); | 96 | int ret; |
95 | return -ENODEV; | 97 | |
98 | ret = component_bind_all(dev, acomp); | ||
99 | if (ret < 0) | ||
100 | return ret; | ||
101 | |||
102 | if (WARN_ON(!(acomp->dev && acomp->ops && acomp->ops->get_power && | ||
103 | acomp->ops->put_power && acomp->ops->get_cdclk_freq))) { | ||
104 | ret = -EINVAL; | ||
105 | goto out_unbind; | ||
96 | } | 106 | } |
97 | 107 | ||
98 | put_power = symbol_request(i915_release_power_well); | 108 | /* |
99 | if (!put_power) { | 109 | * Atm, we don't support dynamic unbinding initiated by the child |
100 | symbol_put(i915_request_power_well); | 110 | * component, so pin its containing module until we unbind. |
101 | get_power = NULL; | 111 | */ |
102 | return -ENODEV; | 112 | if (!try_module_get(acomp->ops->owner)) { |
113 | ret = -ENODEV; | ||
114 | goto out_unbind; | ||
103 | } | 115 | } |
104 | 116 | ||
105 | get_cdclk = symbol_request(i915_get_cdclk_freq); | 117 | return 0; |
106 | if (!get_cdclk) /* may have abnormal BCLK and audio playback rate */ | ||
107 | pr_warn("hda-i915: get_cdclk symbol get fail\n"); | ||
108 | 118 | ||
109 | pr_debug("HDA driver get symbol successfully from i915 module\n"); | 119 | out_unbind: |
120 | component_unbind_all(dev, acomp); | ||
110 | 121 | ||
111 | return err; | 122 | return ret; |
112 | } | 123 | } |
113 | 124 | ||
114 | int hda_i915_exit(void) | 125 | static void hda_component_master_unbind(struct device *dev) |
115 | { | 126 | { |
116 | if (get_power) { | 127 | struct snd_card *card = dev_get_drvdata(dev); |
117 | symbol_put(i915_request_power_well); | 128 | struct azx *chip = card->private_data; |
118 | get_power = NULL; | 129 | struct hda_intel *hda = container_of(chip, struct hda_intel, chip); |
119 | } | 130 | struct i915_audio_component *acomp = &hda->audio_component; |
120 | if (put_power) { | 131 | |
121 | symbol_put(i915_release_power_well); | 132 | module_put(acomp->ops->owner); |
122 | put_power = NULL; | 133 | component_unbind_all(dev, acomp); |
123 | } | 134 | WARN_ON(acomp->ops || acomp->dev); |
124 | if (get_cdclk) { | 135 | } |
125 | symbol_put(i915_get_cdclk_freq); | 136 | |
126 | get_cdclk = NULL; | 137 | static const struct component_master_ops hda_component_master_ops = { |
138 | .bind = hda_component_master_bind, | ||
139 | .unbind = hda_component_master_unbind, | ||
140 | }; | ||
141 | |||
142 | static int hda_component_master_match(struct device *dev, void *data) | ||
143 | { | ||
144 | /* i915 is the only supported component */ | ||
145 | return !strcmp(dev->driver->name, "i915"); | ||
146 | } | ||
147 | |||
148 | int hda_i915_init(struct hda_intel *hda) | ||
149 | { | ||
150 | struct component_match *match = NULL; | ||
151 | struct device *dev = &hda->chip.pci->dev; | ||
152 | struct i915_audio_component *acomp = &hda->audio_component; | ||
153 | int ret; | ||
154 | |||
155 | component_match_add(dev, &match, hda_component_master_match, hda); | ||
156 | ret = component_master_add_with_match(dev, &hda_component_master_ops, | ||
157 | match); | ||
158 | if (ret < 0) | ||
159 | goto out_err; | ||
160 | |||
161 | /* | ||
162 | * Atm, we don't support deferring the component binding, so make sure | ||
163 | * i915 is loaded and that the binding successfully completes. | ||
164 | */ | ||
165 | request_module("i915"); | ||
166 | |||
167 | if (!acomp->ops) { | ||
168 | ret = -ENODEV; | ||
169 | goto out_master_del; | ||
127 | } | 170 | } |
128 | 171 | ||
172 | dev_dbg(dev, "bound to i915 component master\n"); | ||
173 | |||
174 | return 0; | ||
175 | out_master_del: | ||
176 | component_master_del(dev, &hda_component_master_ops); | ||
177 | out_err: | ||
178 | dev_err(dev, "failed to add i915 component master (%d)\n", ret); | ||
179 | |||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | int hda_i915_exit(struct hda_intel *hda) | ||
184 | { | ||
185 | struct device *dev = &hda->chip.pci->dev; | ||
186 | |||
187 | component_master_del(dev, &hda_component_master_ops); | ||
188 | |||
129 | return 0; | 189 | return 0; |
130 | } | 190 | } |
diff --git a/sound/pci/hda/hda_i915.h b/sound/pci/hda/hda_i915.h deleted file mode 100644 index e6072c627583..000000000000 --- a/sound/pci/hda/hda_i915.h +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License as published by the Free | ||
4 | * Software Foundation; either version 2 of the License, or (at your option) | ||
5 | * any later version. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
8 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
9 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
10 | * more details. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License along with | ||
13 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
14 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
15 | */ | ||
16 | #ifndef __SOUND_HDA_I915_H | ||
17 | #define __SOUND_HDA_I915_H | ||
18 | |||
19 | #ifdef CONFIG_SND_HDA_I915 | ||
20 | int hda_display_power(bool enable); | ||
21 | void haswell_set_bclk(struct azx *chip); | ||
22 | int hda_i915_init(void); | ||
23 | int hda_i915_exit(void); | ||
24 | #else | ||
25 | static inline int hda_display_power(bool enable) { return 0; } | ||
26 | static inline void haswell_set_bclk(struct azx *chip) { return; } | ||
27 | static inline int hda_i915_init(void) | ||
28 | { | ||
29 | return -ENODEV; | ||
30 | } | ||
31 | static inline int hda_i915_exit(void) | ||
32 | { | ||
33 | return 0; | ||
34 | } | ||
35 | #endif | ||
36 | |||
37 | #endif | ||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d426a0bd6a5f..36d2f20db7a4 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -63,7 +63,7 @@ | |||
63 | #include "hda_codec.h" | 63 | #include "hda_codec.h" |
64 | #include "hda_controller.h" | 64 | #include "hda_controller.h" |
65 | #include "hda_priv.h" | 65 | #include "hda_priv.h" |
66 | #include "hda_i915.h" | 66 | #include "hda_intel.h" |
67 | 67 | ||
68 | /* position fix mode */ | 68 | /* position fix mode */ |
69 | enum { | 69 | enum { |
@@ -354,31 +354,6 @@ static char *driver_short_names[] = { | |||
354 | [AZX_DRIVER_GENERIC] = "HD-Audio Generic", | 354 | [AZX_DRIVER_GENERIC] = "HD-Audio Generic", |
355 | }; | 355 | }; |
356 | 356 | ||
357 | struct hda_intel { | ||
358 | struct azx chip; | ||
359 | |||
360 | /* for pending irqs */ | ||
361 | struct work_struct irq_pending_work; | ||
362 | |||
363 | /* sync probing */ | ||
364 | struct completion probe_wait; | ||
365 | struct work_struct probe_work; | ||
366 | |||
367 | /* card list (for power_save trigger) */ | ||
368 | struct list_head list; | ||
369 | |||
370 | /* extra flags */ | ||
371 | unsigned int irq_pending_warned:1; | ||
372 | |||
373 | /* VGA-switcheroo setup */ | ||
374 | unsigned int use_vga_switcheroo:1; | ||
375 | unsigned int vga_switcheroo_registered:1; | ||
376 | unsigned int init_failed:1; /* delayed init failed */ | ||
377 | |||
378 | /* secondary power domain for hdmi audio under vga device */ | ||
379 | struct dev_pm_domain hdmi_pm_domain; | ||
380 | }; | ||
381 | |||
382 | #ifdef CONFIG_X86 | 357 | #ifdef CONFIG_X86 |
383 | static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on) | 358 | static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on) |
384 | { | 359 | { |
@@ -795,7 +770,6 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) | |||
795 | */ | 770 | */ |
796 | static int azx_suspend(struct device *dev) | 771 | static int azx_suspend(struct device *dev) |
797 | { | 772 | { |
798 | struct pci_dev *pci = to_pci_dev(dev); | ||
799 | struct snd_card *card = dev_get_drvdata(dev); | 773 | struct snd_card *card = dev_get_drvdata(dev); |
800 | struct azx *chip; | 774 | struct azx *chip; |
801 | struct hda_intel *hda; | 775 | struct hda_intel *hda; |
@@ -824,11 +798,8 @@ static int azx_suspend(struct device *dev) | |||
824 | 798 | ||
825 | if (chip->msi) | 799 | if (chip->msi) |
826 | pci_disable_msi(chip->pci); | 800 | pci_disable_msi(chip->pci); |
827 | pci_disable_device(pci); | ||
828 | pci_save_state(pci); | ||
829 | pci_set_power_state(pci, PCI_D3hot); | ||
830 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | 801 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) |
831 | hda_display_power(false); | 802 | hda_display_power(hda, false); |
832 | return 0; | 803 | return 0; |
833 | } | 804 | } |
834 | 805 | ||
@@ -848,18 +819,9 @@ static int azx_resume(struct device *dev) | |||
848 | return 0; | 819 | return 0; |
849 | 820 | ||
850 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { | 821 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { |
851 | hda_display_power(true); | 822 | hda_display_power(hda, true); |
852 | haswell_set_bclk(chip); | 823 | haswell_set_bclk(hda); |
853 | } | 824 | } |
854 | pci_set_power_state(pci, PCI_D0); | ||
855 | pci_restore_state(pci); | ||
856 | if (pci_enable_device(pci) < 0) { | ||
857 | dev_err(chip->card->dev, | ||
858 | "pci_enable_device failed, disabling device\n"); | ||
859 | snd_card_disconnect(card); | ||
860 | return -EIO; | ||
861 | } | ||
862 | pci_set_master(pci); | ||
863 | if (chip->msi) | 825 | if (chip->msi) |
864 | if (pci_enable_msi(pci) < 0) | 826 | if (pci_enable_msi(pci) < 0) |
865 | chip->msi = 0; | 827 | chip->msi = 0; |
@@ -901,7 +863,7 @@ static int azx_runtime_suspend(struct device *dev) | |||
901 | azx_enter_link_reset(chip); | 863 | azx_enter_link_reset(chip); |
902 | azx_clear_irq_pending(chip); | 864 | azx_clear_irq_pending(chip); |
903 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | 865 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) |
904 | hda_display_power(false); | 866 | hda_display_power(hda, false); |
905 | 867 | ||
906 | return 0; | 868 | return 0; |
907 | } | 869 | } |
@@ -927,8 +889,8 @@ static int azx_runtime_resume(struct device *dev) | |||
927 | return 0; | 889 | return 0; |
928 | 890 | ||
929 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { | 891 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { |
930 | hda_display_power(true); | 892 | hda_display_power(hda, true); |
931 | haswell_set_bclk(chip); | 893 | haswell_set_bclk(hda); |
932 | } | 894 | } |
933 | 895 | ||
934 | /* Read STATESTS before controller reset */ | 896 | /* Read STATESTS before controller reset */ |
@@ -1138,8 +1100,7 @@ static int azx_free(struct azx *chip) | |||
1138 | free_irq(chip->irq, (void*)chip); | 1100 | free_irq(chip->irq, (void*)chip); |
1139 | if (chip->msi) | 1101 | if (chip->msi) |
1140 | pci_disable_msi(chip->pci); | 1102 | pci_disable_msi(chip->pci); |
1141 | if (chip->remap_addr) | 1103 | iounmap(chip->remap_addr); |
1142 | iounmap(chip->remap_addr); | ||
1143 | 1104 | ||
1144 | azx_free_stream_pages(chip); | 1105 | azx_free_stream_pages(chip); |
1145 | if (chip->region_requested) | 1106 | if (chip->region_requested) |
@@ -1150,8 +1111,8 @@ static int azx_free(struct azx *chip) | |||
1150 | release_firmware(chip->fw); | 1111 | release_firmware(chip->fw); |
1151 | #endif | 1112 | #endif |
1152 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { | 1113 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { |
1153 | hda_display_power(false); | 1114 | hda_display_power(hda, false); |
1154 | hda_i915_exit(); | 1115 | hda_i915_exit(hda); |
1155 | } | 1116 | } |
1156 | kfree(hda); | 1117 | kfree(hda); |
1157 | 1118 | ||
@@ -1629,8 +1590,12 @@ static int azx_first_init(struct azx *chip) | |||
1629 | /* initialize chip */ | 1590 | /* initialize chip */ |
1630 | azx_init_pci(chip); | 1591 | azx_init_pci(chip); |
1631 | 1592 | ||
1632 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | 1593 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { |
1633 | haswell_set_bclk(chip); | 1594 | struct hda_intel *hda; |
1595 | |||
1596 | hda = container_of(chip, struct hda_intel, chip); | ||
1597 | haswell_set_bclk(hda); | ||
1598 | } | ||
1634 | 1599 | ||
1635 | azx_init_chip(chip, (probe_only[dev] & 2) == 0); | 1600 | azx_init_chip(chip, (probe_only[dev] & 2) == 0); |
1636 | 1601 | ||
@@ -1910,13 +1875,10 @@ static int azx_probe_continue(struct azx *chip) | |||
1910 | /* Request power well for Haswell HDA controller and codec */ | 1875 | /* Request power well for Haswell HDA controller and codec */ |
1911 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { | 1876 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { |
1912 | #ifdef CONFIG_SND_HDA_I915 | 1877 | #ifdef CONFIG_SND_HDA_I915 |
1913 | err = hda_i915_init(); | 1878 | err = hda_i915_init(hda); |
1914 | if (err < 0) { | 1879 | if (err < 0) |
1915 | dev_err(chip->card->dev, | ||
1916 | "Error request power-well from i915\n"); | ||
1917 | goto out_free; | 1880 | goto out_free; |
1918 | } | 1881 | err = hda_display_power(hda, true); |
1919 | err = hda_display_power(true); | ||
1920 | if (err < 0) { | 1882 | if (err < 0) { |
1921 | dev_err(chip->card->dev, | 1883 | dev_err(chip->card->dev, |
1922 | "Cannot turn on display power on i915\n"); | 1884 | "Cannot turn on display power on i915\n"); |
diff --git a/sound/pci/hda/hda_intel.h b/sound/pci/hda/hda_intel.h new file mode 100644 index 000000000000..348611835476 --- /dev/null +++ b/sound/pci/hda/hda_intel.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License as published by the Free | ||
4 | * Software Foundation; either version 2 of the License, or (at your option) | ||
5 | * any later version. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
8 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
9 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
10 | * more details. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License along with | ||
13 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
14 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
15 | */ | ||
16 | #ifndef __SOUND_HDA_INTEL_H | ||
17 | #define __SOUND_HDA_INTEL_H | ||
18 | |||
19 | #include <drm/i915_component.h> | ||
20 | #include "hda_priv.h" | ||
21 | |||
22 | struct hda_intel { | ||
23 | struct azx chip; | ||
24 | |||
25 | /* for pending irqs */ | ||
26 | struct work_struct irq_pending_work; | ||
27 | |||
28 | /* sync probing */ | ||
29 | struct completion probe_wait; | ||
30 | struct work_struct probe_work; | ||
31 | |||
32 | /* card list (for power_save trigger) */ | ||
33 | struct list_head list; | ||
34 | |||
35 | /* extra flags */ | ||
36 | unsigned int irq_pending_warned:1; | ||
37 | |||
38 | /* VGA-switcheroo setup */ | ||
39 | unsigned int use_vga_switcheroo:1; | ||
40 | unsigned int vga_switcheroo_registered:1; | ||
41 | unsigned int init_failed:1; /* delayed init failed */ | ||
42 | |||
43 | /* secondary power domain for hdmi audio under vga device */ | ||
44 | struct dev_pm_domain hdmi_pm_domain; | ||
45 | |||
46 | /* i915 component interface */ | ||
47 | struct i915_audio_component audio_component; | ||
48 | }; | ||
49 | |||
50 | #ifdef CONFIG_SND_HDA_I915 | ||
51 | int hda_display_power(struct hda_intel *hda, bool enable); | ||
52 | void haswell_set_bclk(struct hda_intel *hda); | ||
53 | int hda_i915_init(struct hda_intel *hda); | ||
54 | int hda_i915_exit(struct hda_intel *hda); | ||
55 | #else | ||
56 | static inline int hda_display_power(struct hda_intel *hda, bool enable) | ||
57 | { | ||
58 | return 0; | ||
59 | } | ||
60 | static inline void haswell_set_bclk(struct hda_intel *hda) { return; } | ||
61 | static inline int hda_i915_init(struct hda_intel *hda) | ||
62 | { | ||
63 | return -ENODEV; | ||
64 | } | ||
65 | static inline int hda_i915_exit(struct hda_intel *hda) | ||
66 | { | ||
67 | return 0; | ||
68 | } | ||
69 | #endif | ||
70 | |||
71 | #endif | ||
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index a9d78e275138..d285904cdb64 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -739,39 +739,6 @@ static int patch_ad1981(struct hda_codec *codec) | |||
739 | * E/F quad mic array | 739 | * E/F quad mic array |
740 | */ | 740 | */ |
741 | 741 | ||
742 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
743 | static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, | ||
744 | struct snd_ctl_elem_info *uinfo) | ||
745 | { | ||
746 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
747 | struct ad198x_spec *spec = codec->spec; | ||
748 | return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, | ||
749 | spec->num_channel_mode); | ||
750 | } | ||
751 | |||
752 | static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol, | ||
753 | struct snd_ctl_elem_value *ucontrol) | ||
754 | { | ||
755 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
756 | struct ad198x_spec *spec = codec->spec; | ||
757 | return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, | ||
758 | spec->num_channel_mode, spec->multiout.max_channels); | ||
759 | } | ||
760 | |||
761 | static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, | ||
762 | struct snd_ctl_elem_value *ucontrol) | ||
763 | { | ||
764 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
765 | struct ad198x_spec *spec = codec->spec; | ||
766 | int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, | ||
767 | spec->num_channel_mode, | ||
768 | &spec->multiout.max_channels); | ||
769 | if (err >= 0 && spec->need_dac_fix) | ||
770 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; | ||
771 | return err; | ||
772 | } | ||
773 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
774 | |||
775 | static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol, | 742 | static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol, |
776 | struct snd_ctl_elem_info *uinfo) | 743 | struct snd_ctl_elem_info *uinfo) |
777 | { | 744 | { |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 65f1f4e18ea5..040306194e6d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/dmi.h> | 30 | #include <linux/dmi.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/input.h> | ||
32 | #include <sound/core.h> | 33 | #include <sound/core.h> |
33 | #include <sound/jack.h> | 34 | #include <sound/jack.h> |
34 | #include "hda_codec.h" | 35 | #include "hda_codec.h" |
@@ -120,6 +121,7 @@ struct alc_spec { | |||
120 | hda_nid_t pll_nid; | 121 | hda_nid_t pll_nid; |
121 | unsigned int pll_coef_idx, pll_coef_bit; | 122 | unsigned int pll_coef_idx, pll_coef_bit; |
122 | unsigned int coef0; | 123 | unsigned int coef0; |
124 | struct input_dev *kb_dev; | ||
123 | }; | 125 | }; |
124 | 126 | ||
125 | /* | 127 | /* |
@@ -3472,6 +3474,79 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, | |||
3472 | } | 3474 | } |
3473 | } | 3475 | } |
3474 | 3476 | ||
3477 | static void gpio2_mic_hotkey_event(struct hda_codec *codec, | ||
3478 | struct hda_jack_callback *event) | ||
3479 | { | ||
3480 | struct alc_spec *spec = codec->spec; | ||
3481 | |||
3482 | /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore | ||
3483 | send both key on and key off event for every interrupt. */ | ||
3484 | input_report_key(spec->kb_dev, KEY_MICMUTE, 1); | ||
3485 | input_sync(spec->kb_dev); | ||
3486 | input_report_key(spec->kb_dev, KEY_MICMUTE, 0); | ||
3487 | input_sync(spec->kb_dev); | ||
3488 | } | ||
3489 | |||
3490 | static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec, | ||
3491 | const struct hda_fixup *fix, int action) | ||
3492 | { | ||
3493 | /* GPIO1 = set according to SKU external amp | ||
3494 | GPIO2 = mic mute hotkey | ||
3495 | GPIO3 = mute LED | ||
3496 | GPIO4 = mic mute LED */ | ||
3497 | static const struct hda_verb gpio_init[] = { | ||
3498 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e }, | ||
3499 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a }, | ||
3500 | { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 }, | ||
3501 | {} | ||
3502 | }; | ||
3503 | |||
3504 | struct alc_spec *spec = codec->spec; | ||
3505 | |||
3506 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3507 | spec->kb_dev = input_allocate_device(); | ||
3508 | if (!spec->kb_dev) { | ||
3509 | codec_err(codec, "Out of memory (input_allocate_device)\n"); | ||
3510 | return; | ||
3511 | } | ||
3512 | spec->kb_dev->name = "Microphone Mute Button"; | ||
3513 | spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
3514 | spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE); | ||
3515 | if (input_register_device(spec->kb_dev)) { | ||
3516 | codec_err(codec, "input_register_device failed\n"); | ||
3517 | input_free_device(spec->kb_dev); | ||
3518 | spec->kb_dev = NULL; | ||
3519 | return; | ||
3520 | } | ||
3521 | |||
3522 | snd_hda_add_verbs(codec, gpio_init); | ||
3523 | snd_hda_codec_write_cache(codec, codec->afg, 0, | ||
3524 | AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04); | ||
3525 | snd_hda_jack_detect_enable_callback(codec, codec->afg, | ||
3526 | gpio2_mic_hotkey_event); | ||
3527 | |||
3528 | spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; | ||
3529 | spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; | ||
3530 | spec->gpio_led = 0; | ||
3531 | spec->mute_led_polarity = 0; | ||
3532 | spec->gpio_mute_led_mask = 0x08; | ||
3533 | spec->gpio_mic_led_mask = 0x10; | ||
3534 | return; | ||
3535 | } | ||
3536 | |||
3537 | if (!spec->kb_dev) | ||
3538 | return; | ||
3539 | |||
3540 | switch (action) { | ||
3541 | case HDA_FIXUP_ACT_PROBE: | ||
3542 | spec->init_amp = ALC_INIT_DEFAULT; | ||
3543 | break; | ||
3544 | case HDA_FIXUP_ACT_FREE: | ||
3545 | input_unregister_device(spec->kb_dev); | ||
3546 | spec->kb_dev = NULL; | ||
3547 | } | ||
3548 | } | ||
3549 | |||
3475 | static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, | 3550 | static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, |
3476 | const struct hda_fixup *fix, int action) | 3551 | const struct hda_fixup *fix, int action) |
3477 | { | 3552 | { |
@@ -4341,6 +4416,8 @@ enum { | |||
4341 | ALC282_FIXUP_ASPIRE_V5_PINS, | 4416 | ALC282_FIXUP_ASPIRE_V5_PINS, |
4342 | ALC280_FIXUP_HP_GPIO4, | 4417 | ALC280_FIXUP_HP_GPIO4, |
4343 | ALC286_FIXUP_HP_GPIO_LED, | 4418 | ALC286_FIXUP_HP_GPIO_LED, |
4419 | ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, | ||
4420 | ALC280_FIXUP_HP_DOCK_PINS, | ||
4344 | }; | 4421 | }; |
4345 | 4422 | ||
4346 | static const struct hda_fixup alc269_fixups[] = { | 4423 | static const struct hda_fixup alc269_fixups[] = { |
@@ -4814,6 +4891,21 @@ static const struct hda_fixup alc269_fixups[] = { | |||
4814 | .type = HDA_FIXUP_FUNC, | 4891 | .type = HDA_FIXUP_FUNC, |
4815 | .v.func = alc286_fixup_hp_gpio_led, | 4892 | .v.func = alc286_fixup_hp_gpio_led, |
4816 | }, | 4893 | }, |
4894 | [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = { | ||
4895 | .type = HDA_FIXUP_FUNC, | ||
4896 | .v.func = alc280_fixup_hp_gpio2_mic_hotkey, | ||
4897 | }, | ||
4898 | [ALC280_FIXUP_HP_DOCK_PINS] = { | ||
4899 | .type = HDA_FIXUP_PINS, | ||
4900 | .v.pins = (const struct hda_pintbl[]) { | ||
4901 | { 0x1b, 0x21011020 }, /* line-out */ | ||
4902 | { 0x1a, 0x01a1903c }, /* headset mic */ | ||
4903 | { 0x18, 0x2181103f }, /* line-in */ | ||
4904 | { }, | ||
4905 | }, | ||
4906 | .chained = true, | ||
4907 | .chain_id = ALC280_FIXUP_HP_GPIO4 | ||
4908 | }, | ||
4817 | }; | 4909 | }; |
4818 | 4910 | ||
4819 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 4911 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
@@ -4843,6 +4935,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4843 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 4935 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
4844 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), | 4936 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), |
4845 | SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), | 4937 | SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), |
4938 | SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY), | ||
4846 | /* ALC282 */ | 4939 | /* ALC282 */ |
4847 | SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4940 | SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4848 | SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4941 | SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
@@ -4856,6 +4949,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4856 | SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4949 | SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4857 | SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4950 | SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4858 | SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED), | 4951 | SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED), |
4952 | SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS), | ||
4859 | SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4953 | SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4860 | SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4954 | SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4861 | SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4955 | SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index b039b46152c6..f7b1523e8a82 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
@@ -880,13 +880,11 @@ static struct snd_pcm_ops snd_ice1712_capture_ops = { | |||
880 | .pointer = snd_ice1712_capture_pointer, | 880 | .pointer = snd_ice1712_capture_pointer, |
881 | }; | 881 | }; |
882 | 882 | ||
883 | static int snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) | 883 | static int snd_ice1712_pcm(struct snd_ice1712 *ice, int device) |
884 | { | 884 | { |
885 | struct snd_pcm *pcm; | 885 | struct snd_pcm *pcm; |
886 | int err; | 886 | int err; |
887 | 887 | ||
888 | if (rpcm) | ||
889 | *rpcm = NULL; | ||
890 | err = snd_pcm_new(ice->card, "ICE1712 consumer", device, 1, 1, &pcm); | 888 | err = snd_pcm_new(ice->card, "ICE1712 consumer", device, 1, 1, &pcm); |
891 | if (err < 0) | 889 | if (err < 0) |
892 | return err; | 890 | return err; |
@@ -902,22 +900,17 @@ static int snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm * | |||
902 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 900 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
903 | snd_dma_pci_data(ice->pci), 64*1024, 64*1024); | 901 | snd_dma_pci_data(ice->pci), 64*1024, 64*1024); |
904 | 902 | ||
905 | if (rpcm) | ||
906 | *rpcm = pcm; | ||
907 | |||
908 | dev_warn(ice->card->dev, | 903 | dev_warn(ice->card->dev, |
909 | "Consumer PCM code does not work well at the moment --jk\n"); | 904 | "Consumer PCM code does not work well at the moment --jk\n"); |
910 | 905 | ||
911 | return 0; | 906 | return 0; |
912 | } | 907 | } |
913 | 908 | ||
914 | static int snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) | 909 | static int snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device) |
915 | { | 910 | { |
916 | struct snd_pcm *pcm; | 911 | struct snd_pcm *pcm; |
917 | int err; | 912 | int err; |
918 | 913 | ||
919 | if (rpcm) | ||
920 | *rpcm = NULL; | ||
921 | err = snd_pcm_new(ice->card, "ICE1712 consumer (DS)", device, 6, 0, &pcm); | 914 | err = snd_pcm_new(ice->card, "ICE1712 consumer (DS)", device, 6, 0, &pcm); |
922 | if (err < 0) | 915 | if (err < 0) |
923 | return err; | 916 | return err; |
@@ -932,9 +925,6 @@ static int snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pc | |||
932 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 925 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
933 | snd_dma_pci_data(ice->pci), 64*1024, 128*1024); | 926 | snd_dma_pci_data(ice->pci), 64*1024, 128*1024); |
934 | 927 | ||
935 | if (rpcm) | ||
936 | *rpcm = pcm; | ||
937 | |||
938 | return 0; | 928 | return 0; |
939 | } | 929 | } |
940 | 930 | ||
@@ -1260,13 +1250,11 @@ static struct snd_pcm_ops snd_ice1712_capture_pro_ops = { | |||
1260 | .pointer = snd_ice1712_capture_pro_pointer, | 1250 | .pointer = snd_ice1712_capture_pro_pointer, |
1261 | }; | 1251 | }; |
1262 | 1252 | ||
1263 | static int snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) | 1253 | static int snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device) |
1264 | { | 1254 | { |
1265 | struct snd_pcm *pcm; | 1255 | struct snd_pcm *pcm; |
1266 | int err; | 1256 | int err; |
1267 | 1257 | ||
1268 | if (rpcm) | ||
1269 | *rpcm = NULL; | ||
1270 | err = snd_pcm_new(ice->card, "ICE1712 multi", device, 1, 1, &pcm); | 1258 | err = snd_pcm_new(ice->card, "ICE1712 multi", device, 1, 1, &pcm); |
1271 | if (err < 0) | 1259 | if (err < 0) |
1272 | return err; | 1260 | return err; |
@@ -1282,8 +1270,6 @@ static int snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd | |||
1282 | snd_dma_pci_data(ice->pci), 256*1024, 256*1024); | 1270 | snd_dma_pci_data(ice->pci), 256*1024, 256*1024); |
1283 | 1271 | ||
1284 | ice->pcm_pro = pcm; | 1272 | ice->pcm_pro = pcm; |
1285 | if (rpcm) | ||
1286 | *rpcm = pcm; | ||
1287 | 1273 | ||
1288 | if (ice->cs8427) { | 1274 | if (ice->cs8427) { |
1289 | /* assign channels to iec958 */ | 1275 | /* assign channels to iec958 */ |
@@ -2691,14 +2677,14 @@ static int snd_ice1712_probe(struct pci_dev *pci, | |||
2691 | c = &no_matched; | 2677 | c = &no_matched; |
2692 | __found: | 2678 | __found: |
2693 | 2679 | ||
2694 | err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL); | 2680 | err = snd_ice1712_pcm_profi(ice, pcm_dev++); |
2695 | if (err < 0) { | 2681 | if (err < 0) { |
2696 | snd_card_free(card); | 2682 | snd_card_free(card); |
2697 | return err; | 2683 | return err; |
2698 | } | 2684 | } |
2699 | 2685 | ||
2700 | if (ice_has_con_ac97(ice)) { | 2686 | if (ice_has_con_ac97(ice)) { |
2701 | err = snd_ice1712_pcm(ice, pcm_dev++, NULL); | 2687 | err = snd_ice1712_pcm(ice, pcm_dev++); |
2702 | if (err < 0) { | 2688 | if (err < 0) { |
2703 | snd_card_free(card); | 2689 | snd_card_free(card); |
2704 | return err; | 2690 | return err; |
@@ -2726,7 +2712,7 @@ static int snd_ice1712_probe(struct pci_dev *pci, | |||
2726 | } | 2712 | } |
2727 | 2713 | ||
2728 | if (ice_has_con_ac97(ice)) { | 2714 | if (ice_has_con_ac97(ice)) { |
2729 | err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL); | 2715 | err = snd_ice1712_pcm_ds(ice, pcm_dev++); |
2730 | if (err < 0) { | 2716 | if (err < 0) { |
2731 | snd_card_free(card); | 2717 | snd_card_free(card); |
2732 | return err; | 2718 | return err; |
@@ -2798,7 +2784,6 @@ static void snd_ice1712_remove(struct pci_dev *pci) | |||
2798 | #ifdef CONFIG_PM_SLEEP | 2784 | #ifdef CONFIG_PM_SLEEP |
2799 | static int snd_ice1712_suspend(struct device *dev) | 2785 | static int snd_ice1712_suspend(struct device *dev) |
2800 | { | 2786 | { |
2801 | struct pci_dev *pci = to_pci_dev(dev); | ||
2802 | struct snd_card *card = dev_get_drvdata(dev); | 2787 | struct snd_card *card = dev_get_drvdata(dev); |
2803 | struct snd_ice1712 *ice = card->private_data; | 2788 | struct snd_ice1712 *ice = card->private_data; |
2804 | 2789 | ||
@@ -2820,16 +2805,11 @@ static int snd_ice1712_suspend(struct device *dev) | |||
2820 | 2805 | ||
2821 | if (ice->pm_suspend) | 2806 | if (ice->pm_suspend) |
2822 | ice->pm_suspend(ice); | 2807 | ice->pm_suspend(ice); |
2823 | |||
2824 | pci_disable_device(pci); | ||
2825 | pci_save_state(pci); | ||
2826 | pci_set_power_state(pci, PCI_D3hot); | ||
2827 | return 0; | 2808 | return 0; |
2828 | } | 2809 | } |
2829 | 2810 | ||
2830 | static int snd_ice1712_resume(struct device *dev) | 2811 | static int snd_ice1712_resume(struct device *dev) |
2831 | { | 2812 | { |
2832 | struct pci_dev *pci = to_pci_dev(dev); | ||
2833 | struct snd_card *card = dev_get_drvdata(dev); | 2813 | struct snd_card *card = dev_get_drvdata(dev); |
2834 | struct snd_ice1712 *ice = card->private_data; | 2814 | struct snd_ice1712 *ice = card->private_data; |
2835 | int rate; | 2815 | int rate; |
@@ -2837,16 +2817,6 @@ static int snd_ice1712_resume(struct device *dev) | |||
2837 | if (!ice->pm_suspend_enabled) | 2817 | if (!ice->pm_suspend_enabled) |
2838 | return 0; | 2818 | return 0; |
2839 | 2819 | ||
2840 | pci_set_power_state(pci, PCI_D0); | ||
2841 | pci_restore_state(pci); | ||
2842 | |||
2843 | if (pci_enable_device(pci) < 0) { | ||
2844 | snd_card_disconnect(card); | ||
2845 | return -EIO; | ||
2846 | } | ||
2847 | |||
2848 | pci_set_master(pci); | ||
2849 | |||
2850 | if (ice->cur_rate) | 2820 | if (ice->cur_rate) |
2851 | rate = ice->cur_rate; | 2821 | rate = ice->cur_rate; |
2852 | else | 2822 | else |
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index d73da157ea14..0b22c00642bb 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
@@ -2798,7 +2798,6 @@ static void snd_vt1724_remove(struct pci_dev *pci) | |||
2798 | #ifdef CONFIG_PM_SLEEP | 2798 | #ifdef CONFIG_PM_SLEEP |
2799 | static int snd_vt1724_suspend(struct device *dev) | 2799 | static int snd_vt1724_suspend(struct device *dev) |
2800 | { | 2800 | { |
2801 | struct pci_dev *pci = to_pci_dev(dev); | ||
2802 | struct snd_card *card = dev_get_drvdata(dev); | 2801 | struct snd_card *card = dev_get_drvdata(dev); |
2803 | struct snd_ice1712 *ice = card->private_data; | 2802 | struct snd_ice1712 *ice = card->private_data; |
2804 | 2803 | ||
@@ -2821,32 +2820,17 @@ static int snd_vt1724_suspend(struct device *dev) | |||
2821 | 2820 | ||
2822 | if (ice->pm_suspend) | 2821 | if (ice->pm_suspend) |
2823 | ice->pm_suspend(ice); | 2822 | ice->pm_suspend(ice); |
2824 | |||
2825 | pci_disable_device(pci); | ||
2826 | pci_save_state(pci); | ||
2827 | pci_set_power_state(pci, PCI_D3hot); | ||
2828 | return 0; | 2823 | return 0; |
2829 | } | 2824 | } |
2830 | 2825 | ||
2831 | static int snd_vt1724_resume(struct device *dev) | 2826 | static int snd_vt1724_resume(struct device *dev) |
2832 | { | 2827 | { |
2833 | struct pci_dev *pci = to_pci_dev(dev); | ||
2834 | struct snd_card *card = dev_get_drvdata(dev); | 2828 | struct snd_card *card = dev_get_drvdata(dev); |
2835 | struct snd_ice1712 *ice = card->private_data; | 2829 | struct snd_ice1712 *ice = card->private_data; |
2836 | 2830 | ||
2837 | if (!ice->pm_suspend_enabled) | 2831 | if (!ice->pm_suspend_enabled) |
2838 | return 0; | 2832 | return 0; |
2839 | 2833 | ||
2840 | pci_set_power_state(pci, PCI_D0); | ||
2841 | pci_restore_state(pci); | ||
2842 | |||
2843 | if (pci_enable_device(pci) < 0) { | ||
2844 | snd_card_disconnect(card); | ||
2845 | return -EIO; | ||
2846 | } | ||
2847 | |||
2848 | pci_set_master(pci); | ||
2849 | |||
2850 | snd_vt1724_chip_reset(ice); | 2834 | snd_vt1724_chip_reset(ice); |
2851 | 2835 | ||
2852 | if (snd_vt1724_chip_init(ice) < 0) { | 2836 | if (snd_vt1724_chip_init(ice) < 0) { |
diff --git a/sound/pci/ice1712/wm8766.c b/sound/pci/ice1712/wm8766.c index 21b373b2e260..f7ac8d5e862c 100644 --- a/sound/pci/ice1712/wm8766.c +++ b/sound/pci/ice1712/wm8766.c | |||
@@ -183,22 +183,6 @@ void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac) | |||
183 | snd_wm8766_write(wm, WM8766_REG_IFCTRL, val | dac); | 183 | snd_wm8766_write(wm, WM8766_REG_IFCTRL, val | dac); |
184 | } | 184 | } |
185 | 185 | ||
186 | void snd_wm8766_set_master_mode(struct snd_wm8766 *wm, u16 mode) | ||
187 | { | ||
188 | u16 val = wm->regs[WM8766_REG_DACCTRL3] & ~WM8766_DAC3_MSTR_MASK; | ||
189 | |||
190 | mode &= WM8766_DAC3_MSTR_MASK; | ||
191 | snd_wm8766_write(wm, WM8766_REG_DACCTRL3, val | mode); | ||
192 | } | ||
193 | |||
194 | void snd_wm8766_set_power(struct snd_wm8766 *wm, u16 power) | ||
195 | { | ||
196 | u16 val = wm->regs[WM8766_REG_DACCTRL3] & ~WM8766_DAC3_POWER_MASK; | ||
197 | |||
198 | power &= WM8766_DAC3_POWER_MASK; | ||
199 | snd_wm8766_write(wm, WM8766_REG_DACCTRL3, val | power); | ||
200 | } | ||
201 | |||
202 | void snd_wm8766_volume_restore(struct snd_wm8766 *wm) | 186 | void snd_wm8766_volume_restore(struct snd_wm8766 *wm) |
203 | { | 187 | { |
204 | u16 val = wm->regs[WM8766_REG_DACR1]; | 188 | u16 val = wm->regs[WM8766_REG_DACR1]; |
diff --git a/sound/pci/ice1712/wm8766.h b/sound/pci/ice1712/wm8766.h index c119f84bd2c2..18c8d9d47b38 100644 --- a/sound/pci/ice1712/wm8766.h +++ b/sound/pci/ice1712/wm8766.h | |||
@@ -155,8 +155,6 @@ struct snd_wm8766 { | |||
155 | void snd_wm8766_init(struct snd_wm8766 *wm); | 155 | void snd_wm8766_init(struct snd_wm8766 *wm); |
156 | void snd_wm8766_resume(struct snd_wm8766 *wm); | 156 | void snd_wm8766_resume(struct snd_wm8766 *wm); |
157 | void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac); | 157 | void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac); |
158 | void snd_wm8766_set_master_mode(struct snd_wm8766 *wm, u16 mode); | ||
159 | void snd_wm8766_set_power(struct snd_wm8766 *wm, u16 power); | ||
160 | void snd_wm8766_volume_restore(struct snd_wm8766 *wm); | 158 | void snd_wm8766_volume_restore(struct snd_wm8766 *wm); |
161 | int snd_wm8766_build_controls(struct snd_wm8766 *wm); | 159 | int snd_wm8766_build_controls(struct snd_wm8766 *wm); |
162 | 160 | ||
diff --git a/sound/pci/ice1712/wm8776.c b/sound/pci/ice1712/wm8776.c index e66c0da62014..ebd2fe4b4a57 100644 --- a/sound/pci/ice1712/wm8776.c +++ b/sound/pci/ice1712/wm8776.c | |||
@@ -452,21 +452,6 @@ void snd_wm8776_resume(struct snd_wm8776 *wm) | |||
452 | snd_wm8776_write(wm, i, wm->regs[i]); | 452 | snd_wm8776_write(wm, i, wm->regs[i]); |
453 | } | 453 | } |
454 | 454 | ||
455 | void snd_wm8776_set_dac_if(struct snd_wm8776 *wm, u16 dac) | ||
456 | { | ||
457 | snd_wm8776_write(wm, WM8776_REG_DACIFCTRL, dac); | ||
458 | } | ||
459 | |||
460 | void snd_wm8776_set_adc_if(struct snd_wm8776 *wm, u16 adc) | ||
461 | { | ||
462 | snd_wm8776_write(wm, WM8776_REG_ADCIFCTRL, adc); | ||
463 | } | ||
464 | |||
465 | void snd_wm8776_set_master_mode(struct snd_wm8776 *wm, u16 mode) | ||
466 | { | ||
467 | snd_wm8776_write(wm, WM8776_REG_MSTRCTRL, mode); | ||
468 | } | ||
469 | |||
470 | void snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power) | 455 | void snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power) |
471 | { | 456 | { |
472 | snd_wm8776_write(wm, WM8776_REG_PWRDOWN, power); | 457 | snd_wm8776_write(wm, WM8776_REG_PWRDOWN, power); |
diff --git a/sound/pci/ice1712/wm8776.h b/sound/pci/ice1712/wm8776.h index 93a2d6971154..42acef05540c 100644 --- a/sound/pci/ice1712/wm8776.h +++ b/sound/pci/ice1712/wm8776.h | |||
@@ -216,9 +216,6 @@ struct snd_wm8776 { | |||
216 | 216 | ||
217 | void snd_wm8776_init(struct snd_wm8776 *wm); | 217 | void snd_wm8776_init(struct snd_wm8776 *wm); |
218 | void snd_wm8776_resume(struct snd_wm8776 *wm); | 218 | void snd_wm8776_resume(struct snd_wm8776 *wm); |
219 | void snd_wm8776_set_dac_if(struct snd_wm8776 *wm, u16 dac); | ||
220 | void snd_wm8776_set_adc_if(struct snd_wm8776 *wm, u16 adc); | ||
221 | void snd_wm8776_set_master_mode(struct snd_wm8776 *wm, u16 mode); | ||
222 | void snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power); | 219 | void snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power); |
223 | void snd_wm8776_volume_restore(struct snd_wm8776 *wm); | 220 | void snd_wm8776_volume_restore(struct snd_wm8776 *wm); |
224 | int snd_wm8776_build_controls(struct snd_wm8776 *wm); | 221 | int snd_wm8776_build_controls(struct snd_wm8776 *wm); |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 4a28252a42b9..67f9e8b77385 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -2654,7 +2654,6 @@ static int snd_intel8x0_free(struct intel8x0 *chip) | |||
2654 | */ | 2654 | */ |
2655 | static int intel8x0_suspend(struct device *dev) | 2655 | static int intel8x0_suspend(struct device *dev) |
2656 | { | 2656 | { |
2657 | struct pci_dev *pci = to_pci_dev(dev); | ||
2658 | struct snd_card *card = dev_get_drvdata(dev); | 2657 | struct snd_card *card = dev_get_drvdata(dev); |
2659 | struct intel8x0 *chip = card->private_data; | 2658 | struct intel8x0 *chip = card->private_data; |
2660 | int i; | 2659 | int i; |
@@ -2682,12 +2681,6 @@ static int intel8x0_suspend(struct device *dev) | |||
2682 | free_irq(chip->irq, chip); | 2681 | free_irq(chip->irq, chip); |
2683 | chip->irq = -1; | 2682 | chip->irq = -1; |
2684 | } | 2683 | } |
2685 | pci_disable_device(pci); | ||
2686 | pci_save_state(pci); | ||
2687 | /* The call below may disable built-in speaker on some laptops | ||
2688 | * after S2RAM. So, don't touch it. | ||
2689 | */ | ||
2690 | /* pci_set_power_state(pci, PCI_D3hot); */ | ||
2691 | return 0; | 2684 | return 0; |
2692 | } | 2685 | } |
2693 | 2686 | ||
@@ -2698,14 +2691,6 @@ static int intel8x0_resume(struct device *dev) | |||
2698 | struct intel8x0 *chip = card->private_data; | 2691 | struct intel8x0 *chip = card->private_data; |
2699 | int i; | 2692 | int i; |
2700 | 2693 | ||
2701 | pci_set_power_state(pci, PCI_D0); | ||
2702 | pci_restore_state(pci); | ||
2703 | if (pci_enable_device(pci) < 0) { | ||
2704 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
2705 | snd_card_disconnect(card); | ||
2706 | return -EIO; | ||
2707 | } | ||
2708 | pci_set_master(pci); | ||
2709 | snd_intel8x0_chip_init(chip, 0); | 2694 | snd_intel8x0_chip_init(chip, 0); |
2710 | if (request_irq(pci->irq, snd_intel8x0_interrupt, | 2695 | if (request_irq(pci->irq, snd_intel8x0_interrupt, |
2711 | IRQF_SHARED, KBUILD_MODNAME, chip)) { | 2696 | IRQF_SHARED, KBUILD_MODNAME, chip)) { |
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 6b40235be13c..748f6f67c982 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c | |||
@@ -1023,7 +1023,6 @@ static int snd_intel8x0m_free(struct intel8x0m *chip) | |||
1023 | */ | 1023 | */ |
1024 | static int intel8x0m_suspend(struct device *dev) | 1024 | static int intel8x0m_suspend(struct device *dev) |
1025 | { | 1025 | { |
1026 | struct pci_dev *pci = to_pci_dev(dev); | ||
1027 | struct snd_card *card = dev_get_drvdata(dev); | 1026 | struct snd_card *card = dev_get_drvdata(dev); |
1028 | struct intel8x0m *chip = card->private_data; | 1027 | struct intel8x0m *chip = card->private_data; |
1029 | int i; | 1028 | int i; |
@@ -1036,9 +1035,6 @@ static int intel8x0m_suspend(struct device *dev) | |||
1036 | free_irq(chip->irq, chip); | 1035 | free_irq(chip->irq, chip); |
1037 | chip->irq = -1; | 1036 | chip->irq = -1; |
1038 | } | 1037 | } |
1039 | pci_disable_device(pci); | ||
1040 | pci_save_state(pci); | ||
1041 | pci_set_power_state(pci, PCI_D3hot); | ||
1042 | return 0; | 1038 | return 0; |
1043 | } | 1039 | } |
1044 | 1040 | ||
@@ -1048,14 +1044,6 @@ static int intel8x0m_resume(struct device *dev) | |||
1048 | struct snd_card *card = dev_get_drvdata(dev); | 1044 | struct snd_card *card = dev_get_drvdata(dev); |
1049 | struct intel8x0m *chip = card->private_data; | 1045 | struct intel8x0m *chip = card->private_data; |
1050 | 1046 | ||
1051 | pci_set_power_state(pci, PCI_D0); | ||
1052 | pci_restore_state(pci); | ||
1053 | if (pci_enable_device(pci) < 0) { | ||
1054 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
1055 | snd_card_disconnect(card); | ||
1056 | return -EIO; | ||
1057 | } | ||
1058 | pci_set_master(pci); | ||
1059 | if (request_irq(pci->irq, snd_intel8x0m_interrupt, | 1047 | if (request_irq(pci->irq, snd_intel8x0m_interrupt, |
1060 | IRQF_SHARED, KBUILD_MODNAME, chip)) { | 1048 | IRQF_SHARED, KBUILD_MODNAME, chip)) { |
1061 | dev_err(dev, "unable to grab IRQ %d, disabling device\n", | 1049 | dev_err(dev, "unable to grab IRQ %d, disabling device\n", |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 59d21c9401d2..bd569e580277 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
@@ -585,8 +585,7 @@ static void snd_korg1212_SendStop(struct snd_korg1212 *korg1212) | |||
585 | korg1212->sharedBufferPtr->cardCommand = 0xffffffff; | 585 | korg1212->sharedBufferPtr->cardCommand = 0xffffffff; |
586 | /* program the timer */ | 586 | /* program the timer */ |
587 | korg1212->stop_pending_cnt = HZ; | 587 | korg1212->stop_pending_cnt = HZ; |
588 | korg1212->timer.expires = jiffies + 1; | 588 | mod_timer(&korg1212->timer, jiffies + 1); |
589 | add_timer(&korg1212->timer); | ||
590 | } | 589 | } |
591 | } | 590 | } |
592 | 591 | ||
@@ -617,8 +616,7 @@ static void snd_korg1212_timer_func(unsigned long data) | |||
617 | } else { | 616 | } else { |
618 | if (--korg1212->stop_pending_cnt > 0) { | 617 | if (--korg1212->stop_pending_cnt > 0) { |
619 | /* reprogram timer */ | 618 | /* reprogram timer */ |
620 | korg1212->timer.expires = jiffies + 1; | 619 | mod_timer(&korg1212->timer, jiffies + 1); |
621 | add_timer(&korg1212->timer); | ||
622 | } else { | 620 | } else { |
623 | snd_printd("korg1212_timer_func timeout\n"); | 621 | snd_printd("korg1212_timer_func timeout\n"); |
624 | korg1212->sharedBufferPtr->cardCommand = 0; | 622 | korg1212->sharedBufferPtr->cardCommand = 0; |
@@ -2172,9 +2170,8 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci, | |||
2172 | init_waitqueue_head(&korg1212->wait); | 2170 | init_waitqueue_head(&korg1212->wait); |
2173 | spin_lock_init(&korg1212->lock); | 2171 | spin_lock_init(&korg1212->lock); |
2174 | mutex_init(&korg1212->open_mutex); | 2172 | mutex_init(&korg1212->open_mutex); |
2175 | init_timer(&korg1212->timer); | 2173 | setup_timer(&korg1212->timer, snd_korg1212_timer_func, |
2176 | korg1212->timer.function = snd_korg1212_timer_func; | 2174 | (unsigned long)korg1212); |
2177 | korg1212->timer.data = (unsigned long)korg1212; | ||
2178 | 2175 | ||
2179 | korg1212->irq = -1; | 2176 | korg1212->irq = -1; |
2180 | korg1212->clkSource = K1212_CLKIDX_Local; | 2177 | korg1212->clkSource = K1212_CLKIDX_Local; |
diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c index 4cf4be5ef82a..9ff600084973 100644 --- a/sound/pci/lola/lola.c +++ b/sound/pci/lola/lola.c | |||
@@ -551,10 +551,8 @@ static void lola_free(struct lola *chip) | |||
551 | lola_free_mixer(chip); | 551 | lola_free_mixer(chip); |
552 | if (chip->irq >= 0) | 552 | if (chip->irq >= 0) |
553 | free_irq(chip->irq, (void *)chip); | 553 | free_irq(chip->irq, (void *)chip); |
554 | if (chip->bar[0].remap_addr) | 554 | iounmap(chip->bar[0].remap_addr); |
555 | iounmap(chip->bar[0].remap_addr); | 555 | iounmap(chip->bar[1].remap_addr); |
556 | if (chip->bar[1].remap_addr) | ||
557 | iounmap(chip->bar[1].remap_addr); | ||
558 | if (chip->rb.area) | 556 | if (chip->rb.area) |
559 | snd_dma_free_pages(&chip->rb); | 557 | snd_dma_free_pages(&chip->rb); |
560 | pci_release_regions(chip->pci); | 558 | pci_release_regions(chip->pci); |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 98823d11d485..18a60be63266 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -2395,7 +2395,6 @@ static int snd_m3_free(struct snd_m3 *chip) | |||
2395 | #ifdef CONFIG_PM_SLEEP | 2395 | #ifdef CONFIG_PM_SLEEP |
2396 | static int m3_suspend(struct device *dev) | 2396 | static int m3_suspend(struct device *dev) |
2397 | { | 2397 | { |
2398 | struct pci_dev *pci = to_pci_dev(dev); | ||
2399 | struct snd_card *card = dev_get_drvdata(dev); | 2398 | struct snd_card *card = dev_get_drvdata(dev); |
2400 | struct snd_m3 *chip = card->private_data; | 2399 | struct snd_m3 *chip = card->private_data; |
2401 | int i, dsp_index; | 2400 | int i, dsp_index; |
@@ -2421,16 +2420,11 @@ static int m3_suspend(struct device *dev) | |||
2421 | for (i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++) | 2420 | for (i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++) |
2422 | chip->suspend_mem[dsp_index++] = | 2421 | chip->suspend_mem[dsp_index++] = |
2423 | snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA, i); | 2422 | snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA, i); |
2424 | |||
2425 | pci_disable_device(pci); | ||
2426 | pci_save_state(pci); | ||
2427 | pci_set_power_state(pci, PCI_D3hot); | ||
2428 | return 0; | 2423 | return 0; |
2429 | } | 2424 | } |
2430 | 2425 | ||
2431 | static int m3_resume(struct device *dev) | 2426 | static int m3_resume(struct device *dev) |
2432 | { | 2427 | { |
2433 | struct pci_dev *pci = to_pci_dev(dev); | ||
2434 | struct snd_card *card = dev_get_drvdata(dev); | 2428 | struct snd_card *card = dev_get_drvdata(dev); |
2435 | struct snd_m3 *chip = card->private_data; | 2429 | struct snd_m3 *chip = card->private_data; |
2436 | int i, dsp_index; | 2430 | int i, dsp_index; |
@@ -2438,15 +2432,6 @@ static int m3_resume(struct device *dev) | |||
2438 | if (chip->suspend_mem == NULL) | 2432 | if (chip->suspend_mem == NULL) |
2439 | return 0; | 2433 | return 0; |
2440 | 2434 | ||
2441 | pci_set_power_state(pci, PCI_D0); | ||
2442 | pci_restore_state(pci); | ||
2443 | if (pci_enable_device(pci) < 0) { | ||
2444 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
2445 | snd_card_disconnect(card); | ||
2446 | return -EIO; | ||
2447 | } | ||
2448 | pci_set_master(pci); | ||
2449 | |||
2450 | /* first lets just bring everything back. .*/ | 2435 | /* first lets just bring everything back. .*/ |
2451 | snd_m3_outw(chip, 0, 0x54); | 2436 | snd_m3_outw(chip, 0, 0x54); |
2452 | snd_m3_outw(chip, 0, 0x56); | 2437 | snd_m3_outw(chip, 0, 0x56); |
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 1faf47e81570..c3a9f39f8d61 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c | |||
@@ -1114,10 +1114,9 @@ static int snd_mixart_free(struct mixart_mgr *mgr) | |||
1114 | } | 1114 | } |
1115 | 1115 | ||
1116 | /* release the i/o ports */ | 1116 | /* release the i/o ports */ |
1117 | for (i = 0; i < 2; i++) { | 1117 | for (i = 0; i < 2; ++i) |
1118 | if (mgr->mem[i].virt) | 1118 | iounmap(mgr->mem[i].virt); |
1119 | iounmap(mgr->mem[i].virt); | 1119 | |
1120 | } | ||
1121 | pci_release_regions(mgr->pci); | 1120 | pci_release_regions(mgr->pci); |
1122 | 1121 | ||
1123 | /* free flowarray */ | 1122 | /* free flowarray */ |
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 4e41a4e29a1e..90674b93b930 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c | |||
@@ -1392,7 +1392,6 @@ snd_nm256_peek_for_sig(struct nm256 *chip) | |||
1392 | */ | 1392 | */ |
1393 | static int nm256_suspend(struct device *dev) | 1393 | static int nm256_suspend(struct device *dev) |
1394 | { | 1394 | { |
1395 | struct pci_dev *pci = to_pci_dev(dev); | ||
1396 | struct snd_card *card = dev_get_drvdata(dev); | 1395 | struct snd_card *card = dev_get_drvdata(dev); |
1397 | struct nm256 *chip = card->private_data; | 1396 | struct nm256 *chip = card->private_data; |
1398 | 1397 | ||
@@ -1400,15 +1399,11 @@ static int nm256_suspend(struct device *dev) | |||
1400 | snd_pcm_suspend_all(chip->pcm); | 1399 | snd_pcm_suspend_all(chip->pcm); |
1401 | snd_ac97_suspend(chip->ac97); | 1400 | snd_ac97_suspend(chip->ac97); |
1402 | chip->coeffs_current = 0; | 1401 | chip->coeffs_current = 0; |
1403 | pci_disable_device(pci); | ||
1404 | pci_save_state(pci); | ||
1405 | pci_set_power_state(pci, PCI_D3hot); | ||
1406 | return 0; | 1402 | return 0; |
1407 | } | 1403 | } |
1408 | 1404 | ||
1409 | static int nm256_resume(struct device *dev) | 1405 | static int nm256_resume(struct device *dev) |
1410 | { | 1406 | { |
1411 | struct pci_dev *pci = to_pci_dev(dev); | ||
1412 | struct snd_card *card = dev_get_drvdata(dev); | 1407 | struct snd_card *card = dev_get_drvdata(dev); |
1413 | struct nm256 *chip = card->private_data; | 1408 | struct nm256 *chip = card->private_data; |
1414 | int i; | 1409 | int i; |
@@ -1416,15 +1411,6 @@ static int nm256_resume(struct device *dev) | |||
1416 | /* Perform a full reset on the hardware */ | 1411 | /* Perform a full reset on the hardware */ |
1417 | chip->in_resume = 1; | 1412 | chip->in_resume = 1; |
1418 | 1413 | ||
1419 | pci_set_power_state(pci, PCI_D0); | ||
1420 | pci_restore_state(pci); | ||
1421 | if (pci_enable_device(pci) < 0) { | ||
1422 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
1423 | snd_card_disconnect(card); | ||
1424 | return -EIO; | ||
1425 | } | ||
1426 | pci_set_master(pci); | ||
1427 | |||
1428 | snd_nm256_init_chip(chip); | 1414 | snd_nm256_init_chip(chip); |
1429 | 1415 | ||
1430 | /* restore ac97 */ | 1416 | /* restore ac97 */ |
@@ -1460,10 +1446,8 @@ static int snd_nm256_free(struct nm256 *chip) | |||
1460 | if (chip->irq >= 0) | 1446 | if (chip->irq >= 0) |
1461 | free_irq(chip->irq, chip); | 1447 | free_irq(chip->irq, chip); |
1462 | 1448 | ||
1463 | if (chip->cport) | 1449 | iounmap(chip->cport); |
1464 | iounmap(chip->cport); | 1450 | iounmap(chip->buffer); |
1465 | if (chip->buffer) | ||
1466 | iounmap(chip->buffer); | ||
1467 | release_and_free_resource(chip->res_cport); | 1451 | release_and_free_resource(chip->res_cport); |
1468 | release_and_free_resource(chip->res_buffer); | 1452 | release_and_free_resource(chip->res_buffer); |
1469 | 1453 | ||
diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile index 8f4c409f7e45..ab085d753661 100644 --- a/sound/pci/oxygen/Makefile +++ b/sound/pci/oxygen/Makefile | |||
@@ -1,8 +1,10 @@ | |||
1 | snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o | 1 | snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o |
2 | snd-oxygen-objs := oxygen.o xonar_dg_mixer.o xonar_dg.o | 2 | snd-oxygen-objs := oxygen.o xonar_dg_mixer.o xonar_dg.o |
3 | snd-se6x-objs := se6x.o | ||
3 | snd-virtuoso-objs := virtuoso.o xonar_lib.o \ | 4 | snd-virtuoso-objs := virtuoso.o xonar_lib.o \ |
4 | xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o | 5 | xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o |
5 | 6 | ||
6 | obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o | 7 | obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o |
7 | obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o | 8 | obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o |
9 | obj-$(CONFIG_SND_SE6X) += snd-se6x.o | ||
8 | obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o | 10 | obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o |
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index c10ab077afd8..293d0b9a50c3 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h | |||
@@ -35,7 +35,7 @@ | |||
35 | #define CAPTURE_1_FROM_SPDIF 0x0080 | 35 | #define CAPTURE_1_FROM_SPDIF 0x0080 |
36 | #define CAPTURE_2_FROM_I2S_2 0x0100 | 36 | #define CAPTURE_2_FROM_I2S_2 0x0100 |
37 | #define CAPTURE_2_FROM_AC97_1 0x0200 | 37 | #define CAPTURE_2_FROM_AC97_1 0x0200 |
38 | /* CAPTURE_3_FROM_I2S_3 not implemented */ | 38 | #define CAPTURE_3_FROM_I2S_3 0x0400 |
39 | #define MIDI_OUTPUT 0x0800 | 39 | #define MIDI_OUTPUT 0x0800 |
40 | #define MIDI_INPUT 0x1000 | 40 | #define MIDI_INPUT 0x1000 |
41 | #define AC97_CD_INPUT 0x2000 | 41 | #define AC97_CD_INPUT 0x2000 |
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index b67e30602473..ffff3b25fd73 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c | |||
@@ -319,11 +319,12 @@ static void oxygen_restore_eeprom(struct oxygen *chip, | |||
319 | 319 | ||
320 | static void configure_pcie_bridge(struct pci_dev *pci) | 320 | static void configure_pcie_bridge(struct pci_dev *pci) |
321 | { | 321 | { |
322 | enum { PEX811X, PI7C9X110 }; | 322 | enum { PEX811X, PI7C9X110, XIO2001 }; |
323 | static const struct pci_device_id bridge_ids[] = { | 323 | static const struct pci_device_id bridge_ids[] = { |
324 | { PCI_VDEVICE(PLX, 0x8111), .driver_data = PEX811X }, | 324 | { PCI_VDEVICE(PLX, 0x8111), .driver_data = PEX811X }, |
325 | { PCI_VDEVICE(PLX, 0x8112), .driver_data = PEX811X }, | 325 | { PCI_VDEVICE(PLX, 0x8112), .driver_data = PEX811X }, |
326 | { PCI_DEVICE(0x12d8, 0xe110), .driver_data = PI7C9X110 }, | 326 | { PCI_DEVICE(0x12d8, 0xe110), .driver_data = PI7C9X110 }, |
327 | { PCI_VDEVICE(TI, 0x8240), .driver_data = XIO2001 }, | ||
327 | { } | 328 | { } |
328 | }; | 329 | }; |
329 | struct pci_dev *bridge; | 330 | struct pci_dev *bridge; |
@@ -357,6 +358,14 @@ static void configure_pcie_bridge(struct pci_dev *pci) | |||
357 | tmp |= 1; /* park the PCI arbiter to the sound chip */ | 358 | tmp |= 1; /* park the PCI arbiter to the sound chip */ |
358 | pci_write_config_dword(bridge, 0x40, tmp); | 359 | pci_write_config_dword(bridge, 0x40, tmp); |
359 | break; | 360 | break; |
361 | |||
362 | case XIO2001: /* Texas Instruments XIO2001 PCIe/PCI bridge */ | ||
363 | pci_read_config_dword(bridge, 0xe8, &tmp); | ||
364 | tmp &= ~0xf; /* request length limit: 64 bytes */ | ||
365 | tmp &= ~(0xf << 8); | ||
366 | tmp |= 1 << 8; /* request count limit: one buffer */ | ||
367 | pci_write_config_dword(bridge, 0xe8, tmp); | ||
368 | break; | ||
360 | } | 369 | } |
361 | } | 370 | } |
362 | 371 | ||
@@ -441,9 +450,18 @@ static void oxygen_init(struct oxygen *chip) | |||
441 | oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, | 450 | oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, |
442 | OXYGEN_I2S_MASTER | | 451 | OXYGEN_I2S_MASTER | |
443 | OXYGEN_I2S_MUTE_MCLK); | 452 | OXYGEN_I2S_MUTE_MCLK); |
444 | oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, | 453 | if (chip->model.device_config & CAPTURE_3_FROM_I2S_3) |
445 | OXYGEN_I2S_MASTER | | 454 | oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, |
446 | OXYGEN_I2S_MUTE_MCLK); | 455 | OXYGEN_RATE_48000 | |
456 | chip->model.adc_i2s_format | | ||
457 | OXYGEN_I2S_MCLK(chip->model.adc_mclks) | | ||
458 | OXYGEN_I2S_BITS_16 | | ||
459 | OXYGEN_I2S_MASTER | | ||
460 | OXYGEN_I2S_BCLK_64); | ||
461 | else | ||
462 | oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, | ||
463 | OXYGEN_I2S_MASTER | | ||
464 | OXYGEN_I2S_MUTE_MCLK); | ||
447 | oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, | 465 | oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, |
448 | OXYGEN_SPDIF_OUT_ENABLE | | 466 | OXYGEN_SPDIF_OUT_ENABLE | |
449 | OXYGEN_SPDIF_LOOPBACK); | 467 | OXYGEN_SPDIF_LOOPBACK); |
@@ -728,7 +746,6 @@ EXPORT_SYMBOL(oxygen_pci_remove); | |||
728 | #ifdef CONFIG_PM_SLEEP | 746 | #ifdef CONFIG_PM_SLEEP |
729 | static int oxygen_pci_suspend(struct device *dev) | 747 | static int oxygen_pci_suspend(struct device *dev) |
730 | { | 748 | { |
731 | struct pci_dev *pci = to_pci_dev(dev); | ||
732 | struct snd_card *card = dev_get_drvdata(dev); | 749 | struct snd_card *card = dev_get_drvdata(dev); |
733 | struct oxygen *chip = card->private_data; | 750 | struct oxygen *chip = card->private_data; |
734 | unsigned int i, saved_interrupt_mask; | 751 | unsigned int i, saved_interrupt_mask; |
@@ -736,8 +753,7 @@ static int oxygen_pci_suspend(struct device *dev) | |||
736 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 753 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
737 | 754 | ||
738 | for (i = 0; i < PCM_COUNT; ++i) | 755 | for (i = 0; i < PCM_COUNT; ++i) |
739 | if (chip->streams[i]) | 756 | snd_pcm_suspend(chip->streams[i]); |
740 | snd_pcm_suspend(chip->streams[i]); | ||
741 | 757 | ||
742 | if (chip->model.suspend) | 758 | if (chip->model.suspend) |
743 | chip->model.suspend(chip); | 759 | chip->model.suspend(chip); |
@@ -753,10 +769,6 @@ static int oxygen_pci_suspend(struct device *dev) | |||
753 | flush_work(&chip->spdif_input_bits_work); | 769 | flush_work(&chip->spdif_input_bits_work); |
754 | flush_work(&chip->gpio_work); | 770 | flush_work(&chip->gpio_work); |
755 | chip->interrupt_mask = saved_interrupt_mask; | 771 | chip->interrupt_mask = saved_interrupt_mask; |
756 | |||
757 | pci_disable_device(pci); | ||
758 | pci_save_state(pci); | ||
759 | pci_set_power_state(pci, PCI_D3hot); | ||
760 | return 0; | 772 | return 0; |
761 | } | 773 | } |
762 | 774 | ||
@@ -788,20 +800,10 @@ static void oxygen_restore_ac97(struct oxygen *chip, unsigned int codec) | |||
788 | 800 | ||
789 | static int oxygen_pci_resume(struct device *dev) | 801 | static int oxygen_pci_resume(struct device *dev) |
790 | { | 802 | { |
791 | struct pci_dev *pci = to_pci_dev(dev); | ||
792 | struct snd_card *card = dev_get_drvdata(dev); | 803 | struct snd_card *card = dev_get_drvdata(dev); |
793 | struct oxygen *chip = card->private_data; | 804 | struct oxygen *chip = card->private_data; |
794 | unsigned int i; | 805 | unsigned int i; |
795 | 806 | ||
796 | pci_set_power_state(pci, PCI_D0); | ||
797 | pci_restore_state(pci); | ||
798 | if (pci_enable_device(pci) < 0) { | ||
799 | dev_err(dev, "cannot reenable device"); | ||
800 | snd_card_disconnect(card); | ||
801 | return -EIO; | ||
802 | } | ||
803 | pci_set_master(pci); | ||
804 | |||
805 | oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); | 807 | oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); |
806 | oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); | 808 | oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); |
807 | for (i = 0; i < OXYGEN_IO_SIZE; ++i) | 809 | for (i = 0; i < OXYGEN_IO_SIZE; ++i) |
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 5988e044c519..6492bca8c70f 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c | |||
@@ -786,6 +786,9 @@ static const struct snd_kcontrol_new controls[] = { | |||
786 | .get = upmix_get, | 786 | .get = upmix_get, |
787 | .put = upmix_put, | 787 | .put = upmix_put, |
788 | }, | 788 | }, |
789 | }; | ||
790 | |||
791 | static const struct snd_kcontrol_new spdif_output_controls[] = { | ||
789 | { | 792 | { |
790 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 793 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
791 | .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH), | 794 | .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH), |
@@ -938,6 +941,33 @@ static const struct { | |||
938 | }, | 941 | }, |
939 | }, | 942 | }, |
940 | { | 943 | { |
944 | .pcm_dev = CAPTURE_3_FROM_I2S_3, | ||
945 | .controls = { | ||
946 | { | ||
947 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
948 | .name = "Analog Input Monitor Playback Switch", | ||
949 | .index = 2, | ||
950 | .info = snd_ctl_boolean_mono_info, | ||
951 | .get = monitor_get, | ||
952 | .put = monitor_put, | ||
953 | .private_value = OXYGEN_ADC_MONITOR_C, | ||
954 | }, | ||
955 | { | ||
956 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
957 | .name = "Analog Input Monitor Playback Volume", | ||
958 | .index = 2, | ||
959 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
960 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
961 | .info = monitor_volume_info, | ||
962 | .get = monitor_get, | ||
963 | .put = monitor_put, | ||
964 | .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL | ||
965 | | (1 << 8), | ||
966 | .tlv = { .p = monitor_db_scale, }, | ||
967 | }, | ||
968 | }, | ||
969 | }, | ||
970 | { | ||
941 | .pcm_dev = CAPTURE_1_FROM_SPDIF, | 971 | .pcm_dev = CAPTURE_1_FROM_SPDIF, |
942 | .controls = { | 972 | .controls = { |
943 | { | 973 | { |
@@ -1073,6 +1103,12 @@ int oxygen_mixer_init(struct oxygen *chip) | |||
1073 | err = add_controls(chip, controls, ARRAY_SIZE(controls)); | 1103 | err = add_controls(chip, controls, ARRAY_SIZE(controls)); |
1074 | if (err < 0) | 1104 | if (err < 0) |
1075 | return err; | 1105 | return err; |
1106 | if (chip->model.device_config & PLAYBACK_1_TO_SPDIF) { | ||
1107 | err = add_controls(chip, spdif_output_controls, | ||
1108 | ARRAY_SIZE(spdif_output_controls)); | ||
1109 | if (err < 0) | ||
1110 | return err; | ||
1111 | } | ||
1076 | if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) { | 1112 | if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) { |
1077 | err = add_controls(chip, spdif_input_controls, | 1113 | err = add_controls(chip, spdif_input_controls, |
1078 | ARRAY_SIZE(spdif_input_controls)); | 1114 | ARRAY_SIZE(spdif_input_controls)); |
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 02828240ba15..aa2ebd1d6d12 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c | |||
@@ -144,9 +144,11 @@ static int oxygen_open(struct snd_pcm_substream *substream, | |||
144 | runtime->hw = *oxygen_hardware[channel]; | 144 | runtime->hw = *oxygen_hardware[channel]; |
145 | switch (channel) { | 145 | switch (channel) { |
146 | case PCM_C: | 146 | case PCM_C: |
147 | runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 | | 147 | if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) { |
148 | SNDRV_PCM_RATE_64000); | 148 | runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 | |
149 | runtime->hw.rate_min = 44100; | 149 | SNDRV_PCM_RATE_64000); |
150 | runtime->hw.rate_min = 44100; | ||
151 | } | ||
150 | /* fall through */ | 152 | /* fall through */ |
151 | case PCM_A: | 153 | case PCM_A: |
152 | case PCM_B: | 154 | case PCM_B: |
@@ -430,17 +432,36 @@ static int oxygen_rec_c_hw_params(struct snd_pcm_substream *substream, | |||
430 | struct snd_pcm_hw_params *hw_params) | 432 | struct snd_pcm_hw_params *hw_params) |
431 | { | 433 | { |
432 | struct oxygen *chip = snd_pcm_substream_chip(substream); | 434 | struct oxygen *chip = snd_pcm_substream_chip(substream); |
435 | bool is_spdif; | ||
433 | int err; | 436 | int err; |
434 | 437 | ||
435 | err = oxygen_hw_params(substream, hw_params); | 438 | err = oxygen_hw_params(substream, hw_params); |
436 | if (err < 0) | 439 | if (err < 0) |
437 | return err; | 440 | return err; |
438 | 441 | ||
442 | is_spdif = chip->model.device_config & CAPTURE_1_FROM_SPDIF; | ||
443 | |||
439 | spin_lock_irq(&chip->reg_lock); | 444 | spin_lock_irq(&chip->reg_lock); |
440 | oxygen_write8_masked(chip, OXYGEN_REC_FORMAT, | 445 | oxygen_write8_masked(chip, OXYGEN_REC_FORMAT, |
441 | oxygen_format(hw_params) << OXYGEN_REC_FORMAT_C_SHIFT, | 446 | oxygen_format(hw_params) << OXYGEN_REC_FORMAT_C_SHIFT, |
442 | OXYGEN_REC_FORMAT_C_MASK); | 447 | OXYGEN_REC_FORMAT_C_MASK); |
448 | if (!is_spdif) | ||
449 | oxygen_write16_masked(chip, OXYGEN_I2S_C_FORMAT, | ||
450 | oxygen_rate(hw_params) | | ||
451 | chip->model.adc_i2s_format | | ||
452 | get_mclk(chip, PCM_B, hw_params) | | ||
453 | oxygen_i2s_bits(hw_params), | ||
454 | OXYGEN_I2S_RATE_MASK | | ||
455 | OXYGEN_I2S_FORMAT_MASK | | ||
456 | OXYGEN_I2S_MCLK_MASK | | ||
457 | OXYGEN_I2S_BITS_MASK); | ||
443 | spin_unlock_irq(&chip->reg_lock); | 458 | spin_unlock_irq(&chip->reg_lock); |
459 | |||
460 | if (!is_spdif) { | ||
461 | mutex_lock(&chip->mutex); | ||
462 | chip->model.set_adc_params(chip, hw_params); | ||
463 | mutex_unlock(&chip->mutex); | ||
464 | } | ||
444 | return 0; | 465 | return 0; |
445 | } | 466 | } |
446 | 467 | ||
@@ -676,11 +697,6 @@ static struct snd_pcm_ops oxygen_ac97_ops = { | |||
676 | .pointer = oxygen_pointer, | 697 | .pointer = oxygen_pointer, |
677 | }; | 698 | }; |
678 | 699 | ||
679 | static void oxygen_pcm_free(struct snd_pcm *pcm) | ||
680 | { | ||
681 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
682 | } | ||
683 | |||
684 | int oxygen_pcm_init(struct oxygen *chip) | 700 | int oxygen_pcm_init(struct oxygen *chip) |
685 | { | 701 | { |
686 | struct snd_pcm *pcm; | 702 | struct snd_pcm *pcm; |
@@ -705,7 +721,6 @@ int oxygen_pcm_init(struct oxygen *chip) | |||
705 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, | 721 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, |
706 | &oxygen_rec_b_ops); | 722 | &oxygen_rec_b_ops); |
707 | pcm->private_data = chip; | 723 | pcm->private_data = chip; |
708 | pcm->private_free = oxygen_pcm_free; | ||
709 | strcpy(pcm->name, "Multichannel"); | 724 | strcpy(pcm->name, "Multichannel"); |
710 | if (outs) | 725 | if (outs) |
711 | snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream, | 726 | snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream, |
@@ -734,7 +749,6 @@ int oxygen_pcm_init(struct oxygen *chip) | |||
734 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, | 749 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, |
735 | &oxygen_rec_c_ops); | 750 | &oxygen_rec_c_ops); |
736 | pcm->private_data = chip; | 751 | pcm->private_data = chip; |
737 | pcm->private_free = oxygen_pcm_free; | ||
738 | strcpy(pcm->name, "Digital"); | 752 | strcpy(pcm->name, "Digital"); |
739 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 753 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
740 | snd_dma_pci_data(chip->pci), | 754 | snd_dma_pci_data(chip->pci), |
@@ -765,12 +779,29 @@ int oxygen_pcm_init(struct oxygen *chip) | |||
765 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, | 779 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, |
766 | &oxygen_rec_b_ops); | 780 | &oxygen_rec_b_ops); |
767 | pcm->private_data = chip; | 781 | pcm->private_data = chip; |
768 | pcm->private_free = oxygen_pcm_free; | ||
769 | strcpy(pcm->name, outs ? "Front Panel" : "Analog 2"); | 782 | strcpy(pcm->name, outs ? "Front Panel" : "Analog 2"); |
770 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 783 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
771 | snd_dma_pci_data(chip->pci), | 784 | snd_dma_pci_data(chip->pci), |
772 | DEFAULT_BUFFER_BYTES, | 785 | DEFAULT_BUFFER_BYTES, |
773 | BUFFER_BYTES_MAX); | 786 | BUFFER_BYTES_MAX); |
774 | } | 787 | } |
788 | |||
789 | ins = !!(chip->model.device_config & CAPTURE_3_FROM_I2S_3); | ||
790 | if (ins) { | ||
791 | err = snd_pcm_new(chip->card, "Analog3", 3, 0, ins, &pcm); | ||
792 | if (err < 0) | ||
793 | return err; | ||
794 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, | ||
795 | &oxygen_rec_c_ops); | ||
796 | oxygen_write8_masked(chip, OXYGEN_REC_ROUTING, | ||
797 | OXYGEN_REC_C_ROUTE_I2S_ADC_3, | ||
798 | OXYGEN_REC_C_ROUTE_MASK); | ||
799 | pcm->private_data = chip; | ||
800 | strcpy(pcm->name, "Analog 3"); | ||
801 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | ||
802 | snd_dma_pci_data(chip->pci), | ||
803 | DEFAULT_BUFFER_BYTES, | ||
804 | BUFFER_BYTES_MAX); | ||
805 | } | ||
775 | return 0; | 806 | return 0; |
776 | } | 807 | } |
diff --git a/sound/pci/oxygen/se6x.c b/sound/pci/oxygen/se6x.c new file mode 100644 index 000000000000..f70d514c1084 --- /dev/null +++ b/sound/pci/oxygen/se6x.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /* | ||
2 | * C-Media CMI8787 driver for the Studio Evolution SE6X | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * | ||
6 | * This driver is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License, version 2. | ||
8 | * | ||
9 | * This driver is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this driver; if not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | /* | ||
19 | * CMI8787: | ||
20 | * | ||
21 | * SPI -> microcontroller (not actually used) | ||
22 | * GPIO 0 -> do. | ||
23 | * GPIO 2 -> do. | ||
24 | * | ||
25 | * DAC0 -> both PCM1792A (L+R, each in mono mode) | ||
26 | * ADC1 <- 1st PCM1804 | ||
27 | * ADC2 <- 2nd PCM1804 | ||
28 | * ADC3 <- 3rd PCM1804 | ||
29 | */ | ||
30 | |||
31 | #include <linux/pci.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <sound/core.h> | ||
34 | #include <sound/control.h> | ||
35 | #include <sound/initval.h> | ||
36 | #include <sound/pcm.h> | ||
37 | #include "oxygen.h" | ||
38 | |||
39 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | ||
40 | MODULE_DESCRIPTION("Studio Evolution SE6X driver"); | ||
41 | MODULE_LICENSE("GPL v2"); | ||
42 | MODULE_SUPPORTED_DEVICE("{{Studio Evolution,SE6X}}"); | ||
43 | |||
44 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
45 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
46 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
47 | |||
48 | module_param_array(index, int, NULL, 0444); | ||
49 | MODULE_PARM_DESC(index, "card index"); | ||
50 | module_param_array(id, charp, NULL, 0444); | ||
51 | MODULE_PARM_DESC(id, "ID string"); | ||
52 | module_param_array(enable, bool, NULL, 0444); | ||
53 | MODULE_PARM_DESC(enable, "enable card"); | ||
54 | |||
55 | static const struct pci_device_id se6x_ids[] = { | ||
56 | { OXYGEN_PCI_SUBID(0x13f6, 0x8788) }, | ||
57 | { } | ||
58 | }; | ||
59 | MODULE_DEVICE_TABLE(pci, se6x_ids); | ||
60 | |||
61 | static void se6x_init(struct oxygen *chip) | ||
62 | { | ||
63 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x005); | ||
64 | |||
65 | snd_component_add(chip->card, "PCM1792A"); | ||
66 | snd_component_add(chip->card, "PCM1804"); | ||
67 | } | ||
68 | |||
69 | static int se6x_control_filter(struct snd_kcontrol_new *template) | ||
70 | { | ||
71 | /* no DAC volume/mute */ | ||
72 | if (!strncmp(template->name, "Master Playback ", 16)) | ||
73 | return 1; | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static void se6x_cleanup(struct oxygen *chip) | ||
78 | { | ||
79 | } | ||
80 | |||
81 | static void set_pcm1792a_params(struct oxygen *chip, | ||
82 | struct snd_pcm_hw_params *params) | ||
83 | { | ||
84 | /* nothing to do (the microcontroller monitors DAC_LRCK) */ | ||
85 | } | ||
86 | |||
87 | static void set_pcm1804_params(struct oxygen *chip, | ||
88 | struct snd_pcm_hw_params *params) | ||
89 | { | ||
90 | } | ||
91 | |||
92 | static unsigned int se6x_adjust_dac_routing(struct oxygen *chip, | ||
93 | unsigned int play_routing) | ||
94 | { | ||
95 | /* route the same stereo pair to DAC0 and DAC1 */ | ||
96 | return ( play_routing & OXYGEN_PLAY_DAC0_SOURCE_MASK) | | ||
97 | ((play_routing << 2) & OXYGEN_PLAY_DAC1_SOURCE_MASK); | ||
98 | } | ||
99 | |||
100 | static const struct oxygen_model model_se6x = { | ||
101 | .shortname = "Studio Evolution SE6X", | ||
102 | .longname = "C-Media Oxygen HD Audio", | ||
103 | .chip = "CMI8787", | ||
104 | .init = se6x_init, | ||
105 | .control_filter = se6x_control_filter, | ||
106 | .cleanup = se6x_cleanup, | ||
107 | .set_dac_params = set_pcm1792a_params, | ||
108 | .set_adc_params = set_pcm1804_params, | ||
109 | .adjust_dac_routing = se6x_adjust_dac_routing, | ||
110 | .device_config = PLAYBACK_0_TO_I2S | | ||
111 | CAPTURE_0_FROM_I2S_1 | | ||
112 | CAPTURE_2_FROM_I2S_2 | | ||
113 | CAPTURE_3_FROM_I2S_3, | ||
114 | .dac_channels_pcm = 2, | ||
115 | .function_flags = OXYGEN_FUNCTION_SPI, | ||
116 | .dac_mclks = OXYGEN_MCLKS(256, 128, 128), | ||
117 | .adc_mclks = OXYGEN_MCLKS(256, 256, 128), | ||
118 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | ||
119 | .adc_i2s_format = OXYGEN_I2S_FORMAT_I2S, | ||
120 | }; | ||
121 | |||
122 | static int se6x_get_model(struct oxygen *chip, | ||
123 | const struct pci_device_id *pci_id) | ||
124 | { | ||
125 | chip->model = model_se6x; | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int se6x_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | ||
130 | { | ||
131 | static int dev; | ||
132 | int err; | ||
133 | |||
134 | if (dev >= SNDRV_CARDS) | ||
135 | return -ENODEV; | ||
136 | if (!enable[dev]) { | ||
137 | ++dev; | ||
138 | return -ENOENT; | ||
139 | } | ||
140 | err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE, | ||
141 | se6x_ids, se6x_get_model); | ||
142 | if (err >= 0) | ||
143 | ++dev; | ||
144 | return err; | ||
145 | } | ||
146 | |||
147 | static struct pci_driver se6x_driver = { | ||
148 | .name = KBUILD_MODNAME, | ||
149 | .id_table = se6x_ids, | ||
150 | .probe = se6x_probe, | ||
151 | .remove = oxygen_pci_remove, | ||
152 | #ifdef CONFIG_PM_SLEEP | ||
153 | .driver = { | ||
154 | .pm = &oxygen_pci_pm, | ||
155 | }, | ||
156 | #endif | ||
157 | .shutdown = oxygen_pci_shutdown, | ||
158 | }; | ||
159 | |||
160 | module_pci_driver(se6x_driver); | ||
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 6abc2ac8fffb..a1521047e619 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c | |||
@@ -1153,7 +1153,6 @@ static void riptide_handleirq(unsigned long dev_id) | |||
1153 | #ifdef CONFIG_PM_SLEEP | 1153 | #ifdef CONFIG_PM_SLEEP |
1154 | static int riptide_suspend(struct device *dev) | 1154 | static int riptide_suspend(struct device *dev) |
1155 | { | 1155 | { |
1156 | struct pci_dev *pci = to_pci_dev(dev); | ||
1157 | struct snd_card *card = dev_get_drvdata(dev); | 1156 | struct snd_card *card = dev_get_drvdata(dev); |
1158 | struct snd_riptide *chip = card->private_data; | 1157 | struct snd_riptide *chip = card->private_data; |
1159 | 1158 | ||
@@ -1161,27 +1160,14 @@ static int riptide_suspend(struct device *dev) | |||
1161 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 1160 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
1162 | snd_pcm_suspend_all(chip->pcm); | 1161 | snd_pcm_suspend_all(chip->pcm); |
1163 | snd_ac97_suspend(chip->ac97); | 1162 | snd_ac97_suspend(chip->ac97); |
1164 | pci_disable_device(pci); | ||
1165 | pci_save_state(pci); | ||
1166 | pci_set_power_state(pci, PCI_D3hot); | ||
1167 | return 0; | 1163 | return 0; |
1168 | } | 1164 | } |
1169 | 1165 | ||
1170 | static int riptide_resume(struct device *dev) | 1166 | static int riptide_resume(struct device *dev) |
1171 | { | 1167 | { |
1172 | struct pci_dev *pci = to_pci_dev(dev); | ||
1173 | struct snd_card *card = dev_get_drvdata(dev); | 1168 | struct snd_card *card = dev_get_drvdata(dev); |
1174 | struct snd_riptide *chip = card->private_data; | 1169 | struct snd_riptide *chip = card->private_data; |
1175 | 1170 | ||
1176 | pci_set_power_state(pci, PCI_D0); | ||
1177 | pci_restore_state(pci); | ||
1178 | if (pci_enable_device(pci) < 0) { | ||
1179 | printk(KERN_ERR "riptide: pci_enable_device failed, " | ||
1180 | "disabling device\n"); | ||
1181 | snd_card_disconnect(card); | ||
1182 | return -EIO; | ||
1183 | } | ||
1184 | pci_set_master(pci); | ||
1185 | snd_riptide_initialize(chip); | 1171 | snd_riptide_initialize(chip); |
1186 | snd_ac97_resume(chip->ac97); | 1172 | snd_ac97_resume(chip->ac97); |
1187 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 1173 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
@@ -1706,14 +1692,11 @@ static struct snd_pcm_ops snd_riptide_capture_ops = { | |||
1706 | .pointer = snd_riptide_pointer, | 1692 | .pointer = snd_riptide_pointer, |
1707 | }; | 1693 | }; |
1708 | 1694 | ||
1709 | static int | 1695 | static int snd_riptide_pcm(struct snd_riptide *chip, int device) |
1710 | snd_riptide_pcm(struct snd_riptide *chip, int device, struct snd_pcm **rpcm) | ||
1711 | { | 1696 | { |
1712 | struct snd_pcm *pcm; | 1697 | struct snd_pcm *pcm; |
1713 | int err; | 1698 | int err; |
1714 | 1699 | ||
1715 | if (rpcm) | ||
1716 | *rpcm = NULL; | ||
1717 | if ((err = | 1700 | if ((err = |
1718 | snd_pcm_new(chip->card, "RIPTIDE", device, PLAYBACK_SUBSTREAMS, 1, | 1701 | snd_pcm_new(chip->card, "RIPTIDE", device, PLAYBACK_SUBSTREAMS, 1, |
1719 | &pcm)) < 0) | 1702 | &pcm)) < 0) |
@@ -1729,8 +1712,6 @@ snd_riptide_pcm(struct snd_riptide *chip, int device, struct snd_pcm **rpcm) | |||
1729 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, | 1712 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, |
1730 | snd_dma_pci_data(chip->pci), | 1713 | snd_dma_pci_data(chip->pci), |
1731 | 64 * 1024, 128 * 1024); | 1714 | 64 * 1024, 128 * 1024); |
1732 | if (rpcm) | ||
1733 | *rpcm = pcm; | ||
1734 | return 0; | 1715 | return 0; |
1735 | } | 1716 | } |
1736 | 1717 | ||
@@ -2092,7 +2073,7 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
2092 | if (err < 0) | 2073 | if (err < 0) |
2093 | goto error; | 2074 | goto error; |
2094 | card->private_data = chip; | 2075 | card->private_data = chip; |
2095 | err = snd_riptide_pcm(chip, 0, NULL); | 2076 | err = snd_riptide_pcm(chip, 0); |
2096 | if (err < 0) | 2077 | if (err < 0) |
2097 | goto error; | 2078 | goto error; |
2098 | err = snd_riptide_mixer(chip); | 2079 | err = snd_riptide_mixer(chip); |
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index 6c60dcd2e5a1..1a7affad7164 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c | |||
@@ -632,7 +632,7 @@ snd_rme32_setframelog(struct rme32 * rme32, int n_channels, int is_playback) | |||
632 | } | 632 | } |
633 | } | 633 | } |
634 | 634 | ||
635 | static int snd_rme32_setformat(struct rme32 * rme32, int format) | 635 | static int snd_rme32_setformat(struct rme32 *rme32, snd_pcm_format_t format) |
636 | { | 636 | { |
637 | switch (format) { | 637 | switch (format) { |
638 | case SNDRV_PCM_FORMAT_S16_LE: | 638 | case SNDRV_PCM_FORMAT_S16_LE: |
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 2f1a85185a16..236ac1d48184 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c | |||
@@ -922,8 +922,7 @@ snd_rme96_setframelog(struct rme96 *rme96, | |||
922 | } | 922 | } |
923 | 923 | ||
924 | static int | 924 | static int |
925 | snd_rme96_playback_setformat(struct rme96 *rme96, | 925 | snd_rme96_playback_setformat(struct rme96 *rme96, snd_pcm_format_t format) |
926 | int format) | ||
927 | { | 926 | { |
928 | switch (format) { | 927 | switch (format) { |
929 | case SNDRV_PCM_FORMAT_S16_LE: | 928 | case SNDRV_PCM_FORMAT_S16_LE: |
@@ -940,8 +939,7 @@ snd_rme96_playback_setformat(struct rme96 *rme96, | |||
940 | } | 939 | } |
941 | 940 | ||
942 | static int | 941 | static int |
943 | snd_rme96_capture_setformat(struct rme96 *rme96, | 942 | snd_rme96_capture_setformat(struct rme96 *rme96, snd_pcm_format_t format) |
944 | int format) | ||
945 | { | 943 | { |
946 | switch (format) { | 944 | switch (format) { |
947 | case SNDRV_PCM_FORMAT_S16_LE: | 945 | case SNDRV_PCM_FORMAT_S16_LE: |
@@ -2358,7 +2356,6 @@ snd_rme96_create_switches(struct snd_card *card, | |||
2358 | 2356 | ||
2359 | static int rme96_suspend(struct device *dev) | 2357 | static int rme96_suspend(struct device *dev) |
2360 | { | 2358 | { |
2361 | struct pci_dev *pci = to_pci_dev(dev); | ||
2362 | struct snd_card *card = dev_get_drvdata(dev); | 2359 | struct snd_card *card = dev_get_drvdata(dev); |
2363 | struct rme96 *rme96 = card->private_data; | 2360 | struct rme96 *rme96 = card->private_data; |
2364 | 2361 | ||
@@ -2381,26 +2378,14 @@ static int rme96_suspend(struct device *dev) | |||
2381 | /* disable the DAC */ | 2378 | /* disable the DAC */ |
2382 | rme96->areg &= ~RME96_AR_DAC_EN; | 2379 | rme96->areg &= ~RME96_AR_DAC_EN; |
2383 | writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); | 2380 | writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); |
2384 | |||
2385 | pci_disable_device(pci); | ||
2386 | pci_save_state(pci); | ||
2387 | |||
2388 | return 0; | 2381 | return 0; |
2389 | } | 2382 | } |
2390 | 2383 | ||
2391 | static int rme96_resume(struct device *dev) | 2384 | static int rme96_resume(struct device *dev) |
2392 | { | 2385 | { |
2393 | struct pci_dev *pci = to_pci_dev(dev); | ||
2394 | struct snd_card *card = dev_get_drvdata(dev); | 2386 | struct snd_card *card = dev_get_drvdata(dev); |
2395 | struct rme96 *rme96 = card->private_data; | 2387 | struct rme96 *rme96 = card->private_data; |
2396 | 2388 | ||
2397 | pci_restore_state(pci); | ||
2398 | if (pci_enable_device(pci) < 0) { | ||
2399 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
2400 | snd_card_disconnect(card); | ||
2401 | return -EIO; | ||
2402 | } | ||
2403 | |||
2404 | /* reset playback and record buffer pointers */ | 2389 | /* reset playback and record buffer pointers */ |
2405 | writel(0, rme96->iobase + RME96_IO_SET_PLAY_POS | 2390 | writel(0, rme96->iobase + RME96_IO_SET_PLAY_POS |
2406 | + rme96->playback_pointer); | 2391 | + rme96->playback_pointer); |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index cf5a6c8b9a63..98a2d911ef17 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -1428,10 +1428,8 @@ static void snd_hdsp_midi_output_timer(unsigned long data) | |||
1428 | leaving istimer wherever it was set before. | 1428 | leaving istimer wherever it was set before. |
1429 | */ | 1429 | */ |
1430 | 1430 | ||
1431 | if (hmidi->istimer) { | 1431 | if (hmidi->istimer) |
1432 | hmidi->timer.expires = 1 + jiffies; | 1432 | mod_timer(&hmidi->timer, 1 + jiffies); |
1433 | add_timer(&hmidi->timer); | ||
1434 | } | ||
1435 | 1433 | ||
1436 | spin_unlock_irqrestore (&hmidi->lock, flags); | 1434 | spin_unlock_irqrestore (&hmidi->lock, flags); |
1437 | } | 1435 | } |
@@ -1445,11 +1443,9 @@ static void snd_hdsp_midi_output_trigger(struct snd_rawmidi_substream *substream | |||
1445 | spin_lock_irqsave (&hmidi->lock, flags); | 1443 | spin_lock_irqsave (&hmidi->lock, flags); |
1446 | if (up) { | 1444 | if (up) { |
1447 | if (!hmidi->istimer) { | 1445 | if (!hmidi->istimer) { |
1448 | init_timer(&hmidi->timer); | 1446 | setup_timer(&hmidi->timer, snd_hdsp_midi_output_timer, |
1449 | hmidi->timer.function = snd_hdsp_midi_output_timer; | 1447 | (unsigned long) hmidi); |
1450 | hmidi->timer.data = (unsigned long) hmidi; | 1448 | mod_timer(&hmidi->timer, 1 + jiffies); |
1451 | hmidi->timer.expires = 1 + jiffies; | ||
1452 | add_timer(&hmidi->timer); | ||
1453 | hmidi->istimer++; | 1449 | hmidi->istimer++; |
1454 | } | 1450 | } |
1455 | } else { | 1451 | } else { |
@@ -5309,9 +5305,7 @@ static int snd_hdsp_free(struct hdsp *hdsp) | |||
5309 | 5305 | ||
5310 | release_firmware(hdsp->firmware); | 5306 | release_firmware(hdsp->firmware); |
5311 | vfree(hdsp->fw_uploaded); | 5307 | vfree(hdsp->fw_uploaded); |
5312 | 5308 | iounmap(hdsp->iobase); | |
5313 | if (hdsp->iobase) | ||
5314 | iounmap(hdsp->iobase); | ||
5315 | 5309 | ||
5316 | if (hdsp->port) | 5310 | if (hdsp->port) |
5317 | pci_release_regions(hdsp->pci); | 5311 | pci_release_regions(hdsp->pci); |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 3342705a5715..1716323fed9c 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -1957,10 +1957,8 @@ static void snd_hdspm_midi_output_timer(unsigned long data) | |||
1957 | leaving istimer wherever it was set before. | 1957 | leaving istimer wherever it was set before. |
1958 | */ | 1958 | */ |
1959 | 1959 | ||
1960 | if (hmidi->istimer) { | 1960 | if (hmidi->istimer) |
1961 | hmidi->timer.expires = 1 + jiffies; | 1961 | mod_timer(&hmidi->timer, 1 + jiffies); |
1962 | add_timer(&hmidi->timer); | ||
1963 | } | ||
1964 | 1962 | ||
1965 | spin_unlock_irqrestore (&hmidi->lock, flags); | 1963 | spin_unlock_irqrestore (&hmidi->lock, flags); |
1966 | } | 1964 | } |
@@ -1975,11 +1973,9 @@ snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) | |||
1975 | spin_lock_irqsave (&hmidi->lock, flags); | 1973 | spin_lock_irqsave (&hmidi->lock, flags); |
1976 | if (up) { | 1974 | if (up) { |
1977 | if (!hmidi->istimer) { | 1975 | if (!hmidi->istimer) { |
1978 | init_timer(&hmidi->timer); | 1976 | setup_timer(&hmidi->timer, snd_hdspm_midi_output_timer, |
1979 | hmidi->timer.function = snd_hdspm_midi_output_timer; | 1977 | (unsigned long) hmidi); |
1980 | hmidi->timer.data = (unsigned long) hmidi; | 1978 | mod_timer(&hmidi->timer, 1 + jiffies); |
1981 | hmidi->timer.expires = 1 + jiffies; | ||
1982 | add_timer(&hmidi->timer); | ||
1983 | hmidi->istimer++; | 1979 | hmidi->istimer++; |
1984 | } | 1980 | } |
1985 | } else { | 1981 | } else { |
@@ -6965,9 +6961,7 @@ static int snd_hdspm_free(struct hdspm * hdspm) | |||
6965 | free_irq(hdspm->irq, (void *) hdspm); | 6961 | free_irq(hdspm->irq, (void *) hdspm); |
6966 | 6962 | ||
6967 | kfree(hdspm->mixer); | 6963 | kfree(hdspm->mixer); |
6968 | 6964 | iounmap(hdspm->iobase); | |
6969 | if (hdspm->iobase) | ||
6970 | iounmap(hdspm->iobase); | ||
6971 | 6965 | ||
6972 | if (hdspm->port) | 6966 | if (hdspm->port) |
6973 | pci_release_regions(hdspm->pci); | 6967 | pci_release_regions(hdspm->pci); |
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index 6521521853b8..648911c1a226 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c | |||
@@ -1756,8 +1756,7 @@ static int snd_rme9652_free(struct snd_rme9652 *rme9652) | |||
1756 | 1756 | ||
1757 | if (rme9652->irq >= 0) | 1757 | if (rme9652->irq >= 0) |
1758 | free_irq(rme9652->irq, (void *)rme9652); | 1758 | free_irq(rme9652->irq, (void *)rme9652); |
1759 | if (rme9652->iobase) | 1759 | iounmap(rme9652->iobase); |
1760 | iounmap(rme9652->iobase); | ||
1761 | if (rme9652->port) | 1760 | if (rme9652->port) |
1762 | pci_release_regions(rme9652->pci); | 1761 | pci_release_regions(rme9652->pci); |
1763 | 1762 | ||
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index 7f6a0a0d115a..efe669b80256 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c | |||
@@ -1064,12 +1064,9 @@ static int sis_chip_free(struct sis7019 *sis) | |||
1064 | if (sis->irq >= 0) | 1064 | if (sis->irq >= 0) |
1065 | free_irq(sis->irq, sis); | 1065 | free_irq(sis->irq, sis); |
1066 | 1066 | ||
1067 | if (sis->ioaddr) | 1067 | iounmap(sis->ioaddr); |
1068 | iounmap(sis->ioaddr); | ||
1069 | |||
1070 | pci_release_regions(sis->pci); | 1068 | pci_release_regions(sis->pci); |
1071 | pci_disable_device(sis->pci); | 1069 | pci_disable_device(sis->pci); |
1072 | |||
1073 | sis_free_suspend(sis); | 1070 | sis_free_suspend(sis); |
1074 | return 0; | 1071 | return 0; |
1075 | } | 1072 | } |
@@ -1211,7 +1208,6 @@ static int sis_chip_init(struct sis7019 *sis) | |||
1211 | #ifdef CONFIG_PM_SLEEP | 1208 | #ifdef CONFIG_PM_SLEEP |
1212 | static int sis_suspend(struct device *dev) | 1209 | static int sis_suspend(struct device *dev) |
1213 | { | 1210 | { |
1214 | struct pci_dev *pci = to_pci_dev(dev); | ||
1215 | struct snd_card *card = dev_get_drvdata(dev); | 1211 | struct snd_card *card = dev_get_drvdata(dev); |
1216 | struct sis7019 *sis = card->private_data; | 1212 | struct sis7019 *sis = card->private_data; |
1217 | void __iomem *ioaddr = sis->ioaddr; | 1213 | void __iomem *ioaddr = sis->ioaddr; |
@@ -1240,9 +1236,6 @@ static int sis_suspend(struct device *dev) | |||
1240 | ioaddr += 4096; | 1236 | ioaddr += 4096; |
1241 | } | 1237 | } |
1242 | 1238 | ||
1243 | pci_disable_device(pci); | ||
1244 | pci_save_state(pci); | ||
1245 | pci_set_power_state(pci, PCI_D3hot); | ||
1246 | return 0; | 1239 | return 0; |
1247 | } | 1240 | } |
1248 | 1241 | ||
@@ -1254,14 +1247,6 @@ static int sis_resume(struct device *dev) | |||
1254 | void __iomem *ioaddr = sis->ioaddr; | 1247 | void __iomem *ioaddr = sis->ioaddr; |
1255 | int i; | 1248 | int i; |
1256 | 1249 | ||
1257 | pci_set_power_state(pci, PCI_D0); | ||
1258 | pci_restore_state(pci); | ||
1259 | |||
1260 | if (pci_enable_device(pci) < 0) { | ||
1261 | dev_err(&pci->dev, "unable to re-enable device\n"); | ||
1262 | goto error; | ||
1263 | } | ||
1264 | |||
1265 | if (sis_chip_init(sis)) { | 1250 | if (sis_chip_init(sis)) { |
1266 | dev_err(&pci->dev, "unable to re-init controller\n"); | 1251 | dev_err(&pci->dev, "unable to re-init controller\n"); |
1267 | goto error; | 1252 | goto error; |
@@ -1284,7 +1269,6 @@ static int sis_resume(struct device *dev) | |||
1284 | memset(sis->suspend_state[0], 0, 4096); | 1269 | memset(sis->suspend_state[0], 0, 4096); |
1285 | 1270 | ||
1286 | sis->irq = pci->irq; | 1271 | sis->irq = pci->irq; |
1287 | pci_set_master(pci); | ||
1288 | 1272 | ||
1289 | if (sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT) | 1273 | if (sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT) |
1290 | snd_ac97_resume(sis->ac97[0]); | 1274 | snd_ac97_resume(sis->ac97[0]); |
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 313a7328bf9c..34cee5c1abd8 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c | |||
@@ -880,8 +880,7 @@ static struct snd_pcm_ops snd_sonicvibes_capture_ops = { | |||
880 | .pointer = snd_sonicvibes_capture_pointer, | 880 | .pointer = snd_sonicvibes_capture_pointer, |
881 | }; | 881 | }; |
882 | 882 | ||
883 | static int snd_sonicvibes_pcm(struct sonicvibes *sonic, int device, | 883 | static int snd_sonicvibes_pcm(struct sonicvibes *sonic, int device) |
884 | struct snd_pcm **rpcm) | ||
885 | { | 884 | { |
886 | struct snd_pcm *pcm; | 885 | struct snd_pcm *pcm; |
887 | int err; | 886 | int err; |
@@ -902,8 +901,6 @@ static int snd_sonicvibes_pcm(struct sonicvibes *sonic, int device, | |||
902 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 901 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
903 | snd_dma_pci_data(sonic->pci), 64*1024, 128*1024); | 902 | snd_dma_pci_data(sonic->pci), 64*1024, 128*1024); |
904 | 903 | ||
905 | if (rpcm) | ||
906 | *rpcm = pcm; | ||
907 | return 0; | 904 | return 0; |
908 | } | 905 | } |
909 | 906 | ||
@@ -1491,7 +1488,7 @@ static int snd_sonic_probe(struct pci_dev *pci, | |||
1491 | (unsigned long long)pci_resource_start(pci, 1), | 1488 | (unsigned long long)pci_resource_start(pci, 1), |
1492 | sonic->irq); | 1489 | sonic->irq); |
1493 | 1490 | ||
1494 | if ((err = snd_sonicvibes_pcm(sonic, 0, NULL)) < 0) { | 1491 | if ((err = snd_sonicvibes_pcm(sonic, 0)) < 0) { |
1495 | snd_card_free(card); | 1492 | snd_card_free(card); |
1496 | return err; | 1493 | return err; |
1497 | } | 1494 | } |
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c index a54cd6879b31..cedf13b64803 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c | |||
@@ -127,21 +127,21 @@ static int snd_trident_probe(struct pci_dev *pci, | |||
127 | sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d", | 127 | sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d", |
128 | card->shortname, trident->port, trident->irq); | 128 | card->shortname, trident->port, trident->irq); |
129 | 129 | ||
130 | if ((err = snd_trident_pcm(trident, pcm_dev++, NULL)) < 0) { | 130 | if ((err = snd_trident_pcm(trident, pcm_dev++)) < 0) { |
131 | snd_card_free(card); | 131 | snd_card_free(card); |
132 | return err; | 132 | return err; |
133 | } | 133 | } |
134 | switch (trident->device) { | 134 | switch (trident->device) { |
135 | case TRIDENT_DEVICE_ID_DX: | 135 | case TRIDENT_DEVICE_ID_DX: |
136 | case TRIDENT_DEVICE_ID_NX: | 136 | case TRIDENT_DEVICE_ID_NX: |
137 | if ((err = snd_trident_foldback_pcm(trident, pcm_dev++, NULL)) < 0) { | 137 | if ((err = snd_trident_foldback_pcm(trident, pcm_dev++)) < 0) { |
138 | snd_card_free(card); | 138 | snd_card_free(card); |
139 | return err; | 139 | return err; |
140 | } | 140 | } |
141 | break; | 141 | break; |
142 | } | 142 | } |
143 | if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) { | 143 | if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) { |
144 | if ((err = snd_trident_spdif_pcm(trident, pcm_dev++, NULL)) < 0) { | 144 | if ((err = snd_trident_spdif_pcm(trident, pcm_dev++)) < 0) { |
145 | snd_card_free(card); | 145 | snd_card_free(card); |
146 | return err; | 146 | return err; |
147 | } | 147 | } |
diff --git a/sound/pci/trident/trident.h b/sound/pci/trident/trident.h index 5f110eb56e47..9624e5937719 100644 --- a/sound/pci/trident/trident.h +++ b/sound/pci/trident/trident.h | |||
@@ -420,9 +420,9 @@ int snd_trident_create(struct snd_card *card, | |||
420 | struct snd_trident ** rtrident); | 420 | struct snd_trident ** rtrident); |
421 | int snd_trident_create_gameport(struct snd_trident *trident); | 421 | int snd_trident_create_gameport(struct snd_trident *trident); |
422 | 422 | ||
423 | int snd_trident_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm); | 423 | int snd_trident_pcm(struct snd_trident *trident, int device); |
424 | int snd_trident_foldback_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm); | 424 | int snd_trident_foldback_pcm(struct snd_trident *trident, int device); |
425 | int snd_trident_spdif_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm); | 425 | int snd_trident_spdif_pcm(struct snd_trident *trident, int device); |
426 | int snd_trident_attach_synthesizer(struct snd_trident * trident); | 426 | int snd_trident_attach_synthesizer(struct snd_trident * trident); |
427 | struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type, | 427 | struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type, |
428 | int client, int port); | 428 | int client, int port); |
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 57cd757acfe7..2870cbf8cee0 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c | |||
@@ -2172,14 +2172,11 @@ static struct snd_pcm_ops snd_trident_spdif_7018_ops = { | |||
2172 | 2172 | ||
2173 | ---------------------------------------------------------------------------*/ | 2173 | ---------------------------------------------------------------------------*/ |
2174 | 2174 | ||
2175 | int snd_trident_pcm(struct snd_trident *trident, | 2175 | int snd_trident_pcm(struct snd_trident *trident, int device) |
2176 | int device, struct snd_pcm **rpcm) | ||
2177 | { | 2176 | { |
2178 | struct snd_pcm *pcm; | 2177 | struct snd_pcm *pcm; |
2179 | int err; | 2178 | int err; |
2180 | 2179 | ||
2181 | if (rpcm) | ||
2182 | *rpcm = NULL; | ||
2183 | if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, trident->ChanPCM, 1, &pcm)) < 0) | 2180 | if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, trident->ChanPCM, 1, &pcm)) < 0) |
2184 | return err; | 2181 | return err; |
2185 | 2182 | ||
@@ -2214,8 +2211,6 @@ int snd_trident_pcm(struct snd_trident *trident, | |||
2214 | snd_dma_pci_data(trident->pci), 64*1024, 128*1024); | 2211 | snd_dma_pci_data(trident->pci), 64*1024, 128*1024); |
2215 | } | 2212 | } |
2216 | 2213 | ||
2217 | if (rpcm) | ||
2218 | *rpcm = pcm; | ||
2219 | return 0; | 2214 | return 0; |
2220 | } | 2215 | } |
2221 | 2216 | ||
@@ -2230,16 +2225,13 @@ int snd_trident_pcm(struct snd_trident *trident, | |||
2230 | 2225 | ||
2231 | ---------------------------------------------------------------------------*/ | 2226 | ---------------------------------------------------------------------------*/ |
2232 | 2227 | ||
2233 | int snd_trident_foldback_pcm(struct snd_trident *trident, | 2228 | int snd_trident_foldback_pcm(struct snd_trident *trident, int device) |
2234 | int device, struct snd_pcm **rpcm) | ||
2235 | { | 2229 | { |
2236 | struct snd_pcm *foldback; | 2230 | struct snd_pcm *foldback; |
2237 | int err; | 2231 | int err; |
2238 | int num_chan = 3; | 2232 | int num_chan = 3; |
2239 | struct snd_pcm_substream *substream; | 2233 | struct snd_pcm_substream *substream; |
2240 | 2234 | ||
2241 | if (rpcm) | ||
2242 | *rpcm = NULL; | ||
2243 | if (trident->device == TRIDENT_DEVICE_ID_NX) | 2235 | if (trident->device == TRIDENT_DEVICE_ID_NX) |
2244 | num_chan = 4; | 2236 | num_chan = 4; |
2245 | if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, 0, num_chan, &foldback)) < 0) | 2237 | if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, 0, num_chan, &foldback)) < 0) |
@@ -2271,8 +2263,6 @@ int snd_trident_foldback_pcm(struct snd_trident *trident, | |||
2271 | snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV, | 2263 | snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV, |
2272 | snd_dma_pci_data(trident->pci), 64*1024, 128*1024); | 2264 | snd_dma_pci_data(trident->pci), 64*1024, 128*1024); |
2273 | 2265 | ||
2274 | if (rpcm) | ||
2275 | *rpcm = foldback; | ||
2276 | return 0; | 2266 | return 0; |
2277 | } | 2267 | } |
2278 | 2268 | ||
@@ -2287,14 +2277,11 @@ int snd_trident_foldback_pcm(struct snd_trident *trident, | |||
2287 | 2277 | ||
2288 | ---------------------------------------------------------------------------*/ | 2278 | ---------------------------------------------------------------------------*/ |
2289 | 2279 | ||
2290 | int snd_trident_spdif_pcm(struct snd_trident *trident, | 2280 | int snd_trident_spdif_pcm(struct snd_trident *trident, int device) |
2291 | int device, struct snd_pcm **rpcm) | ||
2292 | { | 2281 | { |
2293 | struct snd_pcm *spdif; | 2282 | struct snd_pcm *spdif; |
2294 | int err; | 2283 | int err; |
2295 | 2284 | ||
2296 | if (rpcm) | ||
2297 | *rpcm = NULL; | ||
2298 | if ((err = snd_pcm_new(trident->card, "trident_dx_nx IEC958", device, 1, 0, &spdif)) < 0) | 2285 | if ((err = snd_pcm_new(trident->card, "trident_dx_nx IEC958", device, 1, 0, &spdif)) < 0) |
2299 | return err; | 2286 | return err; |
2300 | 2287 | ||
@@ -2310,8 +2297,6 @@ int snd_trident_spdif_pcm(struct snd_trident *trident, | |||
2310 | 2297 | ||
2311 | snd_pcm_lib_preallocate_pages_for_all(spdif, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 64*1024, 128*1024); | 2298 | snd_pcm_lib_preallocate_pages_for_all(spdif, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 64*1024, 128*1024); |
2312 | 2299 | ||
2313 | if (rpcm) | ||
2314 | *rpcm = spdif; | ||
2315 | return 0; | 2300 | return 0; |
2316 | } | 2301 | } |
2317 | 2302 | ||
@@ -3926,7 +3911,6 @@ static void snd_trident_clear_voices(struct snd_trident * trident, unsigned shor | |||
3926 | #ifdef CONFIG_PM_SLEEP | 3911 | #ifdef CONFIG_PM_SLEEP |
3927 | static int snd_trident_suspend(struct device *dev) | 3912 | static int snd_trident_suspend(struct device *dev) |
3928 | { | 3913 | { |
3929 | struct pci_dev *pci = to_pci_dev(dev); | ||
3930 | struct snd_card *card = dev_get_drvdata(dev); | 3914 | struct snd_card *card = dev_get_drvdata(dev); |
3931 | struct snd_trident *trident = card->private_data; | 3915 | struct snd_trident *trident = card->private_data; |
3932 | 3916 | ||
@@ -3938,28 +3922,14 @@ static int snd_trident_suspend(struct device *dev) | |||
3938 | 3922 | ||
3939 | snd_ac97_suspend(trident->ac97); | 3923 | snd_ac97_suspend(trident->ac97); |
3940 | snd_ac97_suspend(trident->ac97_sec); | 3924 | snd_ac97_suspend(trident->ac97_sec); |
3941 | |||
3942 | pci_disable_device(pci); | ||
3943 | pci_save_state(pci); | ||
3944 | pci_set_power_state(pci, PCI_D3hot); | ||
3945 | return 0; | 3925 | return 0; |
3946 | } | 3926 | } |
3947 | 3927 | ||
3948 | static int snd_trident_resume(struct device *dev) | 3928 | static int snd_trident_resume(struct device *dev) |
3949 | { | 3929 | { |
3950 | struct pci_dev *pci = to_pci_dev(dev); | ||
3951 | struct snd_card *card = dev_get_drvdata(dev); | 3930 | struct snd_card *card = dev_get_drvdata(dev); |
3952 | struct snd_trident *trident = card->private_data; | 3931 | struct snd_trident *trident = card->private_data; |
3953 | 3932 | ||
3954 | pci_set_power_state(pci, PCI_D0); | ||
3955 | pci_restore_state(pci); | ||
3956 | if (pci_enable_device(pci) < 0) { | ||
3957 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
3958 | snd_card_disconnect(card); | ||
3959 | return -EIO; | ||
3960 | } | ||
3961 | pci_set_master(pci); | ||
3962 | |||
3963 | switch (trident->device) { | 3933 | switch (trident->device) { |
3964 | case TRIDENT_DEVICE_ID_DX: | 3934 | case TRIDENT_DEVICE_ID_DX: |
3965 | snd_trident_4d_dx_init(trident); | 3935 | snd_trident_4d_dx_init(trident); |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index e088467fb736..120fccbb2461 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -2271,7 +2271,6 @@ static int snd_via82xx_chip_init(struct via82xx *chip) | |||
2271 | */ | 2271 | */ |
2272 | static int snd_via82xx_suspend(struct device *dev) | 2272 | static int snd_via82xx_suspend(struct device *dev) |
2273 | { | 2273 | { |
2274 | struct pci_dev *pci = to_pci_dev(dev); | ||
2275 | struct snd_card *card = dev_get_drvdata(dev); | 2274 | struct snd_card *card = dev_get_drvdata(dev); |
2276 | struct via82xx *chip = card->private_data; | 2275 | struct via82xx *chip = card->private_data; |
2277 | int i; | 2276 | int i; |
@@ -2291,28 +2290,15 @@ static int snd_via82xx_suspend(struct device *dev) | |||
2291 | chip->capture_src_saved[1] = inb(chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10); | 2290 | chip->capture_src_saved[1] = inb(chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10); |
2292 | } | 2291 | } |
2293 | 2292 | ||
2294 | pci_disable_device(pci); | ||
2295 | pci_save_state(pci); | ||
2296 | pci_set_power_state(pci, PCI_D3hot); | ||
2297 | return 0; | 2293 | return 0; |
2298 | } | 2294 | } |
2299 | 2295 | ||
2300 | static int snd_via82xx_resume(struct device *dev) | 2296 | static int snd_via82xx_resume(struct device *dev) |
2301 | { | 2297 | { |
2302 | struct pci_dev *pci = to_pci_dev(dev); | ||
2303 | struct snd_card *card = dev_get_drvdata(dev); | 2298 | struct snd_card *card = dev_get_drvdata(dev); |
2304 | struct via82xx *chip = card->private_data; | 2299 | struct via82xx *chip = card->private_data; |
2305 | int i; | 2300 | int i; |
2306 | 2301 | ||
2307 | pci_set_power_state(pci, PCI_D0); | ||
2308 | pci_restore_state(pci); | ||
2309 | if (pci_enable_device(pci) < 0) { | ||
2310 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
2311 | snd_card_disconnect(card); | ||
2312 | return -EIO; | ||
2313 | } | ||
2314 | pci_set_master(pci); | ||
2315 | |||
2316 | snd_via82xx_chip_init(chip); | 2302 | snd_via82xx_chip_init(chip); |
2317 | 2303 | ||
2318 | if (chip->chip_type == TYPE_VIA686) { | 2304 | if (chip->chip_type == TYPE_VIA686) { |
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index fd46ffe12e4f..884f49eea495 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c | |||
@@ -1031,7 +1031,6 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip) | |||
1031 | */ | 1031 | */ |
1032 | static int snd_via82xx_suspend(struct device *dev) | 1032 | static int snd_via82xx_suspend(struct device *dev) |
1033 | { | 1033 | { |
1034 | struct pci_dev *pci = to_pci_dev(dev); | ||
1035 | struct snd_card *card = dev_get_drvdata(dev); | 1034 | struct snd_card *card = dev_get_drvdata(dev); |
1036 | struct via82xx_modem *chip = card->private_data; | 1035 | struct via82xx_modem *chip = card->private_data; |
1037 | int i; | 1036 | int i; |
@@ -1043,29 +1042,15 @@ static int snd_via82xx_suspend(struct device *dev) | |||
1043 | snd_via82xx_channel_reset(chip, &chip->devs[i]); | 1042 | snd_via82xx_channel_reset(chip, &chip->devs[i]); |
1044 | synchronize_irq(chip->irq); | 1043 | synchronize_irq(chip->irq); |
1045 | snd_ac97_suspend(chip->ac97); | 1044 | snd_ac97_suspend(chip->ac97); |
1046 | |||
1047 | pci_disable_device(pci); | ||
1048 | pci_save_state(pci); | ||
1049 | pci_set_power_state(pci, PCI_D3hot); | ||
1050 | return 0; | 1045 | return 0; |
1051 | } | 1046 | } |
1052 | 1047 | ||
1053 | static int snd_via82xx_resume(struct device *dev) | 1048 | static int snd_via82xx_resume(struct device *dev) |
1054 | { | 1049 | { |
1055 | struct pci_dev *pci = to_pci_dev(dev); | ||
1056 | struct snd_card *card = dev_get_drvdata(dev); | 1050 | struct snd_card *card = dev_get_drvdata(dev); |
1057 | struct via82xx_modem *chip = card->private_data; | 1051 | struct via82xx_modem *chip = card->private_data; |
1058 | int i; | 1052 | int i; |
1059 | 1053 | ||
1060 | pci_set_power_state(pci, PCI_D0); | ||
1061 | pci_restore_state(pci); | ||
1062 | if (pci_enable_device(pci) < 0) { | ||
1063 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
1064 | snd_card_disconnect(card); | ||
1065 | return -EIO; | ||
1066 | } | ||
1067 | pci_set_master(pci); | ||
1068 | |||
1069 | snd_via82xx_chip_init(chip); | 1054 | snd_via82xx_chip_init(chip); |
1070 | 1055 | ||
1071 | snd_ac97_resume(chip->ac97); | 1056 | snd_ac97_resume(chip->ac97); |
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c index c5a25e39e3a8..ecbaf473fc1e 100644 --- a/sound/pci/vx222/vx222.c +++ b/sound/pci/vx222/vx222.c | |||
@@ -259,32 +259,17 @@ static void snd_vx222_remove(struct pci_dev *pci) | |||
259 | #ifdef CONFIG_PM_SLEEP | 259 | #ifdef CONFIG_PM_SLEEP |
260 | static int snd_vx222_suspend(struct device *dev) | 260 | static int snd_vx222_suspend(struct device *dev) |
261 | { | 261 | { |
262 | struct pci_dev *pci = to_pci_dev(dev); | ||
263 | struct snd_card *card = dev_get_drvdata(dev); | 262 | struct snd_card *card = dev_get_drvdata(dev); |
264 | struct snd_vx222 *vx = card->private_data; | 263 | struct snd_vx222 *vx = card->private_data; |
265 | int err; | ||
266 | 264 | ||
267 | err = snd_vx_suspend(&vx->core); | 265 | return snd_vx_suspend(&vx->core); |
268 | pci_disable_device(pci); | ||
269 | pci_save_state(pci); | ||
270 | pci_set_power_state(pci, PCI_D3hot); | ||
271 | return err; | ||
272 | } | 266 | } |
273 | 267 | ||
274 | static int snd_vx222_resume(struct device *dev) | 268 | static int snd_vx222_resume(struct device *dev) |
275 | { | 269 | { |
276 | struct pci_dev *pci = to_pci_dev(dev); | ||
277 | struct snd_card *card = dev_get_drvdata(dev); | 270 | struct snd_card *card = dev_get_drvdata(dev); |
278 | struct snd_vx222 *vx = card->private_data; | 271 | struct snd_vx222 *vx = card->private_data; |
279 | 272 | ||
280 | pci_set_power_state(pci, PCI_D0); | ||
281 | pci_restore_state(pci); | ||
282 | if (pci_enable_device(pci) < 0) { | ||
283 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
284 | snd_card_disconnect(card); | ||
285 | return -EIO; | ||
286 | } | ||
287 | pci_set_master(pci); | ||
288 | return snd_vx_resume(&vx->core); | 273 | return snd_vx_resume(&vx->core); |
289 | } | 274 | } |
290 | 275 | ||
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 47a192369e8f..812e27a1bcbc 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c | |||
@@ -283,11 +283,11 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, | |||
283 | card->shortname, | 283 | card->shortname, |
284 | chip->reg_area_phys, | 284 | chip->reg_area_phys, |
285 | chip->irq); | 285 | chip->irq); |
286 | if ((err = snd_ymfpci_pcm(chip, 0, NULL)) < 0) { | 286 | if ((err = snd_ymfpci_pcm(chip, 0)) < 0) { |
287 | snd_card_free(card); | 287 | snd_card_free(card); |
288 | return err; | 288 | return err; |
289 | } | 289 | } |
290 | if ((err = snd_ymfpci_pcm_spdif(chip, 1, NULL)) < 0) { | 290 | if ((err = snd_ymfpci_pcm_spdif(chip, 1)) < 0) { |
291 | snd_card_free(card); | 291 | snd_card_free(card); |
292 | return err; | 292 | return err; |
293 | } | 293 | } |
@@ -297,12 +297,12 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, | |||
297 | return err; | 297 | return err; |
298 | } | 298 | } |
299 | if (chip->ac97->ext_id & AC97_EI_SDAC) { | 299 | if (chip->ac97->ext_id & AC97_EI_SDAC) { |
300 | err = snd_ymfpci_pcm_4ch(chip, 2, NULL); | 300 | err = snd_ymfpci_pcm_4ch(chip, 2); |
301 | if (err < 0) { | 301 | if (err < 0) { |
302 | snd_card_free(card); | 302 | snd_card_free(card); |
303 | return err; | 303 | return err; |
304 | } | 304 | } |
305 | err = snd_ymfpci_pcm2(chip, 3, NULL); | 305 | err = snd_ymfpci_pcm2(chip, 3); |
306 | if (err < 0) { | 306 | if (err < 0) { |
307 | snd_card_free(card); | 307 | snd_card_free(card); |
308 | return err; | 308 | return err; |
diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h index 4631a2348915..149d4cb46998 100644 --- a/sound/pci/ymfpci/ymfpci.h +++ b/sound/pci/ymfpci/ymfpci.h | |||
@@ -379,10 +379,10 @@ void snd_ymfpci_free_gameport(struct snd_ymfpci *chip); | |||
379 | 379 | ||
380 | extern const struct dev_pm_ops snd_ymfpci_pm; | 380 | extern const struct dev_pm_ops snd_ymfpci_pm; |
381 | 381 | ||
382 | int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); | 382 | int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device); |
383 | int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); | 383 | int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device); |
384 | int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); | 384 | int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device); |
385 | int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); | 385 | int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device); |
386 | int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch); | 386 | int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch); |
387 | int snd_ymfpci_timer(struct snd_ymfpci *chip, int device); | 387 | int snd_ymfpci_timer(struct snd_ymfpci *chip, int device); |
388 | 388 | ||
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 81c916a5eb96..227d5c9dfe09 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c | |||
@@ -1145,13 +1145,11 @@ static struct snd_pcm_ops snd_ymfpci_capture_rec_ops = { | |||
1145 | .pointer = snd_ymfpci_capture_pointer, | 1145 | .pointer = snd_ymfpci_capture_pointer, |
1146 | }; | 1146 | }; |
1147 | 1147 | ||
1148 | int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm) | 1148 | int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device) |
1149 | { | 1149 | { |
1150 | struct snd_pcm *pcm; | 1150 | struct snd_pcm *pcm; |
1151 | int err; | 1151 | int err; |
1152 | 1152 | ||
1153 | if (rpcm) | ||
1154 | *rpcm = NULL; | ||
1155 | if ((err = snd_pcm_new(chip->card, "YMFPCI", device, 32, 1, &pcm)) < 0) | 1153 | if ((err = snd_pcm_new(chip->card, "YMFPCI", device, 32, 1, &pcm)) < 0) |
1156 | return err; | 1154 | return err; |
1157 | pcm->private_data = chip; | 1155 | pcm->private_data = chip; |
@@ -1167,14 +1165,8 @@ int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm) | |||
1167 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1165 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1168 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); | 1166 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); |
1169 | 1167 | ||
1170 | err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, | 1168 | return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
1171 | snd_pcm_std_chmaps, 2, 0, NULL); | 1169 | snd_pcm_std_chmaps, 2, 0, NULL); |
1172 | if (err < 0) | ||
1173 | return err; | ||
1174 | |||
1175 | if (rpcm) | ||
1176 | *rpcm = pcm; | ||
1177 | return 0; | ||
1178 | } | 1170 | } |
1179 | 1171 | ||
1180 | static struct snd_pcm_ops snd_ymfpci_capture_ac97_ops = { | 1172 | static struct snd_pcm_ops snd_ymfpci_capture_ac97_ops = { |
@@ -1188,13 +1180,11 @@ static struct snd_pcm_ops snd_ymfpci_capture_ac97_ops = { | |||
1188 | .pointer = snd_ymfpci_capture_pointer, | 1180 | .pointer = snd_ymfpci_capture_pointer, |
1189 | }; | 1181 | }; |
1190 | 1182 | ||
1191 | int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm) | 1183 | int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device) |
1192 | { | 1184 | { |
1193 | struct snd_pcm *pcm; | 1185 | struct snd_pcm *pcm; |
1194 | int err; | 1186 | int err; |
1195 | 1187 | ||
1196 | if (rpcm) | ||
1197 | *rpcm = NULL; | ||
1198 | if ((err = snd_pcm_new(chip->card, "YMFPCI - PCM2", device, 0, 1, &pcm)) < 0) | 1188 | if ((err = snd_pcm_new(chip->card, "YMFPCI - PCM2", device, 0, 1, &pcm)) < 0) |
1199 | return err; | 1189 | return err; |
1200 | pcm->private_data = chip; | 1190 | pcm->private_data = chip; |
@@ -1210,8 +1200,6 @@ int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm) | |||
1210 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1200 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1211 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); | 1201 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); |
1212 | 1202 | ||
1213 | if (rpcm) | ||
1214 | *rpcm = pcm; | ||
1215 | return 0; | 1203 | return 0; |
1216 | } | 1204 | } |
1217 | 1205 | ||
@@ -1226,14 +1214,11 @@ static struct snd_pcm_ops snd_ymfpci_playback_spdif_ops = { | |||
1226 | .pointer = snd_ymfpci_playback_pointer, | 1214 | .pointer = snd_ymfpci_playback_pointer, |
1227 | }; | 1215 | }; |
1228 | 1216 | ||
1229 | int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, | 1217 | int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device) |
1230 | struct snd_pcm **rpcm) | ||
1231 | { | 1218 | { |
1232 | struct snd_pcm *pcm; | 1219 | struct snd_pcm *pcm; |
1233 | int err; | 1220 | int err; |
1234 | 1221 | ||
1235 | if (rpcm) | ||
1236 | *rpcm = NULL; | ||
1237 | if ((err = snd_pcm_new(chip->card, "YMFPCI - IEC958", device, 1, 0, &pcm)) < 0) | 1222 | if ((err = snd_pcm_new(chip->card, "YMFPCI - IEC958", device, 1, 0, &pcm)) < 0) |
1238 | return err; | 1223 | return err; |
1239 | pcm->private_data = chip; | 1224 | pcm->private_data = chip; |
@@ -1248,8 +1233,6 @@ int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, | |||
1248 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1233 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1249 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); | 1234 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); |
1250 | 1235 | ||
1251 | if (rpcm) | ||
1252 | *rpcm = pcm; | ||
1253 | return 0; | 1236 | return 0; |
1254 | } | 1237 | } |
1255 | 1238 | ||
@@ -1272,14 +1255,11 @@ static const struct snd_pcm_chmap_elem surround_map[] = { | |||
1272 | { } | 1255 | { } |
1273 | }; | 1256 | }; |
1274 | 1257 | ||
1275 | int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, | 1258 | int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device) |
1276 | struct snd_pcm **rpcm) | ||
1277 | { | 1259 | { |
1278 | struct snd_pcm *pcm; | 1260 | struct snd_pcm *pcm; |
1279 | int err; | 1261 | int err; |
1280 | 1262 | ||
1281 | if (rpcm) | ||
1282 | *rpcm = NULL; | ||
1283 | if ((err = snd_pcm_new(chip->card, "YMFPCI - Rear", device, 1, 0, &pcm)) < 0) | 1263 | if ((err = snd_pcm_new(chip->card, "YMFPCI - Rear", device, 1, 0, &pcm)) < 0) |
1284 | return err; | 1264 | return err; |
1285 | pcm->private_data = chip; | 1265 | pcm->private_data = chip; |
@@ -1294,14 +1274,8 @@ int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, | |||
1294 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1274 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1295 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); | 1275 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); |
1296 | 1276 | ||
1297 | err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, | 1277 | return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
1298 | surround_map, 2, 0, NULL); | 1278 | surround_map, 2, 0, NULL); |
1299 | if (err < 0) | ||
1300 | return err; | ||
1301 | |||
1302 | if (rpcm) | ||
1303 | *rpcm = pcm; | ||
1304 | return 0; | ||
1305 | } | 1279 | } |
1306 | 1280 | ||
1307 | static int snd_ymfpci_spdif_default_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1281 | static int snd_ymfpci_spdif_default_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
@@ -2272,8 +2246,7 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip) | |||
2272 | release_and_free_resource(chip->mpu_res); | 2246 | release_and_free_resource(chip->mpu_res); |
2273 | release_and_free_resource(chip->fm_res); | 2247 | release_and_free_resource(chip->fm_res); |
2274 | snd_ymfpci_free_gameport(chip); | 2248 | snd_ymfpci_free_gameport(chip); |
2275 | if (chip->reg_area_virt) | 2249 | iounmap(chip->reg_area_virt); |
2276 | iounmap(chip->reg_area_virt); | ||
2277 | if (chip->work_ptr.area) | 2250 | if (chip->work_ptr.area) |
2278 | snd_dma_free_pages(&chip->work_ptr); | 2251 | snd_dma_free_pages(&chip->work_ptr); |
2279 | 2252 | ||
@@ -2326,7 +2299,6 @@ static int saved_regs_index[] = { | |||
2326 | 2299 | ||
2327 | static int snd_ymfpci_suspend(struct device *dev) | 2300 | static int snd_ymfpci_suspend(struct device *dev) |
2328 | { | 2301 | { |
2329 | struct pci_dev *pci = to_pci_dev(dev); | ||
2330 | struct snd_card *card = dev_get_drvdata(dev); | 2302 | struct snd_card *card = dev_get_drvdata(dev); |
2331 | struct snd_ymfpci *chip = card->private_data; | 2303 | struct snd_ymfpci *chip = card->private_data; |
2332 | unsigned int i; | 2304 | unsigned int i; |
@@ -2347,9 +2319,6 @@ static int snd_ymfpci_suspend(struct device *dev) | |||
2347 | snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); | 2319 | snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); |
2348 | snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0); | 2320 | snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0); |
2349 | snd_ymfpci_disable_dsp(chip); | 2321 | snd_ymfpci_disable_dsp(chip); |
2350 | pci_disable_device(pci); | ||
2351 | pci_save_state(pci); | ||
2352 | pci_set_power_state(pci, PCI_D3hot); | ||
2353 | return 0; | 2322 | return 0; |
2354 | } | 2323 | } |
2355 | 2324 | ||
@@ -2360,14 +2329,6 @@ static int snd_ymfpci_resume(struct device *dev) | |||
2360 | struct snd_ymfpci *chip = card->private_data; | 2329 | struct snd_ymfpci *chip = card->private_data; |
2361 | unsigned int i; | 2330 | unsigned int i; |
2362 | 2331 | ||
2363 | pci_set_power_state(pci, PCI_D0); | ||
2364 | pci_restore_state(pci); | ||
2365 | if (pci_enable_device(pci) < 0) { | ||
2366 | dev_err(dev, "pci_enable_device failed, disabling device\n"); | ||
2367 | snd_card_disconnect(card); | ||
2368 | return -EIO; | ||
2369 | } | ||
2370 | pci_set_master(pci); | ||
2371 | snd_ymfpci_aclink_reset(pci); | 2332 | snd_ymfpci_aclink_reset(pci); |
2372 | snd_ymfpci_codec_ready(chip, 0); | 2333 | snd_ymfpci_codec_ready(chip, 0); |
2373 | snd_ymfpci_download_image(chip); | 2334 | snd_ymfpci_download_image(chip); |
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 5a13b22748b2..d399df473896 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c | |||
@@ -867,16 +867,11 @@ static int snd_pmac_free(struct snd_pmac *chip) | |||
867 | snd_pmac_dbdma_free(chip, &chip->capture.cmd); | 867 | snd_pmac_dbdma_free(chip, &chip->capture.cmd); |
868 | snd_pmac_dbdma_free(chip, &chip->extra_dma); | 868 | snd_pmac_dbdma_free(chip, &chip->extra_dma); |
869 | snd_pmac_dbdma_free(chip, &emergency_dbdma); | 869 | snd_pmac_dbdma_free(chip, &emergency_dbdma); |
870 | if (chip->macio_base) | 870 | iounmap(chip->macio_base); |
871 | iounmap(chip->macio_base); | 871 | iounmap(chip->latch_base); |
872 | if (chip->latch_base) | 872 | iounmap(chip->awacs); |
873 | iounmap(chip->latch_base); | 873 | iounmap(chip->playback.dma); |
874 | if (chip->awacs) | 874 | iounmap(chip->capture.dma); |
875 | iounmap(chip->awacs); | ||
876 | if (chip->playback.dma) | ||
877 | iounmap(chip->playback.dma); | ||
878 | if (chip->capture.dma) | ||
879 | iounmap(chip->capture.dma); | ||
880 | 875 | ||
881 | if (chip->node) { | 876 | if (chip->node) { |
882 | int i; | 877 | int i; |
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index 58f292a87f98..368242519279 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c | |||
@@ -1044,7 +1044,7 @@ static int snd_ps3_driver_probe(struct ps3_system_bus_device *dev) | |||
1044 | if (!the_card.null_buffer_start_vaddr) { | 1044 | if (!the_card.null_buffer_start_vaddr) { |
1045 | pr_info("%s: nullbuffer alloc failed\n", __func__); | 1045 | pr_info("%s: nullbuffer alloc failed\n", __func__); |
1046 | ret = -ENOMEM; | 1046 | ret = -ENOMEM; |
1047 | goto clean_preallocate; | 1047 | goto clean_card; |
1048 | } | 1048 | } |
1049 | pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__, | 1049 | pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__, |
1050 | the_card.null_buffer_start_vaddr, | 1050 | the_card.null_buffer_start_vaddr, |
@@ -1066,8 +1066,6 @@ clean_dma_map: | |||
1066 | PAGE_SIZE, | 1066 | PAGE_SIZE, |
1067 | the_card.null_buffer_start_vaddr, | 1067 | the_card.null_buffer_start_vaddr, |
1068 | the_card.null_buffer_start_dma_addr); | 1068 | the_card.null_buffer_start_dma_addr); |
1069 | clean_preallocate: | ||
1070 | snd_pcm_lib_preallocate_free_for_all(the_card.pcm); | ||
1071 | clean_card: | 1069 | clean_card: |
1072 | snd_card_free(the_card.card); | 1070 | snd_card_free(the_card.card); |
1073 | clean_irq: | 1071 | clean_irq: |
diff --git a/sound/sh/aica.c b/sound/sh/aica.c index f44dda610ed2..8212300088fc 100644 --- a/sound/sh/aica.c +++ b/sound/sh/aica.c | |||
@@ -343,11 +343,9 @@ static void spu_begin_dma(struct snd_pcm_substream *substream) | |||
343 | mod_timer(&dreamcastcard->timer, jiffies + 4); | 343 | mod_timer(&dreamcastcard->timer, jiffies + 4); |
344 | return; | 344 | return; |
345 | } | 345 | } |
346 | init_timer(&(dreamcastcard->timer)); | 346 | setup_timer(&dreamcastcard->timer, aica_period_elapsed, |
347 | dreamcastcard->timer.data = (unsigned long) substream; | 347 | (unsigned long) substream); |
348 | dreamcastcard->timer.function = aica_period_elapsed; | 348 | mod_timer(&dreamcastcard->timer, jiffies + 4); |
349 | dreamcastcard->timer.expires = jiffies + 4; | ||
350 | add_timer(&(dreamcastcard->timer)); | ||
351 | } | 349 | } |
352 | 350 | ||
353 | static int snd_aicapcm_pcm_open(struct snd_pcm_substream | 351 | static int snd_aicapcm_pcm_open(struct snd_pcm_substream |
diff --git a/sound/soc/codecs/pcm512x-i2c.c b/sound/soc/codecs/pcm512x-i2c.c index d0547fa275fc..dcdfac0ffeb1 100644 --- a/sound/soc/codecs/pcm512x-i2c.c +++ b/sound/soc/codecs/pcm512x-i2c.c | |||
@@ -46,6 +46,8 @@ static int pcm512x_i2c_remove(struct i2c_client *i2c) | |||
46 | static const struct i2c_device_id pcm512x_i2c_id[] = { | 46 | static const struct i2c_device_id pcm512x_i2c_id[] = { |
47 | { "pcm5121", }, | 47 | { "pcm5121", }, |
48 | { "pcm5122", }, | 48 | { "pcm5122", }, |
49 | { "pcm5141", }, | ||
50 | { "pcm5142", }, | ||
49 | { } | 51 | { } |
50 | }; | 52 | }; |
51 | MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id); | 53 | MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id); |
@@ -53,6 +55,8 @@ MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id); | |||
53 | static const struct of_device_id pcm512x_of_match[] = { | 55 | static const struct of_device_id pcm512x_of_match[] = { |
54 | { .compatible = "ti,pcm5121", }, | 56 | { .compatible = "ti,pcm5121", }, |
55 | { .compatible = "ti,pcm5122", }, | 57 | { .compatible = "ti,pcm5122", }, |
58 | { .compatible = "ti,pcm5141", }, | ||
59 | { .compatible = "ti,pcm5142", }, | ||
56 | { } | 60 | { } |
57 | }; | 61 | }; |
58 | MODULE_DEVICE_TABLE(of, pcm512x_of_match); | 62 | MODULE_DEVICE_TABLE(of, pcm512x_of_match); |
diff --git a/sound/soc/codecs/pcm512x-spi.c b/sound/soc/codecs/pcm512x-spi.c index f297058c0038..7b64a9cef704 100644 --- a/sound/soc/codecs/pcm512x-spi.c +++ b/sound/soc/codecs/pcm512x-spi.c | |||
@@ -43,6 +43,8 @@ static int pcm512x_spi_remove(struct spi_device *spi) | |||
43 | static const struct spi_device_id pcm512x_spi_id[] = { | 43 | static const struct spi_device_id pcm512x_spi_id[] = { |
44 | { "pcm5121", }, | 44 | { "pcm5121", }, |
45 | { "pcm5122", }, | 45 | { "pcm5122", }, |
46 | { "pcm5141", }, | ||
47 | { "pcm5142", }, | ||
46 | { }, | 48 | { }, |
47 | }; | 49 | }; |
48 | MODULE_DEVICE_TABLE(spi, pcm512x_spi_id); | 50 | MODULE_DEVICE_TABLE(spi, pcm512x_spi_id); |
@@ -50,6 +52,8 @@ MODULE_DEVICE_TABLE(spi, pcm512x_spi_id); | |||
50 | static const struct of_device_id pcm512x_of_match[] = { | 52 | static const struct of_device_id pcm512x_of_match[] = { |
51 | { .compatible = "ti,pcm5121", }, | 53 | { .compatible = "ti,pcm5121", }, |
52 | { .compatible = "ti,pcm5122", }, | 54 | { .compatible = "ti,pcm5122", }, |
55 | { .compatible = "ti,pcm5141", }, | ||
56 | { .compatible = "ti,pcm5142", }, | ||
53 | { } | 57 | { } |
54 | }; | 58 | }; |
55 | MODULE_DEVICE_TABLE(of, pcm512x_of_match); | 59 | MODULE_DEVICE_TABLE(of, pcm512x_of_match); |
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 8a0833de1665..0a027bc94399 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c | |||
@@ -14,10 +14,12 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/pm.h> | 16 | #include <linux/pm.h> |
17 | #include <linux/pm_runtime.h> | ||
17 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
19 | #include <linux/acpi.h> | 20 | #include <linux/acpi.h> |
20 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
22 | #include <linux/dmi.h> | ||
21 | #include <sound/core.h> | 23 | #include <sound/core.h> |
22 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
23 | #include <sound/pcm_params.h> | 25 | #include <sound/pcm_params.h> |
@@ -2188,6 +2190,13 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai, | |||
2188 | if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src) | 2190 | if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src) |
2189 | return 0; | 2191 | return 0; |
2190 | 2192 | ||
2193 | if (rt5670->pdata.jd_mode) { | ||
2194 | if (clk_id == RT5670_SCLK_S_PLL1) | ||
2195 | snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); | ||
2196 | else | ||
2197 | snd_soc_dapm_disable_pin(&codec->dapm, "PLL1"); | ||
2198 | snd_soc_dapm_sync(&codec->dapm); | ||
2199 | } | ||
2191 | switch (clk_id) { | 2200 | switch (clk_id) { |
2192 | case RT5670_SCLK_S_MCLK: | 2201 | case RT5670_SCLK_S_MCLK: |
2193 | reg_val |= RT5670_SCLK_SRC_MCLK; | 2202 | reg_val |= RT5670_SCLK_SRC_MCLK; |
@@ -2549,6 +2558,17 @@ static struct acpi_device_id rt5670_acpi_match[] = { | |||
2549 | MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match); | 2558 | MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match); |
2550 | #endif | 2559 | #endif |
2551 | 2560 | ||
2561 | static const struct dmi_system_id dmi_platform_intel_braswell[] = { | ||
2562 | { | ||
2563 | .ident = "Intel Braswell", | ||
2564 | .matches = { | ||
2565 | DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), | ||
2566 | DMI_MATCH(DMI_BOARD_NAME, "Braswell CRB"), | ||
2567 | }, | ||
2568 | }, | ||
2569 | {} | ||
2570 | }; | ||
2571 | |||
2552 | static int rt5670_i2c_probe(struct i2c_client *i2c, | 2572 | static int rt5670_i2c_probe(struct i2c_client *i2c, |
2553 | const struct i2c_device_id *id) | 2573 | const struct i2c_device_id *id) |
2554 | { | 2574 | { |
@@ -2568,6 +2588,12 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, | |||
2568 | if (pdata) | 2588 | if (pdata) |
2569 | rt5670->pdata = *pdata; | 2589 | rt5670->pdata = *pdata; |
2570 | 2590 | ||
2591 | if (dmi_check_system(dmi_platform_intel_braswell)) { | ||
2592 | rt5670->pdata.dmic_en = true; | ||
2593 | rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; | ||
2594 | rt5670->pdata.jd_mode = 1; | ||
2595 | } | ||
2596 | |||
2571 | rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap); | 2597 | rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap); |
2572 | if (IS_ERR(rt5670->regmap)) { | 2598 | if (IS_ERR(rt5670->regmap)) { |
2573 | ret = PTR_ERR(rt5670->regmap); | 2599 | ret = PTR_ERR(rt5670->regmap); |
@@ -2609,6 +2635,10 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, | |||
2609 | } | 2635 | } |
2610 | 2636 | ||
2611 | if (rt5670->pdata.jd_mode) { | 2637 | if (rt5670->pdata.jd_mode) { |
2638 | regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK, | ||
2639 | RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK); | ||
2640 | rt5670->sysclk = 0; | ||
2641 | rt5670->sysclk_src = RT5670_SCLK_S_RCCLK; | ||
2612 | regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG1, | 2642 | regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG1, |
2613 | RT5670_PWR_MB, RT5670_PWR_MB); | 2643 | RT5670_PWR_MB, RT5670_PWR_MB); |
2614 | regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG2, | 2644 | regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG2, |
@@ -2716,18 +2746,26 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, | |||
2716 | 2746 | ||
2717 | } | 2747 | } |
2718 | 2748 | ||
2749 | pm_runtime_enable(&i2c->dev); | ||
2750 | pm_request_idle(&i2c->dev); | ||
2751 | |||
2719 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670, | 2752 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670, |
2720 | rt5670_dai, ARRAY_SIZE(rt5670_dai)); | 2753 | rt5670_dai, ARRAY_SIZE(rt5670_dai)); |
2721 | if (ret < 0) | 2754 | if (ret < 0) |
2722 | goto err; | 2755 | goto err; |
2723 | 2756 | ||
2757 | pm_runtime_put(&i2c->dev); | ||
2758 | |||
2724 | return 0; | 2759 | return 0; |
2725 | err: | 2760 | err: |
2761 | pm_runtime_disable(&i2c->dev); | ||
2762 | |||
2726 | return ret; | 2763 | return ret; |
2727 | } | 2764 | } |
2728 | 2765 | ||
2729 | static int rt5670_i2c_remove(struct i2c_client *i2c) | 2766 | static int rt5670_i2c_remove(struct i2c_client *i2c) |
2730 | { | 2767 | { |
2768 | pm_runtime_disable(&i2c->dev); | ||
2731 | snd_soc_unregister_codec(&i2c->dev); | 2769 | snd_soc_unregister_codec(&i2c->dev); |
2732 | 2770 | ||
2733 | return 0; | 2771 | return 0; |
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 918ada9738b0..d27630accf03 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c | |||
@@ -922,6 +922,97 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | |||
922 | return 0; | 922 | return 0; |
923 | } | 923 | } |
924 | 924 | ||
925 | static int is_using_asrc(struct snd_soc_dapm_widget *source, | ||
926 | struct snd_soc_dapm_widget *sink) | ||
927 | { | ||
928 | unsigned int reg, shift, val; | ||
929 | |||
930 | if (source->reg == RT5677_ASRC_1) { | ||
931 | switch (source->shift) { | ||
932 | case 12: | ||
933 | reg = RT5677_ASRC_4; | ||
934 | shift = 0; | ||
935 | break; | ||
936 | case 13: | ||
937 | reg = RT5677_ASRC_4; | ||
938 | shift = 4; | ||
939 | break; | ||
940 | case 14: | ||
941 | reg = RT5677_ASRC_4; | ||
942 | shift = 8; | ||
943 | break; | ||
944 | case 15: | ||
945 | reg = RT5677_ASRC_4; | ||
946 | shift = 12; | ||
947 | break; | ||
948 | default: | ||
949 | return 0; | ||
950 | } | ||
951 | } else { | ||
952 | switch (source->shift) { | ||
953 | case 0: | ||
954 | reg = RT5677_ASRC_6; | ||
955 | shift = 8; | ||
956 | break; | ||
957 | case 1: | ||
958 | reg = RT5677_ASRC_6; | ||
959 | shift = 12; | ||
960 | break; | ||
961 | case 2: | ||
962 | reg = RT5677_ASRC_5; | ||
963 | shift = 0; | ||
964 | break; | ||
965 | case 3: | ||
966 | reg = RT5677_ASRC_5; | ||
967 | shift = 4; | ||
968 | break; | ||
969 | case 4: | ||
970 | reg = RT5677_ASRC_5; | ||
971 | shift = 8; | ||
972 | break; | ||
973 | case 5: | ||
974 | reg = RT5677_ASRC_5; | ||
975 | shift = 12; | ||
976 | break; | ||
977 | case 12: | ||
978 | reg = RT5677_ASRC_3; | ||
979 | shift = 0; | ||
980 | break; | ||
981 | case 13: | ||
982 | reg = RT5677_ASRC_3; | ||
983 | shift = 4; | ||
984 | break; | ||
985 | case 14: | ||
986 | reg = RT5677_ASRC_3; | ||
987 | shift = 12; | ||
988 | break; | ||
989 | default: | ||
990 | return 0; | ||
991 | } | ||
992 | } | ||
993 | |||
994 | val = (snd_soc_read(source->codec, reg) >> shift) & 0xf; | ||
995 | switch (val) { | ||
996 | case 1 ... 6: | ||
997 | return 1; | ||
998 | default: | ||
999 | return 0; | ||
1000 | } | ||
1001 | |||
1002 | } | ||
1003 | |||
1004 | static int can_use_asrc(struct snd_soc_dapm_widget *source, | ||
1005 | struct snd_soc_dapm_widget *sink) | ||
1006 | { | ||
1007 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
1008 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | ||
1009 | |||
1010 | if (rt5677->sysclk > rt5677->lrck[RT5677_AIF1] * 384) | ||
1011 | return 1; | ||
1012 | |||
1013 | return 0; | ||
1014 | } | ||
1015 | |||
925 | /* Digital Mixer */ | 1016 | /* Digital Mixer */ |
926 | static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = { | 1017 | static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = { |
927 | SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER, | 1018 | SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER, |
@@ -2226,6 +2317,45 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { | |||
2226 | 0, rt5677_set_pll2_event, SND_SOC_DAPM_PRE_PMU | | 2317 | 0, rt5677_set_pll2_event, SND_SOC_DAPM_PRE_PMU | |
2227 | SND_SOC_DAPM_POST_PMU), | 2318 | SND_SOC_DAPM_POST_PMU), |
2228 | 2319 | ||
2320 | /* ASRC */ | ||
2321 | SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5677_ASRC_1, 0, 0, NULL, 0), | ||
2322 | SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5677_ASRC_1, 1, 0, NULL, 0), | ||
2323 | SND_SOC_DAPM_SUPPLY_S("I2S3 ASRC", 1, RT5677_ASRC_1, 2, 0, NULL, 0), | ||
2324 | SND_SOC_DAPM_SUPPLY_S("I2S4 ASRC", 1, RT5677_ASRC_1, 3, 0, NULL, 0), | ||
2325 | SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5677_ASRC_2, 14, 0, NULL, 0), | ||
2326 | SND_SOC_DAPM_SUPPLY_S("DAC MONO2 L ASRC", 1, RT5677_ASRC_2, 13, 0, NULL, | ||
2327 | 0), | ||
2328 | SND_SOC_DAPM_SUPPLY_S("DAC MONO2 R ASRC", 1, RT5677_ASRC_2, 12, 0, NULL, | ||
2329 | 0), | ||
2330 | SND_SOC_DAPM_SUPPLY_S("DAC MONO3 L ASRC", 1, RT5677_ASRC_1, 15, 0, NULL, | ||
2331 | 0), | ||
2332 | SND_SOC_DAPM_SUPPLY_S("DAC MONO3 R ASRC", 1, RT5677_ASRC_1, 14, 0, NULL, | ||
2333 | 0), | ||
2334 | SND_SOC_DAPM_SUPPLY_S("DAC MONO4 L ASRC", 1, RT5677_ASRC_1, 13, 0, NULL, | ||
2335 | 0), | ||
2336 | SND_SOC_DAPM_SUPPLY_S("DAC MONO4 R ASRC", 1, RT5677_ASRC_1, 12, 0, NULL, | ||
2337 | 0), | ||
2338 | SND_SOC_DAPM_SUPPLY_S("DMIC STO1 ASRC", 1, RT5677_ASRC_2, 11, 0, NULL, | ||
2339 | 0), | ||
2340 | SND_SOC_DAPM_SUPPLY_S("DMIC STO2 ASRC", 1, RT5677_ASRC_2, 10, 0, NULL, | ||
2341 | 0), | ||
2342 | SND_SOC_DAPM_SUPPLY_S("DMIC STO3 ASRC", 1, RT5677_ASRC_2, 9, 0, NULL, | ||
2343 | 0), | ||
2344 | SND_SOC_DAPM_SUPPLY_S("DMIC STO4 ASRC", 1, RT5677_ASRC_2, 8, 0, NULL, | ||
2345 | 0), | ||
2346 | SND_SOC_DAPM_SUPPLY_S("DMIC MONO L ASRC", 1, RT5677_ASRC_2, 7, 0, NULL, | ||
2347 | 0), | ||
2348 | SND_SOC_DAPM_SUPPLY_S("DMIC MONO R ASRC", 1, RT5677_ASRC_2, 6, 0, NULL, | ||
2349 | 0), | ||
2350 | SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5677_ASRC_2, 5, 0, NULL, 0), | ||
2351 | SND_SOC_DAPM_SUPPLY_S("ADC STO2 ASRC", 1, RT5677_ASRC_2, 4, 0, NULL, 0), | ||
2352 | SND_SOC_DAPM_SUPPLY_S("ADC STO3 ASRC", 1, RT5677_ASRC_2, 3, 0, NULL, 0), | ||
2353 | SND_SOC_DAPM_SUPPLY_S("ADC STO4 ASRC", 1, RT5677_ASRC_2, 2, 0, NULL, 0), | ||
2354 | SND_SOC_DAPM_SUPPLY_S("ADC MONO L ASRC", 1, RT5677_ASRC_2, 1, 0, NULL, | ||
2355 | 0), | ||
2356 | SND_SOC_DAPM_SUPPLY_S("ADC MONO R ASRC", 1, RT5677_ASRC_2, 0, 0, NULL, | ||
2357 | 0), | ||
2358 | |||
2229 | /* Input Side */ | 2359 | /* Input Side */ |
2230 | /* micbias */ | 2360 | /* micbias */ |
2231 | SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5677_PWR_ANLG2, RT5677_PWR_MB1_BIT, | 2361 | SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5677_PWR_ANLG2, RT5677_PWR_MB1_BIT, |
@@ -2656,10 +2786,18 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { | |||
2656 | /* DAC Mixer */ | 2786 | /* DAC Mixer */ |
2657 | SND_SOC_DAPM_SUPPLY("dac stereo1 filter", RT5677_PWR_DIG2, | 2787 | SND_SOC_DAPM_SUPPLY("dac stereo1 filter", RT5677_PWR_DIG2, |
2658 | RT5677_PWR_DAC_S1F_BIT, 0, NULL, 0), | 2788 | RT5677_PWR_DAC_S1F_BIT, 0, NULL, 0), |
2659 | SND_SOC_DAPM_SUPPLY("dac mono left filter", RT5677_PWR_DIG2, | 2789 | SND_SOC_DAPM_SUPPLY("dac mono2 left filter", RT5677_PWR_DIG2, |
2660 | RT5677_PWR_DAC_M2F_L_BIT, 0, NULL, 0), | 2790 | RT5677_PWR_DAC_M2F_L_BIT, 0, NULL, 0), |
2661 | SND_SOC_DAPM_SUPPLY("dac mono right filter", RT5677_PWR_DIG2, | 2791 | SND_SOC_DAPM_SUPPLY("dac mono2 right filter", RT5677_PWR_DIG2, |
2662 | RT5677_PWR_DAC_M2F_R_BIT, 0, NULL, 0), | 2792 | RT5677_PWR_DAC_M2F_R_BIT, 0, NULL, 0), |
2793 | SND_SOC_DAPM_SUPPLY("dac mono3 left filter", RT5677_PWR_DIG2, | ||
2794 | RT5677_PWR_DAC_M3F_L_BIT, 0, NULL, 0), | ||
2795 | SND_SOC_DAPM_SUPPLY("dac mono3 right filter", RT5677_PWR_DIG2, | ||
2796 | RT5677_PWR_DAC_M3F_R_BIT, 0, NULL, 0), | ||
2797 | SND_SOC_DAPM_SUPPLY("dac mono4 left filter", RT5677_PWR_DIG2, | ||
2798 | RT5677_PWR_DAC_M4F_L_BIT, 0, NULL, 0), | ||
2799 | SND_SOC_DAPM_SUPPLY("dac mono4 right filter", RT5677_PWR_DIG2, | ||
2800 | RT5677_PWR_DAC_M4F_R_BIT, 0, NULL, 0), | ||
2663 | 2801 | ||
2664 | SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, | 2802 | SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, |
2665 | rt5677_sto1_dac_l_mix, ARRAY_SIZE(rt5677_sto1_dac_l_mix)), | 2803 | rt5677_sto1_dac_l_mix, ARRAY_SIZE(rt5677_sto1_dac_l_mix)), |
@@ -2732,6 +2870,31 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { | |||
2732 | }; | 2870 | }; |
2733 | 2871 | ||
2734 | static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | 2872 | static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { |
2873 | { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC", can_use_asrc }, | ||
2874 | { "Stereo2 DMIC Mux", NULL, "DMIC STO2 ASRC", can_use_asrc }, | ||
2875 | { "Stereo3 DMIC Mux", NULL, "DMIC STO3 ASRC", can_use_asrc }, | ||
2876 | { "Stereo4 DMIC Mux", NULL, "DMIC STO4 ASRC", can_use_asrc }, | ||
2877 | { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC", can_use_asrc }, | ||
2878 | { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC", can_use_asrc }, | ||
2879 | { "I2S1", NULL, "I2S1 ASRC", can_use_asrc}, | ||
2880 | { "I2S2", NULL, "I2S2 ASRC", can_use_asrc}, | ||
2881 | { "I2S3", NULL, "I2S3 ASRC", can_use_asrc}, | ||
2882 | { "I2S4", NULL, "I2S4 ASRC", can_use_asrc}, | ||
2883 | |||
2884 | { "dac stereo1 filter", NULL, "DAC STO ASRC", is_using_asrc }, | ||
2885 | { "dac mono2 left filter", NULL, "DAC MONO2 L ASRC", is_using_asrc }, | ||
2886 | { "dac mono2 right filter", NULL, "DAC MONO2 R ASRC", is_using_asrc }, | ||
2887 | { "dac mono3 left filter", NULL, "DAC MONO3 L ASRC", is_using_asrc }, | ||
2888 | { "dac mono3 right filter", NULL, "DAC MONO3 R ASRC", is_using_asrc }, | ||
2889 | { "dac mono4 left filter", NULL, "DAC MONO4 L ASRC", is_using_asrc }, | ||
2890 | { "dac mono4 right filter", NULL, "DAC MONO4 R ASRC", is_using_asrc }, | ||
2891 | { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc }, | ||
2892 | { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc }, | ||
2893 | { "adc stereo3 filter", NULL, "ADC STO3 ASRC", is_using_asrc }, | ||
2894 | { "adc stereo4 filter", NULL, "ADC STO4 ASRC", is_using_asrc }, | ||
2895 | { "adc mono left filter", NULL, "ADC MONO L ASRC", is_using_asrc }, | ||
2896 | { "adc mono right filter", NULL, "ADC MONO R ASRC", is_using_asrc }, | ||
2897 | |||
2735 | { "DMIC1", NULL, "DMIC L1" }, | 2898 | { "DMIC1", NULL, "DMIC L1" }, |
2736 | { "DMIC1", NULL, "DMIC R1" }, | 2899 | { "DMIC1", NULL, "DMIC R1" }, |
2737 | { "DMIC2", NULL, "DMIC L2" }, | 2900 | { "DMIC2", NULL, "DMIC L2" }, |
@@ -2862,8 +3025,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
2862 | 3025 | ||
2863 | { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" }, | 3026 | { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" }, |
2864 | { "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" }, | 3027 | { "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" }, |
2865 | { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
2866 | |||
2867 | { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" }, | 3028 | { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" }, |
2868 | { "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" }, | 3029 | { "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" }, |
2869 | { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll }, | 3030 | { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll }, |
@@ -2884,8 +3045,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
2884 | 3045 | ||
2885 | { "Stereo2 ADC MIXL", NULL, "Stereo2 ADC LR Mux" }, | 3046 | { "Stereo2 ADC MIXL", NULL, "Stereo2 ADC LR Mux" }, |
2886 | { "Stereo2 ADC MIXL", NULL, "adc stereo2 filter" }, | 3047 | { "Stereo2 ADC MIXL", NULL, "adc stereo2 filter" }, |
2887 | { "adc stereo2 filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
2888 | |||
2889 | { "Stereo2 ADC MIXR", NULL, "Sto2 ADC MIXR" }, | 3048 | { "Stereo2 ADC MIXR", NULL, "Sto2 ADC MIXR" }, |
2890 | { "Stereo2 ADC MIXR", NULL, "adc stereo2 filter" }, | 3049 | { "Stereo2 ADC MIXR", NULL, "adc stereo2 filter" }, |
2891 | { "adc stereo2 filter", NULL, "PLL1", is_sys_clk_from_pll }, | 3050 | { "adc stereo2 filter", NULL, "PLL1", is_sys_clk_from_pll }, |
@@ -2900,8 +3059,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
2900 | 3059 | ||
2901 | { "Stereo3 ADC MIXL", NULL, "Sto3 ADC MIXL" }, | 3060 | { "Stereo3 ADC MIXL", NULL, "Sto3 ADC MIXL" }, |
2902 | { "Stereo3 ADC MIXL", NULL, "adc stereo3 filter" }, | 3061 | { "Stereo3 ADC MIXL", NULL, "adc stereo3 filter" }, |
2903 | { "adc stereo3 filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
2904 | |||
2905 | { "Stereo3 ADC MIXR", NULL, "Sto3 ADC MIXR" }, | 3062 | { "Stereo3 ADC MIXR", NULL, "Sto3 ADC MIXR" }, |
2906 | { "Stereo3 ADC MIXR", NULL, "adc stereo3 filter" }, | 3063 | { "Stereo3 ADC MIXR", NULL, "adc stereo3 filter" }, |
2907 | { "adc stereo3 filter", NULL, "PLL1", is_sys_clk_from_pll }, | 3064 | { "adc stereo3 filter", NULL, "PLL1", is_sys_clk_from_pll }, |
@@ -2916,8 +3073,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
2916 | 3073 | ||
2917 | { "Stereo4 ADC MIXL", NULL, "Sto4 ADC MIXL" }, | 3074 | { "Stereo4 ADC MIXL", NULL, "Sto4 ADC MIXL" }, |
2918 | { "Stereo4 ADC MIXL", NULL, "adc stereo4 filter" }, | 3075 | { "Stereo4 ADC MIXL", NULL, "adc stereo4 filter" }, |
2919 | { "adc stereo4 filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
2920 | |||
2921 | { "Stereo4 ADC MIXR", NULL, "Sto4 ADC MIXR" }, | 3076 | { "Stereo4 ADC MIXR", NULL, "Sto4 ADC MIXR" }, |
2922 | { "Stereo4 ADC MIXR", NULL, "adc stereo4 filter" }, | 3077 | { "Stereo4 ADC MIXR", NULL, "adc stereo4 filter" }, |
2923 | { "adc stereo4 filter", NULL, "PLL1", is_sys_clk_from_pll }, | 3078 | { "adc stereo4 filter", NULL, "PLL1", is_sys_clk_from_pll }, |
@@ -3466,10 +3621,8 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
3466 | 3621 | ||
3467 | { "DAC1 MIXL", "Stereo ADC Switch", "ADDA1 Mux" }, | 3622 | { "DAC1 MIXL", "Stereo ADC Switch", "ADDA1 Mux" }, |
3468 | { "DAC1 MIXL", "DAC1 Switch", "DAC1 Mux" }, | 3623 | { "DAC1 MIXL", "DAC1 Switch", "DAC1 Mux" }, |
3469 | { "DAC1 MIXL", NULL, "dac stereo1 filter" }, | ||
3470 | { "DAC1 MIXR", "Stereo ADC Switch", "ADDA1 Mux" }, | 3624 | { "DAC1 MIXR", "Stereo ADC Switch", "ADDA1 Mux" }, |
3471 | { "DAC1 MIXR", "DAC1 Switch", "DAC1 Mux" }, | 3625 | { "DAC1 MIXR", "DAC1 Switch", "DAC1 Mux" }, |
3472 | { "DAC1 MIXR", NULL, "dac stereo1 filter" }, | ||
3473 | 3626 | ||
3474 | { "DAC1 FS", NULL, "DAC1 MIXL" }, | 3627 | { "DAC1 FS", NULL, "DAC1 MIXL" }, |
3475 | { "DAC1 FS", NULL, "DAC1 MIXR" }, | 3628 | { "DAC1 FS", NULL, "DAC1 MIXR" }, |
@@ -3536,35 +3689,46 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
3536 | { "Stereo DAC MIXR", "DAC2 R Switch", "DAC2 R Mux" }, | 3689 | { "Stereo DAC MIXR", "DAC2 R Switch", "DAC2 R Mux" }, |
3537 | { "Stereo DAC MIXR", "DAC1 L Switch", "DAC1 MIXL" }, | 3690 | { "Stereo DAC MIXR", "DAC1 L Switch", "DAC1 MIXL" }, |
3538 | { "Stereo DAC MIXR", NULL, "dac stereo1 filter" }, | 3691 | { "Stereo DAC MIXR", NULL, "dac stereo1 filter" }, |
3692 | { "dac stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3539 | 3693 | ||
3540 | { "Mono DAC MIXL", "ST L Switch", "Sidetone Mux" }, | 3694 | { "Mono DAC MIXL", "ST L Switch", "Sidetone Mux" }, |
3541 | { "Mono DAC MIXL", "DAC1 L Switch", "DAC1 MIXL" }, | 3695 | { "Mono DAC MIXL", "DAC1 L Switch", "DAC1 MIXL" }, |
3542 | { "Mono DAC MIXL", "DAC2 L Switch", "DAC2 L Mux" }, | 3696 | { "Mono DAC MIXL", "DAC2 L Switch", "DAC2 L Mux" }, |
3543 | { "Mono DAC MIXL", "DAC2 R Switch", "DAC2 R Mux" }, | 3697 | { "Mono DAC MIXL", "DAC2 R Switch", "DAC2 R Mux" }, |
3544 | { "Mono DAC MIXL", NULL, "dac mono left filter" }, | 3698 | { "Mono DAC MIXL", NULL, "dac mono2 left filter" }, |
3699 | { "dac mono2 left filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3545 | { "Mono DAC MIXR", "ST R Switch", "Sidetone Mux" }, | 3700 | { "Mono DAC MIXR", "ST R Switch", "Sidetone Mux" }, |
3546 | { "Mono DAC MIXR", "DAC1 R Switch", "DAC1 MIXR" }, | 3701 | { "Mono DAC MIXR", "DAC1 R Switch", "DAC1 MIXR" }, |
3547 | { "Mono DAC MIXR", "DAC2 R Switch", "DAC2 R Mux" }, | 3702 | { "Mono DAC MIXR", "DAC2 R Switch", "DAC2 R Mux" }, |
3548 | { "Mono DAC MIXR", "DAC2 L Switch", "DAC2 L Mux" }, | 3703 | { "Mono DAC MIXR", "DAC2 L Switch", "DAC2 L Mux" }, |
3549 | { "Mono DAC MIXR", NULL, "dac mono right filter" }, | 3704 | { "Mono DAC MIXR", NULL, "dac mono2 right filter" }, |
3705 | { "dac mono2 right filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3550 | 3706 | ||
3551 | { "DD1 MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" }, | 3707 | { "DD1 MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" }, |
3552 | { "DD1 MIXL", "Mono DAC Mix L Switch", "Mono DAC MIXL" }, | 3708 | { "DD1 MIXL", "Mono DAC Mix L Switch", "Mono DAC MIXL" }, |
3553 | { "DD1 MIXL", "DAC3 L Switch", "DAC3 L Mux" }, | 3709 | { "DD1 MIXL", "DAC3 L Switch", "DAC3 L Mux" }, |
3554 | { "DD1 MIXL", "DAC3 R Switch", "DAC3 R Mux" }, | 3710 | { "DD1 MIXL", "DAC3 R Switch", "DAC3 R Mux" }, |
3711 | { "DD1 MIXL", NULL, "dac mono3 left filter" }, | ||
3712 | { "dac mono3 left filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3555 | { "DD1 MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" }, | 3713 | { "DD1 MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" }, |
3556 | { "DD1 MIXR", "Mono DAC Mix R Switch", "Mono DAC MIXR" }, | 3714 | { "DD1 MIXR", "Mono DAC Mix R Switch", "Mono DAC MIXR" }, |
3557 | { "DD1 MIXR", "DAC3 L Switch", "DAC3 L Mux" }, | 3715 | { "DD1 MIXR", "DAC3 L Switch", "DAC3 L Mux" }, |
3558 | { "DD1 MIXR", "DAC3 R Switch", "DAC3 R Mux" }, | 3716 | { "DD1 MIXR", "DAC3 R Switch", "DAC3 R Mux" }, |
3717 | { "DD1 MIXR", NULL, "dac mono3 right filter" }, | ||
3718 | { "dac mono3 right filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3559 | 3719 | ||
3560 | { "DD2 MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" }, | 3720 | { "DD2 MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" }, |
3561 | { "DD2 MIXL", "Mono DAC Mix L Switch", "Mono DAC MIXL" }, | 3721 | { "DD2 MIXL", "Mono DAC Mix L Switch", "Mono DAC MIXL" }, |
3562 | { "DD2 MIXL", "DAC4 L Switch", "DAC4 L Mux" }, | 3722 | { "DD2 MIXL", "DAC4 L Switch", "DAC4 L Mux" }, |
3563 | { "DD2 MIXL", "DAC4 R Switch", "DAC4 R Mux" }, | 3723 | { "DD2 MIXL", "DAC4 R Switch", "DAC4 R Mux" }, |
3724 | { "DD2 MIXL", NULL, "dac mono4 left filter" }, | ||
3725 | { "dac mono4 left filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3564 | { "DD2 MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" }, | 3726 | { "DD2 MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" }, |
3565 | { "DD2 MIXR", "Mono DAC Mix R Switch", "Mono DAC MIXR" }, | 3727 | { "DD2 MIXR", "Mono DAC Mix R Switch", "Mono DAC MIXR" }, |
3566 | { "DD2 MIXR", "DAC4 L Switch", "DAC4 L Mux" }, | 3728 | { "DD2 MIXR", "DAC4 L Switch", "DAC4 L Mux" }, |
3567 | { "DD2 MIXR", "DAC4 R Switch", "DAC4 R Mux" }, | 3729 | { "DD2 MIXR", "DAC4 R Switch", "DAC4 R Mux" }, |
3730 | { "DD2 MIXR", NULL, "dac mono4 right filter" }, | ||
3731 | { "dac mono4 right filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3568 | 3732 | ||
3569 | { "Stereo DAC MIX", NULL, "Stereo DAC MIXL" }, | 3733 | { "Stereo DAC MIX", NULL, "Stereo DAC MIXL" }, |
3570 | { "Stereo DAC MIX", NULL, "Stereo DAC MIXR" }, | 3734 | { "Stereo DAC MIX", NULL, "Stereo DAC MIXR" }, |
@@ -3586,11 +3750,8 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
3586 | { "DAC3 SRC Mux", "DD MIX2L", "DD2 MIXL" }, | 3750 | { "DAC3 SRC Mux", "DD MIX2L", "DD2 MIXL" }, |
3587 | 3751 | ||
3588 | { "DAC 1", NULL, "DAC12 SRC Mux" }, | 3752 | { "DAC 1", NULL, "DAC12 SRC Mux" }, |
3589 | { "DAC 1", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3590 | { "DAC 2", NULL, "DAC12 SRC Mux" }, | 3753 | { "DAC 2", NULL, "DAC12 SRC Mux" }, |
3591 | { "DAC 2", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3592 | { "DAC 3", NULL, "DAC3 SRC Mux" }, | 3754 | { "DAC 3", NULL, "DAC3 SRC Mux" }, |
3593 | { "DAC 3", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3594 | 3755 | ||
3595 | { "PDM1 L Mux", "STO1 DAC MIX", "Stereo DAC MIXL" }, | 3756 | { "PDM1 L Mux", "STO1 DAC MIX", "Stereo DAC MIXL" }, |
3596 | { "PDM1 L Mux", "MONO DAC MIX", "Mono DAC MIXL" }, | 3757 | { "PDM1 L Mux", "MONO DAC MIX", "Mono DAC MIXL" }, |
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index f6847fdd6ddd..eb0a1644ba11 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
@@ -323,7 +323,7 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { | |||
323 | SND_SOC_DAPM_OUTPUT("ROUT2"), | 323 | SND_SOC_DAPM_OUTPUT("ROUT2"), |
324 | SND_SOC_DAPM_OUTPUT("MONO1"), | 324 | SND_SOC_DAPM_OUTPUT("MONO1"), |
325 | SND_SOC_DAPM_OUTPUT("OUT3"), | 325 | SND_SOC_DAPM_OUTPUT("OUT3"), |
326 | SND_SOC_DAPM_OUTPUT("VREF"), | 326 | SND_SOC_DAPM_VMID("VREF"), |
327 | 327 | ||
328 | SND_SOC_DAPM_INPUT("LINPUT1"), | 328 | SND_SOC_DAPM_INPUT("LINPUT1"), |
329 | SND_SOC_DAPM_INPUT("LINPUT2"), | 329 | SND_SOC_DAPM_INPUT("LINPUT2"), |
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index 8d18bbda661b..06d3a34ac90a 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c | |||
@@ -335,13 +335,47 @@ static int dw_i2s_resume(struct snd_soc_dai *dai) | |||
335 | #define dw_i2s_resume NULL | 335 | #define dw_i2s_resume NULL |
336 | #endif | 336 | #endif |
337 | 337 | ||
338 | static void dw_configure_dai_by_pd(struct dw_i2s_dev *dev, | ||
339 | struct snd_soc_dai_driver *dw_i2s_dai, | ||
340 | struct resource *res, | ||
341 | const struct i2s_platform_data *pdata) | ||
342 | { | ||
343 | /* Set DMA slaves info */ | ||
344 | |||
345 | dev->play_dma_data.data = pdata->play_dma_data; | ||
346 | dev->capture_dma_data.data = pdata->capture_dma_data; | ||
347 | dev->play_dma_data.addr = res->start + I2S_TXDMA; | ||
348 | dev->capture_dma_data.addr = res->start + I2S_RXDMA; | ||
349 | dev->play_dma_data.max_burst = 16; | ||
350 | dev->capture_dma_data.max_burst = 16; | ||
351 | dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
352 | dev->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
353 | dev->play_dma_data.filter = pdata->filter; | ||
354 | dev->capture_dma_data.filter = pdata->filter; | ||
355 | |||
356 | if (pdata->cap & DWC_I2S_PLAY) { | ||
357 | dev_dbg(dev->dev, " designware: play supported\n"); | ||
358 | dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM; | ||
359 | dw_i2s_dai->playback.channels_max = pdata->channel; | ||
360 | dw_i2s_dai->playback.formats = pdata->snd_fmts; | ||
361 | dw_i2s_dai->playback.rates = pdata->snd_rates; | ||
362 | } | ||
363 | |||
364 | if (pdata->cap & DWC_I2S_RECORD) { | ||
365 | dev_dbg(dev->dev, "designware: record supported\n"); | ||
366 | dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM; | ||
367 | dw_i2s_dai->capture.channels_max = pdata->channel; | ||
368 | dw_i2s_dai->capture.formats = pdata->snd_fmts; | ||
369 | dw_i2s_dai->capture.rates = pdata->snd_rates; | ||
370 | } | ||
371 | } | ||
372 | |||
338 | static int dw_i2s_probe(struct platform_device *pdev) | 373 | static int dw_i2s_probe(struct platform_device *pdev) |
339 | { | 374 | { |
340 | const struct i2s_platform_data *pdata = pdev->dev.platform_data; | 375 | const struct i2s_platform_data *pdata = pdev->dev.platform_data; |
341 | struct dw_i2s_dev *dev; | 376 | struct dw_i2s_dev *dev; |
342 | struct resource *res; | 377 | struct resource *res; |
343 | int ret; | 378 | int ret; |
344 | unsigned int cap; | ||
345 | struct snd_soc_dai_driver *dw_i2s_dai; | 379 | struct snd_soc_dai_driver *dw_i2s_dai; |
346 | 380 | ||
347 | if (!pdata) { | 381 | if (!pdata) { |
@@ -356,44 +390,23 @@ static int dw_i2s_probe(struct platform_device *pdev) | |||
356 | } | 390 | } |
357 | 391 | ||
358 | dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL); | 392 | dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL); |
359 | if (!dw_i2s_dai) { | 393 | if (!dw_i2s_dai) |
360 | dev_err(&pdev->dev, "mem allocation failed for dai driver\n"); | ||
361 | return -ENOMEM; | 394 | return -ENOMEM; |
362 | } | ||
363 | 395 | ||
364 | dw_i2s_dai->ops = &dw_i2s_dai_ops; | 396 | dw_i2s_dai->ops = &dw_i2s_dai_ops; |
365 | dw_i2s_dai->suspend = dw_i2s_suspend; | 397 | dw_i2s_dai->suspend = dw_i2s_suspend; |
366 | dw_i2s_dai->resume = dw_i2s_resume; | 398 | dw_i2s_dai->resume = dw_i2s_resume; |
367 | 399 | ||
368 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 400 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
369 | if (!res) { | ||
370 | dev_err(&pdev->dev, "no i2s resource defined\n"); | ||
371 | return -ENODEV; | ||
372 | } | ||
373 | |||
374 | dev->i2s_base = devm_ioremap_resource(&pdev->dev, res); | 401 | dev->i2s_base = devm_ioremap_resource(&pdev->dev, res); |
375 | if (IS_ERR(dev->i2s_base)) { | 402 | if (IS_ERR(dev->i2s_base)) |
376 | dev_err(&pdev->dev, "ioremap fail for i2s_region\n"); | ||
377 | return PTR_ERR(dev->i2s_base); | 403 | return PTR_ERR(dev->i2s_base); |
378 | } | ||
379 | |||
380 | cap = pdata->cap; | ||
381 | dev->capability = cap; | ||
382 | dev->i2s_clk_cfg = pdata->i2s_clk_cfg; | ||
383 | |||
384 | /* Set DMA slaves info */ | ||
385 | 404 | ||
386 | dev->play_dma_data.data = pdata->play_dma_data; | 405 | dev->dev = &pdev->dev; |
387 | dev->capture_dma_data.data = pdata->capture_dma_data; | 406 | dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata); |
388 | dev->play_dma_data.addr = res->start + I2S_TXDMA; | ||
389 | dev->capture_dma_data.addr = res->start + I2S_RXDMA; | ||
390 | dev->play_dma_data.max_burst = 16; | ||
391 | dev->capture_dma_data.max_burst = 16; | ||
392 | dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
393 | dev->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
394 | dev->play_dma_data.filter = pdata->filter; | ||
395 | dev->capture_dma_data.filter = pdata->filter; | ||
396 | 407 | ||
408 | dev->capability = pdata->cap; | ||
409 | dev->i2s_clk_cfg = pdata->i2s_clk_cfg; | ||
397 | dev->clk = clk_get(&pdev->dev, NULL); | 410 | dev->clk = clk_get(&pdev->dev, NULL); |
398 | if (IS_ERR(dev->clk)) | 411 | if (IS_ERR(dev->clk)) |
399 | return PTR_ERR(dev->clk); | 412 | return PTR_ERR(dev->clk); |
@@ -402,23 +415,6 @@ static int dw_i2s_probe(struct platform_device *pdev) | |||
402 | if (ret < 0) | 415 | if (ret < 0) |
403 | goto err_clk_put; | 416 | goto err_clk_put; |
404 | 417 | ||
405 | if (cap & DWC_I2S_PLAY) { | ||
406 | dev_dbg(&pdev->dev, " designware: play supported\n"); | ||
407 | dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM; | ||
408 | dw_i2s_dai->playback.channels_max = pdata->channel; | ||
409 | dw_i2s_dai->playback.formats = pdata->snd_fmts; | ||
410 | dw_i2s_dai->playback.rates = pdata->snd_rates; | ||
411 | } | ||
412 | |||
413 | if (cap & DWC_I2S_RECORD) { | ||
414 | dev_dbg(&pdev->dev, "designware: record supported\n"); | ||
415 | dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM; | ||
416 | dw_i2s_dai->capture.channels_max = pdata->channel; | ||
417 | dw_i2s_dai->capture.formats = pdata->snd_fmts; | ||
418 | dw_i2s_dai->capture.rates = pdata->snd_rates; | ||
419 | } | ||
420 | |||
421 | dev->dev = &pdev->dev; | ||
422 | dev_set_drvdata(&pdev->dev, dev); | 418 | dev_set_drvdata(&pdev->dev, dev); |
423 | ret = snd_soc_register_component(&pdev->dev, &dw_i2s_component, | 419 | ret = snd_soc_register_component(&pdev->dev, &dw_i2s_component, |
424 | dw_i2s_dai, 1); | 420 | dw_i2s_dai, 1); |
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index f86de1211b96..c0813f546d1f 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig | |||
@@ -46,7 +46,7 @@ config SND_SOC_INTEL_BAYTRAIL | |||
46 | 46 | ||
47 | config SND_SOC_INTEL_HASWELL_MACH | 47 | config SND_SOC_INTEL_HASWELL_MACH |
48 | tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" | 48 | tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" |
49 | depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C && \\ | 49 | depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C && \ |
50 | I2C_DESIGNWARE_PLATFORM | 50 | I2C_DESIGNWARE_PLATFORM |
51 | select SND_SOC_INTEL_HASWELL | 51 | select SND_SOC_INTEL_HASWELL |
52 | select SND_SOC_RT5640 | 52 | select SND_SOC_RT5640 |
@@ -76,7 +76,7 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH | |||
76 | 76 | ||
77 | config SND_SOC_INTEL_BROADWELL_MACH | 77 | config SND_SOC_INTEL_BROADWELL_MACH |
78 | tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" | 78 | tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" |
79 | depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC && \\ | 79 | depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC && \ |
80 | I2C_DESIGNWARE_PLATFORM | 80 | I2C_DESIGNWARE_PLATFORM |
81 | select SND_SOC_INTEL_HASWELL | 81 | select SND_SOC_INTEL_HASWELL |
82 | select SND_COMPRESS_OFFLOAD | 82 | select SND_COMPRESS_OFFLOAD |
diff --git a/sound/soc/intel/bytcr_dpcm_rt5640.c b/sound/soc/intel/bytcr_dpcm_rt5640.c index eef0c56ec32e..59308629043e 100644 --- a/sound/soc/intel/bytcr_dpcm_rt5640.c +++ b/sound/soc/intel/bytcr_dpcm_rt5640.c | |||
@@ -215,7 +215,6 @@ static int snd_byt_mc_probe(struct platform_device *pdev) | |||
215 | 215 | ||
216 | static struct platform_driver snd_byt_mc_driver = { | 216 | static struct platform_driver snd_byt_mc_driver = { |
217 | .driver = { | 217 | .driver = { |
218 | .owner = THIS_MODULE, | ||
219 | .name = "bytt100_rt5640", | 218 | .name = "bytt100_rt5640", |
220 | .pm = &snd_soc_pm_ops, | 219 | .pm = &snd_soc_pm_ops, |
221 | }, | 220 | }, |
diff --git a/sound/soc/intel/cht_bsw_rt5672.c b/sound/soc/intel/cht_bsw_rt5672.c index 9b8b561171b7..a406c6104897 100644 --- a/sound/soc/intel/cht_bsw_rt5672.c +++ b/sound/soc/intel/cht_bsw_rt5672.c | |||
@@ -270,7 +270,6 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
270 | 270 | ||
271 | static struct platform_driver snd_cht_mc_driver = { | 271 | static struct platform_driver snd_cht_mc_driver = { |
272 | .driver = { | 272 | .driver = { |
273 | .owner = THIS_MODULE, | ||
274 | .name = "cht-bsw-rt5672", | 273 | .name = "cht-bsw-rt5672", |
275 | .pm = &snd_soc_pm_ops, | 274 | .pm = &snd_soc_pm_ops, |
276 | }, | 275 | }, |
diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index b3f9489794a6..a2ae2c5f2e9f 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c | |||
@@ -497,6 +497,7 @@ struct sst_module *sst_module_new(struct sst_fw *sst_fw, | |||
497 | sst_module->sst_fw = sst_fw; | 497 | sst_module->sst_fw = sst_fw; |
498 | sst_module->scratch_size = template->scratch_size; | 498 | sst_module->scratch_size = template->scratch_size; |
499 | sst_module->persistent_size = template->persistent_size; | 499 | sst_module->persistent_size = template->persistent_size; |
500 | sst_module->entry = template->entry; | ||
500 | 501 | ||
501 | INIT_LIST_HEAD(&sst_module->block_list); | 502 | INIT_LIST_HEAD(&sst_module->block_list); |
502 | INIT_LIST_HEAD(&sst_module->runtime_list); | 503 | INIT_LIST_HEAD(&sst_module->runtime_list); |
diff --git a/sound/soc/intel/sst/sst_acpi.c b/sound/soc/intel/sst/sst_acpi.c index 2ac72eb5e75d..c3fbcdec6a15 100644 --- a/sound/soc/intel/sst/sst_acpi.c +++ b/sound/soc/intel/sst/sst_acpi.c | |||
@@ -245,7 +245,7 @@ static struct sst_machines *sst_acpi_find_machine( | |||
245 | return NULL; | 245 | return NULL; |
246 | } | 246 | } |
247 | 247 | ||
248 | int sst_acpi_probe(struct platform_device *pdev) | 248 | static int sst_acpi_probe(struct platform_device *pdev) |
249 | { | 249 | { |
250 | struct device *dev = &pdev->dev; | 250 | struct device *dev = &pdev->dev; |
251 | int ret = 0; | 251 | int ret = 0; |
@@ -332,7 +332,7 @@ do_sst_cleanup: | |||
332 | * This function is called by OS when a device is unloaded | 332 | * This function is called by OS when a device is unloaded |
333 | * This frees the interrupt etc | 333 | * This frees the interrupt etc |
334 | */ | 334 | */ |
335 | int sst_acpi_remove(struct platform_device *pdev) | 335 | static int sst_acpi_remove(struct platform_device *pdev) |
336 | { | 336 | { |
337 | struct intel_sst_drv *ctx; | 337 | struct intel_sst_drv *ctx; |
338 | 338 | ||
@@ -366,7 +366,6 @@ MODULE_DEVICE_TABLE(acpi, sst_acpi_ids); | |||
366 | static struct platform_driver sst_acpi_driver = { | 366 | static struct platform_driver sst_acpi_driver = { |
367 | .driver = { | 367 | .driver = { |
368 | .name = "intel_sst_acpi", | 368 | .name = "intel_sst_acpi", |
369 | .owner = THIS_MODULE, | ||
370 | .acpi_match_table = ACPI_PTR(sst_acpi_ids), | 369 | .acpi_match_table = ACPI_PTR(sst_acpi_ids), |
371 | .pm = &intel_sst_pm, | 370 | .pm = &intel_sst_pm, |
372 | }, | 371 | }, |
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c index 3f9ac7dbdc80..ccfb41c22e53 100644 --- a/sound/soc/omap/omap-hdmi-audio.c +++ b/sound/soc/omap/omap-hdmi-audio.c | |||
@@ -393,7 +393,6 @@ static int omap_hdmi_audio_remove(struct platform_device *pdev) | |||
393 | static struct platform_driver hdmi_audio_driver = { | 393 | static struct platform_driver hdmi_audio_driver = { |
394 | .driver = { | 394 | .driver = { |
395 | .name = DRV_NAME, | 395 | .name = DRV_NAME, |
396 | .owner = THIS_MODULE, | ||
397 | }, | 396 | }, |
398 | .probe = omap_hdmi_audio_probe, | 397 | .probe = omap_hdmi_audio_probe, |
399 | .remove = omap_hdmi_audio_remove, | 398 | .remove = omap_hdmi_audio_remove, |
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index d7d5fb20ea6f..a6d680acd907 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c | |||
@@ -352,7 +352,6 @@ static int spitz_remove(struct platform_device *pdev) | |||
352 | static struct platform_driver spitz_driver = { | 352 | static struct platform_driver spitz_driver = { |
353 | .driver = { | 353 | .driver = { |
354 | .name = "spitz-audio", | 354 | .name = "spitz-audio", |
355 | .owner = THIS_MODULE, | ||
356 | .pm = &snd_soc_pm_ops, | 355 | .pm = &snd_soc_pm_ops, |
357 | }, | 356 | }, |
358 | .probe = spitz_probe, | 357 | .probe = spitz_probe, |
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index dcc26eda0539..acb5be53bfb4 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c | |||
@@ -247,6 +247,10 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, | |||
247 | 247 | ||
248 | regmap_update_bits(i2s->regmap, I2S_TXCR, I2S_TXCR_VDW_MASK, val); | 248 | regmap_update_bits(i2s->regmap, I2S_TXCR, I2S_TXCR_VDW_MASK, val); |
249 | regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK, val); | 249 | regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK, val); |
250 | regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, | ||
251 | I2S_DMACR_TDL(16)); | ||
252 | regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK, | ||
253 | I2S_DMACR_RDL(16)); | ||
250 | 254 | ||
251 | return 0; | 255 | return 0; |
252 | } | 256 | } |
diff --git a/sound/soc/samsung/arndale_rt5631.c b/sound/soc/samsung/arndale_rt5631.c index 1e2b61ca8db2..8bf2e2c4bafb 100644 --- a/sound/soc/samsung/arndale_rt5631.c +++ b/sound/soc/samsung/arndale_rt5631.c | |||
@@ -135,7 +135,6 @@ MODULE_DEVICE_TABLE(of, samsung_arndale_rt5631_of_match); | |||
135 | static struct platform_driver arndale_audio_driver = { | 135 | static struct platform_driver arndale_audio_driver = { |
136 | .driver = { | 136 | .driver = { |
137 | .name = "arndale-audio", | 137 | .name = "arndale-audio", |
138 | .owner = THIS_MODULE, | ||
139 | .pm = &snd_soc_pm_ops, | 138 | .pm = &snd_soc_pm_ops, |
140 | .of_match_table = of_match_ptr(samsung_arndale_rt5631_of_match), | 139 | .of_match_table = of_match_ptr(samsung_arndale_rt5631_of_match), |
141 | }, | 140 | }, |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2c62620abca6..c024962ba500 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -1626,9 +1626,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1626 | } | 1626 | } |
1627 | } | 1627 | } |
1628 | 1628 | ||
1629 | if (card->fully_routed) | ||
1630 | snd_soc_dapm_auto_nc_pins(card); | ||
1631 | |||
1632 | snd_soc_dapm_new_widgets(card); | 1629 | snd_soc_dapm_new_widgets(card); |
1633 | 1630 | ||
1634 | ret = snd_card_register(card->snd_card); | 1631 | ret = snd_card_register(card->snd_card); |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index c5136bb1f982..ea496842ee83 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -2279,6 +2279,9 @@ static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w) | |||
2279 | 2279 | ||
2280 | switch (w->id) { | 2280 | switch (w->id) { |
2281 | case snd_soc_dapm_input: | 2281 | case snd_soc_dapm_input: |
2282 | /* On a fully routed card a input is never a source */ | ||
2283 | if (w->dapm->card->fully_routed) | ||
2284 | break; | ||
2282 | w->is_source = 1; | 2285 | w->is_source = 1; |
2283 | list_for_each_entry(p, &w->sources, list_sink) { | 2286 | list_for_each_entry(p, &w->sources, list_sink) { |
2284 | if (p->source->id == snd_soc_dapm_micbias || | 2287 | if (p->source->id == snd_soc_dapm_micbias || |
@@ -2291,6 +2294,9 @@ static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w) | |||
2291 | } | 2294 | } |
2292 | break; | 2295 | break; |
2293 | case snd_soc_dapm_output: | 2296 | case snd_soc_dapm_output: |
2297 | /* On a fully routed card a output is never a sink */ | ||
2298 | if (w->dapm->card->fully_routed) | ||
2299 | break; | ||
2294 | w->is_sink = 1; | 2300 | w->is_sink = 1; |
2295 | list_for_each_entry(p, &w->sinks, list_source) { | 2301 | list_for_each_entry(p, &w->sinks, list_source) { |
2296 | if (p->sink->id == snd_soc_dapm_spk || | 2302 | if (p->sink->id == snd_soc_dapm_spk || |
@@ -3085,16 +3091,24 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
3085 | 3091 | ||
3086 | switch (w->id) { | 3092 | switch (w->id) { |
3087 | case snd_soc_dapm_mic: | 3093 | case snd_soc_dapm_mic: |
3088 | case snd_soc_dapm_input: | ||
3089 | w->is_source = 1; | 3094 | w->is_source = 1; |
3090 | w->power_check = dapm_generic_check_power; | 3095 | w->power_check = dapm_generic_check_power; |
3091 | break; | 3096 | break; |
3097 | case snd_soc_dapm_input: | ||
3098 | if (!dapm->card->fully_routed) | ||
3099 | w->is_source = 1; | ||
3100 | w->power_check = dapm_generic_check_power; | ||
3101 | break; | ||
3092 | case snd_soc_dapm_spk: | 3102 | case snd_soc_dapm_spk: |
3093 | case snd_soc_dapm_hp: | 3103 | case snd_soc_dapm_hp: |
3094 | case snd_soc_dapm_output: | ||
3095 | w->is_sink = 1; | 3104 | w->is_sink = 1; |
3096 | w->power_check = dapm_generic_check_power; | 3105 | w->power_check = dapm_generic_check_power; |
3097 | break; | 3106 | break; |
3107 | case snd_soc_dapm_output: | ||
3108 | if (!dapm->card->fully_routed) | ||
3109 | w->is_sink = 1; | ||
3110 | w->power_check = dapm_generic_check_power; | ||
3111 | break; | ||
3098 | case snd_soc_dapm_vmid: | 3112 | case snd_soc_dapm_vmid: |
3099 | case snd_soc_dapm_siggen: | 3113 | case snd_soc_dapm_siggen: |
3100 | w->is_source = 1; | 3114 | w->is_source = 1; |
@@ -3809,93 +3823,6 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, | |||
3809 | EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); | 3823 | EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); |
3810 | 3824 | ||
3811 | /** | 3825 | /** |
3812 | * dapm_is_external_path() - Checks if a path is a external path | ||
3813 | * @card: The card the path belongs to | ||
3814 | * @path: The path to check | ||
3815 | * | ||
3816 | * Returns true if the path is either between two different DAPM contexts or | ||
3817 | * between two external pins of the same DAPM context. Otherwise returns | ||
3818 | * false. | ||
3819 | */ | ||
3820 | static bool dapm_is_external_path(struct snd_soc_card *card, | ||
3821 | struct snd_soc_dapm_path *path) | ||
3822 | { | ||
3823 | dev_dbg(card->dev, | ||
3824 | "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n", | ||
3825 | path->source->name, path->source->id, path->source->dapm, | ||
3826 | path->sink->name, path->sink->id, path->sink->dapm); | ||
3827 | |||
3828 | /* Connection between two different DAPM contexts */ | ||
3829 | if (path->source->dapm != path->sink->dapm) | ||
3830 | return true; | ||
3831 | |||
3832 | /* Loopback connection from external pin to external pin */ | ||
3833 | if (path->sink->id == snd_soc_dapm_input) { | ||
3834 | switch (path->source->id) { | ||
3835 | case snd_soc_dapm_output: | ||
3836 | case snd_soc_dapm_micbias: | ||
3837 | return true; | ||
3838 | default: | ||
3839 | break; | ||
3840 | } | ||
3841 | } | ||
3842 | |||
3843 | return false; | ||
3844 | } | ||
3845 | |||
3846 | static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card, | ||
3847 | struct snd_soc_dapm_widget *w) | ||
3848 | { | ||
3849 | struct snd_soc_dapm_path *p; | ||
3850 | |||
3851 | list_for_each_entry(p, &w->sources, list_sink) { | ||
3852 | if (dapm_is_external_path(card, p)) | ||
3853 | return true; | ||
3854 | } | ||
3855 | |||
3856 | list_for_each_entry(p, &w->sinks, list_source) { | ||
3857 | if (dapm_is_external_path(card, p)) | ||
3858 | return true; | ||
3859 | } | ||
3860 | |||
3861 | return false; | ||
3862 | } | ||
3863 | |||
3864 | /** | ||
3865 | * snd_soc_dapm_auto_nc_pins - call snd_soc_dapm_nc_pin for unused pins | ||
3866 | * @card: The card whose pins should be processed | ||
3867 | * | ||
3868 | * Automatically call snd_soc_dapm_nc_pin() for any external pins in the card | ||
3869 | * which are unused. Pins are used if they are connected externally to a | ||
3870 | * component, whether that be to some other device, or a loop-back connection to | ||
3871 | * the component itself. | ||
3872 | */ | ||
3873 | void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card) | ||
3874 | { | ||
3875 | struct snd_soc_dapm_widget *w; | ||
3876 | |||
3877 | dev_dbg(card->dev, "ASoC: Auto NC: DAPMs: card:%p\n", &card->dapm); | ||
3878 | |||
3879 | list_for_each_entry(w, &card->widgets, list) { | ||
3880 | switch (w->id) { | ||
3881 | case snd_soc_dapm_input: | ||
3882 | case snd_soc_dapm_output: | ||
3883 | case snd_soc_dapm_micbias: | ||
3884 | dev_dbg(card->dev, "ASoC: Auto NC: Checking widget %s\n", | ||
3885 | w->name); | ||
3886 | if (!snd_soc_dapm_widget_in_card_paths(card, w)) { | ||
3887 | dev_dbg(card->dev, | ||
3888 | "... Not in map; disabling\n"); | ||
3889 | snd_soc_dapm_nc_pin(w->dapm, w->name); | ||
3890 | } | ||
3891 | break; | ||
3892 | default: | ||
3893 | break; | ||
3894 | } | ||
3895 | } | ||
3896 | } | ||
3897 | |||
3898 | /** | ||
3899 | * snd_soc_dapm_free - free dapm resources | 3826 | * snd_soc_dapm_free - free dapm resources |
3900 | * @dapm: DAPM context | 3827 | * @dapm: DAPM context |
3901 | * | 3828 | * |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index eb87d96e2cf0..6b0136e7cb88 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -301,34 +301,18 @@ static bool soc_pcm_has_symmetry(struct snd_pcm_substream *substream) | |||
301 | return symmetry; | 301 | return symmetry; |
302 | } | 302 | } |
303 | 303 | ||
304 | /* | ||
305 | * List of sample sizes that might go over the bus for parameter | ||
306 | * application. There ought to be a wildcard sample size for things | ||
307 | * like the DAC/ADC resolution to use but there isn't right now. | ||
308 | */ | ||
309 | static int sample_sizes[] = { | ||
310 | 24, 32, | ||
311 | }; | ||
312 | |||
313 | static void soc_pcm_set_msb(struct snd_pcm_substream *substream, int bits) | 304 | static void soc_pcm_set_msb(struct snd_pcm_substream *substream, int bits) |
314 | { | 305 | { |
315 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 306 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
316 | int ret, i; | 307 | int ret; |
317 | 308 | ||
318 | if (!bits) | 309 | if (!bits) |
319 | return; | 310 | return; |
320 | 311 | ||
321 | for (i = 0; i < ARRAY_SIZE(sample_sizes); i++) { | 312 | ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 0, bits); |
322 | if (bits >= sample_sizes[i]) | 313 | if (ret != 0) |
323 | continue; | 314 | dev_warn(rtd->dev, "ASoC: Failed to set MSB %d: %d\n", |
324 | 315 | bits, ret); | |
325 | ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0, | ||
326 | sample_sizes[i], bits); | ||
327 | if (ret != 0) | ||
328 | dev_warn(rtd->dev, | ||
329 | "ASoC: Failed to set MSB %d/%d: %d\n", | ||
330 | bits, sample_sizes[i], ret); | ||
331 | } | ||
332 | } | 316 | } |
333 | 317 | ||
334 | static void soc_pcm_apply_msb(struct snd_pcm_substream *substream) | 318 | static void soc_pcm_apply_msb(struct snd_pcm_substream *substream) |
@@ -746,7 +730,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
746 | codec_dai); | 730 | codec_dai); |
747 | if (ret < 0) { | 731 | if (ret < 0) { |
748 | dev_err(codec_dai->dev, | 732 | dev_err(codec_dai->dev, |
749 | "ASoC: DAI prepare error: %d\n", ret); | 733 | "ASoC: codec DAI prepare error: %d\n", |
734 | ret); | ||
750 | goto out; | 735 | goto out; |
751 | } | 736 | } |
752 | } | 737 | } |
@@ -755,8 +740,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
755 | if (cpu_dai->driver->ops && cpu_dai->driver->ops->prepare) { | 740 | if (cpu_dai->driver->ops && cpu_dai->driver->ops->prepare) { |
756 | ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); | 741 | ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); |
757 | if (ret < 0) { | 742 | if (ret < 0) { |
758 | dev_err(cpu_dai->dev, "ASoC: DAI prepare error: %d\n", | 743 | dev_err(cpu_dai->dev, |
759 | ret); | 744 | "ASoC: cpu DAI prepare error: %d\n", ret); |
760 | goto out; | 745 | goto out; |
761 | } | 746 | } |
762 | } | 747 | } |
diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c index 93522072bc87..49195325fdf6 100644 --- a/sound/synth/emux/emux.c +++ b/sound/synth/emux/emux.c | |||
@@ -53,9 +53,7 @@ int snd_emux_new(struct snd_emux **remu) | |||
53 | emu->max_voices = 0; | 53 | emu->max_voices = 0; |
54 | emu->use_time = 0; | 54 | emu->use_time = 0; |
55 | 55 | ||
56 | init_timer(&emu->tlist); | 56 | setup_timer(&emu->tlist, snd_emux_timer_callback, (unsigned long)emu); |
57 | emu->tlist.function = snd_emux_timer_callback; | ||
58 | emu->tlist.data = (unsigned long)emu; | ||
59 | emu->timer_active = 0; | 57 | emu->timer_active = 0; |
60 | 58 | ||
61 | *remu = emu; | 59 | *remu = emu; |
@@ -160,12 +158,8 @@ int snd_emux_free(struct snd_emux *emu) | |||
160 | snd_emux_detach_seq_oss(emu); | 158 | snd_emux_detach_seq_oss(emu); |
161 | #endif | 159 | #endif |
162 | snd_emux_detach_seq(emu); | 160 | snd_emux_detach_seq(emu); |
163 | |||
164 | snd_emux_delete_hwdep(emu); | 161 | snd_emux_delete_hwdep(emu); |
165 | 162 | snd_sf_free(emu->sflist); | |
166 | if (emu->sflist) | ||
167 | snd_sf_free(emu->sflist); | ||
168 | |||
169 | kfree(emu->voices); | 163 | kfree(emu->voices); |
170 | kfree(emu->name); | 164 | kfree(emu->name); |
171 | kfree(emu); | 165 | kfree(emu); |
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c index 9a38de459acb..599551b5af44 100644 --- a/sound/synth/emux/emux_synth.c +++ b/sound/synth/emux/emux_synth.c | |||
@@ -186,8 +186,7 @@ snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan) | |||
186 | */ | 186 | */ |
187 | vp->state = SNDRV_EMUX_ST_PENDING; | 187 | vp->state = SNDRV_EMUX_ST_PENDING; |
188 | if (! emu->timer_active) { | 188 | if (! emu->timer_active) { |
189 | emu->tlist.expires = jiffies + 1; | 189 | mod_timer(&emu->tlist, jiffies + 1); |
190 | add_timer(&emu->tlist); | ||
191 | emu->timer_active = 1; | 190 | emu->timer_active = 1; |
192 | } | 191 | } |
193 | } else | 192 | } else |
@@ -223,8 +222,7 @@ void snd_emux_timer_callback(unsigned long data) | |||
223 | } | 222 | } |
224 | } | 223 | } |
225 | if (do_again) { | 224 | if (do_again) { |
226 | emu->tlist.expires = jiffies + 1; | 225 | mod_timer(&emu->tlist, jiffies + 1); |
227 | add_timer(&emu->tlist); | ||
228 | emu->timer_active = 1; | 226 | emu->timer_active = 1; |
229 | } else | 227 | } else |
230 | emu->timer_active = 0; | 228 | emu->timer_active = 0; |
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index d393153c474f..a452ad7cec40 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
@@ -160,5 +160,7 @@ config SND_BCD2000 | |||
160 | To compile this driver as a module, choose M here: the module | 160 | To compile this driver as a module, choose M here: the module |
161 | will be called snd-bcd2000. | 161 | will be called snd-bcd2000. |
162 | 162 | ||
163 | source "sound/usb/line6/Kconfig" | ||
164 | |||
163 | endif # SND_USB | 165 | endif # SND_USB |
164 | 166 | ||
diff --git a/sound/usb/Makefile b/sound/usb/Makefile index bcee4060fd18..2d2d122b069f 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile | |||
@@ -25,3 +25,4 @@ obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o | |||
25 | obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o | 25 | obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o |
26 | 26 | ||
27 | obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ bcd2000/ | 27 | obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ bcd2000/ |
28 | obj-$(CONFIG_SND_USB_LINE6) += line6/ | ||
diff --git a/sound/usb/line6/Kconfig b/sound/usb/line6/Kconfig new file mode 100644 index 000000000000..af20947e0bda --- /dev/null +++ b/sound/usb/line6/Kconfig | |||
@@ -0,0 +1,40 @@ | |||
1 | config SND_USB_LINE6 | ||
2 | tristate | ||
3 | select SND_RAWMIDI | ||
4 | select SND_PCM | ||
5 | |||
6 | config SND_USB_POD | ||
7 | tristate "Line 6 POD USB support" | ||
8 | select SND_USB_LINE6 | ||
9 | help | ||
10 | This is a driver for PODxt and other similar devices, | ||
11 | supporting the following features: | ||
12 | * Reading/writing individual parameters | ||
13 | * Reading/writing complete channel, effects setup, and amp | ||
14 | setup data | ||
15 | * Channel switching | ||
16 | * Virtual MIDI interface | ||
17 | * Tuner access | ||
18 | * Playback/capture/mixer device for any ALSA-compatible PCM | ||
19 | audio application | ||
20 | * Signal routing (record clean/processed guitar signal, | ||
21 | re-amping) | ||
22 | |||
23 | config SND_USB_PODHD | ||
24 | tristate "Line 6 POD HD300/400/500 USB support" | ||
25 | select SND_USB_LINE6 | ||
26 | help | ||
27 | This is a driver for POD HD300, 400 and 500 devices. | ||
28 | |||
29 | config SND_USB_TONEPORT | ||
30 | tristate "TonePort GX, UX1 and UX2 USB support" | ||
31 | select SND_USB_LINE6 | ||
32 | help | ||
33 | This is a driver for TonePort GX, UX1 and UX2 devices. | ||
34 | |||
35 | config SND_USB_VARIAX | ||
36 | tristate "Variax Workbench USB support" | ||
37 | select SND_USB_LINE6 | ||
38 | help | ||
39 | This is a driver for Variax Workbench device. | ||
40 | |||
diff --git a/sound/usb/line6/Makefile b/sound/usb/line6/Makefile new file mode 100644 index 000000000000..b8b3b2a543d8 --- /dev/null +++ b/sound/usb/line6/Makefile | |||
@@ -0,0 +1,18 @@ | |||
1 | snd-usb-line6-y := \ | ||
2 | capture.o \ | ||
3 | driver.o \ | ||
4 | midi.o \ | ||
5 | midibuf.o \ | ||
6 | pcm.o \ | ||
7 | playback.o | ||
8 | |||
9 | snd-usb-pod-y := pod.o | ||
10 | snd-usb-podhd-y := podhd.o | ||
11 | snd-usb-toneport-y := toneport.o | ||
12 | snd-usb-variax-y := variax.o | ||
13 | |||
14 | obj-$(CONFIG_SND_USB_LINE6) += snd-usb-line6.o | ||
15 | obj-$(CONFIG_SND_USB_POD) += snd-usb-pod.o | ||
16 | obj-$(CONFIG_SND_USB_PODHD) += snd-usb-podhd.o | ||
17 | obj-$(CONFIG_SND_USB_TONEPORT) += snd-usb-toneport.o | ||
18 | obj-$(CONFIG_SND_USB_VARIAX) += snd-usb-variax.o | ||
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c new file mode 100644 index 000000000000..5a010ba163fa --- /dev/null +++ b/sound/usb/line6/capture.c | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/slab.h> | ||
13 | #include <sound/core.h> | ||
14 | #include <sound/pcm.h> | ||
15 | #include <sound/pcm_params.h> | ||
16 | |||
17 | #include "capture.h" | ||
18 | #include "driver.h" | ||
19 | #include "pcm.h" | ||
20 | |||
21 | /* | ||
22 | Find a free URB and submit it. | ||
23 | */ | ||
24 | static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm) | ||
25 | { | ||
26 | int index; | ||
27 | unsigned long flags; | ||
28 | int i, urb_size; | ||
29 | int ret; | ||
30 | struct urb *urb_in; | ||
31 | |||
32 | spin_lock_irqsave(&line6pcm->lock_audio_in, flags); | ||
33 | index = | ||
34 | find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS); | ||
35 | |||
36 | if (index < 0 || index >= LINE6_ISO_BUFFERS) { | ||
37 | spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags); | ||
38 | dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); | ||
39 | return -EINVAL; | ||
40 | } | ||
41 | |||
42 | urb_in = line6pcm->urb_audio_in[index]; | ||
43 | urb_size = 0; | ||
44 | |||
45 | for (i = 0; i < LINE6_ISO_PACKETS; ++i) { | ||
46 | struct usb_iso_packet_descriptor *fin = | ||
47 | &urb_in->iso_frame_desc[i]; | ||
48 | fin->offset = urb_size; | ||
49 | fin->length = line6pcm->max_packet_size; | ||
50 | urb_size += line6pcm->max_packet_size; | ||
51 | } | ||
52 | |||
53 | urb_in->transfer_buffer = | ||
54 | line6pcm->buffer_in + | ||
55 | index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; | ||
56 | urb_in->transfer_buffer_length = urb_size; | ||
57 | urb_in->context = line6pcm; | ||
58 | |||
59 | ret = usb_submit_urb(urb_in, GFP_ATOMIC); | ||
60 | |||
61 | if (ret == 0) | ||
62 | set_bit(index, &line6pcm->active_urb_in); | ||
63 | else | ||
64 | dev_err(line6pcm->line6->ifcdev, | ||
65 | "URB in #%d submission failed (%d)\n", index, ret); | ||
66 | |||
67 | spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | Submit all currently available capture URBs. | ||
73 | */ | ||
74 | int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm) | ||
75 | { | ||
76 | int ret, i; | ||
77 | |||
78 | for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { | ||
79 | ret = submit_audio_in_urb(line6pcm); | ||
80 | if (ret < 0) | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | Unlink all currently active capture URBs. | ||
89 | */ | ||
90 | void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm) | ||
91 | { | ||
92 | unsigned int i; | ||
93 | |||
94 | for (i = LINE6_ISO_BUFFERS; i--;) { | ||
95 | if (test_bit(i, &line6pcm->active_urb_in)) { | ||
96 | if (!test_and_set_bit(i, &line6pcm->unlink_urb_in)) { | ||
97 | struct urb *u = line6pcm->urb_audio_in[i]; | ||
98 | |||
99 | usb_unlink_urb(u); | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | Wait until unlinking of all currently active capture URBs has been | ||
107 | finished. | ||
108 | */ | ||
109 | void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm) | ||
110 | { | ||
111 | int timeout = HZ; | ||
112 | unsigned int i; | ||
113 | int alive; | ||
114 | |||
115 | do { | ||
116 | alive = 0; | ||
117 | for (i = LINE6_ISO_BUFFERS; i--;) { | ||
118 | if (test_bit(i, &line6pcm->active_urb_in)) | ||
119 | alive++; | ||
120 | } | ||
121 | if (!alive) | ||
122 | break; | ||
123 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
124 | schedule_timeout(1); | ||
125 | } while (--timeout > 0); | ||
126 | if (alive) | ||
127 | snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive); | ||
128 | } | ||
129 | |||
130 | /* | ||
131 | Unlink all currently active capture URBs, and wait for finishing. | ||
132 | */ | ||
133 | void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm) | ||
134 | { | ||
135 | line6_unlink_audio_in_urbs(line6pcm); | ||
136 | line6_wait_clear_audio_in_urbs(line6pcm); | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | Copy data into ALSA capture buffer. | ||
141 | */ | ||
142 | void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize) | ||
143 | { | ||
144 | struct snd_pcm_substream *substream = | ||
145 | get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); | ||
146 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
147 | const int bytes_per_frame = line6pcm->properties->bytes_per_frame; | ||
148 | int frames = fsize / bytes_per_frame; | ||
149 | |||
150 | if (runtime == NULL) | ||
151 | return; | ||
152 | |||
153 | if (line6pcm->pos_in_done + frames > runtime->buffer_size) { | ||
154 | /* | ||
155 | The transferred area goes over buffer boundary, | ||
156 | copy two separate chunks. | ||
157 | */ | ||
158 | int len; | ||
159 | |||
160 | len = runtime->buffer_size - line6pcm->pos_in_done; | ||
161 | |||
162 | if (len > 0) { | ||
163 | memcpy(runtime->dma_area + | ||
164 | line6pcm->pos_in_done * bytes_per_frame, fbuf, | ||
165 | len * bytes_per_frame); | ||
166 | memcpy(runtime->dma_area, fbuf + len * bytes_per_frame, | ||
167 | (frames - len) * bytes_per_frame); | ||
168 | } else { | ||
169 | /* this is somewhat paranoid */ | ||
170 | dev_err(line6pcm->line6->ifcdev, | ||
171 | "driver bug: len = %d\n", len); | ||
172 | } | ||
173 | } else { | ||
174 | /* copy single chunk */ | ||
175 | memcpy(runtime->dma_area + | ||
176 | line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize); | ||
177 | } | ||
178 | |||
179 | line6pcm->pos_in_done += frames; | ||
180 | if (line6pcm->pos_in_done >= runtime->buffer_size) | ||
181 | line6pcm->pos_in_done -= runtime->buffer_size; | ||
182 | } | ||
183 | |||
184 | void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length) | ||
185 | { | ||
186 | struct snd_pcm_substream *substream = | ||
187 | get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); | ||
188 | |||
189 | line6pcm->bytes_in += length; | ||
190 | if (line6pcm->bytes_in >= line6pcm->period_in) { | ||
191 | line6pcm->bytes_in %= line6pcm->period_in; | ||
192 | snd_pcm_period_elapsed(substream); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm) | ||
197 | { | ||
198 | kfree(line6pcm->buffer_in); | ||
199 | line6pcm->buffer_in = NULL; | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * Callback for completed capture URB. | ||
204 | */ | ||
205 | static void audio_in_callback(struct urb *urb) | ||
206 | { | ||
207 | int i, index, length = 0, shutdown = 0; | ||
208 | unsigned long flags; | ||
209 | |||
210 | struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context; | ||
211 | |||
212 | line6pcm->last_frame_in = urb->start_frame; | ||
213 | |||
214 | /* find index of URB */ | ||
215 | for (index = 0; index < LINE6_ISO_BUFFERS; ++index) | ||
216 | if (urb == line6pcm->urb_audio_in[index]) | ||
217 | break; | ||
218 | |||
219 | spin_lock_irqsave(&line6pcm->lock_audio_in, flags); | ||
220 | |||
221 | for (i = 0; i < LINE6_ISO_PACKETS; ++i) { | ||
222 | char *fbuf; | ||
223 | int fsize; | ||
224 | struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i]; | ||
225 | |||
226 | if (fin->status == -EXDEV) { | ||
227 | shutdown = 1; | ||
228 | break; | ||
229 | } | ||
230 | |||
231 | fbuf = urb->transfer_buffer + fin->offset; | ||
232 | fsize = fin->actual_length; | ||
233 | |||
234 | if (fsize > line6pcm->max_packet_size) { | ||
235 | dev_err(line6pcm->line6->ifcdev, | ||
236 | "driver and/or device bug: packet too large (%d > %d)\n", | ||
237 | fsize, line6pcm->max_packet_size); | ||
238 | } | ||
239 | |||
240 | length += fsize; | ||
241 | |||
242 | /* the following assumes LINE6_ISO_PACKETS == 1: */ | ||
243 | line6pcm->prev_fbuf = fbuf; | ||
244 | line6pcm->prev_fsize = fsize; | ||
245 | |||
246 | if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE)) | ||
247 | if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, | ||
248 | &line6pcm->flags) && (fsize > 0)) | ||
249 | line6_capture_copy(line6pcm, fbuf, fsize); | ||
250 | } | ||
251 | |||
252 | clear_bit(index, &line6pcm->active_urb_in); | ||
253 | |||
254 | if (test_and_clear_bit(index, &line6pcm->unlink_urb_in)) | ||
255 | shutdown = 1; | ||
256 | |||
257 | spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags); | ||
258 | |||
259 | if (!shutdown) { | ||
260 | submit_audio_in_urb(line6pcm); | ||
261 | |||
262 | if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE)) | ||
263 | if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, | ||
264 | &line6pcm->flags)) | ||
265 | line6_capture_check_period(line6pcm, length); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | /* open capture callback */ | ||
270 | static int snd_line6_capture_open(struct snd_pcm_substream *substream) | ||
271 | { | ||
272 | int err; | ||
273 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
274 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | ||
275 | |||
276 | err = snd_pcm_hw_constraint_ratdens(runtime, 0, | ||
277 | SNDRV_PCM_HW_PARAM_RATE, | ||
278 | (&line6pcm-> | ||
279 | properties->snd_line6_rates)); | ||
280 | if (err < 0) | ||
281 | return err; | ||
282 | |||
283 | runtime->hw = line6pcm->properties->snd_line6_capture_hw; | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | /* close capture callback */ | ||
288 | static int snd_line6_capture_close(struct snd_pcm_substream *substream) | ||
289 | { | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | /* hw_params capture callback */ | ||
294 | static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream, | ||
295 | struct snd_pcm_hw_params *hw_params) | ||
296 | { | ||
297 | int ret; | ||
298 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | ||
299 | |||
300 | /* -- Florian Demski [FD] */ | ||
301 | /* don't ask me why, but this fixes the bug on my machine */ | ||
302 | if (line6pcm == NULL) { | ||
303 | if (substream->pcm == NULL) | ||
304 | return -ENOMEM; | ||
305 | if (substream->pcm->private_data == NULL) | ||
306 | return -ENOMEM; | ||
307 | substream->private_data = substream->pcm->private_data; | ||
308 | line6pcm = snd_pcm_substream_chip(substream); | ||
309 | } | ||
310 | /* -- [FD] end */ | ||
311 | |||
312 | ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER); | ||
313 | |||
314 | if (ret < 0) | ||
315 | return ret; | ||
316 | |||
317 | ret = snd_pcm_lib_malloc_pages(substream, | ||
318 | params_buffer_bytes(hw_params)); | ||
319 | if (ret < 0) { | ||
320 | line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | line6pcm->period_in = params_period_bytes(hw_params); | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | /* hw_free capture callback */ | ||
329 | static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream) | ||
330 | { | ||
331 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | ||
332 | |||
333 | line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER); | ||
334 | return snd_pcm_lib_free_pages(substream); | ||
335 | } | ||
336 | |||
337 | /* trigger callback */ | ||
338 | int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd) | ||
339 | { | ||
340 | int err; | ||
341 | |||
342 | switch (cmd) { | ||
343 | case SNDRV_PCM_TRIGGER_START: | ||
344 | case SNDRV_PCM_TRIGGER_RESUME: | ||
345 | err = line6_pcm_acquire(line6pcm, | ||
346 | LINE6_BIT_PCM_ALSA_CAPTURE_STREAM); | ||
347 | |||
348 | if (err < 0) | ||
349 | return err; | ||
350 | |||
351 | break; | ||
352 | |||
353 | case SNDRV_PCM_TRIGGER_STOP: | ||
354 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
355 | err = line6_pcm_release(line6pcm, | ||
356 | LINE6_BIT_PCM_ALSA_CAPTURE_STREAM); | ||
357 | |||
358 | if (err < 0) | ||
359 | return err; | ||
360 | |||
361 | break; | ||
362 | |||
363 | default: | ||
364 | return -EINVAL; | ||
365 | } | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | /* capture pointer callback */ | ||
371 | static snd_pcm_uframes_t | ||
372 | snd_line6_capture_pointer(struct snd_pcm_substream *substream) | ||
373 | { | ||
374 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | ||
375 | |||
376 | return line6pcm->pos_in_done; | ||
377 | } | ||
378 | |||
379 | /* capture operators */ | ||
380 | struct snd_pcm_ops snd_line6_capture_ops = { | ||
381 | .open = snd_line6_capture_open, | ||
382 | .close = snd_line6_capture_close, | ||
383 | .ioctl = snd_pcm_lib_ioctl, | ||
384 | .hw_params = snd_line6_capture_hw_params, | ||
385 | .hw_free = snd_line6_capture_hw_free, | ||
386 | .prepare = snd_line6_prepare, | ||
387 | .trigger = snd_line6_trigger, | ||
388 | .pointer = snd_line6_capture_pointer, | ||
389 | }; | ||
390 | |||
391 | int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) | ||
392 | { | ||
393 | struct usb_line6 *line6 = line6pcm->line6; | ||
394 | int i; | ||
395 | |||
396 | /* create audio URBs and fill in constant values: */ | ||
397 | for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { | ||
398 | struct urb *urb; | ||
399 | |||
400 | /* URB for audio in: */ | ||
401 | urb = line6pcm->urb_audio_in[i] = | ||
402 | usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); | ||
403 | |||
404 | if (urb == NULL) | ||
405 | return -ENOMEM; | ||
406 | |||
407 | urb->dev = line6->usbdev; | ||
408 | urb->pipe = | ||
409 | usb_rcvisocpipe(line6->usbdev, | ||
410 | line6->properties->ep_audio_r & | ||
411 | USB_ENDPOINT_NUMBER_MASK); | ||
412 | urb->transfer_flags = URB_ISO_ASAP; | ||
413 | urb->start_frame = -1; | ||
414 | urb->number_of_packets = LINE6_ISO_PACKETS; | ||
415 | urb->interval = LINE6_ISO_INTERVAL; | ||
416 | urb->error_count = 0; | ||
417 | urb->complete = audio_in_callback; | ||
418 | } | ||
419 | |||
420 | return 0; | ||
421 | } | ||
diff --git a/sound/usb/line6/capture.h b/sound/usb/line6/capture.h new file mode 100644 index 000000000000..0939f400a405 --- /dev/null +++ b/sound/usb/line6/capture.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef CAPTURE_H | ||
13 | #define CAPTURE_H | ||
14 | |||
15 | #include <sound/pcm.h> | ||
16 | |||
17 | #include "driver.h" | ||
18 | #include "pcm.h" | ||
19 | |||
20 | extern struct snd_pcm_ops snd_line6_capture_ops; | ||
21 | |||
22 | extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, | ||
23 | int fsize); | ||
24 | extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm, | ||
25 | int length); | ||
26 | extern int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm); | ||
27 | extern void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm); | ||
28 | extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm); | ||
29 | extern void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm); | ||
30 | extern void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm | ||
31 | *line6pcm); | ||
32 | extern void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm); | ||
33 | extern int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd); | ||
34 | |||
35 | #endif | ||
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c new file mode 100644 index 000000000000..93cd4daa56bc --- /dev/null +++ b/sound/usb/line6/driver.c | |||
@@ -0,0 +1,662 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/export.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/usb.h> | ||
17 | |||
18 | #include <sound/core.h> | ||
19 | #include <sound/initval.h> | ||
20 | |||
21 | #include "capture.h" | ||
22 | #include "driver.h" | ||
23 | #include "midi.h" | ||
24 | #include "playback.h" | ||
25 | #include "revision.h" | ||
26 | #include "usbdefs.h" | ||
27 | |||
28 | #define DRIVER_AUTHOR "Markus Grabner <grabner@icg.tugraz.at>" | ||
29 | #define DRIVER_DESC "Line 6 USB Driver" | ||
30 | |||
31 | /* | ||
32 | This is Line 6's MIDI manufacturer ID. | ||
33 | */ | ||
34 | const unsigned char line6_midi_id[] = { | ||
35 | 0x00, 0x01, 0x0c | ||
36 | }; | ||
37 | EXPORT_SYMBOL_GPL(line6_midi_id); | ||
38 | |||
39 | /* | ||
40 | Code to request version of POD, Variax interface | ||
41 | (and maybe other devices). | ||
42 | */ | ||
43 | static const char line6_request_version[] = { | ||
44 | 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 | ||
45 | }; | ||
46 | |||
47 | /** | ||
48 | Class for asynchronous messages. | ||
49 | */ | ||
50 | struct message { | ||
51 | struct usb_line6 *line6; | ||
52 | const char *buffer; | ||
53 | int size; | ||
54 | int done; | ||
55 | }; | ||
56 | |||
57 | /* | ||
58 | Forward declarations. | ||
59 | */ | ||
60 | static void line6_data_received(struct urb *urb); | ||
61 | static int line6_send_raw_message_async_part(struct message *msg, | ||
62 | struct urb *urb); | ||
63 | |||
64 | /* | ||
65 | Start to listen on endpoint. | ||
66 | */ | ||
67 | static int line6_start_listen(struct usb_line6 *line6) | ||
68 | { | ||
69 | int err; | ||
70 | |||
71 | usb_fill_int_urb(line6->urb_listen, line6->usbdev, | ||
72 | usb_rcvintpipe(line6->usbdev, line6->properties->ep_ctrl_r), | ||
73 | line6->buffer_listen, LINE6_BUFSIZE_LISTEN, | ||
74 | line6_data_received, line6, line6->interval); | ||
75 | line6->urb_listen->actual_length = 0; | ||
76 | err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC); | ||
77 | return err; | ||
78 | } | ||
79 | |||
80 | /* | ||
81 | Stop listening on endpoint. | ||
82 | */ | ||
83 | static void line6_stop_listen(struct usb_line6 *line6) | ||
84 | { | ||
85 | usb_kill_urb(line6->urb_listen); | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | Send raw message in pieces of wMaxPacketSize bytes. | ||
90 | */ | ||
91 | static int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, | ||
92 | int size) | ||
93 | { | ||
94 | int i, done = 0; | ||
95 | |||
96 | for (i = 0; i < size; i += line6->max_packet_size) { | ||
97 | int partial; | ||
98 | const char *frag_buf = buffer + i; | ||
99 | int frag_size = min(line6->max_packet_size, size - i); | ||
100 | int retval; | ||
101 | |||
102 | retval = usb_interrupt_msg(line6->usbdev, | ||
103 | usb_sndintpipe(line6->usbdev, | ||
104 | line6->properties->ep_ctrl_w), | ||
105 | (char *)frag_buf, frag_size, | ||
106 | &partial, LINE6_TIMEOUT * HZ); | ||
107 | |||
108 | if (retval) { | ||
109 | dev_err(line6->ifcdev, | ||
110 | "usb_interrupt_msg failed (%d)\n", retval); | ||
111 | break; | ||
112 | } | ||
113 | |||
114 | done += frag_size; | ||
115 | } | ||
116 | |||
117 | return done; | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | Notification of completion of asynchronous request transmission. | ||
122 | */ | ||
123 | static void line6_async_request_sent(struct urb *urb) | ||
124 | { | ||
125 | struct message *msg = (struct message *)urb->context; | ||
126 | |||
127 | if (msg->done >= msg->size) { | ||
128 | usb_free_urb(urb); | ||
129 | kfree(msg); | ||
130 | } else | ||
131 | line6_send_raw_message_async_part(msg, urb); | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | Asynchronously send part of a raw message. | ||
136 | */ | ||
137 | static int line6_send_raw_message_async_part(struct message *msg, | ||
138 | struct urb *urb) | ||
139 | { | ||
140 | int retval; | ||
141 | struct usb_line6 *line6 = msg->line6; | ||
142 | int done = msg->done; | ||
143 | int bytes = min(msg->size - done, line6->max_packet_size); | ||
144 | |||
145 | usb_fill_int_urb(urb, line6->usbdev, | ||
146 | usb_sndintpipe(line6->usbdev, line6->properties->ep_ctrl_w), | ||
147 | (char *)msg->buffer + done, bytes, | ||
148 | line6_async_request_sent, msg, line6->interval); | ||
149 | |||
150 | msg->done += bytes; | ||
151 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
152 | |||
153 | if (retval < 0) { | ||
154 | dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n", | ||
155 | __func__, retval); | ||
156 | usb_free_urb(urb); | ||
157 | kfree(msg); | ||
158 | return retval; | ||
159 | } | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | Setup and start timer. | ||
166 | */ | ||
167 | void line6_start_timer(struct timer_list *timer, unsigned int msecs, | ||
168 | void (*function)(unsigned long), unsigned long data) | ||
169 | { | ||
170 | setup_timer(timer, function, data); | ||
171 | mod_timer(timer, jiffies + msecs * HZ / 1000); | ||
172 | } | ||
173 | EXPORT_SYMBOL_GPL(line6_start_timer); | ||
174 | |||
175 | /* | ||
176 | Asynchronously send raw message. | ||
177 | */ | ||
178 | int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, | ||
179 | int size) | ||
180 | { | ||
181 | struct message *msg; | ||
182 | struct urb *urb; | ||
183 | |||
184 | /* create message: */ | ||
185 | msg = kmalloc(sizeof(struct message), GFP_ATOMIC); | ||
186 | if (msg == NULL) | ||
187 | return -ENOMEM; | ||
188 | |||
189 | /* create URB: */ | ||
190 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
191 | |||
192 | if (urb == NULL) { | ||
193 | kfree(msg); | ||
194 | return -ENOMEM; | ||
195 | } | ||
196 | |||
197 | /* set message data: */ | ||
198 | msg->line6 = line6; | ||
199 | msg->buffer = buffer; | ||
200 | msg->size = size; | ||
201 | msg->done = 0; | ||
202 | |||
203 | /* start sending: */ | ||
204 | return line6_send_raw_message_async_part(msg, urb); | ||
205 | } | ||
206 | EXPORT_SYMBOL_GPL(line6_send_raw_message_async); | ||
207 | |||
208 | /* | ||
209 | Send asynchronous device version request. | ||
210 | */ | ||
211 | int line6_version_request_async(struct usb_line6 *line6) | ||
212 | { | ||
213 | char *buffer; | ||
214 | int retval; | ||
215 | |||
216 | buffer = kmemdup(line6_request_version, | ||
217 | sizeof(line6_request_version), GFP_ATOMIC); | ||
218 | if (buffer == NULL) | ||
219 | return -ENOMEM; | ||
220 | |||
221 | retval = line6_send_raw_message_async(line6, buffer, | ||
222 | sizeof(line6_request_version)); | ||
223 | kfree(buffer); | ||
224 | return retval; | ||
225 | } | ||
226 | EXPORT_SYMBOL_GPL(line6_version_request_async); | ||
227 | |||
228 | /* | ||
229 | Send sysex message in pieces of wMaxPacketSize bytes. | ||
230 | */ | ||
231 | int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer, | ||
232 | int size) | ||
233 | { | ||
234 | return line6_send_raw_message(line6, buffer, | ||
235 | size + SYSEX_EXTRA_SIZE) - | ||
236 | SYSEX_EXTRA_SIZE; | ||
237 | } | ||
238 | EXPORT_SYMBOL_GPL(line6_send_sysex_message); | ||
239 | |||
240 | /* | ||
241 | Allocate buffer for sysex message and prepare header. | ||
242 | @param code sysex message code | ||
243 | @param size number of bytes between code and sysex end | ||
244 | */ | ||
245 | char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2, | ||
246 | int size) | ||
247 | { | ||
248 | char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_ATOMIC); | ||
249 | |||
250 | if (!buffer) | ||
251 | return NULL; | ||
252 | |||
253 | buffer[0] = LINE6_SYSEX_BEGIN; | ||
254 | memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id)); | ||
255 | buffer[sizeof(line6_midi_id) + 1] = code1; | ||
256 | buffer[sizeof(line6_midi_id) + 2] = code2; | ||
257 | buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END; | ||
258 | return buffer; | ||
259 | } | ||
260 | EXPORT_SYMBOL_GPL(line6_alloc_sysex_buffer); | ||
261 | |||
262 | /* | ||
263 | Notification of data received from the Line 6 device. | ||
264 | */ | ||
265 | static void line6_data_received(struct urb *urb) | ||
266 | { | ||
267 | struct usb_line6 *line6 = (struct usb_line6 *)urb->context; | ||
268 | struct midi_buffer *mb = &line6->line6midi->midibuf_in; | ||
269 | int done; | ||
270 | |||
271 | if (urb->status == -ESHUTDOWN) | ||
272 | return; | ||
273 | |||
274 | done = | ||
275 | line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length); | ||
276 | |||
277 | if (done < urb->actual_length) { | ||
278 | line6_midibuf_ignore(mb, done); | ||
279 | dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n", | ||
280 | done, urb->actual_length); | ||
281 | } | ||
282 | |||
283 | for (;;) { | ||
284 | done = | ||
285 | line6_midibuf_read(mb, line6->buffer_message, | ||
286 | LINE6_MESSAGE_MAXLEN); | ||
287 | |||
288 | if (done == 0) | ||
289 | break; | ||
290 | |||
291 | line6->message_length = done; | ||
292 | line6_midi_receive(line6, line6->buffer_message, done); | ||
293 | |||
294 | if (line6->process_message) | ||
295 | line6->process_message(line6); | ||
296 | } | ||
297 | |||
298 | line6_start_listen(line6); | ||
299 | } | ||
300 | |||
301 | /* | ||
302 | Read data from device. | ||
303 | */ | ||
304 | int line6_read_data(struct usb_line6 *line6, int address, void *data, | ||
305 | size_t datalen) | ||
306 | { | ||
307 | struct usb_device *usbdev = line6->usbdev; | ||
308 | int ret; | ||
309 | unsigned char len; | ||
310 | |||
311 | /* query the serial number: */ | ||
312 | ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, | ||
313 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
314 | (datalen << 8) | 0x21, address, | ||
315 | NULL, 0, LINE6_TIMEOUT * HZ); | ||
316 | |||
317 | if (ret < 0) { | ||
318 | dev_err(line6->ifcdev, "read request failed (error %d)\n", ret); | ||
319 | return ret; | ||
320 | } | ||
321 | |||
322 | /* Wait for data length. We'll get 0xff until length arrives. */ | ||
323 | do { | ||
324 | ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, | ||
325 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | | ||
326 | USB_DIR_IN, | ||
327 | 0x0012, 0x0000, &len, 1, | ||
328 | LINE6_TIMEOUT * HZ); | ||
329 | if (ret < 0) { | ||
330 | dev_err(line6->ifcdev, | ||
331 | "receive length failed (error %d)\n", ret); | ||
332 | return ret; | ||
333 | } | ||
334 | } while (len == 0xff); | ||
335 | |||
336 | if (len != datalen) { | ||
337 | /* should be equal or something went wrong */ | ||
338 | dev_err(line6->ifcdev, | ||
339 | "length mismatch (expected %d, got %d)\n", | ||
340 | (int)datalen, (int)len); | ||
341 | return -EINVAL; | ||
342 | } | ||
343 | |||
344 | /* receive the result: */ | ||
345 | ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, | ||
346 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, | ||
347 | 0x0013, 0x0000, data, datalen, | ||
348 | LINE6_TIMEOUT * HZ); | ||
349 | |||
350 | if (ret < 0) { | ||
351 | dev_err(line6->ifcdev, "read failed (error %d)\n", ret); | ||
352 | return ret; | ||
353 | } | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | EXPORT_SYMBOL_GPL(line6_read_data); | ||
358 | |||
359 | /* | ||
360 | Write data to device. | ||
361 | */ | ||
362 | int line6_write_data(struct usb_line6 *line6, int address, void *data, | ||
363 | size_t datalen) | ||
364 | { | ||
365 | struct usb_device *usbdev = line6->usbdev; | ||
366 | int ret; | ||
367 | unsigned char status; | ||
368 | |||
369 | ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, | ||
370 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
371 | 0x0022, address, data, datalen, | ||
372 | LINE6_TIMEOUT * HZ); | ||
373 | |||
374 | if (ret < 0) { | ||
375 | dev_err(line6->ifcdev, | ||
376 | "write request failed (error %d)\n", ret); | ||
377 | return ret; | ||
378 | } | ||
379 | |||
380 | do { | ||
381 | ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), | ||
382 | 0x67, | ||
383 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | | ||
384 | USB_DIR_IN, | ||
385 | 0x0012, 0x0000, | ||
386 | &status, 1, LINE6_TIMEOUT * HZ); | ||
387 | |||
388 | if (ret < 0) { | ||
389 | dev_err(line6->ifcdev, | ||
390 | "receiving status failed (error %d)\n", ret); | ||
391 | return ret; | ||
392 | } | ||
393 | } while (status == 0xff); | ||
394 | |||
395 | if (status != 0) { | ||
396 | dev_err(line6->ifcdev, "write failed (error %d)\n", ret); | ||
397 | return -EINVAL; | ||
398 | } | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | EXPORT_SYMBOL_GPL(line6_write_data); | ||
403 | |||
404 | /* | ||
405 | Read Line 6 device serial number. | ||
406 | (POD, TonePort, GuitarPort) | ||
407 | */ | ||
408 | int line6_read_serial_number(struct usb_line6 *line6, int *serial_number) | ||
409 | { | ||
410 | return line6_read_data(line6, 0x80d0, serial_number, | ||
411 | sizeof(*serial_number)); | ||
412 | } | ||
413 | EXPORT_SYMBOL_GPL(line6_read_serial_number); | ||
414 | |||
415 | /* | ||
416 | No operation (i.e., unsupported). | ||
417 | */ | ||
418 | ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr, | ||
419 | char *buf) | ||
420 | { | ||
421 | return 0; | ||
422 | } | ||
423 | EXPORT_SYMBOL_GPL(line6_nop_read); | ||
424 | |||
425 | /* | ||
426 | Card destructor. | ||
427 | */ | ||
428 | static void line6_destruct(struct snd_card *card) | ||
429 | { | ||
430 | struct usb_line6 *line6 = card->private_data; | ||
431 | struct usb_device *usbdev; | ||
432 | |||
433 | if (!line6) | ||
434 | return; | ||
435 | usbdev = line6->usbdev; | ||
436 | |||
437 | /* free buffer memory first: */ | ||
438 | kfree(line6->buffer_message); | ||
439 | kfree(line6->buffer_listen); | ||
440 | |||
441 | /* then free URBs: */ | ||
442 | usb_free_urb(line6->urb_listen); | ||
443 | |||
444 | /* free interface data: */ | ||
445 | kfree(line6); | ||
446 | |||
447 | /* decrement reference counters: */ | ||
448 | usb_put_dev(usbdev); | ||
449 | } | ||
450 | |||
451 | /* | ||
452 | Probe USB device. | ||
453 | */ | ||
454 | int line6_probe(struct usb_interface *interface, | ||
455 | struct usb_line6 *line6, | ||
456 | const struct line6_properties *properties, | ||
457 | int (*private_init)(struct usb_interface *, struct usb_line6 *)) | ||
458 | { | ||
459 | struct usb_device *usbdev = interface_to_usbdev(interface); | ||
460 | struct snd_card *card; | ||
461 | int interface_number; | ||
462 | int ret; | ||
463 | |||
464 | /* we don't handle multiple configurations */ | ||
465 | if (usbdev->descriptor.bNumConfigurations != 1) { | ||
466 | ret = -ENODEV; | ||
467 | goto err_put; | ||
468 | } | ||
469 | |||
470 | /* initialize device info: */ | ||
471 | dev_info(&interface->dev, "Line 6 %s found\n", properties->name); | ||
472 | |||
473 | /* query interface number */ | ||
474 | interface_number = interface->cur_altsetting->desc.bInterfaceNumber; | ||
475 | |||
476 | ret = usb_set_interface(usbdev, interface_number, | ||
477 | properties->altsetting); | ||
478 | if (ret < 0) { | ||
479 | dev_err(&interface->dev, "set_interface failed\n"); | ||
480 | goto err_put; | ||
481 | } | ||
482 | |||
483 | /* store basic data: */ | ||
484 | line6->properties = properties; | ||
485 | line6->usbdev = usbdev; | ||
486 | line6->ifcdev = &interface->dev; | ||
487 | |||
488 | /* get data from endpoint descriptor (see usb_maxpacket): */ | ||
489 | { | ||
490 | struct usb_host_endpoint *ep; | ||
491 | unsigned pipe = usb_rcvintpipe(usbdev, properties->ep_ctrl_r); | ||
492 | unsigned epnum = usb_pipeendpoint(pipe); | ||
493 | ep = usbdev->ep_in[epnum]; | ||
494 | |||
495 | if (ep != NULL) { | ||
496 | line6->interval = ep->desc.bInterval; | ||
497 | line6->max_packet_size = | ||
498 | le16_to_cpu(ep->desc.wMaxPacketSize); | ||
499 | } else { | ||
500 | line6->interval = LINE6_FALLBACK_INTERVAL; | ||
501 | line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE; | ||
502 | dev_err(line6->ifcdev, | ||
503 | "endpoint not available, using fallback values"); | ||
504 | } | ||
505 | } | ||
506 | |||
507 | ret = snd_card_new(line6->ifcdev, | ||
508 | SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, | ||
509 | THIS_MODULE, 0, &card); | ||
510 | if (ret < 0) | ||
511 | goto err_put; | ||
512 | |||
513 | line6->card = card; | ||
514 | strcpy(card->id, line6->properties->id); | ||
515 | strcpy(card->driver, DRIVER_NAME); | ||
516 | strcpy(card->shortname, line6->properties->name); | ||
517 | sprintf(card->longname, "Line 6 %s at USB %s", line6->properties->name, | ||
518 | dev_name(line6->ifcdev)); | ||
519 | card->private_data = line6; | ||
520 | card->private_free = line6_destruct; | ||
521 | |||
522 | usb_set_intfdata(interface, line6); | ||
523 | |||
524 | /* increment reference counters: */ | ||
525 | usb_get_dev(usbdev); | ||
526 | |||
527 | if (properties->capabilities & LINE6_CAP_CONTROL) { | ||
528 | /* initialize USB buffers: */ | ||
529 | line6->buffer_listen = | ||
530 | kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL); | ||
531 | if (line6->buffer_listen == NULL) { | ||
532 | ret = -ENOMEM; | ||
533 | goto err_destruct; | ||
534 | } | ||
535 | |||
536 | line6->buffer_message = | ||
537 | kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL); | ||
538 | if (line6->buffer_message == NULL) { | ||
539 | ret = -ENOMEM; | ||
540 | goto err_destruct; | ||
541 | } | ||
542 | |||
543 | line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL); | ||
544 | |||
545 | if (line6->urb_listen == NULL) { | ||
546 | ret = -ENOMEM; | ||
547 | goto err_destruct; | ||
548 | } | ||
549 | |||
550 | ret = line6_start_listen(line6); | ||
551 | if (ret < 0) { | ||
552 | dev_err(&interface->dev, "%s: usb_submit_urb failed\n", | ||
553 | __func__); | ||
554 | goto err_destruct; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | /* initialize device data based on device: */ | ||
559 | ret = private_init(interface, line6); | ||
560 | if (ret < 0) | ||
561 | goto err_destruct; | ||
562 | |||
563 | /* creation of additional special files should go here */ | ||
564 | |||
565 | dev_info(&interface->dev, "Line 6 %s now attached\n", | ||
566 | line6->properties->name); | ||
567 | |||
568 | return 0; | ||
569 | |||
570 | err_destruct: | ||
571 | snd_card_free(card); | ||
572 | err_put: | ||
573 | return ret; | ||
574 | } | ||
575 | EXPORT_SYMBOL_GPL(line6_probe); | ||
576 | |||
577 | /* | ||
578 | Line 6 device disconnected. | ||
579 | */ | ||
580 | void line6_disconnect(struct usb_interface *interface) | ||
581 | { | ||
582 | struct usb_line6 *line6; | ||
583 | struct usb_device *usbdev; | ||
584 | int interface_number; | ||
585 | |||
586 | if (interface == NULL) | ||
587 | return; | ||
588 | usbdev = interface_to_usbdev(interface); | ||
589 | if (usbdev == NULL) | ||
590 | return; | ||
591 | |||
592 | interface_number = interface->cur_altsetting->desc.bInterfaceNumber; | ||
593 | line6 = usb_get_intfdata(interface); | ||
594 | if (!line6) | ||
595 | return; | ||
596 | |||
597 | if (line6->urb_listen != NULL) | ||
598 | line6_stop_listen(line6); | ||
599 | |||
600 | if (usbdev != line6->usbdev) | ||
601 | dev_err(line6->ifcdev, "driver bug: inconsistent usb device\n"); | ||
602 | |||
603 | snd_card_disconnect(line6->card); | ||
604 | if (line6->line6pcm) | ||
605 | line6_pcm_disconnect(line6->line6pcm); | ||
606 | if (line6->disconnect) | ||
607 | line6->disconnect(interface); | ||
608 | |||
609 | dev_info(&interface->dev, "Line 6 %s now disconnected\n", | ||
610 | line6->properties->name); | ||
611 | |||
612 | /* make sure the device isn't destructed twice: */ | ||
613 | usb_set_intfdata(interface, NULL); | ||
614 | |||
615 | snd_card_free_when_closed(line6->card); | ||
616 | } | ||
617 | EXPORT_SYMBOL_GPL(line6_disconnect); | ||
618 | |||
619 | #ifdef CONFIG_PM | ||
620 | |||
621 | /* | ||
622 | Suspend Line 6 device. | ||
623 | */ | ||
624 | int line6_suspend(struct usb_interface *interface, pm_message_t message) | ||
625 | { | ||
626 | struct usb_line6 *line6 = usb_get_intfdata(interface); | ||
627 | struct snd_line6_pcm *line6pcm = line6->line6pcm; | ||
628 | |||
629 | snd_power_change_state(line6->card, SNDRV_CTL_POWER_D3hot); | ||
630 | |||
631 | if (line6->properties->capabilities & LINE6_CAP_CONTROL) | ||
632 | line6_stop_listen(line6); | ||
633 | |||
634 | if (line6pcm != NULL) { | ||
635 | snd_pcm_suspend_all(line6pcm->pcm); | ||
636 | line6pcm->flags = 0; | ||
637 | } | ||
638 | |||
639 | return 0; | ||
640 | } | ||
641 | EXPORT_SYMBOL_GPL(line6_suspend); | ||
642 | |||
643 | /* | ||
644 | Resume Line 6 device. | ||
645 | */ | ||
646 | int line6_resume(struct usb_interface *interface) | ||
647 | { | ||
648 | struct usb_line6 *line6 = usb_get_intfdata(interface); | ||
649 | |||
650 | if (line6->properties->capabilities & LINE6_CAP_CONTROL) | ||
651 | line6_start_listen(line6); | ||
652 | |||
653 | snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0); | ||
654 | return 0; | ||
655 | } | ||
656 | EXPORT_SYMBOL_GPL(line6_resume); | ||
657 | |||
658 | #endif /* CONFIG_PM */ | ||
659 | |||
660 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
661 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
662 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h new file mode 100644 index 000000000000..efd58ac3215b --- /dev/null +++ b/sound/usb/line6/driver.h | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef DRIVER_H | ||
13 | #define DRIVER_H | ||
14 | |||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/usb.h> | ||
17 | #include <sound/core.h> | ||
18 | |||
19 | #include "midi.h" | ||
20 | |||
21 | #define DRIVER_NAME "line6usb" | ||
22 | |||
23 | #define LINE6_TIMEOUT 1 | ||
24 | #define LINE6_BUFSIZE_LISTEN 32 | ||
25 | #define LINE6_MESSAGE_MAXLEN 256 | ||
26 | |||
27 | /* | ||
28 | Line 6 MIDI control commands | ||
29 | */ | ||
30 | #define LINE6_PARAM_CHANGE 0xb0 | ||
31 | #define LINE6_PROGRAM_CHANGE 0xc0 | ||
32 | #define LINE6_SYSEX_BEGIN 0xf0 | ||
33 | #define LINE6_SYSEX_END 0xf7 | ||
34 | #define LINE6_RESET 0xff | ||
35 | |||
36 | /* | ||
37 | MIDI channel for messages initiated by the host | ||
38 | (and eventually echoed back by the device) | ||
39 | */ | ||
40 | #define LINE6_CHANNEL_HOST 0x00 | ||
41 | |||
42 | /* | ||
43 | MIDI channel for messages initiated by the device | ||
44 | */ | ||
45 | #define LINE6_CHANNEL_DEVICE 0x02 | ||
46 | |||
47 | #define LINE6_CHANNEL_UNKNOWN 5 /* don't know yet what this is good for */ | ||
48 | |||
49 | #define LINE6_CHANNEL_MASK 0x0f | ||
50 | |||
51 | #define CHECK_STARTUP_PROGRESS(x, n) \ | ||
52 | do { \ | ||
53 | if ((x) >= (n)) \ | ||
54 | return; \ | ||
55 | x = (n); \ | ||
56 | } while (0) | ||
57 | |||
58 | extern const unsigned char line6_midi_id[3]; | ||
59 | |||
60 | static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3; | ||
61 | static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4; | ||
62 | |||
63 | /** | ||
64 | Common properties of Line 6 devices. | ||
65 | */ | ||
66 | struct line6_properties { | ||
67 | /** | ||
68 | Card id string (maximum 16 characters). | ||
69 | This can be used to address the device in ALSA programs as | ||
70 | "default:CARD=<id>" | ||
71 | */ | ||
72 | const char *id; | ||
73 | |||
74 | /** | ||
75 | Card short name (maximum 32 characters). | ||
76 | */ | ||
77 | const char *name; | ||
78 | |||
79 | /** | ||
80 | Bit vector defining this device's capabilities in the | ||
81 | line6usb driver. | ||
82 | */ | ||
83 | int capabilities; | ||
84 | |||
85 | int altsetting; | ||
86 | |||
87 | unsigned ep_ctrl_r; | ||
88 | unsigned ep_ctrl_w; | ||
89 | unsigned ep_audio_r; | ||
90 | unsigned ep_audio_w; | ||
91 | }; | ||
92 | |||
93 | /** | ||
94 | Common data shared by all Line 6 devices. | ||
95 | Corresponds to a pair of USB endpoints. | ||
96 | */ | ||
97 | struct usb_line6 { | ||
98 | /** | ||
99 | USB device. | ||
100 | */ | ||
101 | struct usb_device *usbdev; | ||
102 | |||
103 | /** | ||
104 | Properties. | ||
105 | */ | ||
106 | const struct line6_properties *properties; | ||
107 | |||
108 | /** | ||
109 | Interval (ms). | ||
110 | */ | ||
111 | int interval; | ||
112 | |||
113 | /** | ||
114 | Maximum size of USB packet. | ||
115 | */ | ||
116 | int max_packet_size; | ||
117 | |||
118 | /** | ||
119 | Device representing the USB interface. | ||
120 | */ | ||
121 | struct device *ifcdev; | ||
122 | |||
123 | /** | ||
124 | Line 6 sound card data structure. | ||
125 | Each device has at least MIDI or PCM. | ||
126 | */ | ||
127 | struct snd_card *card; | ||
128 | |||
129 | /** | ||
130 | Line 6 PCM device data structure. | ||
131 | */ | ||
132 | struct snd_line6_pcm *line6pcm; | ||
133 | |||
134 | /** | ||
135 | Line 6 MIDI device data structure. | ||
136 | */ | ||
137 | struct snd_line6_midi *line6midi; | ||
138 | |||
139 | /** | ||
140 | URB for listening to PODxt Pro control endpoint. | ||
141 | */ | ||
142 | struct urb *urb_listen; | ||
143 | |||
144 | /** | ||
145 | Buffer for listening to PODxt Pro control endpoint. | ||
146 | */ | ||
147 | unsigned char *buffer_listen; | ||
148 | |||
149 | /** | ||
150 | Buffer for message to be processed. | ||
151 | */ | ||
152 | unsigned char *buffer_message; | ||
153 | |||
154 | /** | ||
155 | Length of message to be processed. | ||
156 | */ | ||
157 | int message_length; | ||
158 | |||
159 | void (*process_message)(struct usb_line6 *); | ||
160 | void (*disconnect)(struct usb_interface *); | ||
161 | }; | ||
162 | |||
163 | extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, | ||
164 | int code2, int size); | ||
165 | extern ssize_t line6_nop_read(struct device *dev, | ||
166 | struct device_attribute *attr, char *buf); | ||
167 | extern int line6_read_data(struct usb_line6 *line6, int address, void *data, | ||
168 | size_t datalen); | ||
169 | extern int line6_read_serial_number(struct usb_line6 *line6, | ||
170 | int *serial_number); | ||
171 | extern int line6_send_raw_message_async(struct usb_line6 *line6, | ||
172 | const char *buffer, int size); | ||
173 | extern int line6_send_sysex_message(struct usb_line6 *line6, | ||
174 | const char *buffer, int size); | ||
175 | extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr, | ||
176 | const char *buf, size_t count); | ||
177 | extern void line6_start_timer(struct timer_list *timer, unsigned int msecs, | ||
178 | void (*function)(unsigned long), | ||
179 | unsigned long data); | ||
180 | extern int line6_version_request_async(struct usb_line6 *line6); | ||
181 | extern int line6_write_data(struct usb_line6 *line6, int address, void *data, | ||
182 | size_t datalen); | ||
183 | |||
184 | int line6_probe(struct usb_interface *interface, | ||
185 | struct usb_line6 *line6, | ||
186 | const struct line6_properties *properties, | ||
187 | int (*private_init)(struct usb_interface *, struct usb_line6 *)); | ||
188 | void line6_disconnect(struct usb_interface *interface); | ||
189 | |||
190 | #ifdef CONFIG_PM | ||
191 | int line6_suspend(struct usb_interface *interface, pm_message_t message); | ||
192 | int line6_resume(struct usb_interface *interface); | ||
193 | #endif | ||
194 | |||
195 | #endif | ||
diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c new file mode 100644 index 000000000000..b5a58a7fe11a --- /dev/null +++ b/sound/usb/line6/midi.c | |||
@@ -0,0 +1,299 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/slab.h> | ||
13 | #include <linux/usb.h> | ||
14 | #include <linux/export.h> | ||
15 | #include <sound/core.h> | ||
16 | #include <sound/rawmidi.h> | ||
17 | |||
18 | #include "driver.h" | ||
19 | #include "midi.h" | ||
20 | #include "usbdefs.h" | ||
21 | |||
22 | #define line6_rawmidi_substream_midi(substream) \ | ||
23 | ((struct snd_line6_midi *)((substream)->rmidi->private_data)) | ||
24 | |||
25 | static int send_midi_async(struct usb_line6 *line6, unsigned char *data, | ||
26 | int length); | ||
27 | |||
28 | /* | ||
29 | Pass data received via USB to MIDI. | ||
30 | */ | ||
31 | void line6_midi_receive(struct usb_line6 *line6, unsigned char *data, | ||
32 | int length) | ||
33 | { | ||
34 | if (line6->line6midi->substream_receive) | ||
35 | snd_rawmidi_receive(line6->line6midi->substream_receive, | ||
36 | data, length); | ||
37 | } | ||
38 | |||
39 | /* | ||
40 | Read data from MIDI buffer and transmit them via USB. | ||
41 | */ | ||
42 | static void line6_midi_transmit(struct snd_rawmidi_substream *substream) | ||
43 | { | ||
44 | struct usb_line6 *line6 = | ||
45 | line6_rawmidi_substream_midi(substream)->line6; | ||
46 | struct snd_line6_midi *line6midi = line6->line6midi; | ||
47 | struct midi_buffer *mb = &line6midi->midibuf_out; | ||
48 | unsigned long flags; | ||
49 | unsigned char chunk[LINE6_FALLBACK_MAXPACKETSIZE]; | ||
50 | int req, done; | ||
51 | |||
52 | spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags); | ||
53 | |||
54 | for (;;) { | ||
55 | req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size); | ||
56 | done = snd_rawmidi_transmit_peek(substream, chunk, req); | ||
57 | |||
58 | if (done == 0) | ||
59 | break; | ||
60 | |||
61 | line6_midibuf_write(mb, chunk, done); | ||
62 | snd_rawmidi_transmit_ack(substream, done); | ||
63 | } | ||
64 | |||
65 | for (;;) { | ||
66 | done = line6_midibuf_read(mb, chunk, | ||
67 | LINE6_FALLBACK_MAXPACKETSIZE); | ||
68 | |||
69 | if (done == 0) | ||
70 | break; | ||
71 | |||
72 | send_midi_async(line6, chunk, done); | ||
73 | } | ||
74 | |||
75 | spin_unlock_irqrestore(&line6->line6midi->midi_transmit_lock, flags); | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | Notification of completion of MIDI transmission. | ||
80 | */ | ||
81 | static void midi_sent(struct urb *urb) | ||
82 | { | ||
83 | unsigned long flags; | ||
84 | int status; | ||
85 | int num; | ||
86 | struct usb_line6 *line6 = (struct usb_line6 *)urb->context; | ||
87 | |||
88 | status = urb->status; | ||
89 | kfree(urb->transfer_buffer); | ||
90 | usb_free_urb(urb); | ||
91 | |||
92 | if (status == -ESHUTDOWN) | ||
93 | return; | ||
94 | |||
95 | spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags); | ||
96 | num = --line6->line6midi->num_active_send_urbs; | ||
97 | |||
98 | if (num == 0) { | ||
99 | line6_midi_transmit(line6->line6midi->substream_transmit); | ||
100 | num = line6->line6midi->num_active_send_urbs; | ||
101 | } | ||
102 | |||
103 | if (num == 0) | ||
104 | wake_up(&line6->line6midi->send_wait); | ||
105 | |||
106 | spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags); | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | Send an asynchronous MIDI message. | ||
111 | Assumes that line6->line6midi->send_urb_lock is held | ||
112 | (i.e., this function is serialized). | ||
113 | */ | ||
114 | static int send_midi_async(struct usb_line6 *line6, unsigned char *data, | ||
115 | int length) | ||
116 | { | ||
117 | struct urb *urb; | ||
118 | int retval; | ||
119 | unsigned char *transfer_buffer; | ||
120 | |||
121 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
122 | |||
123 | if (urb == NULL) | ||
124 | return -ENOMEM; | ||
125 | |||
126 | transfer_buffer = kmemdup(data, length, GFP_ATOMIC); | ||
127 | |||
128 | if (transfer_buffer == NULL) { | ||
129 | usb_free_urb(urb); | ||
130 | return -ENOMEM; | ||
131 | } | ||
132 | |||
133 | usb_fill_int_urb(urb, line6->usbdev, | ||
134 | usb_sndbulkpipe(line6->usbdev, | ||
135 | line6->properties->ep_ctrl_w), | ||
136 | transfer_buffer, length, midi_sent, line6, | ||
137 | line6->interval); | ||
138 | urb->actual_length = 0; | ||
139 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
140 | |||
141 | if (retval < 0) { | ||
142 | dev_err(line6->ifcdev, "usb_submit_urb failed\n"); | ||
143 | usb_free_urb(urb); | ||
144 | return retval; | ||
145 | } | ||
146 | |||
147 | ++line6->line6midi->num_active_send_urbs; | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static int line6_midi_output_open(struct snd_rawmidi_substream *substream) | ||
152 | { | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static int line6_midi_output_close(struct snd_rawmidi_substream *substream) | ||
157 | { | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream, | ||
162 | int up) | ||
163 | { | ||
164 | unsigned long flags; | ||
165 | struct usb_line6 *line6 = | ||
166 | line6_rawmidi_substream_midi(substream)->line6; | ||
167 | |||
168 | line6->line6midi->substream_transmit = substream; | ||
169 | spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags); | ||
170 | |||
171 | if (line6->line6midi->num_active_send_urbs == 0) | ||
172 | line6_midi_transmit(substream); | ||
173 | |||
174 | spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags); | ||
175 | } | ||
176 | |||
177 | static void line6_midi_output_drain(struct snd_rawmidi_substream *substream) | ||
178 | { | ||
179 | struct usb_line6 *line6 = | ||
180 | line6_rawmidi_substream_midi(substream)->line6; | ||
181 | struct snd_line6_midi *midi = line6->line6midi; | ||
182 | |||
183 | wait_event_interruptible(midi->send_wait, | ||
184 | midi->num_active_send_urbs == 0); | ||
185 | } | ||
186 | |||
187 | static int line6_midi_input_open(struct snd_rawmidi_substream *substream) | ||
188 | { | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int line6_midi_input_close(struct snd_rawmidi_substream *substream) | ||
193 | { | ||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream, | ||
198 | int up) | ||
199 | { | ||
200 | struct usb_line6 *line6 = | ||
201 | line6_rawmidi_substream_midi(substream)->line6; | ||
202 | |||
203 | if (up) | ||
204 | line6->line6midi->substream_receive = substream; | ||
205 | else | ||
206 | line6->line6midi->substream_receive = NULL; | ||
207 | } | ||
208 | |||
209 | static struct snd_rawmidi_ops line6_midi_output_ops = { | ||
210 | .open = line6_midi_output_open, | ||
211 | .close = line6_midi_output_close, | ||
212 | .trigger = line6_midi_output_trigger, | ||
213 | .drain = line6_midi_output_drain, | ||
214 | }; | ||
215 | |||
216 | static struct snd_rawmidi_ops line6_midi_input_ops = { | ||
217 | .open = line6_midi_input_open, | ||
218 | .close = line6_midi_input_close, | ||
219 | .trigger = line6_midi_input_trigger, | ||
220 | }; | ||
221 | |||
222 | /* Create a MIDI device */ | ||
223 | static int snd_line6_new_midi(struct usb_line6 *line6, | ||
224 | struct snd_rawmidi **rmidi_ret) | ||
225 | { | ||
226 | struct snd_rawmidi *rmidi; | ||
227 | int err; | ||
228 | |||
229 | err = snd_rawmidi_new(line6->card, "Line 6 MIDI", 0, 1, 1, rmidi_ret); | ||
230 | if (err < 0) | ||
231 | return err; | ||
232 | |||
233 | rmidi = *rmidi_ret; | ||
234 | strcpy(rmidi->id, line6->properties->id); | ||
235 | strcpy(rmidi->name, line6->properties->name); | ||
236 | |||
237 | rmidi->info_flags = | ||
238 | SNDRV_RAWMIDI_INFO_OUTPUT | | ||
239 | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; | ||
240 | |||
241 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, | ||
242 | &line6_midi_output_ops); | ||
243 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, | ||
244 | &line6_midi_input_ops); | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | /* MIDI device destructor */ | ||
249 | static void snd_line6_midi_free(struct snd_rawmidi *rmidi) | ||
250 | { | ||
251 | struct snd_line6_midi *line6midi = rmidi->private_data; | ||
252 | |||
253 | line6_midibuf_destroy(&line6midi->midibuf_in); | ||
254 | line6_midibuf_destroy(&line6midi->midibuf_out); | ||
255 | kfree(line6midi); | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | Initialize the Line 6 MIDI subsystem. | ||
260 | */ | ||
261 | int line6_init_midi(struct usb_line6 *line6) | ||
262 | { | ||
263 | int err; | ||
264 | struct snd_rawmidi *rmidi; | ||
265 | struct snd_line6_midi *line6midi; | ||
266 | |||
267 | if (!(line6->properties->capabilities & LINE6_CAP_CONTROL)) { | ||
268 | /* skip MIDI initialization and report success */ | ||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | err = snd_line6_new_midi(line6, &rmidi); | ||
273 | if (err < 0) | ||
274 | return err; | ||
275 | |||
276 | line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL); | ||
277 | if (!line6midi) | ||
278 | return -ENOMEM; | ||
279 | |||
280 | rmidi->private_data = line6midi; | ||
281 | rmidi->private_free = snd_line6_midi_free; | ||
282 | |||
283 | init_waitqueue_head(&line6midi->send_wait); | ||
284 | spin_lock_init(&line6midi->send_urb_lock); | ||
285 | spin_lock_init(&line6midi->midi_transmit_lock); | ||
286 | line6midi->line6 = line6; | ||
287 | |||
288 | err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0); | ||
289 | if (err < 0) | ||
290 | return err; | ||
291 | |||
292 | err = line6_midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1); | ||
293 | if (err < 0) | ||
294 | return err; | ||
295 | |||
296 | line6->line6midi = line6midi; | ||
297 | return 0; | ||
298 | } | ||
299 | EXPORT_SYMBOL_GPL(line6_init_midi); | ||
diff --git a/sound/usb/line6/midi.h b/sound/usb/line6/midi.h new file mode 100644 index 000000000000..ba6bf3828aa5 --- /dev/null +++ b/sound/usb/line6/midi.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef MIDI_H | ||
13 | #define MIDI_H | ||
14 | |||
15 | #include <sound/rawmidi.h> | ||
16 | |||
17 | #include "midibuf.h" | ||
18 | |||
19 | #define MIDI_BUFFER_SIZE 1024 | ||
20 | |||
21 | struct snd_line6_midi { | ||
22 | /** | ||
23 | Pointer back to the Line 6 driver data structure. | ||
24 | */ | ||
25 | struct usb_line6 *line6; | ||
26 | |||
27 | /** | ||
28 | MIDI substream for receiving (or NULL if not active). | ||
29 | */ | ||
30 | struct snd_rawmidi_substream *substream_receive; | ||
31 | |||
32 | /** | ||
33 | MIDI substream for transmitting (or NULL if not active). | ||
34 | */ | ||
35 | struct snd_rawmidi_substream *substream_transmit; | ||
36 | |||
37 | /** | ||
38 | Number of currently active MIDI send URBs. | ||
39 | */ | ||
40 | int num_active_send_urbs; | ||
41 | |||
42 | /** | ||
43 | Spin lock to protect updates of send_urb. | ||
44 | */ | ||
45 | spinlock_t send_urb_lock; | ||
46 | |||
47 | /** | ||
48 | Spin lock to protect MIDI buffer handling. | ||
49 | */ | ||
50 | spinlock_t midi_transmit_lock; | ||
51 | |||
52 | /** | ||
53 | Wait queue for MIDI transmission. | ||
54 | */ | ||
55 | wait_queue_head_t send_wait; | ||
56 | |||
57 | /** | ||
58 | Buffer for incoming MIDI stream. | ||
59 | */ | ||
60 | struct midi_buffer midibuf_in; | ||
61 | |||
62 | /** | ||
63 | Buffer for outgoing MIDI stream. | ||
64 | */ | ||
65 | struct midi_buffer midibuf_out; | ||
66 | }; | ||
67 | |||
68 | extern int line6_init_midi(struct usb_line6 *line6); | ||
69 | extern void line6_midi_receive(struct usb_line6 *line6, unsigned char *data, | ||
70 | int length); | ||
71 | |||
72 | #endif | ||
diff --git a/sound/usb/line6/midibuf.c b/sound/usb/line6/midibuf.c new file mode 100644 index 000000000000..b5c4d79de031 --- /dev/null +++ b/sound/usb/line6/midibuf.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/slab.h> | ||
13 | |||
14 | #include "midibuf.h" | ||
15 | |||
16 | static int midibuf_message_length(unsigned char code) | ||
17 | { | ||
18 | int message_length; | ||
19 | |||
20 | if (code < 0x80) | ||
21 | message_length = -1; | ||
22 | else if (code < 0xf0) { | ||
23 | static const int length[] = { 3, 3, 3, 3, 2, 2, 3 }; | ||
24 | |||
25 | message_length = length[(code >> 4) - 8]; | ||
26 | } else { | ||
27 | /* | ||
28 | Note that according to the MIDI specification 0xf2 is | ||
29 | the "Song Position Pointer", but this is used by Line 6 | ||
30 | to send sysex messages to the host. | ||
31 | */ | ||
32 | static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1, | ||
33 | 1, 1, 1, -1, 1, 1 | ||
34 | }; | ||
35 | message_length = length[code & 0x0f]; | ||
36 | } | ||
37 | |||
38 | return message_length; | ||
39 | } | ||
40 | |||
41 | static int midibuf_is_empty(struct midi_buffer *this) | ||
42 | { | ||
43 | return (this->pos_read == this->pos_write) && !this->full; | ||
44 | } | ||
45 | |||
46 | static int midibuf_is_full(struct midi_buffer *this) | ||
47 | { | ||
48 | return this->full; | ||
49 | } | ||
50 | |||
51 | void line6_midibuf_reset(struct midi_buffer *this) | ||
52 | { | ||
53 | this->pos_read = this->pos_write = this->full = 0; | ||
54 | this->command_prev = -1; | ||
55 | } | ||
56 | |||
57 | int line6_midibuf_init(struct midi_buffer *this, int size, int split) | ||
58 | { | ||
59 | this->buf = kmalloc(size, GFP_KERNEL); | ||
60 | |||
61 | if (this->buf == NULL) | ||
62 | return -ENOMEM; | ||
63 | |||
64 | this->size = size; | ||
65 | this->split = split; | ||
66 | line6_midibuf_reset(this); | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | void line6_midibuf_status(struct midi_buffer *this) | ||
71 | { | ||
72 | pr_debug("midibuf size=%d split=%d pos_read=%d pos_write=%d full=%d command_prev=%02x\n", | ||
73 | this->size, this->split, this->pos_read, this->pos_write, | ||
74 | this->full, this->command_prev); | ||
75 | } | ||
76 | |||
77 | int line6_midibuf_bytes_free(struct midi_buffer *this) | ||
78 | { | ||
79 | return | ||
80 | midibuf_is_full(this) ? | ||
81 | 0 : | ||
82 | (this->pos_read - this->pos_write + this->size - 1) % this->size + | ||
83 | 1; | ||
84 | } | ||
85 | |||
86 | int line6_midibuf_bytes_used(struct midi_buffer *this) | ||
87 | { | ||
88 | return | ||
89 | midibuf_is_empty(this) ? | ||
90 | 0 : | ||
91 | (this->pos_write - this->pos_read + this->size - 1) % this->size + | ||
92 | 1; | ||
93 | } | ||
94 | |||
95 | int line6_midibuf_write(struct midi_buffer *this, unsigned char *data, | ||
96 | int length) | ||
97 | { | ||
98 | int bytes_free; | ||
99 | int length1, length2; | ||
100 | int skip_active_sense = 0; | ||
101 | |||
102 | if (midibuf_is_full(this) || (length <= 0)) | ||
103 | return 0; | ||
104 | |||
105 | /* skip trailing active sense */ | ||
106 | if (data[length - 1] == 0xfe) { | ||
107 | --length; | ||
108 | skip_active_sense = 1; | ||
109 | } | ||
110 | |||
111 | bytes_free = line6_midibuf_bytes_free(this); | ||
112 | |||
113 | if (length > bytes_free) | ||
114 | length = bytes_free; | ||
115 | |||
116 | if (length > 0) { | ||
117 | length1 = this->size - this->pos_write; | ||
118 | |||
119 | if (length < length1) { | ||
120 | /* no buffer wraparound */ | ||
121 | memcpy(this->buf + this->pos_write, data, length); | ||
122 | this->pos_write += length; | ||
123 | } else { | ||
124 | /* buffer wraparound */ | ||
125 | length2 = length - length1; | ||
126 | memcpy(this->buf + this->pos_write, data, length1); | ||
127 | memcpy(this->buf, data + length1, length2); | ||
128 | this->pos_write = length2; | ||
129 | } | ||
130 | |||
131 | if (this->pos_write == this->pos_read) | ||
132 | this->full = 1; | ||
133 | } | ||
134 | |||
135 | return length + skip_active_sense; | ||
136 | } | ||
137 | |||
138 | int line6_midibuf_read(struct midi_buffer *this, unsigned char *data, | ||
139 | int length) | ||
140 | { | ||
141 | int bytes_used; | ||
142 | int length1, length2; | ||
143 | int command; | ||
144 | int midi_length; | ||
145 | int repeat = 0; | ||
146 | int i; | ||
147 | |||
148 | /* we need to be able to store at least a 3 byte MIDI message */ | ||
149 | if (length < 3) | ||
150 | return -EINVAL; | ||
151 | |||
152 | if (midibuf_is_empty(this)) | ||
153 | return 0; | ||
154 | |||
155 | bytes_used = line6_midibuf_bytes_used(this); | ||
156 | |||
157 | if (length > bytes_used) | ||
158 | length = bytes_used; | ||
159 | |||
160 | length1 = this->size - this->pos_read; | ||
161 | |||
162 | /* check MIDI command length */ | ||
163 | command = this->buf[this->pos_read]; | ||
164 | |||
165 | if (command & 0x80) { | ||
166 | midi_length = midibuf_message_length(command); | ||
167 | this->command_prev = command; | ||
168 | } else { | ||
169 | if (this->command_prev > 0) { | ||
170 | int midi_length_prev = | ||
171 | midibuf_message_length(this->command_prev); | ||
172 | |||
173 | if (midi_length_prev > 0) { | ||
174 | midi_length = midi_length_prev - 1; | ||
175 | repeat = 1; | ||
176 | } else | ||
177 | midi_length = -1; | ||
178 | } else | ||
179 | midi_length = -1; | ||
180 | } | ||
181 | |||
182 | if (midi_length < 0) { | ||
183 | /* search for end of message */ | ||
184 | if (length < length1) { | ||
185 | /* no buffer wraparound */ | ||
186 | for (i = 1; i < length; ++i) | ||
187 | if (this->buf[this->pos_read + i] & 0x80) | ||
188 | break; | ||
189 | |||
190 | midi_length = i; | ||
191 | } else { | ||
192 | /* buffer wraparound */ | ||
193 | length2 = length - length1; | ||
194 | |||
195 | for (i = 1; i < length1; ++i) | ||
196 | if (this->buf[this->pos_read + i] & 0x80) | ||
197 | break; | ||
198 | |||
199 | if (i < length1) | ||
200 | midi_length = i; | ||
201 | else { | ||
202 | for (i = 0; i < length2; ++i) | ||
203 | if (this->buf[i] & 0x80) | ||
204 | break; | ||
205 | |||
206 | midi_length = length1 + i; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | if (midi_length == length) | ||
211 | midi_length = -1; /* end of message not found */ | ||
212 | } | ||
213 | |||
214 | if (midi_length < 0) { | ||
215 | if (!this->split) | ||
216 | return 0; /* command is not yet complete */ | ||
217 | } else { | ||
218 | if (length < midi_length) | ||
219 | return 0; /* command is not yet complete */ | ||
220 | |||
221 | length = midi_length; | ||
222 | } | ||
223 | |||
224 | if (length < length1) { | ||
225 | /* no buffer wraparound */ | ||
226 | memcpy(data + repeat, this->buf + this->pos_read, length); | ||
227 | this->pos_read += length; | ||
228 | } else { | ||
229 | /* buffer wraparound */ | ||
230 | length2 = length - length1; | ||
231 | memcpy(data + repeat, this->buf + this->pos_read, length1); | ||
232 | memcpy(data + repeat + length1, this->buf, length2); | ||
233 | this->pos_read = length2; | ||
234 | } | ||
235 | |||
236 | if (repeat) | ||
237 | data[0] = this->command_prev; | ||
238 | |||
239 | this->full = 0; | ||
240 | return length + repeat; | ||
241 | } | ||
242 | |||
243 | int line6_midibuf_ignore(struct midi_buffer *this, int length) | ||
244 | { | ||
245 | int bytes_used = line6_midibuf_bytes_used(this); | ||
246 | |||
247 | if (length > bytes_used) | ||
248 | length = bytes_used; | ||
249 | |||
250 | this->pos_read = (this->pos_read + length) % this->size; | ||
251 | this->full = 0; | ||
252 | return length; | ||
253 | } | ||
254 | |||
255 | int line6_midibuf_skip_message(struct midi_buffer *this, unsigned short mask) | ||
256 | { | ||
257 | int cmd = this->command_prev; | ||
258 | |||
259 | if ((cmd >= 0x80) && (cmd < 0xf0)) | ||
260 | if ((mask & (1 << (cmd & 0x0f))) == 0) | ||
261 | return 1; | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | void line6_midibuf_destroy(struct midi_buffer *this) | ||
267 | { | ||
268 | kfree(this->buf); | ||
269 | this->buf = NULL; | ||
270 | } | ||
diff --git a/sound/usb/line6/midibuf.h b/sound/usb/line6/midibuf.h new file mode 100644 index 000000000000..05dbf11a4d63 --- /dev/null +++ b/sound/usb/line6/midibuf.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef MIDIBUF_H | ||
13 | #define MIDIBUF_H | ||
14 | |||
15 | struct midi_buffer { | ||
16 | unsigned char *buf; | ||
17 | int size; | ||
18 | int split; | ||
19 | int pos_read, pos_write; | ||
20 | int full; | ||
21 | int command_prev; | ||
22 | }; | ||
23 | |||
24 | extern int line6_midibuf_bytes_used(struct midi_buffer *mb); | ||
25 | extern int line6_midibuf_bytes_free(struct midi_buffer *mb); | ||
26 | extern void line6_midibuf_destroy(struct midi_buffer *mb); | ||
27 | extern int line6_midibuf_ignore(struct midi_buffer *mb, int length); | ||
28 | extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split); | ||
29 | extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data, | ||
30 | int length); | ||
31 | extern void line6_midibuf_reset(struct midi_buffer *mb); | ||
32 | extern int line6_midibuf_skip_message(struct midi_buffer *mb, | ||
33 | unsigned short mask); | ||
34 | extern void line6_midibuf_status(struct midi_buffer *mb); | ||
35 | extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data, | ||
36 | int length); | ||
37 | |||
38 | #endif | ||
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c new file mode 100644 index 000000000000..8a6059adef69 --- /dev/null +++ b/sound/usb/line6/pcm.c | |||
@@ -0,0 +1,487 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/slab.h> | ||
13 | #include <linux/export.h> | ||
14 | #include <sound/core.h> | ||
15 | #include <sound/control.h> | ||
16 | #include <sound/pcm.h> | ||
17 | #include <sound/pcm_params.h> | ||
18 | |||
19 | #include "capture.h" | ||
20 | #include "driver.h" | ||
21 | #include "playback.h" | ||
22 | |||
23 | /* impulse response volume controls */ | ||
24 | static int snd_line6_impulse_volume_info(struct snd_kcontrol *kcontrol, | ||
25 | struct snd_ctl_elem_info *uinfo) | ||
26 | { | ||
27 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
28 | uinfo->count = 1; | ||
29 | uinfo->value.integer.min = 0; | ||
30 | uinfo->value.integer.max = 255; | ||
31 | return 0; | ||
32 | } | ||
33 | |||
34 | static int snd_line6_impulse_volume_get(struct snd_kcontrol *kcontrol, | ||
35 | struct snd_ctl_elem_value *ucontrol) | ||
36 | { | ||
37 | struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); | ||
38 | |||
39 | ucontrol->value.integer.value[0] = line6pcm->impulse_volume; | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol, | ||
44 | struct snd_ctl_elem_value *ucontrol) | ||
45 | { | ||
46 | struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); | ||
47 | int value = ucontrol->value.integer.value[0]; | ||
48 | |||
49 | if (line6pcm->impulse_volume == value) | ||
50 | return 0; | ||
51 | |||
52 | line6pcm->impulse_volume = value; | ||
53 | if (value > 0) | ||
54 | line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_IMPULSE); | ||
55 | else | ||
56 | line6_pcm_release(line6pcm, LINE6_BITS_PCM_IMPULSE); | ||
57 | return 1; | ||
58 | } | ||
59 | |||
60 | /* impulse response period controls */ | ||
61 | static int snd_line6_impulse_period_info(struct snd_kcontrol *kcontrol, | ||
62 | struct snd_ctl_elem_info *uinfo) | ||
63 | { | ||
64 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
65 | uinfo->count = 1; | ||
66 | uinfo->value.integer.min = 0; | ||
67 | uinfo->value.integer.max = 2000; | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static int snd_line6_impulse_period_get(struct snd_kcontrol *kcontrol, | ||
72 | struct snd_ctl_elem_value *ucontrol) | ||
73 | { | ||
74 | struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); | ||
75 | |||
76 | ucontrol->value.integer.value[0] = line6pcm->impulse_period; | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int snd_line6_impulse_period_put(struct snd_kcontrol *kcontrol, | ||
81 | struct snd_ctl_elem_value *ucontrol) | ||
82 | { | ||
83 | struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); | ||
84 | int value = ucontrol->value.integer.value[0]; | ||
85 | |||
86 | if (line6pcm->impulse_period == value) | ||
87 | return 0; | ||
88 | |||
89 | line6pcm->impulse_period = value; | ||
90 | return 1; | ||
91 | } | ||
92 | |||
93 | static bool test_flags(unsigned long flags0, unsigned long flags1, | ||
94 | unsigned long mask) | ||
95 | { | ||
96 | return ((flags0 & mask) == 0) && ((flags1 & mask) != 0); | ||
97 | } | ||
98 | |||
99 | int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) | ||
100 | { | ||
101 | unsigned long flags_old, flags_new, flags_final; | ||
102 | int err; | ||
103 | |||
104 | do { | ||
105 | flags_old = ACCESS_ONCE(line6pcm->flags); | ||
106 | flags_new = flags_old | channels; | ||
107 | } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old); | ||
108 | |||
109 | flags_final = flags_old; | ||
110 | |||
111 | line6pcm->prev_fbuf = NULL; | ||
112 | |||
113 | if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) { | ||
114 | /* Invoked multiple times in a row so allocate once only */ | ||
115 | if (!line6pcm->buffer_in) { | ||
116 | line6pcm->buffer_in = | ||
117 | kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * | ||
118 | line6pcm->max_packet_size, GFP_KERNEL); | ||
119 | if (!line6pcm->buffer_in) { | ||
120 | err = -ENOMEM; | ||
121 | goto pcm_acquire_error; | ||
122 | } | ||
123 | |||
124 | flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_STREAM)) { | ||
129 | /* | ||
130 | Waiting for completion of active URBs in the stop handler is | ||
131 | a bug, we therefore report an error if capturing is restarted | ||
132 | too soon. | ||
133 | */ | ||
134 | if (line6pcm->active_urb_in | line6pcm->unlink_urb_in) { | ||
135 | dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n"); | ||
136 | return -EBUSY; | ||
137 | } | ||
138 | |||
139 | line6pcm->count_in = 0; | ||
140 | line6pcm->prev_fsize = 0; | ||
141 | err = line6_submit_audio_in_all_urbs(line6pcm); | ||
142 | |||
143 | if (err < 0) | ||
144 | goto pcm_acquire_error; | ||
145 | |||
146 | flags_final |= channels & LINE6_BITS_CAPTURE_STREAM; | ||
147 | } | ||
148 | |||
149 | if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) { | ||
150 | /* Invoked multiple times in a row so allocate once only */ | ||
151 | if (!line6pcm->buffer_out) { | ||
152 | line6pcm->buffer_out = | ||
153 | kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * | ||
154 | line6pcm->max_packet_size, GFP_KERNEL); | ||
155 | if (!line6pcm->buffer_out) { | ||
156 | err = -ENOMEM; | ||
157 | goto pcm_acquire_error; | ||
158 | } | ||
159 | |||
160 | flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) { | ||
165 | /* | ||
166 | See comment above regarding PCM restart. | ||
167 | */ | ||
168 | if (line6pcm->active_urb_out | line6pcm->unlink_urb_out) { | ||
169 | dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n"); | ||
170 | return -EBUSY; | ||
171 | } | ||
172 | |||
173 | line6pcm->count_out = 0; | ||
174 | err = line6_submit_audio_out_all_urbs(line6pcm); | ||
175 | |||
176 | if (err < 0) | ||
177 | goto pcm_acquire_error; | ||
178 | |||
179 | flags_final |= channels & LINE6_BITS_PLAYBACK_STREAM; | ||
180 | } | ||
181 | |||
182 | return 0; | ||
183 | |||
184 | pcm_acquire_error: | ||
185 | /* | ||
186 | If not all requested resources/streams could be obtained, release | ||
187 | those which were successfully obtained (if any). | ||
188 | */ | ||
189 | line6_pcm_release(line6pcm, flags_final & channels); | ||
190 | return err; | ||
191 | } | ||
192 | EXPORT_SYMBOL_GPL(line6_pcm_acquire); | ||
193 | |||
194 | int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels) | ||
195 | { | ||
196 | unsigned long flags_old, flags_new; | ||
197 | |||
198 | do { | ||
199 | flags_old = ACCESS_ONCE(line6pcm->flags); | ||
200 | flags_new = flags_old & ~channels; | ||
201 | } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old); | ||
202 | |||
203 | if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM)) | ||
204 | line6_unlink_audio_in_urbs(line6pcm); | ||
205 | |||
206 | if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) { | ||
207 | line6_wait_clear_audio_in_urbs(line6pcm); | ||
208 | line6_free_capture_buffer(line6pcm); | ||
209 | } | ||
210 | |||
211 | if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_STREAM)) | ||
212 | line6_unlink_audio_out_urbs(line6pcm); | ||
213 | |||
214 | if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_BUFFER)) { | ||
215 | line6_wait_clear_audio_out_urbs(line6pcm); | ||
216 | line6_free_playback_buffer(line6pcm); | ||
217 | } | ||
218 | |||
219 | return 0; | ||
220 | } | ||
221 | EXPORT_SYMBOL_GPL(line6_pcm_release); | ||
222 | |||
223 | /* trigger callback */ | ||
224 | int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd) | ||
225 | { | ||
226 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | ||
227 | struct snd_pcm_substream *s; | ||
228 | int err; | ||
229 | |||
230 | spin_lock(&line6pcm->lock_trigger); | ||
231 | clear_bit(LINE6_INDEX_PREPARED, &line6pcm->flags); | ||
232 | |||
233 | snd_pcm_group_for_each_entry(s, substream) { | ||
234 | if (s->pcm->card != substream->pcm->card) | ||
235 | continue; | ||
236 | switch (s->stream) { | ||
237 | case SNDRV_PCM_STREAM_PLAYBACK: | ||
238 | err = snd_line6_playback_trigger(line6pcm, cmd); | ||
239 | |||
240 | if (err < 0) { | ||
241 | spin_unlock(&line6pcm->lock_trigger); | ||
242 | return err; | ||
243 | } | ||
244 | |||
245 | break; | ||
246 | |||
247 | case SNDRV_PCM_STREAM_CAPTURE: | ||
248 | err = snd_line6_capture_trigger(line6pcm, cmd); | ||
249 | |||
250 | if (err < 0) { | ||
251 | spin_unlock(&line6pcm->lock_trigger); | ||
252 | return err; | ||
253 | } | ||
254 | |||
255 | break; | ||
256 | |||
257 | default: | ||
258 | dev_err(line6pcm->line6->ifcdev, | ||
259 | "Unknown stream direction %d\n", s->stream); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | spin_unlock(&line6pcm->lock_trigger); | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | /* control info callback */ | ||
268 | static int snd_line6_control_playback_info(struct snd_kcontrol *kcontrol, | ||
269 | struct snd_ctl_elem_info *uinfo) | ||
270 | { | ||
271 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
272 | uinfo->count = 2; | ||
273 | uinfo->value.integer.min = 0; | ||
274 | uinfo->value.integer.max = 256; | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | /* control get callback */ | ||
279 | static int snd_line6_control_playback_get(struct snd_kcontrol *kcontrol, | ||
280 | struct snd_ctl_elem_value *ucontrol) | ||
281 | { | ||
282 | int i; | ||
283 | struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); | ||
284 | |||
285 | for (i = 2; i--;) | ||
286 | ucontrol->value.integer.value[i] = line6pcm->volume_playback[i]; | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | /* control put callback */ | ||
292 | static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol, | ||
293 | struct snd_ctl_elem_value *ucontrol) | ||
294 | { | ||
295 | int i, changed = 0; | ||
296 | struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); | ||
297 | |||
298 | for (i = 2; i--;) | ||
299 | if (line6pcm->volume_playback[i] != | ||
300 | ucontrol->value.integer.value[i]) { | ||
301 | line6pcm->volume_playback[i] = | ||
302 | ucontrol->value.integer.value[i]; | ||
303 | changed = 1; | ||
304 | } | ||
305 | |||
306 | return changed; | ||
307 | } | ||
308 | |||
309 | /* control definition */ | ||
310 | static struct snd_kcontrol_new line6_controls[] = { | ||
311 | { | ||
312 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
313 | .name = "PCM Playback Volume", | ||
314 | .info = snd_line6_control_playback_info, | ||
315 | .get = snd_line6_control_playback_get, | ||
316 | .put = snd_line6_control_playback_put | ||
317 | }, | ||
318 | { | ||
319 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
320 | .name = "Impulse Response Volume", | ||
321 | .info = snd_line6_impulse_volume_info, | ||
322 | .get = snd_line6_impulse_volume_get, | ||
323 | .put = snd_line6_impulse_volume_put | ||
324 | }, | ||
325 | { | ||
326 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
327 | .name = "Impulse Response Period", | ||
328 | .info = snd_line6_impulse_period_info, | ||
329 | .get = snd_line6_impulse_period_get, | ||
330 | .put = snd_line6_impulse_period_put | ||
331 | }, | ||
332 | }; | ||
333 | |||
334 | /* | ||
335 | Cleanup the PCM device. | ||
336 | */ | ||
337 | static void line6_cleanup_pcm(struct snd_pcm *pcm) | ||
338 | { | ||
339 | int i; | ||
340 | struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm); | ||
341 | |||
342 | for (i = LINE6_ISO_BUFFERS; i--;) { | ||
343 | if (line6pcm->urb_audio_out[i]) { | ||
344 | usb_kill_urb(line6pcm->urb_audio_out[i]); | ||
345 | usb_free_urb(line6pcm->urb_audio_out[i]); | ||
346 | } | ||
347 | if (line6pcm->urb_audio_in[i]) { | ||
348 | usb_kill_urb(line6pcm->urb_audio_in[i]); | ||
349 | usb_free_urb(line6pcm->urb_audio_in[i]); | ||
350 | } | ||
351 | } | ||
352 | kfree(line6pcm); | ||
353 | } | ||
354 | |||
355 | /* create a PCM device */ | ||
356 | static int snd_line6_new_pcm(struct usb_line6 *line6, struct snd_pcm **pcm_ret) | ||
357 | { | ||
358 | struct snd_pcm *pcm; | ||
359 | int err; | ||
360 | |||
361 | err = snd_pcm_new(line6->card, (char *)line6->properties->name, | ||
362 | 0, 1, 1, pcm_ret); | ||
363 | if (err < 0) | ||
364 | return err; | ||
365 | pcm = *pcm_ret; | ||
366 | strcpy(pcm->name, line6->properties->name); | ||
367 | |||
368 | /* set operators */ | ||
369 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, | ||
370 | &snd_line6_playback_ops); | ||
371 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops); | ||
372 | |||
373 | /* pre-allocation of buffers */ | ||
374 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, | ||
375 | snd_dma_continuous_data | ||
376 | (GFP_KERNEL), 64 * 1024, | ||
377 | 128 * 1024); | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | /* | ||
382 | Sync with PCM stream stops. | ||
383 | */ | ||
384 | void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm) | ||
385 | { | ||
386 | line6_unlink_wait_clear_audio_out_urbs(line6pcm); | ||
387 | line6_unlink_wait_clear_audio_in_urbs(line6pcm); | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | Create and register the PCM device and mixer entries. | ||
392 | Create URBs for playback and capture. | ||
393 | */ | ||
394 | int line6_init_pcm(struct usb_line6 *line6, | ||
395 | struct line6_pcm_properties *properties) | ||
396 | { | ||
397 | int i, err; | ||
398 | unsigned ep_read = line6->properties->ep_audio_r; | ||
399 | unsigned ep_write = line6->properties->ep_audio_w; | ||
400 | struct snd_pcm *pcm; | ||
401 | struct snd_line6_pcm *line6pcm; | ||
402 | |||
403 | if (!(line6->properties->capabilities & LINE6_CAP_PCM)) | ||
404 | return 0; /* skip PCM initialization and report success */ | ||
405 | |||
406 | err = snd_line6_new_pcm(line6, &pcm); | ||
407 | if (err < 0) | ||
408 | return err; | ||
409 | |||
410 | line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL); | ||
411 | if (!line6pcm) | ||
412 | return -ENOMEM; | ||
413 | |||
414 | line6pcm->pcm = pcm; | ||
415 | line6pcm->properties = properties; | ||
416 | line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255; | ||
417 | line6pcm->volume_monitor = 255; | ||
418 | line6pcm->line6 = line6; | ||
419 | |||
420 | /* Read and write buffers are sized identically, so choose minimum */ | ||
421 | line6pcm->max_packet_size = min( | ||
422 | usb_maxpacket(line6->usbdev, | ||
423 | usb_rcvisocpipe(line6->usbdev, ep_read), 0), | ||
424 | usb_maxpacket(line6->usbdev, | ||
425 | usb_sndisocpipe(line6->usbdev, ep_write), 1)); | ||
426 | |||
427 | spin_lock_init(&line6pcm->lock_audio_out); | ||
428 | spin_lock_init(&line6pcm->lock_audio_in); | ||
429 | spin_lock_init(&line6pcm->lock_trigger); | ||
430 | line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; | ||
431 | |||
432 | line6->line6pcm = line6pcm; | ||
433 | |||
434 | pcm->private_data = line6pcm; | ||
435 | pcm->private_free = line6_cleanup_pcm; | ||
436 | |||
437 | err = line6_create_audio_out_urbs(line6pcm); | ||
438 | if (err < 0) | ||
439 | return err; | ||
440 | |||
441 | err = line6_create_audio_in_urbs(line6pcm); | ||
442 | if (err < 0) | ||
443 | return err; | ||
444 | |||
445 | /* mixer: */ | ||
446 | for (i = 0; i < ARRAY_SIZE(line6_controls); i++) { | ||
447 | err = snd_ctl_add(line6->card, | ||
448 | snd_ctl_new1(&line6_controls[i], line6pcm)); | ||
449 | if (err < 0) | ||
450 | return err; | ||
451 | } | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | EXPORT_SYMBOL_GPL(line6_init_pcm); | ||
456 | |||
457 | /* prepare pcm callback */ | ||
458 | int snd_line6_prepare(struct snd_pcm_substream *substream) | ||
459 | { | ||
460 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | ||
461 | |||
462 | switch (substream->stream) { | ||
463 | case SNDRV_PCM_STREAM_PLAYBACK: | ||
464 | if ((line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) == 0) | ||
465 | line6_unlink_wait_clear_audio_out_urbs(line6pcm); | ||
466 | |||
467 | break; | ||
468 | |||
469 | case SNDRV_PCM_STREAM_CAPTURE: | ||
470 | if ((line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) == 0) | ||
471 | line6_unlink_wait_clear_audio_in_urbs(line6pcm); | ||
472 | |||
473 | break; | ||
474 | } | ||
475 | |||
476 | if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) { | ||
477 | line6pcm->count_out = 0; | ||
478 | line6pcm->pos_out = 0; | ||
479 | line6pcm->pos_out_done = 0; | ||
480 | line6pcm->bytes_out = 0; | ||
481 | line6pcm->count_in = 0; | ||
482 | line6pcm->pos_in_done = 0; | ||
483 | line6pcm->bytes_in = 0; | ||
484 | } | ||
485 | |||
486 | return 0; | ||
487 | } | ||
diff --git a/sound/usb/line6/pcm.h b/sound/usb/line6/pcm.h new file mode 100644 index 000000000000..c742b33666eb --- /dev/null +++ b/sound/usb/line6/pcm.h | |||
@@ -0,0 +1,356 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | PCM interface to POD series devices. | ||
14 | */ | ||
15 | |||
16 | #ifndef PCM_H | ||
17 | #define PCM_H | ||
18 | |||
19 | #include <sound/pcm.h> | ||
20 | |||
21 | #include "driver.h" | ||
22 | #include "usbdefs.h" | ||
23 | |||
24 | /* number of URBs */ | ||
25 | #define LINE6_ISO_BUFFERS 2 | ||
26 | |||
27 | /* | ||
28 | number of USB frames per URB | ||
29 | The Line 6 Windows driver always transmits two frames per packet, but | ||
30 | the Linux driver performs significantly better (i.e., lower latency) | ||
31 | with only one frame per packet. | ||
32 | */ | ||
33 | #define LINE6_ISO_PACKETS 1 | ||
34 | |||
35 | /* in a "full speed" device (such as the PODxt Pro) this means 1ms */ | ||
36 | #define LINE6_ISO_INTERVAL 1 | ||
37 | |||
38 | #define LINE6_IMPULSE_DEFAULT_PERIOD 100 | ||
39 | |||
40 | /* | ||
41 | Get substream from Line 6 PCM data structure | ||
42 | */ | ||
43 | #define get_substream(line6pcm, stream) \ | ||
44 | (line6pcm->pcm->streams[stream].substream) | ||
45 | |||
46 | /* | ||
47 | PCM mode bits. | ||
48 | |||
49 | There are several features of the Line 6 USB driver which require PCM | ||
50 | data to be exchanged with the device: | ||
51 | *) PCM playback and capture via ALSA | ||
52 | *) software monitoring (for devices without hardware monitoring) | ||
53 | *) optional impulse response measurement | ||
54 | However, from the device's point of view, there is just a single | ||
55 | capture and playback stream, which must be shared between these | ||
56 | subsystems. It is therefore necessary to maintain the state of the | ||
57 | subsystems with respect to PCM usage. We define several constants of | ||
58 | the form LINE6_BIT_PCM_<subsystem>_<direction>_<resource> with the | ||
59 | following meanings: | ||
60 | *) <subsystem> is one of | ||
61 | -) ALSA: PCM playback and capture via ALSA | ||
62 | -) MONITOR: software monitoring | ||
63 | -) IMPULSE: optional impulse response measurement | ||
64 | *) <direction> is one of | ||
65 | -) PLAYBACK: audio output (from host to device) | ||
66 | -) CAPTURE: audio input (from device to host) | ||
67 | *) <resource> is one of | ||
68 | -) BUFFER: buffer required by PCM data stream | ||
69 | -) STREAM: actual PCM data stream | ||
70 | |||
71 | The subsystems call line6_pcm_acquire() to acquire the (shared) | ||
72 | resources needed for a particular operation (e.g., allocate the buffer | ||
73 | for ALSA playback or start the capture stream for software monitoring). | ||
74 | When a resource is no longer needed, it is released by calling | ||
75 | line6_pcm_release(). Buffer allocation and stream startup are handled | ||
76 | separately to allow the ALSA kernel driver to perform them at | ||
77 | appropriate places (since the callback which starts a PCM stream is not | ||
78 | allowed to sleep). | ||
79 | */ | ||
80 | enum { | ||
81 | /* individual bit indices: */ | ||
82 | LINE6_INDEX_PCM_ALSA_PLAYBACK_BUFFER, | ||
83 | LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, | ||
84 | LINE6_INDEX_PCM_ALSA_CAPTURE_BUFFER, | ||
85 | LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, | ||
86 | LINE6_INDEX_PCM_MONITOR_PLAYBACK_BUFFER, | ||
87 | LINE6_INDEX_PCM_MONITOR_PLAYBACK_STREAM, | ||
88 | LINE6_INDEX_PCM_MONITOR_CAPTURE_BUFFER, | ||
89 | LINE6_INDEX_PCM_MONITOR_CAPTURE_STREAM, | ||
90 | LINE6_INDEX_PCM_IMPULSE_PLAYBACK_BUFFER, | ||
91 | LINE6_INDEX_PCM_IMPULSE_PLAYBACK_STREAM, | ||
92 | LINE6_INDEX_PCM_IMPULSE_CAPTURE_BUFFER, | ||
93 | LINE6_INDEX_PCM_IMPULSE_CAPTURE_STREAM, | ||
94 | LINE6_INDEX_PAUSE_PLAYBACK, | ||
95 | LINE6_INDEX_PREPARED, | ||
96 | |||
97 | #define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_INDEX_ ## x | ||
98 | |||
99 | /* individual bit masks: */ | ||
100 | LINE6_BIT(PCM_ALSA_PLAYBACK_BUFFER), | ||
101 | LINE6_BIT(PCM_ALSA_PLAYBACK_STREAM), | ||
102 | LINE6_BIT(PCM_ALSA_CAPTURE_BUFFER), | ||
103 | LINE6_BIT(PCM_ALSA_CAPTURE_STREAM), | ||
104 | LINE6_BIT(PCM_MONITOR_PLAYBACK_BUFFER), | ||
105 | LINE6_BIT(PCM_MONITOR_PLAYBACK_STREAM), | ||
106 | LINE6_BIT(PCM_MONITOR_CAPTURE_BUFFER), | ||
107 | LINE6_BIT(PCM_MONITOR_CAPTURE_STREAM), | ||
108 | LINE6_BIT(PCM_IMPULSE_PLAYBACK_BUFFER), | ||
109 | LINE6_BIT(PCM_IMPULSE_PLAYBACK_STREAM), | ||
110 | LINE6_BIT(PCM_IMPULSE_CAPTURE_BUFFER), | ||
111 | LINE6_BIT(PCM_IMPULSE_CAPTURE_STREAM), | ||
112 | LINE6_BIT(PAUSE_PLAYBACK), | ||
113 | LINE6_BIT(PREPARED), | ||
114 | |||
115 | /* combined bit masks (by operation): */ | ||
116 | LINE6_BITS_PCM_ALSA_BUFFER = | ||
117 | LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER | | ||
118 | LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER, | ||
119 | |||
120 | LINE6_BITS_PCM_ALSA_STREAM = | ||
121 | LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM | | ||
122 | LINE6_BIT_PCM_ALSA_CAPTURE_STREAM, | ||
123 | |||
124 | LINE6_BITS_PCM_MONITOR = | ||
125 | LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER | | ||
126 | LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM | | ||
127 | LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER | | ||
128 | LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM, | ||
129 | |||
130 | LINE6_BITS_PCM_IMPULSE = | ||
131 | LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER | | ||
132 | LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM | | ||
133 | LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER | | ||
134 | LINE6_BIT_PCM_IMPULSE_CAPTURE_STREAM, | ||
135 | |||
136 | /* combined bit masks (by direction): */ | ||
137 | LINE6_BITS_PLAYBACK_BUFFER = | ||
138 | LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER | | ||
139 | LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER | | ||
140 | LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER, | ||
141 | |||
142 | LINE6_BITS_PLAYBACK_STREAM = | ||
143 | LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM | | ||
144 | LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM | | ||
145 | LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM, | ||
146 | |||
147 | LINE6_BITS_CAPTURE_BUFFER = | ||
148 | LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER | | ||
149 | LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER | | ||
150 | LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER, | ||
151 | |||
152 | LINE6_BITS_CAPTURE_STREAM = | ||
153 | LINE6_BIT_PCM_IMPULSE_CAPTURE_STREAM | | ||
154 | LINE6_BIT_PCM_ALSA_CAPTURE_STREAM | | ||
155 | LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM, | ||
156 | |||
157 | LINE6_BITS_STREAM = | ||
158 | LINE6_BITS_PLAYBACK_STREAM | | ||
159 | LINE6_BITS_CAPTURE_STREAM | ||
160 | }; | ||
161 | |||
162 | struct line6_pcm_properties { | ||
163 | struct snd_pcm_hardware snd_line6_playback_hw, snd_line6_capture_hw; | ||
164 | struct snd_pcm_hw_constraint_ratdens snd_line6_rates; | ||
165 | int bytes_per_frame; | ||
166 | }; | ||
167 | |||
168 | struct snd_line6_pcm { | ||
169 | /** | ||
170 | Pointer back to the Line 6 driver data structure. | ||
171 | */ | ||
172 | struct usb_line6 *line6; | ||
173 | |||
174 | /** | ||
175 | Properties. | ||
176 | */ | ||
177 | struct line6_pcm_properties *properties; | ||
178 | |||
179 | /** | ||
180 | ALSA pcm stream | ||
181 | */ | ||
182 | struct snd_pcm *pcm; | ||
183 | |||
184 | /** | ||
185 | URBs for audio playback. | ||
186 | */ | ||
187 | struct urb *urb_audio_out[LINE6_ISO_BUFFERS]; | ||
188 | |||
189 | /** | ||
190 | URBs for audio capture. | ||
191 | */ | ||
192 | struct urb *urb_audio_in[LINE6_ISO_BUFFERS]; | ||
193 | |||
194 | /** | ||
195 | Temporary buffer for playback. | ||
196 | Since the packet size is not known in advance, this buffer is | ||
197 | large enough to store maximum size packets. | ||
198 | */ | ||
199 | unsigned char *buffer_out; | ||
200 | |||
201 | /** | ||
202 | Temporary buffer for capture. | ||
203 | Since the packet size is not known in advance, this buffer is | ||
204 | large enough to store maximum size packets. | ||
205 | */ | ||
206 | unsigned char *buffer_in; | ||
207 | |||
208 | /** | ||
209 | Previously captured frame (for software monitoring). | ||
210 | */ | ||
211 | unsigned char *prev_fbuf; | ||
212 | |||
213 | /** | ||
214 | Size of previously captured frame (for software monitoring). | ||
215 | */ | ||
216 | int prev_fsize; | ||
217 | |||
218 | /** | ||
219 | Free frame position in the playback buffer. | ||
220 | */ | ||
221 | snd_pcm_uframes_t pos_out; | ||
222 | |||
223 | /** | ||
224 | Count processed bytes for playback. | ||
225 | This is modulo period size (to determine when a period is | ||
226 | finished). | ||
227 | */ | ||
228 | unsigned bytes_out; | ||
229 | |||
230 | /** | ||
231 | Counter to create desired playback sample rate. | ||
232 | */ | ||
233 | unsigned count_out; | ||
234 | |||
235 | /** | ||
236 | Playback period size in bytes | ||
237 | */ | ||
238 | unsigned period_out; | ||
239 | |||
240 | /** | ||
241 | Processed frame position in the playback buffer. | ||
242 | The contents of the output ring buffer have been consumed by | ||
243 | the USB subsystem (i.e., sent to the USB device) up to this | ||
244 | position. | ||
245 | */ | ||
246 | snd_pcm_uframes_t pos_out_done; | ||
247 | |||
248 | /** | ||
249 | Count processed bytes for capture. | ||
250 | This is modulo period size (to determine when a period is | ||
251 | finished). | ||
252 | */ | ||
253 | unsigned bytes_in; | ||
254 | |||
255 | /** | ||
256 | Counter to create desired capture sample rate. | ||
257 | */ | ||
258 | unsigned count_in; | ||
259 | |||
260 | /** | ||
261 | Capture period size in bytes | ||
262 | */ | ||
263 | unsigned period_in; | ||
264 | |||
265 | /** | ||
266 | Processed frame position in the capture buffer. | ||
267 | The contents of the output ring buffer have been consumed by | ||
268 | the USB subsystem (i.e., sent to the USB device) up to this | ||
269 | position. | ||
270 | */ | ||
271 | snd_pcm_uframes_t pos_in_done; | ||
272 | |||
273 | /** | ||
274 | Bit mask of active playback URBs. | ||
275 | */ | ||
276 | unsigned long active_urb_out; | ||
277 | |||
278 | /** | ||
279 | Maximum size of USB packet. | ||
280 | */ | ||
281 | int max_packet_size; | ||
282 | |||
283 | /** | ||
284 | Bit mask of active capture URBs. | ||
285 | */ | ||
286 | unsigned long active_urb_in; | ||
287 | |||
288 | /** | ||
289 | Bit mask of playback URBs currently being unlinked. | ||
290 | */ | ||
291 | unsigned long unlink_urb_out; | ||
292 | |||
293 | /** | ||
294 | Bit mask of capture URBs currently being unlinked. | ||
295 | */ | ||
296 | unsigned long unlink_urb_in; | ||
297 | |||
298 | /** | ||
299 | Spin lock to protect updates of the playback buffer positions (not | ||
300 | contents!) | ||
301 | */ | ||
302 | spinlock_t lock_audio_out; | ||
303 | |||
304 | /** | ||
305 | Spin lock to protect updates of the capture buffer positions (not | ||
306 | contents!) | ||
307 | */ | ||
308 | spinlock_t lock_audio_in; | ||
309 | |||
310 | /** | ||
311 | Spin lock to protect trigger. | ||
312 | */ | ||
313 | spinlock_t lock_trigger; | ||
314 | |||
315 | /** | ||
316 | PCM playback volume (left and right). | ||
317 | */ | ||
318 | int volume_playback[2]; | ||
319 | |||
320 | /** | ||
321 | PCM monitor volume. | ||
322 | */ | ||
323 | int volume_monitor; | ||
324 | |||
325 | /** | ||
326 | Volume of impulse response test signal (if zero, test is disabled). | ||
327 | */ | ||
328 | int impulse_volume; | ||
329 | |||
330 | /** | ||
331 | Period of impulse response test signal. | ||
332 | */ | ||
333 | int impulse_period; | ||
334 | |||
335 | /** | ||
336 | Counter for impulse response test signal. | ||
337 | */ | ||
338 | int impulse_count; | ||
339 | |||
340 | /** | ||
341 | Several status bits (see LINE6_BIT_*). | ||
342 | */ | ||
343 | unsigned long flags; | ||
344 | |||
345 | int last_frame_in, last_frame_out; | ||
346 | }; | ||
347 | |||
348 | extern int line6_init_pcm(struct usb_line6 *line6, | ||
349 | struct line6_pcm_properties *properties); | ||
350 | extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd); | ||
351 | extern int snd_line6_prepare(struct snd_pcm_substream *substream); | ||
352 | extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm); | ||
353 | extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels); | ||
354 | extern int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels); | ||
355 | |||
356 | #endif | ||
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c new file mode 100644 index 000000000000..1c9f95a370ff --- /dev/null +++ b/sound/usb/line6/playback.c | |||
@@ -0,0 +1,577 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/slab.h> | ||
13 | #include <sound/core.h> | ||
14 | #include <sound/pcm.h> | ||
15 | #include <sound/pcm_params.h> | ||
16 | |||
17 | #include "capture.h" | ||
18 | #include "driver.h" | ||
19 | #include "pcm.h" | ||
20 | #include "playback.h" | ||
21 | |||
22 | /* | ||
23 | Software stereo volume control. | ||
24 | */ | ||
25 | static void change_volume(struct urb *urb_out, int volume[], | ||
26 | int bytes_per_frame) | ||
27 | { | ||
28 | int chn = 0; | ||
29 | |||
30 | if (volume[0] == 256 && volume[1] == 256) | ||
31 | return; /* maximum volume - no change */ | ||
32 | |||
33 | if (bytes_per_frame == 4) { | ||
34 | short *p, *buf_end; | ||
35 | |||
36 | p = (short *)urb_out->transfer_buffer; | ||
37 | buf_end = p + urb_out->transfer_buffer_length / sizeof(*p); | ||
38 | |||
39 | for (; p < buf_end; ++p) { | ||
40 | *p = (*p * volume[chn & 1]) >> 8; | ||
41 | ++chn; | ||
42 | } | ||
43 | } else if (bytes_per_frame == 6) { | ||
44 | unsigned char *p, *buf_end; | ||
45 | |||
46 | p = (unsigned char *)urb_out->transfer_buffer; | ||
47 | buf_end = p + urb_out->transfer_buffer_length; | ||
48 | |||
49 | for (; p < buf_end; p += 3) { | ||
50 | int val; | ||
51 | |||
52 | val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16); | ||
53 | val = (val * volume[chn & 1]) >> 8; | ||
54 | p[0] = val; | ||
55 | p[1] = val >> 8; | ||
56 | p[2] = val >> 16; | ||
57 | ++chn; | ||
58 | } | ||
59 | } | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | Create signal for impulse response test. | ||
64 | */ | ||
65 | static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm, | ||
66 | struct urb *urb_out, int bytes_per_frame) | ||
67 | { | ||
68 | int frames = urb_out->transfer_buffer_length / bytes_per_frame; | ||
69 | |||
70 | if (bytes_per_frame == 4) { | ||
71 | int i; | ||
72 | short *pi = (short *)line6pcm->prev_fbuf; | ||
73 | short *po = (short *)urb_out->transfer_buffer; | ||
74 | |||
75 | for (i = 0; i < frames; ++i) { | ||
76 | po[0] = pi[0]; | ||
77 | po[1] = 0; | ||
78 | pi += 2; | ||
79 | po += 2; | ||
80 | } | ||
81 | } else if (bytes_per_frame == 6) { | ||
82 | int i, j; | ||
83 | unsigned char *pi = line6pcm->prev_fbuf; | ||
84 | unsigned char *po = urb_out->transfer_buffer; | ||
85 | |||
86 | for (i = 0; i < frames; ++i) { | ||
87 | for (j = 0; j < bytes_per_frame / 2; ++j) | ||
88 | po[j] = pi[j]; | ||
89 | |||
90 | for (; j < bytes_per_frame; ++j) | ||
91 | po[j] = 0; | ||
92 | |||
93 | pi += bytes_per_frame; | ||
94 | po += bytes_per_frame; | ||
95 | } | ||
96 | } | ||
97 | if (--line6pcm->impulse_count <= 0) { | ||
98 | ((unsigned char *)(urb_out->transfer_buffer))[bytes_per_frame - | ||
99 | 1] = | ||
100 | line6pcm->impulse_volume; | ||
101 | line6pcm->impulse_count = line6pcm->impulse_period; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | Add signal to buffer for software monitoring. | ||
107 | */ | ||
108 | static void add_monitor_signal(struct urb *urb_out, unsigned char *signal, | ||
109 | int volume, int bytes_per_frame) | ||
110 | { | ||
111 | if (volume == 0) | ||
112 | return; /* zero volume - no change */ | ||
113 | |||
114 | if (bytes_per_frame == 4) { | ||
115 | short *pi, *po, *buf_end; | ||
116 | |||
117 | pi = (short *)signal; | ||
118 | po = (short *)urb_out->transfer_buffer; | ||
119 | buf_end = po + urb_out->transfer_buffer_length / sizeof(*po); | ||
120 | |||
121 | for (; po < buf_end; ++pi, ++po) | ||
122 | *po += (*pi * volume) >> 8; | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | We don't need to handle devices with 6 bytes per frame here | ||
127 | since they all support hardware monitoring. | ||
128 | */ | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | Find a free URB, prepare audio data, and submit URB. | ||
133 | */ | ||
134 | static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | ||
135 | { | ||
136 | int index; | ||
137 | unsigned long flags; | ||
138 | int i, urb_size, urb_frames; | ||
139 | int ret; | ||
140 | const int bytes_per_frame = line6pcm->properties->bytes_per_frame; | ||
141 | const int frame_increment = | ||
142 | line6pcm->properties->snd_line6_rates.rats[0].num_min; | ||
143 | const int frame_factor = | ||
144 | line6pcm->properties->snd_line6_rates.rats[0].den * | ||
145 | (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL); | ||
146 | struct urb *urb_out; | ||
147 | |||
148 | spin_lock_irqsave(&line6pcm->lock_audio_out, flags); | ||
149 | index = | ||
150 | find_first_zero_bit(&line6pcm->active_urb_out, LINE6_ISO_BUFFERS); | ||
151 | |||
152 | if (index < 0 || index >= LINE6_ISO_BUFFERS) { | ||
153 | spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); | ||
154 | dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | urb_out = line6pcm->urb_audio_out[index]; | ||
159 | urb_size = 0; | ||
160 | |||
161 | for (i = 0; i < LINE6_ISO_PACKETS; ++i) { | ||
162 | /* compute frame size for given sampling rate */ | ||
163 | int fsize = 0; | ||
164 | struct usb_iso_packet_descriptor *fout = | ||
165 | &urb_out->iso_frame_desc[i]; | ||
166 | |||
167 | if (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) | ||
168 | fsize = line6pcm->prev_fsize; | ||
169 | |||
170 | if (fsize == 0) { | ||
171 | int n; | ||
172 | |||
173 | line6pcm->count_out += frame_increment; | ||
174 | n = line6pcm->count_out / frame_factor; | ||
175 | line6pcm->count_out -= n * frame_factor; | ||
176 | fsize = n * bytes_per_frame; | ||
177 | } | ||
178 | |||
179 | fout->offset = urb_size; | ||
180 | fout->length = fsize; | ||
181 | urb_size += fsize; | ||
182 | } | ||
183 | |||
184 | if (urb_size == 0) { | ||
185 | /* can't determine URB size */ | ||
186 | spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); | ||
187 | dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n"); | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | |||
191 | urb_frames = urb_size / bytes_per_frame; | ||
192 | urb_out->transfer_buffer = | ||
193 | line6pcm->buffer_out + | ||
194 | index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; | ||
195 | urb_out->transfer_buffer_length = urb_size; | ||
196 | urb_out->context = line6pcm; | ||
197 | |||
198 | if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags) && | ||
199 | !test_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags)) { | ||
200 | struct snd_pcm_runtime *runtime = | ||
201 | get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime; | ||
202 | |||
203 | if (line6pcm->pos_out + urb_frames > runtime->buffer_size) { | ||
204 | /* | ||
205 | The transferred area goes over buffer boundary, | ||
206 | copy the data to the temp buffer. | ||
207 | */ | ||
208 | int len; | ||
209 | |||
210 | len = runtime->buffer_size - line6pcm->pos_out; | ||
211 | |||
212 | if (len > 0) { | ||
213 | memcpy(urb_out->transfer_buffer, | ||
214 | runtime->dma_area + | ||
215 | line6pcm->pos_out * bytes_per_frame, | ||
216 | len * bytes_per_frame); | ||
217 | memcpy(urb_out->transfer_buffer + | ||
218 | len * bytes_per_frame, runtime->dma_area, | ||
219 | (urb_frames - len) * bytes_per_frame); | ||
220 | } else | ||
221 | dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", | ||
222 | len); | ||
223 | } else { | ||
224 | memcpy(urb_out->transfer_buffer, | ||
225 | runtime->dma_area + | ||
226 | line6pcm->pos_out * bytes_per_frame, | ||
227 | urb_out->transfer_buffer_length); | ||
228 | } | ||
229 | |||
230 | line6pcm->pos_out += urb_frames; | ||
231 | if (line6pcm->pos_out >= runtime->buffer_size) | ||
232 | line6pcm->pos_out -= runtime->buffer_size; | ||
233 | } else { | ||
234 | memset(urb_out->transfer_buffer, 0, | ||
235 | urb_out->transfer_buffer_length); | ||
236 | } | ||
237 | |||
238 | change_volume(urb_out, line6pcm->volume_playback, bytes_per_frame); | ||
239 | |||
240 | if (line6pcm->prev_fbuf != NULL) { | ||
241 | if (line6pcm->flags & LINE6_BITS_PCM_IMPULSE) { | ||
242 | create_impulse_test_signal(line6pcm, urb_out, | ||
243 | bytes_per_frame); | ||
244 | if (line6pcm->flags & | ||
245 | LINE6_BIT_PCM_ALSA_CAPTURE_STREAM) { | ||
246 | line6_capture_copy(line6pcm, | ||
247 | urb_out->transfer_buffer, | ||
248 | urb_out-> | ||
249 | transfer_buffer_length); | ||
250 | line6_capture_check_period(line6pcm, | ||
251 | urb_out->transfer_buffer_length); | ||
252 | } | ||
253 | } else { | ||
254 | if (! | ||
255 | (line6pcm->line6-> | ||
256 | properties->capabilities & LINE6_CAP_HWMON) | ||
257 | && (line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) | ||
258 | && (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM)) | ||
259 | add_monitor_signal(urb_out, line6pcm->prev_fbuf, | ||
260 | line6pcm->volume_monitor, | ||
261 | bytes_per_frame); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | ret = usb_submit_urb(urb_out, GFP_ATOMIC); | ||
266 | |||
267 | if (ret == 0) | ||
268 | set_bit(index, &line6pcm->active_urb_out); | ||
269 | else | ||
270 | dev_err(line6pcm->line6->ifcdev, | ||
271 | "URB out #%d submission failed (%d)\n", index, ret); | ||
272 | |||
273 | spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); | ||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | /* | ||
278 | Submit all currently available playback URBs. | ||
279 | */ | ||
280 | int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm) | ||
281 | { | ||
282 | int ret, i; | ||
283 | |||
284 | for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { | ||
285 | ret = submit_audio_out_urb(line6pcm); | ||
286 | if (ret < 0) | ||
287 | return ret; | ||
288 | } | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | Unlink all currently active playback URBs. | ||
295 | */ | ||
296 | void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm) | ||
297 | { | ||
298 | unsigned int i; | ||
299 | |||
300 | for (i = LINE6_ISO_BUFFERS; i--;) { | ||
301 | if (test_bit(i, &line6pcm->active_urb_out)) { | ||
302 | if (!test_and_set_bit(i, &line6pcm->unlink_urb_out)) { | ||
303 | struct urb *u = line6pcm->urb_audio_out[i]; | ||
304 | |||
305 | usb_unlink_urb(u); | ||
306 | } | ||
307 | } | ||
308 | } | ||
309 | } | ||
310 | |||
311 | /* | ||
312 | Wait until unlinking of all currently active playback URBs has been | ||
313 | finished. | ||
314 | */ | ||
315 | void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) | ||
316 | { | ||
317 | int timeout = HZ; | ||
318 | unsigned int i; | ||
319 | int alive; | ||
320 | |||
321 | do { | ||
322 | alive = 0; | ||
323 | for (i = LINE6_ISO_BUFFERS; i--;) { | ||
324 | if (test_bit(i, &line6pcm->active_urb_out)) | ||
325 | alive++; | ||
326 | } | ||
327 | if (!alive) | ||
328 | break; | ||
329 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
330 | schedule_timeout(1); | ||
331 | } while (--timeout > 0); | ||
332 | if (alive) | ||
333 | snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive); | ||
334 | } | ||
335 | |||
336 | /* | ||
337 | Unlink all currently active playback URBs, and wait for finishing. | ||
338 | */ | ||
339 | void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) | ||
340 | { | ||
341 | line6_unlink_audio_out_urbs(line6pcm); | ||
342 | line6_wait_clear_audio_out_urbs(line6pcm); | ||
343 | } | ||
344 | |||
345 | void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm) | ||
346 | { | ||
347 | kfree(line6pcm->buffer_out); | ||
348 | line6pcm->buffer_out = NULL; | ||
349 | } | ||
350 | |||
351 | /* | ||
352 | Callback for completed playback URB. | ||
353 | */ | ||
354 | static void audio_out_callback(struct urb *urb) | ||
355 | { | ||
356 | int i, index, length = 0, shutdown = 0; | ||
357 | unsigned long flags; | ||
358 | struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context; | ||
359 | struct snd_pcm_substream *substream = | ||
360 | get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK); | ||
361 | |||
362 | #if USE_CLEAR_BUFFER_WORKAROUND | ||
363 | memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); | ||
364 | #endif | ||
365 | |||
366 | line6pcm->last_frame_out = urb->start_frame; | ||
367 | |||
368 | /* find index of URB */ | ||
369 | for (index = LINE6_ISO_BUFFERS; index--;) | ||
370 | if (urb == line6pcm->urb_audio_out[index]) | ||
371 | break; | ||
372 | |||
373 | if (index < 0) | ||
374 | return; /* URB has been unlinked asynchronously */ | ||
375 | |||
376 | for (i = LINE6_ISO_PACKETS; i--;) | ||
377 | length += urb->iso_frame_desc[i].length; | ||
378 | |||
379 | spin_lock_irqsave(&line6pcm->lock_audio_out, flags); | ||
380 | |||
381 | if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) { | ||
382 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
383 | |||
384 | line6pcm->pos_out_done += | ||
385 | length / line6pcm->properties->bytes_per_frame; | ||
386 | |||
387 | if (line6pcm->pos_out_done >= runtime->buffer_size) | ||
388 | line6pcm->pos_out_done -= runtime->buffer_size; | ||
389 | } | ||
390 | |||
391 | clear_bit(index, &line6pcm->active_urb_out); | ||
392 | |||
393 | for (i = LINE6_ISO_PACKETS; i--;) | ||
394 | if (urb->iso_frame_desc[i].status == -EXDEV) { | ||
395 | shutdown = 1; | ||
396 | break; | ||
397 | } | ||
398 | |||
399 | if (test_and_clear_bit(index, &line6pcm->unlink_urb_out)) | ||
400 | shutdown = 1; | ||
401 | |||
402 | spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); | ||
403 | |||
404 | if (!shutdown) { | ||
405 | submit_audio_out_urb(line6pcm); | ||
406 | |||
407 | if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, | ||
408 | &line6pcm->flags)) { | ||
409 | line6pcm->bytes_out += length; | ||
410 | if (line6pcm->bytes_out >= line6pcm->period_out) { | ||
411 | line6pcm->bytes_out %= line6pcm->period_out; | ||
412 | snd_pcm_period_elapsed(substream); | ||
413 | } | ||
414 | } | ||
415 | } | ||
416 | } | ||
417 | |||
418 | /* open playback callback */ | ||
419 | static int snd_line6_playback_open(struct snd_pcm_substream *substream) | ||
420 | { | ||
421 | int err; | ||
422 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
423 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | ||
424 | |||
425 | err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
426 | (&line6pcm-> | ||
427 | properties->snd_line6_rates)); | ||
428 | if (err < 0) | ||
429 | return err; | ||
430 | |||
431 | runtime->hw = line6pcm->properties->snd_line6_playback_hw; | ||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | /* close playback callback */ | ||
436 | static int snd_line6_playback_close(struct snd_pcm_substream *substream) | ||
437 | { | ||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | /* hw_params playback callback */ | ||
442 | static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream, | ||
443 | struct snd_pcm_hw_params *hw_params) | ||
444 | { | ||
445 | int ret; | ||
446 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | ||
447 | |||
448 | /* -- Florian Demski [FD] */ | ||
449 | /* don't ask me why, but this fixes the bug on my machine */ | ||
450 | if (line6pcm == NULL) { | ||
451 | if (substream->pcm == NULL) | ||
452 | return -ENOMEM; | ||
453 | if (substream->pcm->private_data == NULL) | ||
454 | return -ENOMEM; | ||
455 | substream->private_data = substream->pcm->private_data; | ||
456 | line6pcm = snd_pcm_substream_chip(substream); | ||
457 | } | ||
458 | /* -- [FD] end */ | ||
459 | |||
460 | ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER); | ||
461 | |||
462 | if (ret < 0) | ||
463 | return ret; | ||
464 | |||
465 | ret = snd_pcm_lib_malloc_pages(substream, | ||
466 | params_buffer_bytes(hw_params)); | ||
467 | if (ret < 0) { | ||
468 | line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER); | ||
469 | return ret; | ||
470 | } | ||
471 | |||
472 | line6pcm->period_out = params_period_bytes(hw_params); | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | /* hw_free playback callback */ | ||
477 | static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream) | ||
478 | { | ||
479 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | ||
480 | |||
481 | line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER); | ||
482 | return snd_pcm_lib_free_pages(substream); | ||
483 | } | ||
484 | |||
485 | /* trigger playback callback */ | ||
486 | int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd) | ||
487 | { | ||
488 | int err; | ||
489 | |||
490 | switch (cmd) { | ||
491 | case SNDRV_PCM_TRIGGER_START: | ||
492 | case SNDRV_PCM_TRIGGER_RESUME: | ||
493 | err = line6_pcm_acquire(line6pcm, | ||
494 | LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM); | ||
495 | |||
496 | if (err < 0) | ||
497 | return err; | ||
498 | |||
499 | break; | ||
500 | |||
501 | case SNDRV_PCM_TRIGGER_STOP: | ||
502 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
503 | err = line6_pcm_release(line6pcm, | ||
504 | LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM); | ||
505 | |||
506 | if (err < 0) | ||
507 | return err; | ||
508 | |||
509 | break; | ||
510 | |||
511 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
512 | set_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags); | ||
513 | break; | ||
514 | |||
515 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
516 | clear_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags); | ||
517 | break; | ||
518 | |||
519 | default: | ||
520 | return -EINVAL; | ||
521 | } | ||
522 | |||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | /* playback pointer callback */ | ||
527 | static snd_pcm_uframes_t | ||
528 | snd_line6_playback_pointer(struct snd_pcm_substream *substream) | ||
529 | { | ||
530 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | ||
531 | |||
532 | return line6pcm->pos_out_done; | ||
533 | } | ||
534 | |||
535 | /* playback operators */ | ||
536 | struct snd_pcm_ops snd_line6_playback_ops = { | ||
537 | .open = snd_line6_playback_open, | ||
538 | .close = snd_line6_playback_close, | ||
539 | .ioctl = snd_pcm_lib_ioctl, | ||
540 | .hw_params = snd_line6_playback_hw_params, | ||
541 | .hw_free = snd_line6_playback_hw_free, | ||
542 | .prepare = snd_line6_prepare, | ||
543 | .trigger = snd_line6_trigger, | ||
544 | .pointer = snd_line6_playback_pointer, | ||
545 | }; | ||
546 | |||
547 | int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) | ||
548 | { | ||
549 | struct usb_line6 *line6 = line6pcm->line6; | ||
550 | int i; | ||
551 | |||
552 | /* create audio URBs and fill in constant values: */ | ||
553 | for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { | ||
554 | struct urb *urb; | ||
555 | |||
556 | /* URB for audio out: */ | ||
557 | urb = line6pcm->urb_audio_out[i] = | ||
558 | usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); | ||
559 | |||
560 | if (urb == NULL) | ||
561 | return -ENOMEM; | ||
562 | |||
563 | urb->dev = line6->usbdev; | ||
564 | urb->pipe = | ||
565 | usb_sndisocpipe(line6->usbdev, | ||
566 | line6->properties->ep_audio_w & | ||
567 | USB_ENDPOINT_NUMBER_MASK); | ||
568 | urb->transfer_flags = URB_ISO_ASAP; | ||
569 | urb->start_frame = -1; | ||
570 | urb->number_of_packets = LINE6_ISO_PACKETS; | ||
571 | urb->interval = LINE6_ISO_INTERVAL; | ||
572 | urb->error_count = 0; | ||
573 | urb->complete = audio_out_callback; | ||
574 | } | ||
575 | |||
576 | return 0; | ||
577 | } | ||
diff --git a/sound/usb/line6/playback.h b/sound/usb/line6/playback.h new file mode 100644 index 000000000000..78a885113221 --- /dev/null +++ b/sound/usb/line6/playback.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef PLAYBACK_H | ||
13 | #define PLAYBACK_H | ||
14 | |||
15 | #include <sound/pcm.h> | ||
16 | |||
17 | #include "driver.h" | ||
18 | |||
19 | /* | ||
20 | * When the TonePort is used with jack in full duplex mode and the outputs are | ||
21 | * not connected, the software monitor produces an ugly noise since everything | ||
22 | * written to the output buffer (i.e., the input signal) will be repeated in | ||
23 | * the next period (sounds like a delay effect). As a workaround, the output | ||
24 | * buffer is cleared after the data have been read, but there must be a better | ||
25 | * solution. Until one is found, this workaround can be used to fix the | ||
26 | * problem. | ||
27 | */ | ||
28 | #define USE_CLEAR_BUFFER_WORKAROUND 1 | ||
29 | |||
30 | extern struct snd_pcm_ops snd_line6_playback_ops; | ||
31 | |||
32 | extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm); | ||
33 | extern void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm); | ||
34 | extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm); | ||
35 | extern void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm); | ||
36 | extern void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm | ||
37 | *line6pcm); | ||
38 | extern void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm); | ||
39 | extern int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd); | ||
40 | |||
41 | #endif | ||
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c new file mode 100644 index 000000000000..bf027fc70cba --- /dev/null +++ b/sound/usb/line6/pod.c | |||
@@ -0,0 +1,631 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/slab.h> | ||
13 | #include <linux/wait.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/usb.h> | ||
17 | |||
18 | #include <sound/core.h> | ||
19 | #include <sound/control.h> | ||
20 | |||
21 | #include "capture.h" | ||
22 | #include "driver.h" | ||
23 | #include "playback.h" | ||
24 | #include "usbdefs.h" | ||
25 | |||
26 | /* | ||
27 | Locate name in binary program dump | ||
28 | */ | ||
29 | #define POD_NAME_OFFSET 0 | ||
30 | #define POD_NAME_LENGTH 16 | ||
31 | |||
32 | /* | ||
33 | Other constants | ||
34 | */ | ||
35 | #define POD_CONTROL_SIZE 0x80 | ||
36 | #define POD_BUFSIZE_DUMPREQ 7 | ||
37 | #define POD_STARTUP_DELAY 1000 | ||
38 | |||
39 | /* | ||
40 | Stages of POD startup procedure | ||
41 | */ | ||
42 | enum { | ||
43 | POD_STARTUP_INIT = 1, | ||
44 | POD_STARTUP_VERSIONREQ, | ||
45 | POD_STARTUP_WORKQUEUE, | ||
46 | POD_STARTUP_SETUP, | ||
47 | POD_STARTUP_LAST = POD_STARTUP_SETUP - 1 | ||
48 | }; | ||
49 | |||
50 | enum { | ||
51 | LINE6_BASSPODXT, | ||
52 | LINE6_BASSPODXTLIVE, | ||
53 | LINE6_BASSPODXTPRO, | ||
54 | LINE6_POCKETPOD, | ||
55 | LINE6_PODXT, | ||
56 | LINE6_PODXTLIVE_POD, | ||
57 | LINE6_PODXTPRO, | ||
58 | }; | ||
59 | |||
60 | struct usb_line6_pod { | ||
61 | /** | ||
62 | Generic Line 6 USB data. | ||
63 | */ | ||
64 | struct usb_line6 line6; | ||
65 | |||
66 | /** | ||
67 | Instrument monitor level. | ||
68 | */ | ||
69 | int monitor_level; | ||
70 | |||
71 | /** | ||
72 | Timer for device initializaton. | ||
73 | */ | ||
74 | struct timer_list startup_timer; | ||
75 | |||
76 | /** | ||
77 | Work handler for device initializaton. | ||
78 | */ | ||
79 | struct work_struct startup_work; | ||
80 | |||
81 | /** | ||
82 | Current progress in startup procedure. | ||
83 | */ | ||
84 | int startup_progress; | ||
85 | |||
86 | /** | ||
87 | Serial number of device. | ||
88 | */ | ||
89 | int serial_number; | ||
90 | |||
91 | /** | ||
92 | Firmware version (x 100). | ||
93 | */ | ||
94 | int firmware_version; | ||
95 | |||
96 | /** | ||
97 | Device ID. | ||
98 | */ | ||
99 | int device_id; | ||
100 | }; | ||
101 | |||
102 | #define POD_SYSEX_CODE 3 | ||
103 | #define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */ | ||
104 | |||
105 | /* *INDENT-OFF* */ | ||
106 | |||
107 | enum { | ||
108 | POD_SYSEX_SAVE = 0x24, | ||
109 | POD_SYSEX_SYSTEM = 0x56, | ||
110 | POD_SYSEX_SYSTEMREQ = 0x57, | ||
111 | /* POD_SYSEX_UPDATE = 0x6c, */ /* software update! */ | ||
112 | POD_SYSEX_STORE = 0x71, | ||
113 | POD_SYSEX_FINISH = 0x72, | ||
114 | POD_SYSEX_DUMPMEM = 0x73, | ||
115 | POD_SYSEX_DUMP = 0x74, | ||
116 | POD_SYSEX_DUMPREQ = 0x75 | ||
117 | |||
118 | /* dumps entire internal memory of PODxt Pro */ | ||
119 | /* POD_SYSEX_DUMPMEM2 = 0x76 */ | ||
120 | }; | ||
121 | |||
122 | enum { | ||
123 | POD_MONITOR_LEVEL = 0x04, | ||
124 | POD_SYSTEM_INVALID = 0x10000 | ||
125 | }; | ||
126 | |||
127 | /* *INDENT-ON* */ | ||
128 | |||
129 | enum { | ||
130 | POD_DUMP_MEMORY = 2 | ||
131 | }; | ||
132 | |||
133 | enum { | ||
134 | POD_BUSY_READ, | ||
135 | POD_BUSY_WRITE, | ||
136 | POD_CHANNEL_DIRTY, | ||
137 | POD_SAVE_PRESSED, | ||
138 | POD_BUSY_MIDISEND | ||
139 | }; | ||
140 | |||
141 | static struct snd_ratden pod_ratden = { | ||
142 | .num_min = 78125, | ||
143 | .num_max = 78125, | ||
144 | .num_step = 1, | ||
145 | .den = 2 | ||
146 | }; | ||
147 | |||
148 | static struct line6_pcm_properties pod_pcm_properties = { | ||
149 | .snd_line6_playback_hw = { | ||
150 | .info = (SNDRV_PCM_INFO_MMAP | | ||
151 | SNDRV_PCM_INFO_INTERLEAVED | | ||
152 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
153 | SNDRV_PCM_INFO_MMAP_VALID | | ||
154 | SNDRV_PCM_INFO_PAUSE | | ||
155 | SNDRV_PCM_INFO_SYNC_START), | ||
156 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | ||
157 | .rates = SNDRV_PCM_RATE_KNOT, | ||
158 | .rate_min = 39062, | ||
159 | .rate_max = 39063, | ||
160 | .channels_min = 2, | ||
161 | .channels_max = 2, | ||
162 | .buffer_bytes_max = 60000, | ||
163 | .period_bytes_min = 64, | ||
164 | .period_bytes_max = 8192, | ||
165 | .periods_min = 1, | ||
166 | .periods_max = 1024}, | ||
167 | .snd_line6_capture_hw = { | ||
168 | .info = (SNDRV_PCM_INFO_MMAP | | ||
169 | SNDRV_PCM_INFO_INTERLEAVED | | ||
170 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
171 | SNDRV_PCM_INFO_MMAP_VALID | | ||
172 | SNDRV_PCM_INFO_SYNC_START), | ||
173 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | ||
174 | .rates = SNDRV_PCM_RATE_KNOT, | ||
175 | .rate_min = 39062, | ||
176 | .rate_max = 39063, | ||
177 | .channels_min = 2, | ||
178 | .channels_max = 2, | ||
179 | .buffer_bytes_max = 60000, | ||
180 | .period_bytes_min = 64, | ||
181 | .period_bytes_max = 8192, | ||
182 | .periods_min = 1, | ||
183 | .periods_max = 1024}, | ||
184 | .snd_line6_rates = { | ||
185 | .nrats = 1, | ||
186 | .rats = &pod_ratden}, | ||
187 | .bytes_per_frame = POD_BYTES_PER_FRAME | ||
188 | }; | ||
189 | |||
190 | static const char pod_version_header[] = { | ||
191 | 0xf2, 0x7e, 0x7f, 0x06, 0x02 | ||
192 | }; | ||
193 | |||
194 | /* forward declarations: */ | ||
195 | static void pod_startup2(unsigned long data); | ||
196 | static void pod_startup3(struct usb_line6_pod *pod); | ||
197 | |||
198 | static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, | ||
199 | int size) | ||
200 | { | ||
201 | return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code, | ||
202 | size); | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | Process a completely received message. | ||
207 | */ | ||
208 | static void line6_pod_process_message(struct usb_line6 *line6) | ||
209 | { | ||
210 | struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; | ||
211 | const unsigned char *buf = pod->line6.buffer_message; | ||
212 | |||
213 | if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) { | ||
214 | pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15]; | ||
215 | pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | | ||
216 | (int) buf[10]; | ||
217 | pod_startup3(pod); | ||
218 | return; | ||
219 | } | ||
220 | |||
221 | /* Only look for sysex messages from this device */ | ||
222 | if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) && | ||
223 | buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) { | ||
224 | return; | ||
225 | } | ||
226 | if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0) | ||
227 | return; | ||
228 | |||
229 | if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) { | ||
230 | short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) | | ||
231 | ((int)buf[9] << 4) | (int)buf[10]; | ||
232 | pod->monitor_level = value; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | /* | ||
237 | Send system parameter (from integer). | ||
238 | */ | ||
239 | static int pod_set_system_param_int(struct usb_line6_pod *pod, int value, | ||
240 | int code) | ||
241 | { | ||
242 | char *sysex; | ||
243 | static const int size = 5; | ||
244 | |||
245 | sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size); | ||
246 | if (!sysex) | ||
247 | return -ENOMEM; | ||
248 | sysex[SYSEX_DATA_OFS] = code; | ||
249 | sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f; | ||
250 | sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f; | ||
251 | sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f; | ||
252 | sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f; | ||
253 | line6_send_sysex_message(&pod->line6, sysex, size); | ||
254 | kfree(sysex); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | "read" request on "serial_number" special file. | ||
260 | */ | ||
261 | static ssize_t serial_number_show(struct device *dev, | ||
262 | struct device_attribute *attr, char *buf) | ||
263 | { | ||
264 | struct usb_interface *interface = to_usb_interface(dev); | ||
265 | struct usb_line6_pod *pod = usb_get_intfdata(interface); | ||
266 | |||
267 | return sprintf(buf, "%d\n", pod->serial_number); | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | "read" request on "firmware_version" special file. | ||
272 | */ | ||
273 | static ssize_t firmware_version_show(struct device *dev, | ||
274 | struct device_attribute *attr, char *buf) | ||
275 | { | ||
276 | struct usb_interface *interface = to_usb_interface(dev); | ||
277 | struct usb_line6_pod *pod = usb_get_intfdata(interface); | ||
278 | |||
279 | return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100, | ||
280 | pod->firmware_version % 100); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | "read" request on "device_id" special file. | ||
285 | */ | ||
286 | static ssize_t device_id_show(struct device *dev, | ||
287 | struct device_attribute *attr, char *buf) | ||
288 | { | ||
289 | struct usb_interface *interface = to_usb_interface(dev); | ||
290 | struct usb_line6_pod *pod = usb_get_intfdata(interface); | ||
291 | |||
292 | return sprintf(buf, "%d\n", pod->device_id); | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | POD startup procedure. | ||
297 | This is a sequence of functions with special requirements (e.g., must | ||
298 | not run immediately after initialization, must not run in interrupt | ||
299 | context). After the last one has finished, the device is ready to use. | ||
300 | */ | ||
301 | |||
302 | static void pod_startup1(struct usb_line6_pod *pod) | ||
303 | { | ||
304 | CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT); | ||
305 | |||
306 | /* delay startup procedure: */ | ||
307 | line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2, | ||
308 | (unsigned long)pod); | ||
309 | } | ||
310 | |||
311 | static void pod_startup2(unsigned long data) | ||
312 | { | ||
313 | struct usb_line6_pod *pod = (struct usb_line6_pod *)data; | ||
314 | struct usb_line6 *line6 = &pod->line6; | ||
315 | |||
316 | CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ); | ||
317 | |||
318 | /* request firmware version: */ | ||
319 | line6_version_request_async(line6); | ||
320 | } | ||
321 | |||
322 | static void pod_startup3(struct usb_line6_pod *pod) | ||
323 | { | ||
324 | CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE); | ||
325 | |||
326 | /* schedule work for global work queue: */ | ||
327 | schedule_work(&pod->startup_work); | ||
328 | } | ||
329 | |||
330 | static void pod_startup4(struct work_struct *work) | ||
331 | { | ||
332 | struct usb_line6_pod *pod = | ||
333 | container_of(work, struct usb_line6_pod, startup_work); | ||
334 | struct usb_line6 *line6 = &pod->line6; | ||
335 | |||
336 | CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP); | ||
337 | |||
338 | /* serial number: */ | ||
339 | line6_read_serial_number(&pod->line6, &pod->serial_number); | ||
340 | |||
341 | /* ALSA audio interface: */ | ||
342 | snd_card_register(line6->card); | ||
343 | } | ||
344 | |||
345 | /* POD special files: */ | ||
346 | static DEVICE_ATTR_RO(device_id); | ||
347 | static DEVICE_ATTR_RO(firmware_version); | ||
348 | static DEVICE_ATTR_RO(serial_number); | ||
349 | |||
350 | /* control info callback */ | ||
351 | static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol, | ||
352 | struct snd_ctl_elem_info *uinfo) | ||
353 | { | ||
354 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
355 | uinfo->count = 1; | ||
356 | uinfo->value.integer.min = 0; | ||
357 | uinfo->value.integer.max = 65535; | ||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | /* control get callback */ | ||
362 | static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol, | ||
363 | struct snd_ctl_elem_value *ucontrol) | ||
364 | { | ||
365 | struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); | ||
366 | struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6; | ||
367 | |||
368 | ucontrol->value.integer.value[0] = pod->monitor_level; | ||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | /* control put callback */ | ||
373 | static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol, | ||
374 | struct snd_ctl_elem_value *ucontrol) | ||
375 | { | ||
376 | struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); | ||
377 | struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6; | ||
378 | |||
379 | if (ucontrol->value.integer.value[0] == pod->monitor_level) | ||
380 | return 0; | ||
381 | |||
382 | pod->monitor_level = ucontrol->value.integer.value[0]; | ||
383 | pod_set_system_param_int(pod, ucontrol->value.integer.value[0], | ||
384 | POD_MONITOR_LEVEL); | ||
385 | return 1; | ||
386 | } | ||
387 | |||
388 | /* control definition */ | ||
389 | static struct snd_kcontrol_new pod_control_monitor = { | ||
390 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
391 | .name = "Monitor Playback Volume", | ||
392 | .index = 0, | ||
393 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
394 | .info = snd_pod_control_monitor_info, | ||
395 | .get = snd_pod_control_monitor_get, | ||
396 | .put = snd_pod_control_monitor_put | ||
397 | }; | ||
398 | |||
399 | /* | ||
400 | POD device disconnected. | ||
401 | */ | ||
402 | static void line6_pod_disconnect(struct usb_interface *interface) | ||
403 | { | ||
404 | struct usb_line6_pod *pod; | ||
405 | |||
406 | if (interface == NULL) | ||
407 | return; | ||
408 | pod = usb_get_intfdata(interface); | ||
409 | |||
410 | if (pod != NULL) { | ||
411 | struct device *dev = &interface->dev; | ||
412 | |||
413 | if (dev != NULL) { | ||
414 | /* remove sysfs entries: */ | ||
415 | device_remove_file(dev, &dev_attr_device_id); | ||
416 | device_remove_file(dev, &dev_attr_firmware_version); | ||
417 | device_remove_file(dev, &dev_attr_serial_number); | ||
418 | } | ||
419 | |||
420 | del_timer_sync(&pod->startup_timer); | ||
421 | cancel_work_sync(&pod->startup_work); | ||
422 | } | ||
423 | } | ||
424 | |||
425 | /* | ||
426 | Create sysfs entries. | ||
427 | */ | ||
428 | static int pod_create_files2(struct device *dev) | ||
429 | { | ||
430 | int err; | ||
431 | |||
432 | err = device_create_file(dev, &dev_attr_device_id); | ||
433 | if (err < 0) | ||
434 | return err; | ||
435 | err = device_create_file(dev, &dev_attr_firmware_version); | ||
436 | if (err < 0) | ||
437 | return err; | ||
438 | err = device_create_file(dev, &dev_attr_serial_number); | ||
439 | if (err < 0) | ||
440 | return err; | ||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | /* | ||
445 | Try to init POD device. | ||
446 | */ | ||
447 | static int pod_init(struct usb_interface *interface, | ||
448 | struct usb_line6 *line6) | ||
449 | { | ||
450 | int err; | ||
451 | struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; | ||
452 | |||
453 | line6->process_message = line6_pod_process_message; | ||
454 | line6->disconnect = line6_pod_disconnect; | ||
455 | |||
456 | init_timer(&pod->startup_timer); | ||
457 | INIT_WORK(&pod->startup_work, pod_startup4); | ||
458 | |||
459 | if ((interface == NULL) || (pod == NULL)) | ||
460 | return -ENODEV; | ||
461 | |||
462 | /* create sysfs entries: */ | ||
463 | err = pod_create_files2(&interface->dev); | ||
464 | if (err < 0) | ||
465 | return err; | ||
466 | |||
467 | /* initialize MIDI subsystem: */ | ||
468 | err = line6_init_midi(line6); | ||
469 | if (err < 0) | ||
470 | return err; | ||
471 | |||
472 | /* initialize PCM subsystem: */ | ||
473 | err = line6_init_pcm(line6, &pod_pcm_properties); | ||
474 | if (err < 0) | ||
475 | return err; | ||
476 | |||
477 | /* register monitor control: */ | ||
478 | err = snd_ctl_add(line6->card, | ||
479 | snd_ctl_new1(&pod_control_monitor, line6->line6pcm)); | ||
480 | if (err < 0) | ||
481 | return err; | ||
482 | |||
483 | /* | ||
484 | When the sound card is registered at this point, the PODxt Live | ||
485 | displays "Invalid Code Error 07", so we do it later in the event | ||
486 | handler. | ||
487 | */ | ||
488 | |||
489 | if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { | ||
490 | pod->monitor_level = POD_SYSTEM_INVALID; | ||
491 | |||
492 | /* initiate startup procedure: */ | ||
493 | pod_startup1(pod); | ||
494 | } | ||
495 | |||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) | ||
500 | #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) | ||
501 | |||
502 | /* table of devices that work with this driver */ | ||
503 | static const struct usb_device_id pod_id_table[] = { | ||
504 | { LINE6_DEVICE(0x4250), .driver_info = LINE6_BASSPODXT }, | ||
505 | { LINE6_DEVICE(0x4642), .driver_info = LINE6_BASSPODXTLIVE }, | ||
506 | { LINE6_DEVICE(0x4252), .driver_info = LINE6_BASSPODXTPRO }, | ||
507 | { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD }, | ||
508 | { LINE6_DEVICE(0x5044), .driver_info = LINE6_PODXT }, | ||
509 | { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD }, | ||
510 | { LINE6_DEVICE(0x5050), .driver_info = LINE6_PODXTPRO }, | ||
511 | {} | ||
512 | }; | ||
513 | |||
514 | MODULE_DEVICE_TABLE(usb, pod_id_table); | ||
515 | |||
516 | static const struct line6_properties pod_properties_table[] = { | ||
517 | [LINE6_BASSPODXT] = { | ||
518 | .id = "BassPODxt", | ||
519 | .name = "BassPODxt", | ||
520 | .capabilities = LINE6_CAP_CONTROL | ||
521 | | LINE6_CAP_PCM | ||
522 | | LINE6_CAP_HWMON, | ||
523 | .altsetting = 5, | ||
524 | .ep_ctrl_r = 0x84, | ||
525 | .ep_ctrl_w = 0x03, | ||
526 | .ep_audio_r = 0x82, | ||
527 | .ep_audio_w = 0x01, | ||
528 | }, | ||
529 | [LINE6_BASSPODXTLIVE] = { | ||
530 | .id = "BassPODxtLive", | ||
531 | .name = "BassPODxt Live", | ||
532 | .capabilities = LINE6_CAP_CONTROL | ||
533 | | LINE6_CAP_PCM | ||
534 | | LINE6_CAP_HWMON, | ||
535 | .altsetting = 1, | ||
536 | .ep_ctrl_r = 0x84, | ||
537 | .ep_ctrl_w = 0x03, | ||
538 | .ep_audio_r = 0x82, | ||
539 | .ep_audio_w = 0x01, | ||
540 | }, | ||
541 | [LINE6_BASSPODXTPRO] = { | ||
542 | .id = "BassPODxtPro", | ||
543 | .name = "BassPODxt Pro", | ||
544 | .capabilities = LINE6_CAP_CONTROL | ||
545 | | LINE6_CAP_PCM | ||
546 | | LINE6_CAP_HWMON, | ||
547 | .altsetting = 5, | ||
548 | .ep_ctrl_r = 0x84, | ||
549 | .ep_ctrl_w = 0x03, | ||
550 | .ep_audio_r = 0x82, | ||
551 | .ep_audio_w = 0x01, | ||
552 | }, | ||
553 | [LINE6_POCKETPOD] = { | ||
554 | .id = "PocketPOD", | ||
555 | .name = "Pocket POD", | ||
556 | .capabilities = LINE6_CAP_CONTROL, | ||
557 | .altsetting = 0, | ||
558 | .ep_ctrl_r = 0x82, | ||
559 | .ep_ctrl_w = 0x02, | ||
560 | /* no audio channel */ | ||
561 | }, | ||
562 | [LINE6_PODXT] = { | ||
563 | .id = "PODxt", | ||
564 | .name = "PODxt", | ||
565 | .capabilities = LINE6_CAP_CONTROL | ||
566 | | LINE6_CAP_PCM | ||
567 | | LINE6_CAP_HWMON, | ||
568 | .altsetting = 5, | ||
569 | .ep_ctrl_r = 0x84, | ||
570 | .ep_ctrl_w = 0x03, | ||
571 | .ep_audio_r = 0x82, | ||
572 | .ep_audio_w = 0x01, | ||
573 | }, | ||
574 | [LINE6_PODXTLIVE_POD] = { | ||
575 | .id = "PODxtLive", | ||
576 | .name = "PODxt Live", | ||
577 | .capabilities = LINE6_CAP_CONTROL | ||
578 | | LINE6_CAP_PCM | ||
579 | | LINE6_CAP_HWMON, | ||
580 | .altsetting = 1, | ||
581 | .ep_ctrl_r = 0x84, | ||
582 | .ep_ctrl_w = 0x03, | ||
583 | .ep_audio_r = 0x82, | ||
584 | .ep_audio_w = 0x01, | ||
585 | }, | ||
586 | [LINE6_PODXTPRO] = { | ||
587 | .id = "PODxtPro", | ||
588 | .name = "PODxt Pro", | ||
589 | .capabilities = LINE6_CAP_CONTROL | ||
590 | | LINE6_CAP_PCM | ||
591 | | LINE6_CAP_HWMON, | ||
592 | .altsetting = 5, | ||
593 | .ep_ctrl_r = 0x84, | ||
594 | .ep_ctrl_w = 0x03, | ||
595 | .ep_audio_r = 0x82, | ||
596 | .ep_audio_w = 0x01, | ||
597 | }, | ||
598 | }; | ||
599 | |||
600 | /* | ||
601 | Probe USB device. | ||
602 | */ | ||
603 | static int pod_probe(struct usb_interface *interface, | ||
604 | const struct usb_device_id *id) | ||
605 | { | ||
606 | struct usb_line6_pod *pod; | ||
607 | |||
608 | pod = kzalloc(sizeof(*pod), GFP_KERNEL); | ||
609 | if (!pod) | ||
610 | return -ENODEV; | ||
611 | return line6_probe(interface, &pod->line6, | ||
612 | &pod_properties_table[id->driver_info], | ||
613 | pod_init); | ||
614 | } | ||
615 | |||
616 | static struct usb_driver pod_driver = { | ||
617 | .name = KBUILD_MODNAME, | ||
618 | .probe = pod_probe, | ||
619 | .disconnect = line6_disconnect, | ||
620 | #ifdef CONFIG_PM | ||
621 | .suspend = line6_suspend, | ||
622 | .resume = line6_resume, | ||
623 | .reset_resume = line6_resume, | ||
624 | #endif | ||
625 | .id_table = pod_id_table, | ||
626 | }; | ||
627 | |||
628 | module_usb_driver(pod_driver); | ||
629 | |||
630 | MODULE_DESCRIPTION("Line 6 POD USB driver"); | ||
631 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c new file mode 100644 index 000000000000..7217fa7e5db1 --- /dev/null +++ b/sound/usb/line6/podhd.c | |||
@@ -0,0 +1,209 @@ | |||
1 | /* | ||
2 | * Line 6 Pod HD | ||
3 | * | ||
4 | * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/usb.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <sound/core.h> | ||
16 | #include <sound/pcm.h> | ||
17 | |||
18 | #include "driver.h" | ||
19 | #include "pcm.h" | ||
20 | #include "usbdefs.h" | ||
21 | |||
22 | enum { | ||
23 | LINE6_PODHD300, | ||
24 | LINE6_PODHD400, | ||
25 | LINE6_PODHD500_0, | ||
26 | LINE6_PODHD500_1, | ||
27 | }; | ||
28 | |||
29 | struct usb_line6_podhd { | ||
30 | /** | ||
31 | Generic Line 6 USB data. | ||
32 | */ | ||
33 | struct usb_line6 line6; | ||
34 | }; | ||
35 | |||
36 | #define PODHD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */ | ||
37 | |||
38 | static struct snd_ratden podhd_ratden = { | ||
39 | .num_min = 48000, | ||
40 | .num_max = 48000, | ||
41 | .num_step = 1, | ||
42 | .den = 1, | ||
43 | }; | ||
44 | |||
45 | static struct line6_pcm_properties podhd_pcm_properties = { | ||
46 | .snd_line6_playback_hw = { | ||
47 | .info = (SNDRV_PCM_INFO_MMAP | | ||
48 | SNDRV_PCM_INFO_INTERLEAVED | | ||
49 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
50 | SNDRV_PCM_INFO_MMAP_VALID | | ||
51 | SNDRV_PCM_INFO_PAUSE | | ||
52 | SNDRV_PCM_INFO_SYNC_START), | ||
53 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | ||
54 | .rates = SNDRV_PCM_RATE_48000, | ||
55 | .rate_min = 48000, | ||
56 | .rate_max = 48000, | ||
57 | .channels_min = 2, | ||
58 | .channels_max = 2, | ||
59 | .buffer_bytes_max = 60000, | ||
60 | .period_bytes_min = 64, | ||
61 | .period_bytes_max = 8192, | ||
62 | .periods_min = 1, | ||
63 | .periods_max = 1024}, | ||
64 | .snd_line6_capture_hw = { | ||
65 | .info = (SNDRV_PCM_INFO_MMAP | | ||
66 | SNDRV_PCM_INFO_INTERLEAVED | | ||
67 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
68 | SNDRV_PCM_INFO_MMAP_VALID | | ||
69 | SNDRV_PCM_INFO_SYNC_START), | ||
70 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | ||
71 | .rates = SNDRV_PCM_RATE_48000, | ||
72 | .rate_min = 48000, | ||
73 | .rate_max = 48000, | ||
74 | .channels_min = 2, | ||
75 | .channels_max = 2, | ||
76 | .buffer_bytes_max = 60000, | ||
77 | .period_bytes_min = 64, | ||
78 | .period_bytes_max = 8192, | ||
79 | .periods_min = 1, | ||
80 | .periods_max = 1024}, | ||
81 | .snd_line6_rates = { | ||
82 | .nrats = 1, | ||
83 | .rats = &podhd_ratden}, | ||
84 | .bytes_per_frame = PODHD_BYTES_PER_FRAME | ||
85 | }; | ||
86 | |||
87 | /* | ||
88 | Try to init POD HD device. | ||
89 | */ | ||
90 | static int podhd_init(struct usb_interface *interface, | ||
91 | struct usb_line6 *line6) | ||
92 | { | ||
93 | struct usb_line6_podhd *podhd = (struct usb_line6_podhd *) line6; | ||
94 | int err; | ||
95 | |||
96 | if ((interface == NULL) || (podhd == NULL)) | ||
97 | return -ENODEV; | ||
98 | |||
99 | /* initialize MIDI subsystem: */ | ||
100 | err = line6_init_midi(line6); | ||
101 | if (err < 0) | ||
102 | return err; | ||
103 | |||
104 | /* initialize PCM subsystem: */ | ||
105 | err = line6_init_pcm(line6, &podhd_pcm_properties); | ||
106 | if (err < 0) | ||
107 | return err; | ||
108 | |||
109 | /* register USB audio system: */ | ||
110 | return snd_card_register(line6->card); | ||
111 | } | ||
112 | |||
113 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) | ||
114 | #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) | ||
115 | |||
116 | /* table of devices that work with this driver */ | ||
117 | static const struct usb_device_id podhd_id_table[] = { | ||
118 | { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, | ||
119 | { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, | ||
120 | { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, | ||
121 | { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, | ||
122 | {} | ||
123 | }; | ||
124 | |||
125 | MODULE_DEVICE_TABLE(usb, podhd_id_table); | ||
126 | |||
127 | static const struct line6_properties podhd_properties_table[] = { | ||
128 | [LINE6_PODHD300] = { | ||
129 | .id = "PODHD300", | ||
130 | .name = "POD HD300", | ||
131 | .capabilities = LINE6_CAP_CONTROL | ||
132 | | LINE6_CAP_PCM | ||
133 | | LINE6_CAP_HWMON, | ||
134 | .altsetting = 5, | ||
135 | .ep_ctrl_r = 0x84, | ||
136 | .ep_ctrl_w = 0x03, | ||
137 | .ep_audio_r = 0x82, | ||
138 | .ep_audio_w = 0x01, | ||
139 | }, | ||
140 | [LINE6_PODHD400] = { | ||
141 | .id = "PODHD400", | ||
142 | .name = "POD HD400", | ||
143 | .capabilities = LINE6_CAP_CONTROL | ||
144 | | LINE6_CAP_PCM | ||
145 | | LINE6_CAP_HWMON, | ||
146 | .altsetting = 5, | ||
147 | .ep_ctrl_r = 0x84, | ||
148 | .ep_ctrl_w = 0x03, | ||
149 | .ep_audio_r = 0x82, | ||
150 | .ep_audio_w = 0x01, | ||
151 | }, | ||
152 | [LINE6_PODHD500_0] = { | ||
153 | .id = "PODHD500", | ||
154 | .name = "POD HD500", | ||
155 | .capabilities = LINE6_CAP_CONTROL | ||
156 | | LINE6_CAP_PCM | ||
157 | | LINE6_CAP_HWMON, | ||
158 | .altsetting = 1, | ||
159 | .ep_ctrl_r = 0x81, | ||
160 | .ep_ctrl_w = 0x01, | ||
161 | .ep_audio_r = 0x86, | ||
162 | .ep_audio_w = 0x02, | ||
163 | }, | ||
164 | [LINE6_PODHD500_1] = { | ||
165 | .id = "PODHD500", | ||
166 | .name = "POD HD500", | ||
167 | .capabilities = LINE6_CAP_CONTROL | ||
168 | | LINE6_CAP_PCM | ||
169 | | LINE6_CAP_HWMON, | ||
170 | .altsetting = 1, | ||
171 | .ep_ctrl_r = 0x81, | ||
172 | .ep_ctrl_w = 0x01, | ||
173 | .ep_audio_r = 0x86, | ||
174 | .ep_audio_w = 0x02, | ||
175 | }, | ||
176 | }; | ||
177 | |||
178 | /* | ||
179 | Probe USB device. | ||
180 | */ | ||
181 | static int podhd_probe(struct usb_interface *interface, | ||
182 | const struct usb_device_id *id) | ||
183 | { | ||
184 | struct usb_line6_podhd *podhd; | ||
185 | |||
186 | podhd = kzalloc(sizeof(*podhd), GFP_KERNEL); | ||
187 | if (!podhd) | ||
188 | return -ENODEV; | ||
189 | return line6_probe(interface, &podhd->line6, | ||
190 | &podhd_properties_table[id->driver_info], | ||
191 | podhd_init); | ||
192 | } | ||
193 | |||
194 | static struct usb_driver podhd_driver = { | ||
195 | .name = KBUILD_MODNAME, | ||
196 | .probe = podhd_probe, | ||
197 | .disconnect = line6_disconnect, | ||
198 | #ifdef CONFIG_PM | ||
199 | .suspend = line6_suspend, | ||
200 | .resume = line6_resume, | ||
201 | .reset_resume = line6_resume, | ||
202 | #endif | ||
203 | .id_table = podhd_id_table, | ||
204 | }; | ||
205 | |||
206 | module_usb_driver(podhd_driver); | ||
207 | |||
208 | MODULE_DESCRIPTION("Line 6 PODHD USB driver"); | ||
209 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/usb/line6/revision.h b/sound/usb/line6/revision.h new file mode 100644 index 000000000000..b4eee2b73831 --- /dev/null +++ b/sound/usb/line6/revision.h | |||
@@ -0,0 +1,4 @@ | |||
1 | #ifndef DRIVER_REVISION | ||
2 | /* current subversion revision */ | ||
3 | #define DRIVER_REVISION " (904)" | ||
4 | #endif | ||
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c new file mode 100644 index 000000000000..c1f61cde52ab --- /dev/null +++ b/sound/usb/line6/toneport.c | |||
@@ -0,0 +1,578 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * Emil Myhrman (emil.myhrman@gmail.com) | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License as | ||
9 | * published by the Free Software Foundation, version 2. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/wait.h> | ||
14 | #include <linux/usb.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <sound/core.h> | ||
18 | #include <sound/control.h> | ||
19 | |||
20 | #include "capture.h" | ||
21 | #include "driver.h" | ||
22 | #include "playback.h" | ||
23 | #include "usbdefs.h" | ||
24 | |||
25 | enum line6_device_type { | ||
26 | LINE6_GUITARPORT, | ||
27 | LINE6_PODSTUDIO_GX, | ||
28 | LINE6_PODSTUDIO_UX1, | ||
29 | LINE6_PODSTUDIO_UX2, | ||
30 | LINE6_TONEPORT_GX, | ||
31 | LINE6_TONEPORT_UX1, | ||
32 | LINE6_TONEPORT_UX2, | ||
33 | }; | ||
34 | |||
35 | struct usb_line6_toneport { | ||
36 | /** | ||
37 | Generic Line 6 USB data. | ||
38 | */ | ||
39 | struct usb_line6 line6; | ||
40 | |||
41 | /** | ||
42 | Source selector. | ||
43 | */ | ||
44 | int source; | ||
45 | |||
46 | /** | ||
47 | Serial number of device. | ||
48 | */ | ||
49 | int serial_number; | ||
50 | |||
51 | /** | ||
52 | Firmware version (x 100). | ||
53 | */ | ||
54 | int firmware_version; | ||
55 | |||
56 | /** | ||
57 | Timer for delayed PCM startup. | ||
58 | */ | ||
59 | struct timer_list timer; | ||
60 | |||
61 | /** | ||
62 | Device type. | ||
63 | */ | ||
64 | enum line6_device_type type; | ||
65 | }; | ||
66 | |||
67 | static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2); | ||
68 | |||
69 | #define TONEPORT_PCM_DELAY 1 | ||
70 | |||
71 | static struct snd_ratden toneport_ratden = { | ||
72 | .num_min = 44100, | ||
73 | .num_max = 44100, | ||
74 | .num_step = 1, | ||
75 | .den = 1 | ||
76 | }; | ||
77 | |||
78 | static struct line6_pcm_properties toneport_pcm_properties = { | ||
79 | .snd_line6_playback_hw = { | ||
80 | .info = (SNDRV_PCM_INFO_MMAP | | ||
81 | SNDRV_PCM_INFO_INTERLEAVED | | ||
82 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
83 | SNDRV_PCM_INFO_MMAP_VALID | | ||
84 | SNDRV_PCM_INFO_PAUSE | | ||
85 | SNDRV_PCM_INFO_SYNC_START), | ||
86 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
87 | .rates = SNDRV_PCM_RATE_KNOT, | ||
88 | .rate_min = 44100, | ||
89 | .rate_max = 44100, | ||
90 | .channels_min = 2, | ||
91 | .channels_max = 2, | ||
92 | .buffer_bytes_max = 60000, | ||
93 | .period_bytes_min = 64, | ||
94 | .period_bytes_max = 8192, | ||
95 | .periods_min = 1, | ||
96 | .periods_max = 1024}, | ||
97 | .snd_line6_capture_hw = { | ||
98 | .info = (SNDRV_PCM_INFO_MMAP | | ||
99 | SNDRV_PCM_INFO_INTERLEAVED | | ||
100 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
101 | SNDRV_PCM_INFO_MMAP_VALID | | ||
102 | SNDRV_PCM_INFO_SYNC_START), | ||
103 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
104 | .rates = SNDRV_PCM_RATE_KNOT, | ||
105 | .rate_min = 44100, | ||
106 | .rate_max = 44100, | ||
107 | .channels_min = 2, | ||
108 | .channels_max = 2, | ||
109 | .buffer_bytes_max = 60000, | ||
110 | .period_bytes_min = 64, | ||
111 | .period_bytes_max = 8192, | ||
112 | .periods_min = 1, | ||
113 | .periods_max = 1024}, | ||
114 | .snd_line6_rates = { | ||
115 | .nrats = 1, | ||
116 | .rats = &toneport_ratden}, | ||
117 | .bytes_per_frame = 4 | ||
118 | }; | ||
119 | |||
120 | /* | ||
121 | For the led on Guitarport. | ||
122 | Brightness goes from 0x00 to 0x26. Set a value above this to have led | ||
123 | blink. | ||
124 | (void cmd_0x02(byte red, byte green) | ||
125 | */ | ||
126 | static int led_red = 0x00; | ||
127 | static int led_green = 0x26; | ||
128 | |||
129 | static const struct { | ||
130 | const char *name; | ||
131 | int code; | ||
132 | } toneport_source_info[] = { | ||
133 | {"Microphone", 0x0a01}, | ||
134 | {"Line", 0x0801}, | ||
135 | {"Instrument", 0x0b01}, | ||
136 | {"Inst & Mic", 0x0901} | ||
137 | }; | ||
138 | |||
139 | static bool toneport_has_led(enum line6_device_type type) | ||
140 | { | ||
141 | return | ||
142 | (type == LINE6_GUITARPORT) || | ||
143 | (type == LINE6_TONEPORT_GX); | ||
144 | /* add your device here if you are missing support for the LEDs */ | ||
145 | } | ||
146 | |||
147 | static void toneport_update_led(struct device *dev) | ||
148 | { | ||
149 | struct usb_interface *interface = to_usb_interface(dev); | ||
150 | struct usb_line6_toneport *tp = usb_get_intfdata(interface); | ||
151 | struct usb_line6 *line6; | ||
152 | |||
153 | if (!tp) | ||
154 | return; | ||
155 | |||
156 | line6 = &tp->line6; | ||
157 | if (line6) | ||
158 | toneport_send_cmd(line6->usbdev, (led_red << 8) | 0x0002, | ||
159 | led_green); | ||
160 | } | ||
161 | |||
162 | static ssize_t toneport_set_led_red(struct device *dev, | ||
163 | struct device_attribute *attr, | ||
164 | const char *buf, size_t count) | ||
165 | { | ||
166 | int retval; | ||
167 | |||
168 | retval = kstrtoint(buf, 10, &led_red); | ||
169 | if (retval) | ||
170 | return retval; | ||
171 | |||
172 | toneport_update_led(dev); | ||
173 | return count; | ||
174 | } | ||
175 | |||
176 | static ssize_t toneport_set_led_green(struct device *dev, | ||
177 | struct device_attribute *attr, | ||
178 | const char *buf, size_t count) | ||
179 | { | ||
180 | int retval; | ||
181 | |||
182 | retval = kstrtoint(buf, 10, &led_green); | ||
183 | if (retval) | ||
184 | return retval; | ||
185 | |||
186 | toneport_update_led(dev); | ||
187 | return count; | ||
188 | } | ||
189 | |||
190 | static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read, | ||
191 | toneport_set_led_red); | ||
192 | static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read, | ||
193 | toneport_set_led_green); | ||
194 | |||
195 | static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2) | ||
196 | { | ||
197 | int ret; | ||
198 | |||
199 | ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, | ||
200 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
201 | cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ); | ||
202 | |||
203 | if (ret < 0) { | ||
204 | dev_err(&usbdev->dev, "send failed (error %d)\n", ret); | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | /* monitor info callback */ | ||
212 | static int snd_toneport_monitor_info(struct snd_kcontrol *kcontrol, | ||
213 | struct snd_ctl_elem_info *uinfo) | ||
214 | { | ||
215 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
216 | uinfo->count = 1; | ||
217 | uinfo->value.integer.min = 0; | ||
218 | uinfo->value.integer.max = 256; | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | /* monitor get callback */ | ||
223 | static int snd_toneport_monitor_get(struct snd_kcontrol *kcontrol, | ||
224 | struct snd_ctl_elem_value *ucontrol) | ||
225 | { | ||
226 | struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); | ||
227 | |||
228 | ucontrol->value.integer.value[0] = line6pcm->volume_monitor; | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | /* monitor put callback */ | ||
233 | static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol, | ||
234 | struct snd_ctl_elem_value *ucontrol) | ||
235 | { | ||
236 | struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); | ||
237 | |||
238 | if (ucontrol->value.integer.value[0] == line6pcm->volume_monitor) | ||
239 | return 0; | ||
240 | |||
241 | line6pcm->volume_monitor = ucontrol->value.integer.value[0]; | ||
242 | |||
243 | if (line6pcm->volume_monitor > 0) | ||
244 | line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_MONITOR); | ||
245 | else | ||
246 | line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR); | ||
247 | |||
248 | return 1; | ||
249 | } | ||
250 | |||
251 | /* source info callback */ | ||
252 | static int snd_toneport_source_info(struct snd_kcontrol *kcontrol, | ||
253 | struct snd_ctl_elem_info *uinfo) | ||
254 | { | ||
255 | const int size = ARRAY_SIZE(toneport_source_info); | ||
256 | |||
257 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
258 | uinfo->count = 1; | ||
259 | uinfo->value.enumerated.items = size; | ||
260 | |||
261 | if (uinfo->value.enumerated.item >= size) | ||
262 | uinfo->value.enumerated.item = size - 1; | ||
263 | |||
264 | strcpy(uinfo->value.enumerated.name, | ||
265 | toneport_source_info[uinfo->value.enumerated.item].name); | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | /* source get callback */ | ||
271 | static int snd_toneport_source_get(struct snd_kcontrol *kcontrol, | ||
272 | struct snd_ctl_elem_value *ucontrol) | ||
273 | { | ||
274 | struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); | ||
275 | struct usb_line6_toneport *toneport = | ||
276 | (struct usb_line6_toneport *)line6pcm->line6; | ||
277 | ucontrol->value.enumerated.item[0] = toneport->source; | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | /* source put callback */ | ||
282 | static int snd_toneport_source_put(struct snd_kcontrol *kcontrol, | ||
283 | struct snd_ctl_elem_value *ucontrol) | ||
284 | { | ||
285 | struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); | ||
286 | struct usb_line6_toneport *toneport = | ||
287 | (struct usb_line6_toneport *)line6pcm->line6; | ||
288 | unsigned int source; | ||
289 | |||
290 | source = ucontrol->value.enumerated.item[0]; | ||
291 | if (source >= ARRAY_SIZE(toneport_source_info)) | ||
292 | return -EINVAL; | ||
293 | if (source == toneport->source) | ||
294 | return 0; | ||
295 | |||
296 | toneport->source = source; | ||
297 | toneport_send_cmd(toneport->line6.usbdev, | ||
298 | toneport_source_info[source].code, 0x0000); | ||
299 | return 1; | ||
300 | } | ||
301 | |||
302 | static void toneport_start_pcm(unsigned long arg) | ||
303 | { | ||
304 | struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg; | ||
305 | struct usb_line6 *line6 = &toneport->line6; | ||
306 | |||
307 | line6_pcm_acquire(line6->line6pcm, LINE6_BITS_PCM_MONITOR); | ||
308 | } | ||
309 | |||
310 | /* control definition */ | ||
311 | static struct snd_kcontrol_new toneport_control_monitor = { | ||
312 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
313 | .name = "Monitor Playback Volume", | ||
314 | .index = 0, | ||
315 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
316 | .info = snd_toneport_monitor_info, | ||
317 | .get = snd_toneport_monitor_get, | ||
318 | .put = snd_toneport_monitor_put | ||
319 | }; | ||
320 | |||
321 | /* source selector definition */ | ||
322 | static struct snd_kcontrol_new toneport_control_source = { | ||
323 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
324 | .name = "PCM Capture Source", | ||
325 | .index = 0, | ||
326 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
327 | .info = snd_toneport_source_info, | ||
328 | .get = snd_toneport_source_get, | ||
329 | .put = snd_toneport_source_put | ||
330 | }; | ||
331 | |||
332 | /* | ||
333 | Setup Toneport device. | ||
334 | */ | ||
335 | static void toneport_setup(struct usb_line6_toneport *toneport) | ||
336 | { | ||
337 | int ticks; | ||
338 | struct usb_line6 *line6 = &toneport->line6; | ||
339 | struct usb_device *usbdev = line6->usbdev; | ||
340 | |||
341 | /* sync time on device with host: */ | ||
342 | ticks = (int)get_seconds(); | ||
343 | line6_write_data(line6, 0x80c6, &ticks, 4); | ||
344 | |||
345 | /* enable device: */ | ||
346 | toneport_send_cmd(usbdev, 0x0301, 0x0000); | ||
347 | |||
348 | /* initialize source select: */ | ||
349 | switch (toneport->type) { | ||
350 | case LINE6_TONEPORT_UX1: | ||
351 | case LINE6_TONEPORT_UX2: | ||
352 | case LINE6_PODSTUDIO_UX1: | ||
353 | case LINE6_PODSTUDIO_UX2: | ||
354 | toneport_send_cmd(usbdev, | ||
355 | toneport_source_info[toneport->source].code, | ||
356 | 0x0000); | ||
357 | default: | ||
358 | break; | ||
359 | } | ||
360 | |||
361 | if (toneport_has_led(toneport->type)) | ||
362 | toneport_update_led(&usbdev->dev); | ||
363 | } | ||
364 | |||
365 | /* | ||
366 | Toneport device disconnected. | ||
367 | */ | ||
368 | static void line6_toneport_disconnect(struct usb_interface *interface) | ||
369 | { | ||
370 | struct usb_line6_toneport *toneport; | ||
371 | u16 idProduct; | ||
372 | |||
373 | if (interface == NULL) | ||
374 | return; | ||
375 | |||
376 | toneport = usb_get_intfdata(interface); | ||
377 | del_timer_sync(&toneport->timer); | ||
378 | idProduct = le16_to_cpu(toneport->line6.usbdev->descriptor.idProduct); | ||
379 | |||
380 | if (toneport_has_led(idProduct)) { | ||
381 | device_remove_file(&interface->dev, &dev_attr_led_red); | ||
382 | device_remove_file(&interface->dev, &dev_attr_led_green); | ||
383 | } | ||
384 | } | ||
385 | |||
386 | |||
387 | /* | ||
388 | Try to init Toneport device. | ||
389 | */ | ||
390 | static int toneport_init(struct usb_interface *interface, | ||
391 | struct usb_line6 *line6) | ||
392 | { | ||
393 | int err; | ||
394 | struct usb_line6_toneport *toneport = (struct usb_line6_toneport *) line6; | ||
395 | |||
396 | if ((interface == NULL) || (toneport == NULL)) | ||
397 | return -ENODEV; | ||
398 | |||
399 | line6->disconnect = line6_toneport_disconnect; | ||
400 | |||
401 | /* initialize PCM subsystem: */ | ||
402 | err = line6_init_pcm(line6, &toneport_pcm_properties); | ||
403 | if (err < 0) | ||
404 | return err; | ||
405 | |||
406 | /* register monitor control: */ | ||
407 | err = snd_ctl_add(line6->card, | ||
408 | snd_ctl_new1(&toneport_control_monitor, | ||
409 | line6->line6pcm)); | ||
410 | if (err < 0) | ||
411 | return err; | ||
412 | |||
413 | /* register source select control: */ | ||
414 | switch (toneport->type) { | ||
415 | case LINE6_TONEPORT_UX1: | ||
416 | case LINE6_TONEPORT_UX2: | ||
417 | case LINE6_PODSTUDIO_UX1: | ||
418 | case LINE6_PODSTUDIO_UX2: | ||
419 | err = | ||
420 | snd_ctl_add(line6->card, | ||
421 | snd_ctl_new1(&toneport_control_source, | ||
422 | line6->line6pcm)); | ||
423 | if (err < 0) | ||
424 | return err; | ||
425 | |||
426 | default: | ||
427 | break; | ||
428 | } | ||
429 | |||
430 | line6_read_serial_number(line6, &toneport->serial_number); | ||
431 | line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1); | ||
432 | |||
433 | if (toneport_has_led(toneport->type)) { | ||
434 | err = device_create_file(&interface->dev, &dev_attr_led_red); | ||
435 | if (err < 0) | ||
436 | return err; | ||
437 | err = device_create_file(&interface->dev, &dev_attr_led_green); | ||
438 | if (err < 0) | ||
439 | return err; | ||
440 | } | ||
441 | |||
442 | toneport_setup(toneport); | ||
443 | |||
444 | setup_timer(&toneport->timer, toneport_start_pcm, | ||
445 | (unsigned long)toneport); | ||
446 | mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ); | ||
447 | |||
448 | /* register audio system: */ | ||
449 | return snd_card_register(line6->card); | ||
450 | } | ||
451 | |||
452 | #ifdef CONFIG_PM | ||
453 | /* | ||
454 | Resume Toneport device after reset. | ||
455 | */ | ||
456 | static int toneport_reset_resume(struct usb_interface *interface) | ||
457 | { | ||
458 | toneport_setup(usb_get_intfdata(interface)); | ||
459 | return line6_resume(interface); | ||
460 | } | ||
461 | #endif | ||
462 | |||
463 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) | ||
464 | #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) | ||
465 | |||
466 | /* table of devices that work with this driver */ | ||
467 | static const struct usb_device_id toneport_id_table[] = { | ||
468 | { LINE6_DEVICE(0x4750), .driver_info = LINE6_GUITARPORT }, | ||
469 | { LINE6_DEVICE(0x4153), .driver_info = LINE6_PODSTUDIO_GX }, | ||
470 | { LINE6_DEVICE(0x4150), .driver_info = LINE6_PODSTUDIO_UX1 }, | ||
471 | { LINE6_IF_NUM(0x4151, 0), .driver_info = LINE6_PODSTUDIO_UX2 }, | ||
472 | { LINE6_DEVICE(0x4147), .driver_info = LINE6_TONEPORT_GX }, | ||
473 | { LINE6_DEVICE(0x4141), .driver_info = LINE6_TONEPORT_UX1 }, | ||
474 | { LINE6_IF_NUM(0x4142, 0), .driver_info = LINE6_TONEPORT_UX2 }, | ||
475 | {} | ||
476 | }; | ||
477 | |||
478 | MODULE_DEVICE_TABLE(usb, toneport_id_table); | ||
479 | |||
480 | static const struct line6_properties toneport_properties_table[] = { | ||
481 | [LINE6_GUITARPORT] = { | ||
482 | .id = "GuitarPort", | ||
483 | .name = "GuitarPort", | ||
484 | .capabilities = LINE6_CAP_PCM, | ||
485 | .altsetting = 2, /* 1..4 seem to be ok */ | ||
486 | /* no control channel */ | ||
487 | .ep_audio_r = 0x82, | ||
488 | .ep_audio_w = 0x01, | ||
489 | }, | ||
490 | [LINE6_PODSTUDIO_GX] = { | ||
491 | .id = "PODStudioGX", | ||
492 | .name = "POD Studio GX", | ||
493 | .capabilities = LINE6_CAP_PCM, | ||
494 | .altsetting = 2, /* 1..4 seem to be ok */ | ||
495 | /* no control channel */ | ||
496 | .ep_audio_r = 0x82, | ||
497 | .ep_audio_w = 0x01, | ||
498 | }, | ||
499 | [LINE6_PODSTUDIO_UX1] = { | ||
500 | .id = "PODStudioUX1", | ||
501 | .name = "POD Studio UX1", | ||
502 | .capabilities = LINE6_CAP_PCM, | ||
503 | .altsetting = 2, /* 1..4 seem to be ok */ | ||
504 | /* no control channel */ | ||
505 | .ep_audio_r = 0x82, | ||
506 | .ep_audio_w = 0x01, | ||
507 | }, | ||
508 | [LINE6_PODSTUDIO_UX2] = { | ||
509 | .id = "PODStudioUX2", | ||
510 | .name = "POD Studio UX2", | ||
511 | .capabilities = LINE6_CAP_PCM, | ||
512 | .altsetting = 2, /* defaults to 44.1kHz, 16-bit */ | ||
513 | /* no control channel */ | ||
514 | .ep_audio_r = 0x82, | ||
515 | .ep_audio_w = 0x01, | ||
516 | }, | ||
517 | [LINE6_TONEPORT_GX] = { | ||
518 | .id = "TonePortGX", | ||
519 | .name = "TonePort GX", | ||
520 | .capabilities = LINE6_CAP_PCM, | ||
521 | .altsetting = 2, /* 1..4 seem to be ok */ | ||
522 | /* no control channel */ | ||
523 | .ep_audio_r = 0x82, | ||
524 | .ep_audio_w = 0x01, | ||
525 | }, | ||
526 | [LINE6_TONEPORT_UX1] = { | ||
527 | .id = "TonePortUX1", | ||
528 | .name = "TonePort UX1", | ||
529 | .capabilities = LINE6_CAP_PCM, | ||
530 | .altsetting = 2, /* 1..4 seem to be ok */ | ||
531 | /* no control channel */ | ||
532 | .ep_audio_r = 0x82, | ||
533 | .ep_audio_w = 0x01, | ||
534 | }, | ||
535 | [LINE6_TONEPORT_UX2] = { | ||
536 | .id = "TonePortUX2", | ||
537 | .name = "TonePort UX2", | ||
538 | .capabilities = LINE6_CAP_PCM, | ||
539 | .altsetting = 2, /* defaults to 44.1kHz, 16-bit */ | ||
540 | /* no control channel */ | ||
541 | .ep_audio_r = 0x82, | ||
542 | .ep_audio_w = 0x01, | ||
543 | }, | ||
544 | }; | ||
545 | |||
546 | /* | ||
547 | Probe USB device. | ||
548 | */ | ||
549 | static int toneport_probe(struct usb_interface *interface, | ||
550 | const struct usb_device_id *id) | ||
551 | { | ||
552 | struct usb_line6_toneport *toneport; | ||
553 | |||
554 | toneport = kzalloc(sizeof(*toneport), GFP_KERNEL); | ||
555 | if (!toneport) | ||
556 | return -ENODEV; | ||
557 | toneport->type = id->driver_info; | ||
558 | return line6_probe(interface, &toneport->line6, | ||
559 | &toneport_properties_table[id->driver_info], | ||
560 | toneport_init); | ||
561 | } | ||
562 | |||
563 | static struct usb_driver toneport_driver = { | ||
564 | .name = KBUILD_MODNAME, | ||
565 | .probe = toneport_probe, | ||
566 | .disconnect = line6_disconnect, | ||
567 | #ifdef CONFIG_PM | ||
568 | .suspend = line6_suspend, | ||
569 | .resume = line6_resume, | ||
570 | .reset_resume = toneport_reset_resume, | ||
571 | #endif | ||
572 | .id_table = toneport_id_table, | ||
573 | }; | ||
574 | |||
575 | module_usb_driver(toneport_driver); | ||
576 | |||
577 | MODULE_DESCRIPTION("TonePort USB driver"); | ||
578 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/usb/line6/usbdefs.h b/sound/usb/line6/usbdefs.h new file mode 100644 index 000000000000..5ef7bcd24e18 --- /dev/null +++ b/sound/usb/line6/usbdefs.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef USBDEFS_H | ||
13 | #define USBDEFS_H | ||
14 | |||
15 | #define USB_INTERVALS_PER_SECOND 1000 | ||
16 | |||
17 | /* device supports settings parameter via USB */ | ||
18 | #define LINE6_CAP_CONTROL (1 << 0) | ||
19 | /* device supports PCM input/output via USB */ | ||
20 | #define LINE6_CAP_PCM (1 << 1) | ||
21 | /* device support hardware monitoring */ | ||
22 | #define LINE6_CAP_HWMON (1 << 2) | ||
23 | |||
24 | #define LINE6_FALLBACK_INTERVAL 10 | ||
25 | #define LINE6_FALLBACK_MAXPACKETSIZE 16 | ||
26 | |||
27 | #endif | ||
diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c new file mode 100644 index 000000000000..99a58cbfd2da --- /dev/null +++ b/sound/usb/line6/variax.c | |||
@@ -0,0 +1,334 @@ | |||
1 | /* | ||
2 | * Line 6 Linux USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/slab.h> | ||
13 | #include <linux/spinlock.h> | ||
14 | #include <linux/usb.h> | ||
15 | #include <linux/wait.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <sound/core.h> | ||
18 | |||
19 | #include "driver.h" | ||
20 | #include "usbdefs.h" | ||
21 | |||
22 | #define VARIAX_STARTUP_DELAY1 1000 | ||
23 | #define VARIAX_STARTUP_DELAY3 100 | ||
24 | #define VARIAX_STARTUP_DELAY4 100 | ||
25 | |||
26 | /* | ||
27 | Stages of Variax startup procedure | ||
28 | */ | ||
29 | enum { | ||
30 | VARIAX_STARTUP_INIT = 1, | ||
31 | VARIAX_STARTUP_VERSIONREQ, | ||
32 | VARIAX_STARTUP_WAIT, | ||
33 | VARIAX_STARTUP_ACTIVATE, | ||
34 | VARIAX_STARTUP_WORKQUEUE, | ||
35 | VARIAX_STARTUP_SETUP, | ||
36 | VARIAX_STARTUP_LAST = VARIAX_STARTUP_SETUP - 1 | ||
37 | }; | ||
38 | |||
39 | enum { | ||
40 | LINE6_PODXTLIVE_VARIAX, | ||
41 | LINE6_VARIAX | ||
42 | }; | ||
43 | |||
44 | struct usb_line6_variax { | ||
45 | /** | ||
46 | Generic Line 6 USB data. | ||
47 | */ | ||
48 | struct usb_line6 line6; | ||
49 | |||
50 | /** | ||
51 | Buffer for activation code. | ||
52 | */ | ||
53 | unsigned char *buffer_activate; | ||
54 | |||
55 | /** | ||
56 | Handler for device initializaton. | ||
57 | */ | ||
58 | struct work_struct startup_work; | ||
59 | |||
60 | /** | ||
61 | Timers for device initializaton. | ||
62 | */ | ||
63 | struct timer_list startup_timer1; | ||
64 | struct timer_list startup_timer2; | ||
65 | |||
66 | /** | ||
67 | Current progress in startup procedure. | ||
68 | */ | ||
69 | int startup_progress; | ||
70 | }; | ||
71 | |||
72 | #define VARIAX_OFFSET_ACTIVATE 7 | ||
73 | |||
74 | /* | ||
75 | This message is sent by the device during initialization and identifies | ||
76 | the connected guitar version. | ||
77 | */ | ||
78 | static const char variax_init_version[] = { | ||
79 | 0xf0, 0x7e, 0x7f, 0x06, 0x02, 0x00, 0x01, 0x0c, | ||
80 | 0x07, 0x00, 0x00, 0x00 | ||
81 | }; | ||
82 | |||
83 | /* | ||
84 | This message is the last one sent by the device during initialization. | ||
85 | */ | ||
86 | static const char variax_init_done[] = { | ||
87 | 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6b | ||
88 | }; | ||
89 | |||
90 | static const char variax_activate[] = { | ||
91 | 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01, | ||
92 | 0xf7 | ||
93 | }; | ||
94 | |||
95 | /* forward declarations: */ | ||
96 | static void variax_startup2(unsigned long data); | ||
97 | static void variax_startup4(unsigned long data); | ||
98 | static void variax_startup5(unsigned long data); | ||
99 | |||
100 | static void variax_activate_async(struct usb_line6_variax *variax, int a) | ||
101 | { | ||
102 | variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a; | ||
103 | line6_send_raw_message_async(&variax->line6, variax->buffer_activate, | ||
104 | sizeof(variax_activate)); | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | Variax startup procedure. | ||
109 | This is a sequence of functions with special requirements (e.g., must | ||
110 | not run immediately after initialization, must not run in interrupt | ||
111 | context). After the last one has finished, the device is ready to use. | ||
112 | */ | ||
113 | |||
114 | static void variax_startup1(struct usb_line6_variax *variax) | ||
115 | { | ||
116 | CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_INIT); | ||
117 | |||
118 | /* delay startup procedure: */ | ||
119 | line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1, | ||
120 | variax_startup2, (unsigned long)variax); | ||
121 | } | ||
122 | |||
123 | static void variax_startup2(unsigned long data) | ||
124 | { | ||
125 | struct usb_line6_variax *variax = (struct usb_line6_variax *)data; | ||
126 | struct usb_line6 *line6 = &variax->line6; | ||
127 | |||
128 | /* schedule another startup procedure until startup is complete: */ | ||
129 | if (variax->startup_progress >= VARIAX_STARTUP_LAST) | ||
130 | return; | ||
131 | |||
132 | variax->startup_progress = VARIAX_STARTUP_VERSIONREQ; | ||
133 | line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1, | ||
134 | variax_startup2, (unsigned long)variax); | ||
135 | |||
136 | /* request firmware version: */ | ||
137 | line6_version_request_async(line6); | ||
138 | } | ||
139 | |||
140 | static void variax_startup3(struct usb_line6_variax *variax) | ||
141 | { | ||
142 | CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_WAIT); | ||
143 | |||
144 | /* delay startup procedure: */ | ||
145 | line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY3, | ||
146 | variax_startup4, (unsigned long)variax); | ||
147 | } | ||
148 | |||
149 | static void variax_startup4(unsigned long data) | ||
150 | { | ||
151 | struct usb_line6_variax *variax = (struct usb_line6_variax *)data; | ||
152 | |||
153 | CHECK_STARTUP_PROGRESS(variax->startup_progress, | ||
154 | VARIAX_STARTUP_ACTIVATE); | ||
155 | |||
156 | /* activate device: */ | ||
157 | variax_activate_async(variax, 1); | ||
158 | line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY4, | ||
159 | variax_startup5, (unsigned long)variax); | ||
160 | } | ||
161 | |||
162 | static void variax_startup5(unsigned long data) | ||
163 | { | ||
164 | struct usb_line6_variax *variax = (struct usb_line6_variax *)data; | ||
165 | |||
166 | CHECK_STARTUP_PROGRESS(variax->startup_progress, | ||
167 | VARIAX_STARTUP_WORKQUEUE); | ||
168 | |||
169 | /* schedule work for global work queue: */ | ||
170 | schedule_work(&variax->startup_work); | ||
171 | } | ||
172 | |||
173 | static void variax_startup6(struct work_struct *work) | ||
174 | { | ||
175 | struct usb_line6_variax *variax = | ||
176 | container_of(work, struct usb_line6_variax, startup_work); | ||
177 | |||
178 | CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP); | ||
179 | |||
180 | /* ALSA audio interface: */ | ||
181 | snd_card_register(variax->line6.card); | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | Process a completely received message. | ||
186 | */ | ||
187 | static void line6_variax_process_message(struct usb_line6 *line6) | ||
188 | { | ||
189 | struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; | ||
190 | const unsigned char *buf = variax->line6.buffer_message; | ||
191 | |||
192 | switch (buf[0]) { | ||
193 | case LINE6_RESET: | ||
194 | dev_info(variax->line6.ifcdev, "VARIAX reset\n"); | ||
195 | break; | ||
196 | |||
197 | case LINE6_SYSEX_BEGIN: | ||
198 | if (memcmp(buf + 1, variax_init_version + 1, | ||
199 | sizeof(variax_init_version) - 1) == 0) { | ||
200 | variax_startup3(variax); | ||
201 | } else if (memcmp(buf + 1, variax_init_done + 1, | ||
202 | sizeof(variax_init_done) - 1) == 0) { | ||
203 | /* notify of complete initialization: */ | ||
204 | variax_startup4((unsigned long)variax); | ||
205 | } | ||
206 | break; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | Variax destructor. | ||
212 | */ | ||
213 | static void line6_variax_disconnect(struct usb_interface *interface) | ||
214 | { | ||
215 | struct usb_line6_variax *variax; | ||
216 | |||
217 | if (!interface) | ||
218 | return; | ||
219 | |||
220 | variax = usb_get_intfdata(interface); | ||
221 | if (!variax) | ||
222 | return; | ||
223 | |||
224 | del_timer(&variax->startup_timer1); | ||
225 | del_timer(&variax->startup_timer2); | ||
226 | cancel_work_sync(&variax->startup_work); | ||
227 | |||
228 | kfree(variax->buffer_activate); | ||
229 | } | ||
230 | |||
231 | /* | ||
232 | Try to init workbench device. | ||
233 | */ | ||
234 | static int variax_init(struct usb_interface *interface, | ||
235 | struct usb_line6 *line6) | ||
236 | { | ||
237 | struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; | ||
238 | int err; | ||
239 | |||
240 | line6->process_message = line6_variax_process_message; | ||
241 | line6->disconnect = line6_variax_disconnect; | ||
242 | |||
243 | init_timer(&variax->startup_timer1); | ||
244 | init_timer(&variax->startup_timer2); | ||
245 | INIT_WORK(&variax->startup_work, variax_startup6); | ||
246 | |||
247 | if ((interface == NULL) || (variax == NULL)) | ||
248 | return -ENODEV; | ||
249 | |||
250 | /* initialize USB buffers: */ | ||
251 | variax->buffer_activate = kmemdup(variax_activate, | ||
252 | sizeof(variax_activate), GFP_KERNEL); | ||
253 | |||
254 | if (variax->buffer_activate == NULL) | ||
255 | return -ENOMEM; | ||
256 | |||
257 | /* initialize MIDI subsystem: */ | ||
258 | err = line6_init_midi(&variax->line6); | ||
259 | if (err < 0) | ||
260 | return err; | ||
261 | |||
262 | /* initiate startup procedure: */ | ||
263 | variax_startup1(variax); | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) | ||
268 | #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) | ||
269 | |||
270 | /* table of devices that work with this driver */ | ||
271 | static const struct usb_device_id variax_id_table[] = { | ||
272 | { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX }, | ||
273 | { LINE6_DEVICE(0x534d), .driver_info = LINE6_VARIAX }, | ||
274 | {} | ||
275 | }; | ||
276 | |||
277 | MODULE_DEVICE_TABLE(usb, variax_id_table); | ||
278 | |||
279 | static const struct line6_properties variax_properties_table[] = { | ||
280 | [LINE6_PODXTLIVE_VARIAX] = { | ||
281 | .id = "PODxtLive", | ||
282 | .name = "PODxt Live", | ||
283 | .capabilities = LINE6_CAP_CONTROL | ||
284 | | LINE6_CAP_PCM | ||
285 | | LINE6_CAP_HWMON, | ||
286 | .altsetting = 1, | ||
287 | .ep_ctrl_r = 0x86, | ||
288 | .ep_ctrl_w = 0x05, | ||
289 | .ep_audio_r = 0x82, | ||
290 | .ep_audio_w = 0x01, | ||
291 | }, | ||
292 | [LINE6_VARIAX] = { | ||
293 | .id = "Variax", | ||
294 | .name = "Variax Workbench", | ||
295 | .capabilities = LINE6_CAP_CONTROL, | ||
296 | .altsetting = 1, | ||
297 | .ep_ctrl_r = 0x82, | ||
298 | .ep_ctrl_w = 0x01, | ||
299 | /* no audio channel */ | ||
300 | } | ||
301 | }; | ||
302 | |||
303 | /* | ||
304 | Probe USB device. | ||
305 | */ | ||
306 | static int variax_probe(struct usb_interface *interface, | ||
307 | const struct usb_device_id *id) | ||
308 | { | ||
309 | struct usb_line6_variax *variax; | ||
310 | |||
311 | variax = kzalloc(sizeof(*variax), GFP_KERNEL); | ||
312 | if (!variax) | ||
313 | return -ENODEV; | ||
314 | return line6_probe(interface, &variax->line6, | ||
315 | &variax_properties_table[id->driver_info], | ||
316 | variax_init); | ||
317 | } | ||
318 | |||
319 | static struct usb_driver variax_driver = { | ||
320 | .name = KBUILD_MODNAME, | ||
321 | .probe = variax_probe, | ||
322 | .disconnect = line6_disconnect, | ||
323 | #ifdef CONFIG_PM | ||
324 | .suspend = line6_suspend, | ||
325 | .resume = line6_resume, | ||
326 | .reset_resume = line6_resume, | ||
327 | #endif | ||
328 | .id_table = variax_id_table, | ||
329 | }; | ||
330 | |||
331 | module_usb_driver(variax_driver); | ||
332 | |||
333 | MODULE_DESCRIPTION("Vairax Workbench USB driver"); | ||
334 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index 5bfb695547f8..417ebb11cf48 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
@@ -2292,14 +2292,13 @@ int snd_usbmidi_create(struct snd_card *card, | |||
2292 | umidi->iface = iface; | 2292 | umidi->iface = iface; |
2293 | umidi->quirk = quirk; | 2293 | umidi->quirk = quirk; |
2294 | umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; | 2294 | umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; |
2295 | init_timer(&umidi->error_timer); | ||
2296 | spin_lock_init(&umidi->disc_lock); | 2295 | spin_lock_init(&umidi->disc_lock); |
2297 | init_rwsem(&umidi->disc_rwsem); | 2296 | init_rwsem(&umidi->disc_rwsem); |
2298 | mutex_init(&umidi->mutex); | 2297 | mutex_init(&umidi->mutex); |
2299 | umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor), | 2298 | umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor), |
2300 | le16_to_cpu(umidi->dev->descriptor.idProduct)); | 2299 | le16_to_cpu(umidi->dev->descriptor.idProduct)); |
2301 | umidi->error_timer.function = snd_usbmidi_error_timer; | 2300 | setup_timer(&umidi->error_timer, snd_usbmidi_error_timer, |
2302 | umidi->error_timer.data = (unsigned long)umidi; | 2301 | (unsigned long)umidi); |
2303 | 2302 | ||
2304 | /* detect the endpoint(s) to use */ | 2303 | /* detect the endpoint(s) to use */ |
2305 | memset(endpoints, 0, sizeof(endpoints)); | 2304 | memset(endpoints, 0, sizeof(endpoints)); |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 0a598af9b38b..67d476548dcf 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -2486,6 +2486,28 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2486 | } | 2486 | } |
2487 | }, | 2487 | }, |
2488 | 2488 | ||
2489 | { | ||
2490 | /* Akai MPC Element */ | ||
2491 | USB_DEVICE(0x09e8, 0x0021), | ||
2492 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
2493 | .ifnum = QUIRK_ANY_INTERFACE, | ||
2494 | .type = QUIRK_COMPOSITE, | ||
2495 | .data = & (const struct snd_usb_audio_quirk[]) { | ||
2496 | { | ||
2497 | .ifnum = 0, | ||
2498 | .type = QUIRK_IGNORE_INTERFACE | ||
2499 | }, | ||
2500 | { | ||
2501 | .ifnum = 1, | ||
2502 | .type = QUIRK_MIDI_STANDARD_INTERFACE | ||
2503 | }, | ||
2504 | { | ||
2505 | .ifnum = -1 | ||
2506 | } | ||
2507 | } | ||
2508 | } | ||
2509 | }, | ||
2510 | |||
2489 | /* TerraTec devices */ | 2511 | /* TerraTec devices */ |
2490 | { | 2512 | { |
2491 | USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012), | 2513 | USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012), |