diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 15:58:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 15:58:37 -0400 |
commit | 0a3fd051c7036ef71b58863f8e5da7c3dabd9d3f (patch) | |
tree | 43388a81494ded94008afff66777f9f6e8cb5484 /sound | |
parent | 57a44415beee38d1afcd8e1b5fad66f3414d2dac (diff) | |
parent | c911d1e16dfc1f0338bbc245ff724322c0113395 (diff) |
Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
* 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa: (122 commits)
[ALSA] version 1.0.14rc4
[ALSA] Add speaker pin sequencing to hda_codec.c:snd_hda_parse_pin_def_config()
[ALSA] hda-codec - Add ALC861VD Lenovo support
[ALSA] hda-codec - Fix connection list in generic parser
[ALSA] usb-audio: work around wrong wMaxPacketSize on ESI M4U
[ALSA] usb-audio: work around broken M-Audio MidiSport Uno firmware
[ALSA] usb-audio: explicitly match Logitech QuickCam
[ALSA] hda-codec - Fix a typo
[ALSA] hda-codec - Fix ALC880 uniwill auto-mutes
[ALSA] hda-codec - Fix AD1988 SPDIF playback route control
[ALSA] wm8750 typo fix
[ALSA] wavefront: only declare isapnp on CONFIG_PNP
[ALSA] hda-codec - bug fixes for stac92xx HDA codecs.
[ALSA] add MODULE_FIRMWARE entries
[ALSA] do not depend on FW_LOADER when internal firmware images are used
[ALSA] hda-codec - Fix resume of STAC92xx codecs
[ALSA] usbaudio - Revert the minimal period size fix patch
[ALSA] hda-codec - Add support for new HP DV series laptops
[ALSA] usb-audio - Fix the minimum period size per transfer mode
[ALSA] sound/pcmcia/vx/vxpocket.c: fix an if() condition
...
Diffstat (limited to 'sound')
161 files changed, 10604 insertions, 5515 deletions
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/snd-aoa-codec-onyx.c index e91f9f66f395..ded516717940 100644 --- a/sound/aoa/codecs/snd-aoa-codec-onyx.c +++ b/sound/aoa/codecs/snd-aoa-codec-onyx.c | |||
@@ -1018,7 +1018,7 @@ static int onyx_create(struct i2c_adapter *adapter, | |||
1018 | onyx->i2c.driver = &onyx_driver; | 1018 | onyx->i2c.driver = &onyx_driver; |
1019 | onyx->i2c.adapter = adapter; | 1019 | onyx->i2c.adapter = adapter; |
1020 | onyx->i2c.addr = addr & 0x7f; | 1020 | onyx->i2c.addr = addr & 0x7f; |
1021 | strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE-1); | 1021 | strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE); |
1022 | 1022 | ||
1023 | if (i2c_attach_client(&onyx->i2c)) { | 1023 | if (i2c_attach_client(&onyx->i2c)) { |
1024 | printk(KERN_ERR PFX "failed to attach to i2c\n"); | 1024 | printk(KERN_ERR PFX "failed to attach to i2c\n"); |
@@ -1033,7 +1033,7 @@ static int onyx_create(struct i2c_adapter *adapter, | |||
1033 | goto fail; | 1033 | goto fail; |
1034 | } | 1034 | } |
1035 | 1035 | ||
1036 | strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN-1); | 1036 | strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN); |
1037 | onyx->codec.owner = THIS_MODULE; | 1037 | onyx->codec.owner = THIS_MODULE; |
1038 | onyx->codec.init = onyx_init_codec; | 1038 | onyx->codec.init = onyx_init_codec; |
1039 | onyx->codec.exit = onyx_exit_codec; | 1039 | onyx->codec.exit = onyx_exit_codec; |
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c index 041fe52cbf29..2f771f57c76f 100644 --- a/sound/aoa/codecs/snd-aoa-codec-tas.c +++ b/sound/aoa/codecs/snd-aoa-codec-tas.c | |||
@@ -899,14 +899,14 @@ static int tas_create(struct i2c_adapter *adapter, | |||
899 | tas->i2c.addr = addr; | 899 | tas->i2c.addr = addr; |
900 | /* seems that half is a saner default */ | 900 | /* seems that half is a saner default */ |
901 | tas->drc_range = TAS3004_DRC_MAX / 2; | 901 | tas->drc_range = TAS3004_DRC_MAX / 2; |
902 | strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1); | 902 | strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE); |
903 | 903 | ||
904 | if (i2c_attach_client(&tas->i2c)) { | 904 | if (i2c_attach_client(&tas->i2c)) { |
905 | printk(KERN_ERR PFX "failed to attach to i2c\n"); | 905 | printk(KERN_ERR PFX "failed to attach to i2c\n"); |
906 | goto fail; | 906 | goto fail; |
907 | } | 907 | } |
908 | 908 | ||
909 | strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN-1); | 909 | strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN); |
910 | tas->codec.owner = THIS_MODULE; | 910 | tas->codec.owner = THIS_MODULE; |
911 | tas->codec.init = tas_init_codec; | 911 | tas->codec.init = tas_init_codec; |
912 | tas->codec.exit = tas_exit_codec; | 912 | tas->codec.exit = tas_exit_codec; |
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c index 8b2e9b905cda..64d163914335 100644 --- a/sound/aoa/soundbus/core.c +++ b/sound/aoa/soundbus/core.c | |||
@@ -163,8 +163,6 @@ static int soundbus_device_resume(struct device * dev) | |||
163 | 163 | ||
164 | #endif /* CONFIG_PM */ | 164 | #endif /* CONFIG_PM */ |
165 | 165 | ||
166 | extern struct device_attribute soundbus_dev_attrs[]; | ||
167 | |||
168 | static struct bus_type soundbus_bus_type = { | 166 | static struct bus_type soundbus_bus_type = { |
169 | .name = "aoa-soundbus", | 167 | .name = "aoa-soundbus", |
170 | .probe = soundbus_probe, | 168 | .probe = soundbus_probe, |
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/i2sbus-core.c index 0fccdbf51663..efb9441b3acf 100644 --- a/sound/aoa/soundbus/i2sbus/i2sbus-core.c +++ b/sound/aoa/soundbus/i2sbus/i2sbus-core.c | |||
@@ -23,9 +23,6 @@ | |||
23 | MODULE_LICENSE("GPL"); | 23 | MODULE_LICENSE("GPL"); |
24 | MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); | 24 | MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); |
25 | MODULE_DESCRIPTION("Apple Soundbus: I2S support"); | 25 | MODULE_DESCRIPTION("Apple Soundbus: I2S support"); |
26 | /* for auto-loading, declare that we handle this weird | ||
27 | * string that macio puts into the relevant device */ | ||
28 | MODULE_ALIAS("of:Ni2sTi2sC"); | ||
29 | 26 | ||
30 | static int force; | 27 | static int force; |
31 | module_param(force, int, 0444); | 28 | module_param(force, int, 0444); |
@@ -37,6 +34,8 @@ static struct of_device_id i2sbus_match[] = { | |||
37 | { } | 34 | { } |
38 | }; | 35 | }; |
39 | 36 | ||
37 | MODULE_DEVICE_TABLE(of, i2sbus_match); | ||
38 | |||
40 | static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev, | 39 | static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev, |
41 | struct dbdma_command_mem *r, | 40 | struct dbdma_command_mem *r, |
42 | int numcmds) | 41 | int numcmds) |
diff --git a/sound/aoa/soundbus/soundbus.h b/sound/aoa/soundbus/soundbus.h index 5c27297835d7..622cd37a0118 100644 --- a/sound/aoa/soundbus/soundbus.h +++ b/sound/aoa/soundbus/soundbus.h | |||
@@ -199,4 +199,6 @@ struct soundbus_driver { | |||
199 | extern int soundbus_register_driver(struct soundbus_driver *drv); | 199 | extern int soundbus_register_driver(struct soundbus_driver *drv); |
200 | extern void soundbus_unregister_driver(struct soundbus_driver *drv); | 200 | extern void soundbus_unregister_driver(struct soundbus_driver *drv); |
201 | 201 | ||
202 | extern struct device_attribute soundbus_dev_attrs[]; | ||
203 | |||
202 | #endif /* __SOUNDBUS_H */ | 204 | #endif /* __SOUNDBUS_H */ |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 905234817c89..a96733a5beb8 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -712,26 +712,23 @@ static int snd_pcm_action_group(struct action_ops *ops, | |||
712 | struct snd_pcm_substream *substream, | 712 | struct snd_pcm_substream *substream, |
713 | int state, int do_lock) | 713 | int state, int do_lock) |
714 | { | 714 | { |
715 | struct list_head *pos; | ||
716 | struct snd_pcm_substream *s = NULL; | 715 | struct snd_pcm_substream *s = NULL; |
717 | struct snd_pcm_substream *s1; | 716 | struct snd_pcm_substream *s1; |
718 | int res = 0; | 717 | int res = 0; |
719 | 718 | ||
720 | snd_pcm_group_for_each(pos, substream) { | 719 | snd_pcm_group_for_each_entry(s, substream) { |
721 | s = snd_pcm_group_substream_entry(pos); | ||
722 | if (do_lock && s != substream) | 720 | if (do_lock && s != substream) |
723 | spin_lock(&s->self_group.lock); | 721 | spin_lock_nested(&s->self_group.lock, |
722 | SINGLE_DEPTH_NESTING); | ||
724 | res = ops->pre_action(s, state); | 723 | res = ops->pre_action(s, state); |
725 | if (res < 0) | 724 | if (res < 0) |
726 | goto _unlock; | 725 | goto _unlock; |
727 | } | 726 | } |
728 | snd_pcm_group_for_each(pos, substream) { | 727 | snd_pcm_group_for_each_entry(s, substream) { |
729 | s = snd_pcm_group_substream_entry(pos); | ||
730 | res = ops->do_action(s, state); | 728 | res = ops->do_action(s, state); |
731 | if (res < 0) { | 729 | if (res < 0) { |
732 | if (ops->undo_action) { | 730 | if (ops->undo_action) { |
733 | snd_pcm_group_for_each(pos, substream) { | 731 | snd_pcm_group_for_each_entry(s1, substream) { |
734 | s1 = snd_pcm_group_substream_entry(pos); | ||
735 | if (s1 == s) /* failed stream */ | 732 | if (s1 == s) /* failed stream */ |
736 | break; | 733 | break; |
737 | ops->undo_action(s1, state); | 734 | ops->undo_action(s1, state); |
@@ -741,15 +738,13 @@ static int snd_pcm_action_group(struct action_ops *ops, | |||
741 | goto _unlock; | 738 | goto _unlock; |
742 | } | 739 | } |
743 | } | 740 | } |
744 | snd_pcm_group_for_each(pos, substream) { | 741 | snd_pcm_group_for_each_entry(s, substream) { |
745 | s = snd_pcm_group_substream_entry(pos); | ||
746 | ops->post_action(s, state); | 742 | ops->post_action(s, state); |
747 | } | 743 | } |
748 | _unlock: | 744 | _unlock: |
749 | if (do_lock) { | 745 | if (do_lock) { |
750 | /* unlock streams */ | 746 | /* unlock streams */ |
751 | snd_pcm_group_for_each(pos, substream) { | 747 | snd_pcm_group_for_each_entry(s1, substream) { |
752 | s1 = snd_pcm_group_substream_entry(pos); | ||
753 | if (s1 != substream) | 748 | if (s1 != substream) |
754 | spin_unlock(&s1->self_group.lock); | 749 | spin_unlock(&s1->self_group.lock); |
755 | if (s1 == s) /* end */ | 750 | if (s1 == s) /* end */ |
@@ -1438,7 +1433,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) | |||
1438 | { | 1433 | { |
1439 | struct snd_card *card; | 1434 | struct snd_card *card; |
1440 | struct snd_pcm_runtime *runtime; | 1435 | struct snd_pcm_runtime *runtime; |
1441 | struct list_head *pos; | 1436 | struct snd_pcm_substream *s; |
1442 | int result = 0; | 1437 | int result = 0; |
1443 | int i, num_drecs; | 1438 | int i, num_drecs; |
1444 | struct drain_rec *drec, drec_tmp, *d; | 1439 | struct drain_rec *drec, drec_tmp, *d; |
@@ -1473,8 +1468,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) | |||
1473 | 1468 | ||
1474 | /* count only playback streams */ | 1469 | /* count only playback streams */ |
1475 | num_drecs = 0; | 1470 | num_drecs = 0; |
1476 | snd_pcm_group_for_each(pos, substream) { | 1471 | snd_pcm_group_for_each_entry(s, substream) { |
1477 | struct snd_pcm_substream *s = snd_pcm_group_substream_entry(pos); | ||
1478 | runtime = s->runtime; | 1472 | runtime = s->runtime; |
1479 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 1473 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
1480 | d = &drec[num_drecs++]; | 1474 | d = &drec[num_drecs++]; |
@@ -1674,7 +1668,7 @@ static void relink_to_local(struct snd_pcm_substream *substream) | |||
1674 | 1668 | ||
1675 | static int snd_pcm_unlink(struct snd_pcm_substream *substream) | 1669 | static int snd_pcm_unlink(struct snd_pcm_substream *substream) |
1676 | { | 1670 | { |
1677 | struct list_head *pos; | 1671 | struct snd_pcm_substream *s; |
1678 | int res = 0; | 1672 | int res = 0; |
1679 | 1673 | ||
1680 | down_write(&snd_pcm_link_rwsem); | 1674 | down_write(&snd_pcm_link_rwsem); |
@@ -1686,8 +1680,8 @@ static int snd_pcm_unlink(struct snd_pcm_substream *substream) | |||
1686 | list_del(&substream->link_list); | 1680 | list_del(&substream->link_list); |
1687 | substream->group->count--; | 1681 | substream->group->count--; |
1688 | if (substream->group->count == 1) { /* detach the last stream, too */ | 1682 | if (substream->group->count == 1) { /* detach the last stream, too */ |
1689 | snd_pcm_group_for_each(pos, substream) { | 1683 | snd_pcm_group_for_each_entry(s, substream) { |
1690 | relink_to_local(snd_pcm_group_substream_entry(pos)); | 1684 | relink_to_local(s); |
1691 | break; | 1685 | break; |
1692 | } | 1686 | } |
1693 | kfree(substream->group); | 1687 | kfree(substream->group); |
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c index 9f7b32e1ccde..7cd5e8f5d4ce 100644 --- a/sound/core/rtctimer.c +++ b/sound/core/rtctimer.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
27 | #include <linux/log2.h> | ||
27 | #include <sound/core.h> | 28 | #include <sound/core.h> |
28 | #include <sound/timer.h> | 29 | #include <sound/timer.h> |
29 | 30 | ||
@@ -129,7 +130,7 @@ static int __init rtctimer_init(void) | |||
129 | struct snd_timer *timer; | 130 | struct snd_timer *timer; |
130 | 131 | ||
131 | if (rtctimer_freq < 2 || rtctimer_freq > 8192 || | 132 | if (rtctimer_freq < 2 || rtctimer_freq > 8192 || |
132 | (rtctimer_freq & (rtctimer_freq - 1)) != 0) { | 133 | !is_power_of_2(rtctimer_freq)) { |
133 | snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", | 134 | snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", |
134 | rtctimer_freq); | 135 | rtctimer_freq); |
135 | return -EINVAL; | 136 | return -EINVAL; |
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 2de181ad0b05..1d563e515c17 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c | |||
@@ -42,6 +42,7 @@ static int pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; | |||
42 | #endif | 42 | #endif |
43 | static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */ | 43 | static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */ |
44 | static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */ | 44 | static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */ |
45 | static int uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; | ||
45 | 46 | ||
46 | module_param_array(index, int, NULL, 0444); | 47 | module_param_array(index, int, NULL, 0444); |
47 | MODULE_PARM_DESC(index, "Index value for MPU-401 device."); | 48 | MODULE_PARM_DESC(index, "Index value for MPU-401 device."); |
@@ -57,6 +58,8 @@ module_param_array(port, long, NULL, 0444); | |||
57 | MODULE_PARM_DESC(port, "Port # for MPU-401 device."); | 58 | MODULE_PARM_DESC(port, "Port # for MPU-401 device."); |
58 | module_param_array(irq, int, NULL, 0444); | 59 | module_param_array(irq, int, NULL, 0444); |
59 | MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device."); | 60 | MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device."); |
61 | module_param_array(uart_enter, bool, NULL, 0444); | ||
62 | MODULE_PARM_DESC(uart_enter, "Issue UART_ENTER command at open."); | ||
60 | 63 | ||
61 | static struct platform_device *platform_devices[SNDRV_CARDS]; | 64 | static struct platform_device *platform_devices[SNDRV_CARDS]; |
62 | static int pnp_registered; | 65 | static int pnp_registered; |
@@ -80,10 +83,11 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard) | |||
80 | strcat(card->longname, "polled"); | 83 | strcat(card->longname, "polled"); |
81 | } | 84 | } |
82 | 85 | ||
83 | if ((err = snd_mpu401_uart_new(card, 0, | 86 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev], |
84 | MPU401_HW_MPU401, | 87 | uart_enter[dev] ? 0 : MPU401_INFO_UART_ONLY, |
85 | port[dev], 0, | 88 | irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0, |
86 | irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0, NULL)) < 0) { | 89 | NULL); |
90 | if (err < 0) { | ||
87 | printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]); | 91 | printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]); |
88 | goto _err; | 92 | goto _err; |
89 | } | 93 | } |
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index 3daa9fa56c0b..85aedc348e2d 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c | |||
@@ -266,6 +266,16 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, | |||
266 | return 0; | 266 | return 0; |
267 | } | 267 | } |
268 | 268 | ||
269 | static int snd_mpu401_do_reset(struct snd_mpu401 *mpu) | ||
270 | { | ||
271 | if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) | ||
272 | return -EIO; | ||
273 | if (!(mpu->info_flags & MPU401_INFO_UART_ONLY) && | ||
274 | snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) | ||
275 | return -EIO; | ||
276 | return 0; | ||
277 | } | ||
278 | |||
269 | /* | 279 | /* |
270 | * input/output open/close - protected by open_mutex in rawmidi.c | 280 | * input/output open/close - protected by open_mutex in rawmidi.c |
271 | */ | 281 | */ |
@@ -278,9 +288,7 @@ static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream) | |||
278 | if (mpu->open_input && (err = mpu->open_input(mpu)) < 0) | 288 | if (mpu->open_input && (err = mpu->open_input(mpu)) < 0) |
279 | return err; | 289 | return err; |
280 | if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { | 290 | if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { |
281 | if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) | 291 | if (snd_mpu401_do_reset(mpu) < 0) |
282 | goto error_out; | ||
283 | if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) | ||
284 | goto error_out; | 292 | goto error_out; |
285 | } | 293 | } |
286 | mpu->substream_input = substream; | 294 | mpu->substream_input = substream; |
@@ -302,9 +310,7 @@ static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream) | |||
302 | if (mpu->open_output && (err = mpu->open_output(mpu)) < 0) | 310 | if (mpu->open_output && (err = mpu->open_output(mpu)) < 0) |
303 | return err; | 311 | return err; |
304 | if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { | 312 | if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { |
305 | if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) | 313 | if (snd_mpu401_do_reset(mpu) < 0) |
306 | goto error_out; | ||
307 | if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) | ||
308 | goto error_out; | 314 | goto error_out; |
309 | } | 315 | } |
310 | mpu->substream_output = substream; | 316 | mpu->substream_output = substream; |
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c index 6c9f4c9bfeb6..ebb1bdac7237 100644 --- a/sound/drivers/mts64.c +++ b/sound/drivers/mts64.c | |||
@@ -892,13 +892,13 @@ static void __devinit snd_mts64_attach(struct parport *p) | |||
892 | struct platform_device *device; | 892 | struct platform_device *device; |
893 | 893 | ||
894 | device = platform_device_alloc(PLATFORM_DRIVER, device_count); | 894 | device = platform_device_alloc(PLATFORM_DRIVER, device_count); |
895 | if (!device) | 895 | if (!device) |
896 | return; | 896 | return; |
897 | 897 | ||
898 | /* Temporary assignment to forward the parport */ | 898 | /* Temporary assignment to forward the parport */ |
899 | platform_set_drvdata(device, p); | 899 | platform_set_drvdata(device, p); |
900 | 900 | ||
901 | if (platform_device_register(device) < 0) { | 901 | if (platform_device_add(device) < 0) { |
902 | platform_device_put(device); | 902 | platform_device_put(device); |
903 | return; | 903 | return; |
904 | } | 904 | } |
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c index b2d0ba4bd184..497cafb57d9b 100644 --- a/sound/drivers/portman2x4.c +++ b/sound/drivers/portman2x4.c | |||
@@ -676,13 +676,13 @@ static void __devinit snd_portman_attach(struct parport *p) | |||
676 | struct platform_device *device; | 676 | struct platform_device *device; |
677 | 677 | ||
678 | device = platform_device_alloc(PLATFORM_DRIVER, device_count); | 678 | device = platform_device_alloc(PLATFORM_DRIVER, device_count); |
679 | if (!device) | 679 | if (!device) |
680 | return; | 680 | return; |
681 | 681 | ||
682 | /* Temporary assignment to forward the parport */ | 682 | /* Temporary assignment to forward the parport */ |
683 | platform_set_drvdata(device, p); | 683 | platform_set_drvdata(device, p); |
684 | 684 | ||
685 | if (platform_device_register(device) < 0) { | 685 | if (platform_device_add(device) < 0) { |
686 | platform_device_put(device); | 686 | platform_device_put(device); |
687 | return; | 687 | return; |
688 | } | 688 | } |
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c index e1920af4501d..9a8154c9416e 100644 --- a/sound/drivers/vx/vx_hwdep.c +++ b/sound/drivers/vx/vx_hwdep.c | |||
@@ -30,6 +30,20 @@ | |||
30 | 30 | ||
31 | #ifdef SND_VX_FW_LOADER | 31 | #ifdef SND_VX_FW_LOADER |
32 | 32 | ||
33 | MODULE_FIRMWARE("vx/bx_1_vxp.b56"); | ||
34 | MODULE_FIRMWARE("vx/bx_1_vp4.b56"); | ||
35 | MODULE_FIRMWARE("vx/x1_1_vx2.xlx"); | ||
36 | MODULE_FIRMWARE("vx/x1_2_v22.xlx"); | ||
37 | MODULE_FIRMWARE("vx/x1_1_vxp.xlx"); | ||
38 | MODULE_FIRMWARE("vx/x1_1_vp4.xlx"); | ||
39 | MODULE_FIRMWARE("vx/bd56002.boot"); | ||
40 | MODULE_FIRMWARE("vx/bd563v2.boot"); | ||
41 | MODULE_FIRMWARE("vx/bd563s3.boot"); | ||
42 | MODULE_FIRMWARE("vx/l_1_vx2.d56"); | ||
43 | MODULE_FIRMWARE("vx/l_1_v22.d56"); | ||
44 | MODULE_FIRMWARE("vx/l_1_vxp.d56"); | ||
45 | MODULE_FIRMWARE("vx/l_1_vp4.d56"); | ||
46 | |||
33 | int snd_vx_setup_firmware(struct vx_core *chip) | 47 | int snd_vx_setup_firmware(struct vx_core *chip) |
34 | { | 48 | { |
35 | static char *fw_files[VX_TYPE_NUMS][4] = { | 49 | static char *fw_files[VX_TYPE_NUMS][4] = { |
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c index adbfd5884d06..1efb973137a6 100644 --- a/sound/i2c/other/ak4114.c +++ b/sound/i2c/other/ak4114.c | |||
@@ -36,6 +36,7 @@ MODULE_LICENSE("GPL"); | |||
36 | #define AK4114_ADDR 0x00 /* fixed address */ | 36 | #define AK4114_ADDR 0x00 /* fixed address */ |
37 | 37 | ||
38 | static void ak4114_stats(struct work_struct *work); | 38 | static void ak4114_stats(struct work_struct *work); |
39 | static void ak4114_init_regs(struct ak4114 *chip); | ||
39 | 40 | ||
40 | static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char val) | 41 | static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char val) |
41 | { | 42 | { |
@@ -105,7 +106,7 @@ int snd_ak4114_create(struct snd_card *card, | |||
105 | for (reg = 0; reg < 5; reg++) | 106 | for (reg = 0; reg < 5; reg++) |
106 | chip->txcsb[reg] = txcsb[reg]; | 107 | chip->txcsb[reg] = txcsb[reg]; |
107 | 108 | ||
108 | snd_ak4114_reinit(chip); | 109 | ak4114_init_regs(chip); |
109 | 110 | ||
110 | chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT); | 111 | chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT); |
111 | chip->rcs1 = reg_read(chip, AK4114_REG_RCS1); | 112 | chip->rcs1 = reg_read(chip, AK4114_REG_RCS1); |
@@ -131,13 +132,10 @@ void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char | |||
131 | (chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val); | 132 | (chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val); |
132 | } | 133 | } |
133 | 134 | ||
134 | void snd_ak4114_reinit(struct ak4114 *chip) | 135 | static void ak4114_init_regs(struct ak4114 *chip) |
135 | { | 136 | { |
136 | unsigned char old = chip->regmap[AK4114_REG_PWRDN], reg; | 137 | unsigned char old = chip->regmap[AK4114_REG_PWRDN], reg; |
137 | 138 | ||
138 | chip->init = 1; | ||
139 | mb(); | ||
140 | flush_scheduled_work(); | ||
141 | /* bring the chip to reset state and powerdown state */ | 139 | /* bring the chip to reset state and powerdown state */ |
142 | reg_write(chip, AK4114_REG_PWRDN, old & ~(AK4114_RST|AK4114_PWN)); | 140 | reg_write(chip, AK4114_REG_PWRDN, old & ~(AK4114_RST|AK4114_PWN)); |
143 | udelay(200); | 141 | udelay(200); |
@@ -150,9 +148,18 @@ void snd_ak4114_reinit(struct ak4114 *chip) | |||
150 | reg_write(chip, reg + AK4114_REG_TXCSB0, chip->txcsb[reg]); | 148 | reg_write(chip, reg + AK4114_REG_TXCSB0, chip->txcsb[reg]); |
151 | /* release powerdown, everything is initialized now */ | 149 | /* release powerdown, everything is initialized now */ |
152 | reg_write(chip, AK4114_REG_PWRDN, old | AK4114_RST | AK4114_PWN); | 150 | reg_write(chip, AK4114_REG_PWRDN, old | AK4114_RST | AK4114_PWN); |
151 | } | ||
152 | |||
153 | void snd_ak4114_reinit(struct ak4114 *chip) | ||
154 | { | ||
155 | chip->init = 1; | ||
156 | mb(); | ||
157 | flush_scheduled_work(); | ||
158 | ak4114_init_regs(chip); | ||
153 | /* bring up statistics / event queing */ | 159 | /* bring up statistics / event queing */ |
154 | chip->init = 0; | 160 | chip->init = 0; |
155 | schedule_delayed_work(&chip->work, HZ / 10); | 161 | if (chip->kctls[0]) |
162 | schedule_delayed_work(&chip->work, HZ / 10); | ||
156 | } | 163 | } |
157 | 164 | ||
158 | static unsigned int external_rate(unsigned char rcs1) | 165 | static unsigned int external_rate(unsigned char rcs1) |
@@ -428,7 +435,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { | |||
428 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 435 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
429 | .info = snd_ak4114_in_bit_info, | 436 | .info = snd_ak4114_in_bit_info, |
430 | .get = snd_ak4114_in_bit_get, | 437 | .get = snd_ak4114_in_bit_get, |
431 | .private_value = (6<<8) | AK4114_REG_RCS1, | 438 | .private_value = (6<<8) | AK4114_REG_RCS0, |
432 | }, | 439 | }, |
433 | { | 440 | { |
434 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 441 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -436,7 +443,15 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { | |||
436 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 443 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
437 | .info = snd_ak4114_in_bit_info, | 444 | .info = snd_ak4114_in_bit_info, |
438 | .get = snd_ak4114_in_bit_get, | 445 | .get = snd_ak4114_in_bit_get, |
439 | .private_value = (3<<8) | AK4114_REG_RCS1, | 446 | .private_value = (3<<8) | AK4114_REG_RCS0, |
447 | }, | ||
448 | { | ||
449 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
450 | .name = "IEC958 PPL Lock Status", | ||
451 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
452 | .info = snd_ak4114_in_bit_info, | ||
453 | .get = snd_ak4114_in_bit_get, | ||
454 | .private_value = (1<<31) | (4<<8) | AK4114_REG_RCS0, | ||
440 | } | 455 | } |
441 | }; | 456 | }; |
442 | 457 | ||
@@ -455,7 +470,7 @@ int snd_ak4114_build(struct ak4114 *ak4114, | |||
455 | kctl = snd_ctl_new1(&snd_ak4114_iec958_controls[idx], ak4114); | 470 | kctl = snd_ctl_new1(&snd_ak4114_iec958_controls[idx], ak4114); |
456 | if (kctl == NULL) | 471 | if (kctl == NULL) |
457 | return -ENOMEM; | 472 | return -ENOMEM; |
458 | if (!strstr(kctl->id.name, "Playback")) { | 473 | if (strstr(kctl->id.name, "Playback")) { |
459 | if (ply_substream == NULL) { | 474 | if (ply_substream == NULL) { |
460 | snd_ctl_free_one(kctl); | 475 | snd_ctl_free_one(kctl); |
461 | ak4114->kctls[idx] = NULL; | 476 | ak4114->kctls[idx] = NULL; |
@@ -472,9 +487,58 @@ int snd_ak4114_build(struct ak4114 *ak4114, | |||
472 | return err; | 487 | return err; |
473 | ak4114->kctls[idx] = kctl; | 488 | ak4114->kctls[idx] = kctl; |
474 | } | 489 | } |
490 | /* trigger workq */ | ||
491 | schedule_delayed_work(&ak4114->work, HZ / 10); | ||
475 | return 0; | 492 | return 0; |
476 | } | 493 | } |
477 | 494 | ||
495 | /* notify kcontrols if any parameters are changed */ | ||
496 | static void ak4114_notify(struct ak4114 *ak4114, | ||
497 | unsigned char rcs0, unsigned char rcs1, | ||
498 | unsigned char c0, unsigned char c1) | ||
499 | { | ||
500 | if (!ak4114->kctls[0]) | ||
501 | return; | ||
502 | |||
503 | if (rcs0 & AK4114_PAR) | ||
504 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
505 | &ak4114->kctls[0]->id); | ||
506 | if (rcs0 & AK4114_V) | ||
507 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
508 | &ak4114->kctls[1]->id); | ||
509 | if (rcs1 & AK4114_CCRC) | ||
510 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
511 | &ak4114->kctls[2]->id); | ||
512 | if (rcs1 & AK4114_QCRC) | ||
513 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
514 | &ak4114->kctls[3]->id); | ||
515 | |||
516 | /* rate change */ | ||
517 | if (c1 & 0xf0) | ||
518 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
519 | &ak4114->kctls[4]->id); | ||
520 | |||
521 | if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT)) | ||
522 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
523 | &ak4114->kctls[9]->id); | ||
524 | if (c0 & AK4114_QINT) | ||
525 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
526 | &ak4114->kctls[10]->id); | ||
527 | |||
528 | if (c0 & AK4114_AUDION) | ||
529 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
530 | &ak4114->kctls[11]->id); | ||
531 | if (c0 & AK4114_AUTO) | ||
532 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
533 | &ak4114->kctls[12]->id); | ||
534 | if (c0 & AK4114_DTSCD) | ||
535 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
536 | &ak4114->kctls[13]->id); | ||
537 | if (c0 & AK4114_UNLCK) | ||
538 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
539 | &ak4114->kctls[14]->id); | ||
540 | } | ||
541 | |||
478 | int snd_ak4114_external_rate(struct ak4114 *ak4114) | 542 | int snd_ak4114_external_rate(struct ak4114 *ak4114) |
479 | { | 543 | { |
480 | unsigned char rcs1; | 544 | unsigned char rcs1; |
@@ -511,31 +575,7 @@ int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags) | |||
511 | ak4114->rcs1 = rcs1; | 575 | ak4114->rcs1 = rcs1; |
512 | spin_unlock_irqrestore(&ak4114->lock, _flags); | 576 | spin_unlock_irqrestore(&ak4114->lock, _flags); |
513 | 577 | ||
514 | if (rcs0 & AK4114_PAR) | 578 | ak4114_notify(ak4114, rcs0, rcs1, c0, c1); |
515 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[0]->id); | ||
516 | if (rcs0 & AK4114_V) | ||
517 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[1]->id); | ||
518 | if (rcs1 & AK4114_CCRC) | ||
519 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[2]->id); | ||
520 | if (rcs1 & AK4114_QCRC) | ||
521 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[3]->id); | ||
522 | |||
523 | /* rate change */ | ||
524 | if (c1 & 0xf0) | ||
525 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[4]->id); | ||
526 | |||
527 | if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT)) | ||
528 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[9]->id); | ||
529 | if (c0 & AK4114_QINT) | ||
530 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[10]->id); | ||
531 | |||
532 | if (c0 & AK4114_AUDION) | ||
533 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[11]->id); | ||
534 | if (c0 & AK4114_AUTO) | ||
535 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[12]->id); | ||
536 | if (c0 & AK4114_DTSCD) | ||
537 | snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[13]->id); | ||
538 | |||
539 | if (ak4114->change_callback && (c0 | c1) != 0) | 579 | if (ak4114->change_callback && (c0 | c1) != 0) |
540 | ak4114->change_callback(ak4114, c0, c1); | 580 | ak4114->change_callback(ak4114, c0, c1); |
541 | 581 | ||
@@ -558,9 +598,9 @@ static void ak4114_stats(struct work_struct *work) | |||
558 | { | 598 | { |
559 | struct ak4114 *chip = container_of(work, struct ak4114, work.work); | 599 | struct ak4114 *chip = container_of(work, struct ak4114, work.work); |
560 | 600 | ||
561 | if (chip->init) | 601 | if (!chip->init) |
562 | return; | 602 | snd_ak4114_check_rate_and_errors(chip, 0); |
563 | snd_ak4114_check_rate_and_errors(chip, 0); | 603 | |
564 | schedule_delayed_work(&chip->work, HZ / 10); | 604 | schedule_delayed_work(&chip->work, HZ / 10); |
565 | } | 605 | } |
566 | 606 | ||
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 4e3a9729f569..cf3803cd579c 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig | |||
@@ -358,12 +358,21 @@ config SND_SBAWE | |||
358 | config SND_SB16_CSP | 358 | config SND_SB16_CSP |
359 | bool "Sound Blaster 16/AWE CSP support" | 359 | bool "Sound Blaster 16/AWE CSP support" |
360 | depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC) | 360 | depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC) |
361 | select FW_LOADER | 361 | select FW_LOADER if !SND_SB16_CSP_FIRMWARE_IN_KERNEL |
362 | help | 362 | help |
363 | Say Y here to include support for the CSP core. This special | 363 | Say Y here to include support for the CSP core. This special |
364 | coprocessor can do variable tasks like various compression and | 364 | coprocessor can do variable tasks like various compression and |
365 | decompression algorithms. | 365 | decompression algorithms. |
366 | 366 | ||
367 | config SND_SB16_CSP_FIRMWARE_IN_KERNEL | ||
368 | bool "In-kernel firmware for SB16 CSP" | ||
369 | depends on SND_SB16_CSP | ||
370 | default y | ||
371 | help | ||
372 | Say Y here to include the static firmware built in the kernel | ||
373 | for the SB16 CSP controller. If you choose N here, you need | ||
374 | to install the firmware files from the alsa-firmware package. | ||
375 | |||
367 | config SND_SGALAXY | 376 | config SND_SGALAXY |
368 | tristate "Aztech Sound Galaxy" | 377 | tristate "Aztech Sound Galaxy" |
369 | depends on SND | 378 | depends on SND |
@@ -391,7 +400,7 @@ config SND_SSCAPE | |||
391 | config SND_WAVEFRONT | 400 | config SND_WAVEFRONT |
392 | tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)" | 401 | tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)" |
393 | depends on SND | 402 | depends on SND |
394 | select FW_LOADER | 403 | select FW_LOADER if !SND_WAVEFRONT_FIRMWARE_IN_KERNEL |
395 | select SND_OPL3_LIB | 404 | select SND_OPL3_LIB |
396 | select SND_MPU401_UART | 405 | select SND_MPU401_UART |
397 | select SND_CS4231_LIB | 406 | select SND_CS4231_LIB |
@@ -402,4 +411,13 @@ config SND_WAVEFRONT | |||
402 | To compile this driver as a module, choose M here: the module | 411 | To compile this driver as a module, choose M here: the module |
403 | will be called snd-wavefront. | 412 | will be called snd-wavefront. |
404 | 413 | ||
414 | config SND_WAVEFRONT_FIRMWARE_IN_KERNEL | ||
415 | bool "In-kernel firmware for Wavefront" | ||
416 | depends on SND_WAVEFRONT | ||
417 | default y | ||
418 | help | ||
419 | Say Y here to include the static firmware built in the kernel | ||
420 | for the Wavefront driver. If you choose N here, you need to | ||
421 | install the firmware files from the alsa-firmware package. | ||
422 | |||
405 | endmenu | 423 | endmenu |
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index 59034507175b..fc88a31da6f5 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c | |||
@@ -129,8 +129,8 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar | |||
129 | } | 129 | } |
130 | acard->devmpu = pnp_request_card_device(card, id->devs[1].id, NULL); | 130 | acard->devmpu = pnp_request_card_device(card, id->devs[1].id, NULL); |
131 | if (acard->devmpu == NULL) { | 131 | if (acard->devmpu == NULL) { |
132 | kfree(cfg); | 132 | mpu_port[dev] = -1; |
133 | return -EBUSY; | 133 | snd_printk(KERN_WARNING PFX "MPU401 device busy, skipping.\n"); |
134 | } | 134 | } |
135 | 135 | ||
136 | pdev = acard->dev; | 136 | pdev = acard->dev; |
@@ -162,6 +162,10 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar | |||
162 | dma2[dev] = pnp_dma(pdev, 1); | 162 | dma2[dev] = pnp_dma(pdev, 1); |
163 | irq[dev] = pnp_irq(pdev, 0); | 163 | irq[dev] = pnp_irq(pdev, 0); |
164 | 164 | ||
165 | if (acard->devmpu == NULL) { | ||
166 | kfree(cfg); | ||
167 | return 0; | ||
168 | } | ||
165 | pdev = acard->devmpu; | 169 | pdev = acard->devmpu; |
166 | pnp_init_resource_table(cfg); | 170 | pnp_init_resource_table(cfg); |
167 | 171 | ||
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index 74e501dea8b1..d09a7fa86545 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <sound/driver.h> | 24 | #include <sound/driver.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/isa.h> |
28 | #include <linux/time.h> | 28 | #include <linux/time.h> |
29 | #include <linux/wait.h> | 29 | #include <linux/wait.h> |
30 | #include <linux/moduleparam.h> | 30 | #include <linux/moduleparam.h> |
@@ -32,8 +32,11 @@ | |||
32 | #include <sound/ad1848.h> | 32 | #include <sound/ad1848.h> |
33 | #include <sound/initval.h> | 33 | #include <sound/initval.h> |
34 | 34 | ||
35 | #define CRD_NAME "Generic AD1848/AD1847/CS4248" | ||
36 | #define DEV_NAME "ad1848" | ||
37 | |||
38 | MODULE_DESCRIPTION(CRD_NAME); | ||
35 | MODULE_AUTHOR("Tugrul Galatali <galatalt@stuy.edu>, Jaroslav Kysela <perex@suse.cz>"); | 39 | MODULE_AUTHOR("Tugrul Galatali <galatalt@stuy.edu>, Jaroslav Kysela <perex@suse.cz>"); |
36 | MODULE_DESCRIPTION("AD1848/AD1847/CS4248"); | ||
37 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
38 | MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1848}," | 41 | MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1848}," |
39 | "{Analog Devices,AD1847}," | 42 | "{Analog Devices,AD1847}," |
@@ -48,95 +51,98 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ | |||
48 | static int thinkpad[SNDRV_CARDS]; /* Thinkpad special case */ | 51 | static int thinkpad[SNDRV_CARDS]; /* Thinkpad special case */ |
49 | 52 | ||
50 | module_param_array(index, int, NULL, 0444); | 53 | module_param_array(index, int, NULL, 0444); |
51 | MODULE_PARM_DESC(index, "Index value for AD1848 soundcard."); | 54 | MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); |
52 | module_param_array(id, charp, NULL, 0444); | 55 | module_param_array(id, charp, NULL, 0444); |
53 | MODULE_PARM_DESC(id, "ID string for AD1848 soundcard."); | 56 | MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); |
54 | module_param_array(enable, bool, NULL, 0444); | 57 | module_param_array(enable, bool, NULL, 0444); |
55 | MODULE_PARM_DESC(enable, "Enable AD1848 soundcard."); | 58 | MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); |
56 | module_param_array(port, long, NULL, 0444); | 59 | module_param_array(port, long, NULL, 0444); |
57 | MODULE_PARM_DESC(port, "Port # for AD1848 driver."); | 60 | MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); |
58 | module_param_array(irq, int, NULL, 0444); | 61 | module_param_array(irq, int, NULL, 0444); |
59 | MODULE_PARM_DESC(irq, "IRQ # for AD1848 driver."); | 62 | MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); |
60 | module_param_array(dma1, int, NULL, 0444); | 63 | module_param_array(dma1, int, NULL, 0444); |
61 | MODULE_PARM_DESC(dma1, "DMA1 # for AD1848 driver."); | 64 | MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver."); |
62 | module_param_array(thinkpad, bool, NULL, 0444); | 65 | module_param_array(thinkpad, bool, NULL, 0444); |
63 | MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series."); | 66 | MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series."); |
64 | 67 | ||
65 | static struct platform_device *devices[SNDRV_CARDS]; | 68 | static int __devinit snd_ad1848_match(struct device *dev, unsigned int n) |
69 | { | ||
70 | if (!enable[n]) | ||
71 | return 0; | ||
66 | 72 | ||
73 | if (port[n] == SNDRV_AUTO_PORT) { | ||
74 | snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id); | ||
75 | return 0; | ||
76 | } | ||
77 | if (irq[n] == SNDRV_AUTO_IRQ) { | ||
78 | snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id); | ||
79 | return 0; | ||
80 | } | ||
81 | if (dma1[n] == SNDRV_AUTO_DMA) { | ||
82 | snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id); | ||
83 | return 0; | ||
84 | } | ||
85 | return 1; | ||
86 | } | ||
67 | 87 | ||
68 | static int __devinit snd_ad1848_probe(struct platform_device *pdev) | 88 | static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n) |
69 | { | 89 | { |
70 | int dev = pdev->id; | ||
71 | struct snd_card *card; | 90 | struct snd_card *card; |
72 | struct snd_ad1848 *chip; | 91 | struct snd_ad1848 *chip; |
73 | struct snd_pcm *pcm; | 92 | struct snd_pcm *pcm; |
74 | int err; | 93 | int error; |
75 | 94 | ||
76 | if (port[dev] == SNDRV_AUTO_PORT) { | 95 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); |
77 | snd_printk(KERN_ERR "ad1848: specify port\n"); | 96 | if (!card) |
78 | return -EINVAL; | 97 | return -EINVAL; |
79 | } | ||
80 | if (irq[dev] == SNDRV_AUTO_IRQ) { | ||
81 | snd_printk(KERN_ERR "ad1848: specify irq\n"); | ||
82 | return -EINVAL; | ||
83 | } | ||
84 | if (dma1[dev] == SNDRV_AUTO_DMA) { | ||
85 | snd_printk(KERN_ERR "ad1848: specify dma1\n"); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | 98 | ||
89 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 99 | error = snd_ad1848_create(card, port[n], irq[n], dma1[n], |
90 | if (card == NULL) | 100 | thinkpad[n] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, &chip); |
91 | return -ENOMEM; | 101 | if (error < 0) |
102 | goto out; | ||
92 | 103 | ||
93 | if ((err = snd_ad1848_create(card, port[dev], | ||
94 | irq[dev], | ||
95 | dma1[dev], | ||
96 | thinkpad[dev] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, | ||
97 | &chip)) < 0) | ||
98 | goto _err; | ||
99 | card->private_data = chip; | 104 | card->private_data = chip; |
100 | 105 | ||
101 | if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0) | 106 | error = snd_ad1848_pcm(chip, 0, &pcm); |
102 | goto _err; | 107 | if (error < 0) |
108 | goto out; | ||
103 | 109 | ||
104 | if ((err = snd_ad1848_mixer(chip)) < 0) | 110 | error = snd_ad1848_mixer(chip); |
105 | goto _err; | 111 | if (error < 0) |
112 | goto out; | ||
106 | 113 | ||
107 | strcpy(card->driver, "AD1848"); | 114 | strcpy(card->driver, "AD1848"); |
108 | strcpy(card->shortname, pcm->name); | 115 | strcpy(card->shortname, pcm->name); |
109 | 116 | ||
110 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", | 117 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", |
111 | pcm->name, chip->port, irq[dev], dma1[dev]); | 118 | pcm->name, chip->port, irq[n], dma1[n]); |
112 | 119 | if (thinkpad[n]) | |
113 | if (thinkpad[dev]) | ||
114 | strcat(card->longname, " [Thinkpad]"); | 120 | strcat(card->longname, " [Thinkpad]"); |
115 | 121 | ||
116 | snd_card_set_dev(card, &pdev->dev); | 122 | snd_card_set_dev(card, dev); |
117 | 123 | ||
118 | if ((err = snd_card_register(card)) < 0) | 124 | error = snd_card_register(card); |
119 | goto _err; | 125 | if (error < 0) |
126 | goto out; | ||
120 | 127 | ||
121 | platform_set_drvdata(pdev, card); | 128 | dev_set_drvdata(dev, card); |
122 | return 0; | 129 | return 0; |
123 | 130 | ||
124 | _err: | 131 | out: snd_card_free(card); |
125 | snd_card_free(card); | 132 | return error; |
126 | return err; | ||
127 | } | 133 | } |
128 | 134 | ||
129 | static int __devexit snd_ad1848_remove(struct platform_device *devptr) | 135 | static int __devexit snd_ad1848_remove(struct device *dev, unsigned int n) |
130 | { | 136 | { |
131 | snd_card_free(platform_get_drvdata(devptr)); | 137 | snd_card_free(dev_get_drvdata(dev)); |
132 | platform_set_drvdata(devptr, NULL); | 138 | dev_set_drvdata(dev, NULL); |
133 | return 0; | 139 | return 0; |
134 | } | 140 | } |
135 | 141 | ||
136 | #ifdef CONFIG_PM | 142 | #ifdef CONFIG_PM |
137 | static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state) | 143 | static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t state) |
138 | { | 144 | { |
139 | struct snd_card *card = platform_get_drvdata(pdev); | 145 | struct snd_card *card = dev_get_drvdata(dev); |
140 | struct snd_ad1848 *chip = card->private_data; | 146 | struct snd_ad1848 *chip = card->private_data; |
141 | 147 | ||
142 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 148 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
@@ -144,9 +150,9 @@ static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state) | |||
144 | return 0; | 150 | return 0; |
145 | } | 151 | } |
146 | 152 | ||
147 | static int snd_ad1848_resume(struct platform_device *pdev) | 153 | static int snd_ad1848_resume(struct device *dev, unsigned int n) |
148 | { | 154 | { |
149 | struct snd_card *card = platform_get_drvdata(pdev); | 155 | struct snd_card *card = dev_get_drvdata(dev); |
150 | struct snd_ad1848 *chip = card->private_data; | 156 | struct snd_ad1848 *chip = card->private_data; |
151 | 157 | ||
152 | chip->resume(chip); | 158 | chip->resume(chip); |
@@ -155,9 +161,8 @@ static int snd_ad1848_resume(struct platform_device *pdev) | |||
155 | } | 161 | } |
156 | #endif | 162 | #endif |
157 | 163 | ||
158 | #define SND_AD1848_DRIVER "snd_ad1848" | 164 | static struct isa_driver snd_ad1848_driver = { |
159 | 165 | .match = snd_ad1848_match, | |
160 | static struct platform_driver snd_ad1848_driver = { | ||
161 | .probe = snd_ad1848_probe, | 166 | .probe = snd_ad1848_probe, |
162 | .remove = __devexit_p(snd_ad1848_remove), | 167 | .remove = __devexit_p(snd_ad1848_remove), |
163 | #ifdef CONFIG_PM | 168 | #ifdef CONFIG_PM |
@@ -165,57 +170,19 @@ static struct platform_driver snd_ad1848_driver = { | |||
165 | .resume = snd_ad1848_resume, | 170 | .resume = snd_ad1848_resume, |
166 | #endif | 171 | #endif |
167 | .driver = { | 172 | .driver = { |
168 | .name = SND_AD1848_DRIVER | 173 | .name = DEV_NAME |
169 | }, | 174 | } |
170 | }; | 175 | }; |
171 | 176 | ||
172 | static void __init_or_module snd_ad1848_unregister_all(void) | ||
173 | { | ||
174 | int i; | ||
175 | |||
176 | for (i = 0; i < ARRAY_SIZE(devices); ++i) | ||
177 | platform_device_unregister(devices[i]); | ||
178 | platform_driver_unregister(&snd_ad1848_driver); | ||
179 | } | ||
180 | |||
181 | static int __init alsa_card_ad1848_init(void) | 177 | static int __init alsa_card_ad1848_init(void) |
182 | { | 178 | { |
183 | int i, cards, err; | 179 | return isa_register_driver(&snd_ad1848_driver, SNDRV_CARDS); |
184 | |||
185 | err = platform_driver_register(&snd_ad1848_driver); | ||
186 | if (err < 0) | ||
187 | return err; | ||
188 | |||
189 | cards = 0; | ||
190 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
191 | struct platform_device *device; | ||
192 | if (! enable[i]) | ||
193 | continue; | ||
194 | device = platform_device_register_simple(SND_AD1848_DRIVER, | ||
195 | i, NULL, 0); | ||
196 | if (IS_ERR(device)) | ||
197 | continue; | ||
198 | if (!platform_get_drvdata(device)) { | ||
199 | platform_device_unregister(device); | ||
200 | continue; | ||
201 | } | ||
202 | devices[i] = device; | ||
203 | cards++; | ||
204 | } | ||
205 | if (!cards) { | ||
206 | #ifdef MODULE | ||
207 | printk(KERN_ERR "AD1848 soundcard not found or device busy\n"); | ||
208 | #endif | ||
209 | snd_ad1848_unregister_all(); | ||
210 | return -ENODEV; | ||
211 | } | ||
212 | return 0; | ||
213 | } | 180 | } |
214 | 181 | ||
215 | static void __exit alsa_card_ad1848_exit(void) | 182 | static void __exit alsa_card_ad1848_exit(void) |
216 | { | 183 | { |
217 | snd_ad1848_unregister_all(); | 184 | isa_unregister_driver(&snd_ad1848_driver); |
218 | } | 185 | } |
219 | 186 | ||
220 | module_init(alsa_card_ad1848_init) | 187 | module_init(alsa_card_ad1848_init); |
221 | module_exit(alsa_card_ad1848_exit) | 188 | module_exit(alsa_card_ad1848_exit); |
diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c index 1124344ed948..d68720724c91 100644 --- a/sound/isa/adlib.c +++ b/sound/isa/adlib.c | |||
@@ -5,13 +5,13 @@ | |||
5 | #include <sound/driver.h> | 5 | #include <sound/driver.h> |
6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/platform_device.h> | 8 | #include <linux/isa.h> |
9 | #include <sound/core.h> | 9 | #include <sound/core.h> |
10 | #include <sound/initval.h> | 10 | #include <sound/initval.h> |
11 | #include <sound/opl3.h> | 11 | #include <sound/opl3.h> |
12 | 12 | ||
13 | #define CRD_NAME "AdLib FM" | 13 | #define CRD_NAME "AdLib FM" |
14 | #define DRV_NAME "snd_adlib" | 14 | #define DEV_NAME "adlib" |
15 | 15 | ||
16 | MODULE_DESCRIPTION(CRD_NAME); | 16 | MODULE_DESCRIPTION(CRD_NAME); |
17 | MODULE_AUTHOR("Rene Herman"); | 17 | MODULE_AUTHOR("Rene Herman"); |
@@ -31,133 +31,99 @@ MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); | |||
31 | module_param_array(port, long, NULL, 0444); | 31 | module_param_array(port, long, NULL, 0444); |
32 | MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); | 32 | MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); |
33 | 33 | ||
34 | static struct platform_device *devices[SNDRV_CARDS]; | 34 | static int __devinit snd_adlib_match(struct device *dev, unsigned int n) |
35 | { | ||
36 | if (!enable[n]) | ||
37 | return 0; | ||
38 | |||
39 | if (port[n] == SNDRV_AUTO_PORT) { | ||
40 | snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id); | ||
41 | return 0; | ||
42 | } | ||
43 | return 1; | ||
44 | } | ||
35 | 45 | ||
36 | static void snd_adlib_free(struct snd_card *card) | 46 | static void snd_adlib_free(struct snd_card *card) |
37 | { | 47 | { |
38 | release_and_free_resource(card->private_data); | 48 | release_and_free_resource(card->private_data); |
39 | } | 49 | } |
40 | 50 | ||
41 | static int __devinit snd_adlib_probe(struct platform_device *device) | 51 | static int __devinit snd_adlib_probe(struct device *dev, unsigned int n) |
42 | { | 52 | { |
43 | struct snd_card *card; | 53 | struct snd_card *card; |
44 | struct snd_opl3 *opl3; | 54 | struct snd_opl3 *opl3; |
55 | int error; | ||
45 | 56 | ||
46 | int error, i = device->id; | 57 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); |
47 | |||
48 | if (port[i] == SNDRV_AUTO_PORT) { | ||
49 | snd_printk(KERN_ERR DRV_NAME ": please specify port\n"); | ||
50 | error = -EINVAL; | ||
51 | goto out0; | ||
52 | } | ||
53 | |||
54 | card = snd_card_new(index[i], id[i], THIS_MODULE, 0); | ||
55 | if (!card) { | 58 | if (!card) { |
56 | snd_printk(KERN_ERR DRV_NAME ": could not create card\n"); | 59 | snd_printk(KERN_ERR "%s: could not create card\n", dev->bus_id); |
57 | error = -EINVAL; | 60 | return -EINVAL; |
58 | goto out0; | ||
59 | } | 61 | } |
60 | 62 | ||
61 | card->private_data = request_region(port[i], 4, CRD_NAME); | 63 | card->private_data = request_region(port[n], 4, CRD_NAME); |
62 | if (!card->private_data) { | 64 | if (!card->private_data) { |
63 | snd_printk(KERN_ERR DRV_NAME ": could not grab ports\n"); | 65 | snd_printk(KERN_ERR "%s: could not grab ports\n", dev->bus_id); |
64 | error = -EBUSY; | 66 | error = -EBUSY; |
65 | goto out1; | 67 | goto out; |
66 | } | 68 | } |
67 | card->private_free = snd_adlib_free; | 69 | card->private_free = snd_adlib_free; |
68 | 70 | ||
69 | error = snd_opl3_create(card, port[i], port[i] + 2, OPL3_HW_AUTO, 1, &opl3); | 71 | strcpy(card->driver, DEV_NAME); |
72 | strcpy(card->shortname, CRD_NAME); | ||
73 | sprintf(card->longname, CRD_NAME " at %#lx", port[n]); | ||
74 | |||
75 | error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3); | ||
70 | if (error < 0) { | 76 | if (error < 0) { |
71 | snd_printk(KERN_ERR DRV_NAME ": could not create OPL\n"); | 77 | snd_printk(KERN_ERR "%s: could not create OPL\n", dev->bus_id); |
72 | goto out1; | 78 | goto out; |
73 | } | 79 | } |
74 | 80 | ||
75 | error = snd_opl3_hwdep_new(opl3, 0, 0, NULL); | 81 | error = snd_opl3_hwdep_new(opl3, 0, 0, NULL); |
76 | if (error < 0) { | 82 | if (error < 0) { |
77 | snd_printk(KERN_ERR DRV_NAME ": could not create FM\n"); | 83 | snd_printk(KERN_ERR "%s: could not create FM\n", dev->bus_id); |
78 | goto out1; | 84 | goto out; |
79 | } | 85 | } |
80 | 86 | ||
81 | strcpy(card->driver, DRV_NAME); | 87 | snd_card_set_dev(card, dev); |
82 | strcpy(card->shortname, CRD_NAME); | ||
83 | sprintf(card->longname, CRD_NAME " at %#lx", port[i]); | ||
84 | |||
85 | snd_card_set_dev(card, &device->dev); | ||
86 | 88 | ||
87 | error = snd_card_register(card); | 89 | error = snd_card_register(card); |
88 | if (error < 0) { | 90 | if (error < 0) { |
89 | snd_printk(KERN_ERR DRV_NAME ": could not register card\n"); | 91 | snd_printk(KERN_ERR "%s: could not register card\n", dev->bus_id); |
90 | goto out1; | 92 | goto out; |
91 | } | 93 | } |
92 | 94 | ||
93 | platform_set_drvdata(device, card); | 95 | dev_set_drvdata(dev, card); |
94 | return 0; | 96 | return 0; |
95 | 97 | ||
96 | out1: snd_card_free(card); | 98 | out: snd_card_free(card); |
97 | out0: return error; | 99 | return error; |
98 | } | 100 | } |
99 | 101 | ||
100 | static int __devexit snd_adlib_remove(struct platform_device *device) | 102 | static int __devexit snd_adlib_remove(struct device *dev, unsigned int n) |
101 | { | 103 | { |
102 | snd_card_free(platform_get_drvdata(device)); | 104 | snd_card_free(dev_get_drvdata(dev)); |
103 | platform_set_drvdata(device, NULL); | 105 | dev_set_drvdata(dev, NULL); |
104 | return 0; | 106 | return 0; |
105 | } | 107 | } |
106 | 108 | ||
107 | static struct platform_driver snd_adlib_driver = { | 109 | static struct isa_driver snd_adlib_driver = { |
110 | .match = snd_adlib_match, | ||
108 | .probe = snd_adlib_probe, | 111 | .probe = snd_adlib_probe, |
109 | .remove = __devexit_p(snd_adlib_remove), | 112 | .remove = __devexit_p(snd_adlib_remove), |
110 | 113 | ||
111 | .driver = { | 114 | .driver = { |
112 | .name = DRV_NAME | 115 | .name = DEV_NAME |
113 | } | 116 | } |
114 | }; | 117 | }; |
115 | 118 | ||
116 | static int __init alsa_card_adlib_init(void) | 119 | static int __init alsa_card_adlib_init(void) |
117 | { | 120 | { |
118 | int i, cards; | 121 | return isa_register_driver(&snd_adlib_driver, SNDRV_CARDS); |
119 | |||
120 | if (platform_driver_register(&snd_adlib_driver) < 0) { | ||
121 | snd_printk(KERN_ERR DRV_NAME ": could not register driver\n"); | ||
122 | return -ENODEV; | ||
123 | } | ||
124 | |||
125 | for (cards = 0, i = 0; i < SNDRV_CARDS; i++) { | ||
126 | struct platform_device *device; | ||
127 | |||
128 | if (!enable[i]) | ||
129 | continue; | ||
130 | |||
131 | device = platform_device_register_simple(DRV_NAME, i, NULL, 0); | ||
132 | if (IS_ERR(device)) | ||
133 | continue; | ||
134 | |||
135 | if (!platform_get_drvdata(device)) { | ||
136 | platform_device_unregister(device); | ||
137 | continue; | ||
138 | } | ||
139 | |||
140 | devices[i] = device; | ||
141 | cards++; | ||
142 | } | ||
143 | |||
144 | if (!cards) { | ||
145 | #ifdef MODULE | ||
146 | printk(KERN_ERR CRD_NAME " soundcard not found or device busy\n"); | ||
147 | #endif | ||
148 | platform_driver_unregister(&snd_adlib_driver); | ||
149 | return -ENODEV; | ||
150 | } | ||
151 | return 0; | ||
152 | } | 122 | } |
153 | 123 | ||
154 | static void __exit alsa_card_adlib_exit(void) | 124 | static void __exit alsa_card_adlib_exit(void) |
155 | { | 125 | { |
156 | int i; | 126 | isa_unregister_driver(&snd_adlib_driver); |
157 | |||
158 | for (i = 0; i < SNDRV_CARDS; i++) | ||
159 | platform_device_unregister(devices[i]); | ||
160 | platform_driver_unregister(&snd_adlib_driver); | ||
161 | } | 127 | } |
162 | 128 | ||
163 | module_init(alsa_card_adlib_init); | 129 | module_init(alsa_card_adlib_init); |
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index c09a8009d2fa..214d65d94c45 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include <sound/driver.h> | 46 | #include <sound/driver.h> |
47 | #include <linux/init.h> | 47 | #include <linux/init.h> |
48 | #include <linux/err.h> | 48 | #include <linux/err.h> |
49 | #include <linux/platform_device.h> | 49 | #include <linux/isa.h> |
50 | #include <linux/slab.h> | 50 | #include <linux/slab.h> |
51 | #include <linux/pnp.h> | 51 | #include <linux/pnp.h> |
52 | #include <linux/moduleparam.h> | 52 | #include <linux/moduleparam.h> |
@@ -108,7 +108,6 @@ MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver."); | |||
108 | module_param_array(wssdma, int, NULL, 0444); | 108 | module_param_array(wssdma, int, NULL, 0444); |
109 | MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver."); | 109 | MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver."); |
110 | 110 | ||
111 | static struct platform_device *platform_devices[SNDRV_CARDS]; | ||
112 | #ifdef CONFIG_PNP | 111 | #ifdef CONFIG_PNP |
113 | static int pnp_registered; | 112 | static int pnp_registered; |
114 | #endif | 113 | #endif |
@@ -547,70 +546,78 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) | |||
547 | return snd_card_register(card); | 546 | return snd_card_register(card); |
548 | } | 547 | } |
549 | 548 | ||
550 | static int __devinit snd_cmi8330_nonpnp_probe(struct platform_device *pdev) | 549 | static int __devinit snd_cmi8330_isa_match(struct device *pdev, |
550 | unsigned int dev) | ||
551 | { | 551 | { |
552 | struct snd_card *card; | 552 | if (!enable[dev] || is_isapnp_selected(dev)) |
553 | int err; | 553 | return 0; |
554 | int dev = pdev->id; | ||
555 | |||
556 | if (wssport[dev] == SNDRV_AUTO_PORT) { | 554 | if (wssport[dev] == SNDRV_AUTO_PORT) { |
557 | snd_printk(KERN_ERR PFX "specify wssport\n"); | 555 | snd_printk(KERN_ERR PFX "specify wssport\n"); |
558 | return -EINVAL; | 556 | return 0; |
559 | } | 557 | } |
560 | if (sbport[dev] == SNDRV_AUTO_PORT) { | 558 | if (sbport[dev] == SNDRV_AUTO_PORT) { |
561 | snd_printk(KERN_ERR PFX "specify sbport\n"); | 559 | snd_printk(KERN_ERR PFX "specify sbport\n"); |
562 | return -EINVAL; | 560 | return 0; |
563 | } | 561 | } |
562 | return 1; | ||
563 | } | ||
564 | |||
565 | static int __devinit snd_cmi8330_isa_probe(struct device *pdev, | ||
566 | unsigned int dev) | ||
567 | { | ||
568 | struct snd_card *card; | ||
569 | int err; | ||
564 | 570 | ||
565 | card = snd_cmi8330_card_new(dev); | 571 | card = snd_cmi8330_card_new(dev); |
566 | if (! card) | 572 | if (! card) |
567 | return -ENOMEM; | 573 | return -ENOMEM; |
568 | snd_card_set_dev(card, &pdev->dev); | 574 | snd_card_set_dev(card, pdev); |
569 | if ((err = snd_cmi8330_probe(card, dev)) < 0) { | 575 | if ((err = snd_cmi8330_probe(card, dev)) < 0) { |
570 | snd_card_free(card); | 576 | snd_card_free(card); |
571 | return err; | 577 | return err; |
572 | } | 578 | } |
573 | platform_set_drvdata(pdev, card); | 579 | dev_set_drvdata(pdev, card); |
574 | return 0; | 580 | return 0; |
575 | } | 581 | } |
576 | 582 | ||
577 | static int __devexit snd_cmi8330_nonpnp_remove(struct platform_device *devptr) | 583 | static int __devexit snd_cmi8330_isa_remove(struct device *devptr, |
584 | unsigned int dev) | ||
578 | { | 585 | { |
579 | snd_card_free(platform_get_drvdata(devptr)); | 586 | snd_card_free(dev_get_drvdata(devptr)); |
580 | platform_set_drvdata(devptr, NULL); | 587 | dev_set_drvdata(devptr, NULL); |
581 | return 0; | 588 | return 0; |
582 | } | 589 | } |
583 | 590 | ||
584 | #ifdef CONFIG_PM | 591 | #ifdef CONFIG_PM |
585 | static int snd_cmi8330_nonpnp_suspend(struct platform_device *dev, pm_message_t state) | 592 | static int snd_cmi8330_isa_suspend(struct device *dev, unsigned int n, |
593 | pm_message_t state) | ||
586 | { | 594 | { |
587 | return snd_cmi8330_suspend(platform_get_drvdata(dev)); | 595 | return snd_cmi8330_suspend(dev_get_drvdata(dev)); |
588 | } | 596 | } |
589 | 597 | ||
590 | static int snd_cmi8330_nonpnp_resume(struct platform_device *dev) | 598 | static int snd_cmi8330_isa_resume(struct device *dev, unsigned int n) |
591 | { | 599 | { |
592 | return snd_cmi8330_resume(platform_get_drvdata(dev)); | 600 | return snd_cmi8330_resume(dev_get_drvdata(dev)); |
593 | } | 601 | } |
594 | #endif | 602 | #endif |
595 | 603 | ||
596 | #define CMI8330_DRIVER "snd_cmi8330" | 604 | #define DEV_NAME "cmi8330" |
597 | 605 | ||
598 | static struct platform_driver snd_cmi8330_driver = { | 606 | static struct isa_driver snd_cmi8330_driver = { |
599 | .probe = snd_cmi8330_nonpnp_probe, | 607 | .match = snd_cmi8330_isa_match, |
600 | .remove = __devexit_p(snd_cmi8330_nonpnp_remove), | 608 | .probe = snd_cmi8330_isa_probe, |
609 | .remove = __devexit_p(snd_cmi8330_isa_remove), | ||
601 | #ifdef CONFIG_PM | 610 | #ifdef CONFIG_PM |
602 | .suspend = snd_cmi8330_nonpnp_suspend, | 611 | .suspend = snd_cmi8330_isa_suspend, |
603 | .resume = snd_cmi8330_nonpnp_resume, | 612 | .resume = snd_cmi8330_isa_resume, |
604 | #endif | 613 | #endif |
605 | .driver = { | 614 | .driver = { |
606 | .name = CMI8330_DRIVER | 615 | .name = DEV_NAME |
607 | }, | 616 | }, |
608 | }; | 617 | }; |
609 | 618 | ||
610 | 619 | ||
611 | #ifdef CONFIG_PNP | 620 | #ifdef CONFIG_PNP |
612 | static unsigned int __devinitdata cmi8330_pnp_devices; | ||
613 | |||
614 | static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, | 621 | static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, |
615 | const struct pnp_card_device_id *pid) | 622 | const struct pnp_card_device_id *pid) |
616 | { | 623 | { |
@@ -640,7 +647,6 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, | |||
640 | } | 647 | } |
641 | pnp_set_card_drvdata(pcard, card); | 648 | pnp_set_card_drvdata(pcard, card); |
642 | dev++; | 649 | dev++; |
643 | cmi8330_pnp_devices++; | ||
644 | return 0; | 650 | return 0; |
645 | } | 651 | } |
646 | 652 | ||
@@ -675,63 +681,28 @@ static struct pnp_card_driver cmi8330_pnpc_driver = { | |||
675 | }; | 681 | }; |
676 | #endif /* CONFIG_PNP */ | 682 | #endif /* CONFIG_PNP */ |
677 | 683 | ||
678 | static void __init_or_module snd_cmi8330_unregister_all(void) | ||
679 | { | ||
680 | int i; | ||
681 | |||
682 | #ifdef CONFIG_PNP | ||
683 | if (pnp_registered) | ||
684 | pnp_unregister_card_driver(&cmi8330_pnpc_driver); | ||
685 | #endif | ||
686 | for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | ||
687 | platform_device_unregister(platform_devices[i]); | ||
688 | platform_driver_unregister(&snd_cmi8330_driver); | ||
689 | } | ||
690 | |||
691 | static int __init alsa_card_cmi8330_init(void) | 684 | static int __init alsa_card_cmi8330_init(void) |
692 | { | 685 | { |
693 | int i, err, cards = 0; | 686 | int err; |
694 | 687 | ||
695 | if ((err = platform_driver_register(&snd_cmi8330_driver)) < 0) | 688 | err = isa_register_driver(&snd_cmi8330_driver, SNDRV_CARDS); |
689 | if (err < 0) | ||
696 | return err; | 690 | return err; |
697 | |||
698 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
699 | struct platform_device *device; | ||
700 | if (! enable[i] || is_isapnp_selected(i)) | ||
701 | continue; | ||
702 | device = platform_device_register_simple(CMI8330_DRIVER, | ||
703 | i, NULL, 0); | ||
704 | if (IS_ERR(device)) | ||
705 | continue; | ||
706 | if (!platform_get_drvdata(device)) { | ||
707 | platform_device_unregister(device); | ||
708 | continue; | ||
709 | } | ||
710 | platform_devices[i] = device; | ||
711 | cards++; | ||
712 | } | ||
713 | |||
714 | #ifdef CONFIG_PNP | 691 | #ifdef CONFIG_PNP |
715 | err = pnp_register_card_driver(&cmi8330_pnpc_driver); | 692 | err = pnp_register_card_driver(&cmi8330_pnpc_driver); |
716 | if (!err) { | 693 | if (!err) |
717 | pnp_registered = 1; | 694 | pnp_registered = 1; |
718 | cards += cmi8330_pnp_devices; | ||
719 | } | ||
720 | #endif | 695 | #endif |
721 | |||
722 | if (!cards) { | ||
723 | #ifdef MODULE | ||
724 | snd_printk(KERN_ERR "CMI8330 not found or device busy\n"); | ||
725 | #endif | ||
726 | snd_cmi8330_unregister_all(); | ||
727 | return -ENODEV; | ||
728 | } | ||
729 | return 0; | 696 | return 0; |
730 | } | 697 | } |
731 | 698 | ||
732 | static void __exit alsa_card_cmi8330_exit(void) | 699 | static void __exit alsa_card_cmi8330_exit(void) |
733 | { | 700 | { |
734 | snd_cmi8330_unregister_all(); | 701 | #ifdef CONFIG_PNP |
702 | if (pnp_registered) | ||
703 | pnp_unregister_card_driver(&cmi8330_pnpc_driver); | ||
704 | #endif | ||
705 | isa_unregister_driver(&snd_cmi8330_driver); | ||
735 | } | 706 | } |
736 | 707 | ||
737 | module_init(alsa_card_cmi8330_init) | 708 | module_init(alsa_card_cmi8330_init) |
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index 696a5c86bcfa..ac4041134150 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <sound/driver.h> | 23 | #include <sound/driver.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/isa.h> |
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/wait.h> | 28 | #include <linux/wait.h> |
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
@@ -32,8 +32,11 @@ | |||
32 | #include <sound/mpu401.h> | 32 | #include <sound/mpu401.h> |
33 | #include <sound/initval.h> | 33 | #include <sound/initval.h> |
34 | 34 | ||
35 | #define CRD_NAME "Generic CS4231" | ||
36 | #define DEV_NAME "cs4231" | ||
37 | |||
38 | MODULE_DESCRIPTION(CRD_NAME); | ||
35 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); | 39 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); |
36 | MODULE_DESCRIPTION("Generic CS4231"); | ||
37 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
38 | MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4231}}"); | 41 | MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4231}}"); |
39 | 42 | ||
@@ -48,132 +51,136 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ | |||
48 | static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ | 51 | static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ |
49 | 52 | ||
50 | module_param_array(index, int, NULL, 0444); | 53 | module_param_array(index, int, NULL, 0444); |
51 | MODULE_PARM_DESC(index, "Index value for CS4231 soundcard."); | 54 | MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); |
52 | module_param_array(id, charp, NULL, 0444); | 55 | module_param_array(id, charp, NULL, 0444); |
53 | MODULE_PARM_DESC(id, "ID string for CS4231 soundcard."); | 56 | MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); |
54 | module_param_array(enable, bool, NULL, 0444); | 57 | module_param_array(enable, bool, NULL, 0444); |
55 | MODULE_PARM_DESC(enable, "Enable CS4231 soundcard."); | 58 | MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); |
56 | module_param_array(port, long, NULL, 0444); | 59 | module_param_array(port, long, NULL, 0444); |
57 | MODULE_PARM_DESC(port, "Port # for CS4231 driver."); | 60 | MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); |
58 | module_param_array(mpu_port, long, NULL, 0444); | 61 | module_param_array(mpu_port, long, NULL, 0444); |
59 | MODULE_PARM_DESC(mpu_port, "MPU-401 port # for CS4231 driver."); | 62 | MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); |
60 | module_param_array(irq, int, NULL, 0444); | 63 | module_param_array(irq, int, NULL, 0444); |
61 | MODULE_PARM_DESC(irq, "IRQ # for CS4231 driver."); | 64 | MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); |
62 | module_param_array(mpu_irq, int, NULL, 0444); | 65 | module_param_array(mpu_irq, int, NULL, 0444); |
63 | MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for CS4231 driver."); | 66 | MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); |
64 | module_param_array(dma1, int, NULL, 0444); | 67 | module_param_array(dma1, int, NULL, 0444); |
65 | MODULE_PARM_DESC(dma1, "DMA1 # for CS4231 driver."); | 68 | MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver."); |
66 | module_param_array(dma2, int, NULL, 0444); | 69 | module_param_array(dma2, int, NULL, 0444); |
67 | MODULE_PARM_DESC(dma2, "DMA2 # for CS4231 driver."); | 70 | MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver."); |
68 | 71 | ||
69 | static struct platform_device *devices[SNDRV_CARDS]; | 72 | static int __devinit snd_cs4231_match(struct device *dev, unsigned int n) |
73 | { | ||
74 | if (!enable[n]) | ||
75 | return 0; | ||
70 | 76 | ||
77 | if (port[n] == SNDRV_AUTO_PORT) { | ||
78 | snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id); | ||
79 | return 0; | ||
80 | } | ||
81 | if (irq[n] == SNDRV_AUTO_IRQ) { | ||
82 | snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id); | ||
83 | return 0; | ||
84 | } | ||
85 | if (dma1[n] == SNDRV_AUTO_DMA) { | ||
86 | snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id); | ||
87 | return 0; | ||
88 | } | ||
89 | return 1; | ||
90 | } | ||
71 | 91 | ||
72 | static int __init snd_cs4231_probe(struct platform_device *pdev) | 92 | static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n) |
73 | { | 93 | { |
74 | int dev = pdev->id; | ||
75 | struct snd_card *card; | 94 | struct snd_card *card; |
76 | struct snd_pcm *pcm; | ||
77 | struct snd_cs4231 *chip; | 95 | struct snd_cs4231 *chip; |
78 | int err; | 96 | struct snd_pcm *pcm; |
97 | int error; | ||
79 | 98 | ||
80 | if (port[dev] == SNDRV_AUTO_PORT) { | 99 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); |
81 | snd_printk(KERN_ERR "specify port\n"); | 100 | if (!card) |
82 | return -EINVAL; | ||
83 | } | ||
84 | if (irq[dev] == SNDRV_AUTO_IRQ) { | ||
85 | snd_printk(KERN_ERR "specify irq\n"); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | if (dma1[dev] == SNDRV_AUTO_DMA) { | ||
89 | snd_printk(KERN_ERR "specify dma1\n"); | ||
90 | return -EINVAL; | 101 | return -EINVAL; |
91 | } | 102 | |
92 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 103 | error = snd_cs4231_create(card, port[n], -1, irq[n], dma1[n], dma2[n], |
93 | if (card == NULL) | 104 | CS4231_HW_DETECT, 0, &chip); |
94 | return -ENOMEM; | 105 | if (error < 0) |
95 | if ((err = snd_cs4231_create(card, port[dev], -1, | 106 | goto out; |
96 | irq[dev], | 107 | |
97 | dma1[dev], | ||
98 | dma2[dev], | ||
99 | CS4231_HW_DETECT, | ||
100 | 0, &chip)) < 0) | ||
101 | goto _err; | ||
102 | card->private_data = chip; | 108 | card->private_data = chip; |
103 | 109 | ||
104 | if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) | 110 | error = snd_cs4231_pcm(chip, 0, &pcm); |
105 | goto _err; | 111 | if (error < 0) |
112 | goto out; | ||
106 | 113 | ||
107 | strcpy(card->driver, "CS4231"); | 114 | strcpy(card->driver, "CS4231"); |
108 | strcpy(card->shortname, pcm->name); | 115 | strcpy(card->shortname, pcm->name); |
116 | |||
109 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", | 117 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", |
110 | pcm->name, chip->port, irq[dev], dma1[dev]); | 118 | pcm->name, chip->port, irq[n], dma1[n]); |
111 | if (dma2[dev] >= 0) | 119 | if (dma2[n] >= 0) |
112 | sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]); | 120 | sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]); |
113 | 121 | ||
114 | if ((err = snd_cs4231_mixer(chip)) < 0) | 122 | error = snd_cs4231_mixer(chip); |
115 | goto _err; | 123 | if (error < 0) |
116 | if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) | 124 | goto out; |
117 | goto _err; | 125 | |
118 | 126 | error = snd_cs4231_timer(chip, 0, NULL); | |
119 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { | 127 | if (error < 0) |
120 | if (mpu_irq[dev] == SNDRV_AUTO_IRQ) | 128 | goto out; |
121 | mpu_irq[dev] = -1; | 129 | |
130 | if (mpu_port[n] > 0 && mpu_port[n] != SNDRV_AUTO_PORT) { | ||
131 | if (mpu_irq[n] == SNDRV_AUTO_IRQ) | ||
132 | mpu_irq[n] = -1; | ||
122 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232, | 133 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232, |
123 | mpu_port[dev], 0, | 134 | mpu_port[n], 0, mpu_irq[n], |
124 | mpu_irq[dev], | 135 | mpu_irq[n] >= 0 ? IRQF_DISABLED : 0, |
125 | mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, | ||
126 | NULL) < 0) | 136 | NULL) < 0) |
127 | printk(KERN_WARNING "cs4231: MPU401 not detected\n"); | 137 | printk(KERN_WARNING "%s: MPU401 not detected\n", dev->bus_id); |
128 | } | 138 | } |
129 | 139 | ||
130 | snd_card_set_dev(card, &pdev->dev); | 140 | snd_card_set_dev(card, dev); |
131 | 141 | ||
132 | if ((err = snd_card_register(card)) < 0) | 142 | error = snd_card_register(card); |
133 | goto _err; | 143 | if (error < 0) |
144 | goto out; | ||
134 | 145 | ||
135 | platform_set_drvdata(pdev, card); | 146 | dev_set_drvdata(dev, card); |
136 | return 0; | 147 | return 0; |
137 | 148 | ||
138 | _err: | 149 | out: snd_card_free(card); |
139 | snd_card_free(card); | 150 | return error; |
140 | return err; | ||
141 | } | 151 | } |
142 | 152 | ||
143 | static int __devexit snd_cs4231_remove(struct platform_device *devptr) | 153 | static int __devexit snd_cs4231_remove(struct device *dev, unsigned int n) |
144 | { | 154 | { |
145 | snd_card_free(platform_get_drvdata(devptr)); | 155 | snd_card_free(dev_get_drvdata(dev)); |
146 | platform_set_drvdata(devptr, NULL); | 156 | dev_set_drvdata(dev, NULL); |
147 | return 0; | 157 | return 0; |
148 | } | 158 | } |
149 | 159 | ||
150 | #ifdef CONFIG_PM | 160 | #ifdef CONFIG_PM |
151 | static int snd_cs4231_suspend(struct platform_device *dev, pm_message_t state) | 161 | static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t state) |
152 | { | 162 | { |
153 | struct snd_card *card; | 163 | struct snd_card *card = dev_get_drvdata(dev); |
154 | struct snd_cs4231 *chip; | 164 | struct snd_cs4231 *chip = card->private_data; |
155 | card = platform_get_drvdata(dev); | 165 | |
156 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 166 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
157 | chip = card->private_data; | ||
158 | chip->suspend(chip); | 167 | chip->suspend(chip); |
159 | return 0; | 168 | return 0; |
160 | } | 169 | } |
161 | 170 | ||
162 | static int snd_cs4231_resume(struct platform_device *dev) | 171 | static int snd_cs4231_resume(struct device *dev, unsigned int n) |
163 | { | 172 | { |
164 | struct snd_card *card; | 173 | struct snd_card *card = dev_get_drvdata(dev); |
165 | struct snd_cs4231 *chip; | 174 | struct snd_cs4231 *chip = card->private_data; |
166 | card = platform_get_drvdata(dev); | 175 | |
167 | chip = card->private_data; | ||
168 | chip->resume(chip); | 176 | chip->resume(chip); |
169 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 177 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
170 | return 0; | 178 | return 0; |
171 | } | 179 | } |
172 | #endif | 180 | #endif |
173 | 181 | ||
174 | #define SND_CS4231_DRIVER "snd_cs4231" | 182 | static struct isa_driver snd_cs4231_driver = { |
175 | 183 | .match = snd_cs4231_match, | |
176 | static struct platform_driver snd_cs4231_driver = { | ||
177 | .probe = snd_cs4231_probe, | 184 | .probe = snd_cs4231_probe, |
178 | .remove = __devexit_p(snd_cs4231_remove), | 185 | .remove = __devexit_p(snd_cs4231_remove), |
179 | #ifdef CONFIG_PM | 186 | #ifdef CONFIG_PM |
@@ -181,57 +188,19 @@ static struct platform_driver snd_cs4231_driver = { | |||
181 | .resume = snd_cs4231_resume, | 188 | .resume = snd_cs4231_resume, |
182 | #endif | 189 | #endif |
183 | .driver = { | 190 | .driver = { |
184 | .name = SND_CS4231_DRIVER | 191 | .name = DEV_NAME |
185 | }, | 192 | } |
186 | }; | 193 | }; |
187 | 194 | ||
188 | static void __init_or_module snd_cs4231_unregister_all(void) | ||
189 | { | ||
190 | int i; | ||
191 | |||
192 | for (i = 0; i < ARRAY_SIZE(devices); ++i) | ||
193 | platform_device_unregister(devices[i]); | ||
194 | platform_driver_unregister(&snd_cs4231_driver); | ||
195 | } | ||
196 | |||
197 | static int __init alsa_card_cs4231_init(void) | 195 | static int __init alsa_card_cs4231_init(void) |
198 | { | 196 | { |
199 | int i, cards, err; | 197 | return isa_register_driver(&snd_cs4231_driver, SNDRV_CARDS); |
200 | |||
201 | err = platform_driver_register(&snd_cs4231_driver); | ||
202 | if (err < 0) | ||
203 | return err; | ||
204 | |||
205 | cards = 0; | ||
206 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
207 | struct platform_device *device; | ||
208 | if (! enable[i]) | ||
209 | continue; | ||
210 | device = platform_device_register_simple(SND_CS4231_DRIVER, | ||
211 | i, NULL, 0); | ||
212 | if (IS_ERR(device)) | ||
213 | continue; | ||
214 | if (!platform_get_drvdata(device)) { | ||
215 | platform_device_unregister(device); | ||
216 | continue; | ||
217 | } | ||
218 | devices[i] = device; | ||
219 | cards++; | ||
220 | } | ||
221 | if (!cards) { | ||
222 | #ifdef MODULE | ||
223 | printk(KERN_ERR "CS4231 soundcard not found or device busy\n"); | ||
224 | #endif | ||
225 | snd_cs4231_unregister_all(); | ||
226 | return -ENODEV; | ||
227 | } | ||
228 | return 0; | ||
229 | } | 198 | } |
230 | 199 | ||
231 | static void __exit alsa_card_cs4231_exit(void) | 200 | static void __exit alsa_card_cs4231_exit(void) |
232 | { | 201 | { |
233 | snd_cs4231_unregister_all(); | 202 | isa_unregister_driver(&snd_cs4231_driver); |
234 | } | 203 | } |
235 | 204 | ||
236 | module_init(alsa_card_cs4231_init) | 205 | module_init(alsa_card_cs4231_init); |
237 | module_exit(alsa_card_cs4231_exit) | 206 | module_exit(alsa_card_cs4231_exit); |
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c index 75c7c5f01989..914d77b61b0c 100644 --- a/sound/isa/cs423x/cs4231_lib.c +++ b/sound/isa/cs423x/cs4231_lib.c | |||
@@ -405,7 +405,6 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, | |||
405 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); | 405 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); |
406 | int result = 0; | 406 | int result = 0; |
407 | unsigned int what; | 407 | unsigned int what; |
408 | struct list_head *pos; | ||
409 | struct snd_pcm_substream *s; | 408 | struct snd_pcm_substream *s; |
410 | int do_start; | 409 | int do_start; |
411 | 410 | ||
@@ -425,8 +424,7 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, | |||
425 | } | 424 | } |
426 | 425 | ||
427 | what = 0; | 426 | what = 0; |
428 | snd_pcm_group_for_each(pos, substream) { | 427 | snd_pcm_group_for_each_entry(s, substream) { |
429 | s = snd_pcm_group_substream_entry(pos); | ||
430 | if (s == chip->playback_substream) { | 428 | if (s == chip->playback_substream) { |
431 | what |= CS4231_PLAYBACK_ENABLE; | 429 | what |= CS4231_PLAYBACK_ENABLE; |
432 | snd_pcm_trigger_done(s, substream); | 430 | snd_pcm_trigger_done(s, substream); |
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 07ffd5c22e81..87f1392a2fa7 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/isa.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/pnp.h> | 27 | #include <linux/pnp.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
@@ -75,10 +75,10 @@ MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235}," | |||
75 | 75 | ||
76 | #ifdef CS4232 | 76 | #ifdef CS4232 |
77 | #define IDENT "CS4232" | 77 | #define IDENT "CS4232" |
78 | #define CS423X_DRIVER "snd_cs4232" | 78 | #define DEV_NAME "cs4232" |
79 | #else | 79 | #else |
80 | #define IDENT "CS4236+" | 80 | #define IDENT "CS4236+" |
81 | #define CS423X_DRIVER "snd_cs4236" | 81 | #define DEV_NAME "cs4236" |
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 84 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
@@ -126,14 +126,12 @@ MODULE_PARM_DESC(dma1, "DMA1 # for " IDENT " driver."); | |||
126 | module_param_array(dma2, int, NULL, 0444); | 126 | module_param_array(dma2, int, NULL, 0444); |
127 | MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver."); | 127 | MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver."); |
128 | 128 | ||
129 | static struct platform_device *platform_devices[SNDRV_CARDS]; | ||
130 | #ifdef CONFIG_PNP | 129 | #ifdef CONFIG_PNP |
131 | static int pnpc_registered; | 130 | static int pnpc_registered; |
132 | #ifdef CS4232 | 131 | #ifdef CS4232 |
133 | static int pnp_registered; | 132 | static int pnp_registered; |
134 | #endif | 133 | #endif |
135 | #endif /* CONFIG_PNP */ | 134 | #endif /* CONFIG_PNP */ |
136 | static unsigned int snd_cs423x_devices; | ||
137 | 135 | ||
138 | struct snd_card_cs4236 { | 136 | struct snd_card_cs4236 { |
139 | struct snd_cs4231 *chip; | 137 | struct snd_cs4231 *chip; |
@@ -542,38 +540,55 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) | |||
542 | return snd_card_register(card); | 540 | return snd_card_register(card); |
543 | } | 541 | } |
544 | 542 | ||
545 | static int __init snd_cs423x_nonpnp_probe(struct platform_device *pdev) | 543 | static int __devinit snd_cs423x_isa_match(struct device *pdev, |
544 | unsigned int dev) | ||
546 | { | 545 | { |
547 | int dev = pdev->id; | 546 | if (!enable[dev] || is_isapnp_selected(dev)) |
548 | struct snd_card *card; | 547 | return 0; |
549 | int err; | ||
550 | 548 | ||
551 | if (port[dev] == SNDRV_AUTO_PORT) { | 549 | if (port[dev] == SNDRV_AUTO_PORT) { |
552 | snd_printk(KERN_ERR "specify port\n"); | 550 | snd_printk(KERN_ERR "%s: please specify port\n", pdev->bus_id); |
553 | return -EINVAL; | 551 | return 0; |
554 | } | 552 | } |
555 | if (cport[dev] == SNDRV_AUTO_PORT) { | 553 | if (cport[dev] == SNDRV_AUTO_PORT) { |
556 | snd_printk(KERN_ERR "specify cport\n"); | 554 | snd_printk(KERN_ERR "%s: please specify cport\n", pdev->bus_id); |
557 | return -EINVAL; | 555 | return 0; |
556 | } | ||
557 | if (irq[dev] == SNDRV_AUTO_IRQ) { | ||
558 | snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id); | ||
559 | return 0; | ||
558 | } | 560 | } |
561 | if (dma1[dev] == SNDRV_AUTO_DMA) { | ||
562 | snd_printk(KERN_ERR "%s: please specify dma1\n", pdev->bus_id); | ||
563 | return 0; | ||
564 | } | ||
565 | return 1; | ||
566 | } | ||
567 | |||
568 | static int __devinit snd_cs423x_isa_probe(struct device *pdev, | ||
569 | unsigned int dev) | ||
570 | { | ||
571 | struct snd_card *card; | ||
572 | int err; | ||
559 | 573 | ||
560 | card = snd_cs423x_card_new(dev); | 574 | card = snd_cs423x_card_new(dev); |
561 | if (! card) | 575 | if (! card) |
562 | return -ENOMEM; | 576 | return -ENOMEM; |
563 | snd_card_set_dev(card, &pdev->dev); | 577 | snd_card_set_dev(card, pdev); |
564 | if ((err = snd_cs423x_probe(card, dev)) < 0) { | 578 | if ((err = snd_cs423x_probe(card, dev)) < 0) { |
565 | snd_card_free(card); | 579 | snd_card_free(card); |
566 | return err; | 580 | return err; |
567 | } | 581 | } |
568 | 582 | ||
569 | platform_set_drvdata(pdev, card); | 583 | dev_set_drvdata(pdev, card); |
570 | return 0; | 584 | return 0; |
571 | } | 585 | } |
572 | 586 | ||
573 | static int __devexit snd_cs423x_nonpnp_remove(struct platform_device *devptr) | 587 | static int __devexit snd_cs423x_isa_remove(struct device *pdev, |
588 | unsigned int dev) | ||
574 | { | 589 | { |
575 | snd_card_free(platform_get_drvdata(devptr)); | 590 | snd_card_free(dev_get_drvdata(pdev)); |
576 | platform_set_drvdata(devptr, NULL); | 591 | dev_set_drvdata(pdev, NULL); |
577 | return 0; | 592 | return 0; |
578 | } | 593 | } |
579 | 594 | ||
@@ -594,26 +609,28 @@ static int snd_cs423x_resume(struct snd_card *card) | |||
594 | return 0; | 609 | return 0; |
595 | } | 610 | } |
596 | 611 | ||
597 | static int snd_cs423x_nonpnp_suspend(struct platform_device *dev, pm_message_t state) | 612 | static int snd_cs423x_isa_suspend(struct device *dev, unsigned int n, |
613 | pm_message_t state) | ||
598 | { | 614 | { |
599 | return snd_cs423x_suspend(platform_get_drvdata(dev)); | 615 | return snd_cs423x_suspend(dev_get_drvdata(dev)); |
600 | } | 616 | } |
601 | 617 | ||
602 | static int snd_cs423x_nonpnp_resume(struct platform_device *dev) | 618 | static int snd_cs423x_isa_resume(struct device *dev, unsigned int n) |
603 | { | 619 | { |
604 | return snd_cs423x_resume(platform_get_drvdata(dev)); | 620 | return snd_cs423x_resume(dev_get_drvdata(dev)); |
605 | } | 621 | } |
606 | #endif | 622 | #endif |
607 | 623 | ||
608 | static struct platform_driver cs423x_nonpnp_driver = { | 624 | static struct isa_driver cs423x_isa_driver = { |
609 | .probe = snd_cs423x_nonpnp_probe, | 625 | .match = snd_cs423x_isa_match, |
610 | .remove = __devexit_p(snd_cs423x_nonpnp_remove), | 626 | .probe = snd_cs423x_isa_probe, |
627 | .remove = __devexit_p(snd_cs423x_isa_remove), | ||
611 | #ifdef CONFIG_PM | 628 | #ifdef CONFIG_PM |
612 | .suspend = snd_cs423x_nonpnp_suspend, | 629 | .suspend = snd_cs423x_isa_suspend, |
613 | .resume = snd_cs423x_nonpnp_resume, | 630 | .resume = snd_cs423x_isa_resume, |
614 | #endif | 631 | #endif |
615 | .driver = { | 632 | .driver = { |
616 | .name = CS423X_DRIVER | 633 | .name = DEV_NAME |
617 | }, | 634 | }, |
618 | }; | 635 | }; |
619 | 636 | ||
@@ -651,7 +668,6 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, | |||
651 | } | 668 | } |
652 | pnp_set_drvdata(pdev, card); | 669 | pnp_set_drvdata(pdev, card); |
653 | dev++; | 670 | dev++; |
654 | snd_cs423x_devices++; | ||
655 | return 0; | 671 | return 0; |
656 | } | 672 | } |
657 | 673 | ||
@@ -715,7 +731,6 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, | |||
715 | } | 731 | } |
716 | pnp_set_card_drvdata(pcard, card); | 732 | pnp_set_card_drvdata(pcard, card); |
717 | dev++; | 733 | dev++; |
718 | snd_cs423x_devices++; | ||
719 | return 0; | 734 | return 0; |
720 | } | 735 | } |
721 | 736 | ||
@@ -750,45 +765,13 @@ static struct pnp_card_driver cs423x_pnpc_driver = { | |||
750 | }; | 765 | }; |
751 | #endif /* CONFIG_PNP */ | 766 | #endif /* CONFIG_PNP */ |
752 | 767 | ||
753 | static void __init_or_module snd_cs423x_unregister_all(void) | ||
754 | { | ||
755 | int i; | ||
756 | |||
757 | #ifdef CONFIG_PNP | ||
758 | if (pnpc_registered) | ||
759 | pnp_unregister_card_driver(&cs423x_pnpc_driver); | ||
760 | #ifdef CS4232 | ||
761 | if (pnp_registered) | ||
762 | pnp_unregister_driver(&cs4232_pnp_driver); | ||
763 | #endif | ||
764 | #endif /* CONFIG_PNP */ | ||
765 | for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | ||
766 | platform_device_unregister(platform_devices[i]); | ||
767 | platform_driver_unregister(&cs423x_nonpnp_driver); | ||
768 | } | ||
769 | |||
770 | static int __init alsa_card_cs423x_init(void) | 768 | static int __init alsa_card_cs423x_init(void) |
771 | { | 769 | { |
772 | int i, err; | 770 | int err; |
773 | 771 | ||
774 | if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0) | 772 | err = isa_register_driver(&cs423x_isa_driver, SNDRV_CARDS); |
773 | if (err < 0) | ||
775 | return err; | 774 | return err; |
776 | |||
777 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
778 | struct platform_device *device; | ||
779 | if (! enable[i] || is_isapnp_selected(i)) | ||
780 | continue; | ||
781 | device = platform_device_register_simple(CS423X_DRIVER, | ||
782 | i, NULL, 0); | ||
783 | if (IS_ERR(device)) | ||
784 | continue; | ||
785 | if (!platform_get_drvdata(device)) { | ||
786 | platform_device_unregister(device); | ||
787 | continue; | ||
788 | } | ||
789 | platform_devices[i] = device; | ||
790 | snd_cs423x_devices++; | ||
791 | } | ||
792 | #ifdef CONFIG_PNP | 775 | #ifdef CONFIG_PNP |
793 | #ifdef CS4232 | 776 | #ifdef CS4232 |
794 | err = pnp_register_driver(&cs4232_pnp_driver); | 777 | err = pnp_register_driver(&cs4232_pnp_driver); |
@@ -799,20 +782,20 @@ static int __init alsa_card_cs423x_init(void) | |||
799 | if (!err) | 782 | if (!err) |
800 | pnpc_registered = 1; | 783 | pnpc_registered = 1; |
801 | #endif /* CONFIG_PNP */ | 784 | #endif /* CONFIG_PNP */ |
802 | |||
803 | if (!snd_cs423x_devices) { | ||
804 | #ifdef MODULE | ||
805 | printk(KERN_ERR IDENT " soundcard not found or device busy\n"); | ||
806 | #endif | ||
807 | snd_cs423x_unregister_all(); | ||
808 | return -ENODEV; | ||
809 | } | ||
810 | return 0; | 785 | return 0; |
811 | } | 786 | } |
812 | 787 | ||
813 | static void __exit alsa_card_cs423x_exit(void) | 788 | static void __exit alsa_card_cs423x_exit(void) |
814 | { | 789 | { |
815 | snd_cs423x_unregister_all(); | 790 | #ifdef CONFIG_PNP |
791 | if (pnpc_registered) | ||
792 | pnp_unregister_card_driver(&cs423x_pnpc_driver); | ||
793 | #ifdef CS4232 | ||
794 | if (pnp_registered) | ||
795 | pnp_unregister_driver(&cs4232_pnp_driver); | ||
796 | #endif | ||
797 | #endif /* CONFIG_PNP */ | ||
798 | isa_unregister_driver(&cs423x_isa_driver); | ||
816 | } | 799 | } |
817 | 800 | ||
818 | module_init(alsa_card_cs423x_init) | 801 | module_init(alsa_card_cs423x_init) |
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 65f97ff4eef1..edc398712e8b 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/isa.h> |
26 | #include <linux/time.h> | 26 | #include <linux/time.h> |
27 | #include <linux/wait.h> | 27 | #include <linux/wait.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
@@ -35,8 +35,11 @@ | |||
35 | #define SNDRV_LEGACY_FIND_FREE_DMA | 35 | #define SNDRV_LEGACY_FIND_FREE_DMA |
36 | #include <sound/initval.h> | 36 | #include <sound/initval.h> |
37 | 37 | ||
38 | #define CRD_NAME "Generic ESS ES1688/ES688 AudioDrive" | ||
39 | #define DEV_NAME "es1688" | ||
40 | |||
41 | MODULE_DESCRIPTION(CRD_NAME); | ||
38 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); | 42 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); |
39 | MODULE_DESCRIPTION("ESS ESx688 AudioDrive"); | ||
40 | MODULE_LICENSE("GPL"); | 43 | MODULE_LICENSE("GPL"); |
41 | MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100}," | 44 | MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100}," |
42 | "{ESS,ES1688 PnP AudioDrive,pnp:ESS0102}," | 45 | "{ESS,ES1688 PnP AudioDrive,pnp:ESS0102}," |
@@ -53,189 +56,157 @@ static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */ | |||
53 | static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */ | 56 | static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */ |
54 | 57 | ||
55 | module_param_array(index, int, NULL, 0444); | 58 | module_param_array(index, int, NULL, 0444); |
56 | MODULE_PARM_DESC(index, "Index value for ESx688 soundcard."); | 59 | MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); |
57 | module_param_array(id, charp, NULL, 0444); | 60 | module_param_array(id, charp, NULL, 0444); |
58 | MODULE_PARM_DESC(id, "ID string for ESx688 soundcard."); | 61 | MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); |
59 | module_param_array(enable, bool, NULL, 0444); | 62 | module_param_array(enable, bool, NULL, 0444); |
60 | MODULE_PARM_DESC(enable, "Enable ESx688 soundcard."); | 63 | MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); |
61 | module_param_array(port, long, NULL, 0444); | 64 | module_param_array(port, long, NULL, 0444); |
62 | MODULE_PARM_DESC(port, "Port # for ESx688 driver."); | 65 | MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); |
63 | module_param_array(mpu_port, long, NULL, 0444); | 66 | module_param_array(mpu_port, long, NULL, 0444); |
64 | MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ESx688 driver."); | 67 | MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); |
65 | module_param_array(irq, int, NULL, 0444); | 68 | module_param_array(irq, int, NULL, 0444); |
66 | MODULE_PARM_DESC(irq, "IRQ # for ESx688 driver."); | 69 | MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); |
67 | module_param_array(mpu_irq, int, NULL, 0444); | 70 | module_param_array(mpu_irq, int, NULL, 0444); |
68 | MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for ESx688 driver."); | 71 | MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); |
69 | module_param_array(dma8, int, NULL, 0444); | 72 | module_param_array(dma8, int, NULL, 0444); |
70 | MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver."); | 73 | MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); |
71 | |||
72 | static struct platform_device *devices[SNDRV_CARDS]; | ||
73 | 74 | ||
74 | #define PFX "es1688: " | 75 | static int __devinit snd_es1688_match(struct device *dev, unsigned int n) |
76 | { | ||
77 | return enable[n]; | ||
78 | } | ||
75 | 79 | ||
76 | static int __devinit snd_es1688_probe(struct platform_device *pdev) | 80 | static int __devinit snd_es1688_legacy_create(struct snd_card *card, |
81 | struct device *dev, unsigned int n, struct snd_es1688 **rchip) | ||
77 | { | 82 | { |
78 | int dev = pdev->id; | 83 | static long possible_ports[] = {0x220, 0x240, 0x260}; |
79 | static int possible_irqs[] = {5, 9, 10, 7, -1}; | 84 | static int possible_irqs[] = {5, 9, 10, 7, -1}; |
80 | static int possible_dmas[] = {1, 3, 0, -1}; | 85 | static int possible_dmas[] = {1, 3, 0, -1}; |
81 | int xirq, xdma, xmpu_irq; | 86 | |
82 | struct snd_card *card; | 87 | int i, error; |
83 | struct snd_es1688 *chip; | 88 | |
84 | struct snd_opl3 *opl3; | 89 | if (irq[n] == SNDRV_AUTO_IRQ) { |
85 | struct snd_pcm *pcm; | 90 | irq[n] = snd_legacy_find_free_irq(possible_irqs); |
86 | int err; | 91 | if (irq[n] < 0) { |
87 | 92 | snd_printk(KERN_ERR "%s: unable to find a free IRQ\n", | |
88 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 93 | dev->bus_id); |
89 | if (card == NULL) | 94 | return -EBUSY; |
90 | return -ENOMEM; | ||
91 | |||
92 | xirq = irq[dev]; | ||
93 | if (xirq == SNDRV_AUTO_IRQ) { | ||
94 | if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) { | ||
95 | snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); | ||
96 | err = -EBUSY; | ||
97 | goto _err; | ||
98 | } | 95 | } |
99 | } | 96 | } |
100 | xmpu_irq = mpu_irq[dev]; | 97 | if (dma8[n] == SNDRV_AUTO_DMA) { |
101 | xdma = dma8[dev]; | 98 | dma8[n] = snd_legacy_find_free_dma(possible_dmas); |
102 | if (xdma == SNDRV_AUTO_DMA) { | 99 | if (dma8[n] < 0) { |
103 | if ((xdma = snd_legacy_find_free_dma(possible_dmas)) < 0) { | 100 | snd_printk(KERN_ERR "%s: unable to find a free DMA\n", |
104 | snd_printk(KERN_ERR PFX "unable to find a free DMA\n"); | 101 | dev->bus_id); |
105 | err = -EBUSY; | 102 | return -EBUSY; |
106 | goto _err; | ||
107 | } | 103 | } |
108 | } | 104 | } |
109 | 105 | ||
110 | if (port[dev] != SNDRV_AUTO_PORT) { | 106 | if (port[n] != SNDRV_AUTO_PORT) |
111 | if ((err = snd_es1688_create(card, port[dev], mpu_port[dev], | 107 | return snd_es1688_create(card, port[n], mpu_port[n], irq[n], |
112 | xirq, xmpu_irq, xdma, | 108 | mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); |
113 | ES1688_HW_AUTO, &chip)) < 0) | 109 | |
114 | goto _err; | 110 | i = 0; |
115 | } else { | 111 | do { |
116 | /* auto-probe legacy ports */ | 112 | port[n] = possible_ports[i]; |
117 | static unsigned long possible_ports[] = { | 113 | error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], |
118 | 0x220, 0x240, 0x260, | 114 | mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); |
119 | }; | 115 | } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); |
120 | int i; | 116 | |
121 | for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { | 117 | return error; |
122 | err = snd_es1688_create(card, possible_ports[i], | 118 | } |
123 | mpu_port[dev], | 119 | |
124 | xirq, xmpu_irq, xdma, | 120 | static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) |
125 | ES1688_HW_AUTO, &chip); | 121 | { |
126 | if (err >= 0) { | 122 | struct snd_card *card; |
127 | port[dev] = possible_ports[i]; | 123 | struct snd_es1688 *chip; |
128 | break; | 124 | struct snd_opl3 *opl3; |
129 | } | 125 | struct snd_pcm *pcm; |
130 | } | 126 | int error; |
131 | if (i >= ARRAY_SIZE(possible_ports)) | 127 | |
132 | goto _err; | 128 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); |
133 | } | 129 | if (!card) |
130 | return -EINVAL; | ||
131 | |||
132 | error = snd_es1688_legacy_create(card, dev, n, &chip); | ||
133 | if (error < 0) | ||
134 | goto out; | ||
134 | 135 | ||
135 | if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0) | 136 | error = snd_es1688_pcm(chip, 0, &pcm); |
136 | goto _err; | 137 | if (error < 0) |
138 | goto out; | ||
137 | 139 | ||
138 | if ((err = snd_es1688_mixer(chip)) < 0) | 140 | error = snd_es1688_mixer(chip); |
139 | goto _err; | 141 | if (error < 0) |
142 | goto out; | ||
140 | 143 | ||
141 | strcpy(card->driver, "ES1688"); | 144 | strcpy(card->driver, "ES1688"); |
142 | strcpy(card->shortname, pcm->name); | 145 | strcpy(card->shortname, pcm->name); |
143 | sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, xirq, xdma); | 146 | sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, |
144 | 147 | chip->port, chip->irq, chip->dma8); | |
145 | if ((snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3)) < 0) { | 148 | |
146 | printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->port); | 149 | if (snd_opl3_create(card, chip->port, chip->port + 2, |
147 | } else { | 150 | OPL3_HW_OPL3, 0, &opl3) < 0) |
148 | if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) | 151 | printk(KERN_WARNING "%s: opl3 not detected at 0x%lx\n", |
149 | goto _err; | 152 | dev->bus_id, chip->port); |
153 | else { | ||
154 | error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); | ||
155 | if (error < 0) | ||
156 | goto out; | ||
150 | } | 157 | } |
151 | 158 | ||
152 | if (xmpu_irq >= 0 && xmpu_irq != SNDRV_AUTO_IRQ && chip->mpu_port > 0) { | 159 | if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ && |
153 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, | 160 | chip->mpu_port > 0) { |
154 | chip->mpu_port, 0, | 161 | error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, |
155 | xmpu_irq, | 162 | chip->mpu_port, 0, |
156 | IRQF_DISABLED, | 163 | mpu_irq[n], IRQF_DISABLED, NULL); |
157 | NULL)) < 0) | 164 | if (error < 0) |
158 | goto _err; | 165 | goto out; |
159 | } | 166 | } |
160 | 167 | ||
161 | snd_card_set_dev(card, &pdev->dev); | 168 | snd_card_set_dev(card, dev); |
162 | 169 | ||
163 | if ((err = snd_card_register(card)) < 0) | 170 | error = snd_card_register(card); |
164 | goto _err; | 171 | if (error < 0) |
172 | goto out; | ||
165 | 173 | ||
166 | platform_set_drvdata(pdev, card); | 174 | dev_set_drvdata(dev, card); |
167 | return 0; | 175 | return 0; |
168 | 176 | ||
169 | _err: | 177 | out: snd_card_free(card); |
170 | snd_card_free(card); | 178 | return error; |
171 | return err; | ||
172 | } | 179 | } |
173 | 180 | ||
174 | static int __devexit snd_es1688_remove(struct platform_device *devptr) | 181 | static int __devexit snd_es1688_remove(struct device *dev, unsigned int n) |
175 | { | 182 | { |
176 | snd_card_free(platform_get_drvdata(devptr)); | 183 | snd_card_free(dev_get_drvdata(dev)); |
177 | platform_set_drvdata(devptr, NULL); | 184 | dev_set_drvdata(dev, NULL); |
178 | return 0; | 185 | return 0; |
179 | } | 186 | } |
180 | 187 | ||
181 | #define ES1688_DRIVER "snd_es1688" | 188 | static struct isa_driver snd_es1688_driver = { |
182 | 189 | .match = snd_es1688_match, | |
183 | static struct platform_driver snd_es1688_driver = { | ||
184 | .probe = snd_es1688_probe, | 190 | .probe = snd_es1688_probe, |
185 | .remove = __devexit_p(snd_es1688_remove), | 191 | .remove = snd_es1688_remove, |
186 | /* FIXME: suspend/resume */ | 192 | #if 0 /* FIXME */ |
193 | .suspend = snd_es1688_suspend, | ||
194 | .resume = snd_es1688_resume, | ||
195 | #endif | ||
187 | .driver = { | 196 | .driver = { |
188 | .name = ES1688_DRIVER | 197 | .name = DEV_NAME |
189 | }, | 198 | } |
190 | }; | 199 | }; |
191 | 200 | ||
192 | static void __init_or_module snd_es1688_unregister_all(void) | ||
193 | { | ||
194 | int i; | ||
195 | |||
196 | for (i = 0; i < ARRAY_SIZE(devices); ++i) | ||
197 | platform_device_unregister(devices[i]); | ||
198 | platform_driver_unregister(&snd_es1688_driver); | ||
199 | } | ||
200 | |||
201 | static int __init alsa_card_es1688_init(void) | 201 | static int __init alsa_card_es1688_init(void) |
202 | { | 202 | { |
203 | int i, cards, err; | 203 | return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS); |
204 | |||
205 | err = platform_driver_register(&snd_es1688_driver); | ||
206 | if (err < 0) | ||
207 | return err; | ||
208 | |||
209 | cards = 0; | ||
210 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
211 | struct platform_device *device; | ||
212 | if (! enable[i]) | ||
213 | continue; | ||
214 | device = platform_device_register_simple(ES1688_DRIVER, | ||
215 | i, NULL, 0); | ||
216 | if (IS_ERR(device)) | ||
217 | continue; | ||
218 | if (!platform_get_drvdata(device)) { | ||
219 | platform_device_unregister(device); | ||
220 | continue; | ||
221 | } | ||
222 | devices[i] = device; | ||
223 | cards++; | ||
224 | } | ||
225 | if (!cards) { | ||
226 | #ifdef MODULE | ||
227 | printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n"); | ||
228 | #endif | ||
229 | snd_es1688_unregister_all(); | ||
230 | return -ENODEV; | ||
231 | } | ||
232 | return 0; | ||
233 | } | 204 | } |
234 | 205 | ||
235 | static void __exit alsa_card_es1688_exit(void) | 206 | static void __exit alsa_card_es1688_exit(void) |
236 | { | 207 | { |
237 | snd_es1688_unregister_all(); | 208 | isa_unregister_driver(&snd_es1688_driver); |
238 | } | 209 | } |
239 | 210 | ||
240 | module_init(alsa_card_es1688_init) | 211 | module_init(alsa_card_es1688_init); |
241 | module_exit(alsa_card_es1688_exit) | 212 | module_exit(alsa_card_es1688_exit); |
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 725c115ff97d..d2a9c7df0ce5 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c | |||
@@ -80,7 +80,7 @@ | |||
80 | #include <sound/driver.h> | 80 | #include <sound/driver.h> |
81 | #include <linux/init.h> | 81 | #include <linux/init.h> |
82 | #include <linux/err.h> | 82 | #include <linux/err.h> |
83 | #include <linux/platform_device.h> | 83 | #include <linux/isa.h> |
84 | #include <linux/slab.h> | 84 | #include <linux/slab.h> |
85 | #include <linux/pnp.h> | 85 | #include <linux/pnp.h> |
86 | #include <linux/isapnp.h> | 86 | #include <linux/isapnp.h> |
@@ -2035,8 +2035,6 @@ MODULE_PARM_DESC(dma1, "DMA 1 # for ES18xx driver."); | |||
2035 | module_param_array(dma2, int, NULL, 0444); | 2035 | module_param_array(dma2, int, NULL, 0444); |
2036 | MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver."); | 2036 | MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver."); |
2037 | 2037 | ||
2038 | static struct platform_device *platform_devices[SNDRV_CARDS]; | ||
2039 | |||
2040 | #ifdef CONFIG_PNP | 2038 | #ifdef CONFIG_PNP |
2041 | static int pnp_registered, pnpc_registered; | 2039 | static int pnp_registered, pnpc_registered; |
2042 | 2040 | ||
@@ -2237,7 +2235,12 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) | |||
2237 | return snd_card_register(card); | 2235 | return snd_card_register(card); |
2238 | } | 2236 | } |
2239 | 2237 | ||
2240 | static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr) | 2238 | static int __devinit snd_es18xx_isa_match(struct device *pdev, unsigned int dev) |
2239 | { | ||
2240 | return enable[dev] && !is_isapnp_selected(dev); | ||
2241 | } | ||
2242 | |||
2243 | static int __devinit snd_es18xx_isa_probe1(int dev, struct device *devptr) | ||
2241 | { | 2244 | { |
2242 | struct snd_card *card; | 2245 | struct snd_card *card; |
2243 | int err; | 2246 | int err; |
@@ -2245,18 +2248,17 @@ static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *d | |||
2245 | card = snd_es18xx_card_new(dev); | 2248 | card = snd_es18xx_card_new(dev); |
2246 | if (! card) | 2249 | if (! card) |
2247 | return -ENOMEM; | 2250 | return -ENOMEM; |
2248 | snd_card_set_dev(card, &devptr->dev); | 2251 | snd_card_set_dev(card, devptr); |
2249 | if ((err = snd_audiodrive_probe(card, dev)) < 0) { | 2252 | if ((err = snd_audiodrive_probe(card, dev)) < 0) { |
2250 | snd_card_free(card); | 2253 | snd_card_free(card); |
2251 | return err; | 2254 | return err; |
2252 | } | 2255 | } |
2253 | platform_set_drvdata(devptr, card); | 2256 | dev_set_drvdata(devptr, card); |
2254 | return 0; | 2257 | return 0; |
2255 | } | 2258 | } |
2256 | 2259 | ||
2257 | static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev) | 2260 | static int __devinit snd_es18xx_isa_probe(struct device *pdev, unsigned int dev) |
2258 | { | 2261 | { |
2259 | int dev = pdev->id; | ||
2260 | int err; | 2262 | int err; |
2261 | static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1}; | 2263 | static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1}; |
2262 | static int possible_dmas[] = {1, 0, 3, 5, -1}; | 2264 | static int possible_dmas[] = {1, 0, 3, 5, -1}; |
@@ -2281,13 +2283,13 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev) | |||
2281 | } | 2283 | } |
2282 | 2284 | ||
2283 | if (port[dev] != SNDRV_AUTO_PORT) { | 2285 | if (port[dev] != SNDRV_AUTO_PORT) { |
2284 | return snd_es18xx_nonpnp_probe1(dev, pdev); | 2286 | return snd_es18xx_isa_probe1(dev, pdev); |
2285 | } else { | 2287 | } else { |
2286 | static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280}; | 2288 | static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280}; |
2287 | int i; | 2289 | int i; |
2288 | for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { | 2290 | for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { |
2289 | port[dev] = possible_ports[i]; | 2291 | port[dev] = possible_ports[i]; |
2290 | err = snd_es18xx_nonpnp_probe1(dev, pdev); | 2292 | err = snd_es18xx_isa_probe1(dev, pdev); |
2291 | if (! err) | 2293 | if (! err) |
2292 | return 0; | 2294 | return 0; |
2293 | } | 2295 | } |
@@ -2295,43 +2297,44 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev) | |||
2295 | } | 2297 | } |
2296 | } | 2298 | } |
2297 | 2299 | ||
2298 | static int __devexit snd_es18xx_nonpnp_remove(struct platform_device *devptr) | 2300 | static int __devexit snd_es18xx_isa_remove(struct device *devptr, |
2301 | unsigned int dev) | ||
2299 | { | 2302 | { |
2300 | snd_card_free(platform_get_drvdata(devptr)); | 2303 | snd_card_free(dev_get_drvdata(devptr)); |
2301 | platform_set_drvdata(devptr, NULL); | 2304 | dev_set_drvdata(devptr, NULL); |
2302 | return 0; | 2305 | return 0; |
2303 | } | 2306 | } |
2304 | 2307 | ||
2305 | #ifdef CONFIG_PM | 2308 | #ifdef CONFIG_PM |
2306 | static int snd_es18xx_nonpnp_suspend(struct platform_device *dev, pm_message_t state) | 2309 | static int snd_es18xx_isa_suspend(struct device *dev, unsigned int n, |
2310 | pm_message_t state) | ||
2307 | { | 2311 | { |
2308 | return snd_es18xx_suspend(platform_get_drvdata(dev), state); | 2312 | return snd_es18xx_suspend(dev_get_drvdata(dev), state); |
2309 | } | 2313 | } |
2310 | 2314 | ||
2311 | static int snd_es18xx_nonpnp_resume(struct platform_device *dev) | 2315 | static int snd_es18xx_isa_resume(struct device *dev, unsigned int n) |
2312 | { | 2316 | { |
2313 | return snd_es18xx_resume(platform_get_drvdata(dev)); | 2317 | return snd_es18xx_resume(dev_get_drvdata(dev)); |
2314 | } | 2318 | } |
2315 | #endif | 2319 | #endif |
2316 | 2320 | ||
2317 | #define ES18XX_DRIVER "snd_es18xx" | 2321 | #define DEV_NAME "es18xx" |
2318 | 2322 | ||
2319 | static struct platform_driver snd_es18xx_nonpnp_driver = { | 2323 | static struct isa_driver snd_es18xx_isa_driver = { |
2320 | .probe = snd_es18xx_nonpnp_probe, | 2324 | .match = snd_es18xx_isa_match, |
2321 | .remove = __devexit_p(snd_es18xx_nonpnp_remove), | 2325 | .probe = snd_es18xx_isa_probe, |
2326 | .remove = __devexit_p(snd_es18xx_isa_remove), | ||
2322 | #ifdef CONFIG_PM | 2327 | #ifdef CONFIG_PM |
2323 | .suspend = snd_es18xx_nonpnp_suspend, | 2328 | .suspend = snd_es18xx_isa_suspend, |
2324 | .resume = snd_es18xx_nonpnp_resume, | 2329 | .resume = snd_es18xx_isa_resume, |
2325 | #endif | 2330 | #endif |
2326 | .driver = { | 2331 | .driver = { |
2327 | .name = ES18XX_DRIVER | 2332 | .name = DEV_NAME |
2328 | }, | 2333 | }, |
2329 | }; | 2334 | }; |
2330 | 2335 | ||
2331 | 2336 | ||
2332 | #ifdef CONFIG_PNP | 2337 | #ifdef CONFIG_PNP |
2333 | static unsigned int __devinitdata es18xx_pnp_devices; | ||
2334 | |||
2335 | static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev, | 2338 | static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev, |
2336 | const struct pnp_device_id *id) | 2339 | const struct pnp_device_id *id) |
2337 | { | 2340 | { |
@@ -2362,7 +2365,6 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev, | |||
2362 | } | 2365 | } |
2363 | pnp_set_drvdata(pdev, card); | 2366 | pnp_set_drvdata(pdev, card); |
2364 | dev++; | 2367 | dev++; |
2365 | es18xx_pnp_devices++; | ||
2366 | return 0; | 2368 | return 0; |
2367 | } | 2369 | } |
2368 | 2370 | ||
@@ -2424,7 +2426,6 @@ static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard, | |||
2424 | 2426 | ||
2425 | pnp_set_card_drvdata(pcard, card); | 2427 | pnp_set_card_drvdata(pcard, card); |
2426 | dev++; | 2428 | dev++; |
2427 | es18xx_pnp_devices++; | ||
2428 | return 0; | 2429 | return 0; |
2429 | } | 2430 | } |
2430 | 2431 | ||
@@ -2460,44 +2461,14 @@ static struct pnp_card_driver es18xx_pnpc_driver = { | |||
2460 | }; | 2461 | }; |
2461 | #endif /* CONFIG_PNP */ | 2462 | #endif /* CONFIG_PNP */ |
2462 | 2463 | ||
2463 | static void __init_or_module snd_es18xx_unregister_all(void) | ||
2464 | { | ||
2465 | int i; | ||
2466 | |||
2467 | #ifdef CONFIG_PNP | ||
2468 | if (pnpc_registered) | ||
2469 | pnp_unregister_card_driver(&es18xx_pnpc_driver); | ||
2470 | if (pnp_registered) | ||
2471 | pnp_unregister_driver(&es18xx_pnp_driver); | ||
2472 | #endif | ||
2473 | for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | ||
2474 | platform_device_unregister(platform_devices[i]); | ||
2475 | platform_driver_unregister(&snd_es18xx_nonpnp_driver); | ||
2476 | } | ||
2477 | |||
2478 | static int __init alsa_card_es18xx_init(void) | 2464 | static int __init alsa_card_es18xx_init(void) |
2479 | { | 2465 | { |
2480 | int i, err, cards = 0; | 2466 | int err; |
2481 | 2467 | ||
2482 | if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0) | 2468 | err = isa_register_driver(&snd_es18xx_isa_driver, SNDRV_CARDS); |
2469 | if (err < 0) | ||
2483 | return err; | 2470 | return err; |
2484 | 2471 | ||
2485 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
2486 | struct platform_device *device; | ||
2487 | if (! enable[i] || is_isapnp_selected(i)) | ||
2488 | continue; | ||
2489 | device = platform_device_register_simple(ES18XX_DRIVER, | ||
2490 | i, NULL, 0); | ||
2491 | if (IS_ERR(device)) | ||
2492 | continue; | ||
2493 | if (!platform_get_drvdata(device)) { | ||
2494 | platform_device_unregister(device); | ||
2495 | continue; | ||
2496 | } | ||
2497 | platform_devices[i] = device; | ||
2498 | cards++; | ||
2499 | } | ||
2500 | |||
2501 | #ifdef CONFIG_PNP | 2472 | #ifdef CONFIG_PNP |
2502 | err = pnp_register_driver(&es18xx_pnp_driver); | 2473 | err = pnp_register_driver(&es18xx_pnp_driver); |
2503 | if (!err) | 2474 | if (!err) |
@@ -2505,22 +2476,19 @@ static int __init alsa_card_es18xx_init(void) | |||
2505 | err = pnp_register_card_driver(&es18xx_pnpc_driver); | 2476 | err = pnp_register_card_driver(&es18xx_pnpc_driver); |
2506 | if (!err) | 2477 | if (!err) |
2507 | pnpc_registered = 1; | 2478 | pnpc_registered = 1; |
2508 | cards += es18xx_pnp_devices; | ||
2509 | #endif | ||
2510 | |||
2511 | if(!cards) { | ||
2512 | #ifdef MODULE | ||
2513 | snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n"); | ||
2514 | #endif | 2479 | #endif |
2515 | snd_es18xx_unregister_all(); | ||
2516 | return -ENODEV; | ||
2517 | } | ||
2518 | return 0; | 2480 | return 0; |
2519 | } | 2481 | } |
2520 | 2482 | ||
2521 | static void __exit alsa_card_es18xx_exit(void) | 2483 | static void __exit alsa_card_es18xx_exit(void) |
2522 | { | 2484 | { |
2523 | snd_es18xx_unregister_all(); | 2485 | #ifdef CONFIG_PNP |
2486 | if (pnpc_registered) | ||
2487 | pnp_unregister_card_driver(&es18xx_pnpc_driver); | ||
2488 | if (pnp_registered) | ||
2489 | pnp_unregister_driver(&es18xx_pnp_driver); | ||
2490 | #endif | ||
2491 | isa_unregister_driver(&snd_es18xx_isa_driver); | ||
2524 | } | 2492 | } |
2525 | 2493 | ||
2526 | module_init(alsa_card_es18xx_init) | 2494 | module_init(alsa_card_es18xx_init) |
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c index 0395e2e0dd03..8f23f433d491 100644 --- a/sound/isa/gus/gusclassic.c +++ b/sound/isa/gus/gusclassic.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/isa.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
@@ -33,8 +33,11 @@ | |||
33 | #define SNDRV_LEGACY_FIND_FREE_DMA | 33 | #define SNDRV_LEGACY_FIND_FREE_DMA |
34 | #include <sound/initval.h> | 34 | #include <sound/initval.h> |
35 | 35 | ||
36 | #define CRD_NAME "Gravis UltraSound Classic" | ||
37 | #define DEV_NAME "gusclassic" | ||
38 | |||
39 | MODULE_DESCRIPTION(CRD_NAME); | ||
36 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); | 40 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); |
37 | MODULE_DESCRIPTION("Gravis UltraSound Classic"); | ||
38 | MODULE_LICENSE("GPL"); | 41 | MODULE_LICENSE("GPL"); |
39 | MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}"); | 42 | MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}"); |
40 | 43 | ||
@@ -51,32 +54,80 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24}; | |||
51 | static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; | 54 | static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; |
52 | 55 | ||
53 | module_param_array(index, int, NULL, 0444); | 56 | module_param_array(index, int, NULL, 0444); |
54 | MODULE_PARM_DESC(index, "Index value for GUS Classic soundcard."); | 57 | MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); |
55 | module_param_array(id, charp, NULL, 0444); | 58 | module_param_array(id, charp, NULL, 0444); |
56 | MODULE_PARM_DESC(id, "ID string for GUS Classic soundcard."); | 59 | MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); |
57 | module_param_array(enable, bool, NULL, 0444); | 60 | module_param_array(enable, bool, NULL, 0444); |
58 | MODULE_PARM_DESC(enable, "Enable GUS Classic soundcard."); | 61 | MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); |
59 | module_param_array(port, long, NULL, 0444); | 62 | module_param_array(port, long, NULL, 0444); |
60 | MODULE_PARM_DESC(port, "Port # for GUS Classic driver."); | 63 | MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); |
61 | module_param_array(irq, int, NULL, 0444); | 64 | module_param_array(irq, int, NULL, 0444); |
62 | MODULE_PARM_DESC(irq, "IRQ # for GUS Classic driver."); | 65 | MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); |
63 | module_param_array(dma1, int, NULL, 0444); | 66 | module_param_array(dma1, int, NULL, 0444); |
64 | MODULE_PARM_DESC(dma1, "DMA1 # for GUS Classic driver."); | 67 | MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver."); |
65 | module_param_array(dma2, int, NULL, 0444); | 68 | module_param_array(dma2, int, NULL, 0444); |
66 | MODULE_PARM_DESC(dma2, "DMA2 # for GUS Classic driver."); | 69 | MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver."); |
67 | module_param_array(joystick_dac, int, NULL, 0444); | 70 | module_param_array(joystick_dac, int, NULL, 0444); |
68 | MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Classic driver."); | 71 | MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver."); |
69 | module_param_array(channels, int, NULL, 0444); | 72 | module_param_array(channels, int, NULL, 0444); |
70 | MODULE_PARM_DESC(channels, "GF1 channels for GUS Classic driver."); | 73 | MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver."); |
71 | module_param_array(pcm_channels, int, NULL, 0444); | 74 | module_param_array(pcm_channels, int, NULL, 0444); |
72 | MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver."); | 75 | MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver."); |
76 | |||
77 | static int __devinit snd_gusclassic_match(struct device *dev, unsigned int n) | ||
78 | { | ||
79 | return enable[n]; | ||
80 | } | ||
81 | |||
82 | static int __devinit snd_gusclassic_create(struct snd_card *card, | ||
83 | struct device *dev, unsigned int n, struct snd_gus_card **rgus) | ||
84 | { | ||
85 | static long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260}; | ||
86 | static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1}; | ||
87 | static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; | ||
88 | |||
89 | int i, error; | ||
90 | |||
91 | if (irq[n] == SNDRV_AUTO_IRQ) { | ||
92 | irq[n] = snd_legacy_find_free_irq(possible_irqs); | ||
93 | if (irq[n] < 0) { | ||
94 | snd_printk(KERN_ERR "%s: unable to find a free IRQ\n", | ||
95 | dev->bus_id); | ||
96 | return -EBUSY; | ||
97 | } | ||
98 | } | ||
99 | if (dma1[n] == SNDRV_AUTO_DMA) { | ||
100 | dma1[n] = snd_legacy_find_free_dma(possible_dmas); | ||
101 | if (dma1[n] < 0) { | ||
102 | snd_printk(KERN_ERR "%s: unable to find a free DMA1\n", | ||
103 | dev->bus_id); | ||
104 | return -EBUSY; | ||
105 | } | ||
106 | } | ||
107 | if (dma2[n] == SNDRV_AUTO_DMA) { | ||
108 | dma2[n] = snd_legacy_find_free_dma(possible_dmas); | ||
109 | if (dma2[n] < 0) { | ||
110 | snd_printk(KERN_ERR "%s: unable to find a free DMA2\n", | ||
111 | dev->bus_id); | ||
112 | return -EBUSY; | ||
113 | } | ||
114 | } | ||
73 | 115 | ||
74 | static struct platform_device *devices[SNDRV_CARDS]; | 116 | if (port[n] != SNDRV_AUTO_PORT) |
117 | return snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n], | ||
118 | 0, channels[n], pcm_channels[n], 0, rgus); | ||
75 | 119 | ||
120 | i = 0; | ||
121 | do { | ||
122 | port[n] = possible_ports[i]; | ||
123 | error = snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n], | ||
124 | 0, channels[n], pcm_channels[n], 0, rgus); | ||
125 | } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); | ||
76 | 126 | ||
77 | #define PFX "gusclassic: " | 127 | return error; |
128 | } | ||
78 | 129 | ||
79 | static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus) | 130 | static int __devinit snd_gusclassic_detect(struct snd_gus_card *gus) |
80 | { | 131 | { |
81 | unsigned char d; | 132 | unsigned char d; |
82 | 133 | ||
@@ -95,187 +146,104 @@ static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus) | |||
95 | return 0; | 146 | return 0; |
96 | } | 147 | } |
97 | 148 | ||
98 | static void __devinit snd_gusclassic_init(int dev, struct snd_gus_card * gus) | 149 | static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n) |
99 | { | ||
100 | gus->equal_irq = 0; | ||
101 | gus->codec_flag = 0; | ||
102 | gus->max_flag = 0; | ||
103 | gus->joystick_dac = joystick_dac[dev]; | ||
104 | } | ||
105 | |||
106 | static int __devinit snd_gusclassic_probe(struct platform_device *pdev) | ||
107 | { | 150 | { |
108 | int dev = pdev->id; | ||
109 | static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1}; | ||
110 | static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; | ||
111 | int xirq, xdma1, xdma2; | ||
112 | struct snd_card *card; | 151 | struct snd_card *card; |
113 | struct snd_gus_card *gus = NULL; | 152 | struct snd_gus_card *gus; |
114 | int err; | 153 | int error; |
115 | |||
116 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | ||
117 | if (card == NULL) | ||
118 | return -ENOMEM; | ||
119 | if (pcm_channels[dev] < 2) | ||
120 | pcm_channels[dev] = 2; | ||
121 | |||
122 | xirq = irq[dev]; | ||
123 | if (xirq == SNDRV_AUTO_IRQ) { | ||
124 | if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) { | ||
125 | snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); | ||
126 | err = -EBUSY; | ||
127 | goto _err; | ||
128 | } | ||
129 | } | ||
130 | xdma1 = dma1[dev]; | ||
131 | if (xdma1 == SNDRV_AUTO_DMA) { | ||
132 | if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) { | ||
133 | snd_printk(KERN_ERR PFX "unable to find a free DMA1\n"); | ||
134 | err = -EBUSY; | ||
135 | goto _err; | ||
136 | } | ||
137 | } | ||
138 | xdma2 = dma2[dev]; | ||
139 | if (xdma2 == SNDRV_AUTO_DMA) { | ||
140 | if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) { | ||
141 | snd_printk(KERN_ERR PFX "unable to find a free DMA2\n"); | ||
142 | err = -EBUSY; | ||
143 | goto _err; | ||
144 | } | ||
145 | } | ||
146 | 154 | ||
147 | if (port[dev] != SNDRV_AUTO_PORT) { | 155 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); |
148 | err = snd_gus_create(card, | 156 | if (!card) |
149 | port[dev], | 157 | return -EINVAL; |
150 | xirq, xdma1, xdma2, | ||
151 | 0, channels[dev], pcm_channels[dev], | ||
152 | 0, &gus); | ||
153 | } else { | ||
154 | /* auto-probe legacy ports */ | ||
155 | static unsigned long possible_ports[] = { | ||
156 | 0x220, 0x230, 0x240, 0x250, 0x260, | ||
157 | }; | ||
158 | int i; | ||
159 | for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { | ||
160 | err = snd_gus_create(card, | ||
161 | possible_ports[i], | ||
162 | xirq, xdma1, xdma2, | ||
163 | 0, channels[dev], pcm_channels[dev], | ||
164 | 0, &gus); | ||
165 | if (err >= 0) { | ||
166 | port[dev] = possible_ports[i]; | ||
167 | break; | ||
168 | } | ||
169 | } | ||
170 | } | ||
171 | if (err < 0) | ||
172 | goto _err; | ||
173 | 158 | ||
174 | if ((err = snd_gusclassic_detect(gus)) < 0) | 159 | if (pcm_channels[n] < 2) |
175 | goto _err; | 160 | pcm_channels[n] = 2; |
176 | 161 | ||
177 | snd_gusclassic_init(dev, gus); | 162 | error = snd_gusclassic_create(card, dev, n, &gus); |
178 | if ((err = snd_gus_initialize(gus)) < 0) | 163 | if (error < 0) |
179 | goto _err; | 164 | goto out; |
180 | 165 | ||
166 | error = snd_gusclassic_detect(gus); | ||
167 | if (error < 0) | ||
168 | goto out; | ||
169 | |||
170 | gus->joystick_dac = joystick_dac[n]; | ||
171 | |||
172 | error = snd_gus_initialize(gus); | ||
173 | if (error < 0) | ||
174 | goto out; | ||
175 | |||
176 | error = -ENODEV; | ||
181 | if (gus->max_flag || gus->ess_flag) { | 177 | if (gus->max_flag || gus->ess_flag) { |
182 | snd_printk(KERN_ERR PFX "GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port); | 178 | snd_printk(KERN_ERR "%s: GUS Classic or ACE soundcard was " |
183 | err = -ENODEV; | 179 | "not detected at 0x%lx\n", dev->bus_id, gus->gf1.port); |
184 | goto _err; | 180 | goto out; |
185 | } | 181 | } |
186 | 182 | ||
187 | if ((err = snd_gf1_new_mixer(gus)) < 0) | 183 | error = snd_gf1_new_mixer(gus); |
188 | goto _err; | 184 | if (error < 0) |
185 | goto out; | ||
189 | 186 | ||
190 | if ((err = snd_gf1_pcm_new(gus, 0, 0, NULL)) < 0) | 187 | error = snd_gf1_pcm_new(gus, 0, 0, NULL); |
191 | goto _err; | 188 | if (error < 0) |
189 | goto out; | ||
192 | 190 | ||
193 | if (!gus->ace_flag) { | 191 | if (!gus->ace_flag) { |
194 | if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) | 192 | error = snd_gf1_rawmidi_new(gus, 0, NULL); |
195 | goto _err; | 193 | if (error < 0) |
194 | goto out; | ||
196 | } | 195 | } |
197 | sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %d, dma %d", gus->gf1.port, xirq, xdma1); | ||
198 | if (xdma2 >= 0) | ||
199 | sprintf(card->longname + strlen(card->longname), "&%d", xdma2); | ||
200 | 196 | ||
201 | snd_card_set_dev(card, &pdev->dev); | 197 | sprintf(card->longname + strlen(card->longname), |
198 | " at 0x%lx, irq %d, dma %d", | ||
199 | gus->gf1.port, gus->gf1.irq, gus->gf1.dma1); | ||
202 | 200 | ||
203 | if ((err = snd_card_register(card)) < 0) | 201 | if (gus->gf1.dma2 >= 0) |
204 | goto _err; | 202 | sprintf(card->longname + strlen(card->longname), |
203 | "&%d", gus->gf1.dma2); | ||
205 | 204 | ||
206 | platform_set_drvdata(pdev, card); | 205 | snd_card_set_dev(card, dev); |
206 | |||
207 | error = snd_card_register(card); | ||
208 | if (error < 0) | ||
209 | goto out; | ||
210 | |||
211 | dev_set_drvdata(dev, card); | ||
207 | return 0; | 212 | return 0; |
208 | 213 | ||
209 | _err: | 214 | out: snd_card_free(card); |
210 | snd_card_free(card); | 215 | return error; |
211 | return err; | ||
212 | } | 216 | } |
213 | 217 | ||
214 | static int __devexit snd_gusclassic_remove(struct platform_device *devptr) | 218 | static int __devexit snd_gusclassic_remove(struct device *dev, unsigned int n) |
215 | { | 219 | { |
216 | snd_card_free(platform_get_drvdata(devptr)); | 220 | snd_card_free(dev_get_drvdata(dev)); |
217 | platform_set_drvdata(devptr, NULL); | 221 | dev_set_drvdata(dev, NULL); |
218 | return 0; | 222 | return 0; |
219 | } | 223 | } |
220 | 224 | ||
221 | #define GUSCLASSIC_DRIVER "snd_gusclassic" | 225 | static struct isa_driver snd_gusclassic_driver = { |
222 | 226 | .match = snd_gusclassic_match, | |
223 | static struct platform_driver snd_gusclassic_driver = { | ||
224 | .probe = snd_gusclassic_probe, | 227 | .probe = snd_gusclassic_probe, |
225 | .remove = __devexit_p(snd_gusclassic_remove), | 228 | .remove = __devexit_p(snd_gusclassic_remove), |
226 | /* FIXME: suspend/resume */ | 229 | #if 0 /* FIXME */ |
230 | .suspend = snd_gusclassic_suspend, | ||
231 | .remove = snd_gusclassic_remove, | ||
232 | #endif | ||
227 | .driver = { | 233 | .driver = { |
228 | .name = GUSCLASSIC_DRIVER | 234 | .name = DEV_NAME |
229 | }, | 235 | } |
230 | }; | 236 | }; |
231 | 237 | ||
232 | static void __init_or_module snd_gusclassic_unregister_all(void) | ||
233 | { | ||
234 | int i; | ||
235 | |||
236 | for (i = 0; i < ARRAY_SIZE(devices); ++i) | ||
237 | platform_device_unregister(devices[i]); | ||
238 | platform_driver_unregister(&snd_gusclassic_driver); | ||
239 | } | ||
240 | |||
241 | static int __init alsa_card_gusclassic_init(void) | 238 | static int __init alsa_card_gusclassic_init(void) |
242 | { | 239 | { |
243 | int i, cards, err; | 240 | return isa_register_driver(&snd_gusclassic_driver, SNDRV_CARDS); |
244 | |||
245 | err = platform_driver_register(&snd_gusclassic_driver); | ||
246 | if (err < 0) | ||
247 | return err; | ||
248 | |||
249 | cards = 0; | ||
250 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
251 | struct platform_device *device; | ||
252 | if (! enable[i]) | ||
253 | continue; | ||
254 | device = platform_device_register_simple(GUSCLASSIC_DRIVER, | ||
255 | i, NULL, 0); | ||
256 | if (IS_ERR(device)) | ||
257 | continue; | ||
258 | if (!platform_get_drvdata(device)) { | ||
259 | platform_device_unregister(device); | ||
260 | continue; | ||
261 | } | ||
262 | devices[i] = device; | ||
263 | cards++; | ||
264 | } | ||
265 | if (!cards) { | ||
266 | #ifdef MODULE | ||
267 | printk(KERN_ERR "GUS Classic soundcard not found or device busy\n"); | ||
268 | #endif | ||
269 | snd_gusclassic_unregister_all(); | ||
270 | return -ENODEV; | ||
271 | } | ||
272 | return 0; | ||
273 | } | 241 | } |
274 | 242 | ||
275 | static void __exit alsa_card_gusclassic_exit(void) | 243 | static void __exit alsa_card_gusclassic_exit(void) |
276 | { | 244 | { |
277 | snd_gusclassic_unregister_all(); | 245 | isa_unregister_driver(&snd_gusclassic_driver); |
278 | } | 246 | } |
279 | 247 | ||
280 | module_init(alsa_card_gusclassic_init) | 248 | module_init(alsa_card_gusclassic_init); |
281 | module_exit(alsa_card_gusclassic_exit) | 249 | module_exit(alsa_card_gusclassic_exit); |
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 4f55fc3e66c1..0aeaa6cf6cf0 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/isa.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
@@ -37,8 +37,11 @@ | |||
37 | #define SNDRV_LEGACY_FIND_FREE_DMA | 37 | #define SNDRV_LEGACY_FIND_FREE_DMA |
38 | #include <sound/initval.h> | 38 | #include <sound/initval.h> |
39 | 39 | ||
40 | #define CRD_NAME "Gravis UltraSound Extreme" | ||
41 | #define DEV_NAME "gusextreme" | ||
42 | |||
43 | MODULE_DESCRIPTION(CRD_NAME); | ||
40 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); | 44 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); |
41 | MODULE_DESCRIPTION("Gravis UltraSound Extreme"); | ||
42 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
43 | MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}"); | 46 | MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}"); |
44 | 47 | ||
@@ -59,43 +62,107 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24}; | |||
59 | static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; | 62 | static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; |
60 | 63 | ||
61 | module_param_array(index, int, NULL, 0444); | 64 | module_param_array(index, int, NULL, 0444); |
62 | MODULE_PARM_DESC(index, "Index value for GUS Extreme soundcard."); | 65 | MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); |
63 | module_param_array(id, charp, NULL, 0444); | 66 | module_param_array(id, charp, NULL, 0444); |
64 | MODULE_PARM_DESC(id, "ID string for GUS Extreme soundcard."); | 67 | MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); |
65 | module_param_array(enable, bool, NULL, 0444); | 68 | module_param_array(enable, bool, NULL, 0444); |
66 | MODULE_PARM_DESC(enable, "Enable GUS Extreme soundcard."); | 69 | MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); |
67 | module_param_array(port, long, NULL, 0444); | 70 | module_param_array(port, long, NULL, 0444); |
68 | MODULE_PARM_DESC(port, "Port # for GUS Extreme driver."); | 71 | MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); |
69 | module_param_array(gf1_port, long, NULL, 0444); | 72 | module_param_array(gf1_port, long, NULL, 0444); |
70 | MODULE_PARM_DESC(gf1_port, "GF1 port # for GUS Extreme driver (optional)."); | 73 | MODULE_PARM_DESC(gf1_port, "GF1 port # for " CRD_NAME " driver (optional)."); |
71 | module_param_array(mpu_port, long, NULL, 0444); | 74 | module_param_array(mpu_port, long, NULL, 0444); |
72 | MODULE_PARM_DESC(mpu_port, "MPU-401 port # for GUS Extreme driver."); | 75 | MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); |
73 | module_param_array(irq, int, NULL, 0444); | 76 | module_param_array(irq, int, NULL, 0444); |
74 | MODULE_PARM_DESC(irq, "IRQ # for GUS Extreme driver."); | 77 | MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); |
75 | module_param_array(mpu_irq, int, NULL, 0444); | 78 | module_param_array(mpu_irq, int, NULL, 0444); |
76 | MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for GUS Extreme driver."); | 79 | MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); |
77 | module_param_array(gf1_irq, int, NULL, 0444); | 80 | module_param_array(gf1_irq, int, NULL, 0444); |
78 | MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for GUS Extreme driver."); | 81 | MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for " CRD_NAME " driver."); |
79 | module_param_array(dma8, int, NULL, 0444); | 82 | module_param_array(dma8, int, NULL, 0444); |
80 | MODULE_PARM_DESC(dma8, "8-bit DMA # for GUS Extreme driver."); | 83 | MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); |
81 | module_param_array(dma1, int, NULL, 0444); | 84 | module_param_array(dma1, int, NULL, 0444); |
82 | MODULE_PARM_DESC(dma1, "GF1 DMA # for GUS Extreme driver."); | 85 | MODULE_PARM_DESC(dma1, "GF1 DMA # for " CRD_NAME " driver."); |
83 | module_param_array(joystick_dac, int, NULL, 0444); | 86 | module_param_array(joystick_dac, int, NULL, 0444); |
84 | MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Extreme driver."); | 87 | MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver."); |
85 | module_param_array(channels, int, NULL, 0444); | 88 | module_param_array(channels, int, NULL, 0444); |
86 | MODULE_PARM_DESC(channels, "GF1 channels for GUS Extreme driver."); | 89 | MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver."); |
87 | module_param_array(pcm_channels, int, NULL, 0444); | 90 | module_param_array(pcm_channels, int, NULL, 0444); |
88 | MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver."); | 91 | MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver."); |
92 | |||
93 | static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n) | ||
94 | { | ||
95 | return enable[n]; | ||
96 | } | ||
97 | |||
98 | static int __devinit snd_gusextreme_es1688_create(struct snd_card *card, | ||
99 | struct device *dev, unsigned int n, struct snd_es1688 **rchip) | ||
100 | { | ||
101 | static long possible_ports[] = {0x220, 0x240, 0x260}; | ||
102 | static int possible_irqs[] = {5, 9, 10, 7, -1}; | ||
103 | static int possible_dmas[] = {1, 3, 0, -1}; | ||
104 | |||
105 | int i, error; | ||
106 | |||
107 | if (irq[n] == SNDRV_AUTO_IRQ) { | ||
108 | irq[n] = snd_legacy_find_free_irq(possible_irqs); | ||
109 | if (irq[n] < 0) { | ||
110 | snd_printk(KERN_ERR "%s: unable to find a free IRQ " | ||
111 | "for ES1688\n", dev->bus_id); | ||
112 | return -EBUSY; | ||
113 | } | ||
114 | } | ||
115 | if (dma8[n] == SNDRV_AUTO_DMA) { | ||
116 | dma8[n] = snd_legacy_find_free_dma(possible_dmas); | ||
117 | if (dma8[n] < 0) { | ||
118 | snd_printk(KERN_ERR "%s: unable to find a free DMA " | ||
119 | "for ES1688\n", dev->bus_id); | ||
120 | return -EBUSY; | ||
121 | } | ||
122 | } | ||
89 | 123 | ||
90 | static struct platform_device *devices[SNDRV_CARDS]; | 124 | if (port[n] != SNDRV_AUTO_PORT) |
125 | return snd_es1688_create(card, port[n], mpu_port[n], irq[n], | ||
126 | mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); | ||
91 | 127 | ||
128 | i = 0; | ||
129 | do { | ||
130 | port[n] = possible_ports[i]; | ||
131 | error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], | ||
132 | mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); | ||
133 | } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); | ||
92 | 134 | ||
93 | #define PFX "gusextreme: " | 135 | return error; |
136 | } | ||
94 | 137 | ||
95 | static int __devinit snd_gusextreme_detect(int dev, | 138 | static int __devinit snd_gusextreme_gus_card_create(struct snd_card *card, |
96 | struct snd_card *card, | 139 | struct device *dev, unsigned int n, struct snd_gus_card **rgus) |
97 | struct snd_gus_card * gus, | 140 | { |
98 | struct snd_es1688 *es1688) | 141 | static int possible_irqs[] = {11, 12, 15, 9, 5, 7, 3, -1}; |
142 | static int possible_dmas[] = {5, 6, 7, 3, 1, -1}; | ||
143 | |||
144 | if (gf1_irq[n] == SNDRV_AUTO_IRQ) { | ||
145 | gf1_irq[n] = snd_legacy_find_free_irq(possible_irqs); | ||
146 | if (gf1_irq[n] < 0) { | ||
147 | snd_printk(KERN_ERR "%s: unable to find a free IRQ " | ||
148 | "for GF1\n", dev->bus_id); | ||
149 | return -EBUSY; | ||
150 | } | ||
151 | } | ||
152 | if (dma1[n] == SNDRV_AUTO_DMA) { | ||
153 | dma1[n] = snd_legacy_find_free_dma(possible_dmas); | ||
154 | if (dma1[n] < 0) { | ||
155 | snd_printk(KERN_ERR "%s: unable to find a free DMA " | ||
156 | "for GF1\n", dev->bus_id); | ||
157 | return -EBUSY; | ||
158 | } | ||
159 | } | ||
160 | return snd_gus_create(card, gf1_port[n], gf1_irq[n], dma1[n], -1, | ||
161 | 0, channels[n], pcm_channels[n], 0, rgus); | ||
162 | } | ||
163 | |||
164 | static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus, | ||
165 | struct snd_es1688 *es1688) | ||
99 | { | 166 | { |
100 | unsigned long flags; | 167 | unsigned long flags; |
101 | unsigned char d; | 168 | unsigned char d; |
@@ -117,12 +184,13 @@ static int __devinit snd_gusextreme_detect(int dev, | |||
117 | spin_lock_irqsave(&es1688->mixer_lock, flags); | 184 | spin_lock_irqsave(&es1688->mixer_lock, flags); |
118 | snd_es1688_mixer_write(es1688, 0x40, 0x0b); /* don't change!!! */ | 185 | snd_es1688_mixer_write(es1688, 0x40, 0x0b); /* don't change!!! */ |
119 | spin_unlock_irqrestore(&es1688->mixer_lock, flags); | 186 | spin_unlock_irqrestore(&es1688->mixer_lock, flags); |
187 | |||
120 | spin_lock_irqsave(&es1688->reg_lock, flags); | 188 | spin_lock_irqsave(&es1688->reg_lock, flags); |
121 | outb(gf1_port[dev] & 0x040 ? 2 : 0, ES1688P(es1688, INIT1)); | 189 | outb(gus->gf1.port & 0x040 ? 2 : 0, ES1688P(es1688, INIT1)); |
122 | outb(0, 0x201); | 190 | outb(0, 0x201); |
123 | outb(gf1_port[dev] & 0x020 ? 2 : 0, ES1688P(es1688, INIT1)); | 191 | outb(gus->gf1.port & 0x020 ? 2 : 0, ES1688P(es1688, INIT1)); |
124 | outb(0, 0x201); | 192 | outb(0, 0x201); |
125 | outb(gf1_port[dev] & 0x010 ? 3 : 1, ES1688P(es1688, INIT1)); | 193 | outb(gus->gf1.port & 0x010 ? 3 : 1, ES1688P(es1688, INIT1)); |
126 | spin_unlock_irqrestore(&es1688->reg_lock, flags); | 194 | spin_unlock_irqrestore(&es1688->reg_lock, flags); |
127 | 195 | ||
128 | udelay(100); | 196 | udelay(100); |
@@ -139,253 +207,172 @@ static int __devinit snd_gusextreme_detect(int dev, | |||
139 | snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d); | 207 | snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d); |
140 | return -EIO; | 208 | return -EIO; |
141 | } | 209 | } |
142 | return 0; | ||
143 | } | ||
144 | 210 | ||
145 | static void __devinit snd_gusextreme_init(int dev, struct snd_gus_card * gus) | 211 | return 0; |
146 | { | ||
147 | gus->joystick_dac = joystick_dac[dev]; | ||
148 | } | 212 | } |
149 | 213 | ||
150 | static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip) | 214 | static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip) |
151 | { | 215 | { |
152 | struct snd_card *card = chip->card; | 216 | struct snd_card *card = chip->card; |
153 | struct snd_ctl_elem_id id1, id2; | 217 | struct snd_ctl_elem_id id1, id2; |
154 | int err; | 218 | int error; |
155 | 219 | ||
156 | memset(&id1, 0, sizeof(id1)); | 220 | memset(&id1, 0, sizeof(id1)); |
157 | memset(&id2, 0, sizeof(id2)); | 221 | memset(&id2, 0, sizeof(id2)); |
158 | id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 222 | id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
223 | |||
159 | /* reassign AUX to SYNTHESIZER */ | 224 | /* reassign AUX to SYNTHESIZER */ |
160 | strcpy(id1.name, "Aux Playback Volume"); | 225 | strcpy(id1.name, "Aux Playback Volume"); |
161 | strcpy(id2.name, "Synth Playback Volume"); | 226 | strcpy(id2.name, "Synth Playback Volume"); |
162 | if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) | 227 | error = snd_ctl_rename_id(card, &id1, &id2); |
163 | return err; | 228 | if (error < 0) |
229 | return error; | ||
230 | |||
164 | /* reassign Master Playback Switch to Synth Playback Switch */ | 231 | /* reassign Master Playback Switch to Synth Playback Switch */ |
165 | strcpy(id1.name, "Master Playback Switch"); | 232 | strcpy(id1.name, "Master Playback Switch"); |
166 | strcpy(id2.name, "Synth Playback Switch"); | 233 | strcpy(id2.name, "Synth Playback Switch"); |
167 | if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) | 234 | error = snd_ctl_rename_id(card, &id1, &id2); |
168 | return err; | 235 | if (error < 0) |
236 | return error; | ||
237 | |||
169 | return 0; | 238 | return 0; |
170 | } | 239 | } |
171 | 240 | ||
172 | static int __devinit snd_gusextreme_probe(struct platform_device *pdev) | 241 | static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) |
173 | { | 242 | { |
174 | int dev = pdev->id; | ||
175 | static int possible_ess_irqs[] = {5, 9, 10, 7, -1}; | ||
176 | static int possible_ess_dmas[] = {1, 3, 0, -1}; | ||
177 | static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; | ||
178 | static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1}; | ||
179 | int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma; | ||
180 | struct snd_card *card; | 243 | struct snd_card *card; |
181 | struct snd_gus_card *gus; | 244 | struct snd_gus_card *gus; |
182 | struct snd_es1688 *es1688; | 245 | struct snd_es1688 *es1688; |
183 | struct snd_opl3 *opl3; | 246 | struct snd_opl3 *opl3; |
184 | int err; | 247 | int error; |
185 | 248 | ||
186 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 249 | card = snd_card_new(index[n], id[n], THIS_MODULE, 0); |
187 | if (card == NULL) | 250 | if (!card) |
188 | return -ENOMEM; | 251 | return -EINVAL; |
189 | 252 | ||
190 | xgf1_irq = gf1_irq[dev]; | 253 | if (mpu_port[n] == SNDRV_AUTO_PORT) |
191 | if (xgf1_irq == SNDRV_AUTO_IRQ) { | 254 | mpu_port[n] = 0; |
192 | if ((xgf1_irq = snd_legacy_find_free_irq(possible_gf1_irqs)) < 0) { | ||
193 | snd_printk(KERN_ERR PFX "unable to find a free IRQ for GF1\n"); | ||
194 | err = -EBUSY; | ||
195 | goto out; | ||
196 | } | ||
197 | } | ||
198 | xess_irq = irq[dev]; | ||
199 | if (xess_irq == SNDRV_AUTO_IRQ) { | ||
200 | if ((xess_irq = snd_legacy_find_free_irq(possible_ess_irqs)) < 0) { | ||
201 | snd_printk(KERN_ERR PFX "unable to find a free IRQ for ES1688\n"); | ||
202 | err = -EBUSY; | ||
203 | goto out; | ||
204 | } | ||
205 | } | ||
206 | if (mpu_port[dev] == SNDRV_AUTO_PORT) | ||
207 | mpu_port[dev] = 0; | ||
208 | xmpu_irq = mpu_irq[dev]; | ||
209 | if (xmpu_irq > 15) | ||
210 | xmpu_irq = -1; | ||
211 | xgf1_dma = dma1[dev]; | ||
212 | if (xgf1_dma == SNDRV_AUTO_DMA) { | ||
213 | if ((xgf1_dma = snd_legacy_find_free_dma(possible_gf1_dmas)) < 0) { | ||
214 | snd_printk(KERN_ERR PFX "unable to find a free DMA for GF1\n"); | ||
215 | err = -EBUSY; | ||
216 | goto out; | ||
217 | } | ||
218 | } | ||
219 | xess_dma = dma8[dev]; | ||
220 | if (xess_dma == SNDRV_AUTO_DMA) { | ||
221 | if ((xess_dma = snd_legacy_find_free_dma(possible_ess_dmas)) < 0) { | ||
222 | snd_printk(KERN_ERR PFX "unable to find a free DMA for ES1688\n"); | ||
223 | err = -EBUSY; | ||
224 | goto out; | ||
225 | } | ||
226 | } | ||
227 | 255 | ||
228 | if (port[dev] != SNDRV_AUTO_PORT) { | 256 | if (mpu_irq[n] > 15) |
229 | err = snd_es1688_create(card, port[dev], mpu_port[dev], | 257 | mpu_irq[n] = -1; |
230 | xess_irq, xmpu_irq, xess_dma, | 258 | |
231 | ES1688_HW_1688, &es1688); | 259 | error = snd_gusextreme_es1688_create(card, dev, n, &es1688); |
232 | } else { | 260 | if (error < 0) |
233 | /* auto-probe legacy ports */ | ||
234 | static unsigned long possible_ports[] = {0x220, 0x240, 0x260}; | ||
235 | int i; | ||
236 | for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { | ||
237 | err = snd_es1688_create(card, | ||
238 | possible_ports[i], | ||
239 | mpu_port[dev], | ||
240 | xess_irq, xmpu_irq, xess_dma, | ||
241 | ES1688_HW_1688, &es1688); | ||
242 | if (err >= 0) { | ||
243 | port[dev] = possible_ports[i]; | ||
244 | break; | ||
245 | } | ||
246 | } | ||
247 | } | ||
248 | if (err < 0) | ||
249 | goto out; | 261 | goto out; |
250 | 262 | ||
251 | if (gf1_port[dev] < 0) | 263 | if (gf1_port[n] < 0) |
252 | gf1_port[dev] = port[dev] + 0x20; | 264 | gf1_port[n] = es1688->port + 0x20; |
253 | if ((err = snd_gus_create(card, | 265 | |
254 | gf1_port[dev], | 266 | error = snd_gusextreme_gus_card_create(card, dev, n, &gus); |
255 | xgf1_irq, | 267 | if (error < 0) |
256 | xgf1_dma, | ||
257 | -1, | ||
258 | 0, channels[dev], | ||
259 | pcm_channels[dev], 0, | ||
260 | &gus)) < 0) | ||
261 | goto out; | 268 | goto out; |
262 | 269 | ||
263 | if ((err = snd_gusextreme_detect(dev, card, gus, es1688)) < 0) | 270 | error = snd_gusextreme_detect(gus, es1688); |
271 | if (error < 0) | ||
264 | goto out; | 272 | goto out; |
265 | 273 | ||
266 | snd_gusextreme_init(dev, gus); | 274 | gus->joystick_dac = joystick_dac[n]; |
267 | if ((err = snd_gus_initialize(gus)) < 0) | 275 | |
276 | error = snd_gus_initialize(gus); | ||
277 | if (error < 0) | ||
268 | goto out; | 278 | goto out; |
269 | 279 | ||
280 | error = -ENODEV; | ||
270 | if (!gus->ess_flag) { | 281 | if (!gus->ess_flag) { |
271 | snd_printk(KERN_ERR PFX "GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port); | 282 | snd_printk(KERN_ERR "%s: GUS Extreme soundcard was not " |
272 | err = -ENODEV; | 283 | "detected at 0x%lx\n", dev->bus_id, gus->gf1.port); |
273 | goto out; | 284 | goto out; |
274 | } | 285 | } |
275 | if ((err = snd_es1688_pcm(es1688, 0, NULL)) < 0) | 286 | gus->codec_flag = 1; |
287 | |||
288 | error = snd_es1688_pcm(es1688, 0, NULL); | ||
289 | if (error < 0) | ||
276 | goto out; | 290 | goto out; |
277 | 291 | ||
278 | if ((err = snd_es1688_mixer(es1688)) < 0) | 292 | error = snd_es1688_mixer(es1688); |
293 | if (error < 0) | ||
279 | goto out; | 294 | goto out; |
280 | 295 | ||
281 | snd_component_add(card, "ES1688"); | 296 | snd_component_add(card, "ES1688"); |
282 | if (pcm_channels[dev] > 0) { | 297 | |
283 | if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) | 298 | if (pcm_channels[n] > 0) { |
299 | error = snd_gf1_pcm_new(gus, 1, 1, NULL); | ||
300 | if (error < 0) | ||
284 | goto out; | 301 | goto out; |
285 | } | 302 | } |
286 | if ((err = snd_gf1_new_mixer(gus)) < 0) | 303 | |
304 | error = snd_gf1_new_mixer(gus); | ||
305 | if (error < 0) | ||
287 | goto out; | 306 | goto out; |
288 | 307 | ||
289 | if ((err = snd_gusextreme_mixer(es1688)) < 0) | 308 | error = snd_gusextreme_mixer(es1688); |
309 | if (error < 0) | ||
290 | goto out; | 310 | goto out; |
291 | 311 | ||
292 | if (snd_opl3_create(card, es1688->port, es1688->port + 2, | 312 | if (snd_opl3_create(card, es1688->port, es1688->port + 2, |
293 | OPL3_HW_OPL3, 0, &opl3) < 0) { | 313 | OPL3_HW_OPL3, 0, &opl3) < 0) |
294 | printk(KERN_ERR PFX "gusextreme: opl3 not detected at 0x%lx\n", es1688->port); | 314 | printk(KERN_ERR "%s: opl3 not detected at 0x%lx\n", |
295 | } else { | 315 | dev->bus_id, es1688->port); |
296 | if ((err = snd_opl3_hwdep_new(opl3, 0, 2, NULL)) < 0) | 316 | else { |
317 | error = snd_opl3_hwdep_new(opl3, 0, 2, NULL); | ||
318 | if (error < 0) | ||
297 | goto out; | 319 | goto out; |
298 | } | 320 | } |
299 | 321 | ||
300 | if (es1688->mpu_port >= 0x300 && | 322 | if (es1688->mpu_port >= 0x300) { |
301 | (err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, | 323 | error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, |
302 | es1688->mpu_port, 0, | 324 | es1688->mpu_port, 0, |
303 | xmpu_irq, | 325 | mpu_irq[n], IRQF_DISABLED, NULL); |
304 | IRQF_DISABLED, | 326 | if (error < 0) |
305 | NULL)) < 0) | 327 | goto out; |
306 | goto out; | 328 | } |
307 | 329 | ||
308 | sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i", | 330 | sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, " |
309 | es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma); | 331 | "irq %i&%i, dma %i&%i", es1688->port, |
332 | gus->gf1.irq, es1688->irq, gus->gf1.dma1, es1688->dma8); | ||
310 | 333 | ||
311 | snd_card_set_dev(card, &pdev->dev); | 334 | snd_card_set_dev(card, dev); |
312 | 335 | ||
313 | if ((err = snd_card_register(card)) < 0) | 336 | error = snd_card_register(card); |
337 | if (error < 0) | ||
314 | goto out; | 338 | goto out; |
315 | 339 | ||
316 | platform_set_drvdata(pdev, card); | 340 | dev_set_drvdata(dev, card); |
317 | return 0; | 341 | return 0; |
318 | 342 | ||
319 | out: | 343 | out: snd_card_free(card); |
320 | snd_card_free(card); | 344 | return error; |
321 | return err; | ||
322 | } | 345 | } |
323 | 346 | ||
324 | static int __devexit snd_gusextreme_remove(struct platform_device *devptr) | 347 | static int __devexit snd_gusextreme_remove(struct device *dev, unsigned int n) |
325 | { | 348 | { |
326 | snd_card_free(platform_get_drvdata(devptr)); | 349 | snd_card_free(dev_get_drvdata(dev)); |
327 | platform_set_drvdata(devptr, NULL); | 350 | dev_set_drvdata(dev, NULL); |
328 | return 0; | 351 | return 0; |
329 | } | 352 | } |
330 | 353 | ||
331 | #define GUSEXTREME_DRIVER "snd_gusextreme" | 354 | static struct isa_driver snd_gusextreme_driver = { |
332 | 355 | .match = snd_gusextreme_match, | |
333 | static struct platform_driver snd_gusextreme_driver = { | ||
334 | .probe = snd_gusextreme_probe, | 356 | .probe = snd_gusextreme_probe, |
335 | .remove = __devexit_p(snd_gusextreme_remove), | 357 | .remove = snd_gusextreme_remove, |
336 | /* FIXME: suspend/resume */ | 358 | #if 0 /* FIXME */ |
359 | .suspend = snd_gusextreme_suspend, | ||
360 | .resume = snd_gusextreme_resume, | ||
361 | #endif | ||
337 | .driver = { | 362 | .driver = { |
338 | .name = GUSEXTREME_DRIVER | 363 | .name = DEV_NAME |
339 | }, | 364 | } |
340 | }; | 365 | }; |
341 | 366 | ||
342 | static void __init_or_module snd_gusextreme_unregister_all(void) | ||
343 | { | ||
344 | int i; | ||
345 | |||
346 | for (i = 0; i < ARRAY_SIZE(devices); ++i) | ||
347 | platform_device_unregister(devices[i]); | ||
348 | platform_driver_unregister(&snd_gusextreme_driver); | ||
349 | } | ||
350 | |||
351 | static int __init alsa_card_gusextreme_init(void) | 367 | static int __init alsa_card_gusextreme_init(void) |
352 | { | 368 | { |
353 | int i, cards, err; | 369 | return isa_register_driver(&snd_gusextreme_driver, SNDRV_CARDS); |
354 | |||
355 | err = platform_driver_register(&snd_gusextreme_driver); | ||
356 | if (err < 0) | ||
357 | return err; | ||
358 | |||
359 | cards = 0; | ||
360 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
361 | struct platform_device *device; | ||
362 | if (! enable[i]) | ||
363 | continue; | ||
364 | device = platform_device_register_simple(GUSEXTREME_DRIVER, | ||
365 | i, NULL, 0); | ||
366 | if (IS_ERR(device)) | ||
367 | continue; | ||
368 | if (!platform_get_drvdata(device)) { | ||
369 | platform_device_unregister(device); | ||
370 | continue; | ||
371 | } | ||
372 | devices[i] = device; | ||
373 | cards++; | ||
374 | } | ||
375 | if (!cards) { | ||
376 | #ifdef MODULE | ||
377 | printk(KERN_ERR "GUS Extreme soundcard not found or device busy\n"); | ||
378 | #endif | ||
379 | snd_gusextreme_unregister_all(); | ||
380 | return -ENODEV; | ||
381 | } | ||
382 | return 0; | ||
383 | } | 370 | } |
384 | 371 | ||
385 | static void __exit alsa_card_gusextreme_exit(void) | 372 | static void __exit alsa_card_gusextreme_exit(void) |
386 | { | 373 | { |
387 | snd_gusextreme_unregister_all(); | 374 | isa_unregister_driver(&snd_gusextreme_driver); |
388 | } | 375 | } |
389 | 376 | ||
390 | module_init(alsa_card_gusextreme_init) | 377 | module_init(alsa_card_gusextreme_init); |
391 | module_exit(alsa_card_gusextreme_exit) | 378 | module_exit(alsa_card_gusextreme_exit); |
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index d1ad90ca035d..708783d4351f 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/isa.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
@@ -72,8 +72,6 @@ MODULE_PARM_DESC(channels, "Used GF1 channels for GUS MAX driver."); | |||
72 | module_param_array(pcm_channels, int, NULL, 0444); | 72 | module_param_array(pcm_channels, int, NULL, 0444); |
73 | MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver."); | 73 | MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver."); |
74 | 74 | ||
75 | static struct platform_device *devices[SNDRV_CARDS]; | ||
76 | |||
77 | struct snd_gusmax { | 75 | struct snd_gusmax { |
78 | int irq; | 76 | int irq; |
79 | struct snd_card *card; | 77 | struct snd_card *card; |
@@ -205,9 +203,13 @@ static void snd_gusmax_free(struct snd_card *card) | |||
205 | free_irq(maxcard->irq, (void *)maxcard); | 203 | free_irq(maxcard->irq, (void *)maxcard); |
206 | } | 204 | } |
207 | 205 | ||
208 | static int __devinit snd_gusmax_probe(struct platform_device *pdev) | 206 | static int __devinit snd_gusmax_match(struct device *pdev, unsigned int dev) |
207 | { | ||
208 | return enable[dev]; | ||
209 | } | ||
210 | |||
211 | static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev) | ||
209 | { | 212 | { |
210 | int dev = pdev->id; | ||
211 | static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; | 213 | static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; |
212 | static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; | 214 | static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; |
213 | int xirq, xdma1, xdma2, err; | 215 | int xirq, xdma1, xdma2, err; |
@@ -333,7 +335,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev) | |||
333 | if (xdma2 >= 0) | 335 | if (xdma2 >= 0) |
334 | sprintf(card->longname + strlen(card->longname), "&%i", xdma2); | 336 | sprintf(card->longname + strlen(card->longname), "&%i", xdma2); |
335 | 337 | ||
336 | snd_card_set_dev(card, &pdev->dev); | 338 | snd_card_set_dev(card, pdev); |
337 | 339 | ||
338 | if ((err = snd_card_register(card)) < 0) | 340 | if ((err = snd_card_register(card)) < 0) |
339 | goto _err; | 341 | goto _err; |
@@ -341,7 +343,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev) | |||
341 | maxcard->gus = gus; | 343 | maxcard->gus = gus; |
342 | maxcard->cs4231 = cs4231; | 344 | maxcard->cs4231 = cs4231; |
343 | 345 | ||
344 | platform_set_drvdata(pdev, card); | 346 | dev_set_drvdata(pdev, card); |
345 | return 0; | 347 | return 0; |
346 | 348 | ||
347 | _err: | 349 | _err: |
@@ -349,70 +351,33 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev) | |||
349 | return err; | 351 | return err; |
350 | } | 352 | } |
351 | 353 | ||
352 | static int __devexit snd_gusmax_remove(struct platform_device *devptr) | 354 | static int __devexit snd_gusmax_remove(struct device *devptr, unsigned int dev) |
353 | { | 355 | { |
354 | snd_card_free(platform_get_drvdata(devptr)); | 356 | snd_card_free(dev_get_drvdata(devptr)); |
355 | platform_set_drvdata(devptr, NULL); | 357 | dev_set_drvdata(devptr, NULL); |
356 | return 0; | 358 | return 0; |
357 | } | 359 | } |
358 | 360 | ||
359 | #define GUSMAX_DRIVER "snd_gusmax" | 361 | #define DEV_NAME "gusmax" |
360 | 362 | ||
361 | static struct platform_driver snd_gusmax_driver = { | 363 | static struct isa_driver snd_gusmax_driver = { |
364 | .match = snd_gusmax_match, | ||
362 | .probe = snd_gusmax_probe, | 365 | .probe = snd_gusmax_probe, |
363 | .remove = __devexit_p(snd_gusmax_remove), | 366 | .remove = __devexit_p(snd_gusmax_remove), |
364 | /* FIXME: suspend/resume */ | 367 | /* FIXME: suspend/resume */ |
365 | .driver = { | 368 | .driver = { |
366 | .name = GUSMAX_DRIVER | 369 | .name = DEV_NAME |
367 | }, | 370 | }, |
368 | }; | 371 | }; |
369 | 372 | ||
370 | static void __init_or_module snd_gusmax_unregister_all(void) | ||
371 | { | ||
372 | int i; | ||
373 | |||
374 | for (i = 0; i < ARRAY_SIZE(devices); ++i) | ||
375 | platform_device_unregister(devices[i]); | ||
376 | platform_driver_unregister(&snd_gusmax_driver); | ||
377 | } | ||
378 | |||
379 | static int __init alsa_card_gusmax_init(void) | 373 | static int __init alsa_card_gusmax_init(void) |
380 | { | 374 | { |
381 | int i, cards, err; | 375 | return isa_register_driver(&snd_gusmax_driver, SNDRV_CARDS); |
382 | |||
383 | err = platform_driver_register(&snd_gusmax_driver); | ||
384 | if (err < 0) | ||
385 | return err; | ||
386 | |||
387 | cards = 0; | ||
388 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
389 | struct platform_device *device; | ||
390 | if (! enable[i]) | ||
391 | continue; | ||
392 | device = platform_device_register_simple(GUSMAX_DRIVER, | ||
393 | i, NULL, 0); | ||
394 | if (IS_ERR(device)) | ||
395 | continue; | ||
396 | if (!platform_get_drvdata(device)) { | ||
397 | platform_device_unregister(device); | ||
398 | continue; | ||
399 | } | ||
400 | devices[i] = device; | ||
401 | cards++; | ||
402 | } | ||
403 | if (!cards) { | ||
404 | #ifdef MODULE | ||
405 | printk(KERN_ERR "GUS MAX soundcard not found or device busy\n"); | ||
406 | #endif | ||
407 | snd_gusmax_unregister_all(); | ||
408 | return -ENODEV; | ||
409 | } | ||
410 | return 0; | ||
411 | } | 376 | } |
412 | 377 | ||
413 | static void __exit alsa_card_gusmax_exit(void) | 378 | static void __exit alsa_card_gusmax_exit(void) |
414 | { | 379 | { |
415 | snd_gusmax_unregister_all(); | 380 | isa_unregister_driver(&snd_gusmax_driver); |
416 | } | 381 | } |
417 | 382 | ||
418 | module_init(alsa_card_gusmax_init) | 383 | module_init(alsa_card_gusmax_init) |
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 4ec2d79431fc..3e4657255536 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <sound/driver.h> | 25 | #include <sound/driver.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/isa.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/pnp.h> | 31 | #include <linux/pnp.h> |
@@ -115,9 +115,6 @@ MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for InterWave driver."); | |||
115 | module_param_array(effect, int, NULL, 0444); | 115 | module_param_array(effect, int, NULL, 0444); |
116 | MODULE_PARM_DESC(effect, "Effects enable for InterWave driver."); | 116 | MODULE_PARM_DESC(effect, "Effects enable for InterWave driver."); |
117 | 117 | ||
118 | static struct platform_device *platform_devices[SNDRV_CARDS]; | ||
119 | static int pnp_registered; | ||
120 | |||
121 | struct snd_interwave { | 118 | struct snd_interwave { |
122 | int irq; | 119 | int irq; |
123 | struct snd_card *card; | 120 | struct snd_card *card; |
@@ -138,6 +135,7 @@ struct snd_interwave { | |||
138 | 135 | ||
139 | 136 | ||
140 | #ifdef CONFIG_PNP | 137 | #ifdef CONFIG_PNP |
138 | static int pnp_registered; | ||
141 | 139 | ||
142 | static struct pnp_card_device_id snd_interwave_pnpids[] = { | 140 | static struct pnp_card_device_id snd_interwave_pnpids[] = { |
143 | #ifndef SNDRV_STB | 141 | #ifndef SNDRV_STB |
@@ -793,7 +791,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev) | |||
793 | return 0; | 791 | return 0; |
794 | } | 792 | } |
795 | 793 | ||
796 | static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr) | 794 | static int __devinit snd_interwave_isa_probe1(int dev, struct device *devptr) |
797 | { | 795 | { |
798 | struct snd_card *card; | 796 | struct snd_card *card; |
799 | int err; | 797 | int err; |
@@ -802,18 +800,30 @@ static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device | |||
802 | if (! card) | 800 | if (! card) |
803 | return -ENOMEM; | 801 | return -ENOMEM; |
804 | 802 | ||
805 | snd_card_set_dev(card, &devptr->dev); | 803 | snd_card_set_dev(card, devptr); |
806 | if ((err = snd_interwave_probe(card, dev)) < 0) { | 804 | if ((err = snd_interwave_probe(card, dev)) < 0) { |
807 | snd_card_free(card); | 805 | snd_card_free(card); |
808 | return err; | 806 | return err; |
809 | } | 807 | } |
810 | platform_set_drvdata(devptr, card); | 808 | dev_set_drvdata(devptr, card); |
811 | return 0; | 809 | return 0; |
812 | } | 810 | } |
813 | 811 | ||
814 | static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev) | 812 | static int __devinit snd_interwave_isa_match(struct device *pdev, |
813 | unsigned int dev) | ||
814 | { | ||
815 | if (!enable[dev]) | ||
816 | return 0; | ||
817 | #ifdef CONFIG_PNP | ||
818 | if (isapnp[dev]) | ||
819 | return 0; | ||
820 | #endif | ||
821 | return 1; | ||
822 | } | ||
823 | |||
824 | static int __devinit snd_interwave_isa_probe(struct device *pdev, | ||
825 | unsigned int dev) | ||
815 | { | 826 | { |
816 | int dev = pdev->id; | ||
817 | int err; | 827 | int err; |
818 | static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; | 828 | static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; |
819 | static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1}; | 829 | static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1}; |
@@ -838,13 +848,13 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev) | |||
838 | } | 848 | } |
839 | 849 | ||
840 | if (port[dev] != SNDRV_AUTO_PORT) | 850 | if (port[dev] != SNDRV_AUTO_PORT) |
841 | return snd_interwave_nonpnp_probe1(dev, pdev); | 851 | return snd_interwave_isa_probe1(dev, pdev); |
842 | else { | 852 | else { |
843 | static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260}; | 853 | static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260}; |
844 | int i; | 854 | int i; |
845 | for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { | 855 | for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { |
846 | port[dev] = possible_ports[i]; | 856 | port[dev] = possible_ports[i]; |
847 | err = snd_interwave_nonpnp_probe1(dev, pdev); | 857 | err = snd_interwave_isa_probe1(dev, pdev); |
848 | if (! err) | 858 | if (! err) |
849 | return 0; | 859 | return 0; |
850 | } | 860 | } |
@@ -852,16 +862,17 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev) | |||
852 | } | 862 | } |
853 | } | 863 | } |
854 | 864 | ||
855 | static int __devexit snd_interwave_nonpnp_remove(struct platform_device *devptr) | 865 | static int __devexit snd_interwave_isa_remove(struct device *devptr, unsigned int dev) |
856 | { | 866 | { |
857 | snd_card_free(platform_get_drvdata(devptr)); | 867 | snd_card_free(dev_get_drvdata(devptr)); |
858 | platform_set_drvdata(devptr, NULL); | 868 | dev_set_drvdata(devptr, NULL); |
859 | return 0; | 869 | return 0; |
860 | } | 870 | } |
861 | 871 | ||
862 | static struct platform_driver snd_interwave_driver = { | 872 | static struct isa_driver snd_interwave_driver = { |
863 | .probe = snd_interwave_nonpnp_probe, | 873 | .match = snd_interwave_isa_match, |
864 | .remove = __devexit_p(snd_interwave_nonpnp_remove), | 874 | .probe = snd_interwave_isa_probe, |
875 | .remove = __devexit_p(snd_interwave_isa_remove), | ||
865 | /* FIXME: suspend,resume */ | 876 | /* FIXME: suspend,resume */ |
866 | .driver = { | 877 | .driver = { |
867 | .name = INTERWAVE_DRIVER | 878 | .name = INTERWAVE_DRIVER |
@@ -869,8 +880,6 @@ static struct platform_driver snd_interwave_driver = { | |||
869 | }; | 880 | }; |
870 | 881 | ||
871 | #ifdef CONFIG_PNP | 882 | #ifdef CONFIG_PNP |
872 | static unsigned int __devinitdata interwave_pnp_devices; | ||
873 | |||
874 | static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, | 883 | static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, |
875 | const struct pnp_card_device_id *pid) | 884 | const struct pnp_card_device_id *pid) |
876 | { | 885 | { |
@@ -900,7 +909,6 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, | |||
900 | } | 909 | } |
901 | pnp_set_card_drvdata(pcard, card); | 910 | pnp_set_card_drvdata(pcard, card); |
902 | dev++; | 911 | dev++; |
903 | interwave_pnp_devices++; | ||
904 | return 0; | 912 | return 0; |
905 | } | 913 | } |
906 | 914 | ||
@@ -921,64 +929,29 @@ static struct pnp_card_driver interwave_pnpc_driver = { | |||
921 | 929 | ||
922 | #endif /* CONFIG_PNP */ | 930 | #endif /* CONFIG_PNP */ |
923 | 931 | ||
924 | static void __init_or_module snd_interwave_unregister_all(void) | ||
925 | { | ||
926 | int i; | ||
927 | |||
928 | if (pnp_registered) | ||
929 | pnp_unregister_card_driver(&interwave_pnpc_driver); | ||
930 | for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | ||
931 | platform_device_unregister(platform_devices[i]); | ||
932 | platform_driver_unregister(&snd_interwave_driver); | ||
933 | } | ||
934 | |||
935 | static int __init alsa_card_interwave_init(void) | 932 | static int __init alsa_card_interwave_init(void) |
936 | { | 933 | { |
937 | int i, err, cards = 0; | 934 | int err; |
938 | 935 | ||
939 | if ((err = platform_driver_register(&snd_interwave_driver)) < 0) | 936 | err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS); |
937 | if (err < 0) | ||
940 | return err; | 938 | return err; |
941 | |||
942 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
943 | struct platform_device *device; | ||
944 | if (! enable[i]) | ||
945 | continue; | ||
946 | #ifdef CONFIG_PNP | 939 | #ifdef CONFIG_PNP |
947 | if (isapnp[i]) | ||
948 | continue; | ||
949 | #endif | ||
950 | device = platform_device_register_simple(INTERWAVE_DRIVER, | ||
951 | i, NULL, 0); | ||
952 | if (IS_ERR(device)) | ||
953 | continue; | ||
954 | if (!platform_get_drvdata(device)) { | ||
955 | platform_device_unregister(device); | ||
956 | continue; | ||
957 | } | ||
958 | platform_devices[i] = device; | ||
959 | cards++; | ||
960 | } | ||
961 | |||
962 | /* ISA PnP cards */ | 940 | /* ISA PnP cards */ |
963 | err = pnp_register_card_driver(&interwave_pnpc_driver); | 941 | err = pnp_register_card_driver(&interwave_pnpc_driver); |
964 | if (!err) { | 942 | if (!err) |
965 | pnp_registered = 1; | 943 | pnp_registered = 1; |
966 | cards += interwave_pnp_devices;; | ||
967 | } | ||
968 | |||
969 | if (!cards) { | ||
970 | #ifdef MODULE | ||
971 | printk(KERN_ERR "InterWave soundcard not found or device busy\n"); | ||
972 | #endif | 944 | #endif |
973 | snd_interwave_unregister_all(); | ||
974 | return -ENODEV; | ||
975 | } | ||
976 | return 0; | 945 | return 0; |
977 | } | 946 | } |
978 | 947 | ||
979 | static void __exit alsa_card_interwave_exit(void) | 948 | static void __exit alsa_card_interwave_exit(void) |
980 | { | 949 | { |
981 | snd_interwave_unregister_all(); | 950 | #ifdef CONFIG_PNP |
951 | if (pnp_registered) | ||
952 | pnp_unregister_card_driver(&interwave_pnpc_driver); | ||
953 | #endif | ||
954 | isa_unregister_driver(&snd_interwave_driver); | ||
982 | } | 955 | } |
983 | 956 | ||
984 | module_init(alsa_card_interwave_init) | 957 | module_init(alsa_card_interwave_init) |
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index f3db686b1c0c..48743eb85fb6 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/isa.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/pm.h> | 27 | #include <linux/pm.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
@@ -91,12 +91,10 @@ MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver."); | |||
91 | module_param_array(opl3sa3_ymode, int, NULL, 0444); | 91 | module_param_array(opl3sa3_ymode, int, NULL, 0444); |
92 | MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi."); | 92 | MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi."); |
93 | 93 | ||
94 | static struct platform_device *platform_devices[SNDRV_CARDS]; | ||
95 | #ifdef CONFIG_PNP | 94 | #ifdef CONFIG_PNP |
96 | static int pnp_registered; | 95 | static int pnp_registered; |
97 | static int pnpc_registered; | 96 | static int pnpc_registered; |
98 | #endif | 97 | #endif |
99 | static unsigned int snd_opl3sa2_devices; | ||
100 | 98 | ||
101 | /* control ports */ | 99 | /* control ports */ |
102 | #define OPL3SA2_PM_CTRL 0x01 | 100 | #define OPL3SA2_PM_CTRL 0x01 |
@@ -783,7 +781,6 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev, | |||
783 | } | 781 | } |
784 | pnp_set_drvdata(pdev, card); | 782 | pnp_set_drvdata(pdev, card); |
785 | dev++; | 783 | dev++; |
786 | snd_opl3sa2_devices++; | ||
787 | return 0; | 784 | return 0; |
788 | } | 785 | } |
789 | 786 | ||
@@ -850,7 +847,6 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard, | |||
850 | } | 847 | } |
851 | pnp_set_card_drvdata(pcard, card); | 848 | pnp_set_card_drvdata(pcard, card); |
852 | dev++; | 849 | dev++; |
853 | snd_opl3sa2_devices++; | ||
854 | return 0; | 850 | return 0; |
855 | } | 851 | } |
856 | 852 | ||
@@ -884,116 +880,95 @@ static struct pnp_card_driver opl3sa2_pnpc_driver = { | |||
884 | }; | 880 | }; |
885 | #endif /* CONFIG_PNP */ | 881 | #endif /* CONFIG_PNP */ |
886 | 882 | ||
887 | static int __devinit snd_opl3sa2_nonpnp_probe(struct platform_device *pdev) | 883 | static int __devinit snd_opl3sa2_isa_match(struct device *pdev, |
884 | unsigned int dev) | ||
888 | { | 885 | { |
889 | struct snd_card *card; | 886 | if (!enable[dev]) |
890 | int err; | 887 | return 0; |
891 | int dev = pdev->id; | 888 | #ifdef CONFIG_PNP |
892 | 889 | if (isapnp[dev]) | |
890 | return 0; | ||
891 | #endif | ||
893 | if (port[dev] == SNDRV_AUTO_PORT) { | 892 | if (port[dev] == SNDRV_AUTO_PORT) { |
894 | snd_printk(KERN_ERR PFX "specify port\n"); | 893 | snd_printk(KERN_ERR PFX "specify port\n"); |
895 | return -EINVAL; | 894 | return 0; |
896 | } | 895 | } |
897 | if (wss_port[dev] == SNDRV_AUTO_PORT) { | 896 | if (wss_port[dev] == SNDRV_AUTO_PORT) { |
898 | snd_printk(KERN_ERR PFX "specify wss_port\n"); | 897 | snd_printk(KERN_ERR PFX "specify wss_port\n"); |
899 | return -EINVAL; | 898 | return 0; |
900 | } | 899 | } |
901 | if (fm_port[dev] == SNDRV_AUTO_PORT) { | 900 | if (fm_port[dev] == SNDRV_AUTO_PORT) { |
902 | snd_printk(KERN_ERR PFX "specify fm_port\n"); | 901 | snd_printk(KERN_ERR PFX "specify fm_port\n"); |
903 | return -EINVAL; | 902 | return 0; |
904 | } | 903 | } |
905 | if (midi_port[dev] == SNDRV_AUTO_PORT) { | 904 | if (midi_port[dev] == SNDRV_AUTO_PORT) { |
906 | snd_printk(KERN_ERR PFX "specify midi_port\n"); | 905 | snd_printk(KERN_ERR PFX "specify midi_port\n"); |
907 | return -EINVAL; | 906 | return 0; |
908 | } | 907 | } |
908 | return 1; | ||
909 | } | ||
910 | |||
911 | static int __devinit snd_opl3sa2_isa_probe(struct device *pdev, | ||
912 | unsigned int dev) | ||
913 | { | ||
914 | struct snd_card *card; | ||
915 | int err; | ||
909 | 916 | ||
910 | card = snd_opl3sa2_card_new(dev); | 917 | card = snd_opl3sa2_card_new(dev); |
911 | if (! card) | 918 | if (! card) |
912 | return -ENOMEM; | 919 | return -ENOMEM; |
913 | snd_card_set_dev(card, &pdev->dev); | 920 | snd_card_set_dev(card, pdev); |
914 | if ((err = snd_opl3sa2_probe(card, dev)) < 0) { | 921 | if ((err = snd_opl3sa2_probe(card, dev)) < 0) { |
915 | snd_card_free(card); | 922 | snd_card_free(card); |
916 | return err; | 923 | return err; |
917 | } | 924 | } |
918 | platform_set_drvdata(pdev, card); | 925 | dev_set_drvdata(pdev, card); |
919 | return 0; | 926 | return 0; |
920 | } | 927 | } |
921 | 928 | ||
922 | static int __devexit snd_opl3sa2_nonpnp_remove(struct platform_device *devptr) | 929 | static int __devexit snd_opl3sa2_isa_remove(struct device *devptr, |
930 | unsigned int dev) | ||
923 | { | 931 | { |
924 | snd_card_free(platform_get_drvdata(devptr)); | 932 | snd_card_free(dev_get_drvdata(devptr)); |
925 | platform_set_drvdata(devptr, NULL); | 933 | dev_set_drvdata(devptr, NULL); |
926 | return 0; | 934 | return 0; |
927 | } | 935 | } |
928 | 936 | ||
929 | #ifdef CONFIG_PM | 937 | #ifdef CONFIG_PM |
930 | static int snd_opl3sa2_nonpnp_suspend(struct platform_device *dev, pm_message_t state) | 938 | static int snd_opl3sa2_isa_suspend(struct device *dev, unsigned int n, |
939 | pm_message_t state) | ||
931 | { | 940 | { |
932 | return snd_opl3sa2_suspend(platform_get_drvdata(dev), state); | 941 | return snd_opl3sa2_suspend(dev_get_drvdata(dev), state); |
933 | } | 942 | } |
934 | 943 | ||
935 | static int snd_opl3sa2_nonpnp_resume(struct platform_device *dev) | 944 | static int snd_opl3sa2_isa_resume(struct device *dev, unsigned int n) |
936 | { | 945 | { |
937 | return snd_opl3sa2_resume(platform_get_drvdata(dev)); | 946 | return snd_opl3sa2_resume(dev_get_drvdata(dev)); |
938 | } | 947 | } |
939 | #endif | 948 | #endif |
940 | 949 | ||
941 | #define OPL3SA2_DRIVER "snd_opl3sa2" | 950 | #define DEV_NAME "opl3sa2" |
942 | 951 | ||
943 | static struct platform_driver snd_opl3sa2_nonpnp_driver = { | 952 | static struct isa_driver snd_opl3sa2_isa_driver = { |
944 | .probe = snd_opl3sa2_nonpnp_probe, | 953 | .match = snd_opl3sa2_isa_match, |
945 | .remove = __devexit( snd_opl3sa2_nonpnp_remove), | 954 | .probe = snd_opl3sa2_isa_probe, |
955 | .remove = __devexit( snd_opl3sa2_isa_remove), | ||
946 | #ifdef CONFIG_PM | 956 | #ifdef CONFIG_PM |
947 | .suspend = snd_opl3sa2_nonpnp_suspend, | 957 | .suspend = snd_opl3sa2_isa_suspend, |
948 | .resume = snd_opl3sa2_nonpnp_resume, | 958 | .resume = snd_opl3sa2_isa_resume, |
949 | #endif | 959 | #endif |
950 | .driver = { | 960 | .driver = { |
951 | .name = OPL3SA2_DRIVER | 961 | .name = DEV_NAME |
952 | }, | 962 | }, |
953 | }; | 963 | }; |
954 | 964 | ||
955 | static void __init_or_module snd_opl3sa2_unregister_all(void) | ||
956 | { | ||
957 | int i; | ||
958 | |||
959 | #ifdef CONFIG_PNP | ||
960 | if (pnpc_registered) | ||
961 | pnp_unregister_card_driver(&opl3sa2_pnpc_driver); | ||
962 | if (pnp_registered) | ||
963 | pnp_unregister_driver(&opl3sa2_pnp_driver); | ||
964 | #endif | ||
965 | for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | ||
966 | platform_device_unregister(platform_devices[i]); | ||
967 | platform_driver_unregister(&snd_opl3sa2_nonpnp_driver); | ||
968 | } | ||
969 | |||
970 | static int __init alsa_card_opl3sa2_init(void) | 965 | static int __init alsa_card_opl3sa2_init(void) |
971 | { | 966 | { |
972 | int i, err; | 967 | int err; |
973 | 968 | ||
974 | if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0) | 969 | err = isa_register_driver(&snd_opl3sa2_isa_driver, SNDRV_CARDS); |
970 | if (err < 0) | ||
975 | return err; | 971 | return err; |
976 | |||
977 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
978 | struct platform_device *device; | ||
979 | if (! enable[i]) | ||
980 | continue; | ||
981 | #ifdef CONFIG_PNP | ||
982 | if (isapnp[i]) | ||
983 | continue; | ||
984 | #endif | ||
985 | device = platform_device_register_simple(OPL3SA2_DRIVER, | ||
986 | i, NULL, 0); | ||
987 | if (IS_ERR(device)) | ||
988 | continue; | ||
989 | if (!platform_get_drvdata(device)) { | ||
990 | platform_device_unregister(device); | ||
991 | continue; | ||
992 | } | ||
993 | platform_devices[i] = device; | ||
994 | snd_opl3sa2_devices++; | ||
995 | } | ||
996 | |||
997 | #ifdef CONFIG_PNP | 972 | #ifdef CONFIG_PNP |
998 | err = pnp_register_driver(&opl3sa2_pnp_driver); | 973 | err = pnp_register_driver(&opl3sa2_pnp_driver); |
999 | if (!err) | 974 | if (!err) |
@@ -1002,20 +977,18 @@ static int __init alsa_card_opl3sa2_init(void) | |||
1002 | if (!err) | 977 | if (!err) |
1003 | pnpc_registered = 1; | 978 | pnpc_registered = 1; |
1004 | #endif | 979 | #endif |
1005 | |||
1006 | if (!snd_opl3sa2_devices) { | ||
1007 | #ifdef MODULE | ||
1008 | snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n"); | ||
1009 | #endif | ||
1010 | snd_opl3sa2_unregister_all(); | ||
1011 | return -ENODEV; | ||
1012 | } | ||
1013 | return 0; | 980 | return 0; |
1014 | } | 981 | } |
1015 | 982 | ||
1016 | static void __exit alsa_card_opl3sa2_exit(void) | 983 | static void __exit alsa_card_opl3sa2_exit(void) |
1017 | { | 984 | { |
1018 | snd_opl3sa2_unregister_all(); | 985 | #ifdef CONFIG_PNP |
986 | if (pnpc_registered) | ||
987 | pnp_unregister_card_driver(&opl3sa2_pnpc_driver); | ||
988 | if (pnp_registered) | ||
989 | pnp_unregister_driver(&opl3sa2_pnp_driver); | ||
990 | #endif | ||
991 | isa_unregister_driver(&snd_opl3sa2_isa_driver); | ||
1019 | } | 992 | } |
1020 | 993 | ||
1021 | module_init(alsa_card_opl3sa2_init) | 994 | module_init(alsa_card_opl3sa2_init) |
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index 1dd98375ac85..cd29b30b362e 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <sound/driver.h> | 25 | #include <sound/driver.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/isa.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/ioport.h> | 31 | #include <linux/ioport.h> |
@@ -137,10 +137,6 @@ struct snd_miro { | |||
137 | 137 | ||
138 | static void snd_miro_proc_init(struct snd_miro * miro); | 138 | static void snd_miro_proc_init(struct snd_miro * miro); |
139 | 139 | ||
140 | #define DRIVER_NAME "snd-miro" | ||
141 | |||
142 | static struct platform_device *device; | ||
143 | |||
144 | static char * snd_opti9xx_names[] = { | 140 | static char * snd_opti9xx_names[] = { |
145 | "unkown", | 141 | "unkown", |
146 | "82C928", "82C929", | 142 | "82C928", "82C929", |
@@ -558,7 +554,7 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol, | |||
558 | return change; | 554 | return change; |
559 | } | 555 | } |
560 | 556 | ||
561 | static struct snd_kcontrol_new snd_miro_controls[] = { | 557 | static struct snd_kcontrol_new snd_miro_controls[] __devinitdata = { |
562 | MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER), | 558 | MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER), |
563 | MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC), | 559 | MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC), |
564 | MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE), | 560 | MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE), |
@@ -570,7 +566,7 @@ MIRO_DOUBLE("Aux Playback Volume", 2, ACI_GET_LINE2, ACI_SET_LINE2), | |||
570 | 566 | ||
571 | /* Equalizer with seven bands (only PCM20) | 567 | /* Equalizer with seven bands (only PCM20) |
572 | from -12dB up to +12dB on each band */ | 568 | from -12dB up to +12dB on each band */ |
573 | static struct snd_kcontrol_new snd_miro_eq_controls[] = { | 569 | static struct snd_kcontrol_new snd_miro_eq_controls[] __devinitdata = { |
574 | MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1), | 570 | MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1), |
575 | MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2), | 571 | MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2), |
576 | MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3), | 572 | MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3), |
@@ -580,15 +576,15 @@ MIRO_DOUBLE("Tone Control - 6.3 kHz", 0, ACI_GET_EQ6, ACI_SET_EQ6), | |||
580 | MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7), | 576 | MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7), |
581 | }; | 577 | }; |
582 | 578 | ||
583 | static struct snd_kcontrol_new snd_miro_radio_control[] = { | 579 | static struct snd_kcontrol_new snd_miro_radio_control[] __devinitdata = { |
584 | MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1), | 580 | MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1), |
585 | }; | 581 | }; |
586 | 582 | ||
587 | static struct snd_kcontrol_new snd_miro_line_control[] = { | 583 | static struct snd_kcontrol_new snd_miro_line_control[] __devinitdata = { |
588 | MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1), | 584 | MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1), |
589 | }; | 585 | }; |
590 | 586 | ||
591 | static struct snd_kcontrol_new snd_miro_preamp_control[] = { | 587 | static struct snd_kcontrol_new snd_miro_preamp_control[] __devinitdata = { |
592 | { | 588 | { |
593 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 589 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
594 | .name = "Mic Boost", | 590 | .name = "Mic Boost", |
@@ -598,7 +594,7 @@ static struct snd_kcontrol_new snd_miro_preamp_control[] = { | |||
598 | .put = snd_miro_put_preamp, | 594 | .put = snd_miro_put_preamp, |
599 | }}; | 595 | }}; |
600 | 596 | ||
601 | static struct snd_kcontrol_new snd_miro_amp_control[] = { | 597 | static struct snd_kcontrol_new snd_miro_amp_control[] __devinitdata = { |
602 | { | 598 | { |
603 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 599 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
604 | .name = "Line Boost", | 600 | .name = "Line Boost", |
@@ -608,7 +604,7 @@ static struct snd_kcontrol_new snd_miro_amp_control[] = { | |||
608 | .put = snd_miro_put_amp, | 604 | .put = snd_miro_put_amp, |
609 | }}; | 605 | }}; |
610 | 606 | ||
611 | static struct snd_kcontrol_new snd_miro_capture_control[] = { | 607 | static struct snd_kcontrol_new snd_miro_capture_control[] __devinitdata = { |
612 | { | 608 | { |
613 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 609 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
614 | .name = "PCM Capture Switch", | 610 | .name = "PCM Capture Switch", |
@@ -618,7 +614,7 @@ static struct snd_kcontrol_new snd_miro_capture_control[] = { | |||
618 | .put = snd_miro_put_capture, | 614 | .put = snd_miro_put_capture, |
619 | }}; | 615 | }}; |
620 | 616 | ||
621 | static unsigned char aci_init_values[][2] __initdata = { | 617 | static unsigned char aci_init_values[][2] __devinitdata = { |
622 | { ACI_SET_MUTE, 0x00 }, | 618 | { ACI_SET_MUTE, 0x00 }, |
623 | { ACI_SET_POWERAMP, 0x00 }, | 619 | { ACI_SET_POWERAMP, 0x00 }, |
624 | { ACI_SET_PREAMP, 0x00 }, | 620 | { ACI_SET_PREAMP, 0x00 }, |
@@ -641,7 +637,7 @@ static unsigned char aci_init_values[][2] __initdata = { | |||
641 | { ACI_SET_MASTER + 1, 0x20 }, | 637 | { ACI_SET_MASTER + 1, 0x20 }, |
642 | }; | 638 | }; |
643 | 639 | ||
644 | static int __init snd_set_aci_init_values(struct snd_miro *miro) | 640 | static int __devinit snd_set_aci_init_values(struct snd_miro *miro) |
645 | { | 641 | { |
646 | int idx, error; | 642 | int idx, error; |
647 | 643 | ||
@@ -751,7 +747,8 @@ static long snd_legacy_find_free_ioport(long *port_table, long size) | |||
751 | return -1; | 747 | return -1; |
752 | } | 748 | } |
753 | 749 | ||
754 | static int __init snd_miro_init(struct snd_miro *chip, unsigned short hardware) | 750 | static int __devinit snd_miro_init(struct snd_miro *chip, |
751 | unsigned short hardware) | ||
755 | { | 752 | { |
756 | static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2}; | 753 | static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2}; |
757 | 754 | ||
@@ -962,7 +959,7 @@ static void snd_miro_proc_read(struct snd_info_entry * entry, | |||
962 | snd_iprintf(buffer, " preamp : 0x%x\n", miro->aci_preamp); | 959 | snd_iprintf(buffer, " preamp : 0x%x\n", miro->aci_preamp); |
963 | } | 960 | } |
964 | 961 | ||
965 | static void __init snd_miro_proc_init(struct snd_miro * miro) | 962 | static void __devinit snd_miro_proc_init(struct snd_miro * miro) |
966 | { | 963 | { |
967 | struct snd_info_entry *entry; | 964 | struct snd_info_entry *entry; |
968 | 965 | ||
@@ -974,7 +971,7 @@ static void __init snd_miro_proc_init(struct snd_miro * miro) | |||
974 | * Init | 971 | * Init |
975 | */ | 972 | */ |
976 | 973 | ||
977 | static int __init snd_miro_configure(struct snd_miro *chip) | 974 | static int __devinit snd_miro_configure(struct snd_miro *chip) |
978 | { | 975 | { |
979 | unsigned char wss_base_bits; | 976 | unsigned char wss_base_bits; |
980 | unsigned char irq_bits; | 977 | unsigned char irq_bits; |
@@ -1131,7 +1128,8 @@ __skip_mpu: | |||
1131 | return 0; | 1128 | return 0; |
1132 | } | 1129 | } |
1133 | 1130 | ||
1134 | static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *chip) | 1131 | static int __devinit snd_card_miro_detect(struct snd_card *card, |
1132 | struct snd_miro *chip) | ||
1135 | { | 1133 | { |
1136 | int i, err; | 1134 | int i, err; |
1137 | unsigned char value; | 1135 | unsigned char value; |
@@ -1157,7 +1155,8 @@ static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *c | |||
1157 | return -ENODEV; | 1155 | return -ENODEV; |
1158 | } | 1156 | } |
1159 | 1157 | ||
1160 | static int __init snd_card_miro_aci_detect(struct snd_card *card, struct snd_miro * miro) | 1158 | static int __devinit snd_card_miro_aci_detect(struct snd_card *card, |
1159 | struct snd_miro * miro) | ||
1161 | { | 1160 | { |
1162 | unsigned char regval; | 1161 | unsigned char regval; |
1163 | int i; | 1162 | int i; |
@@ -1213,7 +1212,12 @@ static void snd_card_miro_free(struct snd_card *card) | |||
1213 | release_and_free_resource(miro->res_mc_base); | 1212 | release_and_free_resource(miro->res_mc_base); |
1214 | } | 1213 | } |
1215 | 1214 | ||
1216 | static int __init snd_miro_probe(struct platform_device *devptr) | 1215 | static int __devinit snd_miro_match(struct device *devptr, unsigned int n) |
1216 | { | ||
1217 | return 1; | ||
1218 | } | ||
1219 | |||
1220 | static int __devinit snd_miro_probe(struct device *devptr, unsigned int n) | ||
1217 | { | 1221 | { |
1218 | static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; | 1222 | static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; |
1219 | static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1}; | 1223 | static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1}; |
@@ -1399,56 +1403,44 @@ static int __init snd_miro_probe(struct platform_device *devptr) | |||
1399 | return error; | 1403 | return error; |
1400 | } | 1404 | } |
1401 | 1405 | ||
1402 | snd_card_set_dev(card, &devptr->dev); | 1406 | snd_card_set_dev(card, devptr); |
1403 | 1407 | ||
1404 | if ((error = snd_card_register(card))) { | 1408 | if ((error = snd_card_register(card))) { |
1405 | snd_card_free(card); | 1409 | snd_card_free(card); |
1406 | return error; | 1410 | return error; |
1407 | } | 1411 | } |
1408 | 1412 | ||
1409 | platform_set_drvdata(devptr, card); | 1413 | dev_set_drvdata(devptr, card); |
1410 | return 0; | 1414 | return 0; |
1411 | } | 1415 | } |
1412 | 1416 | ||
1413 | static int __devexit snd_miro_remove(struct platform_device *devptr) | 1417 | static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev) |
1414 | { | 1418 | { |
1415 | snd_card_free(platform_get_drvdata(devptr)); | 1419 | snd_card_free(dev_get_drvdata(devptr)); |
1416 | platform_set_drvdata(devptr, NULL); | 1420 | dev_set_drvdata(devptr, NULL); |
1417 | return 0; | 1421 | return 0; |
1418 | } | 1422 | } |
1419 | 1423 | ||
1420 | static struct platform_driver snd_miro_driver = { | 1424 | #define DEV_NAME "miro" |
1425 | |||
1426 | static struct isa_driver snd_miro_driver = { | ||
1427 | .match = snd_miro_match, | ||
1421 | .probe = snd_miro_probe, | 1428 | .probe = snd_miro_probe, |
1422 | .remove = __devexit_p(snd_miro_remove), | 1429 | .remove = __devexit_p(snd_miro_remove), |
1423 | /* FIXME: suspend/resume */ | 1430 | /* FIXME: suspend/resume */ |
1424 | .driver = { | 1431 | .driver = { |
1425 | .name = DRIVER_NAME | 1432 | .name = DEV_NAME |
1426 | }, | 1433 | }, |
1427 | }; | 1434 | }; |
1428 | 1435 | ||
1429 | static int __init alsa_card_miro_init(void) | 1436 | static int __init alsa_card_miro_init(void) |
1430 | { | 1437 | { |
1431 | int error; | 1438 | return isa_register_driver(&snd_miro_driver, 1); |
1432 | |||
1433 | if ((error = platform_driver_register(&snd_miro_driver)) < 0) | ||
1434 | return error; | ||
1435 | device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); | ||
1436 | if (! IS_ERR(device)) { | ||
1437 | if (platform_get_drvdata(device)) | ||
1438 | return 0; | ||
1439 | platform_device_unregister(device); | ||
1440 | } | ||
1441 | #ifdef MODULE | ||
1442 | printk(KERN_ERR "no miro soundcard found\n"); | ||
1443 | #endif | ||
1444 | platform_driver_unregister(&snd_miro_driver); | ||
1445 | return PTR_ERR(device); | ||
1446 | } | 1439 | } |
1447 | 1440 | ||
1448 | static void __exit alsa_card_miro_exit(void) | 1441 | static void __exit alsa_card_miro_exit(void) |
1449 | { | 1442 | { |
1450 | platform_device_unregister(device); | 1443 | isa_unregister_driver(&snd_miro_driver); |
1451 | platform_driver_unregister(&snd_miro_driver); | ||
1452 | } | 1444 | } |
1453 | 1445 | ||
1454 | module_init(alsa_card_miro_init) | 1446 | module_init(alsa_card_miro_init) |
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index df227377c333..60c120ffb9de 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <sound/driver.h> | 26 | #include <sound/driver.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/err.h> | 28 | #include <linux/err.h> |
29 | #include <linux/platform_device.h> | 29 | #include <linux/isa.h> |
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/pnp.h> | 32 | #include <linux/pnp.h> |
@@ -259,7 +259,6 @@ struct snd_opti9xx { | |||
259 | }; | 259 | }; |
260 | 260 | ||
261 | static int snd_opti9xx_pnp_is_probed; | 261 | static int snd_opti9xx_pnp_is_probed; |
262 | static struct platform_device *snd_opti9xx_platform_device; | ||
263 | 262 | ||
264 | #ifdef CONFIG_PNP | 263 | #ifdef CONFIG_PNP |
265 | 264 | ||
@@ -281,10 +280,10 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids); | |||
281 | #endif /* CONFIG_PNP */ | 280 | #endif /* CONFIG_PNP */ |
282 | 281 | ||
283 | #ifdef OPTi93X | 282 | #ifdef OPTi93X |
284 | #define DRIVER_NAME "snd-card-opti93x" | 283 | #define DEV_NAME "opti93x" |
285 | #else | 284 | #else |
286 | #define DRIVER_NAME "snd-card-opti92x" | 285 | #define DEV_NAME "opti92x" |
287 | #endif /* OPTi93X */ | 286 | #endif |
288 | 287 | ||
289 | static char * snd_opti9xx_names[] = { | 288 | static char * snd_opti9xx_names[] = { |
290 | "unkown", | 289 | "unkown", |
@@ -294,7 +293,7 @@ static char * snd_opti9xx_names[] = { | |||
294 | }; | 293 | }; |
295 | 294 | ||
296 | 295 | ||
297 | static long __init snd_legacy_find_free_ioport(long *port_table, long size) | 296 | static long __devinit snd_legacy_find_free_ioport(long *port_table, long size) |
298 | { | 297 | { |
299 | while (*port_table != -1) { | 298 | while (*port_table != -1) { |
300 | if (request_region(*port_table, size, "ALSA test")) { | 299 | if (request_region(*port_table, size, "ALSA test")) { |
@@ -306,7 +305,8 @@ static long __init snd_legacy_find_free_ioport(long *port_table, long size) | |||
306 | return -1; | 305 | return -1; |
307 | } | 306 | } |
308 | 307 | ||
309 | static int __init snd_opti9xx_init(struct snd_opti9xx *chip, unsigned short hardware) | 308 | static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, |
309 | unsigned short hardware) | ||
310 | { | 310 | { |
311 | static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2}; | 311 | static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2}; |
312 | 312 | ||
@@ -451,7 +451,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, | |||
451 | (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) | 451 | (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) |
452 | 452 | ||
453 | 453 | ||
454 | static int __init snd_opti9xx_configure(struct snd_opti9xx *chip) | 454 | static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) |
455 | { | 455 | { |
456 | unsigned char wss_base_bits; | 456 | unsigned char wss_base_bits; |
457 | unsigned char irq_bits; | 457 | unsigned char irq_bits; |
@@ -934,10 +934,8 @@ static int snd_opti93x_trigger(struct snd_pcm_substream *substream, | |||
934 | case SNDRV_PCM_TRIGGER_STOP: | 934 | case SNDRV_PCM_TRIGGER_STOP: |
935 | { | 935 | { |
936 | unsigned int what = 0; | 936 | unsigned int what = 0; |
937 | struct list_head *pos; | ||
938 | struct snd_pcm_substream *s; | 937 | struct snd_pcm_substream *s; |
939 | snd_pcm_group_for_each(pos, substream) { | 938 | snd_pcm_group_for_each_entry(s, substream) { |
940 | s = snd_pcm_group_substream_entry(pos); | ||
941 | if (s == chip->playback_substream) { | 939 | if (s == chip->playback_substream) { |
942 | what |= OPTi93X_PLAYBACK_ENABLE; | 940 | what |= OPTi93X_PLAYBACK_ENABLE; |
943 | snd_pcm_trigger_done(s, substream); | 941 | snd_pcm_trigger_done(s, substream); |
@@ -1291,7 +1289,7 @@ static int snd_opti93x_create(struct snd_card *card, struct snd_opti9xx *chip, | |||
1291 | } | 1289 | } |
1292 | codec->dma2 = chip->dma2; | 1290 | codec->dma2 = chip->dma2; |
1293 | 1291 | ||
1294 | if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DRIVER_NAME" - WSS", codec)) { | 1292 | if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DEV_NAME" - WSS", codec)) { |
1295 | snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq); | 1293 | snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq); |
1296 | snd_opti93x_free(codec); | 1294 | snd_opti93x_free(codec); |
1297 | return -EBUSY; | 1295 | return -EBUSY; |
@@ -1561,7 +1559,7 @@ static int snd_opti93x_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1561 | return change; | 1559 | return change; |
1562 | } | 1560 | } |
1563 | 1561 | ||
1564 | static struct snd_kcontrol_new snd_opti93x_controls[] = { | 1562 | static struct snd_kcontrol_new snd_opti93x_controls[] __devinitdata = { |
1565 | OPTi93X_DOUBLE("Master Playback Switch", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1), | 1563 | OPTi93X_DOUBLE("Master Playback Switch", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1), |
1566 | OPTi93X_DOUBLE("Master Playback Volume", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), | 1564 | OPTi93X_DOUBLE("Master Playback Volume", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), |
1567 | OPTi93X_DOUBLE("PCM Playback Switch", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 7, 7, 1, 1), | 1565 | OPTi93X_DOUBLE("PCM Playback Switch", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 7, 7, 1, 1), |
@@ -1622,7 +1620,8 @@ static int snd_opti93x_mixer(struct snd_opti93x *chip) | |||
1622 | 1620 | ||
1623 | #endif /* OPTi93X */ | 1621 | #endif /* OPTi93X */ |
1624 | 1622 | ||
1625 | static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti9xx *chip) | 1623 | static int __devinit snd_card_opti9xx_detect(struct snd_card *card, |
1624 | struct snd_opti9xx *chip) | ||
1626 | { | 1625 | { |
1627 | int i, err; | 1626 | int i, err; |
1628 | 1627 | ||
@@ -1676,8 +1675,9 @@ static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti | |||
1676 | } | 1675 | } |
1677 | 1676 | ||
1678 | #ifdef CONFIG_PNP | 1677 | #ifdef CONFIG_PNP |
1679 | static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card_link *card, | 1678 | static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, |
1680 | const struct pnp_card_device_id *pid) | 1679 | struct pnp_card_link *card, |
1680 | const struct pnp_card_device_id *pid) | ||
1681 | { | 1681 | { |
1682 | struct pnp_dev *pdev; | 1682 | struct pnp_dev *pdev; |
1683 | struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); | 1683 | struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); |
@@ -1778,7 +1778,7 @@ static void snd_card_opti9xx_free(struct snd_card *card) | |||
1778 | release_and_free_resource(chip->res_mc_base); | 1778 | release_and_free_resource(chip->res_mc_base); |
1779 | } | 1779 | } |
1780 | 1780 | ||
1781 | static int __init snd_opti9xx_probe(struct snd_card *card) | 1781 | static int __devinit snd_opti9xx_probe(struct snd_card *card) |
1782 | { | 1782 | { |
1783 | static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; | 1783 | static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; |
1784 | int error; | 1784 | int error; |
@@ -1924,7 +1924,18 @@ static struct snd_card *snd_opti9xx_card_new(void) | |||
1924 | return card; | 1924 | return card; |
1925 | } | 1925 | } |
1926 | 1926 | ||
1927 | static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr) | 1927 | static int __devinit snd_opti9xx_isa_match(struct device *devptr, |
1928 | unsigned int dev) | ||
1929 | { | ||
1930 | if (snd_opti9xx_pnp_is_probed) | ||
1931 | return 0; | ||
1932 | if (isapnp) | ||
1933 | return 0; | ||
1934 | return 1; | ||
1935 | } | ||
1936 | |||
1937 | static int __devinit snd_opti9xx_isa_probe(struct device *devptr, | ||
1938 | unsigned int dev) | ||
1928 | { | 1939 | { |
1929 | struct snd_card *card; | 1940 | struct snd_card *card; |
1930 | int error; | 1941 | int error; |
@@ -1940,9 +1951,6 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr) | |||
1940 | static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}}; | 1951 | static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}}; |
1941 | #endif /* CS4231 || OPTi93X */ | 1952 | #endif /* CS4231 || OPTi93X */ |
1942 | 1953 | ||
1943 | if (snd_opti9xx_pnp_is_probed) | ||
1944 | return -EBUSY; | ||
1945 | |||
1946 | if (mpu_port == SNDRV_AUTO_PORT) { | 1954 | if (mpu_port == SNDRV_AUTO_PORT) { |
1947 | if ((mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) { | 1955 | if ((mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) { |
1948 | snd_printk(KERN_ERR "unable to find a free MPU401 port\n"); | 1956 | snd_printk(KERN_ERR "unable to find a free MPU401 port\n"); |
@@ -1984,34 +1992,36 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr) | |||
1984 | snd_card_free(card); | 1992 | snd_card_free(card); |
1985 | return error; | 1993 | return error; |
1986 | } | 1994 | } |
1987 | snd_card_set_dev(card, &devptr->dev); | 1995 | snd_card_set_dev(card, devptr); |
1988 | if ((error = snd_opti9xx_probe(card)) < 0) { | 1996 | if ((error = snd_opti9xx_probe(card)) < 0) { |
1989 | snd_card_free(card); | 1997 | snd_card_free(card); |
1990 | return error; | 1998 | return error; |
1991 | } | 1999 | } |
1992 | platform_set_drvdata(devptr, card); | 2000 | dev_set_drvdata(devptr, card); |
1993 | return 0; | 2001 | return 0; |
1994 | } | 2002 | } |
1995 | 2003 | ||
1996 | static int __devexit snd_opti9xx_nonpnp_remove(struct platform_device *devptr) | 2004 | static int __devexit snd_opti9xx_isa_remove(struct device *devptr, |
2005 | unsigned int dev) | ||
1997 | { | 2006 | { |
1998 | snd_card_free(platform_get_drvdata(devptr)); | 2007 | snd_card_free(dev_get_drvdata(devptr)); |
1999 | platform_set_drvdata(devptr, NULL); | 2008 | dev_set_drvdata(devptr, NULL); |
2000 | return 0; | 2009 | return 0; |
2001 | } | 2010 | } |
2002 | 2011 | ||
2003 | static struct platform_driver snd_opti9xx_driver = { | 2012 | static struct isa_driver snd_opti9xx_driver = { |
2004 | .probe = snd_opti9xx_nonpnp_probe, | 2013 | .match = snd_opti9xx_isa_match, |
2005 | .remove = __devexit_p(snd_opti9xx_nonpnp_remove), | 2014 | .probe = snd_opti9xx_isa_probe, |
2015 | .remove = __devexit_p(snd_opti9xx_isa_remove), | ||
2006 | /* FIXME: suspend/resume */ | 2016 | /* FIXME: suspend/resume */ |
2007 | .driver = { | 2017 | .driver = { |
2008 | .name = DRIVER_NAME | 2018 | .name = DEV_NAME |
2009 | }, | 2019 | }, |
2010 | }; | 2020 | }; |
2011 | 2021 | ||
2012 | #ifdef CONFIG_PNP | 2022 | #ifdef CONFIG_PNP |
2013 | static int __init snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, | 2023 | static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, |
2014 | const struct pnp_card_device_id *pid) | 2024 | const struct pnp_card_device_id *pid) |
2015 | { | 2025 | { |
2016 | struct snd_card *card; | 2026 | struct snd_card *card; |
2017 | int error, hw; | 2027 | int error, hw; |
@@ -2074,11 +2084,6 @@ static struct pnp_card_driver opti9xx_pnpc_driver = { | |||
2074 | }; | 2084 | }; |
2075 | #endif | 2085 | #endif |
2076 | 2086 | ||
2077 | #ifdef CONFIG_PNP | ||
2078 | #define is_isapnp_selected() isapnp | ||
2079 | #else | ||
2080 | #define is_isapnp_selected() 0 | ||
2081 | #endif | ||
2082 | #ifdef OPTi93X | 2087 | #ifdef OPTi93X |
2083 | #define CHIP_NAME "82C93x" | 2088 | #define CHIP_NAME "82C93x" |
2084 | #else | 2089 | #else |
@@ -2087,42 +2092,19 @@ static struct pnp_card_driver opti9xx_pnpc_driver = { | |||
2087 | 2092 | ||
2088 | static int __init alsa_card_opti9xx_init(void) | 2093 | static int __init alsa_card_opti9xx_init(void) |
2089 | { | 2094 | { |
2090 | int error; | ||
2091 | struct platform_device *device; | ||
2092 | |||
2093 | #ifdef CONFIG_PNP | 2095 | #ifdef CONFIG_PNP |
2094 | pnp_register_card_driver(&opti9xx_pnpc_driver); | 2096 | pnp_register_card_driver(&opti9xx_pnpc_driver); |
2095 | if (snd_opti9xx_pnp_is_probed) | 2097 | if (snd_opti9xx_pnp_is_probed) |
2096 | return 0; | 2098 | return 0; |
2097 | #endif | 2099 | #endif |
2098 | if (! is_isapnp_selected()) { | 2100 | return isa_register_driver(&snd_opti9xx_driver, 1); |
2099 | error = platform_driver_register(&snd_opti9xx_driver); | ||
2100 | if (error < 0) | ||
2101 | return error; | ||
2102 | device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); | ||
2103 | if (!IS_ERR(device)) { | ||
2104 | if (platform_get_drvdata(device)) { | ||
2105 | snd_opti9xx_platform_device = device; | ||
2106 | return 0; | ||
2107 | } | ||
2108 | platform_device_unregister(device); | ||
2109 | } | ||
2110 | platform_driver_unregister(&snd_opti9xx_driver); | ||
2111 | } | ||
2112 | #ifdef CONFIG_PNP | ||
2113 | pnp_unregister_card_driver(&opti9xx_pnpc_driver); | ||
2114 | #endif | ||
2115 | #ifdef MODULE | ||
2116 | printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n"); | ||
2117 | #endif | ||
2118 | return -ENODEV; | ||
2119 | } | 2101 | } |
2120 | 2102 | ||
2121 | static void __exit alsa_card_opti9xx_exit(void) | 2103 | static void __exit alsa_card_opti9xx_exit(void) |
2122 | { | 2104 | { |
2123 | if (!snd_opti9xx_pnp_is_probed) { | 2105 | if (!snd_opti9xx_pnp_is_probed) { |
2124 | platform_device_unregister(snd_opti9xx_platform_device); | 2106 | isa_unregister_driver(&snd_opti9xx_driver); |
2125 | platform_driver_unregister(&snd_opti9xx_driver); | 2107 | return; |
2126 | } | 2108 | } |
2127 | #ifdef CONFIG_PNP | 2109 | #ifdef CONFIG_PNP |
2128 | pnp_unregister_card_driver(&opti9xx_pnpc_driver); | 2110 | pnp_unregister_card_driver(&opti9xx_pnpc_driver); |
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index d64e67f2bafa..2a19b0a39eda 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/pnp.h> | 26 | #include <linux/pnp.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/isa.h> |
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <sound/core.h> | 30 | #include <sound/core.h> |
31 | #include <sound/sb.h> | 31 | #include <sound/sb.h> |
@@ -128,7 +128,6 @@ module_param_array(seq_ports, int, NULL, 0444); | |||
128 | MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth."); | 128 | MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth."); |
129 | #endif | 129 | #endif |
130 | 130 | ||
131 | static struct platform_device *platform_devices[SNDRV_CARDS]; | ||
132 | #ifdef CONFIG_PNP | 131 | #ifdef CONFIG_PNP |
133 | static int pnp_registered; | 132 | static int pnp_registered; |
134 | #endif | 133 | #endif |
@@ -519,7 +518,7 @@ static int snd_sb16_resume(struct snd_card *card) | |||
519 | } | 518 | } |
520 | #endif | 519 | #endif |
521 | 520 | ||
522 | static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr) | 521 | static int __devinit snd_sb16_isa_probe1(int dev, struct device *pdev) |
523 | { | 522 | { |
524 | struct snd_card_sb16 *acard; | 523 | struct snd_card_sb16 *acard; |
525 | struct snd_card *card; | 524 | struct snd_card *card; |
@@ -539,19 +538,23 @@ static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *dev | |||
539 | awe_port[dev] = port[dev] + 0x400; | 538 | awe_port[dev] = port[dev] + 0x400; |
540 | #endif | 539 | #endif |
541 | 540 | ||
542 | snd_card_set_dev(card, &devptr->dev); | 541 | snd_card_set_dev(card, pdev); |
543 | if ((err = snd_sb16_probe(card, dev)) < 0) { | 542 | if ((err = snd_sb16_probe(card, dev)) < 0) { |
544 | snd_card_free(card); | 543 | snd_card_free(card); |
545 | return err; | 544 | return err; |
546 | } | 545 | } |
547 | platform_set_drvdata(devptr, card); | 546 | dev_set_drvdata(pdev, card); |
548 | return 0; | 547 | return 0; |
549 | } | 548 | } |
550 | 549 | ||
551 | 550 | ||
552 | static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev) | 551 | static int __devinit snd_sb16_isa_match(struct device *pdev, unsigned int dev) |
552 | { | ||
553 | return enable[dev] && !is_isapnp_selected(dev); | ||
554 | } | ||
555 | |||
556 | static int __devinit snd_sb16_isa_probe(struct device *pdev, unsigned int dev) | ||
553 | { | 557 | { |
554 | int dev = pdev->id; | ||
555 | int err; | 558 | int err; |
556 | static int possible_irqs[] = {5, 9, 10, 7, -1}; | 559 | static int possible_irqs[] = {5, 9, 10, 7, -1}; |
557 | static int possible_dmas8[] = {1, 3, 0, -1}; | 560 | static int possible_dmas8[] = {1, 3, 0, -1}; |
@@ -577,13 +580,13 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev) | |||
577 | } | 580 | } |
578 | 581 | ||
579 | if (port[dev] != SNDRV_AUTO_PORT) | 582 | if (port[dev] != SNDRV_AUTO_PORT) |
580 | return snd_sb16_nonpnp_probe1(dev, pdev); | 583 | return snd_sb16_isa_probe1(dev, pdev); |
581 | else { | 584 | else { |
582 | static int possible_ports[] = {0x220, 0x240, 0x260, 0x280}; | 585 | static int possible_ports[] = {0x220, 0x240, 0x260, 0x280}; |
583 | int i; | 586 | int i; |
584 | for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { | 587 | for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { |
585 | port[dev] = possible_ports[i]; | 588 | port[dev] = possible_ports[i]; |
586 | err = snd_sb16_nonpnp_probe1(dev, pdev); | 589 | err = snd_sb16_isa_probe1(dev, pdev); |
587 | if (! err) | 590 | if (! err) |
588 | return 0; | 591 | return 0; |
589 | } | 592 | } |
@@ -591,47 +594,47 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev) | |||
591 | } | 594 | } |
592 | } | 595 | } |
593 | 596 | ||
594 | static int __devexit snd_sb16_nonpnp_remove(struct platform_device *devptr) | 597 | static int __devexit snd_sb16_isa_remove(struct device *pdev, unsigned int dev) |
595 | { | 598 | { |
596 | snd_card_free(platform_get_drvdata(devptr)); | 599 | snd_card_free(dev_get_drvdata(pdev)); |
597 | platform_set_drvdata(devptr, NULL); | 600 | dev_set_drvdata(pdev, NULL); |
598 | return 0; | 601 | return 0; |
599 | } | 602 | } |
600 | 603 | ||
601 | #ifdef CONFIG_PM | 604 | #ifdef CONFIG_PM |
602 | static int snd_sb16_nonpnp_suspend(struct platform_device *dev, pm_message_t state) | 605 | static int snd_sb16_isa_suspend(struct device *dev, unsigned int n, |
606 | pm_message_t state) | ||
603 | { | 607 | { |
604 | return snd_sb16_suspend(platform_get_drvdata(dev), state); | 608 | return snd_sb16_suspend(dev_get_drvdata(dev), state); |
605 | } | 609 | } |
606 | 610 | ||
607 | static int snd_sb16_nonpnp_resume(struct platform_device *dev) | 611 | static int snd_sb16_isa_resume(struct device *dev, unsigned int n) |
608 | { | 612 | { |
609 | return snd_sb16_resume(platform_get_drvdata(dev)); | 613 | return snd_sb16_resume(dev_get_drvdata(dev)); |
610 | } | 614 | } |
611 | #endif | 615 | #endif |
612 | 616 | ||
613 | #ifdef SNDRV_SBAWE | 617 | #ifdef SNDRV_SBAWE |
614 | #define SND_SB16_DRIVER "snd_sbawe" | 618 | #define DEV_NAME "sbawe" |
615 | #else | 619 | #else |
616 | #define SND_SB16_DRIVER "snd_sb16" | 620 | #define DEV_NAME "sb16" |
617 | #endif | 621 | #endif |
618 | 622 | ||
619 | static struct platform_driver snd_sb16_nonpnp_driver = { | 623 | static struct isa_driver snd_sb16_isa_driver = { |
620 | .probe = snd_sb16_nonpnp_probe, | 624 | .match = snd_sb16_isa_match, |
621 | .remove = __devexit_p(snd_sb16_nonpnp_remove), | 625 | .probe = snd_sb16_isa_probe, |
626 | .remove = __devexit_p(snd_sb16_isa_remove), | ||
622 | #ifdef CONFIG_PM | 627 | #ifdef CONFIG_PM |
623 | .suspend = snd_sb16_nonpnp_suspend, | 628 | .suspend = snd_sb16_isa_suspend, |
624 | .resume = snd_sb16_nonpnp_resume, | 629 | .resume = snd_sb16_isa_resume, |
625 | #endif | 630 | #endif |
626 | .driver = { | 631 | .driver = { |
627 | .name = SND_SB16_DRIVER | 632 | .name = DEV_NAME |
628 | }, | 633 | }, |
629 | }; | 634 | }; |
630 | 635 | ||
631 | 636 | ||
632 | #ifdef CONFIG_PNP | 637 | #ifdef CONFIG_PNP |
633 | static unsigned int __devinitdata sb16_pnp_devices; | ||
634 | |||
635 | static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, | 638 | static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, |
636 | const struct pnp_card_device_id *pid) | 639 | const struct pnp_card_device_id *pid) |
637 | { | 640 | { |
@@ -653,7 +656,6 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, | |||
653 | } | 656 | } |
654 | pnp_set_card_drvdata(pcard, card); | 657 | pnp_set_card_drvdata(pcard, card); |
655 | dev++; | 658 | dev++; |
656 | sb16_pnp_devices++; | ||
657 | return 0; | 659 | return 0; |
658 | } | 660 | } |
659 | 661 | ||
@@ -695,68 +697,29 @@ static struct pnp_card_driver sb16_pnpc_driver = { | |||
695 | 697 | ||
696 | #endif /* CONFIG_PNP */ | 698 | #endif /* CONFIG_PNP */ |
697 | 699 | ||
698 | static void __init_or_module snd_sb16_unregister_all(void) | ||
699 | { | ||
700 | int i; | ||
701 | |||
702 | #ifdef CONFIG_PNP | ||
703 | if (pnp_registered) | ||
704 | pnp_unregister_card_driver(&sb16_pnpc_driver); | ||
705 | #endif | ||
706 | for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | ||
707 | platform_device_unregister(platform_devices[i]); | ||
708 | platform_driver_unregister(&snd_sb16_nonpnp_driver); | ||
709 | } | ||
710 | |||
711 | static int __init alsa_card_sb16_init(void) | 700 | static int __init alsa_card_sb16_init(void) |
712 | { | 701 | { |
713 | int i, err, cards = 0; | 702 | int err; |
714 | 703 | ||
715 | if ((err = platform_driver_register(&snd_sb16_nonpnp_driver)) < 0) | 704 | err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS); |
705 | if (err < 0) | ||
716 | return err; | 706 | return err; |
717 | |||
718 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
719 | struct platform_device *device; | ||
720 | if (! enable[i] || is_isapnp_selected(i)) | ||
721 | continue; | ||
722 | device = platform_device_register_simple(SND_SB16_DRIVER, | ||
723 | i, NULL, 0); | ||
724 | if (IS_ERR(device)) | ||
725 | continue; | ||
726 | if (!platform_get_drvdata(device)) { | ||
727 | platform_device_unregister(device); | ||
728 | continue; | ||
729 | } | ||
730 | platform_devices[i] = device; | ||
731 | cards++; | ||
732 | } | ||
733 | #ifdef CONFIG_PNP | 707 | #ifdef CONFIG_PNP |
734 | /* PnP cards at last */ | 708 | /* PnP cards at last */ |
735 | err = pnp_register_card_driver(&sb16_pnpc_driver); | 709 | err = pnp_register_card_driver(&sb16_pnpc_driver); |
736 | if (!err) { | 710 | if (!err) |
737 | pnp_registered = 1; | 711 | pnp_registered = 1; |
738 | cards += sb16_pnp_devices; | ||
739 | } | ||
740 | #endif | ||
741 | |||
742 | if (!cards) { | ||
743 | #ifdef MODULE | ||
744 | snd_printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n"); | ||
745 | #ifdef SNDRV_SBAWE_EMU8000 | ||
746 | snd_printk(KERN_ERR "In case, if you have non-AWE card, try snd-sb16 module\n"); | ||
747 | #else | ||
748 | snd_printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n"); | ||
749 | #endif | 712 | #endif |
750 | #endif | ||
751 | snd_sb16_unregister_all(); | ||
752 | return -ENODEV; | ||
753 | } | ||
754 | return 0; | 713 | return 0; |
755 | } | 714 | } |
756 | 715 | ||
757 | static void __exit alsa_card_sb16_exit(void) | 716 | static void __exit alsa_card_sb16_exit(void) |
758 | { | 717 | { |
759 | snd_sb16_unregister_all(); | 718 | #ifdef CONFIG_PNP |
719 | if (pnp_registered) | ||
720 | pnp_unregister_card_driver(&sb16_pnpc_driver); | ||
721 | #endif | ||
722 | isa_unregister_driver(&snd_sb16_isa_driver); | ||
760 | } | 723 | } |
761 | 724 | ||
762 | module_init(alsa_card_sb16_init) | 725 | module_init(alsa_card_sb16_init) |
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c index 3d9d7e0107ca..b279f2308aef 100644 --- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c | |||
@@ -36,6 +36,13 @@ | |||
36 | MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>"); | 36 | MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>"); |
37 | MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor"); | 37 | MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor"); |
38 | MODULE_LICENSE("GPL"); | 38 | MODULE_LICENSE("GPL"); |
39 | #ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL | ||
40 | MODULE_FIRMWARE("sb16/mulaw_main.csp"); | ||
41 | MODULE_FIRMWARE("sb16/alaw_main.csp"); | ||
42 | MODULE_FIRMWARE("sb16/ima_adpcm_init.csp"); | ||
43 | MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp"); | ||
44 | MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp"); | ||
45 | #endif | ||
39 | 46 | ||
40 | #ifdef SNDRV_LITTLE_ENDIAN | 47 | #ifdef SNDRV_LITTLE_ENDIAN |
41 | #define CSP_HDR_VALUE(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24)) | 48 | #define CSP_HDR_VALUE(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24)) |
@@ -161,13 +168,17 @@ int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep) | |||
161 | */ | 168 | */ |
162 | static void snd_sb_csp_free(struct snd_hwdep *hwdep) | 169 | static void snd_sb_csp_free(struct snd_hwdep *hwdep) |
163 | { | 170 | { |
171 | #ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL | ||
164 | int i; | 172 | int i; |
173 | #endif | ||
165 | struct snd_sb_csp *p = hwdep->private_data; | 174 | struct snd_sb_csp *p = hwdep->private_data; |
166 | if (p) { | 175 | if (p) { |
167 | if (p->running & SNDRV_SB_CSP_ST_RUNNING) | 176 | if (p->running & SNDRV_SB_CSP_ST_RUNNING) |
168 | snd_sb_csp_stop(p); | 177 | snd_sb_csp_stop(p); |
178 | #ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL | ||
169 | for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i) | 179 | for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i) |
170 | release_firmware(p->csp_programs[i]); | 180 | release_firmware(p->csp_programs[i]); |
181 | #endif | ||
171 | kfree(p); | 182 | kfree(p); |
172 | } | 183 | } |
173 | } | 184 | } |
@@ -690,9 +701,7 @@ static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __use | |||
690 | return err; | 701 | return err; |
691 | } | 702 | } |
692 | 703 | ||
693 | #define FIRMWARE_IN_THE_KERNEL | 704 | #ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL |
694 | |||
695 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
696 | #include "sb16_csp_codecs.h" | 705 | #include "sb16_csp_codecs.h" |
697 | 706 | ||
698 | static const struct firmware snd_sb_csp_static_programs[] = { | 707 | static const struct firmware snd_sb_csp_static_programs[] = { |
@@ -714,22 +723,19 @@ static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags) | |||
714 | "sb16/ima_adpcm_capture.csp", | 723 | "sb16/ima_adpcm_capture.csp", |
715 | }; | 724 | }; |
716 | const struct firmware *program; | 725 | const struct firmware *program; |
717 | int err; | ||
718 | 726 | ||
719 | BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT); | 727 | BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT); |
720 | program = p->csp_programs[index]; | 728 | program = p->csp_programs[index]; |
721 | if (!program) { | 729 | if (!program) { |
722 | err = request_firmware(&program, names[index], | 730 | #ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL |
723 | p->chip->card->dev); | 731 | program = &snd_sb_csp_static_programs[index]; |
724 | if (err >= 0) | ||
725 | p->csp_programs[index] = program; | ||
726 | else { | ||
727 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
728 | program = &snd_sb_csp_static_programs[index]; | ||
729 | #else | 732 | #else |
733 | int err = request_firmware(&program, names[index], | ||
734 | p->chip->card->dev); | ||
735 | if (err < 0) | ||
730 | return err; | 736 | return err; |
731 | #endif | 737 | #endif |
732 | } | 738 | p->csp_programs[index] = program; |
733 | } | 739 | } |
734 | return snd_sb_csp_load(p, program->data, program->size, flags); | 740 | return snd_sb_csp_load(p, program->data, program->size, flags); |
735 | } | 741 | } |
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index be1e83e6dea3..a1b3786b391e 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/isa.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
@@ -56,8 +56,6 @@ MODULE_PARM_DESC(irq, "IRQ # for SB8 driver."); | |||
56 | module_param_array(dma8, int, NULL, 0444); | 56 | module_param_array(dma8, int, NULL, 0444); |
57 | MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver."); | 57 | MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver."); |
58 | 58 | ||
59 | static struct platform_device *devices[SNDRV_CARDS]; | ||
60 | |||
61 | struct snd_sb8 { | 59 | struct snd_sb8 { |
62 | struct resource *fm_res; /* used to block FM i/o region for legacy cards */ | 60 | struct resource *fm_res; /* used to block FM i/o region for legacy cards */ |
63 | struct snd_sb *chip; | 61 | struct snd_sb *chip; |
@@ -83,9 +81,23 @@ static void snd_sb8_free(struct snd_card *card) | |||
83 | release_and_free_resource(acard->fm_res); | 81 | release_and_free_resource(acard->fm_res); |
84 | } | 82 | } |
85 | 83 | ||
86 | static int __devinit snd_sb8_probe(struct platform_device *pdev) | 84 | static int __devinit snd_sb8_match(struct device *pdev, unsigned int dev) |
85 | { | ||
86 | if (!enable[dev]) | ||
87 | return 0; | ||
88 | if (irq[dev] == SNDRV_AUTO_IRQ) { | ||
89 | snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id); | ||
90 | return 0; | ||
91 | } | ||
92 | if (dma8[dev] == SNDRV_AUTO_DMA) { | ||
93 | snd_printk(KERN_ERR "%s: please specify dma8\n", pdev->bus_id); | ||
94 | return 0; | ||
95 | } | ||
96 | return 1; | ||
97 | } | ||
98 | |||
99 | static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev) | ||
87 | { | 100 | { |
88 | int dev = pdev->id; | ||
89 | struct snd_sb *chip; | 101 | struct snd_sb *chip; |
90 | struct snd_card *card; | 102 | struct snd_card *card; |
91 | struct snd_sb8 *acard; | 103 | struct snd_sb8 *acard; |
@@ -180,12 +192,12 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev) | |||
180 | chip->port, | 192 | chip->port, |
181 | irq[dev], dma8[dev]); | 193 | irq[dev], dma8[dev]); |
182 | 194 | ||
183 | snd_card_set_dev(card, &pdev->dev); | 195 | snd_card_set_dev(card, pdev); |
184 | 196 | ||
185 | if ((err = snd_card_register(card)) < 0) | 197 | if ((err = snd_card_register(card)) < 0) |
186 | goto _err; | 198 | goto _err; |
187 | 199 | ||
188 | platform_set_drvdata(pdev, card); | 200 | dev_set_drvdata(pdev, card); |
189 | return 0; | 201 | return 0; |
190 | 202 | ||
191 | _err: | 203 | _err: |
@@ -193,17 +205,18 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev) | |||
193 | return err; | 205 | return err; |
194 | } | 206 | } |
195 | 207 | ||
196 | static int __devexit snd_sb8_remove(struct platform_device *pdev) | 208 | static int __devexit snd_sb8_remove(struct device *pdev, unsigned int dev) |
197 | { | 209 | { |
198 | snd_card_free(platform_get_drvdata(pdev)); | 210 | snd_card_free(dev_get_drvdata(pdev)); |
199 | platform_set_drvdata(pdev, NULL); | 211 | dev_set_drvdata(pdev, NULL); |
200 | return 0; | 212 | return 0; |
201 | } | 213 | } |
202 | 214 | ||
203 | #ifdef CONFIG_PM | 215 | #ifdef CONFIG_PM |
204 | static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state) | 216 | static int snd_sb8_suspend(struct device *dev, unsigned int n, |
217 | pm_message_t state) | ||
205 | { | 218 | { |
206 | struct snd_card *card = platform_get_drvdata(dev); | 219 | struct snd_card *card = dev_get_drvdata(dev); |
207 | struct snd_sb8 *acard = card->private_data; | 220 | struct snd_sb8 *acard = card->private_data; |
208 | struct snd_sb *chip = acard->chip; | 221 | struct snd_sb *chip = acard->chip; |
209 | 222 | ||
@@ -213,9 +226,9 @@ static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state) | |||
213 | return 0; | 226 | return 0; |
214 | } | 227 | } |
215 | 228 | ||
216 | static int snd_sb8_resume(struct platform_device *dev) | 229 | static int snd_sb8_resume(struct device *dev, unsigned int n) |
217 | { | 230 | { |
218 | struct snd_card *card = platform_get_drvdata(dev); | 231 | struct snd_card *card = dev_get_drvdata(dev); |
219 | struct snd_sb8 *acard = card->private_data; | 232 | struct snd_sb8 *acard = card->private_data; |
220 | struct snd_sb *chip = acard->chip; | 233 | struct snd_sb *chip = acard->chip; |
221 | 234 | ||
@@ -226,9 +239,10 @@ static int snd_sb8_resume(struct platform_device *dev) | |||
226 | } | 239 | } |
227 | #endif | 240 | #endif |
228 | 241 | ||
229 | #define SND_SB8_DRIVER "snd_sb8" | 242 | #define DEV_NAME "sb8" |
230 | 243 | ||
231 | static struct platform_driver snd_sb8_driver = { | 244 | static struct isa_driver snd_sb8_driver = { |
245 | .match = snd_sb8_match, | ||
232 | .probe = snd_sb8_probe, | 246 | .probe = snd_sb8_probe, |
233 | .remove = __devexit_p(snd_sb8_remove), | 247 | .remove = __devexit_p(snd_sb8_remove), |
234 | #ifdef CONFIG_PM | 248 | #ifdef CONFIG_PM |
@@ -236,56 +250,18 @@ static struct platform_driver snd_sb8_driver = { | |||
236 | .resume = snd_sb8_resume, | 250 | .resume = snd_sb8_resume, |
237 | #endif | 251 | #endif |
238 | .driver = { | 252 | .driver = { |
239 | .name = SND_SB8_DRIVER | 253 | .name = DEV_NAME |
240 | }, | 254 | }, |
241 | }; | 255 | }; |
242 | 256 | ||
243 | static void __init_or_module snd_sb8_unregister_all(void) | ||
244 | { | ||
245 | int i; | ||
246 | |||
247 | for (i = 0; i < ARRAY_SIZE(devices); ++i) | ||
248 | platform_device_unregister(devices[i]); | ||
249 | platform_driver_unregister(&snd_sb8_driver); | ||
250 | } | ||
251 | |||
252 | static int __init alsa_card_sb8_init(void) | 257 | static int __init alsa_card_sb8_init(void) |
253 | { | 258 | { |
254 | int i, cards, err; | 259 | return isa_register_driver(&snd_sb8_driver, SNDRV_CARDS); |
255 | |||
256 | err = platform_driver_register(&snd_sb8_driver); | ||
257 | if (err < 0) | ||
258 | return err; | ||
259 | |||
260 | cards = 0; | ||
261 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
262 | struct platform_device *device; | ||
263 | if (! enable[i]) | ||
264 | continue; | ||
265 | device = platform_device_register_simple(SND_SB8_DRIVER, | ||
266 | i, NULL, 0); | ||
267 | if (IS_ERR(device)) | ||
268 | continue; | ||
269 | if (!platform_get_drvdata(device)) { | ||
270 | platform_device_unregister(device); | ||
271 | continue; | ||
272 | } | ||
273 | devices[i] = device; | ||
274 | cards++; | ||
275 | } | ||
276 | if (!cards) { | ||
277 | #ifdef MODULE | ||
278 | snd_printk(KERN_ERR "Sound Blaster soundcard not found or device busy\n"); | ||
279 | #endif | ||
280 | snd_sb8_unregister_all(); | ||
281 | return -ENODEV; | ||
282 | } | ||
283 | return 0; | ||
284 | } | 260 | } |
285 | 261 | ||
286 | static void __exit alsa_card_sb8_exit(void) | 262 | static void __exit alsa_card_sb8_exit(void) |
287 | { | 263 | { |
288 | snd_sb8_unregister_all(); | 264 | isa_unregister_driver(&snd_sb8_driver); |
289 | } | 265 | } |
290 | 266 | ||
291 | module_init(alsa_card_sb8_init) | 267 | module_init(alsa_card_sb8_init) |
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index 4fcd0f4e868c..922519def099 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <sound/driver.h> | 24 | #include <sound/driver.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/isa.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/time.h> | 29 | #include <linux/time.h> |
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
@@ -64,8 +64,6 @@ MODULE_PARM_DESC(irq, "IRQ # for Sound Galaxy driver."); | |||
64 | module_param_array(dma1, int, NULL, 0444); | 64 | module_param_array(dma1, int, NULL, 0444); |
65 | MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver."); | 65 | MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver."); |
66 | 66 | ||
67 | static struct platform_device *devices[SNDRV_CARDS]; | ||
68 | |||
69 | #define SGALAXY_AUXC_LEFT 18 | 67 | #define SGALAXY_AUXC_LEFT 18 |
70 | #define SGALAXY_AUXC_RIGHT 19 | 68 | #define SGALAXY_AUXC_RIGHT 19 |
71 | 69 | ||
@@ -96,7 +94,8 @@ static int snd_sgalaxy_sbdsp_reset(unsigned long port) | |||
96 | return 0; | 94 | return 0; |
97 | } | 95 | } |
98 | 96 | ||
99 | static int __init snd_sgalaxy_sbdsp_command(unsigned long port, unsigned char val) | 97 | static int __devinit snd_sgalaxy_sbdsp_command(unsigned long port, |
98 | unsigned char val) | ||
100 | { | 99 | { |
101 | int i; | 100 | int i; |
102 | 101 | ||
@@ -114,7 +113,7 @@ static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id) | |||
114 | return IRQ_NONE; | 113 | return IRQ_NONE; |
115 | } | 114 | } |
116 | 115 | ||
117 | static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma) | 116 | static int __devinit snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma) |
118 | { | 117 | { |
119 | static int interrupt_bits[] = {-1, -1, -1, -1, -1, -1, -1, 0x08, -1, | 118 | static int interrupt_bits[] = {-1, -1, -1, -1, -1, -1, -1, 0x08, -1, |
120 | 0x10, 0x18, 0x20, -1, -1, -1, -1}; | 119 | 0x10, 0x18, 0x20, -1, -1, -1, -1}; |
@@ -161,7 +160,7 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma) | |||
161 | return 0; | 160 | return 0; |
162 | } | 161 | } |
163 | 162 | ||
164 | static int __init snd_sgalaxy_detect(int dev, int irq, int dma) | 163 | static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma) |
165 | { | 164 | { |
166 | #if 0 | 165 | #if 0 |
167 | snd_printdd(PFX "switching to WSS mode\n"); | 166 | snd_printdd(PFX "switching to WSS mode\n"); |
@@ -182,7 +181,7 @@ AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7 | |||
182 | AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0) | 181 | AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0) |
183 | }; | 182 | }; |
184 | 183 | ||
185 | static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip) | 184 | static int __devinit snd_sgalaxy_mixer(struct snd_ad1848 *chip) |
186 | { | 185 | { |
187 | struct snd_card *card = chip->card; | 186 | struct snd_card *card = chip->card; |
188 | struct snd_ctl_elem_id id1, id2; | 187 | struct snd_ctl_elem_id id1, id2; |
@@ -218,23 +217,29 @@ static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip) | |||
218 | return 0; | 217 | return 0; |
219 | } | 218 | } |
220 | 219 | ||
221 | static int __init snd_sgalaxy_probe(struct platform_device *devptr) | 220 | static int __devinit snd_sgalaxy_match(struct device *devptr, unsigned int dev) |
222 | { | 221 | { |
223 | int dev = devptr->id; | 222 | if (!enable[dev]) |
224 | static int possible_irqs[] = {7, 9, 10, 11, -1}; | 223 | return 0; |
225 | static int possible_dmas[] = {1, 3, 0, -1}; | ||
226 | int err, xirq, xdma1; | ||
227 | struct snd_card *card; | ||
228 | struct snd_ad1848 *chip; | ||
229 | |||
230 | if (sbport[dev] == SNDRV_AUTO_PORT) { | 224 | if (sbport[dev] == SNDRV_AUTO_PORT) { |
231 | snd_printk(KERN_ERR PFX "specify SB port\n"); | 225 | snd_printk(KERN_ERR PFX "specify SB port\n"); |
232 | return -EINVAL; | 226 | return 0; |
233 | } | 227 | } |
234 | if (wssport[dev] == SNDRV_AUTO_PORT) { | 228 | if (wssport[dev] == SNDRV_AUTO_PORT) { |
235 | snd_printk(KERN_ERR PFX "specify WSS port\n"); | 229 | snd_printk(KERN_ERR PFX "specify WSS port\n"); |
236 | return -EINVAL; | 230 | return 0; |
237 | } | 231 | } |
232 | return 1; | ||
233 | } | ||
234 | |||
235 | static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev) | ||
236 | { | ||
237 | static int possible_irqs[] = {7, 9, 10, 11, -1}; | ||
238 | static int possible_dmas[] = {1, 3, 0, -1}; | ||
239 | int err, xirq, xdma1; | ||
240 | struct snd_card *card; | ||
241 | struct snd_ad1848 *chip; | ||
242 | |||
238 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 243 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); |
239 | if (card == NULL) | 244 | if (card == NULL) |
240 | return -ENOMEM; | 245 | return -ENOMEM; |
@@ -283,12 +288,12 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr) | |||
283 | sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d", | 288 | sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d", |
284 | wssport[dev], xirq, xdma1); | 289 | wssport[dev], xirq, xdma1); |
285 | 290 | ||
286 | snd_card_set_dev(card, &devptr->dev); | 291 | snd_card_set_dev(card, devptr); |
287 | 292 | ||
288 | if ((err = snd_card_register(card)) < 0) | 293 | if ((err = snd_card_register(card)) < 0) |
289 | goto _err; | 294 | goto _err; |
290 | 295 | ||
291 | platform_set_drvdata(devptr, card); | 296 | dev_set_drvdata(devptr, card); |
292 | return 0; | 297 | return 0; |
293 | 298 | ||
294 | _err: | 299 | _err: |
@@ -296,17 +301,18 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr) | |||
296 | return err; | 301 | return err; |
297 | } | 302 | } |
298 | 303 | ||
299 | static int __devexit snd_sgalaxy_remove(struct platform_device *devptr) | 304 | static int __devexit snd_sgalaxy_remove(struct device *devptr, unsigned int dev) |
300 | { | 305 | { |
301 | snd_card_free(platform_get_drvdata(devptr)); | 306 | snd_card_free(dev_get_drvdata(devptr)); |
302 | platform_set_drvdata(devptr, NULL); | 307 | dev_set_drvdata(devptr, NULL); |
303 | return 0; | 308 | return 0; |
304 | } | 309 | } |
305 | 310 | ||
306 | #ifdef CONFIG_PM | 311 | #ifdef CONFIG_PM |
307 | static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state) | 312 | static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n, |
313 | pm_message_t state) | ||
308 | { | 314 | { |
309 | struct snd_card *card = platform_get_drvdata(pdev); | 315 | struct snd_card *card = dev_get_drvdata(pdev); |
310 | struct snd_ad1848 *chip = card->private_data; | 316 | struct snd_ad1848 *chip = card->private_data; |
311 | 317 | ||
312 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 318 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
@@ -314,9 +320,9 @@ static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state) | |||
314 | return 0; | 320 | return 0; |
315 | } | 321 | } |
316 | 322 | ||
317 | static int snd_sgalaxy_resume(struct platform_device *pdev) | 323 | static int snd_sgalaxy_resume(struct device *pdev, unsigned int n) |
318 | { | 324 | { |
319 | struct snd_card *card = platform_get_drvdata(pdev); | 325 | struct snd_card *card = dev_get_drvdata(pdev); |
320 | struct snd_ad1848 *chip = card->private_data; | 326 | struct snd_ad1848 *chip = card->private_data; |
321 | 327 | ||
322 | chip->resume(chip); | 328 | chip->resume(chip); |
@@ -328,9 +334,10 @@ static int snd_sgalaxy_resume(struct platform_device *pdev) | |||
328 | } | 334 | } |
329 | #endif | 335 | #endif |
330 | 336 | ||
331 | #define SND_SGALAXY_DRIVER "snd_sgalaxy" | 337 | #define DEV_NAME "sgalaxy" |
332 | 338 | ||
333 | static struct platform_driver snd_sgalaxy_driver = { | 339 | static struct isa_driver snd_sgalaxy_driver = { |
340 | .match = snd_sgalaxy_match, | ||
334 | .probe = snd_sgalaxy_probe, | 341 | .probe = snd_sgalaxy_probe, |
335 | .remove = __devexit_p(snd_sgalaxy_remove), | 342 | .remove = __devexit_p(snd_sgalaxy_remove), |
336 | #ifdef CONFIG_PM | 343 | #ifdef CONFIG_PM |
@@ -338,56 +345,18 @@ static struct platform_driver snd_sgalaxy_driver = { | |||
338 | .resume = snd_sgalaxy_resume, | 345 | .resume = snd_sgalaxy_resume, |
339 | #endif | 346 | #endif |
340 | .driver = { | 347 | .driver = { |
341 | .name = SND_SGALAXY_DRIVER | 348 | .name = DEV_NAME |
342 | }, | 349 | }, |
343 | }; | 350 | }; |
344 | 351 | ||
345 | static void __init_or_module snd_sgalaxy_unregister_all(void) | ||
346 | { | ||
347 | int i; | ||
348 | |||
349 | for (i = 0; i < ARRAY_SIZE(devices); ++i) | ||
350 | platform_device_unregister(devices[i]); | ||
351 | platform_driver_unregister(&snd_sgalaxy_driver); | ||
352 | } | ||
353 | |||
354 | static int __init alsa_card_sgalaxy_init(void) | 352 | static int __init alsa_card_sgalaxy_init(void) |
355 | { | 353 | { |
356 | int i, cards, err; | 354 | return isa_register_driver(&snd_sgalaxy_driver, SNDRV_CARDS); |
357 | |||
358 | err = platform_driver_register(&snd_sgalaxy_driver); | ||
359 | if (err < 0) | ||
360 | return err; | ||
361 | |||
362 | cards = 0; | ||
363 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
364 | struct platform_device *device; | ||
365 | if (! enable[i]) | ||
366 | continue; | ||
367 | device = platform_device_register_simple(SND_SGALAXY_DRIVER, | ||
368 | i, NULL, 0); | ||
369 | if (IS_ERR(device)) | ||
370 | continue; | ||
371 | if (!platform_get_drvdata(device)) { | ||
372 | platform_device_unregister(device); | ||
373 | continue; | ||
374 | } | ||
375 | devices[i] = device; | ||
376 | cards++; | ||
377 | } | ||
378 | if (!cards) { | ||
379 | #ifdef MODULE | ||
380 | snd_printk(KERN_ERR "Sound Galaxy soundcard not found or device busy\n"); | ||
381 | #endif | ||
382 | snd_sgalaxy_unregister_all(); | ||
383 | return -ENODEV; | ||
384 | } | ||
385 | return 0; | ||
386 | } | 355 | } |
387 | 356 | ||
388 | static void __exit alsa_card_sgalaxy_exit(void) | 357 | static void __exit alsa_card_sgalaxy_exit(void) |
389 | { | 358 | { |
390 | snd_sgalaxy_unregister_all(); | 359 | isa_unregister_driver(&snd_sgalaxy_driver); |
391 | } | 360 | } |
392 | 361 | ||
393 | module_init(alsa_card_sgalaxy_init) | 362 | module_init(alsa_card_sgalaxy_init) |
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index b1f25823c652..08c14978558c 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <sound/driver.h> | 24 | #include <sound/driver.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/isa.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/pnp.h> | 29 | #include <linux/pnp.h> |
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
@@ -68,8 +68,6 @@ MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver."); | |||
68 | module_param_array(dma, int, NULL, 0444); | 68 | module_param_array(dma, int, NULL, 0444); |
69 | MODULE_PARM_DESC(dma, "DMA # for SoundScape driver."); | 69 | MODULE_PARM_DESC(dma, "DMA # for SoundScape driver."); |
70 | 70 | ||
71 | static struct platform_device *platform_devices[SNDRV_CARDS]; | ||
72 | |||
73 | #ifdef CONFIG_PNP | 71 | #ifdef CONFIG_PNP |
74 | static int pnp_registered; | 72 | static int pnp_registered; |
75 | static struct pnp_card_device_id sscape_pnpids[] = { | 73 | static struct pnp_card_device_id sscape_pnpids[] = { |
@@ -1254,9 +1252,27 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) | |||
1254 | } | 1252 | } |
1255 | 1253 | ||
1256 | 1254 | ||
1257 | static int __devinit snd_sscape_probe(struct platform_device *pdev) | 1255 | static int __devinit snd_sscape_match(struct device *pdev, unsigned int i) |
1256 | { | ||
1257 | /* | ||
1258 | * Make sure we were given ALL of the other parameters. | ||
1259 | */ | ||
1260 | if (port[i] == SNDRV_AUTO_PORT) | ||
1261 | return 0; | ||
1262 | |||
1263 | if (irq[i] == SNDRV_AUTO_IRQ || | ||
1264 | mpu_irq[i] == SNDRV_AUTO_IRQ || | ||
1265 | dma[i] == SNDRV_AUTO_DMA) { | ||
1266 | printk(KERN_INFO | ||
1267 | "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n"); | ||
1268 | return 0; | ||
1269 | } | ||
1270 | |||
1271 | return 1; | ||
1272 | } | ||
1273 | |||
1274 | static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev) | ||
1258 | { | 1275 | { |
1259 | int dev = pdev->id; | ||
1260 | struct snd_card *card; | 1276 | struct snd_card *card; |
1261 | int ret; | 1277 | int ret; |
1262 | 1278 | ||
@@ -1264,30 +1280,31 @@ static int __devinit snd_sscape_probe(struct platform_device *pdev) | |||
1264 | ret = create_sscape(dev, &card); | 1280 | ret = create_sscape(dev, &card); |
1265 | if (ret < 0) | 1281 | if (ret < 0) |
1266 | return ret; | 1282 | return ret; |
1267 | snd_card_set_dev(card, &pdev->dev); | 1283 | snd_card_set_dev(card, pdev); |
1268 | if ((ret = snd_card_register(card)) < 0) { | 1284 | if ((ret = snd_card_register(card)) < 0) { |
1269 | printk(KERN_ERR "sscape: Failed to register sound card\n"); | 1285 | printk(KERN_ERR "sscape: Failed to register sound card\n"); |
1270 | return ret; | 1286 | return ret; |
1271 | } | 1287 | } |
1272 | platform_set_drvdata(pdev, card); | 1288 | dev_set_drvdata(pdev, card); |
1273 | return 0; | 1289 | return 0; |
1274 | } | 1290 | } |
1275 | 1291 | ||
1276 | static int __devexit snd_sscape_remove(struct platform_device *devptr) | 1292 | static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev) |
1277 | { | 1293 | { |
1278 | snd_card_free(platform_get_drvdata(devptr)); | 1294 | snd_card_free(dev_get_drvdata(devptr)); |
1279 | platform_set_drvdata(devptr, NULL); | 1295 | dev_set_drvdata(devptr, NULL); |
1280 | return 0; | 1296 | return 0; |
1281 | } | 1297 | } |
1282 | 1298 | ||
1283 | #define SSCAPE_DRIVER "snd_sscape" | 1299 | #define DEV_NAME "sscape" |
1284 | 1300 | ||
1285 | static struct platform_driver snd_sscape_driver = { | 1301 | static struct isa_driver snd_sscape_driver = { |
1302 | .match = snd_sscape_match, | ||
1286 | .probe = snd_sscape_probe, | 1303 | .probe = snd_sscape_probe, |
1287 | .remove = __devexit_p(snd_sscape_remove), | 1304 | .remove = __devexit_p(snd_sscape_remove), |
1288 | /* FIXME: suspend/resume */ | 1305 | /* FIXME: suspend/resume */ |
1289 | .driver = { | 1306 | .driver = { |
1290 | .name = SSCAPE_DRIVER | 1307 | .name = DEV_NAME |
1291 | }, | 1308 | }, |
1292 | }; | 1309 | }; |
1293 | 1310 | ||
@@ -1386,72 +1403,6 @@ static struct pnp_card_driver sscape_pnpc_driver = { | |||
1386 | 1403 | ||
1387 | #endif /* CONFIG_PNP */ | 1404 | #endif /* CONFIG_PNP */ |
1388 | 1405 | ||
1389 | static void __init_or_module sscape_unregister_all(void) | ||
1390 | { | ||
1391 | int i; | ||
1392 | |||
1393 | #ifdef CONFIG_PNP | ||
1394 | if (pnp_registered) | ||
1395 | pnp_unregister_card_driver(&sscape_pnpc_driver); | ||
1396 | #endif | ||
1397 | for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | ||
1398 | platform_device_unregister(platform_devices[i]); | ||
1399 | platform_driver_unregister(&snd_sscape_driver); | ||
1400 | } | ||
1401 | |||
1402 | static int __init sscape_manual_probe(void) | ||
1403 | { | ||
1404 | struct platform_device *device; | ||
1405 | int i, ret; | ||
1406 | |||
1407 | ret = platform_driver_register(&snd_sscape_driver); | ||
1408 | if (ret < 0) | ||
1409 | return ret; | ||
1410 | |||
1411 | for (i = 0; i < SNDRV_CARDS; ++i) { | ||
1412 | /* | ||
1413 | * We do NOT probe for ports. | ||
1414 | * If we're not given a port number for this | ||
1415 | * card then we completely ignore this line | ||
1416 | * of parameters. | ||
1417 | */ | ||
1418 | if (port[i] == SNDRV_AUTO_PORT) | ||
1419 | continue; | ||
1420 | |||
1421 | /* | ||
1422 | * Make sure we were given ALL of the other parameters. | ||
1423 | */ | ||
1424 | if (irq[i] == SNDRV_AUTO_IRQ || | ||
1425 | mpu_irq[i] == SNDRV_AUTO_IRQ || | ||
1426 | dma[i] == SNDRV_AUTO_DMA) { | ||
1427 | printk(KERN_INFO | ||
1428 | "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n"); | ||
1429 | sscape_unregister_all(); | ||
1430 | return -ENXIO; | ||
1431 | } | ||
1432 | |||
1433 | /* | ||
1434 | * This cards looks OK ... | ||
1435 | */ | ||
1436 | device = platform_device_register_simple(SSCAPE_DRIVER, | ||
1437 | i, NULL, 0); | ||
1438 | if (IS_ERR(device)) | ||
1439 | continue; | ||
1440 | if (!platform_get_drvdata(device)) { | ||
1441 | platform_device_unregister(device); | ||
1442 | continue; | ||
1443 | } | ||
1444 | platform_devices[i] = device; | ||
1445 | } | ||
1446 | return 0; | ||
1447 | } | ||
1448 | |||
1449 | static void sscape_exit(void) | ||
1450 | { | ||
1451 | sscape_unregister_all(); | ||
1452 | } | ||
1453 | |||
1454 | |||
1455 | static int __init sscape_init(void) | 1406 | static int __init sscape_init(void) |
1456 | { | 1407 | { |
1457 | int ret; | 1408 | int ret; |
@@ -1462,7 +1413,7 @@ static int __init sscape_init(void) | |||
1462 | * of allocating cards, because the operator is | 1413 | * of allocating cards, because the operator is |
1463 | * S-P-E-L-L-I-N-G it out for us... | 1414 | * S-P-E-L-L-I-N-G it out for us... |
1464 | */ | 1415 | */ |
1465 | ret = sscape_manual_probe(); | 1416 | ret = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS); |
1466 | if (ret < 0) | 1417 | if (ret < 0) |
1467 | return ret; | 1418 | return ret; |
1468 | #ifdef CONFIG_PNP | 1419 | #ifdef CONFIG_PNP |
@@ -1472,5 +1423,14 @@ static int __init sscape_init(void) | |||
1472 | return 0; | 1423 | return 0; |
1473 | } | 1424 | } |
1474 | 1425 | ||
1426 | static void __exit sscape_exit(void) | ||
1427 | { | ||
1428 | #ifdef CONFIG_PNP | ||
1429 | if (pnp_registered) | ||
1430 | pnp_unregister_card_driver(&sscape_pnpc_driver); | ||
1431 | #endif | ||
1432 | isa_unregister_driver(&snd_sscape_driver); | ||
1433 | } | ||
1434 | |||
1475 | module_init(sscape_init); | 1435 | module_init(sscape_init); |
1476 | module_exit(sscape_exit); | 1436 | module_exit(sscape_exit); |
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index e2fdd5fd39d0..75673f723857 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/isa.h> |
28 | #include <linux/pnp.h> | 28 | #include <linux/pnp.h> |
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <sound/core.h> | 30 | #include <sound/core.h> |
@@ -40,7 +40,9 @@ MODULE_SUPPORTED_DEVICE("{{Turtle Beach,Maui/Tropez/Tropez+}}"); | |||
40 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 40 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
41 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 41 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
42 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ | 42 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ |
43 | #ifdef CONFIG_PNP | ||
43 | static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; | 44 | static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; |
45 | #endif | ||
44 | static long cs4232_pcm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ | 46 | static long cs4232_pcm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ |
45 | static int cs4232_pcm_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */ | 47 | static int cs4232_pcm_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */ |
46 | static long cs4232_mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ | 48 | static long cs4232_mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ |
@@ -83,8 +85,6 @@ MODULE_PARM_DESC(fm_port, "FM port #."); | |||
83 | module_param_array(use_cs4232_midi, bool, NULL, 0444); | 85 | module_param_array(use_cs4232_midi, bool, NULL, 0444); |
84 | MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)"); | 86 | MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)"); |
85 | 87 | ||
86 | static struct platform_device *platform_devices[SNDRV_CARDS]; | ||
87 | |||
88 | #ifdef CONFIG_PNP | 88 | #ifdef CONFIG_PNP |
89 | static int pnp_registered; | 89 | static int pnp_registered; |
90 | 90 | ||
@@ -588,56 +588,67 @@ snd_wavefront_probe (struct snd_card *card, int dev) | |||
588 | return snd_card_register(card); | 588 | return snd_card_register(card); |
589 | } | 589 | } |
590 | 590 | ||
591 | static int __devinit snd_wavefront_nonpnp_probe(struct platform_device *pdev) | 591 | static int __devinit snd_wavefront_isa_match(struct device *pdev, |
592 | unsigned int dev) | ||
592 | { | 593 | { |
593 | int dev = pdev->id; | 594 | if (!enable[dev]) |
594 | struct snd_card *card; | 595 | return 0; |
595 | int err; | 596 | #ifdef CONFIG_PNP |
596 | 597 | if (isapnp[dev]) | |
598 | return 0; | ||
599 | #endif | ||
597 | if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { | 600 | if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { |
598 | snd_printk("specify CS4232 port\n"); | 601 | snd_printk("specify CS4232 port\n"); |
599 | return -EINVAL; | 602 | return 0; |
600 | } | 603 | } |
601 | if (ics2115_port[dev] == SNDRV_AUTO_PORT) { | 604 | if (ics2115_port[dev] == SNDRV_AUTO_PORT) { |
602 | snd_printk("specify ICS2115 port\n"); | 605 | snd_printk("specify ICS2115 port\n"); |
603 | return -ENODEV; | 606 | return 0; |
604 | } | 607 | } |
608 | return 1; | ||
609 | } | ||
610 | |||
611 | static int __devinit snd_wavefront_isa_probe(struct device *pdev, | ||
612 | unsigned int dev) | ||
613 | { | ||
614 | struct snd_card *card; | ||
615 | int err; | ||
605 | 616 | ||
606 | card = snd_wavefront_card_new(dev); | 617 | card = snd_wavefront_card_new(dev); |
607 | if (! card) | 618 | if (! card) |
608 | return -ENOMEM; | 619 | return -ENOMEM; |
609 | snd_card_set_dev(card, &pdev->dev); | 620 | snd_card_set_dev(card, pdev); |
610 | if ((err = snd_wavefront_probe(card, dev)) < 0) { | 621 | if ((err = snd_wavefront_probe(card, dev)) < 0) { |
611 | snd_card_free(card); | 622 | snd_card_free(card); |
612 | return err; | 623 | return err; |
613 | } | 624 | } |
614 | 625 | ||
615 | platform_set_drvdata(pdev, card); | 626 | dev_set_drvdata(pdev, card); |
616 | return 0; | 627 | return 0; |
617 | } | 628 | } |
618 | 629 | ||
619 | static int __devexit snd_wavefront_nonpnp_remove(struct platform_device *devptr) | 630 | static int __devexit snd_wavefront_isa_remove(struct device *devptr, |
631 | unsigned int dev) | ||
620 | { | 632 | { |
621 | snd_card_free(platform_get_drvdata(devptr)); | 633 | snd_card_free(dev_get_drvdata(devptr)); |
622 | platform_set_drvdata(devptr, NULL); | 634 | dev_set_drvdata(devptr, NULL); |
623 | return 0; | 635 | return 0; |
624 | } | 636 | } |
625 | 637 | ||
626 | #define WAVEFRONT_DRIVER "snd_wavefront" | 638 | #define DEV_NAME "wavefront" |
627 | 639 | ||
628 | static struct platform_driver snd_wavefront_driver = { | 640 | static struct isa_driver snd_wavefront_driver = { |
629 | .probe = snd_wavefront_nonpnp_probe, | 641 | .match = snd_wavefront_isa_match, |
630 | .remove = __devexit_p(snd_wavefront_nonpnp_remove), | 642 | .probe = snd_wavefront_isa_probe, |
643 | .remove = __devexit_p(snd_wavefront_isa_remove), | ||
631 | /* FIXME: suspend, resume */ | 644 | /* FIXME: suspend, resume */ |
632 | .driver = { | 645 | .driver = { |
633 | .name = WAVEFRONT_DRIVER | 646 | .name = DEV_NAME |
634 | }, | 647 | }, |
635 | }; | 648 | }; |
636 | 649 | ||
637 | 650 | ||
638 | #ifdef CONFIG_PNP | 651 | #ifdef CONFIG_PNP |
639 | static unsigned int __devinitdata wavefront_pnp_devices; | ||
640 | |||
641 | static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, | 652 | static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, |
642 | const struct pnp_card_device_id *pid) | 653 | const struct pnp_card_device_id *pid) |
643 | { | 654 | { |
@@ -670,7 +681,6 @@ static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, | |||
670 | 681 | ||
671 | pnp_set_card_drvdata(pcard, card); | 682 | pnp_set_card_drvdata(pcard, card); |
672 | dev++; | 683 | dev++; |
673 | wavefront_pnp_devices++; | ||
674 | return 0; | 684 | return 0; |
675 | } | 685 | } |
676 | 686 | ||
@@ -691,67 +701,28 @@ static struct pnp_card_driver wavefront_pnpc_driver = { | |||
691 | 701 | ||
692 | #endif /* CONFIG_PNP */ | 702 | #endif /* CONFIG_PNP */ |
693 | 703 | ||
694 | static void __init_or_module snd_wavefront_unregister_all(void) | ||
695 | { | ||
696 | int i; | ||
697 | |||
698 | #ifdef CONFIG_PNP | ||
699 | if (pnp_registered) | ||
700 | pnp_unregister_card_driver(&wavefront_pnpc_driver); | ||
701 | #endif | ||
702 | for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | ||
703 | platform_device_unregister(platform_devices[i]); | ||
704 | platform_driver_unregister(&snd_wavefront_driver); | ||
705 | } | ||
706 | |||
707 | static int __init alsa_card_wavefront_init(void) | 704 | static int __init alsa_card_wavefront_init(void) |
708 | { | 705 | { |
709 | int i, err, cards = 0; | 706 | int err; |
710 | 707 | ||
711 | if ((err = platform_driver_register(&snd_wavefront_driver)) < 0) | 708 | err = isa_register_driver(&snd_wavefront_driver, SNDRV_CARDS); |
709 | if (err < 0) | ||
712 | return err; | 710 | return err; |
713 | |||
714 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
715 | struct platform_device *device; | ||
716 | if (! enable[i]) | ||
717 | continue; | ||
718 | #ifdef CONFIG_PNP | ||
719 | if (isapnp[i]) | ||
720 | continue; | ||
721 | #endif | ||
722 | device = platform_device_register_simple(WAVEFRONT_DRIVER, | ||
723 | i, NULL, 0); | ||
724 | if (IS_ERR(device)) | ||
725 | continue; | ||
726 | if (!platform_get_drvdata(device)) { | ||
727 | platform_device_unregister(device); | ||
728 | continue; | ||
729 | } | ||
730 | platform_devices[i] = device; | ||
731 | cards++; | ||
732 | } | ||
733 | |||
734 | #ifdef CONFIG_PNP | 711 | #ifdef CONFIG_PNP |
735 | err = pnp_register_card_driver(&wavefront_pnpc_driver); | 712 | err = pnp_register_card_driver(&wavefront_pnpc_driver); |
736 | if (!err) { | 713 | if (!err) |
737 | pnp_registered = 1; | 714 | pnp_registered = 1; |
738 | cards += wavefront_pnp_devices; | ||
739 | } | ||
740 | #endif | ||
741 | |||
742 | if (!cards) { | ||
743 | #ifdef MODULE | ||
744 | printk (KERN_ERR "No WaveFront cards found or devices busy\n"); | ||
745 | #endif | 715 | #endif |
746 | snd_wavefront_unregister_all(); | ||
747 | return -ENODEV; | ||
748 | } | ||
749 | return 0; | 716 | return 0; |
750 | } | 717 | } |
751 | 718 | ||
752 | static void __exit alsa_card_wavefront_exit(void) | 719 | static void __exit alsa_card_wavefront_exit(void) |
753 | { | 720 | { |
754 | snd_wavefront_unregister_all(); | 721 | #ifdef CONFIG_PNP |
722 | if (pnp_registered) | ||
723 | pnp_unregister_card_driver(&wavefront_pnpc_driver); | ||
724 | #endif | ||
725 | isa_unregister_driver(&snd_wavefront_driver); | ||
755 | } | 726 | } |
756 | 727 | ||
757 | module_init(alsa_card_wavefront_init) | 728 | module_init(alsa_card_wavefront_init) |
diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c index 15331ed88194..fc95a870f690 100644 --- a/sound/isa/wavefront/wavefront_fx.c +++ b/sound/isa/wavefront/wavefront_fx.c | |||
@@ -35,9 +35,7 @@ | |||
35 | 35 | ||
36 | #define WAIT_IDLE 0xff | 36 | #define WAIT_IDLE 0xff |
37 | 37 | ||
38 | #define FIRMWARE_IN_THE_KERNEL | 38 | #ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL |
39 | |||
40 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
41 | #include "yss225.c" | 39 | #include "yss225.c" |
42 | static const struct firmware yss225_registers_firmware = { | 40 | static const struct firmware yss225_registers_firmware = { |
43 | .data = (u8 *)yss225_registers, | 41 | .data = (u8 *)yss225_registers, |
@@ -258,21 +256,21 @@ snd_wavefront_fx_start (snd_wavefront_t *dev) | |||
258 | { | 256 | { |
259 | unsigned int i; | 257 | unsigned int i; |
260 | int err; | 258 | int err; |
261 | const struct firmware *firmware; | 259 | const struct firmware *firmware = NULL; |
262 | 260 | ||
263 | if (dev->fx_initialized) | 261 | if (dev->fx_initialized) |
264 | return 0; | 262 | return 0; |
265 | 263 | ||
264 | #ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL | ||
265 | firmware = &yss225_registers_firmware; | ||
266 | #else | ||
266 | err = request_firmware(&firmware, "yamaha/yss225_registers.bin", | 267 | err = request_firmware(&firmware, "yamaha/yss225_registers.bin", |
267 | dev->card->dev); | 268 | dev->card->dev); |
268 | if (err < 0) { | 269 | if (err < 0) { |
269 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
270 | firmware = &yss225_registers_firmware; | ||
271 | #else | ||
272 | err = -1; | 270 | err = -1; |
273 | goto out; | 271 | goto out; |
274 | #endif | ||
275 | } | 272 | } |
273 | #endif | ||
276 | 274 | ||
277 | for (i = 0; i + 1 < firmware->size; i += 2) { | 275 | for (i = 0; i + 1 < firmware->size; i += 2) { |
278 | if (firmware->data[i] >= 8 && firmware->data[i] < 16) { | 276 | if (firmware->data[i] >= 8 && firmware->data[i] < 16) { |
@@ -295,9 +293,12 @@ snd_wavefront_fx_start (snd_wavefront_t *dev) | |||
295 | err = 0; | 293 | err = 0; |
296 | 294 | ||
297 | out: | 295 | out: |
298 | #ifdef FIRMWARE_IN_THE_KERNEL | 296 | #ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL |
299 | if (firmware != &yss225_registers_firmware) | 297 | release_firmware(firmware); |
300 | #endif | 298 | #endif |
301 | release_firmware(firmware); | ||
302 | return err; | 299 | return err; |
303 | } | 300 | } |
301 | |||
302 | #ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL | ||
303 | MODULE_FIRMWARE("yamaha/yss225_registers.bin"); | ||
304 | #endif | ||
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 1bcfb3aac18d..61e35ecc57b8 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -576,7 +576,7 @@ config SND_INTEL8X0M | |||
576 | config SND_KORG1212 | 576 | config SND_KORG1212 |
577 | tristate "Korg 1212 IO" | 577 | tristate "Korg 1212 IO" |
578 | depends on SND | 578 | depends on SND |
579 | select FW_LOADER | 579 | select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL |
580 | select SND_PCM | 580 | select SND_PCM |
581 | help | 581 | help |
582 | Say Y here to include support for Korg 1212IO soundcards. | 582 | Say Y here to include support for Korg 1212IO soundcards. |
@@ -584,10 +584,19 @@ config SND_KORG1212 | |||
584 | To compile this driver as a module, choose M here: the module | 584 | To compile this driver as a module, choose M here: the module |
585 | will be called snd-korg1212. | 585 | will be called snd-korg1212. |
586 | 586 | ||
587 | config SND_KORG1212_FIRMWARE_IN_KERNEL | ||
588 | bool "In-kernel firmware for Korg1212 driver" | ||
589 | depends on SND_KORG1212 | ||
590 | default y | ||
591 | help | ||
592 | Say Y here to include the static firmware built in the kernel | ||
593 | for the Korg1212 driver. If you choose N here, you need to | ||
594 | install the firmware files from the alsa-firmware package. | ||
595 | |||
587 | config SND_MAESTRO3 | 596 | config SND_MAESTRO3 |
588 | tristate "ESS Allegro/Maestro3" | 597 | tristate "ESS Allegro/Maestro3" |
589 | depends on SND | 598 | depends on SND |
590 | select FW_LOADER | 599 | select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL |
591 | select SND_AC97_CODEC | 600 | select SND_AC97_CODEC |
592 | help | 601 | help |
593 | Say Y here to include support for soundcards based on ESS Maestro 3 | 602 | Say Y here to include support for soundcards based on ESS Maestro 3 |
@@ -596,6 +605,15 @@ config SND_MAESTRO3 | |||
596 | To compile this driver as a module, choose M here: the module | 605 | To compile this driver as a module, choose M here: the module |
597 | will be called snd-maestro3. | 606 | will be called snd-maestro3. |
598 | 607 | ||
608 | config SND_MAESTRO3_FIRMWARE_IN_KERNEL | ||
609 | bool "In-kernel firmware for Maestro3 driver" | ||
610 | depends on SND_MAESTRO3 | ||
611 | default y | ||
612 | help | ||
613 | Say Y here to include the static firmware built in the kernel | ||
614 | for the Maestro3 driver. If you choose N here, you need to | ||
615 | install the firmware files from the alsa-firmware package. | ||
616 | |||
599 | config SND_MIXART | 617 | config SND_MIXART |
600 | tristate "Digigram miXart" | 618 | tristate "Digigram miXart" |
601 | depends on SND | 619 | depends on SND |
@@ -737,7 +755,7 @@ config SND_VX222 | |||
737 | config SND_YMFPCI | 755 | config SND_YMFPCI |
738 | tristate "Yamaha YMF724/740/744/754" | 756 | tristate "Yamaha YMF724/740/744/754" |
739 | depends on SND | 757 | depends on SND |
740 | select FW_LOADER | 758 | select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL |
741 | select SND_OPL3_LIB | 759 | select SND_OPL3_LIB |
742 | select SND_MPU401_UART | 760 | select SND_MPU401_UART |
743 | select SND_AC97_CODEC | 761 | select SND_AC97_CODEC |
@@ -748,6 +766,15 @@ config SND_YMFPCI | |||
748 | To compile this driver as a module, choose M here: the module | 766 | To compile this driver as a module, choose M here: the module |
749 | will be called snd-ymfpci. | 767 | will be called snd-ymfpci. |
750 | 768 | ||
769 | config SND_YMFPCI_FIRMWARE_IN_KERNEL | ||
770 | bool "In-kernel firmware for YMFPCI driver" | ||
771 | depends on SND_YMFPCI | ||
772 | default y | ||
773 | help | ||
774 | Say Y here to include the static firmware built in the kernel | ||
775 | for the YMFPCI driver. If you choose N here, you need to | ||
776 | install the firmware files from the alsa-firmware package. | ||
777 | |||
751 | config SND_AC97_POWER_SAVE | 778 | config SND_AC97_POWER_SAVE |
752 | bool "AC97 Power-Saving Mode" | 779 | bool "AC97 Power-Saving Mode" |
753 | depends on SND_AC97_CODEC && EXPERIMENTAL | 780 | depends on SND_AC97_CODEC && EXPERIMENTAL |
diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile index 3c3222122d8b..f5d471896b95 100644 --- a/sound/pci/ac97/Makefile +++ b/sound/pci/ac97/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> | 3 | # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> |
4 | # | 4 | # |
5 | 5 | ||
6 | snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ac97_patch.o | 6 | snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o |
7 | 7 | ||
8 | ifneq ($(CONFIG_PROC_FS),) | 8 | ifneq ($(CONFIG_PROC_FS),) |
9 | snd-ac97-codec-objs += ac97_proc.o | 9 | snd-ac97-codec-objs += ac97_proc.o |
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 3bfb2102fc5d..bbed644bf9c5 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -35,9 +35,9 @@ | |||
35 | #include <sound/ac97_codec.h> | 35 | #include <sound/ac97_codec.h> |
36 | #include <sound/asoundef.h> | 36 | #include <sound/asoundef.h> |
37 | #include <sound/initval.h> | 37 | #include <sound/initval.h> |
38 | #include "ac97_local.h" | ||
39 | #include "ac97_id.h" | 38 | #include "ac97_id.h" |
40 | #include "ac97_patch.h" | 39 | |
40 | #include "ac97_patch.c" | ||
41 | 41 | ||
42 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); | 42 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); |
43 | MODULE_DESCRIPTION("Universal interface for Audio Codec '97"); | 43 | MODULE_DESCRIPTION("Universal interface for Audio Codec '97"); |
@@ -432,7 +432,8 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns | |||
432 | * Controls | 432 | * Controls |
433 | */ | 433 | */ |
434 | 434 | ||
435 | int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 435 | static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, |
436 | struct snd_ctl_elem_info *uinfo) | ||
436 | { | 437 | { |
437 | struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; | 438 | struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; |
438 | 439 | ||
@@ -446,7 +447,8 @@ int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
446 | return 0; | 447 | return 0; |
447 | } | 448 | } |
448 | 449 | ||
449 | int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 450 | static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, |
451 | struct snd_ctl_elem_value *ucontrol) | ||
450 | { | 452 | { |
451 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 453 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
452 | struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; | 454 | struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; |
@@ -462,7 +464,8 @@ int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
462 | return 0; | 464 | return 0; |
463 | } | 465 | } |
464 | 466 | ||
465 | int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 467 | static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, |
468 | struct snd_ctl_elem_value *ucontrol) | ||
466 | { | 469 | { |
467 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 470 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
468 | struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; | 471 | struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; |
@@ -508,7 +511,8 @@ static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save) | |||
508 | } | 511 | } |
509 | 512 | ||
510 | /* volume and switch controls */ | 513 | /* volume and switch controls */ |
511 | int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 514 | static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, |
515 | struct snd_ctl_elem_info *uinfo) | ||
512 | { | 516 | { |
513 | int mask = (kcontrol->private_value >> 16) & 0xff; | 517 | int mask = (kcontrol->private_value >> 16) & 0xff; |
514 | int shift = (kcontrol->private_value >> 8) & 0x0f; | 518 | int shift = (kcontrol->private_value >> 8) & 0x0f; |
@@ -521,7 +525,8 @@ int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info | |||
521 | return 0; | 525 | return 0; |
522 | } | 526 | } |
523 | 527 | ||
524 | int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 528 | static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, |
529 | struct snd_ctl_elem_value *ucontrol) | ||
525 | { | 530 | { |
526 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 531 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
527 | int reg = kcontrol->private_value & 0xff; | 532 | int reg = kcontrol->private_value & 0xff; |
@@ -544,7 +549,8 @@ int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value | |||
544 | return 0; | 549 | return 0; |
545 | } | 550 | } |
546 | 551 | ||
547 | int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 552 | static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, |
553 | struct snd_ctl_elem_value *ucontrol) | ||
548 | { | 554 | { |
549 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 555 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
550 | int reg = kcontrol->private_value & 0xff; | 556 | int reg = kcontrol->private_value & 0xff; |
@@ -646,7 +652,7 @@ AC97_ENUM("Mic Select", std_enum[3]), | |||
646 | AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0) | 652 | AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0) |
647 | }; | 653 | }; |
648 | 654 | ||
649 | const struct snd_kcontrol_new snd_ac97_controls_3d[2] = { | 655 | static const struct snd_kcontrol_new snd_ac97_controls_3d[2] = { |
650 | AC97_SINGLE("3D Control - Center", AC97_3D_CONTROL, 8, 15, 0), | 656 | AC97_SINGLE("3D Control - Center", AC97_3D_CONTROL, 8, 15, 0), |
651 | AC97_SINGLE("3D Control - Depth", AC97_3D_CONTROL, 0, 15, 0) | 657 | AC97_SINGLE("3D Control - Depth", AC97_3D_CONTROL, 0, 15, 0) |
652 | }; | 658 | }; |
@@ -817,7 +823,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
817 | return change; | 823 | return change; |
818 | } | 824 | } |
819 | 825 | ||
820 | const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = { | 826 | static const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = { |
821 | { | 827 | { |
822 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 828 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
823 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 829 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -1097,7 +1103,7 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha | |||
1097 | } | 1103 | } |
1098 | } | 1104 | } |
1099 | 1105 | ||
1100 | int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit) | 1106 | static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit) |
1101 | { | 1107 | { |
1102 | unsigned short mask, val, orig, res; | 1108 | unsigned short mask, val, orig, res; |
1103 | 1109 | ||
@@ -1137,7 +1143,8 @@ static inline int printable(unsigned int x) | |||
1137 | return x; | 1143 | return x; |
1138 | } | 1144 | } |
1139 | 1145 | ||
1140 | struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97) | 1146 | static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, |
1147 | struct snd_ac97 * ac97) | ||
1141 | { | 1148 | { |
1142 | struct snd_kcontrol_new template; | 1149 | struct snd_kcontrol_new template; |
1143 | memcpy(&template, _template, sizeof(template)); | 1150 | memcpy(&template, _template, sizeof(template)); |
@@ -2544,7 +2551,8 @@ static void set_ctl_name(char *dst, const char *src, const char *suffix) | |||
2544 | } | 2551 | } |
2545 | 2552 | ||
2546 | /* remove the control with the given name and optional suffix */ | 2553 | /* remove the control with the given name and optional suffix */ |
2547 | int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix) | 2554 | static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, |
2555 | const char *suffix) | ||
2548 | { | 2556 | { |
2549 | struct snd_ctl_elem_id id; | 2557 | struct snd_ctl_elem_id id; |
2550 | memset(&id, 0, sizeof(id)); | 2558 | memset(&id, 0, sizeof(id)); |
@@ -2563,7 +2571,8 @@ static struct snd_kcontrol *ctl_find(struct snd_ac97 *ac97, const char *name, co | |||
2563 | } | 2571 | } |
2564 | 2572 | ||
2565 | /* rename the control with the given name and optional suffix */ | 2573 | /* rename the control with the given name and optional suffix */ |
2566 | int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix) | 2574 | static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, |
2575 | const char *dst, const char *suffix) | ||
2567 | { | 2576 | { |
2568 | struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix); | 2577 | struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix); |
2569 | if (kctl) { | 2578 | if (kctl) { |
@@ -2574,14 +2583,16 @@ int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, | |||
2574 | } | 2583 | } |
2575 | 2584 | ||
2576 | /* rename both Volume and Switch controls - don't check the return value */ | 2585 | /* rename both Volume and Switch controls - don't check the return value */ |
2577 | void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst) | 2586 | static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, |
2587 | const char *dst) | ||
2578 | { | 2588 | { |
2579 | snd_ac97_rename_ctl(ac97, src, dst, "Switch"); | 2589 | snd_ac97_rename_ctl(ac97, src, dst, "Switch"); |
2580 | snd_ac97_rename_ctl(ac97, src, dst, "Volume"); | 2590 | snd_ac97_rename_ctl(ac97, src, dst, "Volume"); |
2581 | } | 2591 | } |
2582 | 2592 | ||
2583 | /* swap controls */ | 2593 | /* swap controls */ |
2584 | int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix) | 2594 | static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, |
2595 | const char *s2, const char *suffix) | ||
2585 | { | 2596 | { |
2586 | struct snd_kcontrol *kctl1, *kctl2; | 2597 | struct snd_kcontrol *kctl1, *kctl2; |
2587 | kctl1 = ctl_find(ac97, s1, suffix); | 2598 | kctl1 = ctl_find(ac97, s1, suffix); |
diff --git a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h index a6244c720a1d..78745c5c6df8 100644 --- a/sound/pci/ac97/ac97_local.h +++ b/sound/pci/ac97/ac97_local.h | |||
@@ -22,59 +22,8 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | ((invert) << 24)) | 25 | void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, |
26 | #define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26)) | 26 | int modem); |
27 | #define AC97_SINGLE(xname, reg, shift, mask, invert) \ | ||
28 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \ | ||
29 | .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ | ||
30 | .private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) } | ||
31 | #define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \ | ||
32 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \ | ||
33 | .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ | ||
34 | .private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) } | ||
35 | #define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \ | ||
36 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_ac97_info_volsw, \ | ||
37 | .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ | ||
38 | .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) } | ||
39 | |||
40 | /* enum control */ | ||
41 | struct ac97_enum { | ||
42 | unsigned char reg; | ||
43 | unsigned char shift_l; | ||
44 | unsigned char shift_r; | ||
45 | unsigned short mask; | ||
46 | const char **texts; | ||
47 | }; | ||
48 | |||
49 | #define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ | ||
50 | { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ | ||
51 | .mask = xmask, .texts = xtexts } | ||
52 | #define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \ | ||
53 | AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts) | ||
54 | #define AC97_ENUM(xname, xenum) \ | ||
55 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_enum_double, \ | ||
56 | .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \ | ||
57 | .private_value = (unsigned long)&xenum } | ||
58 | |||
59 | /* ac97_codec.c */ | ||
60 | extern const struct snd_kcontrol_new snd_ac97_controls_3d[]; | ||
61 | extern const struct snd_kcontrol_new snd_ac97_controls_spdif[]; | ||
62 | struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97); | ||
63 | void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int modem); | ||
64 | int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); | ||
65 | int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); | ||
66 | int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); | ||
67 | int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit); | ||
68 | int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix); | ||
69 | int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix); | ||
70 | int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix); | ||
71 | void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst); | ||
72 | void snd_ac97_restore_status(struct snd_ac97 *ac97); | ||
73 | void snd_ac97_restore_iec958(struct snd_ac97 *ac97); | ||
74 | int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); | ||
75 | int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); | ||
76 | int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); | ||
77 | |||
78 | int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg, | 27 | int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg, |
79 | unsigned short mask, unsigned short value); | 28 | unsigned short mask, unsigned short value); |
80 | 29 | ||
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index b188a4df58cb..3eac0f86266c 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -23,20 +23,8 @@ | |||
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <sound/driver.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/mutex.h> | ||
31 | |||
32 | #include <sound/core.h> | ||
33 | #include <sound/pcm.h> | ||
34 | #include <sound/control.h> | ||
35 | #include <sound/tlv.h> | ||
36 | #include <sound/ac97_codec.h> | ||
37 | #include "ac97_patch.h" | ||
38 | #include "ac97_id.h" | ||
39 | #include "ac97_local.h" | 26 | #include "ac97_local.h" |
27 | #include "ac97_patch.h" | ||
40 | 28 | ||
41 | /* | 29 | /* |
42 | * Chip specific initialization | 30 | * Chip specific initialization |
@@ -390,7 +378,7 @@ static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { | |||
390 | .build_post_spdif = patch_yamaha_ymf753_post_spdif | 378 | .build_post_spdif = patch_yamaha_ymf753_post_spdif |
391 | }; | 379 | }; |
392 | 380 | ||
393 | int patch_yamaha_ymf753(struct snd_ac97 * ac97) | 381 | static int patch_yamaha_ymf753(struct snd_ac97 * ac97) |
394 | { | 382 | { |
395 | /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com. | 383 | /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com. |
396 | This chip has nonstandard and extended behaviour with regard to its S/PDIF output. | 384 | This chip has nonstandard and extended behaviour with regard to its S/PDIF output. |
@@ -436,7 +424,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { | |||
436 | .build_specific = patch_wolfson_wm9703_specific, | 424 | .build_specific = patch_wolfson_wm9703_specific, |
437 | }; | 425 | }; |
438 | 426 | ||
439 | int patch_wolfson03(struct snd_ac97 * ac97) | 427 | static int patch_wolfson03(struct snd_ac97 * ac97) |
440 | { | 428 | { |
441 | ac97->build_ops = &patch_wolfson_wm9703_ops; | 429 | ac97->build_ops = &patch_wolfson_wm9703_ops; |
442 | return 0; | 430 | return 0; |
@@ -467,7 +455,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { | |||
467 | .build_specific = patch_wolfson_wm9704_specific, | 455 | .build_specific = patch_wolfson_wm9704_specific, |
468 | }; | 456 | }; |
469 | 457 | ||
470 | int patch_wolfson04(struct snd_ac97 * ac97) | 458 | static int patch_wolfson04(struct snd_ac97 * ac97) |
471 | { | 459 | { |
472 | /* WM9704M/9704Q */ | 460 | /* WM9704M/9704Q */ |
473 | ac97->build_ops = &patch_wolfson_wm9704_ops; | 461 | ac97->build_ops = &patch_wolfson_wm9704_ops; |
@@ -489,7 +477,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = { | |||
489 | .build_specific = patch_wolfson_wm9705_specific, | 477 | .build_specific = patch_wolfson_wm9705_specific, |
490 | }; | 478 | }; |
491 | 479 | ||
492 | int patch_wolfson05(struct snd_ac97 * ac97) | 480 | static int patch_wolfson05(struct snd_ac97 * ac97) |
493 | { | 481 | { |
494 | /* WM9705, WM9710 */ | 482 | /* WM9705, WM9710 */ |
495 | ac97->build_ops = &patch_wolfson_wm9705_ops; | 483 | ac97->build_ops = &patch_wolfson_wm9705_ops; |
@@ -625,7 +613,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { | |||
625 | .build_specific = patch_wolfson_wm9711_specific, | 613 | .build_specific = patch_wolfson_wm9711_specific, |
626 | }; | 614 | }; |
627 | 615 | ||
628 | int patch_wolfson11(struct snd_ac97 * ac97) | 616 | static int patch_wolfson11(struct snd_ac97 * ac97) |
629 | { | 617 | { |
630 | /* WM9711, WM9712 */ | 618 | /* WM9711, WM9712 */ |
631 | ac97->build_ops = &patch_wolfson_wm9711_ops; | 619 | ac97->build_ops = &patch_wolfson_wm9711_ops; |
@@ -824,7 +812,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { | |||
824 | #endif | 812 | #endif |
825 | }; | 813 | }; |
826 | 814 | ||
827 | int patch_wolfson13(struct snd_ac97 * ac97) | 815 | static int patch_wolfson13(struct snd_ac97 * ac97) |
828 | { | 816 | { |
829 | /* WM9713, WM9714 */ | 817 | /* WM9713, WM9714 */ |
830 | ac97->build_ops = &patch_wolfson_wm9713_ops; | 818 | ac97->build_ops = &patch_wolfson_wm9713_ops; |
@@ -844,7 +832,7 @@ int patch_wolfson13(struct snd_ac97 * ac97) | |||
844 | /* | 832 | /* |
845 | * Tritech codec | 833 | * Tritech codec |
846 | */ | 834 | */ |
847 | int patch_tritech_tr28028(struct snd_ac97 * ac97) | 835 | static int patch_tritech_tr28028(struct snd_ac97 * ac97) |
848 | { | 836 | { |
849 | snd_ac97_write_cache(ac97, 0x26, 0x0300); | 837 | snd_ac97_write_cache(ac97, 0x26, 0x0300); |
850 | snd_ac97_write_cache(ac97, 0x26, 0x0000); | 838 | snd_ac97_write_cache(ac97, 0x26, 0x0000); |
@@ -922,7 +910,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = { | |||
922 | .build_specific = patch_sigmatel_stac97xx_specific | 910 | .build_specific = patch_sigmatel_stac97xx_specific |
923 | }; | 911 | }; |
924 | 912 | ||
925 | int patch_sigmatel_stac9700(struct snd_ac97 * ac97) | 913 | static int patch_sigmatel_stac9700(struct snd_ac97 * ac97) |
926 | { | 914 | { |
927 | ac97->build_ops = &patch_sigmatel_stac9700_ops; | 915 | ac97->build_ops = &patch_sigmatel_stac9700_ops; |
928 | return 0; | 916 | return 0; |
@@ -969,7 +957,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = { | |||
969 | .build_specific = patch_sigmatel_stac9708_specific | 957 | .build_specific = patch_sigmatel_stac9708_specific |
970 | }; | 958 | }; |
971 | 959 | ||
972 | int patch_sigmatel_stac9708(struct snd_ac97 * ac97) | 960 | static int patch_sigmatel_stac9708(struct snd_ac97 * ac97) |
973 | { | 961 | { |
974 | unsigned int codec72, codec6c; | 962 | unsigned int codec72, codec6c; |
975 | 963 | ||
@@ -995,7 +983,7 @@ int patch_sigmatel_stac9708(struct snd_ac97 * ac97) | |||
995 | return 0; | 983 | return 0; |
996 | } | 984 | } |
997 | 985 | ||
998 | int patch_sigmatel_stac9721(struct snd_ac97 * ac97) | 986 | static int patch_sigmatel_stac9721(struct snd_ac97 * ac97) |
999 | { | 987 | { |
1000 | ac97->build_ops = &patch_sigmatel_stac9700_ops; | 988 | ac97->build_ops = &patch_sigmatel_stac9700_ops; |
1001 | if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) { | 989 | if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) { |
@@ -1009,7 +997,7 @@ int patch_sigmatel_stac9721(struct snd_ac97 * ac97) | |||
1009 | return 0; | 997 | return 0; |
1010 | } | 998 | } |
1011 | 999 | ||
1012 | int patch_sigmatel_stac9744(struct snd_ac97 * ac97) | 1000 | static int patch_sigmatel_stac9744(struct snd_ac97 * ac97) |
1013 | { | 1001 | { |
1014 | // patch for SigmaTel | 1002 | // patch for SigmaTel |
1015 | ac97->build_ops = &patch_sigmatel_stac9700_ops; | 1003 | ac97->build_ops = &patch_sigmatel_stac9700_ops; |
@@ -1021,7 +1009,7 @@ int patch_sigmatel_stac9744(struct snd_ac97 * ac97) | |||
1021 | return 0; | 1009 | return 0; |
1022 | } | 1010 | } |
1023 | 1011 | ||
1024 | int patch_sigmatel_stac9756(struct snd_ac97 * ac97) | 1012 | static int patch_sigmatel_stac9756(struct snd_ac97 * ac97) |
1025 | { | 1013 | { |
1026 | // patch for SigmaTel | 1014 | // patch for SigmaTel |
1027 | ac97->build_ops = &patch_sigmatel_stac9700_ops; | 1015 | ac97->build_ops = &patch_sigmatel_stac9700_ops; |
@@ -1198,7 +1186,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = { | |||
1198 | .build_specific = patch_sigmatel_stac9758_specific | 1186 | .build_specific = patch_sigmatel_stac9758_specific |
1199 | }; | 1187 | }; |
1200 | 1188 | ||
1201 | int patch_sigmatel_stac9758(struct snd_ac97 * ac97) | 1189 | static int patch_sigmatel_stac9758(struct snd_ac97 * ac97) |
1202 | { | 1190 | { |
1203 | static unsigned short regs[4] = { | 1191 | static unsigned short regs[4] = { |
1204 | AC97_SIGMATEL_OUTSEL, | 1192 | AC97_SIGMATEL_OUTSEL, |
@@ -1272,7 +1260,7 @@ static struct snd_ac97_build_ops patch_cirrus_ops = { | |||
1272 | .build_spdif = patch_cirrus_build_spdif | 1260 | .build_spdif = patch_cirrus_build_spdif |
1273 | }; | 1261 | }; |
1274 | 1262 | ||
1275 | int patch_cirrus_spdif(struct snd_ac97 * ac97) | 1263 | static int patch_cirrus_spdif(struct snd_ac97 * ac97) |
1276 | { | 1264 | { |
1277 | /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers. | 1265 | /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers. |
1278 | WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh* | 1266 | WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh* |
@@ -1293,7 +1281,7 @@ int patch_cirrus_spdif(struct snd_ac97 * ac97) | |||
1293 | return 0; | 1281 | return 0; |
1294 | } | 1282 | } |
1295 | 1283 | ||
1296 | int patch_cirrus_cs4299(struct snd_ac97 * ac97) | 1284 | static int patch_cirrus_cs4299(struct snd_ac97 * ac97) |
1297 | { | 1285 | { |
1298 | /* force the detection of PC Beep */ | 1286 | /* force the detection of PC Beep */ |
1299 | ac97->flags |= AC97_HAS_PC_BEEP; | 1287 | ac97->flags |= AC97_HAS_PC_BEEP; |
@@ -1329,7 +1317,7 @@ static struct snd_ac97_build_ops patch_conexant_ops = { | |||
1329 | .build_spdif = patch_conexant_build_spdif | 1317 | .build_spdif = patch_conexant_build_spdif |
1330 | }; | 1318 | }; |
1331 | 1319 | ||
1332 | int patch_conexant(struct snd_ac97 * ac97) | 1320 | static int patch_conexant(struct snd_ac97 * ac97) |
1333 | { | 1321 | { |
1334 | ac97->build_ops = &patch_conexant_ops; | 1322 | ac97->build_ops = &patch_conexant_ops; |
1335 | ac97->flags |= AC97_CX_SPDIF; | 1323 | ac97->flags |= AC97_CX_SPDIF; |
@@ -1338,7 +1326,7 @@ int patch_conexant(struct snd_ac97 * ac97) | |||
1338 | return 0; | 1326 | return 0; |
1339 | } | 1327 | } |
1340 | 1328 | ||
1341 | int patch_cx20551(struct snd_ac97 *ac97) | 1329 | static int patch_cx20551(struct snd_ac97 *ac97) |
1342 | { | 1330 | { |
1343 | snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01); | 1331 | snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01); |
1344 | return 0; | 1332 | return 0; |
@@ -1430,7 +1418,7 @@ static const struct snd_ac97_res_table ad1819_restbl[] = { | |||
1430 | { } /* terminator */ | 1418 | { } /* terminator */ |
1431 | }; | 1419 | }; |
1432 | 1420 | ||
1433 | int patch_ad1819(struct snd_ac97 * ac97) | 1421 | static int patch_ad1819(struct snd_ac97 * ac97) |
1434 | { | 1422 | { |
1435 | unsigned short scfg; | 1423 | unsigned short scfg; |
1436 | 1424 | ||
@@ -1507,7 +1495,7 @@ static struct snd_ac97_build_ops patch_ad1881_build_ops = { | |||
1507 | #endif | 1495 | #endif |
1508 | }; | 1496 | }; |
1509 | 1497 | ||
1510 | int patch_ad1881(struct snd_ac97 * ac97) | 1498 | static int patch_ad1881(struct snd_ac97 * ac97) |
1511 | { | 1499 | { |
1512 | static const char cfg_idxs[3][2] = { | 1500 | static const char cfg_idxs[3][2] = { |
1513 | {2, 1}, | 1501 | {2, 1}, |
@@ -1595,7 +1583,7 @@ static struct snd_ac97_build_ops patch_ad1885_build_ops = { | |||
1595 | #endif | 1583 | #endif |
1596 | }; | 1584 | }; |
1597 | 1585 | ||
1598 | int patch_ad1885(struct snd_ac97 * ac97) | 1586 | static int patch_ad1885(struct snd_ac97 * ac97) |
1599 | { | 1587 | { |
1600 | patch_ad1881(ac97); | 1588 | patch_ad1881(ac97); |
1601 | /* This is required to deal with the Intel D815EEAL2 */ | 1589 | /* This is required to deal with the Intel D815EEAL2 */ |
@@ -1622,7 +1610,7 @@ static struct snd_ac97_build_ops patch_ad1886_build_ops = { | |||
1622 | #endif | 1610 | #endif |
1623 | }; | 1611 | }; |
1624 | 1612 | ||
1625 | int patch_ad1886(struct snd_ac97 * ac97) | 1613 | static int patch_ad1886(struct snd_ac97 * ac97) |
1626 | { | 1614 | { |
1627 | patch_ad1881(ac97); | 1615 | patch_ad1881(ac97); |
1628 | /* Presario700 workaround */ | 1616 | /* Presario700 workaround */ |
@@ -1844,7 +1832,7 @@ static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97) | |||
1844 | snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); | 1832 | snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); |
1845 | } | 1833 | } |
1846 | 1834 | ||
1847 | int patch_ad1981a(struct snd_ac97 *ac97) | 1835 | static int patch_ad1981a(struct snd_ac97 *ac97) |
1848 | { | 1836 | { |
1849 | patch_ad1881(ac97); | 1837 | patch_ad1881(ac97); |
1850 | ac97->build_ops = &patch_ad1981a_build_ops; | 1838 | ac97->build_ops = &patch_ad1981a_build_ops; |
@@ -1877,7 +1865,7 @@ static struct snd_ac97_build_ops patch_ad1981b_build_ops = { | |||
1877 | #endif | 1865 | #endif |
1878 | }; | 1866 | }; |
1879 | 1867 | ||
1880 | int patch_ad1981b(struct snd_ac97 *ac97) | 1868 | static int patch_ad1981b(struct snd_ac97 *ac97) |
1881 | { | 1869 | { |
1882 | patch_ad1881(ac97); | 1870 | patch_ad1881(ac97); |
1883 | ac97->build_ops = &patch_ad1981b_build_ops; | 1871 | ac97->build_ops = &patch_ad1981b_build_ops; |
@@ -2014,7 +2002,7 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = { | |||
2014 | .update_jacks = ad1888_update_jacks, | 2002 | .update_jacks = ad1888_update_jacks, |
2015 | }; | 2003 | }; |
2016 | 2004 | ||
2017 | int patch_ad1888(struct snd_ac97 * ac97) | 2005 | static int patch_ad1888(struct snd_ac97 * ac97) |
2018 | { | 2006 | { |
2019 | unsigned short misc; | 2007 | unsigned short misc; |
2020 | 2008 | ||
@@ -2052,7 +2040,7 @@ static struct snd_ac97_build_ops patch_ad1980_build_ops = { | |||
2052 | .update_jacks = ad1888_update_jacks, | 2040 | .update_jacks = ad1888_update_jacks, |
2053 | }; | 2041 | }; |
2054 | 2042 | ||
2055 | int patch_ad1980(struct snd_ac97 * ac97) | 2043 | static int patch_ad1980(struct snd_ac97 * ac97) |
2056 | { | 2044 | { |
2057 | patch_ad1888(ac97); | 2045 | patch_ad1888(ac97); |
2058 | ac97->build_ops = &patch_ad1980_build_ops; | 2046 | ac97->build_ops = &patch_ad1980_build_ops; |
@@ -2168,7 +2156,7 @@ static struct snd_ac97_build_ops patch_ad1985_build_ops = { | |||
2168 | .update_jacks = ad1985_update_jacks, | 2156 | .update_jacks = ad1985_update_jacks, |
2169 | }; | 2157 | }; |
2170 | 2158 | ||
2171 | int patch_ad1985(struct snd_ac97 * ac97) | 2159 | static int patch_ad1985(struct snd_ac97 * ac97) |
2172 | { | 2160 | { |
2173 | unsigned short misc; | 2161 | unsigned short misc; |
2174 | 2162 | ||
@@ -2468,7 +2456,7 @@ static struct snd_ac97_build_ops patch_ad1986_build_ops = { | |||
2468 | .update_jacks = ad1986_update_jacks, | 2456 | .update_jacks = ad1986_update_jacks, |
2469 | }; | 2457 | }; |
2470 | 2458 | ||
2471 | int patch_ad1986(struct snd_ac97 * ac97) | 2459 | static int patch_ad1986(struct snd_ac97 * ac97) |
2472 | { | 2460 | { |
2473 | patch_ad1881(ac97); | 2461 | patch_ad1881(ac97); |
2474 | ac97->build_ops = &patch_ad1986_build_ops; | 2462 | ac97->build_ops = &patch_ad1986_build_ops; |
@@ -2561,7 +2549,7 @@ static struct snd_ac97_build_ops patch_alc650_ops = { | |||
2561 | .update_jacks = alc650_update_jacks | 2549 | .update_jacks = alc650_update_jacks |
2562 | }; | 2550 | }; |
2563 | 2551 | ||
2564 | int patch_alc650(struct snd_ac97 * ac97) | 2552 | static int patch_alc650(struct snd_ac97 * ac97) |
2565 | { | 2553 | { |
2566 | unsigned short val; | 2554 | unsigned short val; |
2567 | 2555 | ||
@@ -2713,7 +2701,7 @@ static struct snd_ac97_build_ops patch_alc655_ops = { | |||
2713 | .update_jacks = alc655_update_jacks | 2701 | .update_jacks = alc655_update_jacks |
2714 | }; | 2702 | }; |
2715 | 2703 | ||
2716 | int patch_alc655(struct snd_ac97 * ac97) | 2704 | static int patch_alc655(struct snd_ac97 * ac97) |
2717 | { | 2705 | { |
2718 | unsigned int val; | 2706 | unsigned int val; |
2719 | 2707 | ||
@@ -2739,6 +2727,7 @@ int patch_alc655(struct snd_ac97 * ac97) | |||
2739 | (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */ | 2727 | (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */ |
2740 | ac97->subsystem_device == 0x0161 || /* LG K1 Express */ | 2728 | ac97->subsystem_device == 0x0161 || /* LG K1 Express */ |
2741 | ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */ | 2729 | ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */ |
2730 | ac97->subsystem_device == 0x0471 || /* MSI L720 laptop */ | ||
2742 | ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */ | 2731 | ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */ |
2743 | val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ | 2732 | val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ |
2744 | else | 2733 | else |
@@ -2815,7 +2804,7 @@ static struct snd_ac97_build_ops patch_alc850_ops = { | |||
2815 | .update_jacks = alc850_update_jacks | 2804 | .update_jacks = alc850_update_jacks |
2816 | }; | 2805 | }; |
2817 | 2806 | ||
2818 | int patch_alc850(struct snd_ac97 *ac97) | 2807 | static int patch_alc850(struct snd_ac97 *ac97) |
2819 | { | 2808 | { |
2820 | ac97->build_ops = &patch_alc850_ops; | 2809 | ac97->build_ops = &patch_alc850_ops; |
2821 | 2810 | ||
@@ -2875,7 +2864,7 @@ static struct snd_ac97_build_ops patch_cm9738_ops = { | |||
2875 | .update_jacks = cm9738_update_jacks | 2864 | .update_jacks = cm9738_update_jacks |
2876 | }; | 2865 | }; |
2877 | 2866 | ||
2878 | int patch_cm9738(struct snd_ac97 * ac97) | 2867 | static int patch_cm9738(struct snd_ac97 * ac97) |
2879 | { | 2868 | { |
2880 | ac97->build_ops = &patch_cm9738_ops; | 2869 | ac97->build_ops = &patch_cm9738_ops; |
2881 | /* FIXME: can anyone confirm below? */ | 2870 | /* FIXME: can anyone confirm below? */ |
@@ -2967,7 +2956,7 @@ static struct snd_ac97_build_ops patch_cm9739_ops = { | |||
2967 | .update_jacks = cm9739_update_jacks | 2956 | .update_jacks = cm9739_update_jacks |
2968 | }; | 2957 | }; |
2969 | 2958 | ||
2970 | int patch_cm9739(struct snd_ac97 * ac97) | 2959 | static int patch_cm9739(struct snd_ac97 * ac97) |
2971 | { | 2960 | { |
2972 | unsigned short val; | 2961 | unsigned short val; |
2973 | 2962 | ||
@@ -3141,7 +3130,7 @@ static struct snd_ac97_build_ops patch_cm9761_ops = { | |||
3141 | .update_jacks = cm9761_update_jacks | 3130 | .update_jacks = cm9761_update_jacks |
3142 | }; | 3131 | }; |
3143 | 3132 | ||
3144 | int patch_cm9761(struct snd_ac97 *ac97) | 3133 | static int patch_cm9761(struct snd_ac97 *ac97) |
3145 | { | 3134 | { |
3146 | unsigned short val; | 3135 | unsigned short val; |
3147 | 3136 | ||
@@ -3236,7 +3225,7 @@ static struct snd_ac97_build_ops patch_cm9780_ops = { | |||
3236 | .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */ | 3225 | .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */ |
3237 | }; | 3226 | }; |
3238 | 3227 | ||
3239 | int patch_cm9780(struct snd_ac97 *ac97) | 3228 | static int patch_cm9780(struct snd_ac97 *ac97) |
3240 | { | 3229 | { |
3241 | unsigned short val; | 3230 | unsigned short val; |
3242 | 3231 | ||
@@ -3279,7 +3268,7 @@ static struct snd_ac97_build_ops patch_vt1616_ops = { | |||
3279 | .build_specific = patch_vt1616_specific | 3268 | .build_specific = patch_vt1616_specific |
3280 | }; | 3269 | }; |
3281 | 3270 | ||
3282 | int patch_vt1616(struct snd_ac97 * ac97) | 3271 | static int patch_vt1616(struct snd_ac97 * ac97) |
3283 | { | 3272 | { |
3284 | ac97->build_ops = &patch_vt1616_ops; | 3273 | ac97->build_ops = &patch_vt1616_ops; |
3285 | return 0; | 3274 | return 0; |
@@ -3288,16 +3277,111 @@ int patch_vt1616(struct snd_ac97 * ac97) | |||
3288 | /* | 3277 | /* |
3289 | * VT1617A codec | 3278 | * VT1617A codec |
3290 | */ | 3279 | */ |
3280 | |||
3281 | /* | ||
3282 | * unfortunately, the vt1617a stashes the twiddlers required for | ||
3283 | * nooding the i/o jacks on 2 different regs. * thameans that we cant | ||
3284 | * use the easy way provided by AC97_ENUM_DOUBLE() we have to write | ||
3285 | * are own funcs. | ||
3286 | * | ||
3287 | * NB: this is absolutely and utterly different from the vt1618. dunno | ||
3288 | * about the 1616. | ||
3289 | */ | ||
3290 | |||
3291 | /* copied from ac97_surround_jack_mode_info() */ | ||
3292 | static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol, | ||
3293 | struct snd_ctl_elem_info *uinfo) | ||
3294 | { | ||
3295 | /* ordering in this list reflects vt1617a docs for Reg 20 and | ||
3296 | * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51 | ||
3297 | * is SM51EN *AND* it's Bit14, not Bit15 so the table is very | ||
3298 | * counter-intuitive */ | ||
3299 | |||
3300 | static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3", | ||
3301 | "Surr LFE/C Mic3", "LineIn LFE/C Mic3", | ||
3302 | "LineIn Mic2", "LineIn Mic2 Mic1", | ||
3303 | "Surr LFE Mic1", "Surr LFE Mic1 Mic2"}; | ||
3304 | return ac97_enum_text_info(kcontrol, uinfo, texts, 8); | ||
3305 | } | ||
3306 | |||
3307 | static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol, | ||
3308 | struct snd_ctl_elem_value *ucontrol) | ||
3309 | { | ||
3310 | ushort usSM51, usMS; | ||
3311 | |||
3312 | struct snd_ac97 *pac97; | ||
3313 | |||
3314 | pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ | ||
3315 | |||
3316 | /* grab our desirec bits, then mash them together in a manner | ||
3317 | * consistent with Table 6 on page 17 in the 1617a docs */ | ||
3318 | |||
3319 | usSM51 = snd_ac97_read(pac97, 0x7a) >> 14; | ||
3320 | usMS = snd_ac97_read(pac97, 0x20) >> 8; | ||
3321 | |||
3322 | ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS; | ||
3323 | |||
3324 | return 0; | ||
3325 | } | ||
3326 | |||
3327 | static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol, | ||
3328 | struct snd_ctl_elem_value *ucontrol) | ||
3329 | { | ||
3330 | ushort usSM51, usMS, usReg; | ||
3331 | |||
3332 | struct snd_ac97 *pac97; | ||
3333 | |||
3334 | pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ | ||
3335 | |||
3336 | usSM51 = ucontrol->value.enumerated.item[0] >> 1; | ||
3337 | usMS = ucontrol->value.enumerated.item[0] & 1; | ||
3338 | |||
3339 | /* push our values into the register - consider that things will be left | ||
3340 | * in a funky state if the write fails */ | ||
3341 | |||
3342 | usReg = snd_ac97_read(pac97, 0x7a); | ||
3343 | snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14)); | ||
3344 | usReg = snd_ac97_read(pac97, 0x20); | ||
3345 | snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8)); | ||
3346 | |||
3347 | return 0; | ||
3348 | } | ||
3349 | |||
3350 | static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = { | ||
3351 | |||
3352 | AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0), | ||
3353 | /* | ||
3354 | * These are used to enable/disable surround sound on motherboards | ||
3355 | * that have 3 bidirectional analog jacks | ||
3356 | */ | ||
3357 | { | ||
3358 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3359 | .name = "Smart 5.1 Select", | ||
3360 | .info = snd_ac97_vt1617a_smart51_info, | ||
3361 | .get = snd_ac97_vt1617a_smart51_get, | ||
3362 | .put = snd_ac97_vt1617a_smart51_put, | ||
3363 | }, | ||
3364 | }; | ||
3365 | |||
3291 | int patch_vt1617a(struct snd_ac97 * ac97) | 3366 | int patch_vt1617a(struct snd_ac97 * ac97) |
3292 | { | 3367 | { |
3293 | /* bring analog power consumption to normal, like WinXP driver | 3368 | int err = 0; |
3294 | * for EPIA SP | 3369 | |
3370 | /* we choose to not fail out at this point, but we tell the | ||
3371 | caller when we return */ | ||
3372 | |||
3373 | err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0], | ||
3374 | ARRAY_SIZE(snd_ac97_controls_vt1617a)); | ||
3375 | |||
3376 | /* bring analog power consumption to normal by turning off the | ||
3377 | * headphone amplifier, like WinXP driver for EPIA SP | ||
3295 | */ | 3378 | */ |
3296 | snd_ac97_write_cache(ac97, 0x5c, 0x20); | 3379 | snd_ac97_write_cache(ac97, 0x5c, 0x20); |
3297 | ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ | 3380 | ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ |
3298 | ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; | 3381 | ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; |
3299 | ac97->build_ops = &patch_vt1616_ops; | 3382 | ac97->build_ops = &patch_vt1616_ops; |
3300 | return 0; | 3383 | |
3384 | return err; | ||
3301 | } | 3385 | } |
3302 | 3386 | ||
3303 | /* | 3387 | /* |
@@ -3338,7 +3422,7 @@ static struct snd_ac97_build_ops patch_it2646_ops = { | |||
3338 | .update_jacks = it2646_update_jacks | 3422 | .update_jacks = it2646_update_jacks |
3339 | }; | 3423 | }; |
3340 | 3424 | ||
3341 | int patch_it2646(struct snd_ac97 * ac97) | 3425 | static int patch_it2646(struct snd_ac97 * ac97) |
3342 | { | 3426 | { |
3343 | ac97->build_ops = &patch_it2646_ops; | 3427 | ac97->build_ops = &patch_it2646_ops; |
3344 | /* full DAC volume */ | 3428 | /* full DAC volume */ |
@@ -3371,7 +3455,7 @@ static struct snd_ac97_build_ops patch_si3036_ops = { | |||
3371 | .build_specific = patch_si3036_specific, | 3455 | .build_specific = patch_si3036_specific, |
3372 | }; | 3456 | }; |
3373 | 3457 | ||
3374 | int mpatch_si3036(struct snd_ac97 * ac97) | 3458 | static int mpatch_si3036(struct snd_ac97 * ac97) |
3375 | { | 3459 | { |
3376 | ac97->build_ops = &patch_si3036_ops; | 3460 | ac97->build_ops = &patch_si3036_ops; |
3377 | snd_ac97_write_cache(ac97, 0x5c, 0xf210 ); | 3461 | snd_ac97_write_cache(ac97, 0x5c, 0xf210 ); |
@@ -3403,7 +3487,7 @@ static struct snd_ac97_res_table lm4550_restbl[] = { | |||
3403 | { } /* terminator */ | 3487 | { } /* terminator */ |
3404 | }; | 3488 | }; |
3405 | 3489 | ||
3406 | int patch_lm4550(struct snd_ac97 *ac97) | 3490 | static int patch_lm4550(struct snd_ac97 *ac97) |
3407 | { | 3491 | { |
3408 | ac97->res_table = lm4550_restbl; | 3492 | ac97->res_table = lm4550_restbl; |
3409 | return 0; | 3493 | return 0; |
@@ -3438,7 +3522,7 @@ static struct snd_ac97_build_ops patch_ucb1400_ops = { | |||
3438 | .build_specific = patch_ucb1400_specific, | 3522 | .build_specific = patch_ucb1400_specific, |
3439 | }; | 3523 | }; |
3440 | 3524 | ||
3441 | int patch_ucb1400(struct snd_ac97 * ac97) | 3525 | static int patch_ucb1400(struct snd_ac97 * ac97) |
3442 | { | 3526 | { |
3443 | ac97->build_ops = &patch_ucb1400_ops; | 3527 | ac97->build_ops = &patch_ucb1400_ops; |
3444 | /* enable headphone driver and smart low power mode by default */ | 3528 | /* enable headphone driver and smart low power mode by default */ |
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index 555d1c9a98fd..fd341ce63762 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h | |||
@@ -22,44 +22,72 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | int patch_yamaha_ymf753(struct snd_ac97 * ac97); | 25 | #define AC97_SINGLE_VALUE(reg,shift,mask,invert) \ |
26 | int patch_wolfson00(struct snd_ac97 * ac97); | 26 | ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | \ |
27 | int patch_wolfson03(struct snd_ac97 * ac97); | 27 | ((invert) << 24)) |
28 | int patch_wolfson04(struct snd_ac97 * ac97); | 28 | #define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) \ |
29 | int patch_wolfson05(struct snd_ac97 * ac97); | 29 | (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26)) |
30 | int patch_wolfson11(struct snd_ac97 * ac97); | 30 | #define AC97_SINGLE(xname, reg, shift, mask, invert) \ |
31 | int patch_wolfson13(struct snd_ac97 * ac97); | 31 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
32 | int patch_tritech_tr28028(struct snd_ac97 * ac97); | 32 | .info = snd_ac97_info_volsw, \ |
33 | int patch_sigmatel_stac9700(struct snd_ac97 * ac97); | 33 | .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ |
34 | int patch_sigmatel_stac9708(struct snd_ac97 * ac97); | 34 | .private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) } |
35 | int patch_sigmatel_stac9721(struct snd_ac97 * ac97); | 35 | #define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \ |
36 | int patch_sigmatel_stac9744(struct snd_ac97 * ac97); | 36 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
37 | int patch_sigmatel_stac9756(struct snd_ac97 * ac97); | 37 | .info = snd_ac97_info_volsw, \ |
38 | int patch_sigmatel_stac9758(struct snd_ac97 * ac97); | 38 | .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ |
39 | int patch_cirrus_cs4299(struct snd_ac97 * ac97); | 39 | .private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) } |
40 | int patch_cirrus_spdif(struct snd_ac97 * ac97); | 40 | #define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \ |
41 | int patch_conexant(struct snd_ac97 * ac97); | 41 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ |
42 | int patch_cx20551(struct snd_ac97 * ac97); | 42 | .info = snd_ac97_info_volsw, \ |
43 | int patch_ad1819(struct snd_ac97 * ac97); | 43 | .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ |
44 | int patch_ad1881(struct snd_ac97 * ac97); | 44 | .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) } |
45 | int patch_ad1885(struct snd_ac97 * ac97); | 45 | |
46 | int patch_ad1886(struct snd_ac97 * ac97); | 46 | /* enum control */ |
47 | int patch_ad1888(struct snd_ac97 * ac97); | 47 | struct ac97_enum { |
48 | int patch_ad1980(struct snd_ac97 * ac97); | 48 | unsigned char reg; |
49 | int patch_ad1981a(struct snd_ac97 * ac97); | 49 | unsigned char shift_l; |
50 | int patch_ad1981b(struct snd_ac97 * ac97); | 50 | unsigned char shift_r; |
51 | int patch_ad1985(struct snd_ac97 * ac97); | 51 | unsigned short mask; |
52 | int patch_ad1986(struct snd_ac97 * ac97); | 52 | const char **texts; |
53 | int patch_alc650(struct snd_ac97 * ac97); | 53 | }; |
54 | int patch_alc655(struct snd_ac97 * ac97); | 54 | |
55 | int patch_alc850(struct snd_ac97 * ac97); | 55 | #define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ |
56 | int patch_cm9738(struct snd_ac97 * ac97); | 56 | { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ |
57 | int patch_cm9739(struct snd_ac97 * ac97); | 57 | .mask = xmask, .texts = xtexts } |
58 | int patch_cm9761(struct snd_ac97 * ac97); | 58 | #define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \ |
59 | int patch_cm9780(struct snd_ac97 * ac97); | 59 | AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts) |
60 | int patch_vt1616(struct snd_ac97 * ac97); | 60 | #define AC97_ENUM(xname, xenum) \ |
61 | int patch_vt1617a(struct snd_ac97 * ac97); | 61 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
62 | int patch_it2646(struct snd_ac97 * ac97); | 62 | .info = snd_ac97_info_enum_double, \ |
63 | int patch_ucb1400(struct snd_ac97 * ac97); | 63 | .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \ |
64 | int mpatch_si3036(struct snd_ac97 * ac97); | 64 | .private_value = (unsigned long)&xenum } |
65 | int patch_lm4550(struct snd_ac97 * ac97); | 65 | |
66 | /* ac97_codec.c */ | ||
67 | static const struct snd_kcontrol_new snd_ac97_controls_3d[]; | ||
68 | static const struct snd_kcontrol_new snd_ac97_controls_spdif[]; | ||
69 | static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, | ||
70 | struct snd_ac97 * ac97); | ||
71 | static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, | ||
72 | struct snd_ctl_elem_info *uinfo); | ||
73 | static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, | ||
74 | struct snd_ctl_elem_value *ucontrol); | ||
75 | static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, | ||
76 | struct snd_ctl_elem_value *ucontrol); | ||
77 | static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit); | ||
78 | static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, | ||
79 | const char *suffix); | ||
80 | static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, | ||
81 | const char *dst, const char *suffix); | ||
82 | static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, | ||
83 | const char *s2, const char *suffix); | ||
84 | static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, | ||
85 | const char *dst); | ||
86 | static void snd_ac97_restore_status(struct snd_ac97 *ac97); | ||
87 | static void snd_ac97_restore_iec958(struct snd_ac97 *ac97); | ||
88 | static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, | ||
89 | struct snd_ctl_elem_info *uinfo); | ||
90 | static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, | ||
91 | struct snd_ctl_elem_value *ucontrol); | ||
92 | static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, | ||
93 | struct snd_ctl_elem_value *ucontrol); | ||
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c index 3758d07182f8..4281e6d0c5b6 100644 --- a/sound/pci/ac97/ac97_pcm.c +++ b/sound/pci/ac97/ac97_pcm.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <sound/control.h> | 34 | #include <sound/control.h> |
35 | #include <sound/ac97_codec.h> | 35 | #include <sound/ac97_codec.h> |
36 | #include <sound/asoundef.h> | 36 | #include <sound/asoundef.h> |
37 | #include "ac97_patch.h" | ||
38 | #include "ac97_id.h" | 37 | #include "ac97_id.h" |
39 | #include "ac97_local.h" | 38 | #include "ac97_local.h" |
40 | 39 | ||
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index ba7fa22b285d..e1ed59549c50 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
@@ -69,10 +69,10 @@ module_param(enable, bool, 0444); | |||
69 | * Debug part definitions | 69 | * Debug part definitions |
70 | */ | 70 | */ |
71 | 71 | ||
72 | //#define ALI_DEBUG | 72 | /* #define ALI_DEBUG */ |
73 | 73 | ||
74 | #ifdef ALI_DEBUG | 74 | #ifdef ALI_DEBUG |
75 | #define snd_ali_printk(format, args...) printk(format, ##args); | 75 | #define snd_ali_printk(format, args...) printk(KERN_DEBUG format, ##args); |
76 | #else | 76 | #else |
77 | #define snd_ali_printk(format, args...) | 77 | #define snd_ali_printk(format, args...) |
78 | #endif | 78 | #endif |
@@ -105,10 +105,10 @@ module_param(enable, bool, 0444); | |||
105 | * Direct Registers | 105 | * Direct Registers |
106 | */ | 106 | */ |
107 | 107 | ||
108 | #define ALI_LEGACY_DMAR0 0x00 // ADR0 | 108 | #define ALI_LEGACY_DMAR0 0x00 /* ADR0 */ |
109 | #define ALI_LEGACY_DMAR4 0x04 // CNT0 | 109 | #define ALI_LEGACY_DMAR4 0x04 /* CNT0 */ |
110 | #define ALI_LEGACY_DMAR11 0x0b // MOD | 110 | #define ALI_LEGACY_DMAR11 0x0b /* MOD */ |
111 | #define ALI_LEGACY_DMAR15 0x0f // MMR | 111 | #define ALI_LEGACY_DMAR15 0x0f /* MMR */ |
112 | #define ALI_MPUR0 0x20 | 112 | #define ALI_MPUR0 0x20 |
113 | #define ALI_MPUR1 0x21 | 113 | #define ALI_MPUR1 0x21 |
114 | #define ALI_MPUR2 0x22 | 114 | #define ALI_MPUR2 0x22 |
@@ -175,7 +175,7 @@ struct snd_ali; | |||
175 | struct snd_ali_voice; | 175 | struct snd_ali_voice; |
176 | 176 | ||
177 | struct snd_ali_channel_control { | 177 | struct snd_ali_channel_control { |
178 | // register data | 178 | /* register data */ |
179 | struct REGDATA { | 179 | struct REGDATA { |
180 | unsigned int start; | 180 | unsigned int start; |
181 | unsigned int stop; | 181 | unsigned int stop; |
@@ -183,7 +183,7 @@ struct snd_ali_channel_control { | |||
183 | unsigned int ainten; | 183 | unsigned int ainten; |
184 | } data; | 184 | } data; |
185 | 185 | ||
186 | // register addresses | 186 | /* register addresses */ |
187 | struct REGS { | 187 | struct REGS { |
188 | unsigned int start; | 188 | unsigned int start; |
189 | unsigned int stop; | 189 | unsigned int stop; |
@@ -197,19 +197,18 @@ struct snd_ali_channel_control { | |||
197 | 197 | ||
198 | struct snd_ali_voice { | 198 | struct snd_ali_voice { |
199 | unsigned int number; | 199 | unsigned int number; |
200 | unsigned int use: 1, | 200 | unsigned int use :1, |
201 | pcm: 1, | 201 | pcm :1, |
202 | midi: 1, | 202 | midi :1, |
203 | mode: 1, | 203 | mode :1, |
204 | synth: 1; | 204 | synth :1, |
205 | running :1; | ||
205 | 206 | ||
206 | /* PCM data */ | 207 | /* PCM data */ |
207 | struct snd_ali *codec; | 208 | struct snd_ali *codec; |
208 | struct snd_pcm_substream *substream; | 209 | struct snd_pcm_substream *substream; |
209 | struct snd_ali_voice *extra; | 210 | struct snd_ali_voice *extra; |
210 | 211 | ||
211 | unsigned int running: 1; | ||
212 | |||
213 | int eso; /* final ESO value for channel */ | 212 | int eso; /* final ESO value for channel */ |
214 | int count; /* runtime->period_size */ | 213 | int count; /* runtime->period_size */ |
215 | 214 | ||
@@ -231,14 +230,12 @@ struct snd_alidev { | |||
231 | }; | 230 | }; |
232 | 231 | ||
233 | 232 | ||
234 | #ifdef CONFIG_PM | ||
235 | #define ALI_GLOBAL_REGS 56 | 233 | #define ALI_GLOBAL_REGS 56 |
236 | #define ALI_CHANNEL_REGS 8 | 234 | #define ALI_CHANNEL_REGS 8 |
237 | struct snd_ali_image { | 235 | struct snd_ali_image { |
238 | unsigned long regs[ALI_GLOBAL_REGS]; | 236 | u32 regs[ALI_GLOBAL_REGS]; |
239 | unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS]; | 237 | u32 channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS]; |
240 | }; | 238 | }; |
241 | #endif | ||
242 | 239 | ||
243 | 240 | ||
244 | struct snd_ali { | 241 | struct snd_ali { |
@@ -246,8 +243,8 @@ struct snd_ali { | |||
246 | unsigned long port; | 243 | unsigned long port; |
247 | unsigned char revision; | 244 | unsigned char revision; |
248 | 245 | ||
249 | unsigned int hw_initialized: 1; | 246 | unsigned int hw_initialized :1; |
250 | unsigned int spdif_support: 1; | 247 | unsigned int spdif_support :1; |
251 | 248 | ||
252 | struct pci_dev *pci; | 249 | struct pci_dev *pci; |
253 | struct pci_dev *pci_m1533; | 250 | struct pci_dev *pci_m1533; |
@@ -287,108 +284,28 @@ MODULE_DEVICE_TABLE(pci, snd_ali_ids); | |||
287 | 284 | ||
288 | static void snd_ali_clear_voices(struct snd_ali *, unsigned int, unsigned int); | 285 | static void snd_ali_clear_voices(struct snd_ali *, unsigned int, unsigned int); |
289 | static unsigned short snd_ali_codec_peek(struct snd_ali *, int, unsigned short); | 286 | static unsigned short snd_ali_codec_peek(struct snd_ali *, int, unsigned short); |
290 | static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, unsigned short); | 287 | static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, |
291 | 288 | unsigned short); | |
292 | /* | ||
293 | * Debug Part | ||
294 | */ | ||
295 | |||
296 | #ifdef ALI_DEBUG | ||
297 | |||
298 | static void ali_read_regs(struct snd_ali *codec, int channel) | ||
299 | { | ||
300 | int i,j; | ||
301 | unsigned int dwVal; | ||
302 | |||
303 | printk("channel %d registers map:\n", channel); | ||
304 | outb((unsigned char)(channel & 0x001f), ALI_REG(codec,ALI_GC_CIR)); | ||
305 | |||
306 | printk(" "); | ||
307 | for(j=0;j<8;j++) | ||
308 | printk("%2.2x ", j*4); | ||
309 | printk("\n"); | ||
310 | |||
311 | for (i=0; i<=0xf8/4;i++) { | ||
312 | if(i%8 == 0) | ||
313 | printk("%2.2x ", (i*4/0x10)*0x10); | ||
314 | dwVal = inl(ALI_REG(codec,i*4)); | ||
315 | printk("%8.8x ", dwVal); | ||
316 | if ((i+1)%8 == 0) | ||
317 | printk("\n"); | ||
318 | } | ||
319 | printk("\n"); | ||
320 | } | ||
321 | static void ali_read_cfg(unsigned int vendor, unsigned deviceid) | ||
322 | { | ||
323 | unsigned int dwVal; | ||
324 | struct pci_dev *pci_dev; | ||
325 | int i,j; | ||
326 | |||
327 | pci_dev = pci_get_device(vendor, deviceid, NULL); | ||
328 | if (pci_dev == NULL) | ||
329 | return ; | ||
330 | |||
331 | printk("\nM%x PCI CFG\n", deviceid); | ||
332 | printk(" "); | ||
333 | for(j=0;j<8;j++) | ||
334 | printk("%d ",j); | ||
335 | printk("\n"); | ||
336 | |||
337 | for(i=0;i<8;i++) { | ||
338 | printk("%d ",i); | ||
339 | for(j=0;j<8;j++) | ||
340 | { | ||
341 | pci_read_config_dword(pci_dev, i*0x20+j*4, &dwVal); | ||
342 | printk("%8.8x ", dwVal); | ||
343 | } | ||
344 | printk("\n"); | ||
345 | } | ||
346 | pci_dev_put(pci_dev); | ||
347 | } | ||
348 | static void ali_read_ac97regs(struct snd_ali *codec, int secondary) | ||
349 | { | ||
350 | unsigned short i,j; | ||
351 | unsigned short wVal; | ||
352 | |||
353 | printk("\ncodec %d registers map:\n", secondary); | ||
354 | |||
355 | printk(" "); | ||
356 | for(j=0;j<8;j++) | ||
357 | printk("%2.2x ",j*2); | ||
358 | printk("\n"); | ||
359 | |||
360 | for (i=0; i<64;i++) { | ||
361 | if(i%8 == 0) | ||
362 | printk("%2.2x ", (i/8)*0x10); | ||
363 | wVal = snd_ali_codec_peek(codec, secondary, i*2); | ||
364 | printk("%4.4x ", wVal); | ||
365 | if ((i+1)%8 == 0) | ||
366 | printk("\n"); | ||
367 | } | ||
368 | printk("\n"); | ||
369 | } | ||
370 | |||
371 | #endif | ||
372 | 289 | ||
373 | /* | 290 | /* |
374 | * AC97 ACCESS | 291 | * AC97 ACCESS |
375 | */ | 292 | */ |
376 | 293 | ||
377 | static inline unsigned int snd_ali_5451_peek(struct snd_ali *codec, | 294 | static inline unsigned int snd_ali_5451_peek(struct snd_ali *codec, |
378 | unsigned int port ) | 295 | unsigned int port) |
379 | { | 296 | { |
380 | return (unsigned int)inl(ALI_REG(codec, port)); | 297 | return (unsigned int)inl(ALI_REG(codec, port)); |
381 | } | 298 | } |
382 | 299 | ||
383 | static inline void snd_ali_5451_poke( struct snd_ali *codec, | 300 | static inline void snd_ali_5451_poke(struct snd_ali *codec, |
384 | unsigned int port, | 301 | unsigned int port, |
385 | unsigned int val ) | 302 | unsigned int val) |
386 | { | 303 | { |
387 | outl((unsigned int)val, ALI_REG(codec, port)); | 304 | outl((unsigned int)val, ALI_REG(codec, port)); |
388 | } | 305 | } |
389 | 306 | ||
390 | static int snd_ali_codec_ready( struct snd_ali *codec, | 307 | static int snd_ali_codec_ready(struct snd_ali *codec, |
391 | unsigned int port ) | 308 | unsigned int port) |
392 | { | 309 | { |
393 | unsigned long end_time; | 310 | unsigned long end_time; |
394 | unsigned int res; | 311 | unsigned int res; |
@@ -396,7 +313,7 @@ static int snd_ali_codec_ready( struct snd_ali *codec, | |||
396 | end_time = jiffies + msecs_to_jiffies(250); | 313 | end_time = jiffies + msecs_to_jiffies(250); |
397 | do { | 314 | do { |
398 | res = snd_ali_5451_peek(codec,port); | 315 | res = snd_ali_5451_peek(codec,port); |
399 | if (! (res & 0x8000)) | 316 | if (!(res & 0x8000)) |
400 | return 0; | 317 | return 0; |
401 | schedule_timeout_uninterruptible(1); | 318 | schedule_timeout_uninterruptible(1); |
402 | } while (time_after_eq(end_time, jiffies)); | 319 | } while (time_after_eq(end_time, jiffies)); |
@@ -425,11 +342,11 @@ static int snd_ali_stimer_ready(struct snd_ali *codec) | |||
425 | } | 342 | } |
426 | 343 | ||
427 | static void snd_ali_codec_poke(struct snd_ali *codec,int secondary, | 344 | static void snd_ali_codec_poke(struct snd_ali *codec,int secondary, |
428 | unsigned short reg, | 345 | unsigned short reg, |
429 | unsigned short val) | 346 | unsigned short val) |
430 | { | 347 | { |
431 | unsigned int dwVal = 0; | 348 | unsigned int dwVal; |
432 | unsigned int port = 0; | 349 | unsigned int port; |
433 | 350 | ||
434 | if (reg >= 0x80) { | 351 | if (reg >= 0x80) { |
435 | snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg); | 352 | snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg); |
@@ -445,20 +362,22 @@ static void snd_ali_codec_poke(struct snd_ali *codec,int secondary, | |||
445 | 362 | ||
446 | dwVal = (unsigned int) (reg & 0xff); | 363 | dwVal = (unsigned int) (reg & 0xff); |
447 | dwVal |= 0x8000 | (val << 16); | 364 | dwVal |= 0x8000 | (val << 16); |
448 | if (secondary) dwVal |= 0x0080; | 365 | if (secondary) |
449 | if (codec->revision == ALI_5451_V02) dwVal |= 0x0100; | 366 | dwVal |= 0x0080; |
367 | if (codec->revision == ALI_5451_V02) | ||
368 | dwVal |= 0x0100; | ||
450 | 369 | ||
451 | snd_ali_5451_poke(codec,port,dwVal); | 370 | snd_ali_5451_poke(codec, port, dwVal); |
452 | 371 | ||
453 | return ; | 372 | return ; |
454 | } | 373 | } |
455 | 374 | ||
456 | static unsigned short snd_ali_codec_peek( struct snd_ali *codec, | 375 | static unsigned short snd_ali_codec_peek(struct snd_ali *codec, |
457 | int secondary, | 376 | int secondary, |
458 | unsigned short reg) | 377 | unsigned short reg) |
459 | { | 378 | { |
460 | unsigned int dwVal = 0; | 379 | unsigned int dwVal; |
461 | unsigned int port = 0; | 380 | unsigned int port; |
462 | 381 | ||
463 | if (reg >= 0x80) { | 382 | if (reg >= 0x80) { |
464 | snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg); | 383 | snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg); |
@@ -474,7 +393,8 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec, | |||
474 | 393 | ||
475 | dwVal = (unsigned int) (reg & 0xff); | 394 | dwVal = (unsigned int) (reg & 0xff); |
476 | dwVal |= 0x8000; /* bit 15*/ | 395 | dwVal |= 0x8000; /* bit 15*/ |
477 | if (secondary) dwVal |= 0x0080; | 396 | if (secondary) |
397 | dwVal |= 0x0080; | ||
478 | 398 | ||
479 | snd_ali_5451_poke(codec, port, dwVal); | 399 | snd_ali_5451_poke(codec, port, dwVal); |
480 | 400 | ||
@@ -483,7 +403,7 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec, | |||
483 | if (snd_ali_codec_ready(codec, port) < 0) | 403 | if (snd_ali_codec_ready(codec, port) < 0) |
484 | return ~0; | 404 | return ~0; |
485 | 405 | ||
486 | return (snd_ali_5451_peek(codec, port) & 0xffff0000)>>16; | 406 | return (snd_ali_5451_peek(codec, port) & 0xffff0000) >> 16; |
487 | } | 407 | } |
488 | 408 | ||
489 | static void snd_ali_codec_write(struct snd_ac97 *ac97, | 409 | static void snd_ali_codec_write(struct snd_ac97 *ac97, |
@@ -493,9 +413,9 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97, | |||
493 | struct snd_ali *codec = ac97->private_data; | 413 | struct snd_ali *codec = ac97->private_data; |
494 | 414 | ||
495 | snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val); | 415 | snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val); |
496 | if(reg == AC97_GPIO_STATUS) { | 416 | if (reg == AC97_GPIO_STATUS) { |
497 | outl((val << ALI_AC97_GPIO_DATA_SHIFT)|ALI_AC97_GPIO_ENABLE, | 417 | outl((val << ALI_AC97_GPIO_DATA_SHIFT) | ALI_AC97_GPIO_ENABLE, |
498 | ALI_REG(codec, ALI_AC97_GPIO)); | 418 | ALI_REG(codec, ALI_AC97_GPIO)); |
499 | return; | 419 | return; |
500 | } | 420 | } |
501 | snd_ali_codec_poke(codec, ac97->num, reg, val); | 421 | snd_ali_codec_poke(codec, ac97->num, reg, val); |
@@ -503,12 +423,13 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97, | |||
503 | } | 423 | } |
504 | 424 | ||
505 | 425 | ||
506 | static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short reg) | 426 | static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, |
427 | unsigned short reg) | ||
507 | { | 428 | { |
508 | struct snd_ali *codec = ac97->private_data; | 429 | struct snd_ali *codec = ac97->private_data; |
509 | 430 | ||
510 | snd_ali_printk("codec_read reg=%xh.\n", reg); | 431 | snd_ali_printk("codec_read reg=%xh.\n", reg); |
511 | return (snd_ali_codec_peek(codec, ac97->num, reg)); | 432 | return snd_ali_codec_peek(codec, ac97->num, reg); |
512 | } | 433 | } |
513 | 434 | ||
514 | /* | 435 | /* |
@@ -517,11 +438,12 @@ static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short r | |||
517 | 438 | ||
518 | static int snd_ali_reset_5451(struct snd_ali *codec) | 439 | static int snd_ali_reset_5451(struct snd_ali *codec) |
519 | { | 440 | { |
520 | struct pci_dev *pci_dev = NULL; | 441 | struct pci_dev *pci_dev; |
521 | unsigned short wCount, wReg; | 442 | unsigned short wCount, wReg; |
522 | unsigned int dwVal; | 443 | unsigned int dwVal; |
523 | 444 | ||
524 | if ((pci_dev = codec->pci_m1533) != NULL) { | 445 | pci_dev = codec->pci_m1533; |
446 | if (pci_dev) { | ||
525 | pci_read_config_dword(pci_dev, 0x7c, &dwVal); | 447 | pci_read_config_dword(pci_dev, 0x7c, &dwVal); |
526 | pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000); | 448 | pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000); |
527 | udelay(5000); | 449 | udelay(5000); |
@@ -541,7 +463,7 @@ static int snd_ali_reset_5451(struct snd_ali *codec) | |||
541 | wCount = 200; | 463 | wCount = 200; |
542 | while(wCount--) { | 464 | while(wCount--) { |
543 | wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN); | 465 | wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN); |
544 | if((wReg & 0x000f) == 0x000f) | 466 | if ((wReg & 0x000f) == 0x000f) |
545 | return 0; | 467 | return 0; |
546 | udelay(5000); | 468 | udelay(5000); |
547 | } | 469 | } |
@@ -555,8 +477,8 @@ static int snd_ali_reset_5451(struct snd_ali *codec) | |||
555 | 477 | ||
556 | static int snd_ali_reset_codec(struct snd_ali *codec) | 478 | static int snd_ali_reset_codec(struct snd_ali *codec) |
557 | { | 479 | { |
558 | struct pci_dev *pci_dev = NULL; | 480 | struct pci_dev *pci_dev; |
559 | unsigned char bVal = 0; | 481 | unsigned char bVal; |
560 | unsigned int dwVal; | 482 | unsigned int dwVal; |
561 | unsigned short wCount, wReg; | 483 | unsigned short wCount, wReg; |
562 | 484 | ||
@@ -579,9 +501,9 @@ static int snd_ali_reset_codec(struct snd_ali *codec) | |||
579 | udelay(15000); | 501 | udelay(15000); |
580 | 502 | ||
581 | wCount = 200; | 503 | wCount = 200; |
582 | while(wCount--) { | 504 | while (wCount--) { |
583 | wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN); | 505 | wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN); |
584 | if((wReg & 0x000f) == 0x000f) | 506 | if ((wReg & 0x000f) == 0x000f) |
585 | return 0; | 507 | return 0; |
586 | udelay(5000); | 508 | udelay(5000); |
587 | } | 509 | } |
@@ -594,25 +516,27 @@ static int snd_ali_reset_codec(struct snd_ali *codec) | |||
594 | * ALI 5451 Controller | 516 | * ALI 5451 Controller |
595 | */ | 517 | */ |
596 | 518 | ||
597 | static void snd_ali_enable_special_channel(struct snd_ali *codec, unsigned int channel) | 519 | static void snd_ali_enable_special_channel(struct snd_ali *codec, |
520 | unsigned int channel) | ||
598 | { | 521 | { |
599 | unsigned long dwVal = 0; | 522 | unsigned long dwVal; |
600 | 523 | ||
601 | dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL)); | 524 | dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
602 | dwVal |= 1 << (channel & 0x0000001f); | 525 | dwVal |= 1 << (channel & 0x0000001f); |
603 | outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL)); | 526 | outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
604 | } | 527 | } |
605 | 528 | ||
606 | static void snd_ali_disable_special_channel(struct snd_ali *codec, unsigned int channel) | 529 | static void snd_ali_disable_special_channel(struct snd_ali *codec, |
530 | unsigned int channel) | ||
607 | { | 531 | { |
608 | unsigned long dwVal = 0; | 532 | unsigned long dwVal; |
609 | 533 | ||
610 | dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL)); | 534 | dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
611 | dwVal &= ~(1 << (channel & 0x0000001f)); | 535 | dwVal &= ~(1 << (channel & 0x0000001f)); |
612 | outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL)); | 536 | outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
613 | } | 537 | } |
614 | 538 | ||
615 | static void snd_ali_enable_address_interrupt(struct snd_ali * codec) | 539 | static void snd_ali_enable_address_interrupt(struct snd_ali *codec) |
616 | { | 540 | { |
617 | unsigned int gc; | 541 | unsigned int gc; |
618 | 542 | ||
@@ -622,7 +546,7 @@ static void snd_ali_enable_address_interrupt(struct snd_ali * codec) | |||
622 | outl( gc, ALI_REG(codec, ALI_GC_CIR)); | 546 | outl( gc, ALI_REG(codec, ALI_GC_CIR)); |
623 | } | 547 | } |
624 | 548 | ||
625 | static void snd_ali_disable_address_interrupt(struct snd_ali * codec) | 549 | static void snd_ali_disable_address_interrupt(struct snd_ali *codec) |
626 | { | 550 | { |
627 | unsigned int gc; | 551 | unsigned int gc; |
628 | 552 | ||
@@ -632,8 +556,9 @@ static void snd_ali_disable_address_interrupt(struct snd_ali * codec) | |||
632 | outl(gc, ALI_REG(codec, ALI_GC_CIR)); | 556 | outl(gc, ALI_REG(codec, ALI_GC_CIR)); |
633 | } | 557 | } |
634 | 558 | ||
635 | #if 0 // not used | 559 | #if 0 /* not used */ |
636 | static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel) | 560 | static void snd_ali_enable_voice_irq(struct snd_ali *codec, |
561 | unsigned int channel) | ||
637 | { | 562 | { |
638 | unsigned int mask; | 563 | unsigned int mask; |
639 | struct snd_ali_channel_control *pchregs = &(codec->chregs); | 564 | struct snd_ali_channel_control *pchregs = &(codec->chregs); |
@@ -641,13 +566,14 @@ static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel | |||
641 | snd_ali_printk("enable_voice_irq channel=%d\n",channel); | 566 | snd_ali_printk("enable_voice_irq channel=%d\n",channel); |
642 | 567 | ||
643 | mask = 1 << (channel & 0x1f); | 568 | mask = 1 << (channel & 0x1f); |
644 | pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten)); | 569 | pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten)); |
645 | pchregs->data.ainten |= mask; | 570 | pchregs->data.ainten |= mask; |
646 | outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten)); | 571 | outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten)); |
647 | } | 572 | } |
648 | #endif | 573 | #endif |
649 | 574 | ||
650 | static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channel) | 575 | static void snd_ali_disable_voice_irq(struct snd_ali *codec, |
576 | unsigned int channel) | ||
651 | { | 577 | { |
652 | unsigned int mask; | 578 | unsigned int mask; |
653 | struct snd_ali_channel_control *pchregs = &(codec->chregs); | 579 | struct snd_ali_channel_control *pchregs = &(codec->chregs); |
@@ -655,9 +581,9 @@ static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channe | |||
655 | snd_ali_printk("disable_voice_irq channel=%d\n",channel); | 581 | snd_ali_printk("disable_voice_irq channel=%d\n",channel); |
656 | 582 | ||
657 | mask = 1 << (channel & 0x1f); | 583 | mask = 1 << (channel & 0x1f); |
658 | pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten)); | 584 | pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten)); |
659 | pchregs->data.ainten &= ~mask; | 585 | pchregs->data.ainten &= ~mask; |
660 | outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten)); | 586 | outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten)); |
661 | } | 587 | } |
662 | 588 | ||
663 | static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel) | 589 | static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel) |
@@ -665,7 +591,8 @@ static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel) | |||
665 | unsigned int idx = channel & 0x1f; | 591 | unsigned int idx = channel & 0x1f; |
666 | 592 | ||
667 | if (codec->synth.chcnt >= ALI_CHANNELS){ | 593 | if (codec->synth.chcnt >= ALI_CHANNELS){ |
668 | snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n"); | 594 | snd_printk(KERN_ERR |
595 | "ali_alloc_pcm_channel: no free channels.\n"); | ||
669 | return -1; | 596 | return -1; |
670 | } | 597 | } |
671 | 598 | ||
@@ -685,35 +612,41 @@ static int snd_ali_find_free_channel(struct snd_ali * codec, int rec) | |||
685 | 612 | ||
686 | snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm"); | 613 | snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm"); |
687 | 614 | ||
688 | // recording | 615 | /* recording */ |
689 | if (rec) { | 616 | if (rec) { |
690 | if (codec->spdif_support && | 617 | if (codec->spdif_support && |
691 | (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_IN_SUPPORT)) | 618 | (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & |
619 | ALI_SPDIF_IN_SUPPORT)) | ||
692 | idx = ALI_SPDIF_IN_CHANNEL; | 620 | idx = ALI_SPDIF_IN_CHANNEL; |
693 | else | 621 | else |
694 | idx = ALI_PCM_IN_CHANNEL; | 622 | idx = ALI_PCM_IN_CHANNEL; |
695 | 623 | ||
696 | if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) { | 624 | result = snd_ali_alloc_pcm_channel(codec, idx); |
625 | if (result >= 0) | ||
697 | return result; | 626 | return result; |
698 | } else { | 627 | else { |
699 | snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n"); | 628 | snd_printk(KERN_ERR "ali_find_free_channel: " |
629 | "record channel is busy now.\n"); | ||
700 | return -1; | 630 | return -1; |
701 | } | 631 | } |
702 | } | 632 | } |
703 | 633 | ||
704 | //playback... | 634 | /* playback... */ |
705 | if (codec->spdif_support && | 635 | if (codec->spdif_support && |
706 | (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)) { | 636 | (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & |
637 | ALI_SPDIF_OUT_CH_ENABLE)) { | ||
707 | idx = ALI_SPDIF_OUT_CHANNEL; | 638 | idx = ALI_SPDIF_OUT_CHANNEL; |
708 | if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) { | 639 | result = snd_ali_alloc_pcm_channel(codec, idx); |
640 | if (result >= 0) | ||
709 | return result; | 641 | return result; |
710 | } else { | 642 | else |
711 | snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n"); | 643 | snd_printk(KERN_ERR "ali_find_free_channel: " |
712 | } | 644 | "S/PDIF out channel is in busy now.\n"); |
713 | } | 645 | } |
714 | 646 | ||
715 | for (idx = 0; idx < ALI_CHANNELS; idx++) { | 647 | for (idx = 0; idx < ALI_CHANNELS; idx++) { |
716 | if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) | 648 | result = snd_ali_alloc_pcm_channel(codec, idx); |
649 | if (result >= 0) | ||
717 | return result; | 650 | return result; |
718 | } | 651 | } |
719 | snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n"); | 652 | snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n"); |
@@ -730,7 +663,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel) | |||
730 | return; | 663 | return; |
731 | 664 | ||
732 | if (!(codec->synth.chmap & (1 << idx))) { | 665 | if (!(codec->synth.chmap & (1 << idx))) { |
733 | snd_printk(KERN_ERR "ali_free_channel_pcm: channel %d is not in use.\n",channel); | 666 | snd_printk(KERN_ERR "ali_free_channel_pcm: " |
667 | "channel %d is not in use.\n", channel); | ||
734 | return; | 668 | return; |
735 | } else { | 669 | } else { |
736 | codec->synth.chmap &= ~(1 << idx); | 670 | codec->synth.chmap &= ~(1 << idx); |
@@ -738,8 +672,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel) | |||
738 | } | 672 | } |
739 | } | 673 | } |
740 | 674 | ||
741 | #if 0 // not used | 675 | #if 0 /* not used */ |
742 | static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel) | 676 | static void snd_ali_start_voice(struct snd_ali *codec, unsigned int channel) |
743 | { | 677 | { |
744 | unsigned int mask = 1 << (channel & 0x1f); | 678 | unsigned int mask = 1 << (channel & 0x1f); |
745 | 679 | ||
@@ -748,7 +682,7 @@ static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel) | |||
748 | } | 682 | } |
749 | #endif | 683 | #endif |
750 | 684 | ||
751 | static void snd_ali_stop_voice(struct snd_ali * codec, unsigned int channel) | 685 | static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel) |
752 | { | 686 | { |
753 | unsigned int mask = 1 << (channel & 0x1f); | 687 | unsigned int mask = 1 << (channel & 0x1f); |
754 | 688 | ||
@@ -768,26 +702,27 @@ static void snd_ali_delay(struct snd_ali *codec,int interval) | |||
768 | currenttimer = inl(ALI_REG(codec, ALI_STIMER)); | 702 | currenttimer = inl(ALI_REG(codec, ALI_STIMER)); |
769 | 703 | ||
770 | while (currenttimer < begintimer + interval) { | 704 | while (currenttimer < begintimer + interval) { |
771 | if(snd_ali_stimer_ready(codec) < 0) | 705 | if (snd_ali_stimer_ready(codec) < 0) |
772 | break; | 706 | break; |
773 | currenttimer = inl(ALI_REG(codec, ALI_STIMER)); | 707 | currenttimer = inl(ALI_REG(codec, ALI_STIMER)); |
708 | cpu_relax(); | ||
774 | } | 709 | } |
775 | } | 710 | } |
776 | 711 | ||
777 | static void snd_ali_detect_spdif_rate(struct snd_ali *codec) | 712 | static void snd_ali_detect_spdif_rate(struct snd_ali *codec) |
778 | { | 713 | { |
779 | u16 wval = 0; | 714 | u16 wval; |
780 | u16 count = 0; | 715 | u16 count = 0; |
781 | u8 bval = 0, R1 = 0, R2 = 0; | 716 | u8 bval, R1 = 0, R2; |
782 | 717 | ||
783 | bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); | 718 | bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1)); |
784 | bval |= 0x1F; | 719 | bval |= 0x1F; |
785 | outb(bval,ALI_REG(codec,ALI_SPDIF_CTRL + 1)); | 720 | outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL + 1)); |
786 | 721 | ||
787 | while (((R1 < 0x0B )||(R1 > 0x0E)) && (R1 != 0x12) && count <= 50000) { | 722 | while ((R1 < 0x0b || R1 > 0x0e) && R1 != 0x12 && count <= 50000) { |
788 | count ++; | 723 | count ++; |
789 | snd_ali_delay(codec, 6); | 724 | snd_ali_delay(codec, 6); |
790 | bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); | 725 | bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1)); |
791 | R1 = bval & 0x1F; | 726 | R1 = bval & 0x1F; |
792 | } | 727 | } |
793 | 728 | ||
@@ -801,7 +736,10 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) | |||
801 | snd_ali_delay(codec, 6); | 736 | snd_ali_delay(codec, 6); |
802 | bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); | 737 | bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); |
803 | R2 = bval & 0x1F; | 738 | R2 = bval & 0x1F; |
804 | if (R2 != R1) R1 = R2; else break; | 739 | if (R2 != R1) |
740 | R1 = R2; | ||
741 | else | ||
742 | break; | ||
805 | } | 743 | } |
806 | 744 | ||
807 | if (count > 50000) { | 745 | if (count > 50000) { |
@@ -810,42 +748,45 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) | |||
810 | } | 748 | } |
811 | 749 | ||
812 | if (R2 >= 0x0b && R2 <= 0x0e) { | 750 | if (R2 >= 0x0b && R2 <= 0x0e) { |
813 | wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2)); | 751 | wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2)); |
814 | wval &= 0xE0F0; | 752 | wval &= 0xe0f0; |
815 | wval |= (u16)0x09 << 8 | (u16)0x05; | 753 | wval |= (0x09 << 8) | 0x05; |
816 | outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2)); | 754 | outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2)); |
817 | 755 | ||
818 | bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0; | 756 | bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)) & 0xf0; |
819 | outb(bval|0x02,ALI_REG(codec,ALI_SPDIF_CS + 3)); | 757 | outb(bval | 0x02, ALI_REG(codec, ALI_SPDIF_CS + 3)); |
820 | } else if (R2 == 0x12) { | 758 | } else if (R2 == 0x12) { |
821 | wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2)); | 759 | wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2)); |
822 | wval &= 0xE0F0; | 760 | wval &= 0xe0f0; |
823 | wval |= (u16)0x0E << 8 | (u16)0x08; | 761 | wval |= (0x0e << 8) | 0x08; |
824 | outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2)); | 762 | outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2)); |
825 | 763 | ||
826 | bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0; | 764 | bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)) & 0xf0; |
827 | outb(bval|0x03,ALI_REG(codec,ALI_SPDIF_CS + 3)); | 765 | outb(bval | 0x03, ALI_REG(codec, ALI_SPDIF_CS + 3)); |
828 | } | 766 | } |
829 | } | 767 | } |
830 | 768 | ||
831 | static unsigned int snd_ali_get_spdif_in_rate(struct snd_ali *codec) | 769 | static unsigned int snd_ali_get_spdif_in_rate(struct snd_ali *codec) |
832 | { | 770 | { |
833 | u32 dwRate = 0; | 771 | u32 dwRate; |
834 | u8 bval = 0; | 772 | u8 bval; |
835 | 773 | ||
836 | bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL)); | 774 | bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); |
837 | bval &= 0x7F; | 775 | bval &= 0x7f; |
838 | bval |= 0x40; | 776 | bval |= 0x40; |
839 | outb(bval, ALI_REG(codec,ALI_SPDIF_CTRL)); | 777 | outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL)); |
840 | 778 | ||
841 | snd_ali_detect_spdif_rate(codec); | 779 | snd_ali_detect_spdif_rate(codec); |
842 | 780 | ||
843 | bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)); | 781 | bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)); |
844 | bval &= 0x0F; | 782 | bval &= 0x0f; |
845 | 783 | ||
846 | if (bval == 0) dwRate = 44100; | 784 | switch (bval) { |
847 | if (bval == 1) dwRate = 48000; | 785 | case 0: dwRate = 44100; break; |
848 | if (bval == 2) dwRate = 32000; | 786 | case 1: dwRate = 48000; break; |
787 | case 2: dwRate = 32000; break; | ||
788 | default: dwRate = 0; break; | ||
789 | } | ||
849 | 790 | ||
850 | return dwRate; | 791 | return dwRate; |
851 | } | 792 | } |
@@ -880,20 +821,22 @@ static void snd_ali_disable_spdif_in(struct snd_ali *codec) | |||
880 | static void snd_ali_set_spdif_out_rate(struct snd_ali *codec, unsigned int rate) | 821 | static void snd_ali_set_spdif_out_rate(struct snd_ali *codec, unsigned int rate) |
881 | { | 822 | { |
882 | unsigned char bVal; | 823 | unsigned char bVal; |
883 | unsigned int dwRate = 0; | 824 | unsigned int dwRate; |
884 | 825 | ||
885 | if (rate == 32000) dwRate = 0x300; | 826 | switch (rate) { |
886 | if (rate == 44100) dwRate = 0; | 827 | case 32000: dwRate = 0x300; break; |
887 | if (rate == 48000) dwRate = 0x200; | 828 | case 48000: dwRate = 0x200; break; |
829 | default: dwRate = 0; break; | ||
830 | } | ||
888 | 831 | ||
889 | bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); | 832 | bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); |
890 | bVal &= (unsigned char)(~(1<<6)); | 833 | bVal &= (unsigned char)(~(1<<6)); |
891 | 834 | ||
892 | bVal |= 0x80; //select right | 835 | bVal |= 0x80; /* select right */ |
893 | outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); | 836 | outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); |
894 | outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2)); | 837 | outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2)); |
895 | 838 | ||
896 | bVal &= (~0x80); //select left | 839 | bVal &= ~0x80; /* select left */ |
897 | outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); | 840 | outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); |
898 | outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2)); | 841 | outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2)); |
899 | } | 842 | } |
@@ -902,8 +845,7 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec) | |||
902 | { | 845 | { |
903 | unsigned short wVal; | 846 | unsigned short wVal; |
904 | unsigned char bVal; | 847 | unsigned char bVal; |
905 | 848 | struct pci_dev *pci_dev; | |
906 | struct pci_dev *pci_dev = NULL; | ||
907 | 849 | ||
908 | pci_dev = codec->pci_m1533; | 850 | pci_dev = codec->pci_m1533; |
909 | if (pci_dev == NULL) | 851 | if (pci_dev == NULL) |
@@ -926,17 +868,15 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec) | |||
926 | bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); | 868 | bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); |
927 | outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL)); | 869 | outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL)); |
928 | 870 | ||
929 | { | 871 | wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
930 | wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); | 872 | wVal |= ALI_SPDIF_OUT_SEL_PCM; |
931 | wVal |= ALI_SPDIF_OUT_SEL_PCM; | 873 | outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
932 | outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); | 874 | snd_ali_disable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL); |
933 | snd_ali_disable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL); | ||
934 | } | ||
935 | } | 875 | } |
936 | 876 | ||
937 | static void snd_ali_enable_spdif_chnout(struct snd_ali *codec) | 877 | static void snd_ali_enable_spdif_chnout(struct snd_ali *codec) |
938 | { | 878 | { |
939 | unsigned short wVal = 0; | 879 | unsigned short wVal; |
940 | 880 | ||
941 | wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); | 881 | wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
942 | wVal &= ~ALI_SPDIF_OUT_SEL_PCM; | 882 | wVal &= ~ALI_SPDIF_OUT_SEL_PCM; |
@@ -949,12 +889,13 @@ static void snd_ali_enable_spdif_chnout(struct snd_ali *codec) | |||
949 | wVal &= (~0x0002); | 889 | wVal &= (~0x0002); |
950 | outw(wVal, ALI_REG(codec, ALI_SPDIF_CS)); | 890 | outw(wVal, ALI_REG(codec, ALI_SPDIF_CS)); |
951 | */ | 891 | */ |
952 | snd_ali_enable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL); | 892 | snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL); |
953 | } | 893 | } |
954 | 894 | ||
955 | static void snd_ali_disable_spdif_chnout(struct snd_ali *codec) | 895 | static void snd_ali_disable_spdif_chnout(struct snd_ali *codec) |
956 | { | 896 | { |
957 | unsigned short wVal = 0; | 897 | unsigned short wVal; |
898 | |||
958 | wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); | 899 | wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
959 | wVal |= ALI_SPDIF_OUT_SEL_PCM; | 900 | wVal |= ALI_SPDIF_OUT_SEL_PCM; |
960 | outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); | 901 | outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
@@ -972,11 +913,11 @@ static void snd_ali_disable_spdif_out(struct snd_ali *codec) | |||
972 | snd_ali_disable_spdif_chnout(codec); | 913 | snd_ali_disable_spdif_chnout(codec); |
973 | } | 914 | } |
974 | 915 | ||
975 | static void snd_ali_update_ptr(struct snd_ali *codec,int channel) | 916 | static void snd_ali_update_ptr(struct snd_ali *codec, int channel) |
976 | { | 917 | { |
977 | struct snd_ali_voice *pvoice = NULL; | 918 | struct snd_ali_voice *pvoice; |
978 | struct snd_pcm_runtime *runtime; | 919 | struct snd_pcm_runtime *runtime; |
979 | struct snd_ali_channel_control *pchregs = NULL; | 920 | struct snd_ali_channel_control *pchregs; |
980 | unsigned int old, mask; | 921 | unsigned int old, mask; |
981 | #ifdef ALI_DEBUG | 922 | #ifdef ALI_DEBUG |
982 | unsigned int temp, cspf; | 923 | unsigned int temp, cspf; |
@@ -984,9 +925,9 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) | |||
984 | 925 | ||
985 | pchregs = &(codec->chregs); | 926 | pchregs = &(codec->chregs); |
986 | 927 | ||
987 | // check if interrupt occurred for channel | 928 | /* check if interrupt occurred for channel */ |
988 | old = pchregs->data.aint; | 929 | old = pchregs->data.aint; |
989 | mask = ((unsigned int) 1L) << (channel & 0x1f); | 930 | mask = 1U << (channel & 0x1f); |
990 | 931 | ||
991 | if (!(old & mask)) | 932 | if (!(old & mask)) |
992 | return; | 933 | return; |
@@ -1005,7 +946,8 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) | |||
1005 | cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask; | 946 | cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask; |
1006 | #endif | 947 | #endif |
1007 | if (pvoice->running) { | 948 | if (pvoice->running) { |
1008 | snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",(u16)temp,cspf); | 949 | snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n", |
950 | (u16)temp, cspf); | ||
1009 | spin_unlock(&codec->reg_lock); | 951 | spin_unlock(&codec->reg_lock); |
1010 | snd_pcm_period_elapsed(pvoice->substream); | 952 | snd_pcm_period_elapsed(pvoice->substream); |
1011 | spin_lock(&codec->reg_lock); | 953 | spin_lock(&codec->reg_lock); |
@@ -1027,49 +969,47 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) | |||
1027 | pchregs->data.aint = old & (~mask); | 969 | pchregs->data.aint = old & (~mask); |
1028 | } | 970 | } |
1029 | 971 | ||
1030 | static void snd_ali_interrupt(struct snd_ali * codec) | 972 | static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id) |
1031 | { | 973 | { |
974 | struct snd_ali *codec = dev_id; | ||
1032 | int channel; | 975 | int channel; |
1033 | unsigned int audio_int; | 976 | unsigned int audio_int; |
1034 | struct snd_ali_channel_control *pchregs = NULL; | 977 | struct snd_ali_channel_control *pchregs; |
1035 | pchregs = &(codec->chregs); | 978 | |
979 | if (codec == NULL || !codec->hw_initialized) | ||
980 | return IRQ_NONE; | ||
1036 | 981 | ||
1037 | audio_int = inl(ALI_REG(codec, ALI_MISCINT)); | 982 | audio_int = inl(ALI_REG(codec, ALI_MISCINT)); |
983 | if (!audio_int) | ||
984 | return IRQ_NONE; | ||
985 | |||
986 | pchregs = &(codec->chregs); | ||
1038 | if (audio_int & ADDRESS_IRQ) { | 987 | if (audio_int & ADDRESS_IRQ) { |
1039 | // get interrupt status for all channels | 988 | /* get interrupt status for all channels */ |
1040 | pchregs->data.aint = inl(ALI_REG(codec,pchregs->regs.aint)); | 989 | pchregs->data.aint = inl(ALI_REG(codec, pchregs->regs.aint)); |
1041 | for (channel = 0; channel < ALI_CHANNELS; channel++) { | 990 | for (channel = 0; channel < ALI_CHANNELS; channel++) |
1042 | snd_ali_update_ptr(codec, channel); | 991 | snd_ali_update_ptr(codec, channel); |
1043 | } | ||
1044 | } | 992 | } |
1045 | outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), | 993 | outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), |
1046 | ALI_REG(codec,ALI_MISCINT)); | 994 | ALI_REG(codec, ALI_MISCINT)); |
1047 | } | ||
1048 | |||
1049 | |||
1050 | static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id) | ||
1051 | { | ||
1052 | struct snd_ali *codec = dev_id; | ||
1053 | 995 | ||
1054 | if (codec == NULL) | ||
1055 | return IRQ_NONE; | ||
1056 | snd_ali_interrupt(codec); | ||
1057 | return IRQ_HANDLED; | 996 | return IRQ_HANDLED; |
1058 | } | 997 | } |
1059 | 998 | ||
1060 | 999 | ||
1061 | static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int type, int rec, int channel) | 1000 | static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, |
1001 | int type, int rec, int channel) | ||
1062 | { | 1002 | { |
1063 | struct snd_ali_voice *pvoice = NULL; | 1003 | struct snd_ali_voice *pvoice; |
1064 | int idx; | 1004 | int idx; |
1065 | 1005 | ||
1066 | snd_ali_printk("alloc_voice: type=%d rec=%d\n",type,rec); | 1006 | snd_ali_printk("alloc_voice: type=%d rec=%d\n", type, rec); |
1067 | 1007 | ||
1068 | spin_lock_irq(&codec->voice_alloc); | 1008 | spin_lock_irq(&codec->voice_alloc); |
1069 | if (type == SNDRV_ALI_VOICE_TYPE_PCM) { | 1009 | if (type == SNDRV_ALI_VOICE_TYPE_PCM) { |
1070 | idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) : | 1010 | idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) : |
1071 | snd_ali_find_free_channel(codec,rec); | 1011 | snd_ali_find_free_channel(codec,rec); |
1072 | if(idx < 0) { | 1012 | if (idx < 0) { |
1073 | snd_printk(KERN_ERR "ali_alloc_voice: err.\n"); | 1013 | snd_printk(KERN_ERR "ali_alloc_voice: err.\n"); |
1074 | spin_unlock_irq(&codec->voice_alloc); | 1014 | spin_unlock_irq(&codec->voice_alloc); |
1075 | return NULL; | 1015 | return NULL; |
@@ -1087,7 +1027,8 @@ static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int typ | |||
1087 | } | 1027 | } |
1088 | 1028 | ||
1089 | 1029 | ||
1090 | static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvoice) | 1030 | static void snd_ali_free_voice(struct snd_ali * codec, |
1031 | struct snd_ali_voice *pvoice) | ||
1091 | { | 1032 | { |
1092 | void (*private_free)(void *); | 1033 | void (*private_free)(void *); |
1093 | void *private_data; | 1034 | void *private_data; |
@@ -1101,9 +1042,8 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo | |||
1101 | private_data = pvoice->private_data; | 1042 | private_data = pvoice->private_data; |
1102 | pvoice->private_free = NULL; | 1043 | pvoice->private_free = NULL; |
1103 | pvoice->private_data = NULL; | 1044 | pvoice->private_data = NULL; |
1104 | if (pvoice->pcm) { | 1045 | if (pvoice->pcm) |
1105 | snd_ali_free_channel_pcm(codec, pvoice->number); | 1046 | snd_ali_free_channel_pcm(codec, pvoice->number); |
1106 | } | ||
1107 | pvoice->use = pvoice->pcm = pvoice->synth = 0; | 1047 | pvoice->use = pvoice->pcm = pvoice->synth = 0; |
1108 | pvoice->substream = NULL; | 1048 | pvoice->substream = NULL; |
1109 | spin_unlock_irq(&codec->voice_alloc); | 1049 | spin_unlock_irq(&codec->voice_alloc); |
@@ -1112,9 +1052,9 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo | |||
1112 | } | 1052 | } |
1113 | 1053 | ||
1114 | 1054 | ||
1115 | static void snd_ali_clear_voices(struct snd_ali * codec, | 1055 | static void snd_ali_clear_voices(struct snd_ali *codec, |
1116 | unsigned int v_min, | 1056 | unsigned int v_min, |
1117 | unsigned int v_max) | 1057 | unsigned int v_max) |
1118 | { | 1058 | { |
1119 | unsigned int i; | 1059 | unsigned int i; |
1120 | 1060 | ||
@@ -1124,7 +1064,7 @@ static void snd_ali_clear_voices(struct snd_ali * codec, | |||
1124 | } | 1064 | } |
1125 | } | 1065 | } |
1126 | 1066 | ||
1127 | static void snd_ali_write_voice_regs(struct snd_ali * codec, | 1067 | static void snd_ali_write_voice_regs(struct snd_ali *codec, |
1128 | unsigned int Channel, | 1068 | unsigned int Channel, |
1129 | unsigned int LBA, | 1069 | unsigned int LBA, |
1130 | unsigned int CSO, | 1070 | unsigned int CSO, |
@@ -1139,7 +1079,7 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec, | |||
1139 | { | 1079 | { |
1140 | unsigned int ctlcmds[4]; | 1080 | unsigned int ctlcmds[4]; |
1141 | 1081 | ||
1142 | outb((unsigned char)(Channel & 0x001f),ALI_REG(codec,ALI_GC_CIR)); | 1082 | outb((unsigned char)(Channel & 0x001f), ALI_REG(codec, ALI_GC_CIR)); |
1143 | 1083 | ||
1144 | ctlcmds[0] = (CSO << 16) | (ALPHA_FMS & 0x0000ffff); | 1084 | ctlcmds[0] = (CSO << 16) | (ALPHA_FMS & 0x0000ffff); |
1145 | ctlcmds[1] = LBA; | 1085 | ctlcmds[1] = LBA; |
@@ -1152,10 +1092,10 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec, | |||
1152 | 1092 | ||
1153 | outb(Channel, ALI_REG(codec, ALI_GC_CIR)); | 1093 | outb(Channel, ALI_REG(codec, ALI_GC_CIR)); |
1154 | 1094 | ||
1155 | outl(ctlcmds[0], ALI_REG(codec,ALI_CSO_ALPHA_FMS)); | 1095 | outl(ctlcmds[0], ALI_REG(codec, ALI_CSO_ALPHA_FMS)); |
1156 | outl(ctlcmds[1], ALI_REG(codec,ALI_LBA)); | 1096 | outl(ctlcmds[1], ALI_REG(codec, ALI_LBA)); |
1157 | outl(ctlcmds[2], ALI_REG(codec,ALI_ESO_DELTA)); | 1097 | outl(ctlcmds[2], ALI_REG(codec, ALI_ESO_DELTA)); |
1158 | outl(ctlcmds[3], ALI_REG(codec,ALI_GVSEL_PAN_VOC_CTRL_EC)); | 1098 | outl(ctlcmds[3], ALI_REG(codec, ALI_GVSEL_PAN_VOC_CTRL_EC)); |
1159 | 1099 | ||
1160 | outl(0x30000000, ALI_REG(codec, ALI_EBUF1)); /* Still Mode */ | 1100 | outl(0x30000000, ALI_REG(codec, ALI_EBUF1)); /* Still Mode */ |
1161 | outl(0x30000000, ALI_REG(codec, ALI_EBUF2)); /* Still Mode */ | 1101 | outl(0x30000000, ALI_REG(codec, ALI_EBUF2)); /* Still Mode */ |
@@ -1165,8 +1105,10 @@ static unsigned int snd_ali_convert_rate(unsigned int rate, int rec) | |||
1165 | { | 1105 | { |
1166 | unsigned int delta; | 1106 | unsigned int delta; |
1167 | 1107 | ||
1168 | if (rate < 4000) rate = 4000; | 1108 | if (rate < 4000) |
1169 | if (rate > 48000) rate = 48000; | 1109 | rate = 4000; |
1110 | if (rate > 48000) | ||
1111 | rate = 48000; | ||
1170 | 1112 | ||
1171 | if (rec) { | 1113 | if (rec) { |
1172 | if (rate == 44100) | 1114 | if (rate == 44100) |
@@ -1201,11 +1143,11 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream) | |||
1201 | */ | 1143 | */ |
1202 | CTRL = 0x00000001; | 1144 | CTRL = 0x00000001; |
1203 | if (snd_pcm_format_width(runtime->format) == 16) | 1145 | if (snd_pcm_format_width(runtime->format) == 16) |
1204 | CTRL |= 0x00000008; // 16-bit data | 1146 | CTRL |= 0x00000008; /* 16-bit data */ |
1205 | if (!snd_pcm_format_unsigned(runtime->format)) | 1147 | if (!snd_pcm_format_unsigned(runtime->format)) |
1206 | CTRL |= 0x00000002; // signed data | 1148 | CTRL |= 0x00000002; /* signed data */ |
1207 | if (runtime->channels > 1) | 1149 | if (runtime->channels > 1) |
1208 | CTRL |= 0x00000004; // stereo data | 1150 | CTRL |= 0x00000004; /* stereo data */ |
1209 | return CTRL; | 1151 | return CTRL; |
1210 | } | 1152 | } |
1211 | 1153 | ||
@@ -1213,45 +1155,39 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream) | |||
1213 | * PCM part | 1155 | * PCM part |
1214 | */ | 1156 | */ |
1215 | 1157 | ||
1216 | static int snd_ali_ioctl(struct snd_pcm_substream *substream, | ||
1217 | unsigned int cmd, void *arg) | ||
1218 | { | ||
1219 | return snd_pcm_lib_ioctl(substream, cmd, arg); | ||
1220 | } | ||
1221 | |||
1222 | static int snd_ali_trigger(struct snd_pcm_substream *substream, | 1158 | static int snd_ali_trigger(struct snd_pcm_substream *substream, |
1223 | int cmd) | 1159 | int cmd) |
1224 | 1160 | ||
1225 | { | 1161 | { |
1226 | struct snd_ali *codec = snd_pcm_substream_chip(substream); | 1162 | struct snd_ali *codec = snd_pcm_substream_chip(substream); |
1227 | struct list_head *pos; | ||
1228 | struct snd_pcm_substream *s; | 1163 | struct snd_pcm_substream *s; |
1229 | unsigned int what, whati, capture_flag; | 1164 | unsigned int what, whati, capture_flag; |
1230 | struct snd_ali_voice *pvoice = NULL, *evoice = NULL; | 1165 | struct snd_ali_voice *pvoice, *evoice; |
1231 | unsigned int val; | 1166 | unsigned int val; |
1232 | int do_start; | 1167 | int do_start; |
1233 | 1168 | ||
1234 | switch (cmd) { | 1169 | switch (cmd) { |
1235 | case SNDRV_PCM_TRIGGER_START: | 1170 | case SNDRV_PCM_TRIGGER_START: |
1236 | case SNDRV_PCM_TRIGGER_RESUME: | 1171 | case SNDRV_PCM_TRIGGER_RESUME: |
1237 | do_start = 1; break; | 1172 | do_start = 1; |
1173 | break; | ||
1238 | case SNDRV_PCM_TRIGGER_STOP: | 1174 | case SNDRV_PCM_TRIGGER_STOP: |
1239 | case SNDRV_PCM_TRIGGER_SUSPEND: | 1175 | case SNDRV_PCM_TRIGGER_SUSPEND: |
1240 | do_start = 0; break; | 1176 | do_start = 0; |
1177 | break; | ||
1241 | default: | 1178 | default: |
1242 | return -EINVAL; | 1179 | return -EINVAL; |
1243 | } | 1180 | } |
1244 | 1181 | ||
1245 | what = whati = capture_flag = 0; | 1182 | what = whati = capture_flag = 0; |
1246 | snd_pcm_group_for_each(pos, substream) { | 1183 | snd_pcm_group_for_each_entry(s, substream) { |
1247 | s = snd_pcm_group_substream_entry(pos); | ||
1248 | if ((struct snd_ali *) snd_pcm_substream_chip(s) == codec) { | 1184 | if ((struct snd_ali *) snd_pcm_substream_chip(s) == codec) { |
1249 | pvoice = s->runtime->private_data; | 1185 | pvoice = s->runtime->private_data; |
1250 | evoice = pvoice->extra; | 1186 | evoice = pvoice->extra; |
1251 | what |= 1 << (pvoice->number & 0x1f); | 1187 | what |= 1 << (pvoice->number & 0x1f); |
1252 | if (evoice == NULL) { | 1188 | if (evoice == NULL) |
1253 | whati |= 1 << (pvoice->number & 0x1f); | 1189 | whati |= 1 << (pvoice->number & 0x1f); |
1254 | } else { | 1190 | else { |
1255 | whati |= 1 << (evoice->number & 0x1f); | 1191 | whati |= 1 << (evoice->number & 0x1f); |
1256 | what |= 1 << (evoice->number & 0x1f); | 1192 | what |= 1 << (evoice->number & 0x1f); |
1257 | } | 1193 | } |
@@ -1270,48 +1206,51 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, | |||
1270 | } | 1206 | } |
1271 | } | 1207 | } |
1272 | spin_lock(&codec->reg_lock); | 1208 | spin_lock(&codec->reg_lock); |
1273 | if (! do_start) { | 1209 | if (!do_start) |
1274 | outl(what, ALI_REG(codec, ALI_STOP)); | 1210 | outl(what, ALI_REG(codec, ALI_STOP)); |
1275 | } | ||
1276 | val = inl(ALI_REG(codec, ALI_AINTEN)); | 1211 | val = inl(ALI_REG(codec, ALI_AINTEN)); |
1277 | if (do_start) { | 1212 | if (do_start) |
1278 | val |= whati; | 1213 | val |= whati; |
1279 | } else { | 1214 | else |
1280 | val &= ~whati; | 1215 | val &= ~whati; |
1281 | } | ||
1282 | outl(val, ALI_REG(codec, ALI_AINTEN)); | 1216 | outl(val, ALI_REG(codec, ALI_AINTEN)); |
1283 | if (do_start) { | 1217 | if (do_start) |
1284 | outl(what, ALI_REG(codec, ALI_START)); | 1218 | outl(what, ALI_REG(codec, ALI_START)); |
1285 | } | 1219 | snd_ali_printk("trigger: what=%xh whati=%xh\n", what, whati); |
1286 | snd_ali_printk("trigger: what=%xh whati=%xh\n",what,whati); | ||
1287 | spin_unlock(&codec->reg_lock); | 1220 | spin_unlock(&codec->reg_lock); |
1288 | 1221 | ||
1289 | return 0; | 1222 | return 0; |
1290 | } | 1223 | } |
1291 | 1224 | ||
1292 | static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream, | 1225 | static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream, |
1293 | struct snd_pcm_hw_params *hw_params) | 1226 | struct snd_pcm_hw_params *hw_params) |
1294 | { | 1227 | { |
1295 | struct snd_ali *codec = snd_pcm_substream_chip(substream); | 1228 | struct snd_ali *codec = snd_pcm_substream_chip(substream); |
1296 | struct snd_pcm_runtime *runtime = substream->runtime; | 1229 | struct snd_pcm_runtime *runtime = substream->runtime; |
1297 | struct snd_ali_voice *pvoice = runtime->private_data; | 1230 | struct snd_ali_voice *pvoice = runtime->private_data; |
1298 | struct snd_ali_voice *evoice = pvoice->extra; | 1231 | struct snd_ali_voice *evoice = pvoice->extra; |
1299 | int err; | 1232 | int err; |
1300 | err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); | 1233 | |
1301 | if (err < 0) return err; | 1234 | err = snd_pcm_lib_malloc_pages(substream, |
1235 | params_buffer_bytes(hw_params)); | ||
1236 | if (err < 0) | ||
1237 | return err; | ||
1302 | 1238 | ||
1303 | /* voice management */ | 1239 | /* voice management */ |
1304 | 1240 | ||
1305 | if (params_buffer_size(hw_params)/2 != params_period_size(hw_params)) { | 1241 | if (params_buffer_size(hw_params) / 2 != |
1306 | if (evoice == NULL) { | 1242 | params_period_size(hw_params)) { |
1307 | evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0, -1); | 1243 | if (!evoice) { |
1308 | if (evoice == NULL) | 1244 | evoice = snd_ali_alloc_voice(codec, |
1245 | SNDRV_ALI_VOICE_TYPE_PCM, | ||
1246 | 0, -1); | ||
1247 | if (!evoice) | ||
1309 | return -ENOMEM; | 1248 | return -ENOMEM; |
1310 | pvoice->extra = evoice; | 1249 | pvoice->extra = evoice; |
1311 | evoice->substream = substream; | 1250 | evoice->substream = substream; |
1312 | } | 1251 | } |
1313 | } else { | 1252 | } else { |
1314 | if (evoice != NULL) { | 1253 | if (!evoice) { |
1315 | snd_ali_free_voice(codec, evoice); | 1254 | snd_ali_free_voice(codec, evoice); |
1316 | pvoice->extra = evoice = NULL; | 1255 | pvoice->extra = evoice = NULL; |
1317 | } | 1256 | } |
@@ -1328,7 +1267,7 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream) | |||
1328 | struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL; | 1267 | struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL; |
1329 | 1268 | ||
1330 | snd_pcm_lib_free_pages(substream); | 1269 | snd_pcm_lib_free_pages(substream); |
1331 | if (evoice != NULL) { | 1270 | if (!evoice) { |
1332 | snd_ali_free_voice(codec, evoice); | 1271 | snd_ali_free_voice(codec, evoice); |
1333 | pvoice->extra = NULL; | 1272 | pvoice->extra = NULL; |
1334 | } | 1273 | } |
@@ -1336,9 +1275,10 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream) | |||
1336 | } | 1275 | } |
1337 | 1276 | ||
1338 | static int snd_ali_hw_params(struct snd_pcm_substream *substream, | 1277 | static int snd_ali_hw_params(struct snd_pcm_substream *substream, |
1339 | struct snd_pcm_hw_params *hw_params) | 1278 | struct snd_pcm_hw_params *hw_params) |
1340 | { | 1279 | { |
1341 | return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); | 1280 | return snd_pcm_lib_malloc_pages(substream, |
1281 | params_buffer_bytes(hw_params)); | ||
1342 | } | 1282 | } |
1343 | 1283 | ||
1344 | static int snd_ali_hw_free(struct snd_pcm_substream *substream) | 1284 | static int snd_ali_hw_free(struct snd_pcm_substream *substream) |
@@ -1369,12 +1309,13 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) | |||
1369 | /* set Delta (rate) value */ | 1309 | /* set Delta (rate) value */ |
1370 | Delta = snd_ali_convert_rate(runtime->rate, 0); | 1310 | Delta = snd_ali_convert_rate(runtime->rate, 0); |
1371 | 1311 | ||
1372 | if ((pvoice->number == ALI_SPDIF_IN_CHANNEL) || | 1312 | if (pvoice->number == ALI_SPDIF_IN_CHANNEL || |
1373 | (pvoice->number == ALI_PCM_IN_CHANNEL)) | 1313 | pvoice->number == ALI_PCM_IN_CHANNEL) |
1374 | snd_ali_disable_special_channel(codec, pvoice->number); | 1314 | snd_ali_disable_special_channel(codec, pvoice->number); |
1375 | else if (codec->spdif_support && | 1315 | else if (codec->spdif_support && |
1376 | (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE) | 1316 | (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & |
1377 | && (pvoice->number == ALI_SPDIF_OUT_CHANNEL)) { | 1317 | ALI_SPDIF_OUT_CH_ENABLE) |
1318 | && pvoice->number == ALI_SPDIF_OUT_CHANNEL) { | ||
1378 | snd_ali_set_spdif_out_rate(codec, runtime->rate); | 1319 | snd_ali_set_spdif_out_rate(codec, runtime->rate); |
1379 | Delta = 0x1000; | 1320 | Delta = 0x1000; |
1380 | } | 1321 | } |
@@ -1388,7 +1329,8 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) | |||
1388 | /* set target ESO for channel */ | 1329 | /* set target ESO for channel */ |
1389 | pvoice->eso = runtime->buffer_size; | 1330 | pvoice->eso = runtime->buffer_size; |
1390 | 1331 | ||
1391 | snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",pvoice->eso,pvoice->count); | 1332 | snd_ali_printk("playback_prepare: eso=%xh count=%xh\n", |
1333 | pvoice->eso, pvoice->count); | ||
1392 | 1334 | ||
1393 | /* set ESO to capture first MIDLP interrupt */ | 1335 | /* set ESO to capture first MIDLP interrupt */ |
1394 | ESO = pvoice->eso -1; | 1336 | ESO = pvoice->eso -1; |
@@ -1399,35 +1341,37 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) | |||
1399 | PAN = 0; | 1341 | PAN = 0; |
1400 | VOL = 0; | 1342 | VOL = 0; |
1401 | EC = 0; | 1343 | EC = 0; |
1402 | snd_ali_printk("playback_prepare:\n ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL); | 1344 | snd_ali_printk("playback_prepare:\n"); |
1403 | snd_ali_write_voice_regs( codec, | 1345 | snd_ali_printk("ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n", |
1404 | pvoice->number, | 1346 | pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL); |
1405 | LBA, | 1347 | snd_ali_write_voice_regs(codec, |
1406 | 0, /* cso */ | 1348 | pvoice->number, |
1407 | ESO, | 1349 | LBA, |
1408 | Delta, | 1350 | 0, /* cso */ |
1409 | 0, /* alpha */ | 1351 | ESO, |
1410 | GVSEL, | 1352 | Delta, |
1411 | PAN, | 1353 | 0, /* alpha */ |
1412 | VOL, | 1354 | GVSEL, |
1413 | CTRL, | 1355 | PAN, |
1414 | EC); | 1356 | VOL, |
1415 | if (evoice != NULL) { | 1357 | CTRL, |
1358 | EC); | ||
1359 | if (!evoice) { | ||
1416 | evoice->count = pvoice->count; | 1360 | evoice->count = pvoice->count; |
1417 | evoice->eso = pvoice->count << 1; | 1361 | evoice->eso = pvoice->count << 1; |
1418 | ESO = evoice->eso - 1; | 1362 | ESO = evoice->eso - 1; |
1419 | snd_ali_write_voice_regs(codec, | 1363 | snd_ali_write_voice_regs(codec, |
1420 | evoice->number, | 1364 | evoice->number, |
1421 | LBA, | 1365 | LBA, |
1422 | 0, /* cso */ | 1366 | 0, /* cso */ |
1423 | ESO, | 1367 | ESO, |
1424 | Delta, | 1368 | Delta, |
1425 | 0, /* alpha */ | 1369 | 0, /* alpha */ |
1426 | GVSEL, | 1370 | GVSEL, |
1427 | (unsigned int)0x7f, | 1371 | 0x7f, |
1428 | (unsigned int)0x3ff, | 1372 | 0x3ff, |
1429 | CTRL, | 1373 | CTRL, |
1430 | EC); | 1374 | EC); |
1431 | } | 1375 | } |
1432 | spin_unlock_irq(&codec->reg_lock); | 1376 | spin_unlock_irq(&codec->reg_lock); |
1433 | return 0; | 1377 | return 0; |
@@ -1459,7 +1403,7 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) | |||
1459 | pvoice->number == ALI_MODEM_OUT_CHANNEL) ? | 1403 | pvoice->number == ALI_MODEM_OUT_CHANNEL) ? |
1460 | 0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode); | 1404 | 0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode); |
1461 | 1405 | ||
1462 | // Prepare capture intr channel | 1406 | /* Prepare capture intr channel */ |
1463 | if (pvoice->number == ALI_SPDIF_IN_CHANNEL) { | 1407 | if (pvoice->number == ALI_SPDIF_IN_CHANNEL) { |
1464 | 1408 | ||
1465 | unsigned int rate; | 1409 | unsigned int rate; |
@@ -1470,7 +1414,8 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) | |||
1470 | 1414 | ||
1471 | rate = snd_ali_get_spdif_in_rate(codec); | 1415 | rate = snd_ali_get_spdif_in_rate(codec); |
1472 | if (rate == 0) { | 1416 | if (rate == 0) { |
1473 | snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n"); | 1417 | snd_printk(KERN_WARNING "ali_capture_preapre: " |
1418 | "spdif rate detect err!\n"); | ||
1474 | rate = 48000; | 1419 | rate = 48000; |
1475 | } | 1420 | } |
1476 | spin_lock_irq(&codec->reg_lock); | 1421 | spin_lock_irq(&codec->reg_lock); |
@@ -1481,19 +1426,19 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) | |||
1481 | } | 1426 | } |
1482 | 1427 | ||
1483 | if (rate != 48000) | 1428 | if (rate != 48000) |
1484 | Delta = ((rate << 12)/runtime->rate)&0x00ffff; | 1429 | Delta = ((rate << 12) / runtime->rate) & 0x00ffff; |
1485 | } | 1430 | } |
1486 | 1431 | ||
1487 | // set target ESO for channel | 1432 | /* set target ESO for channel */ |
1488 | pvoice->eso = runtime->buffer_size; | 1433 | pvoice->eso = runtime->buffer_size; |
1489 | 1434 | ||
1490 | // set interrupt count size | 1435 | /* set interrupt count size */ |
1491 | pvoice->count = runtime->period_size; | 1436 | pvoice->count = runtime->period_size; |
1492 | 1437 | ||
1493 | // set Loop Back Address | 1438 | /* set Loop Back Address */ |
1494 | LBA = runtime->dma_addr; | 1439 | LBA = runtime->dma_addr; |
1495 | 1440 | ||
1496 | // set ESO to capture first MIDLP interrupt | 1441 | /* set ESO to capture first MIDLP interrupt */ |
1497 | ESO = pvoice->eso - 1; | 1442 | ESO = pvoice->eso - 1; |
1498 | CTRL = snd_ali_control_mode(substream); | 1443 | CTRL = snd_ali_control_mode(substream); |
1499 | GVSEL = 0; | 1444 | GVSEL = 0; |
@@ -1514,14 +1459,14 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) | |||
1514 | CTRL, | 1459 | CTRL, |
1515 | EC); | 1460 | EC); |
1516 | 1461 | ||
1517 | |||
1518 | spin_unlock_irq(&codec->reg_lock); | 1462 | spin_unlock_irq(&codec->reg_lock); |
1519 | 1463 | ||
1520 | return 0; | 1464 | return 0; |
1521 | } | 1465 | } |
1522 | 1466 | ||
1523 | 1467 | ||
1524 | static snd_pcm_uframes_t snd_ali_playback_pointer(struct snd_pcm_substream *substream) | 1468 | static snd_pcm_uframes_t |
1469 | snd_ali_playback_pointer(struct snd_pcm_substream *substream) | ||
1525 | { | 1470 | { |
1526 | struct snd_ali *codec = snd_pcm_substream_chip(substream); | 1471 | struct snd_ali *codec = snd_pcm_substream_chip(substream); |
1527 | struct snd_pcm_runtime *runtime = substream->runtime; | 1472 | struct snd_pcm_runtime *runtime = substream->runtime; |
@@ -1563,14 +1508,14 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream) | |||
1563 | 1508 | ||
1564 | static struct snd_pcm_hardware snd_ali_playback = | 1509 | static struct snd_pcm_hardware snd_ali_playback = |
1565 | { | 1510 | { |
1566 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1511 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
1567 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1512 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
1568 | SNDRV_PCM_INFO_MMAP_VALID | | 1513 | SNDRV_PCM_INFO_MMAP_VALID | |
1569 | SNDRV_PCM_INFO_RESUME | | 1514 | SNDRV_PCM_INFO_RESUME | |
1570 | SNDRV_PCM_INFO_SYNC_START), | 1515 | SNDRV_PCM_INFO_SYNC_START), |
1571 | .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | | 1516 | .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | |
1572 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), | 1517 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), |
1573 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, | 1518 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, |
1574 | .rate_min = 4000, | 1519 | .rate_min = 4000, |
1575 | .rate_max = 48000, | 1520 | .rate_max = 48000, |
1576 | .channels_min = 1, | 1521 | .channels_min = 1, |
@@ -1589,14 +1534,14 @@ static struct snd_pcm_hardware snd_ali_playback = | |||
1589 | 1534 | ||
1590 | static struct snd_pcm_hardware snd_ali_capture = | 1535 | static struct snd_pcm_hardware snd_ali_capture = |
1591 | { | 1536 | { |
1592 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1537 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
1593 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1538 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
1594 | SNDRV_PCM_INFO_MMAP_VALID | | 1539 | SNDRV_PCM_INFO_MMAP_VALID | |
1595 | SNDRV_PCM_INFO_RESUME | | 1540 | SNDRV_PCM_INFO_RESUME | |
1596 | SNDRV_PCM_INFO_SYNC_START), | 1541 | SNDRV_PCM_INFO_SYNC_START), |
1597 | .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | | 1542 | .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | |
1598 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), | 1543 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), |
1599 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, | 1544 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, |
1600 | .rate_min = 4000, | 1545 | .rate_min = 4000, |
1601 | .rate_max = 48000, | 1546 | .rate_max = 48000, |
1602 | .channels_min = 1, | 1547 | .channels_min = 1, |
@@ -1620,15 +1565,16 @@ static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime) | |||
1620 | } | 1565 | } |
1621 | } | 1566 | } |
1622 | 1567 | ||
1623 | static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channel, | 1568 | static int snd_ali_open(struct snd_pcm_substream *substream, int rec, |
1624 | struct snd_pcm_hardware *phw) | 1569 | int channel, struct snd_pcm_hardware *phw) |
1625 | { | 1570 | { |
1626 | struct snd_ali *codec = snd_pcm_substream_chip(substream); | 1571 | struct snd_ali *codec = snd_pcm_substream_chip(substream); |
1627 | struct snd_pcm_runtime *runtime = substream->runtime; | 1572 | struct snd_pcm_runtime *runtime = substream->runtime; |
1628 | struct snd_ali_voice *pvoice; | 1573 | struct snd_ali_voice *pvoice; |
1629 | 1574 | ||
1630 | pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, channel); | 1575 | pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, |
1631 | if (pvoice == NULL) | 1576 | channel); |
1577 | if (!pvoice) | ||
1632 | return -EAGAIN; | 1578 | return -EAGAIN; |
1633 | 1579 | ||
1634 | pvoice->substream = substream; | 1580 | pvoice->substream = substream; |
@@ -1637,7 +1583,8 @@ static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channe | |||
1637 | 1583 | ||
1638 | runtime->hw = *phw; | 1584 | runtime->hw = *phw; |
1639 | snd_pcm_set_sync(substream); | 1585 | snd_pcm_set_sync(substream); |
1640 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); | 1586 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, |
1587 | 0, 64*1024); | ||
1641 | return 0; | 1588 | return 0; |
1642 | } | 1589 | } |
1643 | 1590 | ||
@@ -1669,7 +1616,7 @@ static int snd_ali_close(struct snd_pcm_substream *substream) | |||
1669 | static struct snd_pcm_ops snd_ali_playback_ops = { | 1616 | static struct snd_pcm_ops snd_ali_playback_ops = { |
1670 | .open = snd_ali_playback_open, | 1617 | .open = snd_ali_playback_open, |
1671 | .close = snd_ali_playback_close, | 1618 | .close = snd_ali_playback_close, |
1672 | .ioctl = snd_ali_ioctl, | 1619 | .ioctl = snd_pcm_lib_ioctl, |
1673 | .hw_params = snd_ali_playback_hw_params, | 1620 | .hw_params = snd_ali_playback_hw_params, |
1674 | .hw_free = snd_ali_playback_hw_free, | 1621 | .hw_free = snd_ali_playback_hw_free, |
1675 | .prepare = snd_ali_playback_prepare, | 1622 | .prepare = snd_ali_playback_prepare, |
@@ -1680,7 +1627,7 @@ static struct snd_pcm_ops snd_ali_playback_ops = { | |||
1680 | static struct snd_pcm_ops snd_ali_capture_ops = { | 1627 | static struct snd_pcm_ops snd_ali_capture_ops = { |
1681 | .open = snd_ali_capture_open, | 1628 | .open = snd_ali_capture_open, |
1682 | .close = snd_ali_close, | 1629 | .close = snd_ali_close, |
1683 | .ioctl = snd_ali_ioctl, | 1630 | .ioctl = snd_pcm_lib_ioctl, |
1684 | .hw_params = snd_ali_hw_params, | 1631 | .hw_params = snd_ali_hw_params, |
1685 | .hw_free = snd_ali_hw_free, | 1632 | .hw_free = snd_ali_hw_free, |
1686 | .prepare = snd_ali_prepare, | 1633 | .prepare = snd_ali_prepare, |
@@ -1697,20 +1644,22 @@ static int snd_ali_modem_hw_params(struct snd_pcm_substream *substream, | |||
1697 | { | 1644 | { |
1698 | struct snd_ali *chip = snd_pcm_substream_chip(substream); | 1645 | struct snd_ali *chip = snd_pcm_substream_chip(substream); |
1699 | unsigned int modem_num = chip->num_of_codecs - 1; | 1646 | unsigned int modem_num = chip->num_of_codecs - 1; |
1700 | snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, params_rate(hw_params)); | 1647 | snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, |
1648 | params_rate(hw_params)); | ||
1701 | snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0); | 1649 | snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0); |
1702 | return snd_ali_hw_params(substream, hw_params); | 1650 | return snd_ali_hw_params(substream, hw_params); |
1703 | } | 1651 | } |
1704 | 1652 | ||
1705 | static struct snd_pcm_hardware snd_ali_modem = | 1653 | static struct snd_pcm_hardware snd_ali_modem = |
1706 | { | 1654 | { |
1707 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1655 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
1708 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1656 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
1709 | SNDRV_PCM_INFO_MMAP_VALID | | 1657 | SNDRV_PCM_INFO_MMAP_VALID | |
1710 | SNDRV_PCM_INFO_RESUME | | 1658 | SNDRV_PCM_INFO_RESUME | |
1711 | SNDRV_PCM_INFO_SYNC_START), | 1659 | SNDRV_PCM_INFO_SYNC_START), |
1712 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 1660 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
1713 | .rates = SNDRV_PCM_RATE_KNOT|SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000, | 1661 | .rates = (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000 | |
1662 | SNDRV_PCM_RATE_16000), | ||
1714 | .rate_min = 8000, | 1663 | .rate_min = 8000, |
1715 | .rate_max = 16000, | 1664 | .rate_max = 16000, |
1716 | .channels_min = 1, | 1665 | .channels_min = 1, |
@@ -1723,15 +1672,17 @@ static struct snd_pcm_hardware snd_ali_modem = | |||
1723 | .fifo_size = 0, | 1672 | .fifo_size = 0, |
1724 | }; | 1673 | }; |
1725 | 1674 | ||
1726 | static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, int channel) | 1675 | static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, |
1676 | int channel) | ||
1727 | { | 1677 | { |
1728 | static unsigned int rates [] = {8000,9600,12000,16000}; | 1678 | static unsigned int rates[] = {8000, 9600, 12000, 16000}; |
1729 | static struct snd_pcm_hw_constraint_list hw_constraint_rates = { | 1679 | static struct snd_pcm_hw_constraint_list hw_constraint_rates = { |
1730 | .count = ARRAY_SIZE(rates), | 1680 | .count = ARRAY_SIZE(rates), |
1731 | .list = rates, | 1681 | .list = rates, |
1732 | .mask = 0, | 1682 | .mask = 0, |
1733 | }; | 1683 | }; |
1734 | int err = snd_ali_open(substream, rec, channel, &snd_ali_modem); | 1684 | int err = snd_ali_open(substream, rec, channel, &snd_ali_modem); |
1685 | |||
1735 | if (err) | 1686 | if (err) |
1736 | return err; | 1687 | return err; |
1737 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | 1688 | return snd_pcm_hw_constraint_list(substream->runtime, 0, |
@@ -1788,7 +1739,8 @@ static void snd_ali_pcm_free(struct snd_pcm *pcm) | |||
1788 | } | 1739 | } |
1789 | 1740 | ||
1790 | 1741 | ||
1791 | static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_pcm_description *desc) | 1742 | static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, |
1743 | struct ali_pcm_description *desc) | ||
1792 | { | 1744 | { |
1793 | struct snd_pcm *pcm; | 1745 | struct snd_pcm *pcm; |
1794 | int err; | 1746 | int err; |
@@ -1802,12 +1754,15 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_ | |||
1802 | pcm->private_data = codec; | 1754 | pcm->private_data = codec; |
1803 | pcm->private_free = snd_ali_pcm_free; | 1755 | pcm->private_free = snd_ali_pcm_free; |
1804 | if (desc->playback_ops) | 1756 | if (desc->playback_ops) |
1805 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops); | 1757 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
1758 | desc->playback_ops); | ||
1806 | if (desc->capture_ops) | 1759 | if (desc->capture_ops) |
1807 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, desc->capture_ops); | 1760 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, |
1761 | desc->capture_ops); | ||
1808 | 1762 | ||
1809 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1763 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1810 | snd_dma_pci_data(codec->pci), 64*1024, 128*1024); | 1764 | snd_dma_pci_data(codec->pci), |
1765 | 64*1024, 128*1024); | ||
1811 | 1766 | ||
1812 | pcm->info_flags = 0; | 1767 | pcm->info_flags = 0; |
1813 | pcm->dev_class = desc->class; | 1768 | pcm->dev_class = desc->class; |
@@ -1818,16 +1773,29 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_ | |||
1818 | } | 1773 | } |
1819 | 1774 | ||
1820 | static struct ali_pcm_description ali_pcms[] = { | 1775 | static struct ali_pcm_description ali_pcms[] = { |
1821 | { "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops }, | 1776 | { .name = "ALI 5451", |
1822 | { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM } | 1777 | .playback_num = ALI_CHANNELS, |
1778 | .capture_num = 1, | ||
1779 | .playback_ops = &snd_ali_playback_ops, | ||
1780 | .capture_ops = &snd_ali_capture_ops | ||
1781 | }, | ||
1782 | { .name = "ALI 5451 modem", | ||
1783 | .playback_num = 1, | ||
1784 | .capture_num = 1, | ||
1785 | .playback_ops = &snd_ali_modem_playback_ops, | ||
1786 | .capture_ops = &snd_ali_modem_capture_ops, | ||
1787 | .class = SNDRV_PCM_CLASS_MODEM | ||
1788 | } | ||
1823 | }; | 1789 | }; |
1824 | 1790 | ||
1825 | static int __devinit snd_ali_build_pcms(struct snd_ali *codec) | 1791 | static int __devinit snd_ali_build_pcms(struct snd_ali *codec) |
1826 | { | 1792 | { |
1827 | int i, err; | 1793 | int i, err; |
1828 | for(i = 0 ; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms) ; i++) | 1794 | for (i = 0; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms); i++) { |
1829 | if((err = snd_ali_pcm(codec, i, &ali_pcms[i])) < 0) | 1795 | err = snd_ali_pcm(codec, i, &ali_pcms[i]); |
1796 | if (err < 0) | ||
1830 | return err; | 1797 | return err; |
1798 | } | ||
1831 | return 0; | 1799 | return 0; |
1832 | } | 1800 | } |
1833 | 1801 | ||
@@ -1837,7 +1805,8 @@ static int __devinit snd_ali_build_pcms(struct snd_ali *codec) | |||
1837 | .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \ | 1805 | .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \ |
1838 | .put = snd_ali5451_spdif_put, .private_value = value} | 1806 | .put = snd_ali5451_spdif_put, .private_value = value} |
1839 | 1807 | ||
1840 | static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1808 | static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, |
1809 | struct snd_ctl_elem_info *uinfo) | ||
1841 | { | 1810 | { |
1842 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 1811 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
1843 | uinfo->count = 1; | 1812 | uinfo->count = 1; |
@@ -1846,7 +1815,8 @@ static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1846 | return 0; | 1815 | return 0; |
1847 | } | 1816 | } |
1848 | 1817 | ||
1849 | static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1818 | static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, |
1819 | struct snd_ctl_elem_value *ucontrol) | ||
1850 | { | 1820 | { |
1851 | struct snd_ali *codec = kcontrol->private_data; | 1821 | struct snd_ali *codec = kcontrol->private_data; |
1852 | unsigned int enable; | 1822 | unsigned int enable; |
@@ -1854,12 +1824,13 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1854 | enable = ucontrol->value.integer.value[0] ? 1 : 0; | 1824 | enable = ucontrol->value.integer.value[0] ? 1 : 0; |
1855 | 1825 | ||
1856 | spin_lock_irq(&codec->reg_lock); | 1826 | spin_lock_irq(&codec->reg_lock); |
1857 | switch(kcontrol->private_value) { | 1827 | switch (kcontrol->private_value) { |
1858 | case 0: | 1828 | case 0: |
1859 | enable = (codec->spdif_mask & 0x02) ? 1 : 0; | 1829 | enable = (codec->spdif_mask & 0x02) ? 1 : 0; |
1860 | break; | 1830 | break; |
1861 | case 1: | 1831 | case 1: |
1862 | enable = ((codec->spdif_mask & 0x02) && (codec->spdif_mask & 0x04)) ? 1 : 0; | 1832 | enable = ((codec->spdif_mask & 0x02) && |
1833 | (codec->spdif_mask & 0x04)) ? 1 : 0; | ||
1863 | break; | 1834 | break; |
1864 | case 2: | 1835 | case 2: |
1865 | enable = (codec->spdif_mask & 0x01) ? 1 : 0; | 1836 | enable = (codec->spdif_mask & 0x01) ? 1 : 0; |
@@ -1872,7 +1843,8 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1872 | return 0; | 1843 | return 0; |
1873 | } | 1844 | } |
1874 | 1845 | ||
1875 | static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1846 | static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, |
1847 | struct snd_ctl_elem_value *ucontrol) | ||
1876 | { | 1848 | { |
1877 | struct snd_ali *codec = kcontrol->private_data; | 1849 | struct snd_ali *codec = kcontrol->private_data; |
1878 | unsigned int change = 0, enable = 0; | 1850 | unsigned int change = 0, enable = 0; |
@@ -1939,18 +1911,6 @@ static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] __devinitdata = { | |||
1939 | ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2) | 1911 | ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2) |
1940 | }; | 1912 | }; |
1941 | 1913 | ||
1942 | static void snd_ali_mixer_free_ac97_bus(struct snd_ac97_bus *bus) | ||
1943 | { | ||
1944 | struct snd_ali *codec = bus->private_data; | ||
1945 | codec->ac97_bus = NULL; | ||
1946 | } | ||
1947 | |||
1948 | static void snd_ali_mixer_free_ac97(struct snd_ac97 *ac97) | ||
1949 | { | ||
1950 | struct snd_ali *codec = ac97->private_data; | ||
1951 | codec->ac97[ac97->num] = NULL; | ||
1952 | } | ||
1953 | |||
1954 | static int __devinit snd_ali_mixer(struct snd_ali * codec) | 1914 | static int __devinit snd_ali_mixer(struct snd_ali * codec) |
1955 | { | 1915 | { |
1956 | struct snd_ac97_template ac97; | 1916 | struct snd_ac97_template ac97; |
@@ -1961,19 +1921,20 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec) | |||
1961 | .read = snd_ali_codec_read, | 1921 | .read = snd_ali_codec_read, |
1962 | }; | 1922 | }; |
1963 | 1923 | ||
1964 | if ((err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus)) < 0) | 1924 | err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus); |
1925 | if (err < 0) | ||
1965 | return err; | 1926 | return err; |
1966 | codec->ac97_bus->private_free = snd_ali_mixer_free_ac97_bus; | ||
1967 | 1927 | ||
1968 | memset(&ac97, 0, sizeof(ac97)); | 1928 | memset(&ac97, 0, sizeof(ac97)); |
1969 | ac97.private_data = codec; | 1929 | ac97.private_data = codec; |
1970 | ac97.private_free = snd_ali_mixer_free_ac97; | ||
1971 | 1930 | ||
1972 | for ( i = 0 ; i < codec->num_of_codecs ; i++) { | 1931 | for (i = 0; i < codec->num_of_codecs; i++) { |
1973 | ac97.num = i; | 1932 | ac97.num = i; |
1974 | if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) { | 1933 | err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i]); |
1975 | snd_printk(KERN_ERR "ali mixer %d creating error.\n", i); | 1934 | if (err < 0) { |
1976 | if(i == 0) | 1935 | snd_printk(KERN_ERR |
1936 | "ali mixer %d creating error.\n", i); | ||
1937 | if (i == 0) | ||
1977 | return err; | 1938 | return err; |
1978 | codec->num_of_codecs = 1; | 1939 | codec->num_of_codecs = 1; |
1979 | break; | 1940 | break; |
@@ -1981,9 +1942,11 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec) | |||
1981 | } | 1942 | } |
1982 | 1943 | ||
1983 | if (codec->spdif_support) { | 1944 | if (codec->spdif_support) { |
1984 | for(idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) { | 1945 | for (idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) { |
1985 | err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec)); | 1946 | err = snd_ctl_add(codec->card, |
1986 | if (err < 0) return err; | 1947 | snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec)); |
1948 | if (err < 0) | ||
1949 | return err; | ||
1987 | } | 1950 | } |
1988 | } | 1951 | } |
1989 | return 0; | 1952 | return 0; |
@@ -1998,11 +1961,11 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) | |||
1998 | int i, j; | 1961 | int i, j; |
1999 | 1962 | ||
2000 | im = chip->image; | 1963 | im = chip->image; |
2001 | if (! im) | 1964 | if (!im) |
2002 | return 0; | 1965 | return 0; |
2003 | 1966 | ||
2004 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 1967 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
2005 | for(i = 0 ; i < chip->num_of_codecs ; i++) { | 1968 | for (i = 0; i < chip->num_of_codecs; i++) { |
2006 | snd_pcm_suspend_all(chip->pcm[i]); | 1969 | snd_pcm_suspend_all(chip->pcm[i]); |
2007 | snd_ac97_suspend(chip->ac97[i]); | 1970 | snd_ac97_suspend(chip->ac97[i]); |
2008 | } | 1971 | } |
@@ -2010,10 +1973,10 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) | |||
2010 | spin_lock_irq(&chip->reg_lock); | 1973 | spin_lock_irq(&chip->reg_lock); |
2011 | 1974 | ||
2012 | im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT)); | 1975 | im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT)); |
2013 | // im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); | 1976 | /* im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); */ |
2014 | im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP)); | 1977 | im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP)); |
2015 | 1978 | ||
2016 | // disable all IRQ bits | 1979 | /* disable all IRQ bits */ |
2017 | outl(0, ALI_REG(chip, ALI_MISCINT)); | 1980 | outl(0, ALI_REG(chip, ALI_MISCINT)); |
2018 | 1981 | ||
2019 | for (i = 0; i < ALI_GLOBAL_REGS; i++) { | 1982 | for (i = 0; i < ALI_GLOBAL_REGS; i++) { |
@@ -2028,7 +1991,7 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) | |||
2028 | im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0)); | 1991 | im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0)); |
2029 | } | 1992 | } |
2030 | 1993 | ||
2031 | // stop all HW channel | 1994 | /* stop all HW channel */ |
2032 | outl(0xffffffff, ALI_REG(chip, ALI_STOP)); | 1995 | outl(0xffffffff, ALI_REG(chip, ALI_STOP)); |
2033 | 1996 | ||
2034 | spin_unlock_irq(&chip->reg_lock); | 1997 | spin_unlock_irq(&chip->reg_lock); |
@@ -2047,7 +2010,7 @@ static int ali_resume(struct pci_dev *pci) | |||
2047 | int i, j; | 2010 | int i, j; |
2048 | 2011 | ||
2049 | im = chip->image; | 2012 | im = chip->image; |
2050 | if (! im) | 2013 | if (!im) |
2051 | return 0; | 2014 | return 0; |
2052 | 2015 | ||
2053 | pci_set_power_state(pci, PCI_D0); | 2016 | pci_set_power_state(pci, PCI_D0); |
@@ -2069,19 +2032,20 @@ static int ali_resume(struct pci_dev *pci) | |||
2069 | } | 2032 | } |
2070 | 2033 | ||
2071 | for (i = 0; i < ALI_GLOBAL_REGS; i++) { | 2034 | for (i = 0; i < ALI_GLOBAL_REGS; i++) { |
2072 | if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || (i*4 == ALI_START)) | 2035 | if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || |
2036 | (i*4 == ALI_START)) | ||
2073 | continue; | 2037 | continue; |
2074 | outl(im->regs[i], ALI_REG(chip, i*4)); | 2038 | outl(im->regs[i], ALI_REG(chip, i*4)); |
2075 | } | 2039 | } |
2076 | 2040 | ||
2077 | // start HW channel | 2041 | /* start HW channel */ |
2078 | outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START)); | 2042 | outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START)); |
2079 | // restore IRQ enable bits | 2043 | /* restore IRQ enable bits */ |
2080 | outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT)); | 2044 | outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT)); |
2081 | 2045 | ||
2082 | spin_unlock_irq(&chip->reg_lock); | 2046 | spin_unlock_irq(&chip->reg_lock); |
2083 | 2047 | ||
2084 | for(i = 0 ; i < chip->num_of_codecs ; i++) | 2048 | for (i = 0 ; i < chip->num_of_codecs; i++) |
2085 | snd_ac97_resume(chip->ac97[i]); | 2049 | snd_ac97_resume(chip->ac97[i]); |
2086 | 2050 | ||
2087 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 2051 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
@@ -2113,7 +2077,7 @@ static int snd_ali_chip_init(struct snd_ali *codec) | |||
2113 | { | 2077 | { |
2114 | unsigned int legacy; | 2078 | unsigned int legacy; |
2115 | unsigned char temp; | 2079 | unsigned char temp; |
2116 | struct pci_dev *pci_dev = NULL; | 2080 | struct pci_dev *pci_dev; |
2117 | 2081 | ||
2118 | snd_ali_printk("chip initializing ... \n"); | 2082 | snd_ali_printk("chip initializing ... \n"); |
2119 | 2083 | ||
@@ -2146,7 +2110,8 @@ static int snd_ali_chip_init(struct snd_ali *codec) | |||
2146 | outb(0x10, ALI_REG(codec, ALI_MPUR2)); | 2110 | outb(0x10, ALI_REG(codec, ALI_MPUR2)); |
2147 | 2111 | ||
2148 | codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID); | 2112 | codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID); |
2149 | codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_STATUS); | 2113 | codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, |
2114 | AC97_EXTENDED_STATUS); | ||
2150 | if (codec->spdif_support) { | 2115 | if (codec->spdif_support) { |
2151 | snd_ali_enable_spdif_out(codec); | 2116 | snd_ali_enable_spdif_out(codec); |
2152 | codec->spdif_mask = 0x00000002; | 2117 | codec->spdif_mask = 0x00000002; |
@@ -2158,8 +2123,9 @@ static int snd_ali_chip_init(struct snd_ali *codec) | |||
2158 | if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) { | 2123 | if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) { |
2159 | codec->num_of_codecs++; | 2124 | codec->num_of_codecs++; |
2160 | outl(inl(ALI_REG(codec, ALI_SCTRL)) | | 2125 | outl(inl(ALI_REG(codec, ALI_SCTRL)) | |
2161 | (ALI_SCTRL_LINE_IN2|ALI_SCTRL_GPIO_IN2|ALI_SCTRL_LINE_OUT_EN), | 2126 | (ALI_SCTRL_LINE_IN2 | ALI_SCTRL_GPIO_IN2 | |
2162 | ALI_REG(codec, ALI_SCTRL)); | 2127 | ALI_SCTRL_LINE_OUT_EN), |
2128 | ALI_REG(codec, ALI_SCTRL)); | ||
2163 | } | 2129 | } |
2164 | 2130 | ||
2165 | snd_ali_printk("chip initialize succeed.\n"); | 2131 | snd_ali_printk("chip initialize succeed.\n"); |
@@ -2168,18 +2134,19 @@ static int snd_ali_chip_init(struct snd_ali *codec) | |||
2168 | } | 2134 | } |
2169 | 2135 | ||
2170 | /* proc for register dump */ | 2136 | /* proc for register dump */ |
2171 | static void snd_ali_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buf) | 2137 | static void snd_ali_proc_read(struct snd_info_entry *entry, |
2138 | struct snd_info_buffer *buf) | ||
2172 | { | 2139 | { |
2173 | struct snd_ali *codec = entry->private_data; | 2140 | struct snd_ali *codec = entry->private_data; |
2174 | int i; | 2141 | int i; |
2175 | for(i = 0 ; i < 256 ; i+= 4) | 2142 | for (i = 0; i < 256 ; i+= 4) |
2176 | snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i))); | 2143 | snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i))); |
2177 | } | 2144 | } |
2178 | 2145 | ||
2179 | static void __devinit snd_ali_proc_init(struct snd_ali *codec) | 2146 | static void __devinit snd_ali_proc_init(struct snd_ali *codec) |
2180 | { | 2147 | { |
2181 | struct snd_info_entry *entry; | 2148 | struct snd_info_entry *entry; |
2182 | if(!snd_card_proc_new(codec->card, "ali5451", &entry)) | 2149 | if (!snd_card_proc_new(codec->card, "ali5451", &entry)) |
2183 | snd_info_set_text_ops(entry, codec, snd_ali_proc_read); | 2150 | snd_info_set_text_ops(entry, codec, snd_ali_proc_read); |
2184 | } | 2151 | } |
2185 | 2152 | ||
@@ -2188,7 +2155,8 @@ static int __devinit snd_ali_resources(struct snd_ali *codec) | |||
2188 | int err; | 2155 | int err; |
2189 | 2156 | ||
2190 | snd_ali_printk("resouces allocation ...\n"); | 2157 | snd_ali_printk("resouces allocation ...\n"); |
2191 | if ((err = pci_request_regions(codec->pci, "ALI 5451")) < 0) | 2158 | err = pci_request_regions(codec->pci, "ALI 5451"); |
2159 | if (err < 0) | ||
2192 | return err; | 2160 | return err; |
2193 | codec->port = pci_resource_start(codec->pci, 0); | 2161 | codec->port = pci_resource_start(codec->pci, 0); |
2194 | 2162 | ||
@@ -2201,9 +2169,9 @@ static int __devinit snd_ali_resources(struct snd_ali *codec) | |||
2201 | snd_ali_printk("resouces allocated.\n"); | 2169 | snd_ali_printk("resouces allocated.\n"); |
2202 | return 0; | 2170 | return 0; |
2203 | } | 2171 | } |
2204 | static int snd_ali_dev_free(struct snd_device *device) | 2172 | static int snd_ali_dev_free(struct snd_device *device) |
2205 | { | 2173 | { |
2206 | struct snd_ali *codec=device->device_data; | 2174 | struct snd_ali *codec = device->device_data; |
2207 | snd_ali_free(codec); | 2175 | snd_ali_free(codec); |
2208 | return 0; | 2176 | return 0; |
2209 | } | 2177 | } |
@@ -2226,17 +2194,20 @@ static int __devinit snd_ali_create(struct snd_card *card, | |||
2226 | snd_ali_printk("creating ...\n"); | 2194 | snd_ali_printk("creating ...\n"); |
2227 | 2195 | ||
2228 | /* enable PCI device */ | 2196 | /* enable PCI device */ |
2229 | if ((err = pci_enable_device(pci)) < 0) | 2197 | err = pci_enable_device(pci); |
2198 | if (err < 0) | ||
2230 | return err; | 2199 | return err; |
2231 | /* check, if we can restrict PCI DMA transfers to 31 bits */ | 2200 | /* check, if we can restrict PCI DMA transfers to 31 bits */ |
2232 | if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 || | 2201 | if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 || |
2233 | pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) { | 2202 | pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) { |
2234 | snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n"); | 2203 | snd_printk(KERN_ERR "architecture does not support " |
2204 | "31bit PCI busmaster DMA\n"); | ||
2235 | pci_disable_device(pci); | 2205 | pci_disable_device(pci); |
2236 | return -ENXIO; | 2206 | return -ENXIO; |
2237 | } | 2207 | } |
2238 | 2208 | ||
2239 | if ((codec = kzalloc(sizeof(*codec), GFP_KERNEL)) == NULL) { | 2209 | codec = kzalloc(sizeof(*codec), GFP_KERNEL); |
2210 | if (!codec) { | ||
2240 | pci_disable_device(pci); | 2211 | pci_disable_device(pci); |
2241 | return -ENOMEM; | 2212 | return -ENOMEM; |
2242 | } | 2213 | } |
@@ -2293,21 +2264,22 @@ static int __devinit snd_ali_create(struct snd_card *card, | |||
2293 | 2264 | ||
2294 | /* M1533: southbridge */ | 2265 | /* M1533: southbridge */ |
2295 | codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL); | 2266 | codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL); |
2296 | if (! codec->pci_m1533) { | 2267 | if (!codec->pci_m1533) { |
2297 | snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n"); | 2268 | snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n"); |
2298 | snd_ali_free(codec); | 2269 | snd_ali_free(codec); |
2299 | return -ENODEV; | 2270 | return -ENODEV; |
2300 | } | 2271 | } |
2301 | /* M7101: power management */ | 2272 | /* M7101: power management */ |
2302 | codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL); | 2273 | codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL); |
2303 | if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) { | 2274 | if (!codec->pci_m7101 && codec->revision == ALI_5451_V02) { |
2304 | snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n"); | 2275 | snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n"); |
2305 | snd_ali_free(codec); | 2276 | snd_ali_free(codec); |
2306 | return -ENODEV; | 2277 | return -ENODEV; |
2307 | } | 2278 | } |
2308 | 2279 | ||
2309 | snd_ali_printk("snd_device_new is called.\n"); | 2280 | snd_ali_printk("snd_device_new is called.\n"); |
2310 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) { | 2281 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops); |
2282 | if (err < 0) { | ||
2311 | snd_ali_free(codec); | 2283 | snd_ali_free(codec); |
2312 | return err; | 2284 | return err; |
2313 | } | 2285 | } |
@@ -2315,18 +2287,18 @@ static int __devinit snd_ali_create(struct snd_card *card, | |||
2315 | snd_card_set_dev(card, &pci->dev); | 2287 | snd_card_set_dev(card, &pci->dev); |
2316 | 2288 | ||
2317 | /* initialise synth voices*/ | 2289 | /* initialise synth voices*/ |
2318 | for (i = 0; i < ALI_CHANNELS; i++ ) { | 2290 | for (i = 0; i < ALI_CHANNELS; i++) |
2319 | codec->synth.voices[i].number = i; | 2291 | codec->synth.voices[i].number = i; |
2320 | } | ||
2321 | 2292 | ||
2322 | if ((err = snd_ali_chip_init(codec)) < 0) { | 2293 | err = snd_ali_chip_init(codec); |
2294 | if (err < 0) { | ||
2323 | snd_printk(KERN_ERR "ali create: chip init error.\n"); | 2295 | snd_printk(KERN_ERR "ali create: chip init error.\n"); |
2324 | return err; | 2296 | return err; |
2325 | } | 2297 | } |
2326 | 2298 | ||
2327 | #ifdef CONFIG_PM | 2299 | #ifdef CONFIG_PM |
2328 | codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL); | 2300 | codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL); |
2329 | if (! codec->image) | 2301 | if (!codec->image) |
2330 | snd_printk(KERN_WARNING "can't allocate apm buffer\n"); | 2302 | snd_printk(KERN_WARNING "can't allocate apm buffer\n"); |
2331 | #endif | 2303 | #endif |
2332 | 2304 | ||
@@ -2348,26 +2320,23 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, | |||
2348 | snd_ali_printk("probe ...\n"); | 2320 | snd_ali_printk("probe ...\n"); |
2349 | 2321 | ||
2350 | card = snd_card_new(index, id, THIS_MODULE, 0); | 2322 | card = snd_card_new(index, id, THIS_MODULE, 0); |
2351 | if (card == NULL) | 2323 | if (!card) |
2352 | return -ENOMEM; | 2324 | return -ENOMEM; |
2353 | 2325 | ||
2354 | if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) { | 2326 | err = snd_ali_create(card, pci, pcm_channels, spdif, &codec); |
2355 | snd_card_free(card); | 2327 | if (err < 0) |
2356 | return err; | 2328 | goto error; |
2357 | } | ||
2358 | card->private_data = codec; | 2329 | card->private_data = codec; |
2359 | 2330 | ||
2360 | snd_ali_printk("mixer building ...\n"); | 2331 | snd_ali_printk("mixer building ...\n"); |
2361 | if ((err = snd_ali_mixer(codec)) < 0) { | 2332 | err = snd_ali_mixer(codec); |
2362 | snd_card_free(card); | 2333 | if (err < 0) |
2363 | return err; | 2334 | goto error; |
2364 | } | ||
2365 | 2335 | ||
2366 | snd_ali_printk("pcm building ...\n"); | 2336 | snd_ali_printk("pcm building ...\n"); |
2367 | if ((err = snd_ali_build_pcms(codec)) < 0) { | 2337 | err = snd_ali_build_pcms(codec); |
2368 | snd_card_free(card); | 2338 | if (err < 0) |
2369 | return err; | 2339 | goto error; |
2370 | } | ||
2371 | 2340 | ||
2372 | snd_ali_proc_init(codec); | 2341 | snd_ali_proc_init(codec); |
2373 | 2342 | ||
@@ -2378,12 +2347,16 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, | |||
2378 | card->shortname, codec->port, codec->irq); | 2347 | card->shortname, codec->port, codec->irq); |
2379 | 2348 | ||
2380 | snd_ali_printk("register card.\n"); | 2349 | snd_ali_printk("register card.\n"); |
2381 | if ((err = snd_card_register(card)) < 0) { | 2350 | err = snd_card_register(card); |
2382 | snd_card_free(card); | 2351 | if (err < 0) |
2383 | return err; | 2352 | goto error; |
2384 | } | 2353 | |
2385 | pci_set_drvdata(pci, card); | 2354 | pci_set_drvdata(pci, card); |
2386 | return 0; | 2355 | return 0; |
2356 | |||
2357 | error: | ||
2358 | snd_card_free(card); | ||
2359 | return err; | ||
2387 | } | 2360 | } |
2388 | 2361 | ||
2389 | static void __devexit snd_ali_remove(struct pci_dev *pci) | 2362 | static void __devexit snd_ali_remove(struct pci_dev *pci) |
diff --git a/sound/pci/au88x0/au88x0_sb.h b/sound/pci/au88x0/au88x0_sb.h deleted file mode 100644 index 5a4d8fc2bbfc..000000000000 --- a/sound/pci/au88x0/au88x0_sb.h +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * au88x0_sb.h | ||
3 | * | ||
4 | * Wed Oct 29 22:10:42 2003 | ||
5 | * | ||
6 | ****************************************************************************/ | ||
7 | |||
8 | #ifdef CHIP_AU8820 | ||
9 | /* AU8820 starting @ 64KiB offset */ | ||
10 | #define SBEMU_BASE 0x10000 | ||
11 | #else | ||
12 | /* AU8810? and AU8830 starting @ 164KiB offset */ | ||
13 | #define SBEMU_BASE 0x29000 | ||
14 | #endif | ||
15 | |||
16 | #define FM_A_STATUS (SBEMU_BASE + 0x00) /* read */ | ||
17 | #define FM_A_ADDRESS (SBEMU_BASE + 0x00) /* write */ | ||
18 | #define FM_A_DATA (SBEMU_BASE + 0x04) | ||
19 | #define FM_B_STATUS (SBEMU_BASE + 0x08) | ||
20 | #define FM_B_ADDRESS (SBEMU_BASE + 0x08) | ||
21 | #define FM_B_DATA (SBEMU_BASE + 0x0C) | ||
22 | #define SB_MIXER_ADDR (SBEMU_BASE + 0x10) | ||
23 | #define SB_MIXER_DATA (SBEMU_BASE + 0x14) | ||
24 | #define SB_RESET (SBEMU_BASE + 0x18) | ||
25 | #define SB_RESET_ALIAS (SBEMU_BASE + 0x1C) | ||
26 | #define FM_STATUS2 (SBEMU_BASE + 0x20) | ||
27 | #define FM_ADDR2 (SBEMU_BASE + 0x20) | ||
28 | #define FM_DATA2 (SBEMU_BASE + 0x24) | ||
29 | #define SB_DSP_READ (SBEMU_BASE + 0x28) | ||
30 | #define SB_DSP_WRITE (SBEMU_BASE + 0x30) | ||
31 | #define SB_DSP_WRITE_STATUS (SBEMU_BASE + 0x30) /* bit 7 */ | ||
32 | #define SB_DSP_READ_STATUS (SBEMU_BASE + 0x38) /* bit 7 */ | ||
33 | #define SB_LACR (SBEMU_BASE + 0x40) /* ? */ | ||
34 | #define SB_LADCR (SBEMU_BASE + 0x44) /* ? */ | ||
35 | #define SB_LAMR (SBEMU_BASE + 0x48) /* ? */ | ||
36 | #define SB_LARR (SBEMU_BASE + 0x4C) /* ? */ | ||
37 | #define SB_VERSION (SBEMU_BASE + 0x50) | ||
38 | #define SB_CTRLSTAT (SBEMU_BASE + 0x54) | ||
39 | #define SB_TIMERSTAT (SBEMU_BASE + 0x58) | ||
40 | #define FM_RAM (SBEMU_BASE + 0x100) /* 0x40 ULONG */ | ||
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 43edd2839b5a..36d3666a5b77 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). | 2 | * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). |
3 | * Copyright (C) 2002, 2005 by Andreas Mohr <andi AT lisas.de> | 3 | * Copyright (C) 2002, 2005, 2006, 2007 by Andreas Mohr <andi AT lisas.de> |
4 | * | 4 | * |
5 | * Framework borrowed from Bart Hartgers's als4000.c. | 5 | * Framework borrowed from Bart Hartgers's als4000.c. |
6 | * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), | 6 | * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), |
@@ -52,6 +52,9 @@ | |||
52 | * - full duplex 16bit playback/record at independent sampling rate | 52 | * - full duplex 16bit playback/record at independent sampling rate |
53 | * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr?? | 53 | * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr?? |
54 | * - game port (legacy address support) | 54 | * - game port (legacy address support) |
55 | * - builtin 3D enhancement (said to be YAMAHA Ymersion) | ||
56 | * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven | ||
57 | * features supported) | ||
55 | * - built-in General DirectX timer having a 20 bits counter | 58 | * - built-in General DirectX timer having a 20 bits counter |
56 | * with 1us resolution (see below!) | 59 | * with 1us resolution (see below!) |
57 | * - I2S serial port for external DAC | 60 | * - I2S serial port for external DAC |
@@ -94,6 +97,10 @@ | |||
94 | * | 97 | * |
95 | * BUGS | 98 | * BUGS |
96 | * - full-duplex might *still* be problematic, not fully tested recently | 99 | * - full-duplex might *still* be problematic, not fully tested recently |
100 | * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated | ||
101 | * if you set PCM output switch to "pre 3D" instead of "post 3D". | ||
102 | * If this can't be set, then get a mixer application that Isn't Stupid (tm) | ||
103 | * (e.g. kmix, gamix) - unfortunately several are!! | ||
97 | * | 104 | * |
98 | * TODO | 105 | * TODO |
99 | * - test MPU401 MIDI playback etc. | 106 | * - test MPU401 MIDI playback etc. |
@@ -622,7 +629,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol, | |||
622 | return (nreg != oreg); | 629 | return (nreg != oreg); |
623 | } | 630 | } |
624 | 631 | ||
625 | static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = { | 632 | static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = { |
626 | AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1), | 633 | AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1), |
627 | AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1), | 634 | AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1), |
628 | AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1), | 635 | AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1), |
@@ -652,7 +659,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata | |||
652 | AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1), | 659 | AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1), |
653 | AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8), | 660 | AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8), |
654 | AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9), | 661 | AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9), |
655 | AZF3328_MIXER_ENUM("PCM", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */ | 662 | AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */ |
656 | AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0), | 663 | AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0), |
657 | AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0), | 664 | AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0), |
658 | AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0), | 665 | AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0), |
@@ -678,7 +685,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata | |||
678 | #endif | 685 | #endif |
679 | }; | 686 | }; |
680 | 687 | ||
681 | static const u16 __devinitdata snd_azf3328_init_values[][2] = { | 688 | static u16 __devinitdata snd_azf3328_init_values[][2] = { |
682 | { IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f }, | 689 | { IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f }, |
683 | { IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f }, | 690 | { IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f }, |
684 | { IDX_MIXER_BASSTREBLE, 0x0000 }, | 691 | { IDX_MIXER_BASSTREBLE, 0x0000 }, |
@@ -1369,7 +1376,6 @@ snd_azf3328_playback_close(struct snd_pcm_substream *substream) | |||
1369 | struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); | 1376 | struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); |
1370 | 1377 | ||
1371 | snd_azf3328_dbgcallenter(); | 1378 | snd_azf3328_dbgcallenter(); |
1372 | |||
1373 | chip->playback_substream = NULL; | 1379 | chip->playback_substream = NULL; |
1374 | snd_azf3328_dbgcallleave(); | 1380 | snd_azf3328_dbgcallleave(); |
1375 | return 0; | 1381 | return 0; |
@@ -1660,10 +1666,10 @@ snd_azf3328_test_bit(unsigned int reg, int bit) | |||
1660 | } | 1666 | } |
1661 | #endif | 1667 | #endif |
1662 | 1668 | ||
1669 | #if DEBUG_MISC | ||
1663 | static void | 1670 | static void |
1664 | snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) | 1671 | snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) |
1665 | { | 1672 | { |
1666 | #if DEBUG_MISC | ||
1667 | u16 tmp; | 1673 | u16 tmp; |
1668 | 1674 | ||
1669 | snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq); | 1675 | snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq); |
@@ -1673,10 +1679,16 @@ snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) | |||
1673 | for (tmp=0; tmp <= 0x01; tmp += 1) | 1679 | for (tmp=0; tmp <= 0x01; tmp += 1) |
1674 | snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp)); | 1680 | snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp)); |
1675 | 1681 | ||
1676 | for (tmp = 0; tmp <= 0x6E; tmp += 2) | 1682 | for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2) |
1677 | snd_azf3328_dbgmisc("0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inb(chip, tmp)); | 1683 | snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp)); |
1678 | #endif | 1684 | |
1685 | for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2) | ||
1686 | snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp)); | ||
1679 | } | 1687 | } |
1688 | #else | ||
1689 | static inline void | ||
1690 | snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {} | ||
1691 | #endif | ||
1680 | 1692 | ||
1681 | static int __devinit | 1693 | static int __devinit |
1682 | snd_azf3328_create(struct snd_card *card, | 1694 | snd_azf3328_create(struct snd_card *card, |
@@ -1842,8 +1854,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
1842 | 1854 | ||
1843 | #ifdef MODULE | 1855 | #ifdef MODULE |
1844 | printk( | 1856 | printk( |
1845 | "azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168\n" | 1857 | "azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n" |
1846 | "azt3328: (hardware was completely undocumented - ZERO support from Aztech).\n" | 1858 | "azt3328: Hardware was completely undocumented, unfortunately.\n" |
1847 | "azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n" | 1859 | "azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n" |
1848 | "azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n", | 1860 | "azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n", |
1849 | 1024000 / seqtimer_scaling, seqtimer_scaling); | 1861 | 1024000 / seqtimer_scaling, seqtimer_scaling); |
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h index b4f3e3cd006b..679fa992e2bc 100644 --- a/sound/pci/azt3328.h +++ b/sound/pci/azt3328.h | |||
@@ -106,8 +106,8 @@ | |||
106 | #define IRQ_RECORDING 0x0002 | 106 | #define IRQ_RECORDING 0x0002 |
107 | #define IRQ_MPU401 0x0010 | 107 | #define IRQ_MPU401 0x0010 |
108 | #define IRQ_TIMER 0x0020 /* DirectX timer */ | 108 | #define IRQ_TIMER 0x0020 /* DirectX timer */ |
109 | #define IRQ_UNKNOWN1 0x0040 /* probably unused */ | 109 | #define IRQ_UNKNOWN1 0x0040 /* probably unused, or possibly I2S port? or gameport IRQ? */ |
110 | #define IRQ_UNKNOWN2 0x0080 /* probably unused */ | 110 | #define IRQ_UNKNOWN2 0x0080 /* probably unused, or possibly I2S port? or gameport IRQ? */ |
111 | #define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ | 111 | #define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ |
112 | #define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */ | 112 | #define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */ |
113 | #define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */ | 113 | #define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */ |
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index e9b029e1cd6d..6523ba07db96 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c | |||
@@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_ids[] = { | |||
781 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), | 781 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), |
782 | /* Viewcast Osprey 200 */ | 782 | /* Viewcast Osprey 200 */ |
783 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), | 783 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), |
784 | /* ATI TV-Wonder */ | ||
785 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000), | ||
784 | /* Leadtek Winfast tv 2000xp delux */ | 786 | /* Leadtek Winfast tv 2000xp delux */ |
785 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000), | 787 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000), |
786 | /* Voodoo TV 200 */ | 788 | /* Voodoo TV 200 */ |
@@ -833,7 +835,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) | |||
833 | pci->device, pci->subsystem_vendor, pci->subsystem_device); | 835 | pci->device, pci->subsystem_vendor, pci->subsystem_device); |
834 | snd_printk(KERN_DEBUG "please mail id, board name, and, " | 836 | snd_printk(KERN_DEBUG "please mail id, board name, and, " |
835 | "if it works, the correct digital_rate option to " | 837 | "if it works, the correct digital_rate option to " |
836 | "<alsa-devel@lists.sf.net>\n"); | 838 | "<alsa-devel@alsa-project.org>\n"); |
837 | return 32000; /* default rate */ | 839 | return 32000; /* default rate */ |
838 | } | 840 | } |
839 | 841 | ||
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index ea6712b63c9f..48f3f17c5170 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -775,7 +775,6 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream, | |||
775 | struct snd_ca0106_pcm *epcm; | 775 | struct snd_ca0106_pcm *epcm; |
776 | int channel; | 776 | int channel; |
777 | int result = 0; | 777 | int result = 0; |
778 | struct list_head *pos; | ||
779 | struct snd_pcm_substream *s; | 778 | struct snd_pcm_substream *s; |
780 | u32 basic = 0; | 779 | u32 basic = 0; |
781 | u32 extended = 0; | 780 | u32 extended = 0; |
@@ -790,8 +789,7 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream, | |||
790 | running=0; | 789 | running=0; |
791 | break; | 790 | break; |
792 | } | 791 | } |
793 | snd_pcm_group_for_each(pos, substream) { | 792 | snd_pcm_group_for_each_entry(s, substream) { |
794 | s = snd_pcm_group_substream_entry(pos); | ||
795 | runtime = s->runtime; | 793 | runtime = s->runtime; |
796 | epcm = runtime->private_data; | 794 | epcm = runtime->private_data; |
797 | channel = epcm->channel_id; | 795 | channel = epcm->channel_id; |
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 2ae539b195fd..bef1f6d1859c 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c | |||
@@ -3107,7 +3107,7 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) | |||
3107 | snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n"); | 3107 | snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n"); |
3108 | snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n"); | 3108 | snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n"); |
3109 | snd_printk(KERN_ERR " broken or not working on your soundcard upon\n"); | 3109 | snd_printk(KERN_ERR " broken or not working on your soundcard upon\n"); |
3110 | snd_printk(KERN_ERR " this message please report to alsa-devel@lists.sourceforge.net\n"); | 3110 | snd_printk(KERN_ERR " this message please report to alsa-devel@alsa-project.org\n"); |
3111 | 3111 | ||
3112 | return -EIO; | 3112 | return -EIO; |
3113 | #endif | 3113 | #endif |
diff --git a/sound/pci/cs46xx/imgs/cwcemb80.h b/sound/pci/cs46xx/imgs/cwcemb80.h deleted file mode 100644 index a64c6ff9983a..000000000000 --- a/sound/pci/cs46xx/imgs/cwcemb80.h +++ /dev/null | |||
@@ -1,1607 +0,0 @@ | |||
1 | /* generated from cwcemb80.osp DO NOT MODIFY */ | ||
2 | |||
3 | #ifndef __HEADER_cwcemb80_H__ | ||
4 | #define __HEADER_cwcemb80_H__ | ||
5 | |||
6 | static struct dsp_symbol_entry cwcemb80_symbols[] = { | ||
7 | { 0x0000, "BEGINADDRESS",0x00 }, | ||
8 | { 0x8000, "EXECCHILD",0x03 }, | ||
9 | { 0x8001, "EXECCHILD_98",0x03 }, | ||
10 | { 0x8003, "EXECCHILD_PUSH1IND",0x03 }, | ||
11 | { 0x8008, "EXECSIBLING",0x03 }, | ||
12 | { 0x800a, "EXECSIBLING_298",0x03 }, | ||
13 | { 0x800b, "EXECSIBLING_2IND1",0x03 }, | ||
14 | { 0x8010, "TIMINGMASTER",0x03 }, | ||
15 | { 0x804f, "S16_CODECINPUTTASK",0x03 }, | ||
16 | { 0x805e, "PCMSERIALINPUTTASK",0x03 }, | ||
17 | { 0x806d, "S16_MIX_TO_OSTREAM",0x03 }, | ||
18 | { 0x809a, "S16_MIX",0x03 }, | ||
19 | { 0x80bb, "S16_UPSRC",0x03 }, | ||
20 | { 0x813b, "MIX3_EXP",0x03 }, | ||
21 | { 0x8164, "DECIMATEBYPOW2",0x03 }, | ||
22 | { 0x8197, "VARIDECIMATE",0x03 }, | ||
23 | { 0x81f2, "_3DINPUTTASK",0x03 }, | ||
24 | { 0x820a, "_3DPRLGCINPTASK",0x03 }, | ||
25 | { 0x8227, "_3DSTEREOINPUTTASK",0x03 }, | ||
26 | { 0x8242, "_3DOUTPUTTASK",0x03 }, | ||
27 | { 0x82c4, "HRTF_MORPH_TASK",0x03 }, | ||
28 | { 0x82c6, "WAIT4DATA",0x03 }, | ||
29 | { 0x82fa, "PROLOGIC",0x03 }, | ||
30 | { 0x8496, "DECORRELATOR",0x03 }, | ||
31 | { 0x84a4, "STEREO2MONO",0x03 }, | ||
32 | { 0x0070, "SPOSCB",0x02 }, | ||
33 | { 0x0105, "TASKTREETHREAD",0x03 }, | ||
34 | { 0x0136, "TASKTREEHEADERCODE",0x03 }, | ||
35 | { 0x013f, "FGTASKTREEHEADERCODE",0x03 }, | ||
36 | { 0x0163, "NULLALGORITHM",0x03 }, | ||
37 | { 0x0167, "HFGEXECCHILD",0x03 }, | ||
38 | { 0x0168, "HFGEXECCHILD_98",0x03 }, | ||
39 | { 0x016a, "HFGEXECCHILD_PUSH1IND",0x03 }, | ||
40 | { 0x016d, "HFGEXECSIBLING",0x03 }, | ||
41 | { 0x016f, "HFGEXECSIBLING_298",0x03 }, | ||
42 | { 0x0170, "HFGEXECSIBLING_2IND1",0x03 }, | ||
43 | { 0x0173, "S16_CODECOUTPUTTASK",0x03 }, | ||
44 | { 0x018e, "#CODE_END",0x00 }, | ||
45 | }; /* cwcemb80 symbols */ | ||
46 | |||
47 | static u32 cwcemb80_code[] = { | ||
48 | /* BEGINADDRESS */ | ||
49 | /* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003, | ||
50 | /* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003, | ||
51 | /* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003, | ||
52 | /* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003, | ||
53 | /* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003, | ||
54 | /* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003, | ||
55 | /* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003, | ||
56 | /* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003, | ||
57 | /* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003, | ||
58 | /* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003, | ||
59 | /* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003, | ||
60 | /* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003, | ||
61 | /* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003, | ||
62 | /* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003, | ||
63 | /* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003, | ||
64 | /* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003, | ||
65 | /* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003, | ||
66 | /* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040, | ||
67 | /* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, | ||
68 | /* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003, | ||
69 | /* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, | ||
70 | /* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003, | ||
71 | /* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003, | ||
72 | /* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003, | ||
73 | /* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, | ||
74 | /* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003, | ||
75 | /* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, | ||
76 | /* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003, | ||
77 | /* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, | ||
78 | /* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003, | ||
79 | /* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003, | ||
80 | /* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003, | ||
81 | /* 0040 */ 0x0000a730,0x00001008,0x000e2730,0x00001002, | ||
82 | /* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, | ||
83 | /* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, | ||
84 | /* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, | ||
85 | /* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003, | ||
86 | /* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000, | ||
87 | /* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
88 | /* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
89 | /* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000, | ||
90 | /* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000, | ||
91 | /* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000, | ||
92 | /* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000, | ||
93 | /* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
94 | /* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000, | ||
95 | /* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003, | ||
96 | /* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003, | ||
97 | /* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000, | ||
98 | /* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000, | ||
99 | /* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
100 | /* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003, | ||
101 | /* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000, | ||
102 | /* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000, | ||
103 | /* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
104 | /* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000, | ||
105 | /* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000, | ||
106 | /* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140, | ||
107 | /* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040, | ||
108 | /* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0, | ||
109 | /* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40, | ||
110 | /* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00, | ||
111 | /* 007C */ 0x0000002e,0x0009d6c0,0x00038630,0x00001004, | ||
112 | /* 007E */ 0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000, | ||
113 | /* 0080 */ 0x00000000,0x000c70e0,0x0007d182,0x0002c640, | ||
114 | /* 0082 */ 0x00000630,0x00001004,0x000799b8,0x0002c6c0, | ||
115 | /* 0084 */ 0x00031705,0x00092240,0x00039f05,0x000932c0, | ||
116 | /* 0086 */ 0x0003520a,0x00000000,0x00040731,0x0000100b, | ||
117 | /* 0088 */ 0x00010705,0x000b20c0,0x00000000,0x000eba44, | ||
118 | /* 008A */ 0x00032108,0x000c60c4,0x00065208,0x000c2917, | ||
119 | /* 008C */ 0x000406b0,0x00001007,0x00012f05,0x00036880, | ||
120 | /* 008E */ 0x0002818e,0x000c0000,0x0004410a,0x00000000, | ||
121 | /* 0090 */ 0x00040630,0x00001007,0x00029705,0x000c0000, | ||
122 | /* 0092 */ 0x00000000,0x00000000,0x00003fc1,0x0003fc40, | ||
123 | /* 0094 */ 0x000037c1,0x00091b40,0x00003fc1,0x000911c0, | ||
124 | /* 0096 */ 0x000037c1,0x000957c0,0x00003fc1,0x000951c0, | ||
125 | /* 0098 */ 0x000037c1,0x00000000,0x00003fc1,0x000991c0, | ||
126 | /* 009A */ 0x000037c1,0x00000000,0x00003fc1,0x0009d1c0, | ||
127 | /* 009C */ 0x000037c1,0x00000000,0x0001ccc1,0x000915c0, | ||
128 | /* 009E */ 0x0001c441,0x0009d800,0x0009cdc1,0x00091240, | ||
129 | /* 00A0 */ 0x0001c541,0x00091d00,0x0009cfc1,0x00095240, | ||
130 | /* 00A2 */ 0x0001c741,0x00095c80,0x000e8ca9,0x00099240, | ||
131 | /* 00A4 */ 0x000e85ad,0x00095640,0x00069ca9,0x00099d80, | ||
132 | /* 00A6 */ 0x000e952d,0x00099640,0x000eaca9,0x0009d6c0, | ||
133 | /* 00A8 */ 0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80, | ||
134 | /* 00AA */ 0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0, | ||
135 | /* 00AC */ 0x000ec5ad,0x0009da40,0x000edca9,0x0009d300, | ||
136 | /* 00AE */ 0x000a6e0a,0x00001000,0x000ed52d,0x00091e40, | ||
137 | /* 00B0 */ 0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40, | ||
138 | /* 00B2 */ 0x0006fca9,0x00002500,0x000fb208,0x000c59a0, | ||
139 | /* 00B4 */ 0x000ef52d,0x0009de40,0x00068ca9,0x000912c1, | ||
140 | /* 00B6 */ 0x000683ad,0x00095241,0x00020f05,0x000991c1, | ||
141 | /* 00B8 */ 0x00000000,0x00000000,0x00086f88,0x00001000, | ||
142 | /* 00BA */ 0x0009cf81,0x000b5340,0x0009c701,0x000b92c0, | ||
143 | /* 00BC */ 0x0009de81,0x000bd300,0x0009d601,0x000b1700, | ||
144 | /* 00BE */ 0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0, | ||
145 | /* 00C0 */ 0x000a0f81,0x000bd740,0x00020701,0x000b5c80, | ||
146 | /* 00C2 */ 0x000a1681,0x000b97c0,0x00021601,0x00002500, | ||
147 | /* 00C4 */ 0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0, | ||
148 | /* 00C6 */ 0x00021681,0x00002d00,0x00020f81,0x000bd800, | ||
149 | /* 00C8 */ 0x000a0701,0x000b5bc0,0x00021601,0x00003500, | ||
150 | /* 00CA */ 0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0, | ||
151 | /* 00CC */ 0x00021681,0x00003d00,0x00020f81,0x000b1d00, | ||
152 | /* 00CE */ 0x000a0701,0x000b1fc0,0x00021601,0x00020500, | ||
153 | /* 00D0 */ 0x00020f81,0x000b1341,0x000a0701,0x000b9fc0, | ||
154 | /* 00D2 */ 0x00021681,0x00020d00,0x00020f81,0x000bde80, | ||
155 | /* 00D4 */ 0x000a0701,0x000bdfc0,0x00021601,0x00021500, | ||
156 | /* 00D6 */ 0x00020f81,0x000b9341,0x00020701,0x000b53c1, | ||
157 | /* 00D8 */ 0x00021681,0x00021d00,0x000a0f81,0x000d0380, | ||
158 | /* 00DA */ 0x0000b601,0x000b15c0,0x00007b01,0x00000000, | ||
159 | /* 00DC */ 0x00007b81,0x000bd1c0,0x00007b01,0x00000000, | ||
160 | /* 00DE */ 0x00007b81,0x000b91c0,0x00007b01,0x000b57c0, | ||
161 | /* 00E0 */ 0x00007b81,0x000b51c0,0x00007b01,0x000b1b40, | ||
162 | /* 00E2 */ 0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0, | ||
163 | /* 00E4 */ 0x0007e488,0x000d7e45,0x00000000,0x000d7a44, | ||
164 | /* 00E6 */ 0x0007e48a,0x00000000,0x00011f05,0x00084080, | ||
165 | /* 00E8 */ 0x00000000,0x00000000,0x00001705,0x000b3540, | ||
166 | /* 00EA */ 0x00008a01,0x000bf040,0x00007081,0x000bb5c0, | ||
167 | /* 00EC */ 0x00055488,0x00000000,0x0000d482,0x0003fc40, | ||
168 | /* 00EE */ 0x0003fc88,0x00000000,0x0001e401,0x000b3a00, | ||
169 | /* 00F0 */ 0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784, | ||
170 | /* 00F2 */ 0x000c86b0,0x00001007,0x00008281,0x000bb240, | ||
171 | /* 00F4 */ 0x0000b801,0x000b7140,0x00007888,0x00000000, | ||
172 | /* 00F6 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000, | ||
173 | /* 00F8 */ 0x00000000,0x00000000,0x00055288,0x000c555c, | ||
174 | /* 00FA */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00, | ||
175 | /* 00FC */ 0x0000fa88,0x00000000,0x00000032,0x00001000, | ||
176 | /* 00FE */ 0x0000073d,0x00001000,0x0007f188,0x000c0000, | ||
177 | /* 0100 */ 0x00000000,0x00000000,0x0008c01c,0x00001003, | ||
178 | /* 0102 */ 0x00002705,0x00001008,0x0008b201,0x000c1392, | ||
179 | /* 0104 */ 0x0000ba01,0x00000000, | ||
180 | /* TASKTREETHREAD */ | ||
181 | /* 0105 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4, | ||
182 | /* 0107 */ 0x00057488,0x00000000,0x000a6388,0x00001001, | ||
183 | /* 0109 */ 0x0008b334,0x000bc141,0x0003020e,0x00000000, | ||
184 | /* 010B */ 0x000886b0,0x00001008,0x00003625,0x000c5dfa, | ||
185 | /* 010D */ 0x000a638a,0x00001001,0x0008020e,0x00001002, | ||
186 | /* 010F */ 0x0008a6b0,0x00001008,0x0007f301,0x00000000, | ||
187 | /* 0111 */ 0x00000000,0x00000000,0x00002725,0x000a8c40, | ||
188 | /* 0113 */ 0x000000ae,0x00000000,0x000d8630,0x00001008, | ||
189 | /* 0115 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640, | ||
190 | /* 0117 */ 0x000a8630,0x00001008,0x000799b8,0x0002d6c0, | ||
191 | /* 0119 */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000, | ||
192 | /* 011B */ 0x00062208,0x000c4117,0x00070630,0x00001009, | ||
193 | /* 011D */ 0x00000000,0x000c0000,0x0001022e,0x00000000, | ||
194 | /* 011F */ 0x0003a630,0x00001009,0x00000000,0x000c0000, | ||
195 | /* 0121 */ 0x00000036,0x00001000,0x00000000,0x00000000, | ||
196 | /* 0123 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
197 | /* 0125 */ 0x00000000,0x00000000,0x0002a730,0x00001008, | ||
198 | /* 0127 */ 0x0007f801,0x000c0000,0x00000037,0x00001000, | ||
199 | /* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
200 | /* 012B */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
201 | /* 012D */ 0x0002a730,0x00001008,0x00000033,0x00001000, | ||
202 | /* 012F */ 0x0002a705,0x00001008,0x00007a01,0x000c0000, | ||
203 | /* 0131 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000, | ||
204 | /* 0133 */ 0x00060730,0x0000100a,0x00000000,0x000c0000, | ||
205 | /* 0135 */ 0x00000000,0x00000000, | ||
206 | /* TASKTREEHEADERCODE */ | ||
207 | /* 0136 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100b, | ||
208 | /* 0138 */ 0x00057488,0x00000000,0x00033b94,0x00081140, | ||
209 | /* 013A */ 0x000183ae,0x00000000,0x000786b0,0x0000100b, | ||
210 | /* 013C */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000, | ||
211 | /* 013E */ 0x00042731,0x00001003, | ||
212 | /* FGTASKTREEHEADERCODE */ | ||
213 | /* 013F */ 0x0007aab0,0x00034880,0x00048fb0,0x0000100a, | ||
214 | /* 0141 */ 0x00057488,0x00000000,0x00033b94,0x00081140, | ||
215 | /* 0143 */ 0x000183ae,0x00000000,0x000806b0,0x0000100b, | ||
216 | /* 0145 */ 0x00022f05,0x00000000,0x00007401,0x00091140, | ||
217 | /* 0147 */ 0x00048f05,0x000951c0,0x00042731,0x00001003, | ||
218 | /* 0149 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47, | ||
219 | /* 014B */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003, | ||
220 | /* 014D */ 0x00000000,0x00000000,0x0008e19c,0x00001003, | ||
221 | /* 014F */ 0x000083c1,0x00093040,0x00000f41,0x00097140, | ||
222 | /* 0151 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040, | ||
223 | /* 0153 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0, | ||
224 | /* 0155 */ 0x00000000,0x000fdc44,0x00055208,0x00000000, | ||
225 | /* 0157 */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00, | ||
226 | /* 0159 */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000, | ||
227 | /* 015B */ 0x00012f05,0x00036880,0x00065308,0x000c2997, | ||
228 | /* 015D */ 0x000d86b0,0x0000100a,0x0004410a,0x000d40c7, | ||
229 | /* 015F */ 0x00000000,0x00000000,0x00080730,0x00001004, | ||
230 | /* 0161 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000, | ||
231 | /* NULLALGORITHM */ | ||
232 | /* 0163 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47, | ||
233 | /* 0165 */ 0x00080000,0x000bffc7,0x0000273d,0x00001000, | ||
234 | /* HFGEXECCHILD */ | ||
235 | /* 0167 */ 0x00000000,0x000eba44, | ||
236 | /* HFGEXECCHILD_98 */ | ||
237 | /* 0168 */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0, | ||
238 | /* HFGEXECCHILD_PUSH1IND */ | ||
239 | /* 016A */ 0x00000734,0x00001000,0x00010705,0x000a6880, | ||
240 | /* 016C */ 0x00006a88,0x000c75c4, | ||
241 | /* HFGEXECSIBLING */ | ||
242 | /* 016D */ 0x00000000,0x000e5084,0x00000000,0x000eba44, | ||
243 | /* HFGEXECSIBLING_298 */ | ||
244 | /* 016F */ 0x00087401,0x000e4782, | ||
245 | /* HFGEXECSIBLING_2IND1 */ | ||
246 | /* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880, | ||
247 | /* 0172 */ 0x00006a88,0x000c75c4, | ||
248 | /* S16_CODECOUTPUTTASK */ | ||
249 | /* 0173 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40, | ||
250 | /* 0175 */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80, | ||
251 | /* 0177 */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0, | ||
252 | /* 0179 */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0, | ||
253 | /* 017B */ 0x00073fb0,0x00074c80,0x000283a0,0x0000100c, | ||
254 | /* 017D */ 0x000ee388,0x00042970,0x00008301,0x00021ef2, | ||
255 | /* 017F */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b, | ||
256 | /* 0181 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916, | ||
257 | /* 0183 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000, | ||
258 | /* 0185 */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b, | ||
259 | /* 0187 */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956, | ||
260 | /* 0189 */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40, | ||
261 | /* 018B */ 0x00058730,0x00001400,0x000d7488,0x000c3a00, | ||
262 | /* 018D */ 0x00048f05,0x00000000 | ||
263 | }; | ||
264 | /* #CODE_END */ | ||
265 | |||
266 | static u32 cwcemb80_parameter[] = { | ||
267 | /* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
268 | /* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
269 | /* 0008 */ 0x00000000,0x00000000,0x00000163,0x00000000, | ||
270 | /* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
271 | /* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
272 | /* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
273 | /* 0018 */ 0x00000000,0x00200040,0x00008010,0x00000000, | ||
274 | /* 001C */ 0x00000000,0x80000001,0x00000001,0x00060000, | ||
275 | /* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
276 | /* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
277 | /* 0028 */ 0x00000000,0x00900080,0x00000173,0x00000000, | ||
278 | /* 002C */ 0x00000000,0x00000010,0x00800000,0x00900000, | ||
279 | /* 0030 */ 0xf2c0000f,0x00000200,0x00000000,0x00010600, | ||
280 | /* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
281 | /* 0038 */ 0x00000000,0x00000000,0x00000163,0x330300c2, | ||
282 | /* 003C */ 0x06000000,0x00000000,0x80008000,0x80008000, | ||
283 | /* 0040 */ 0x3fc0000f,0x00000301,0x00010400,0x00000000, | ||
284 | /* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
285 | /* 0048 */ 0x00000000,0x00b00000,0x00d0806d,0x330480c3, | ||
286 | /* 004C */ 0x04800000,0x00000001,0x00800001,0x0000ffff, | ||
287 | /* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
288 | /* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
289 | /* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
290 | /* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
291 | /* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
292 | /* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
293 | /* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
294 | /* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
295 | /* 0070 */ 0x066a0600,0x06350070,0x0000929d,0x929d929d, | ||
296 | /* 0074 */ 0x00000000,0x0000735a,0x00000600,0x00000000, | ||
297 | /* 0078 */ 0x929d735a,0x00000000,0x00010000,0x735a735a, | ||
298 | /* 007C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
299 | /* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
300 | /* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
301 | /* 0088 */ 0x00000000,0x00000000,0x0000804f,0x000000c3, | ||
302 | /* 008C */ 0x05000000,0x00a00010,0x00000000,0x80008000, | ||
303 | /* 0090 */ 0x00000000,0x00000000,0x00000700,0x00000000, | ||
304 | /* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
305 | /* 0098 */ 0x00000080,0x00a00000,0x0000809a,0x000000c2, | ||
306 | /* 009C */ 0x07400000,0x00000000,0x80008000,0xffffffff, | ||
307 | /* 00A0 */ 0x00c80028,0x00005555,0x00000000,0x000107a0, | ||
308 | /* 00A4 */ 0x00c80028,0x000000c2,0x06800000,0x00000000, | ||
309 | /* 00A8 */ 0x06e00080,0x00300000,0x000080bb,0x000000c9, | ||
310 | /* 00AC */ 0x07a00000,0x04000000,0x80008000,0xffffffff, | ||
311 | /* 00B0 */ 0x00c80028,0x00005555,0x00000000,0x00000780, | ||
312 | /* 00B4 */ 0x00c80028,0x000000c5,0xff800000,0x00000000, | ||
313 | /* 00B8 */ 0x00640080,0x00c00000,0x00008197,0x000000c9, | ||
314 | /* 00BC */ 0x07800000,0x04000000,0x80008000,0xffffffff, | ||
315 | /* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
316 | /* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
317 | /* 00C8 */ 0x00000000,0x00000000,0x0000805e,0x000000c1, | ||
318 | /* 00CC */ 0x00000000,0x00800000,0x80008000,0x80008000, | ||
319 | /* 00D0 */ 0x00020000,0x0000ffff,0x00000000,0x00000000, | ||
320 | /* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
321 | /* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
322 | /* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
323 | /* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
324 | /* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
325 | /* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
326 | /* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
327 | /* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
328 | /* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
329 | /* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
330 | /* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
331 | /* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
332 | /* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
333 | /* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
334 | /* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
335 | /* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
336 | /* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
337 | /* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
338 | /* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
339 | /* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
340 | /* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
341 | /* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
342 | /* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
343 | /* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
344 | /* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
345 | /* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
346 | /* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
347 | /* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
348 | /* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
349 | /* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
350 | /* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
351 | /* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
352 | /* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
353 | /* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
354 | /* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
355 | /* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
356 | /* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
357 | /* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
358 | /* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
359 | /* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
360 | /* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
361 | /* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
362 | /* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
363 | /* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
364 | /* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
365 | /* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
366 | /* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
367 | /* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
368 | /* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
369 | /* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
370 | /* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
371 | /* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
372 | /* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
373 | /* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
374 | /* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
375 | /* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
376 | /* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
377 | /* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
378 | /* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
379 | /* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
380 | /* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
381 | /* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
382 | /* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
383 | /* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
384 | /* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
385 | /* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
386 | /* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
387 | /* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
388 | /* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
389 | /* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
390 | /* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
391 | /* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
392 | /* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
393 | /* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
394 | /* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
395 | /* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
396 | /* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
397 | /* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
398 | /* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
399 | /* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
400 | /* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
401 | /* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
402 | /* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
403 | /* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
404 | /* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
405 | /* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
406 | /* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
407 | /* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
408 | /* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
409 | /* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
410 | /* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
411 | /* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
412 | /* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
413 | /* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
414 | /* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
415 | /* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
416 | /* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
417 | /* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
418 | /* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
419 | /* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
420 | /* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
421 | /* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
422 | /* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
423 | /* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
424 | /* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
425 | /* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
426 | /* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
427 | /* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
428 | /* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
429 | /* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
430 | /* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
431 | /* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
432 | /* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
433 | /* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
434 | /* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
435 | /* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
436 | /* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
437 | /* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
438 | /* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
439 | /* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
440 | /* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
441 | /* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
442 | /* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
443 | /* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
444 | /* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
445 | /* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
446 | /* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
447 | /* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
448 | /* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
449 | /* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
450 | /* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
451 | /* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
452 | /* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
453 | /* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
454 | /* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
455 | /* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
456 | /* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
457 | /* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
458 | /* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
459 | /* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
460 | /* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
461 | /* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
462 | /* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
463 | /* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
464 | /* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
465 | /* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
466 | /* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
467 | /* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
468 | /* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
469 | /* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
470 | /* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
471 | /* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
472 | /* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
473 | /* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
474 | /* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
475 | /* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
476 | /* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
477 | /* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
478 | /* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
479 | /* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
480 | /* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
481 | /* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
482 | /* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
483 | /* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
484 | /* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
485 | /* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
486 | /* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
487 | /* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
488 | /* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
489 | /* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
490 | /* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
491 | /* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
492 | /* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
493 | /* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
494 | /* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
495 | /* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
496 | /* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
497 | /* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
498 | /* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
499 | /* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
500 | /* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
501 | /* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
502 | /* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
503 | /* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
504 | /* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
505 | /* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
506 | /* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
507 | /* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
508 | /* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
509 | /* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
510 | /* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
511 | /* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
512 | /* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
513 | /* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
514 | /* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
515 | /* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
516 | /* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
517 | /* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
518 | /* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
519 | /* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
520 | /* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
521 | /* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
522 | /* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
523 | /* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
524 | /* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
525 | /* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
526 | /* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
527 | /* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
528 | /* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
529 | /* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
530 | /* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
531 | /* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
532 | /* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
533 | /* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
534 | /* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
535 | /* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
536 | /* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
537 | /* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
538 | /* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
539 | /* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
540 | /* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
541 | /* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
542 | /* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
543 | /* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
544 | /* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
545 | /* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
546 | /* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
547 | /* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
548 | /* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
549 | /* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
550 | /* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
551 | /* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
552 | /* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
553 | /* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
554 | /* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
555 | /* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
556 | /* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
557 | /* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
558 | /* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
559 | /* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
560 | /* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
561 | /* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
562 | /* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
563 | /* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
564 | /* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
565 | /* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
566 | /* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
567 | /* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
568 | /* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
569 | /* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
570 | /* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
571 | /* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
572 | /* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
573 | /* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
574 | /* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
575 | /* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
576 | /* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
577 | /* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
578 | /* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
579 | /* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
580 | /* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
581 | /* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
582 | /* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
583 | /* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
584 | /* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
585 | /* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
586 | /* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
587 | /* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
588 | /* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
589 | /* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
590 | /* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
591 | /* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
592 | /* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
593 | /* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
594 | /* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
595 | /* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
596 | /* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
597 | /* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
598 | /* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
599 | /* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
600 | /* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
601 | /* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
602 | /* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
603 | /* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
604 | /* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
605 | /* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
606 | /* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
607 | /* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
608 | /* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
609 | /* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
610 | /* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
611 | /* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
612 | /* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
613 | /* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
614 | /* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
615 | /* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
616 | /* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
617 | /* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
618 | /* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
619 | /* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
620 | /* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
621 | /* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
622 | /* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
623 | /* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
624 | /* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
625 | /* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
626 | /* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
627 | /* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
628 | /* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
629 | /* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
630 | /* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
631 | /* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
632 | /* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
633 | /* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
634 | /* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
635 | /* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
636 | /* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
637 | /* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
638 | /* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
639 | /* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
640 | /* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
641 | /* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
642 | /* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
643 | /* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
644 | /* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
645 | /* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
646 | /* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
647 | /* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
648 | /* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
649 | /* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
650 | /* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
651 | /* 0600 */ 0x929d0600,0x929d929d,0x929d929d,0x929d0000, | ||
652 | /* 0604 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d, | ||
653 | /* 0608 */ 0x929d929d,0x00100635,0x060b013f,0x00000004, | ||
654 | /* 060C */ 0x00000001,0x007a0002,0x00000000,0x066e0610, | ||
655 | /* 0610 */ 0x0105929d,0x929d929d,0x929d929d,0x929d929d, | ||
656 | /* 0614 */ 0x929d929d,0xa431ac75,0x0001735a,0xa431ac75, | ||
657 | /* 0618 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
658 | /* 061C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
659 | /* 0620 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
660 | /* 0624 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
661 | /* 0628 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
662 | /* 062C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
663 | /* 0630 */ 0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051, | ||
664 | /* 0634 */ 0x00000000,0x929d929d,0x929d929d,0x929d929d, | ||
665 | /* 0638 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d, | ||
666 | /* 063C */ 0x929d929d,0x929d929d,0x00000000,0x06400136, | ||
667 | /* 0640 */ 0x0000270f,0x00010000,0x007a0000,0x00000000, | ||
668 | /* 0644 */ 0x068e0645,0x0105929d,0x929d929d,0x929d929d, | ||
669 | /* 0648 */ 0x929d929d,0x929d929d,0xa431ac75,0x0001735a, | ||
670 | /* 064C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
671 | /* 0650 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
672 | /* 0654 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
673 | /* 0658 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
674 | /* 065C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
675 | /* 0660 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
676 | /* 0664 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, | ||
677 | /* 0668 */ 0x735a0100,0x00000000,0x00000000,0x00000000, | ||
678 | /* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
679 | /* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
680 | /* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
681 | /* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
682 | /* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
683 | /* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
684 | /* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
685 | /* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
686 | /* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
687 | /* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
688 | /* 0694 */ 0x00000000,0x00000000,0x00000000 | ||
689 | }; /* #PARAMETER_END */ | ||
690 | |||
691 | static u32 cwcemb80_sample[] = { | ||
692 | /* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
693 | /* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
694 | /* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
695 | /* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
696 | /* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
697 | /* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
698 | /* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
699 | /* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
700 | /* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
701 | /* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
702 | /* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
703 | /* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
704 | /* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
705 | /* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
706 | /* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
707 | /* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
708 | /* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
709 | /* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
710 | /* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
711 | /* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
712 | /* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
713 | /* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
714 | /* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
715 | /* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
716 | /* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
717 | /* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
718 | /* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
719 | /* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
720 | /* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
721 | /* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
722 | /* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
723 | /* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
724 | /* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
725 | /* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
726 | /* 0088 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
727 | /* 008C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
728 | /* 0090 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
729 | /* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
730 | /* 0098 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
731 | /* 009C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
732 | /* 00A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
733 | /* 00A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
734 | /* 00A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
735 | /* 00AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
736 | /* 00B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
737 | /* 00B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
738 | /* 00B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
739 | /* 00BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
740 | /* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
741 | /* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
742 | /* 00C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
743 | /* 00CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
744 | /* 00D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
745 | /* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
746 | /* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
747 | /* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
748 | /* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
749 | /* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
750 | /* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
751 | /* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
752 | /* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
753 | /* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
754 | /* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
755 | /* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
756 | /* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
757 | /* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
758 | /* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
759 | /* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
760 | /* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
761 | /* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
762 | /* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
763 | /* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
764 | /* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
765 | /* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
766 | /* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
767 | /* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
768 | /* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
769 | /* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
770 | /* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
771 | /* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
772 | /* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
773 | /* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
774 | /* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
775 | /* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
776 | /* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
777 | /* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
778 | /* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
779 | /* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
780 | /* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
781 | /* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
782 | /* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
783 | /* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
784 | /* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
785 | /* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
786 | /* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
787 | /* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
788 | /* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
789 | /* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
790 | /* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
791 | /* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
792 | /* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
793 | /* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
794 | /* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
795 | /* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
796 | /* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
797 | /* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
798 | /* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
799 | /* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
800 | /* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
801 | /* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
802 | /* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
803 | /* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
804 | /* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
805 | /* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
806 | /* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
807 | /* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
808 | /* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
809 | /* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
810 | /* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
811 | /* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
812 | /* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
813 | /* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
814 | /* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
815 | /* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
816 | /* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
817 | /* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
818 | /* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
819 | /* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
820 | /* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
821 | /* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
822 | /* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
823 | /* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
824 | /* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
825 | /* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
826 | /* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
827 | /* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
828 | /* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
829 | /* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
830 | /* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
831 | /* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
832 | /* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
833 | /* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
834 | /* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
835 | /* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
836 | /* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
837 | /* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
838 | /* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
839 | /* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
840 | /* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
841 | /* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
842 | /* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
843 | /* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
844 | /* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
845 | /* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
846 | /* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
847 | /* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
848 | /* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
849 | /* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
850 | /* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
851 | /* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
852 | /* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
853 | /* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
854 | /* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
855 | /* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
856 | /* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
857 | /* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
858 | /* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
859 | /* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
860 | /* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
861 | /* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
862 | /* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
863 | /* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
864 | /* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
865 | /* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
866 | /* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
867 | /* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
868 | /* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
869 | /* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
870 | /* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
871 | /* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
872 | /* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
873 | /* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
874 | /* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
875 | /* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
876 | /* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
877 | /* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
878 | /* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
879 | /* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
880 | /* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
881 | /* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
882 | /* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
883 | /* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
884 | /* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
885 | /* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
886 | /* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
887 | /* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
888 | /* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
889 | /* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
890 | /* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
891 | /* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
892 | /* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
893 | /* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
894 | /* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
895 | /* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
896 | /* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
897 | /* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
898 | /* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
899 | /* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
900 | /* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
901 | /* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
902 | /* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
903 | /* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
904 | /* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
905 | /* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
906 | /* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
907 | /* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
908 | /* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
909 | /* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
910 | /* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
911 | /* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
912 | /* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
913 | /* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
914 | /* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
915 | /* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
916 | /* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
917 | /* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
918 | /* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
919 | /* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
920 | /* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
921 | /* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
922 | /* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
923 | /* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
924 | /* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
925 | /* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
926 | /* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
927 | /* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
928 | /* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
929 | /* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
930 | /* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
931 | /* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
932 | /* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
933 | /* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
934 | /* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
935 | /* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
936 | /* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
937 | /* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
938 | /* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
939 | /* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
940 | /* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
941 | /* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
942 | /* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
943 | /* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
944 | /* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
945 | /* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
946 | /* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
947 | /* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
948 | /* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
949 | /* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
950 | /* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
951 | /* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
952 | /* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
953 | /* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
954 | /* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
955 | /* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
956 | /* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
957 | /* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
958 | /* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
959 | /* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
960 | /* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
961 | /* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
962 | /* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
963 | /* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
964 | /* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
965 | /* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
966 | /* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
967 | /* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
968 | /* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
969 | /* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
970 | /* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
971 | /* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
972 | /* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
973 | /* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
974 | /* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
975 | /* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
976 | /* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
977 | /* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
978 | /* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
979 | /* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
980 | /* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
981 | /* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
982 | /* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
983 | /* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
984 | /* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
985 | /* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
986 | /* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
987 | /* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
988 | /* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
989 | /* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
990 | /* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
991 | /* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
992 | /* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
993 | /* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
994 | /* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
995 | /* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
996 | /* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
997 | /* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
998 | /* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
999 | /* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1000 | /* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1001 | /* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1002 | /* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1003 | /* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1004 | /* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1005 | /* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1006 | /* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1007 | /* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1008 | /* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1009 | /* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1010 | /* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1011 | /* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1012 | /* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1013 | /* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1014 | /* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1015 | /* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1016 | /* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1017 | /* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1018 | /* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1019 | /* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1020 | /* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1021 | /* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1022 | /* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1023 | /* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1024 | /* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1025 | /* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1026 | /* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1027 | /* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1028 | /* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1029 | /* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1030 | /* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1031 | /* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1032 | /* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1033 | /* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1034 | /* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1035 | /* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1036 | /* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1037 | /* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1038 | /* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1039 | /* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1040 | /* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1041 | /* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1042 | /* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1043 | /* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1044 | /* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1045 | /* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1046 | /* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1047 | /* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1048 | /* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1049 | /* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1050 | /* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1051 | /* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1052 | /* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1053 | /* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1054 | /* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1055 | /* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1056 | /* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1057 | /* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1058 | /* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1059 | /* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1060 | /* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1061 | /* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1062 | /* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1063 | /* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1064 | /* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1065 | /* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1066 | /* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1067 | /* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1068 | /* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1069 | /* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1070 | /* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1071 | /* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1072 | /* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1073 | /* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1074 | /* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1075 | /* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1076 | /* 0600 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1077 | /* 0604 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1078 | /* 0608 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1079 | /* 060C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1080 | /* 0610 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1081 | /* 0614 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1082 | /* 0618 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1083 | /* 061C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1084 | /* 0620 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1085 | /* 0624 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1086 | /* 0628 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1087 | /* 062C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1088 | /* 0630 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1089 | /* 0634 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1090 | /* 0638 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1091 | /* 063C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1092 | /* 0640 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1093 | /* 0644 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1094 | /* 0648 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1095 | /* 064C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1096 | /* 0650 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1097 | /* 0654 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1098 | /* 0658 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1099 | /* 065C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1100 | /* 0660 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1101 | /* 0664 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1102 | /* 0668 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1103 | /* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1104 | /* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1105 | /* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1106 | /* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1107 | /* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1108 | /* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1109 | /* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1110 | /* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1111 | /* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1112 | /* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1113 | /* 0694 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1114 | /* 0698 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1115 | /* 069C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1116 | /* 06A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1117 | /* 06A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1118 | /* 06A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1119 | /* 06AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1120 | /* 06B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1121 | /* 06B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1122 | /* 06B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1123 | /* 06BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1124 | /* 06C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1125 | /* 06C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1126 | /* 06C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1127 | /* 06CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1128 | /* 06D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1129 | /* 06D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1130 | /* 06D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1131 | /* 06DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1132 | /* 06E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1133 | /* 06E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1134 | /* 06E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1135 | /* 06EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1136 | /* 06F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1137 | /* 06F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1138 | /* 06F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1139 | /* 06FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1140 | /* 0700 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1141 | /* 0704 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1142 | /* 0708 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1143 | /* 070C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1144 | /* 0710 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1145 | /* 0714 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1146 | /* 0718 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1147 | /* 071C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1148 | /* 0720 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1149 | /* 0724 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1150 | /* 0728 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1151 | /* 072C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1152 | /* 0730 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1153 | /* 0734 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1154 | /* 0738 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1155 | /* 073C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1156 | /* 0740 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1157 | /* 0744 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1158 | /* 0748 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1159 | /* 074C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1160 | /* 0750 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1161 | /* 0754 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1162 | /* 0758 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1163 | /* 075C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1164 | /* 0760 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1165 | /* 0764 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1166 | /* 0768 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1167 | /* 076C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1168 | /* 0770 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1169 | /* 0774 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1170 | /* 0778 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1171 | /* 077C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1172 | /* 0780 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1173 | /* 0784 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1174 | /* 0788 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1175 | /* 078C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1176 | /* 0790 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1177 | /* 0794 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1178 | /* 0798 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1179 | /* 079C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1180 | /* 07A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1181 | /* 07A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1182 | /* 07A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1183 | /* 07AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1184 | /* 07B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1185 | /* 07B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1186 | /* 07B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1187 | /* 07BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1188 | /* 07C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1189 | /* 07C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1190 | /* 07C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1191 | /* 07CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1192 | /* 07D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1193 | /* 07D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1194 | /* 07D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1195 | /* 07DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1196 | /* 07E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1197 | /* 07E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1198 | /* 07E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1199 | /* 07EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1200 | /* 07F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1201 | /* 07F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1202 | /* 07F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1203 | /* 07FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1204 | /* 0800 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1205 | /* 0804 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1206 | /* 0808 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1207 | /* 080C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1208 | /* 0810 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1209 | /* 0814 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1210 | /* 0818 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1211 | /* 081C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1212 | /* 0820 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1213 | /* 0824 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1214 | /* 0828 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1215 | /* 082C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1216 | /* 0830 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1217 | /* 0834 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1218 | /* 0838 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1219 | /* 083C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1220 | /* 0840 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1221 | /* 0844 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1222 | /* 0848 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1223 | /* 084C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1224 | /* 0850 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1225 | /* 0854 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1226 | /* 0858 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1227 | /* 085C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1228 | /* 0860 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1229 | /* 0864 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1230 | /* 0868 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1231 | /* 086C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1232 | /* 0870 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1233 | /* 0874 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1234 | /* 0878 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1235 | /* 087C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1236 | /* 0880 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1237 | /* 0884 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1238 | /* 0888 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1239 | /* 088C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1240 | /* 0890 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1241 | /* 0894 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1242 | /* 0898 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1243 | /* 089C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1244 | /* 08A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1245 | /* 08A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1246 | /* 08A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1247 | /* 08AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1248 | /* 08B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1249 | /* 08B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1250 | /* 08B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1251 | /* 08BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1252 | /* 08C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1253 | /* 08C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1254 | /* 08C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1255 | /* 08CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1256 | /* 08D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1257 | /* 08D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1258 | /* 08D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1259 | /* 08DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1260 | /* 08E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1261 | /* 08E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1262 | /* 08E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1263 | /* 08EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1264 | /* 08F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1265 | /* 08F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1266 | /* 08F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1267 | /* 08FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1268 | /* 0900 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1269 | /* 0904 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1270 | /* 0908 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1271 | /* 090C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1272 | /* 0910 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1273 | /* 0914 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1274 | /* 0918 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1275 | /* 091C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1276 | /* 0920 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1277 | /* 0924 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1278 | /* 0928 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1279 | /* 092C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1280 | /* 0930 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1281 | /* 0934 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1282 | /* 0938 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1283 | /* 093C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1284 | /* 0940 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1285 | /* 0944 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1286 | /* 0948 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1287 | /* 094C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1288 | /* 0950 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1289 | /* 0954 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1290 | /* 0958 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1291 | /* 095C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1292 | /* 0960 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1293 | /* 0964 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1294 | /* 0968 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1295 | /* 096C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1296 | /* 0970 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1297 | /* 0974 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1298 | /* 0978 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1299 | /* 097C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1300 | /* 0980 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1301 | /* 0984 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1302 | /* 0988 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1303 | /* 098C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1304 | /* 0990 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1305 | /* 0994 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1306 | /* 0998 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1307 | /* 099C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1308 | /* 09A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1309 | /* 09A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1310 | /* 09A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1311 | /* 09AC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1312 | /* 09B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1313 | /* 09B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1314 | /* 09B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1315 | /* 09BC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1316 | /* 09C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1317 | /* 09C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1318 | /* 09C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1319 | /* 09CC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1320 | /* 09D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1321 | /* 09D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1322 | /* 09D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1323 | /* 09DC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1324 | /* 09E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1325 | /* 09E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1326 | /* 09E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1327 | /* 09EC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1328 | /* 09F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1329 | /* 09F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1330 | /* 09F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1331 | /* 09FC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1332 | /* 0A00 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1333 | /* 0A04 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1334 | /* 0A08 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1335 | /* 0A0C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1336 | /* 0A10 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1337 | /* 0A14 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1338 | /* 0A18 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1339 | /* 0A1C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1340 | /* 0A20 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1341 | /* 0A24 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1342 | /* 0A28 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1343 | /* 0A2C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1344 | /* 0A30 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1345 | /* 0A34 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1346 | /* 0A38 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1347 | /* 0A3C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1348 | /* 0A40 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1349 | /* 0A44 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1350 | /* 0A48 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1351 | /* 0A4C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1352 | /* 0A50 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1353 | /* 0A54 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1354 | /* 0A58 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1355 | /* 0A5C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1356 | /* 0A60 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1357 | /* 0A64 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1358 | /* 0A68 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1359 | /* 0A6C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1360 | /* 0A70 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1361 | /* 0A74 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1362 | /* 0A78 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1363 | /* 0A7C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1364 | /* 0A80 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1365 | /* 0A84 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1366 | /* 0A88 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1367 | /* 0A8C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1368 | /* 0A90 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1369 | /* 0A94 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1370 | /* 0A98 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1371 | /* 0A9C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1372 | /* 0AA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1373 | /* 0AA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1374 | /* 0AA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1375 | /* 0AAC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1376 | /* 0AB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1377 | /* 0AB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1378 | /* 0AB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1379 | /* 0ABC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1380 | /* 0AC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1381 | /* 0AC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1382 | /* 0AC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1383 | /* 0ACC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1384 | /* 0AD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1385 | /* 0AD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1386 | /* 0AD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1387 | /* 0ADC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1388 | /* 0AE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1389 | /* 0AE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1390 | /* 0AE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1391 | /* 0AEC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1392 | /* 0AF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1393 | /* 0AF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1394 | /* 0AF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1395 | /* 0AFC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1396 | /* 0B00 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1397 | /* 0B04 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1398 | /* 0B08 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1399 | /* 0B0C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1400 | /* 0B10 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1401 | /* 0B14 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1402 | /* 0B18 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1403 | /* 0B1C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1404 | /* 0B20 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1405 | /* 0B24 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1406 | /* 0B28 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1407 | /* 0B2C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1408 | /* 0B30 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1409 | /* 0B34 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1410 | /* 0B38 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1411 | /* 0B3C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1412 | /* 0B40 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1413 | /* 0B44 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1414 | /* 0B48 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1415 | /* 0B4C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1416 | /* 0B50 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1417 | /* 0B54 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1418 | /* 0B58 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1419 | /* 0B5C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1420 | /* 0B60 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1421 | /* 0B64 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1422 | /* 0B68 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1423 | /* 0B6C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1424 | /* 0B70 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1425 | /* 0B74 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1426 | /* 0B78 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1427 | /* 0B7C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1428 | /* 0B80 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1429 | /* 0B84 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1430 | /* 0B88 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1431 | /* 0B8C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1432 | /* 0B90 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1433 | /* 0B94 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1434 | /* 0B98 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1435 | /* 0B9C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1436 | /* 0BA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1437 | /* 0BA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1438 | /* 0BA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1439 | /* 0BAC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1440 | /* 0BB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1441 | /* 0BB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1442 | /* 0BB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1443 | /* 0BBC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1444 | /* 0BC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1445 | /* 0BC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1446 | /* 0BC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1447 | /* 0BCC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1448 | /* 0BD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1449 | /* 0BD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1450 | /* 0BD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1451 | /* 0BDC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1452 | /* 0BE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1453 | /* 0BE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1454 | /* 0BE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1455 | /* 0BEC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1456 | /* 0BF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1457 | /* 0BF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1458 | /* 0BF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1459 | /* 0BFC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1460 | /* 0C00 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1461 | /* 0C04 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1462 | /* 0C08 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1463 | /* 0C0C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1464 | /* 0C10 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1465 | /* 0C14 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1466 | /* 0C18 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1467 | /* 0C1C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1468 | /* 0C20 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1469 | /* 0C24 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1470 | /* 0C28 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1471 | /* 0C2C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1472 | /* 0C30 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1473 | /* 0C34 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1474 | /* 0C38 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1475 | /* 0C3C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1476 | /* 0C40 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1477 | /* 0C44 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1478 | /* 0C48 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1479 | /* 0C4C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1480 | /* 0C50 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1481 | /* 0C54 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1482 | /* 0C58 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1483 | /* 0C5C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1484 | /* 0C60 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1485 | /* 0C64 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1486 | /* 0C68 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1487 | /* 0C6C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1488 | /* 0C70 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1489 | /* 0C74 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1490 | /* 0C78 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1491 | /* 0C7C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1492 | /* 0C80 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1493 | /* 0C84 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1494 | /* 0C88 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1495 | /* 0C8C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1496 | /* 0C90 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1497 | /* 0C94 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1498 | /* 0C98 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1499 | /* 0C9C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1500 | /* 0CA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1501 | /* 0CA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1502 | /* 0CA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1503 | /* 0CAC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1504 | /* 0CB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1505 | /* 0CB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1506 | /* 0CB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1507 | /* 0CBC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1508 | /* 0CC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1509 | /* 0CC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1510 | /* 0CC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1511 | /* 0CCC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1512 | /* 0CD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1513 | /* 0CD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1514 | /* 0CD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1515 | /* 0CDC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1516 | /* 0CE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1517 | /* 0CE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1518 | /* 0CE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1519 | /* 0CEC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1520 | /* 0CF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1521 | /* 0CF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1522 | /* 0CF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1523 | /* 0CFC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1524 | /* 0D00 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1525 | /* 0D04 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1526 | /* 0D08 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1527 | /* 0D0C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1528 | /* 0D10 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1529 | /* 0D14 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1530 | /* 0D18 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1531 | /* 0D1C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1532 | /* 0D20 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1533 | /* 0D24 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1534 | /* 0D28 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1535 | /* 0D2C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1536 | /* 0D30 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1537 | /* 0D34 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1538 | /* 0D38 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1539 | /* 0D3C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1540 | /* 0D40 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1541 | /* 0D44 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1542 | /* 0D48 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1543 | /* 0D4C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1544 | /* 0D50 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1545 | /* 0D54 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1546 | /* 0D58 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1547 | /* 0D5C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1548 | /* 0D60 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1549 | /* 0D64 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1550 | /* 0D68 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1551 | /* 0D6C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1552 | /* 0D70 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1553 | /* 0D74 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1554 | /* 0D78 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1555 | /* 0D7C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1556 | /* 0D80 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1557 | /* 0D84 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1558 | /* 0D88 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1559 | /* 0D8C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1560 | /* 0D90 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1561 | /* 0D94 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1562 | /* 0D98 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1563 | /* 0D9C */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1564 | /* 0DA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1565 | /* 0DA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1566 | /* 0DA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1567 | /* 0DAC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1568 | /* 0DB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1569 | /* 0DB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1570 | /* 0DB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1571 | /* 0DBC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1572 | /* 0DC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1573 | /* 0DC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1574 | /* 0DC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1575 | /* 0DCC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1576 | /* 0DD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1577 | /* 0DD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1578 | /* 0DD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1579 | /* 0DDC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1580 | /* 0DE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1581 | /* 0DE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1582 | /* 0DE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1583 | /* 0DEC */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1584 | /* 0DF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1585 | /* 0DF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1586 | /* 0DF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, | ||
1587 | /* 0DFC */ 0x00000000,0x00000000,0x00000000,0x00010004 | ||
1588 | }; /* #SAMPLE_END */ | ||
1589 | |||
1590 | |||
1591 | static struct dsp_segment_desc cwcemb80_segments[] = { | ||
1592 | { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000031c, cwcemb80_code }, | ||
1593 | { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000697, cwcemb80_parameter }, | ||
1594 | { SEGTYPE_SP_SAMPLE, 0x00000000, 0x00000e00, cwcemb80_sample }, | ||
1595 | }; | ||
1596 | |||
1597 | static struct dsp_module_desc cwcemb80_module = { | ||
1598 | "cwcemb80", | ||
1599 | { | ||
1600 | 38, | ||
1601 | cwcemb80_symbols | ||
1602 | }, | ||
1603 | 3, | ||
1604 | cwcemb80_segments, | ||
1605 | }; | ||
1606 | |||
1607 | #endif /* __HEADER_cwcemb80_H__ */ | ||
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c index 8e7fe033270f..87078d3a6854 100644 --- a/sound/pci/echoaudio/darla20.c +++ b/sound/pci/echoaudio/darla20.c | |||
@@ -56,6 +56,8 @@ | |||
56 | #include <asm/atomic.h> | 56 | #include <asm/atomic.h> |
57 | #include "echoaudio.h" | 57 | #include "echoaudio.h" |
58 | 58 | ||
59 | MODULE_FIRMWARE("ea/darla20_dsp.fw"); | ||
60 | |||
59 | #define FW_DARLA20_DSP 0 | 61 | #define FW_DARLA20_DSP 0 |
60 | 62 | ||
61 | static const struct firmware card_fw[] = { | 63 | static const struct firmware card_fw[] = { |
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c index a13c623eb999..42b48f9d2128 100644 --- a/sound/pci/echoaudio/darla24.c +++ b/sound/pci/echoaudio/darla24.c | |||
@@ -60,6 +60,8 @@ | |||
60 | #include <asm/atomic.h> | 60 | #include <asm/atomic.h> |
61 | #include "echoaudio.h" | 61 | #include "echoaudio.h" |
62 | 62 | ||
63 | MODULE_FIRMWARE("ea/darla24_dsp.fw"); | ||
64 | |||
63 | #define FW_DARLA24_DSP 0 | 65 | #define FW_DARLA24_DSP 0 |
64 | 66 | ||
65 | static const struct firmware card_fw[] = { | 67 | static const struct firmware card_fw[] = { |
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c index 8fb15823aca5..8dbb7ac865c1 100644 --- a/sound/pci/echoaudio/echo3g.c +++ b/sound/pci/echoaudio/echo3g.c | |||
@@ -68,6 +68,10 @@ | |||
68 | #include <asm/atomic.h> | 68 | #include <asm/atomic.h> |
69 | #include "echoaudio.h" | 69 | #include "echoaudio.h" |
70 | 70 | ||
71 | MODULE_FIRMWARE("ea/loader_dsp.fw"); | ||
72 | MODULE_FIRMWARE("ea/echo3g_dsp.fw"); | ||
73 | MODULE_FIRMWARE("ea/3g_asic.fw"); | ||
74 | |||
71 | #define FW_361_LOADER 0 | 75 | #define FW_361_LOADER 0 |
72 | #define FW_ECHO3G_DSP 1 | 76 | #define FW_ECHO3G_DSP 1 |
73 | #define FW_3G_ASIC 2 | 77 | #define FW_3G_ASIC 2 |
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index e413da00759b..f27b6a733b96 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c | |||
@@ -705,11 +705,9 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
705 | struct audiopipe *pipe = runtime->private_data; | 705 | struct audiopipe *pipe = runtime->private_data; |
706 | int i, err; | 706 | int i, err; |
707 | u32 channelmask = 0; | 707 | u32 channelmask = 0; |
708 | struct list_head *pos; | ||
709 | struct snd_pcm_substream *s; | 708 | struct snd_pcm_substream *s; |
710 | 709 | ||
711 | snd_pcm_group_for_each(pos, substream) { | 710 | snd_pcm_group_for_each_entry(s, substream) { |
712 | s = snd_pcm_group_substream_entry(pos); | ||
713 | for (i = 0; i < DSP_MAXPIPES; i++) { | 711 | for (i = 0; i < DSP_MAXPIPES; i++) { |
714 | if (s == chip->substream[i]) { | 712 | if (s == chip->substream[i]) { |
715 | channelmask |= 1 << i; | 713 | channelmask |= 1 << i; |
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c index 9f439ea459f4..52a933189576 100644 --- a/sound/pci/echoaudio/echoaudio_3g.c +++ b/sound/pci/echoaudio/echoaudio_3g.c | |||
@@ -233,8 +233,8 @@ static int load_asic(struct echoaudio *chip) | |||
233 | 233 | ||
234 | chip->asic_code = &card_fw[FW_3G_ASIC]; | 234 | chip->asic_code = &card_fw[FW_3G_ASIC]; |
235 | 235 | ||
236 | /* Now give the new ASIC a little time to set up */ | 236 | /* Now give the new ASIC some time to set up */ |
237 | mdelay(2); | 237 | msleep(1000); |
238 | /* See if it worked */ | 238 | /* See if it worked */ |
239 | box_type = check_asic_status(chip); | 239 | box_type = check_asic_status(chip); |
240 | 240 | ||
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c index af4d32026e4a..fee2d4831732 100644 --- a/sound/pci/echoaudio/gina20.c +++ b/sound/pci/echoaudio/gina20.c | |||
@@ -60,6 +60,8 @@ | |||
60 | #include <asm/atomic.h> | 60 | #include <asm/atomic.h> |
61 | #include "echoaudio.h" | 61 | #include "echoaudio.h" |
62 | 62 | ||
63 | MODULE_FIRMWARE("ea/gina20_dsp.fw"); | ||
64 | |||
63 | #define FW_GINA20_DSP 0 | 65 | #define FW_GINA20_DSP 0 |
64 | 66 | ||
65 | static const struct firmware card_fw[] = { | 67 | static const struct firmware card_fw[] = { |
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c index 9ff454a947ed..d5eae470fe9a 100644 --- a/sound/pci/echoaudio/gina24.c +++ b/sound/pci/echoaudio/gina24.c | |||
@@ -66,6 +66,12 @@ | |||
66 | #include <asm/atomic.h> | 66 | #include <asm/atomic.h> |
67 | #include "echoaudio.h" | 67 | #include "echoaudio.h" |
68 | 68 | ||
69 | MODULE_FIRMWARE("ea/loader_dsp.fw"); | ||
70 | MODULE_FIRMWARE("ea/gina24_301_dsp.fw"); | ||
71 | MODULE_FIRMWARE("ea/gina24_361_dsp.fw"); | ||
72 | MODULE_FIRMWARE("ea/gina24_301_asic.fw"); | ||
73 | MODULE_FIRMWARE("ea/gina24_361_asic.fw"); | ||
74 | |||
69 | #define FW_361_LOADER 0 | 75 | #define FW_361_LOADER 0 |
70 | #define FW_GINA24_301_DSP 1 | 76 | #define FW_GINA24_301_DSP 1 |
71 | #define FW_GINA24_361_DSP 2 | 77 | #define FW_GINA24_361_DSP 2 |
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c index 37eb726fd03d..40f601cd016f 100644 --- a/sound/pci/echoaudio/indigo.c +++ b/sound/pci/echoaudio/indigo.c | |||
@@ -58,6 +58,9 @@ | |||
58 | #include <asm/atomic.h> | 58 | #include <asm/atomic.h> |
59 | #include "echoaudio.h" | 59 | #include "echoaudio.h" |
60 | 60 | ||
61 | MODULE_FIRMWARE("ea/loader_dsp.fw"); | ||
62 | MODULE_FIRMWARE("ea/indigo_dsp.fw"); | ||
63 | |||
61 | #define FW_361_LOADER 0 | 64 | #define FW_361_LOADER 0 |
62 | #define FW_INDIGO_DSP 1 | 65 | #define FW_INDIGO_DSP 1 |
63 | 66 | ||
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c index dc8b91824181..771c5383210d 100644 --- a/sound/pci/echoaudio/indigodj.c +++ b/sound/pci/echoaudio/indigodj.c | |||
@@ -58,6 +58,9 @@ | |||
58 | #include <asm/atomic.h> | 58 | #include <asm/atomic.h> |
59 | #include "echoaudio.h" | 59 | #include "echoaudio.h" |
60 | 60 | ||
61 | MODULE_FIRMWARE("ea/loader_dsp.fw"); | ||
62 | MODULE_FIRMWARE("ea/indigo_dj_dsp.fw"); | ||
63 | |||
61 | #define FW_361_LOADER 0 | 64 | #define FW_361_LOADER 0 |
62 | #define FW_INDIGO_DJ_DSP 1 | 65 | #define FW_INDIGO_DJ_DSP 1 |
63 | 66 | ||
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c index eadf3263453a..49c550defcf9 100644 --- a/sound/pci/echoaudio/indigoio.c +++ b/sound/pci/echoaudio/indigoio.c | |||
@@ -59,6 +59,9 @@ | |||
59 | #include <asm/atomic.h> | 59 | #include <asm/atomic.h> |
60 | #include "echoaudio.h" | 60 | #include "echoaudio.h" |
61 | 61 | ||
62 | MODULE_FIRMWARE("ea/loader_dsp.fw"); | ||
63 | MODULE_FIRMWARE("ea/indigo_io_dsp.fw"); | ||
64 | |||
62 | #define FW_361_LOADER 0 | 65 | #define FW_361_LOADER 0 |
63 | #define FW_INDIGO_IO_DSP 1 | 66 | #define FW_INDIGO_IO_DSP 1 |
64 | 67 | ||
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c index 6cede497579e..8f5483a405ae 100644 --- a/sound/pci/echoaudio/layla20.c +++ b/sound/pci/echoaudio/layla20.c | |||
@@ -66,6 +66,9 @@ | |||
66 | #include <asm/atomic.h> | 66 | #include <asm/atomic.h> |
67 | #include "echoaudio.h" | 67 | #include "echoaudio.h" |
68 | 68 | ||
69 | MODULE_FIRMWARE("ea/layla20_dsp.fw"); | ||
70 | MODULE_FIRMWARE("ea/layla20_asic.fw"); | ||
71 | |||
69 | #define FW_LAYLA20_DSP 0 | 72 | #define FW_LAYLA20_DSP 0 |
70 | #define FW_LAYLA20_ASIC 1 | 73 | #define FW_LAYLA20_ASIC 1 |
71 | 74 | ||
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c index 44f735426aa0..0524667c02f7 100644 --- a/sound/pci/echoaudio/layla24.c +++ b/sound/pci/echoaudio/layla24.c | |||
@@ -68,6 +68,12 @@ | |||
68 | #include <asm/atomic.h> | 68 | #include <asm/atomic.h> |
69 | #include "echoaudio.h" | 69 | #include "echoaudio.h" |
70 | 70 | ||
71 | MODULE_FIRMWARE("ea/loader_dsp.fw"); | ||
72 | MODULE_FIRMWARE("ea/layla24_dsp.fw"); | ||
73 | MODULE_FIRMWARE("ea/layla24_1_asic.fw"); | ||
74 | MODULE_FIRMWARE("ea/layla24_2A_asic.fw"); | ||
75 | MODULE_FIRMWARE("ea/layla24_2S_asic.fw"); | ||
76 | |||
71 | #define FW_361_LOADER 0 | 77 | #define FW_361_LOADER 0 |
72 | #define FW_LAYLA24_DSP 1 | 78 | #define FW_LAYLA24_DSP 1 |
73 | #define FW_LAYLA24_1_ASIC 2 | 79 | #define FW_LAYLA24_1_ASIC 2 |
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c index dc172d03ac3f..893c7c20dd70 100644 --- a/sound/pci/echoaudio/mia.c +++ b/sound/pci/echoaudio/mia.c | |||
@@ -66,6 +66,9 @@ | |||
66 | #include <asm/atomic.h> | 66 | #include <asm/atomic.h> |
67 | #include "echoaudio.h" | 67 | #include "echoaudio.h" |
68 | 68 | ||
69 | MODULE_FIRMWARE("ea/loader_dsp.fw"); | ||
70 | MODULE_FIRMWARE("ea/mia_dsp.fw"); | ||
71 | |||
69 | #define FW_361_LOADER 0 | 72 | #define FW_361_LOADER 0 |
70 | #define FW_MIA_DSP 1 | 73 | #define FW_MIA_DSP 1 |
71 | 74 | ||
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c index c856ed50dd9a..3a5d5b0020df 100644 --- a/sound/pci/echoaudio/mona.c +++ b/sound/pci/echoaudio/mona.c | |||
@@ -64,6 +64,15 @@ | |||
64 | #include <asm/atomic.h> | 64 | #include <asm/atomic.h> |
65 | #include "echoaudio.h" | 65 | #include "echoaudio.h" |
66 | 66 | ||
67 | MODULE_FIRMWARE("ea/loader_dsp.fw"); | ||
68 | MODULE_FIRMWARE("ea/mona_301_dsp.fw"); | ||
69 | MODULE_FIRMWARE("ea/mona_361_dsp.fw"); | ||
70 | MODULE_FIRMWARE("ea/mona_301_1_asic_48.fw"); | ||
71 | MODULE_FIRMWARE("ea/mona_301_1_asic_96.fw"); | ||
72 | MODULE_FIRMWARE("ea/mona_361_1_asic_48.fw"); | ||
73 | MODULE_FIRMWARE("ea/mona_361_1_asic_96.fw"); | ||
74 | MODULE_FIRMWARE("ea/mona_2_asic.fw"); | ||
75 | |||
67 | #define FW_361_LOADER 0 | 76 | #define FW_361_LOADER 0 |
68 | #define FW_MONA_301_DSP 1 | 77 | #define FW_MONA_301_DSP 1 |
69 | #define FW_MONA_361_DSP 2 | 78 | #define FW_MONA_361_DSP 2 |
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 80aa585eade4..dbc805c33fc4 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -49,6 +49,13 @@ | |||
49 | #include "p17v.h" | 49 | #include "p17v.h" |
50 | 50 | ||
51 | 51 | ||
52 | #define HANA_FILENAME "emu/hana.fw" | ||
53 | #define DOCK_FILENAME "emu/audio_dock.fw" | ||
54 | |||
55 | MODULE_FIRMWARE(HANA_FILENAME); | ||
56 | MODULE_FIRMWARE(DOCK_FILENAME); | ||
57 | |||
58 | |||
52 | /************************************************************************* | 59 | /************************************************************************* |
53 | * EMU10K1 init / done | 60 | * EMU10K1 init / done |
54 | *************************************************************************/ | 61 | *************************************************************************/ |
@@ -693,8 +700,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) | |||
693 | int tmp,tmp2; | 700 | int tmp,tmp2; |
694 | int reg; | 701 | int reg; |
695 | int err; | 702 | int err; |
696 | const char *hana_filename = "emu/hana.fw"; | ||
697 | const char *dock_filename = "emu/audio_dock.fw"; | ||
698 | 703 | ||
699 | snd_printk(KERN_INFO "emu1010: Special config.\n"); | 704 | snd_printk(KERN_INFO "emu1010: Special config.\n"); |
700 | /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, | 705 | /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, |
@@ -735,8 +740,8 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) | |||
735 | return -ENODEV; | 740 | return -ENODEV; |
736 | } | 741 | } |
737 | snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); | 742 | snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); |
738 | if ((err = snd_emu1010_load_firmware(emu, hana_filename)) != 0) { | 743 | if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) { |
739 | snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", hana_filename); | 744 | snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME); |
740 | return err; | 745 | return err; |
741 | } | 746 | } |
742 | 747 | ||
@@ -938,7 +943,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) | |||
938 | /* Return to Audio Dock programming mode */ | 943 | /* Return to Audio Dock programming mode */ |
939 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); | 944 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); |
940 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); | 945 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); |
941 | if ((err = snd_emu1010_load_firmware(emu, dock_filename)) != 0) { | 946 | if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { |
942 | return err; | 947 | return err; |
943 | } | 948 | } |
944 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); | 949 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); |
@@ -1216,6 +1221,15 @@ static struct snd_emu_chip_details emu_chip_details[] = { | |||
1216 | .spi_dac = 1, | 1221 | .spi_dac = 1, |
1217 | .i2c_adc = 1, | 1222 | .i2c_adc = 1, |
1218 | .spk71 = 1} , | 1223 | .spk71 = 1} , |
1224 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102, | ||
1225 | .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]", | ||
1226 | .id = "EMU1010", | ||
1227 | .emu10k2_chip = 1, | ||
1228 | .ca0108_chip = 1, | ||
1229 | .ca_cardbus_chip = 1, | ||
1230 | .spi_dac = 1, | ||
1231 | .i2c_adc = 1, | ||
1232 | .spk71 = 1} , | ||
1219 | {.vendor = 0x1102, .device = 0x0008, | 1233 | {.vendor = 0x1102, .device = 0x0008, |
1220 | .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", | 1234 | .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", |
1221 | .id = "Audigy2", | 1235 | .id = "Audigy2", |
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index 465f8d505329..7ee19c63c2c8 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c | |||
@@ -433,7 +433,6 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, | |||
433 | struct snd_emu10k1_pcm *epcm; | 433 | struct snd_emu10k1_pcm *epcm; |
434 | int channel; | 434 | int channel; |
435 | int result = 0; | 435 | int result = 0; |
436 | struct list_head *pos; | ||
437 | struct snd_pcm_substream *s; | 436 | struct snd_pcm_substream *s; |
438 | u32 basic = 0; | 437 | u32 basic = 0; |
439 | u32 inte = 0; | 438 | u32 inte = 0; |
@@ -448,8 +447,7 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, | |||
448 | running = 0; | 447 | running = 0; |
449 | break; | 448 | break; |
450 | } | 449 | } |
451 | snd_pcm_group_for_each(pos, substream) { | 450 | snd_pcm_group_for_each_entry(s, substream) { |
452 | s = snd_pcm_group_substream_entry(pos); | ||
453 | runtime = s->runtime; | 451 | runtime = s->runtime; |
454 | epcm = runtime->private_data; | 452 | epcm = runtime->private_data; |
455 | channel = substream->pcm->device-emu->p16v_device_offset; | 453 | channel = substream->pcm->device-emu->p16v_device_offset; |
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 425b167522d5..6a0ddcf00884 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
@@ -798,10 +798,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd) | |||
798 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 798 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
799 | { | 799 | { |
800 | unsigned int what = 0; | 800 | unsigned int what = 0; |
801 | struct list_head *pos; | ||
802 | struct snd_pcm_substream *s; | 801 | struct snd_pcm_substream *s; |
803 | snd_pcm_group_for_each(pos, substream) { | 802 | snd_pcm_group_for_each_entry(s, substream) { |
804 | s = snd_pcm_group_substream_entry(pos); | ||
805 | if (s == ensoniq->playback1_substream) { | 803 | if (s == ensoniq->playback1_substream) { |
806 | what |= ES_P1_PAUSE; | 804 | what |= ES_P1_PAUSE; |
807 | snd_pcm_trigger_done(s, substream); | 805 | snd_pcm_trigger_done(s, substream); |
@@ -824,10 +822,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd) | |||
824 | case SNDRV_PCM_TRIGGER_STOP: | 822 | case SNDRV_PCM_TRIGGER_STOP: |
825 | { | 823 | { |
826 | unsigned int what = 0; | 824 | unsigned int what = 0; |
827 | struct list_head *pos; | ||
828 | struct snd_pcm_substream *s; | 825 | struct snd_pcm_substream *s; |
829 | snd_pcm_group_for_each(pos, substream) { | 826 | snd_pcm_group_for_each_entry(s, substream) { |
830 | s = snd_pcm_group_substream_entry(pos); | ||
831 | if (s == ensoniq->playback1_substream) { | 827 | if (s == ensoniq->playback1_substream) { |
832 | what |= ES_DAC1_EN; | 828 | what |= ES_DAC1_EN; |
833 | snd_pcm_trigger_done(s, substream); | 829 | snd_pcm_trigger_done(s, substream); |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index dc84c189b05f..2faf009076bb 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -1554,10 +1554,7 @@ static int snd_es1968_playback_open(struct snd_pcm_substream *substream) | |||
1554 | runtime->hw = snd_es1968_playback; | 1554 | runtime->hw = snd_es1968_playback; |
1555 | runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = | 1555 | runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = |
1556 | calc_available_memory_size(chip); | 1556 | calc_available_memory_size(chip); |
1557 | #if 0 | 1557 | |
1558 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | ||
1559 | 1024); | ||
1560 | #endif | ||
1561 | spin_lock_irq(&chip->substream_lock); | 1558 | spin_lock_irq(&chip->substream_lock); |
1562 | list_add(&es->list, &chip->substream_list); | 1559 | list_add(&es->list, &chip->substream_list); |
1563 | spin_unlock_irq(&chip->substream_lock); | 1560 | spin_unlock_irq(&chip->substream_lock); |
@@ -1613,10 +1610,8 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream) | |||
1613 | runtime->hw = snd_es1968_capture; | 1610 | runtime->hw = snd_es1968_capture; |
1614 | runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = | 1611 | runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = |
1615 | calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */ | 1612 | calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */ |
1616 | #if 0 | 1613 | snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES); |
1617 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | 1614 | |
1618 | 1024); | ||
1619 | #endif | ||
1620 | spin_lock_irq(&chip->substream_lock); | 1615 | spin_lock_irq(&chip->substream_lock); |
1621 | list_add(&es->list, &chip->substream_list); | 1616 | list_add(&es->list, &chip->substream_list); |
1622 | spin_unlock_irq(&chip->substream_lock); | 1617 | spin_unlock_irq(&chip->substream_lock); |
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 60d7b05a204a..b2484bbdcc1d 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile | |||
@@ -1,5 +1,8 @@ | |||
1 | snd-hda-intel-objs := hda_intel.o | 1 | snd-hda-intel-objs := hda_intel.o |
2 | snd-hda-codec-objs := hda_codec.o \ | 2 | # since snd-hda-intel is the only driver using hda-codec, |
3 | # merge it into a single module although it was originally | ||
4 | # designed to be individual modules | ||
5 | snd-hda-intel-objs += hda_codec.o \ | ||
3 | hda_generic.o \ | 6 | hda_generic.o \ |
4 | patch_realtek.o \ | 7 | patch_realtek.o \ |
5 | patch_cmedia.o \ | 8 | patch_cmedia.o \ |
@@ -10,7 +13,7 @@ snd-hda-codec-objs := hda_codec.o \ | |||
10 | patch_conexant.o \ | 13 | patch_conexant.o \ |
11 | patch_via.o | 14 | patch_via.o |
12 | ifdef CONFIG_PROC_FS | 15 | ifdef CONFIG_PROC_FS |
13 | snd-hda-codec-objs += hda_proc.o | 16 | snd-hda-intel-objs += hda_proc.o |
14 | endif | 17 | endif |
15 | 18 | ||
16 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o snd-hda-codec.o | 19 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 8f34fb447983..14649d54b493 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/moduleparam.h> | ||
28 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
29 | #include <sound/core.h> | 28 | #include <sound/core.h> |
30 | #include "hda_codec.h" | 29 | #include "hda_codec.h" |
@@ -34,11 +33,6 @@ | |||
34 | #include "hda_local.h" | 33 | #include "hda_local.h" |
35 | 34 | ||
36 | 35 | ||
37 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); | ||
38 | MODULE_DESCRIPTION("Universal interface for High Definition Audio Codec"); | ||
39 | MODULE_LICENSE("GPL"); | ||
40 | |||
41 | |||
42 | /* | 36 | /* |
43 | * vendor / preset table | 37 | * vendor / preset table |
44 | */ | 38 | */ |
@@ -77,12 +71,13 @@ static struct hda_vendor_id hda_vendor_ids[] = { | |||
77 | * | 71 | * |
78 | * Returns the obtained response value, or -1 for an error. | 72 | * Returns the obtained response value, or -1 for an error. |
79 | */ | 73 | */ |
80 | unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct, | 74 | unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, |
75 | int direct, | ||
81 | unsigned int verb, unsigned int parm) | 76 | unsigned int verb, unsigned int parm) |
82 | { | 77 | { |
83 | unsigned int res; | 78 | unsigned int res; |
84 | mutex_lock(&codec->bus->cmd_mutex); | 79 | mutex_lock(&codec->bus->cmd_mutex); |
85 | if (! codec->bus->ops.command(codec, nid, direct, verb, parm)) | 80 | if (!codec->bus->ops.command(codec, nid, direct, verb, parm)) |
86 | res = codec->bus->ops.get_response(codec); | 81 | res = codec->bus->ops.get_response(codec); |
87 | else | 82 | else |
88 | res = (unsigned int)-1; | 83 | res = (unsigned int)-1; |
@@ -90,8 +85,6 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int dire | |||
90 | return res; | 85 | return res; |
91 | } | 86 | } |
92 | 87 | ||
93 | EXPORT_SYMBOL(snd_hda_codec_read); | ||
94 | |||
95 | /** | 88 | /** |
96 | * snd_hda_codec_write - send a single command without waiting for response | 89 | * snd_hda_codec_write - send a single command without waiting for response |
97 | * @codec: the HDA codec | 90 | * @codec: the HDA codec |
@@ -114,8 +107,6 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, | |||
114 | return err; | 107 | return err; |
115 | } | 108 | } |
116 | 109 | ||
117 | EXPORT_SYMBOL(snd_hda_codec_write); | ||
118 | |||
119 | /** | 110 | /** |
120 | * snd_hda_sequence_write - sequence writes | 111 | * snd_hda_sequence_write - sequence writes |
121 | * @codec: the HDA codec | 112 | * @codec: the HDA codec |
@@ -130,8 +121,6 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq) | |||
130 | snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param); | 121 | snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param); |
131 | } | 122 | } |
132 | 123 | ||
133 | EXPORT_SYMBOL(snd_hda_sequence_write); | ||
134 | |||
135 | /** | 124 | /** |
136 | * snd_hda_get_sub_nodes - get the range of sub nodes | 125 | * snd_hda_get_sub_nodes - get the range of sub nodes |
137 | * @codec: the HDA codec | 126 | * @codec: the HDA codec |
@@ -141,7 +130,8 @@ EXPORT_SYMBOL(snd_hda_sequence_write); | |||
141 | * Parse the NID and store the start NID of its sub-nodes. | 130 | * Parse the NID and store the start NID of its sub-nodes. |
142 | * Returns the number of sub-nodes. | 131 | * Returns the number of sub-nodes. |
143 | */ | 132 | */ |
144 | int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id) | 133 | int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, |
134 | hda_nid_t *start_id) | ||
145 | { | 135 | { |
146 | unsigned int parm; | 136 | unsigned int parm; |
147 | 137 | ||
@@ -150,8 +140,6 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *sta | |||
150 | return (int)(parm & 0x7fff); | 140 | return (int)(parm & 0x7fff); |
151 | } | 141 | } |
152 | 142 | ||
153 | EXPORT_SYMBOL(snd_hda_get_sub_nodes); | ||
154 | |||
155 | /** | 143 | /** |
156 | * snd_hda_get_connections - get connection list | 144 | * snd_hda_get_connections - get connection list |
157 | * @codec: the HDA codec | 145 | * @codec: the HDA codec |
@@ -187,12 +175,13 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
187 | conn_len = parm & AC_CLIST_LENGTH; | 175 | conn_len = parm & AC_CLIST_LENGTH; |
188 | mask = (1 << (shift-1)) - 1; | 176 | mask = (1 << (shift-1)) - 1; |
189 | 177 | ||
190 | if (! conn_len) | 178 | if (!conn_len) |
191 | return 0; /* no connection */ | 179 | return 0; /* no connection */ |
192 | 180 | ||
193 | if (conn_len == 1) { | 181 | if (conn_len == 1) { |
194 | /* single connection */ | 182 | /* single connection */ |
195 | parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, 0); | 183 | parm = snd_hda_codec_read(codec, nid, 0, |
184 | AC_VERB_GET_CONNECT_LIST, 0); | ||
196 | conn_list[0] = parm & mask; | 185 | conn_list[0] = parm & mask; |
197 | return 1; | 186 | return 1; |
198 | } | 187 | } |
@@ -207,18 +196,21 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
207 | if (i % num_elems == 0) | 196 | if (i % num_elems == 0) |
208 | parm = snd_hda_codec_read(codec, nid, 0, | 197 | parm = snd_hda_codec_read(codec, nid, 0, |
209 | AC_VERB_GET_CONNECT_LIST, i); | 198 | AC_VERB_GET_CONNECT_LIST, i); |
210 | range_val = !! (parm & (1 << (shift-1))); /* ranges */ | 199 | range_val = !!(parm & (1 << (shift-1))); /* ranges */ |
211 | val = parm & mask; | 200 | val = parm & mask; |
212 | parm >>= shift; | 201 | parm >>= shift; |
213 | if (range_val) { | 202 | if (range_val) { |
214 | /* ranges between the previous and this one */ | 203 | /* ranges between the previous and this one */ |
215 | if (! prev_nid || prev_nid >= val) { | 204 | if (!prev_nid || prev_nid >= val) { |
216 | snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", prev_nid, val); | 205 | snd_printk(KERN_WARNING "hda_codec: " |
206 | "invalid dep_range_val %x:%x\n", | ||
207 | prev_nid, val); | ||
217 | continue; | 208 | continue; |
218 | } | 209 | } |
219 | for (n = prev_nid + 1; n <= val; n++) { | 210 | for (n = prev_nid + 1; n <= val; n++) { |
220 | if (conns >= max_conns) { | 211 | if (conns >= max_conns) { |
221 | snd_printk(KERN_ERR "Too many connections\n"); | 212 | snd_printk(KERN_ERR |
213 | "Too many connections\n"); | ||
222 | return -EINVAL; | 214 | return -EINVAL; |
223 | } | 215 | } |
224 | conn_list[conns++] = n; | 216 | conn_list[conns++] = n; |
@@ -253,7 +245,8 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) | |||
253 | struct hda_bus_unsolicited *unsol; | 245 | struct hda_bus_unsolicited *unsol; |
254 | unsigned int wp; | 246 | unsigned int wp; |
255 | 247 | ||
256 | if ((unsol = bus->unsol) == NULL) | 248 | unsol = bus->unsol; |
249 | if (!unsol) | ||
257 | return 0; | 250 | return 0; |
258 | 251 | ||
259 | wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE; | 252 | wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE; |
@@ -268,8 +261,6 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) | |||
268 | return 0; | 261 | return 0; |
269 | } | 262 | } |
270 | 263 | ||
271 | EXPORT_SYMBOL(snd_hda_queue_unsol_event); | ||
272 | |||
273 | /* | 264 | /* |
274 | * process queueud unsolicited events | 265 | * process queueud unsolicited events |
275 | */ | 266 | */ |
@@ -287,7 +278,7 @@ static void process_unsol_events(struct work_struct *work) | |||
287 | rp <<= 1; | 278 | rp <<= 1; |
288 | res = unsol->queue[rp]; | 279 | res = unsol->queue[rp]; |
289 | caddr = unsol->queue[rp + 1]; | 280 | caddr = unsol->queue[rp + 1]; |
290 | if (! (caddr & (1 << 4))) /* no unsolicited event? */ | 281 | if (!(caddr & (1 << 4))) /* no unsolicited event? */ |
291 | continue; | 282 | continue; |
292 | codec = bus->caddr_tbl[caddr & 0x0f]; | 283 | codec = bus->caddr_tbl[caddr & 0x0f]; |
293 | if (codec && codec->patch_ops.unsol_event) | 284 | if (codec && codec->patch_ops.unsol_event) |
@@ -298,7 +289,7 @@ static void process_unsol_events(struct work_struct *work) | |||
298 | /* | 289 | /* |
299 | * initialize unsolicited queue | 290 | * initialize unsolicited queue |
300 | */ | 291 | */ |
301 | static int init_unsol_queue(struct hda_bus *bus) | 292 | static int __devinit init_unsol_queue(struct hda_bus *bus) |
302 | { | 293 | { |
303 | struct hda_bus_unsolicited *unsol; | 294 | struct hda_bus_unsolicited *unsol; |
304 | 295 | ||
@@ -306,8 +297,9 @@ static int init_unsol_queue(struct hda_bus *bus) | |||
306 | return 0; | 297 | return 0; |
307 | 298 | ||
308 | unsol = kzalloc(sizeof(*unsol), GFP_KERNEL); | 299 | unsol = kzalloc(sizeof(*unsol), GFP_KERNEL); |
309 | if (! unsol) { | 300 | if (!unsol) { |
310 | snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n"); | 301 | snd_printk(KERN_ERR "hda_codec: " |
302 | "can't allocate unsolicited queue\n"); | ||
311 | return -ENOMEM; | 303 | return -ENOMEM; |
312 | } | 304 | } |
313 | INIT_WORK(&unsol->work, process_unsol_events); | 305 | INIT_WORK(&unsol->work, process_unsol_events); |
@@ -323,16 +315,15 @@ static void snd_hda_codec_free(struct hda_codec *codec); | |||
323 | 315 | ||
324 | static int snd_hda_bus_free(struct hda_bus *bus) | 316 | static int snd_hda_bus_free(struct hda_bus *bus) |
325 | { | 317 | { |
326 | struct list_head *p, *n; | 318 | struct hda_codec *codec, *n; |
327 | 319 | ||
328 | if (! bus) | 320 | if (!bus) |
329 | return 0; | 321 | return 0; |
330 | if (bus->unsol) { | 322 | if (bus->unsol) { |
331 | flush_scheduled_work(); | 323 | flush_scheduled_work(); |
332 | kfree(bus->unsol); | 324 | kfree(bus->unsol); |
333 | } | 325 | } |
334 | list_for_each_safe(p, n, &bus->codec_list) { | 326 | list_for_each_entry_safe(codec, n, &bus->codec_list, list) { |
335 | struct hda_codec *codec = list_entry(p, struct hda_codec, list); | ||
336 | snd_hda_codec_free(codec); | 327 | snd_hda_codec_free(codec); |
337 | } | 328 | } |
338 | if (bus->ops.private_free) | 329 | if (bus->ops.private_free) |
@@ -355,8 +346,9 @@ static int snd_hda_bus_dev_free(struct snd_device *device) | |||
355 | * | 346 | * |
356 | * Returns 0 if successful, or a negative error code. | 347 | * Returns 0 if successful, or a negative error code. |
357 | */ | 348 | */ |
358 | int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, | 349 | int __devinit snd_hda_bus_new(struct snd_card *card, |
359 | struct hda_bus **busp) | 350 | const struct hda_bus_template *temp, |
351 | struct hda_bus **busp) | ||
360 | { | 352 | { |
361 | struct hda_bus *bus; | 353 | struct hda_bus *bus; |
362 | int err; | 354 | int err; |
@@ -385,7 +377,8 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, | |||
385 | mutex_init(&bus->cmd_mutex); | 377 | mutex_init(&bus->cmd_mutex); |
386 | INIT_LIST_HEAD(&bus->codec_list); | 378 | INIT_LIST_HEAD(&bus->codec_list); |
387 | 379 | ||
388 | if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) { | 380 | err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops); |
381 | if (err < 0) { | ||
389 | snd_hda_bus_free(bus); | 382 | snd_hda_bus_free(bus); |
390 | return err; | 383 | return err; |
391 | } | 384 | } |
@@ -394,22 +387,24 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, | |||
394 | return 0; | 387 | return 0; |
395 | } | 388 | } |
396 | 389 | ||
397 | EXPORT_SYMBOL(snd_hda_bus_new); | ||
398 | |||
399 | /* | 390 | /* |
400 | * find a matching codec preset | 391 | * find a matching codec preset |
401 | */ | 392 | */ |
402 | static const struct hda_codec_preset *find_codec_preset(struct hda_codec *codec) | 393 | static const struct hda_codec_preset __devinit * |
394 | find_codec_preset(struct hda_codec *codec) | ||
403 | { | 395 | { |
404 | const struct hda_codec_preset **tbl, *preset; | 396 | const struct hda_codec_preset **tbl, *preset; |
405 | 397 | ||
398 | if (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic")) | ||
399 | return NULL; /* use the generic parser */ | ||
400 | |||
406 | for (tbl = hda_preset_tables; *tbl; tbl++) { | 401 | for (tbl = hda_preset_tables; *tbl; tbl++) { |
407 | for (preset = *tbl; preset->id; preset++) { | 402 | for (preset = *tbl; preset->id; preset++) { |
408 | u32 mask = preset->mask; | 403 | u32 mask = preset->mask; |
409 | if (! mask) | 404 | if (!mask) |
410 | mask = ~0; | 405 | mask = ~0; |
411 | if (preset->id == (codec->vendor_id & mask) && | 406 | if (preset->id == (codec->vendor_id & mask) && |
412 | (! preset->rev || | 407 | (!preset->rev || |
413 | preset->rev == codec->revision_id)) | 408 | preset->rev == codec->revision_id)) |
414 | return preset; | 409 | return preset; |
415 | } | 410 | } |
@@ -434,27 +429,30 @@ void snd_hda_get_codec_name(struct hda_codec *codec, | |||
434 | break; | 429 | break; |
435 | } | 430 | } |
436 | } | 431 | } |
437 | if (! vendor) { | 432 | if (!vendor) { |
438 | sprintf(tmp, "Generic %04x", vendor_id); | 433 | sprintf(tmp, "Generic %04x", vendor_id); |
439 | vendor = tmp; | 434 | vendor = tmp; |
440 | } | 435 | } |
441 | if (codec->preset && codec->preset->name) | 436 | if (codec->preset && codec->preset->name) |
442 | snprintf(name, namelen, "%s %s", vendor, codec->preset->name); | 437 | snprintf(name, namelen, "%s %s", vendor, codec->preset->name); |
443 | else | 438 | else |
444 | snprintf(name, namelen, "%s ID %x", vendor, codec->vendor_id & 0xffff); | 439 | snprintf(name, namelen, "%s ID %x", vendor, |
440 | codec->vendor_id & 0xffff); | ||
445 | } | 441 | } |
446 | 442 | ||
447 | /* | 443 | /* |
448 | * look for an AFG and MFG nodes | 444 | * look for an AFG and MFG nodes |
449 | */ | 445 | */ |
450 | static void setup_fg_nodes(struct hda_codec *codec) | 446 | static void __devinit setup_fg_nodes(struct hda_codec *codec) |
451 | { | 447 | { |
452 | int i, total_nodes; | 448 | int i, total_nodes; |
453 | hda_nid_t nid; | 449 | hda_nid_t nid; |
454 | 450 | ||
455 | total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); | 451 | total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); |
456 | for (i = 0; i < total_nodes; i++, nid++) { | 452 | for (i = 0; i < total_nodes; i++, nid++) { |
457 | switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) { | 453 | unsigned int func; |
454 | func = snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE); | ||
455 | switch (func & 0xff) { | ||
458 | case AC_GRP_AUDIO_FUNCTION: | 456 | case AC_GRP_AUDIO_FUNCTION: |
459 | codec->afg = nid; | 457 | codec->afg = nid; |
460 | break; | 458 | break; |
@@ -478,7 +476,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) | |||
478 | codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node, | 476 | codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node, |
479 | &codec->start_nid); | 477 | &codec->start_nid); |
480 | codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL); | 478 | codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL); |
481 | if (! codec->wcaps) | 479 | if (!codec->wcaps) |
482 | return -ENOMEM; | 480 | return -ENOMEM; |
483 | nid = codec->start_nid; | 481 | nid = codec->start_nid; |
484 | for (i = 0; i < codec->num_nodes; i++, nid++) | 482 | for (i = 0; i < codec->num_nodes; i++, nid++) |
@@ -493,7 +491,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) | |||
493 | */ | 491 | */ |
494 | static void snd_hda_codec_free(struct hda_codec *codec) | 492 | static void snd_hda_codec_free(struct hda_codec *codec) |
495 | { | 493 | { |
496 | if (! codec) | 494 | if (!codec) |
497 | return; | 495 | return; |
498 | list_del(&codec->list); | 496 | list_del(&codec->list); |
499 | codec->bus->caddr_tbl[codec->addr] = NULL; | 497 | codec->bus->caddr_tbl[codec->addr] = NULL; |
@@ -514,8 +512,8 @@ static void init_amp_hash(struct hda_codec *codec); | |||
514 | * | 512 | * |
515 | * Returns 0 if successful, or a negative error code. | 513 | * Returns 0 if successful, or a negative error code. |
516 | */ | 514 | */ |
517 | int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | 515 | int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, |
518 | struct hda_codec **codecp) | 516 | struct hda_codec **codecp) |
519 | { | 517 | { |
520 | struct hda_codec *codec; | 518 | struct hda_codec *codec; |
521 | char component[13]; | 519 | char component[13]; |
@@ -525,7 +523,8 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | |||
525 | snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL); | 523 | snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL); |
526 | 524 | ||
527 | if (bus->caddr_tbl[codec_addr]) { | 525 | if (bus->caddr_tbl[codec_addr]) { |
528 | snd_printk(KERN_ERR "hda_codec: address 0x%x is already occupied\n", codec_addr); | 526 | snd_printk(KERN_ERR "hda_codec: " |
527 | "address 0x%x is already occupied\n", codec_addr); | ||
529 | return -EBUSY; | 528 | return -EBUSY; |
530 | } | 529 | } |
531 | 530 | ||
@@ -543,18 +542,21 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | |||
543 | list_add_tail(&codec->list, &bus->codec_list); | 542 | list_add_tail(&codec->list, &bus->codec_list); |
544 | bus->caddr_tbl[codec_addr] = codec; | 543 | bus->caddr_tbl[codec_addr] = codec; |
545 | 544 | ||
546 | codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID); | 545 | codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, |
546 | AC_PAR_VENDOR_ID); | ||
547 | if (codec->vendor_id == -1) | 547 | if (codec->vendor_id == -1) |
548 | /* read again, hopefully the access method was corrected | 548 | /* read again, hopefully the access method was corrected |
549 | * in the last read... | 549 | * in the last read... |
550 | */ | 550 | */ |
551 | codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, | 551 | codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, |
552 | AC_PAR_VENDOR_ID); | 552 | AC_PAR_VENDOR_ID); |
553 | codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID); | 553 | codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, |
554 | codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID); | 554 | AC_PAR_SUBSYSTEM_ID); |
555 | codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, | ||
556 | AC_PAR_REV_ID); | ||
555 | 557 | ||
556 | setup_fg_nodes(codec); | 558 | setup_fg_nodes(codec); |
557 | if (! codec->afg && ! codec->mfg) { | 559 | if (!codec->afg && !codec->mfg) { |
558 | snd_printdd("hda_codec: no AFG or MFG node found\n"); | 560 | snd_printdd("hda_codec: no AFG or MFG node found\n"); |
559 | snd_hda_codec_free(codec); | 561 | snd_hda_codec_free(codec); |
560 | return -ENODEV; | 562 | return -ENODEV; |
@@ -566,15 +568,16 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | |||
566 | return -ENOMEM; | 568 | return -ENOMEM; |
567 | } | 569 | } |
568 | 570 | ||
569 | if (! codec->subsystem_id) { | 571 | if (!codec->subsystem_id) { |
570 | hda_nid_t nid = codec->afg ? codec->afg : codec->mfg; | 572 | hda_nid_t nid = codec->afg ? codec->afg : codec->mfg; |
571 | codec->subsystem_id = snd_hda_codec_read(codec, nid, 0, | 573 | codec->subsystem_id = |
572 | AC_VERB_GET_SUBSYSTEM_ID, | 574 | snd_hda_codec_read(codec, nid, 0, |
573 | 0); | 575 | AC_VERB_GET_SUBSYSTEM_ID, 0); |
574 | } | 576 | } |
575 | 577 | ||
576 | codec->preset = find_codec_preset(codec); | 578 | codec->preset = find_codec_preset(codec); |
577 | if (! *bus->card->mixername) | 579 | /* audio codec should override the mixer name */ |
580 | if (codec->afg || !*bus->card->mixername) | ||
578 | snd_hda_get_codec_name(codec, bus->card->mixername, | 581 | snd_hda_get_codec_name(codec, bus->card->mixername, |
579 | sizeof(bus->card->mixername)); | 582 | sizeof(bus->card->mixername)); |
580 | 583 | ||
@@ -600,8 +603,6 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | |||
600 | return 0; | 603 | return 0; |
601 | } | 604 | } |
602 | 605 | ||
603 | EXPORT_SYMBOL(snd_hda_codec_new); | ||
604 | |||
605 | /** | 606 | /** |
606 | * snd_hda_codec_setup_stream - set up the codec for streaming | 607 | * snd_hda_codec_setup_stream - set up the codec for streaming |
607 | * @codec: the CODEC to set up | 608 | * @codec: the CODEC to set up |
@@ -610,13 +611,15 @@ EXPORT_SYMBOL(snd_hda_codec_new); | |||
610 | * @channel_id: channel id to pass, zero based. | 611 | * @channel_id: channel id to pass, zero based. |
611 | * @format: stream format. | 612 | * @format: stream format. |
612 | */ | 613 | */ |
613 | void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, | 614 | void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, |
615 | u32 stream_tag, | ||
614 | int channel_id, int format) | 616 | int channel_id, int format) |
615 | { | 617 | { |
616 | if (! nid) | 618 | if (!nid) |
617 | return; | 619 | return; |
618 | 620 | ||
619 | snd_printdd("hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", | 621 | snd_printdd("hda_codec_setup_stream: " |
622 | "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", | ||
620 | nid, stream_tag, channel_id, format); | 623 | nid, stream_tag, channel_id, format); |
621 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, | 624 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, |
622 | (stream_tag << 4) | channel_id); | 625 | (stream_tag << 4) | channel_id); |
@@ -624,8 +627,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stre | |||
624 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); | 627 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); |
625 | } | 628 | } |
626 | 629 | ||
627 | EXPORT_SYMBOL(snd_hda_codec_setup_stream); | ||
628 | |||
629 | /* | 630 | /* |
630 | * amp access functions | 631 | * amp access functions |
631 | */ | 632 | */ |
@@ -636,7 +637,7 @@ EXPORT_SYMBOL(snd_hda_codec_setup_stream); | |||
636 | #define INFO_AMP_VOL(ch) (1 << (1 + (ch))) | 637 | #define INFO_AMP_VOL(ch) (1 << (1 + (ch))) |
637 | 638 | ||
638 | /* initialize the hash table */ | 639 | /* initialize the hash table */ |
639 | static void init_amp_hash(struct hda_codec *codec) | 640 | static void __devinit init_amp_hash(struct hda_codec *codec) |
640 | { | 641 | { |
641 | memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash)); | 642 | memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash)); |
642 | codec->num_amp_entries = 0; | 643 | codec->num_amp_entries = 0; |
@@ -662,15 +663,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key) | |||
662 | if (codec->num_amp_entries >= codec->amp_info_size) { | 663 | if (codec->num_amp_entries >= codec->amp_info_size) { |
663 | /* reallocate the array */ | 664 | /* reallocate the array */ |
664 | int new_size = codec->amp_info_size + 64; | 665 | int new_size = codec->amp_info_size + 64; |
665 | struct hda_amp_info *new_info = kcalloc(new_size, sizeof(struct hda_amp_info), | 666 | struct hda_amp_info *new_info; |
666 | GFP_KERNEL); | 667 | new_info = kcalloc(new_size, sizeof(struct hda_amp_info), |
667 | if (! new_info) { | 668 | GFP_KERNEL); |
668 | snd_printk(KERN_ERR "hda_codec: can't malloc amp_info\n"); | 669 | if (!new_info) { |
670 | snd_printk(KERN_ERR "hda_codec: " | ||
671 | "can't malloc amp_info\n"); | ||
669 | return NULL; | 672 | return NULL; |
670 | } | 673 | } |
671 | if (codec->amp_info) { | 674 | if (codec->amp_info) { |
672 | memcpy(new_info, codec->amp_info, | 675 | memcpy(new_info, codec->amp_info, |
673 | codec->amp_info_size * sizeof(struct hda_amp_info)); | 676 | codec->amp_info_size * |
677 | sizeof(struct hda_amp_info)); | ||
674 | kfree(codec->amp_info); | 678 | kfree(codec->amp_info); |
675 | } | 679 | } |
676 | codec->amp_info_size = new_size; | 680 | codec->amp_info_size = new_size; |
@@ -691,15 +695,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key) | |||
691 | */ | 695 | */ |
692 | static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) | 696 | static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) |
693 | { | 697 | { |
694 | struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0)); | 698 | struct hda_amp_info *info; |
695 | 699 | ||
696 | if (! info) | 700 | info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0)); |
701 | if (!info) | ||
697 | return 0; | 702 | return 0; |
698 | if (! (info->status & INFO_AMP_CAPS)) { | 703 | if (!(info->status & INFO_AMP_CAPS)) { |
699 | if (! (get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) | 704 | if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) |
700 | nid = codec->afg; | 705 | nid = codec->afg; |
701 | info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ? | 706 | info->amp_caps = snd_hda_param_read(codec, nid, |
702 | AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP); | 707 | direction == HDA_OUTPUT ? |
708 | AC_PAR_AMP_OUT_CAP : | ||
709 | AC_PAR_AMP_IN_CAP); | ||
703 | info->status |= INFO_AMP_CAPS; | 710 | info->status |= INFO_AMP_CAPS; |
704 | } | 711 | } |
705 | return info->amp_caps; | 712 | return info->amp_caps; |
@@ -709,8 +716,9 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) | |||
709 | * read the current volume to info | 716 | * read the current volume to info |
710 | * if the cache exists, read the cache value. | 717 | * if the cache exists, read the cache value. |
711 | */ | 718 | */ |
712 | static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, | 719 | static unsigned int get_vol_mute(struct hda_codec *codec, |
713 | hda_nid_t nid, int ch, int direction, int index) | 720 | struct hda_amp_info *info, hda_nid_t nid, |
721 | int ch, int direction, int index) | ||
714 | { | 722 | { |
715 | u32 val, parm; | 723 | u32 val, parm; |
716 | 724 | ||
@@ -720,7 +728,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i | |||
720 | parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT; | 728 | parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT; |
721 | parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; | 729 | parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; |
722 | parm |= index; | 730 | parm |= index; |
723 | val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, parm); | 731 | val = snd_hda_codec_read(codec, nid, 0, |
732 | AC_VERB_GET_AMP_GAIN_MUTE, parm); | ||
724 | info->vol[ch] = val & 0xff; | 733 | info->vol[ch] = val & 0xff; |
725 | info->status |= INFO_AMP_VOL(ch); | 734 | info->status |= INFO_AMP_VOL(ch); |
726 | return info->vol[ch]; | 735 | return info->vol[ch]; |
@@ -730,7 +739,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i | |||
730 | * write the current volume in info to the h/w and update the cache | 739 | * write the current volume in info to the h/w and update the cache |
731 | */ | 740 | */ |
732 | static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, | 741 | static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, |
733 | hda_nid_t nid, int ch, int direction, int index, int val) | 742 | hda_nid_t nid, int ch, int direction, int index, |
743 | int val) | ||
734 | { | 744 | { |
735 | u32 parm; | 745 | u32 parm; |
736 | 746 | ||
@@ -748,8 +758,9 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, | |||
748 | int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, | 758 | int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, |
749 | int direction, int index) | 759 | int direction, int index) |
750 | { | 760 | { |
751 | struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); | 761 | struct hda_amp_info *info; |
752 | if (! info) | 762 | info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); |
763 | if (!info) | ||
753 | return 0; | 764 | return 0; |
754 | return get_vol_mute(codec, info, nid, ch, direction, index); | 765 | return get_vol_mute(codec, info, nid, ch, direction, index); |
755 | } | 766 | } |
@@ -760,13 +771,14 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
760 | int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | 771 | int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, |
761 | int direction, int idx, int mask, int val) | 772 | int direction, int idx, int mask, int val) |
762 | { | 773 | { |
763 | struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); | 774 | struct hda_amp_info *info; |
764 | 775 | ||
765 | if (! info) | 776 | info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); |
777 | if (!info) | ||
766 | return 0; | 778 | return 0; |
767 | val &= mask; | 779 | val &= mask; |
768 | val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask; | 780 | val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask; |
769 | if (info->vol[ch] == val && ! codec->in_resume) | 781 | if (info->vol[ch] == val && !codec->in_resume) |
770 | return 0; | 782 | return 0; |
771 | put_vol_mute(codec, info, nid, ch, direction, idx, val); | 783 | put_vol_mute(codec, info, nid, ch, direction, idx, val); |
772 | return 1; | 784 | return 1; |
@@ -783,7 +795,8 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
783 | #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) | 795 | #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) |
784 | 796 | ||
785 | /* volume */ | 797 | /* volume */ |
786 | int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 798 | int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, |
799 | struct snd_ctl_elem_info *uinfo) | ||
787 | { | 800 | { |
788 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 801 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
789 | u16 nid = get_amp_nid(kcontrol); | 802 | u16 nid = get_amp_nid(kcontrol); |
@@ -792,9 +805,11 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
792 | u32 caps; | 805 | u32 caps; |
793 | 806 | ||
794 | caps = query_amp_caps(codec, nid, dir); | 807 | caps = query_amp_caps(codec, nid, dir); |
795 | caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; /* num steps */ | 808 | /* num steps */ |
796 | if (! caps) { | 809 | caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; |
797 | printk(KERN_WARNING "hda_codec: num_steps = 0 for NID=0x%x\n", nid); | 810 | if (!caps) { |
811 | printk(KERN_WARNING "hda_codec: " | ||
812 | "num_steps = 0 for NID=0x%x\n", nid); | ||
798 | return -EINVAL; | 813 | return -EINVAL; |
799 | } | 814 | } |
800 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 815 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
@@ -804,7 +819,8 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
804 | return 0; | 819 | return 0; |
805 | } | 820 | } |
806 | 821 | ||
807 | int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 822 | int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, |
823 | struct snd_ctl_elem_value *ucontrol) | ||
808 | { | 824 | { |
809 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 825 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
810 | hda_nid_t nid = get_amp_nid(kcontrol); | 826 | hda_nid_t nid = get_amp_nid(kcontrol); |
@@ -820,7 +836,8 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
820 | return 0; | 836 | return 0; |
821 | } | 837 | } |
822 | 838 | ||
823 | int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 839 | int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, |
840 | struct snd_ctl_elem_value *ucontrol) | ||
824 | { | 841 | { |
825 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 842 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
826 | hda_nid_t nid = get_amp_nid(kcontrol); | 843 | hda_nid_t nid = get_amp_nid(kcontrol); |
@@ -852,7 +869,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
852 | if (size < 4 * sizeof(unsigned int)) | 869 | if (size < 4 * sizeof(unsigned int)) |
853 | return -ENOMEM; | 870 | return -ENOMEM; |
854 | caps = query_amp_caps(codec, nid, dir); | 871 | caps = query_amp_caps(codec, nid, dir); |
855 | val2 = (((caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT) + 1) * 25; | 872 | val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT; |
873 | val2 = (val2 + 1) * 25; | ||
856 | val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); | 874 | val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); |
857 | val1 = ((int)val1) * ((int)val2); | 875 | val1 = ((int)val1) * ((int)val2); |
858 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) | 876 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) |
@@ -867,7 +885,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
867 | } | 885 | } |
868 | 886 | ||
869 | /* switch */ | 887 | /* switch */ |
870 | int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 888 | int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, |
889 | struct snd_ctl_elem_info *uinfo) | ||
871 | { | 890 | { |
872 | int chs = get_amp_channels(kcontrol); | 891 | int chs = get_amp_channels(kcontrol); |
873 | 892 | ||
@@ -878,7 +897,8 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
878 | return 0; | 897 | return 0; |
879 | } | 898 | } |
880 | 899 | ||
881 | int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 900 | int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, |
901 | struct snd_ctl_elem_value *ucontrol) | ||
882 | { | 902 | { |
883 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 903 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
884 | hda_nid_t nid = get_amp_nid(kcontrol); | 904 | hda_nid_t nid = get_amp_nid(kcontrol); |
@@ -888,13 +908,16 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
888 | long *valp = ucontrol->value.integer.value; | 908 | long *valp = ucontrol->value.integer.value; |
889 | 909 | ||
890 | if (chs & 1) | 910 | if (chs & 1) |
891 | *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x80) ? 0 : 1; | 911 | *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & |
912 | 0x80) ? 0 : 1; | ||
892 | if (chs & 2) | 913 | if (chs & 2) |
893 | *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x80) ? 0 : 1; | 914 | *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & |
915 | 0x80) ? 0 : 1; | ||
894 | return 0; | 916 | return 0; |
895 | } | 917 | } |
896 | 918 | ||
897 | int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 919 | int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, |
920 | struct snd_ctl_elem_value *ucontrol) | ||
898 | { | 921 | { |
899 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 922 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
900 | hda_nid_t nid = get_amp_nid(kcontrol); | 923 | hda_nid_t nid = get_amp_nid(kcontrol); |
@@ -925,7 +948,8 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
925 | #define AMP_VAL_IDX_SHIFT 19 | 948 | #define AMP_VAL_IDX_SHIFT 19 |
926 | #define AMP_VAL_IDX_MASK (0x0f<<19) | 949 | #define AMP_VAL_IDX_MASK (0x0f<<19) |
927 | 950 | ||
928 | int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 951 | int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, |
952 | struct snd_ctl_elem_value *ucontrol) | ||
929 | { | 953 | { |
930 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 954 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
931 | unsigned long pval; | 955 | unsigned long pval; |
@@ -940,7 +964,8 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
940 | return err; | 964 | return err; |
941 | } | 965 | } |
942 | 966 | ||
943 | int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 967 | int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, |
968 | struct snd_ctl_elem_value *ucontrol) | ||
944 | { | 969 | { |
945 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 970 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
946 | unsigned long pval; | 971 | unsigned long pval; |
@@ -950,7 +975,8 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
950 | pval = kcontrol->private_value; | 975 | pval = kcontrol->private_value; |
951 | indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; | 976 | indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; |
952 | for (i = 0; i < indices; i++) { | 977 | for (i = 0; i < indices; i++) { |
953 | kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT); | 978 | kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | |
979 | (i << AMP_VAL_IDX_SHIFT); | ||
954 | err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | 980 | err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); |
955 | if (err < 0) | 981 | if (err < 0) |
956 | break; | 982 | break; |
@@ -965,14 +991,16 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
965 | * SPDIF out controls | 991 | * SPDIF out controls |
966 | */ | 992 | */ |
967 | 993 | ||
968 | static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 994 | static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, |
995 | struct snd_ctl_elem_info *uinfo) | ||
969 | { | 996 | { |
970 | uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; | 997 | uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; |
971 | uinfo->count = 1; | 998 | uinfo->count = 1; |
972 | return 0; | 999 | return 0; |
973 | } | 1000 | } |
974 | 1001 | ||
975 | static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1002 | static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, |
1003 | struct snd_ctl_elem_value *ucontrol) | ||
976 | { | 1004 | { |
977 | ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL | | 1005 | ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL | |
978 | IEC958_AES0_NONAUDIO | | 1006 | IEC958_AES0_NONAUDIO | |
@@ -983,7 +1011,8 @@ static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
983 | return 0; | 1011 | return 0; |
984 | } | 1012 | } |
985 | 1013 | ||
986 | static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1014 | static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, |
1015 | struct snd_ctl_elem_value *ucontrol) | ||
987 | { | 1016 | { |
988 | ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL | | 1017 | ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL | |
989 | IEC958_AES0_NONAUDIO | | 1018 | IEC958_AES0_NONAUDIO | |
@@ -991,7 +1020,8 @@ static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
991 | return 0; | 1020 | return 0; |
992 | } | 1021 | } |
993 | 1022 | ||
994 | static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1023 | static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, |
1024 | struct snd_ctl_elem_value *ucontrol) | ||
995 | { | 1025 | { |
996 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1026 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
997 | 1027 | ||
@@ -1011,19 +1041,21 @@ static unsigned short convert_from_spdif_status(unsigned int sbits) | |||
1011 | unsigned short val = 0; | 1041 | unsigned short val = 0; |
1012 | 1042 | ||
1013 | if (sbits & IEC958_AES0_PROFESSIONAL) | 1043 | if (sbits & IEC958_AES0_PROFESSIONAL) |
1014 | val |= 1 << 6; | 1044 | val |= AC_DIG1_PROFESSIONAL; |
1015 | if (sbits & IEC958_AES0_NONAUDIO) | 1045 | if (sbits & IEC958_AES0_NONAUDIO) |
1016 | val |= 1 << 5; | 1046 | val |= AC_DIG1_NONAUDIO; |
1017 | if (sbits & IEC958_AES0_PROFESSIONAL) { | 1047 | if (sbits & IEC958_AES0_PROFESSIONAL) { |
1018 | if ((sbits & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015) | 1048 | if ((sbits & IEC958_AES0_PRO_EMPHASIS) == |
1019 | val |= 1 << 3; | 1049 | IEC958_AES0_PRO_EMPHASIS_5015) |
1050 | val |= AC_DIG1_EMPHASIS; | ||
1020 | } else { | 1051 | } else { |
1021 | if ((sbits & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_5015) | 1052 | if ((sbits & IEC958_AES0_CON_EMPHASIS) == |
1022 | val |= 1 << 3; | 1053 | IEC958_AES0_CON_EMPHASIS_5015) |
1023 | if (! (sbits & IEC958_AES0_CON_NOT_COPYRIGHT)) | 1054 | val |= AC_DIG1_EMPHASIS; |
1024 | val |= 1 << 4; | 1055 | if (!(sbits & IEC958_AES0_CON_NOT_COPYRIGHT)) |
1056 | val |= AC_DIG1_COPYRIGHT; | ||
1025 | if (sbits & (IEC958_AES1_CON_ORIGINAL << 8)) | 1057 | if (sbits & (IEC958_AES1_CON_ORIGINAL << 8)) |
1026 | val |= 1 << 7; | 1058 | val |= AC_DIG1_LEVEL; |
1027 | val |= sbits & (IEC958_AES1_CON_CATEGORY << 8); | 1059 | val |= sbits & (IEC958_AES1_CON_CATEGORY << 8); |
1028 | } | 1060 | } |
1029 | return val; | 1061 | return val; |
@@ -1035,26 +1067,27 @@ static unsigned int convert_to_spdif_status(unsigned short val) | |||
1035 | { | 1067 | { |
1036 | unsigned int sbits = 0; | 1068 | unsigned int sbits = 0; |
1037 | 1069 | ||
1038 | if (val & (1 << 5)) | 1070 | if (val & AC_DIG1_NONAUDIO) |
1039 | sbits |= IEC958_AES0_NONAUDIO; | 1071 | sbits |= IEC958_AES0_NONAUDIO; |
1040 | if (val & (1 << 6)) | 1072 | if (val & AC_DIG1_PROFESSIONAL) |
1041 | sbits |= IEC958_AES0_PROFESSIONAL; | 1073 | sbits |= IEC958_AES0_PROFESSIONAL; |
1042 | if (sbits & IEC958_AES0_PROFESSIONAL) { | 1074 | if (sbits & IEC958_AES0_PROFESSIONAL) { |
1043 | if (sbits & (1 << 3)) | 1075 | if (sbits & AC_DIG1_EMPHASIS) |
1044 | sbits |= IEC958_AES0_PRO_EMPHASIS_5015; | 1076 | sbits |= IEC958_AES0_PRO_EMPHASIS_5015; |
1045 | } else { | 1077 | } else { |
1046 | if (val & (1 << 3)) | 1078 | if (val & AC_DIG1_EMPHASIS) |
1047 | sbits |= IEC958_AES0_CON_EMPHASIS_5015; | 1079 | sbits |= IEC958_AES0_CON_EMPHASIS_5015; |
1048 | if (! (val & (1 << 4))) | 1080 | if (!(val & AC_DIG1_COPYRIGHT)) |
1049 | sbits |= IEC958_AES0_CON_NOT_COPYRIGHT; | 1081 | sbits |= IEC958_AES0_CON_NOT_COPYRIGHT; |
1050 | if (val & (1 << 7)) | 1082 | if (val & AC_DIG1_LEVEL) |
1051 | sbits |= (IEC958_AES1_CON_ORIGINAL << 8); | 1083 | sbits |= (IEC958_AES1_CON_ORIGINAL << 8); |
1052 | sbits |= val & (0x7f << 8); | 1084 | sbits |= val & (0x7f << 8); |
1053 | } | 1085 | } |
1054 | return sbits; | 1086 | return sbits; |
1055 | } | 1087 | } |
1056 | 1088 | ||
1057 | static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1089 | static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, |
1090 | struct snd_ctl_elem_value *ucontrol) | ||
1058 | { | 1091 | { |
1059 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1092 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1060 | hda_nid_t nid = kcontrol->private_value; | 1093 | hda_nid_t nid = kcontrol->private_value; |
@@ -1072,15 +1105,18 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c | |||
1072 | codec->spdif_ctls = val; | 1105 | codec->spdif_ctls = val; |
1073 | 1106 | ||
1074 | if (change || codec->in_resume) { | 1107 | if (change || codec->in_resume) { |
1075 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); | 1108 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, |
1076 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8); | 1109 | val & 0xff); |
1110 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, | ||
1111 | val >> 8); | ||
1077 | } | 1112 | } |
1078 | 1113 | ||
1079 | mutex_unlock(&codec->spdif_mutex); | 1114 | mutex_unlock(&codec->spdif_mutex); |
1080 | return change; | 1115 | return change; |
1081 | } | 1116 | } |
1082 | 1117 | ||
1083 | static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1118 | static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, |
1119 | struct snd_ctl_elem_info *uinfo) | ||
1084 | { | 1120 | { |
1085 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 1121 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
1086 | uinfo->count = 1; | 1122 | uinfo->count = 1; |
@@ -1089,15 +1125,17 @@ static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct s | |||
1089 | return 0; | 1125 | return 0; |
1090 | } | 1126 | } |
1091 | 1127 | ||
1092 | static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1128 | static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, |
1129 | struct snd_ctl_elem_value *ucontrol) | ||
1093 | { | 1130 | { |
1094 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1131 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1095 | 1132 | ||
1096 | ucontrol->value.integer.value[0] = codec->spdif_ctls & 1; | 1133 | ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE; |
1097 | return 0; | 1134 | return 0; |
1098 | } | 1135 | } |
1099 | 1136 | ||
1100 | static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1137 | static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, |
1138 | struct snd_ctl_elem_value *ucontrol) | ||
1101 | { | 1139 | { |
1102 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1140 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1103 | hda_nid_t nid = kcontrol->private_value; | 1141 | hda_nid_t nid = kcontrol->private_value; |
@@ -1105,16 +1143,21 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn | |||
1105 | int change; | 1143 | int change; |
1106 | 1144 | ||
1107 | mutex_lock(&codec->spdif_mutex); | 1145 | mutex_lock(&codec->spdif_mutex); |
1108 | val = codec->spdif_ctls & ~1; | 1146 | val = codec->spdif_ctls & ~AC_DIG1_ENABLE; |
1109 | if (ucontrol->value.integer.value[0]) | 1147 | if (ucontrol->value.integer.value[0]) |
1110 | val |= 1; | 1148 | val |= AC_DIG1_ENABLE; |
1111 | change = codec->spdif_ctls != val; | 1149 | change = codec->spdif_ctls != val; |
1112 | if (change || codec->in_resume) { | 1150 | if (change || codec->in_resume) { |
1113 | codec->spdif_ctls = val; | 1151 | codec->spdif_ctls = val; |
1114 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); | 1152 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, |
1115 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 1153 | val & 0xff); |
1116 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | | 1154 | /* unmute amp switch (if any) */ |
1117 | AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80)); | 1155 | if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) && |
1156 | (val & AC_DIG1_ENABLE)) | ||
1157 | snd_hda_codec_write(codec, nid, 0, | ||
1158 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
1159 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | | ||
1160 | AC_AMP_SET_OUTPUT); | ||
1118 | } | 1161 | } |
1119 | mutex_unlock(&codec->spdif_mutex); | 1162 | mutex_unlock(&codec->spdif_mutex); |
1120 | return change; | 1163 | return change; |
@@ -1162,7 +1205,8 @@ static struct snd_kcontrol_new dig_mixes[] = { | |||
1162 | * | 1205 | * |
1163 | * Returns 0 if successful, or a negative error code. | 1206 | * Returns 0 if successful, or a negative error code. |
1164 | */ | 1207 | */ |
1165 | int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) | 1208 | int __devinit snd_hda_create_spdif_out_ctls(struct hda_codec *codec, |
1209 | hda_nid_t nid) | ||
1166 | { | 1210 | { |
1167 | int err; | 1211 | int err; |
1168 | struct snd_kcontrol *kctl; | 1212 | struct snd_kcontrol *kctl; |
@@ -1171,10 +1215,12 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) | |||
1171 | for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { | 1215 | for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { |
1172 | kctl = snd_ctl_new1(dig_mix, codec); | 1216 | kctl = snd_ctl_new1(dig_mix, codec); |
1173 | kctl->private_value = nid; | 1217 | kctl->private_value = nid; |
1174 | if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) | 1218 | err = snd_ctl_add(codec->bus->card, kctl); |
1219 | if (err < 0) | ||
1175 | return err; | 1220 | return err; |
1176 | } | 1221 | } |
1177 | codec->spdif_ctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0); | 1222 | codec->spdif_ctls = |
1223 | snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0); | ||
1178 | codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); | 1224 | codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); |
1179 | return 0; | 1225 | return 0; |
1180 | } | 1226 | } |
@@ -1185,7 +1231,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) | |||
1185 | 1231 | ||
1186 | #define snd_hda_spdif_in_switch_info snd_hda_spdif_out_switch_info | 1232 | #define snd_hda_spdif_in_switch_info snd_hda_spdif_out_switch_info |
1187 | 1233 | ||
1188 | static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1234 | static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, |
1235 | struct snd_ctl_elem_value *ucontrol) | ||
1189 | { | 1236 | { |
1190 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1237 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1191 | 1238 | ||
@@ -1193,7 +1240,8 @@ static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd | |||
1193 | return 0; | 1240 | return 0; |
1194 | } | 1241 | } |
1195 | 1242 | ||
1196 | static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1243 | static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, |
1244 | struct snd_ctl_elem_value *ucontrol) | ||
1197 | { | 1245 | { |
1198 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1246 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1199 | hda_nid_t nid = kcontrol->private_value; | 1247 | hda_nid_t nid = kcontrol->private_value; |
@@ -1204,13 +1252,15 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd | |||
1204 | change = codec->spdif_in_enable != val; | 1252 | change = codec->spdif_in_enable != val; |
1205 | if (change || codec->in_resume) { | 1253 | if (change || codec->in_resume) { |
1206 | codec->spdif_in_enable = val; | 1254 | codec->spdif_in_enable = val; |
1207 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val); | 1255 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, |
1256 | val); | ||
1208 | } | 1257 | } |
1209 | mutex_unlock(&codec->spdif_mutex); | 1258 | mutex_unlock(&codec->spdif_mutex); |
1210 | return change; | 1259 | return change; |
1211 | } | 1260 | } |
1212 | 1261 | ||
1213 | static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1262 | static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, |
1263 | struct snd_ctl_elem_value *ucontrol) | ||
1214 | { | 1264 | { |
1215 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1265 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1216 | hda_nid_t nid = kcontrol->private_value; | 1266 | hda_nid_t nid = kcontrol->private_value; |
@@ -1254,7 +1304,8 @@ static struct snd_kcontrol_new dig_in_ctls[] = { | |||
1254 | * | 1304 | * |
1255 | * Returns 0 if successful, or a negative error code. | 1305 | * Returns 0 if successful, or a negative error code. |
1256 | */ | 1306 | */ |
1257 | int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) | 1307 | int __devinit snd_hda_create_spdif_in_ctls(struct hda_codec *codec, |
1308 | hda_nid_t nid) | ||
1258 | { | 1309 | { |
1259 | int err; | 1310 | int err; |
1260 | struct snd_kcontrol *kctl; | 1311 | struct snd_kcontrol *kctl; |
@@ -1263,10 +1314,13 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) | |||
1263 | for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) { | 1314 | for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) { |
1264 | kctl = snd_ctl_new1(dig_mix, codec); | 1315 | kctl = snd_ctl_new1(dig_mix, codec); |
1265 | kctl->private_value = nid; | 1316 | kctl->private_value = nid; |
1266 | if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) | 1317 | err = snd_ctl_add(codec->bus->card, kctl); |
1318 | if (err < 0) | ||
1267 | return err; | 1319 | return err; |
1268 | } | 1320 | } |
1269 | codec->spdif_in_enable = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & 1; | 1321 | codec->spdif_in_enable = |
1322 | snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & | ||
1323 | AC_DIG1_ENABLE; | ||
1270 | return 0; | 1324 | return 0; |
1271 | } | 1325 | } |
1272 | 1326 | ||
@@ -1304,15 +1358,14 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
1304 | * | 1358 | * |
1305 | * Returns 0 if successful, otherwise a negative error code. | 1359 | * Returns 0 if successful, otherwise a negative error code. |
1306 | */ | 1360 | */ |
1307 | int snd_hda_build_controls(struct hda_bus *bus) | 1361 | int __devinit snd_hda_build_controls(struct hda_bus *bus) |
1308 | { | 1362 | { |
1309 | struct list_head *p; | 1363 | struct hda_codec *codec; |
1310 | 1364 | ||
1311 | /* build controls */ | 1365 | /* build controls */ |
1312 | list_for_each(p, &bus->codec_list) { | 1366 | list_for_each_entry(codec, &bus->codec_list, list) { |
1313 | struct hda_codec *codec = list_entry(p, struct hda_codec, list); | ||
1314 | int err; | 1367 | int err; |
1315 | if (! codec->patch_ops.build_controls) | 1368 | if (!codec->patch_ops.build_controls) |
1316 | continue; | 1369 | continue; |
1317 | err = codec->patch_ops.build_controls(codec); | 1370 | err = codec->patch_ops.build_controls(codec); |
1318 | if (err < 0) | 1371 | if (err < 0) |
@@ -1320,13 +1373,12 @@ int snd_hda_build_controls(struct hda_bus *bus) | |||
1320 | } | 1373 | } |
1321 | 1374 | ||
1322 | /* initialize */ | 1375 | /* initialize */ |
1323 | list_for_each(p, &bus->codec_list) { | 1376 | list_for_each_entry(codec, &bus->codec_list, list) { |
1324 | struct hda_codec *codec = list_entry(p, struct hda_codec, list); | ||
1325 | int err; | 1377 | int err; |
1326 | hda_set_power_state(codec, | 1378 | hda_set_power_state(codec, |
1327 | codec->afg ? codec->afg : codec->mfg, | 1379 | codec->afg ? codec->afg : codec->mfg, |
1328 | AC_PWRST_D0); | 1380 | AC_PWRST_D0); |
1329 | if (! codec->patch_ops.init) | 1381 | if (!codec->patch_ops.init) |
1330 | continue; | 1382 | continue; |
1331 | err = codec->patch_ops.init(codec); | 1383 | err = codec->patch_ops.init(codec); |
1332 | if (err < 0) | 1384 | if (err < 0) |
@@ -1335,8 +1387,6 @@ int snd_hda_build_controls(struct hda_bus *bus) | |||
1335 | return 0; | 1387 | return 0; |
1336 | } | 1388 | } |
1337 | 1389 | ||
1338 | EXPORT_SYMBOL(snd_hda_build_controls); | ||
1339 | |||
1340 | /* | 1390 | /* |
1341 | * stream formats | 1391 | * stream formats |
1342 | */ | 1392 | */ |
@@ -1361,6 +1411,11 @@ static struct hda_rate_tbl rate_bits[] = { | |||
1361 | { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ | 1411 | { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ |
1362 | { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ | 1412 | { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ |
1363 | { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ | 1413 | { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ |
1414 | #define AC_PAR_PCM_RATE_BITS 11 | ||
1415 | /* up to bits 10, 384kHZ isn't supported properly */ | ||
1416 | |||
1417 | /* not autodetected value */ | ||
1418 | { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */ | ||
1364 | 1419 | ||
1365 | { 0 } /* terminator */ | 1420 | { 0 } /* terminator */ |
1366 | }; | 1421 | }; |
@@ -1389,7 +1444,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
1389 | val = rate_bits[i].hda_fmt; | 1444 | val = rate_bits[i].hda_fmt; |
1390 | break; | 1445 | break; |
1391 | } | 1446 | } |
1392 | if (! rate_bits[i].hz) { | 1447 | if (!rate_bits[i].hz) { |
1393 | snd_printdd("invalid rate %d\n", rate); | 1448 | snd_printdd("invalid rate %d\n", rate); |
1394 | return 0; | 1449 | return 0; |
1395 | } | 1450 | } |
@@ -1414,15 +1469,14 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
1414 | val |= 0x20; | 1469 | val |= 0x20; |
1415 | break; | 1470 | break; |
1416 | default: | 1471 | default: |
1417 | snd_printdd("invalid format width %d\n", snd_pcm_format_width(format)); | 1472 | snd_printdd("invalid format width %d\n", |
1473 | snd_pcm_format_width(format)); | ||
1418 | return 0; | 1474 | return 0; |
1419 | } | 1475 | } |
1420 | 1476 | ||
1421 | return val; | 1477 | return val; |
1422 | } | 1478 | } |
1423 | 1479 | ||
1424 | EXPORT_SYMBOL(snd_hda_calc_stream_format); | ||
1425 | |||
1426 | /** | 1480 | /** |
1427 | * snd_hda_query_supported_pcm - query the supported PCM rates and formats | 1481 | * snd_hda_query_supported_pcm - query the supported PCM rates and formats |
1428 | * @codec: the HDA codec | 1482 | * @codec: the HDA codec |
@@ -1449,12 +1503,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
1449 | if (val == -1) | 1503 | if (val == -1) |
1450 | return -EIO; | 1504 | return -EIO; |
1451 | } | 1505 | } |
1452 | if (! val) | 1506 | if (!val) |
1453 | val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); | 1507 | val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); |
1454 | 1508 | ||
1455 | if (ratesp) { | 1509 | if (ratesp) { |
1456 | u32 rates = 0; | 1510 | u32 rates = 0; |
1457 | for (i = 0; rate_bits[i].hz; i++) { | 1511 | for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) { |
1458 | if (val & (1 << i)) | 1512 | if (val & (1 << i)) |
1459 | rates |= rate_bits[i].alsa_bits; | 1513 | rates |= rate_bits[i].alsa_bits; |
1460 | } | 1514 | } |
@@ -1470,8 +1524,9 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
1470 | streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); | 1524 | streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); |
1471 | if (streams == -1) | 1525 | if (streams == -1) |
1472 | return -EIO; | 1526 | return -EIO; |
1473 | if (! streams) { | 1527 | if (!streams) { |
1474 | streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); | 1528 | streams = snd_hda_param_read(codec, codec->afg, |
1529 | AC_PAR_STREAM); | ||
1475 | if (streams == -1) | 1530 | if (streams == -1) |
1476 | return -EIO; | 1531 | return -EIO; |
1477 | } | 1532 | } |
@@ -1495,7 +1550,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
1495 | bps = 24; | 1550 | bps = 24; |
1496 | else if (val & AC_SUPPCM_BITS_20) | 1551 | else if (val & AC_SUPPCM_BITS_20) |
1497 | bps = 20; | 1552 | bps = 20; |
1498 | } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|AC_SUPPCM_BITS_32)) { | 1553 | } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24| |
1554 | AC_SUPPCM_BITS_32)) { | ||
1499 | formats |= SNDRV_PCM_FMTBIT_S32_LE; | 1555 | formats |= SNDRV_PCM_FMTBIT_S32_LE; |
1500 | if (val & AC_SUPPCM_BITS_32) | 1556 | if (val & AC_SUPPCM_BITS_32) |
1501 | bps = 32; | 1557 | bps = 32; |
@@ -1505,10 +1561,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
1505 | bps = 20; | 1561 | bps = 20; |
1506 | } | 1562 | } |
1507 | } | 1563 | } |
1508 | else if (streams == AC_SUPFMT_FLOAT32) { /* should be exclusive */ | 1564 | else if (streams == AC_SUPFMT_FLOAT32) { |
1565 | /* should be exclusive */ | ||
1509 | formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; | 1566 | formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; |
1510 | bps = 32; | 1567 | bps = 32; |
1511 | } else if (streams == AC_SUPFMT_AC3) { /* should be exclusive */ | 1568 | } else if (streams == AC_SUPFMT_AC3) { |
1569 | /* should be exclusive */ | ||
1512 | /* temporary hack: we have still no proper support | 1570 | /* temporary hack: we have still no proper support |
1513 | * for the direct AC3 stream... | 1571 | * for the direct AC3 stream... |
1514 | */ | 1572 | */ |
@@ -1525,7 +1583,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
1525 | } | 1583 | } |
1526 | 1584 | ||
1527 | /** | 1585 | /** |
1528 | * snd_hda_is_supported_format - check whether the given node supports the format val | 1586 | * snd_hda_is_supported_format - check whether the given node supports |
1587 | * the format val | ||
1529 | * | 1588 | * |
1530 | * Returns 1 if supported, 0 if not. | 1589 | * Returns 1 if supported, 0 if not. |
1531 | */ | 1590 | */ |
@@ -1541,50 +1600,50 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, | |||
1541 | if (val == -1) | 1600 | if (val == -1) |
1542 | return 0; | 1601 | return 0; |
1543 | } | 1602 | } |
1544 | if (! val) { | 1603 | if (!val) { |
1545 | val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); | 1604 | val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); |
1546 | if (val == -1) | 1605 | if (val == -1) |
1547 | return 0; | 1606 | return 0; |
1548 | } | 1607 | } |
1549 | 1608 | ||
1550 | rate = format & 0xff00; | 1609 | rate = format & 0xff00; |
1551 | for (i = 0; rate_bits[i].hz; i++) | 1610 | for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) |
1552 | if (rate_bits[i].hda_fmt == rate) { | 1611 | if (rate_bits[i].hda_fmt == rate) { |
1553 | if (val & (1 << i)) | 1612 | if (val & (1 << i)) |
1554 | break; | 1613 | break; |
1555 | return 0; | 1614 | return 0; |
1556 | } | 1615 | } |
1557 | if (! rate_bits[i].hz) | 1616 | if (i >= AC_PAR_PCM_RATE_BITS) |
1558 | return 0; | 1617 | return 0; |
1559 | 1618 | ||
1560 | stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); | 1619 | stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); |
1561 | if (stream == -1) | 1620 | if (stream == -1) |
1562 | return 0; | 1621 | return 0; |
1563 | if (! stream && nid != codec->afg) | 1622 | if (!stream && nid != codec->afg) |
1564 | stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); | 1623 | stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); |
1565 | if (! stream || stream == -1) | 1624 | if (!stream || stream == -1) |
1566 | return 0; | 1625 | return 0; |
1567 | 1626 | ||
1568 | if (stream & AC_SUPFMT_PCM) { | 1627 | if (stream & AC_SUPFMT_PCM) { |
1569 | switch (format & 0xf0) { | 1628 | switch (format & 0xf0) { |
1570 | case 0x00: | 1629 | case 0x00: |
1571 | if (! (val & AC_SUPPCM_BITS_8)) | 1630 | if (!(val & AC_SUPPCM_BITS_8)) |
1572 | return 0; | 1631 | return 0; |
1573 | break; | 1632 | break; |
1574 | case 0x10: | 1633 | case 0x10: |
1575 | if (! (val & AC_SUPPCM_BITS_16)) | 1634 | if (!(val & AC_SUPPCM_BITS_16)) |
1576 | return 0; | 1635 | return 0; |
1577 | break; | 1636 | break; |
1578 | case 0x20: | 1637 | case 0x20: |
1579 | if (! (val & AC_SUPPCM_BITS_20)) | 1638 | if (!(val & AC_SUPPCM_BITS_20)) |
1580 | return 0; | 1639 | return 0; |
1581 | break; | 1640 | break; |
1582 | case 0x30: | 1641 | case 0x30: |
1583 | if (! (val & AC_SUPPCM_BITS_24)) | 1642 | if (!(val & AC_SUPPCM_BITS_24)) |
1584 | return 0; | 1643 | return 0; |
1585 | break; | 1644 | break; |
1586 | case 0x40: | 1645 | case 0x40: |
1587 | if (! (val & AC_SUPPCM_BITS_32)) | 1646 | if (!(val & AC_SUPPCM_BITS_32)) |
1588 | return 0; | 1647 | return 0; |
1589 | break; | 1648 | break; |
1590 | default: | 1649 | default: |
@@ -1625,15 +1684,15 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo, | |||
1625 | return 0; | 1684 | return 0; |
1626 | } | 1685 | } |
1627 | 1686 | ||
1628 | static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream *info) | 1687 | static int __devinit set_pcm_default_values(struct hda_codec *codec, |
1688 | struct hda_pcm_stream *info) | ||
1629 | { | 1689 | { |
1630 | if (info->nid) { | 1690 | /* query support PCM information from the given NID */ |
1631 | /* query support PCM information from the given NID */ | 1691 | if (info->nid && (!info->rates || !info->formats)) { |
1632 | if (! info->rates || ! info->formats) | 1692 | snd_hda_query_supported_pcm(codec, info->nid, |
1633 | snd_hda_query_supported_pcm(codec, info->nid, | 1693 | info->rates ? NULL : &info->rates, |
1634 | info->rates ? NULL : &info->rates, | 1694 | info->formats ? NULL : &info->formats, |
1635 | info->formats ? NULL : &info->formats, | 1695 | info->maxbps ? NULL : &info->maxbps); |
1636 | info->maxbps ? NULL : &info->maxbps); | ||
1637 | } | 1696 | } |
1638 | if (info->ops.open == NULL) | 1697 | if (info->ops.open == NULL) |
1639 | info->ops.open = hda_pcm_default_open_close; | 1698 | info->ops.open = hda_pcm_default_open_close; |
@@ -1676,15 +1735,14 @@ static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream | |||
1676 | * | 1735 | * |
1677 | * This function returns 0 if successfull, or a negative error code. | 1736 | * This function returns 0 if successfull, or a negative error code. |
1678 | */ | 1737 | */ |
1679 | int snd_hda_build_pcms(struct hda_bus *bus) | 1738 | int __devinit snd_hda_build_pcms(struct hda_bus *bus) |
1680 | { | 1739 | { |
1681 | struct list_head *p; | 1740 | struct hda_codec *codec; |
1682 | 1741 | ||
1683 | list_for_each(p, &bus->codec_list) { | 1742 | list_for_each_entry(codec, &bus->codec_list, list) { |
1684 | struct hda_codec *codec = list_entry(p, struct hda_codec, list); | ||
1685 | unsigned int pcm, s; | 1743 | unsigned int pcm, s; |
1686 | int err; | 1744 | int err; |
1687 | if (! codec->patch_ops.build_pcms) | 1745 | if (!codec->patch_ops.build_pcms) |
1688 | continue; | 1746 | continue; |
1689 | err = codec->patch_ops.build_pcms(codec); | 1747 | err = codec->patch_ops.build_pcms(codec); |
1690 | if (err < 0) | 1748 | if (err < 0) |
@@ -1693,7 +1751,7 @@ int snd_hda_build_pcms(struct hda_bus *bus) | |||
1693 | for (s = 0; s < 2; s++) { | 1751 | for (s = 0; s < 2; s++) { |
1694 | struct hda_pcm_stream *info; | 1752 | struct hda_pcm_stream *info; |
1695 | info = &codec->pcm_info[pcm].stream[s]; | 1753 | info = &codec->pcm_info[pcm].stream[s]; |
1696 | if (! info->substreams) | 1754 | if (!info->substreams) |
1697 | continue; | 1755 | continue; |
1698 | err = set_pcm_default_values(codec, info); | 1756 | err = set_pcm_default_values(codec, info); |
1699 | if (err < 0) | 1757 | if (err < 0) |
@@ -1704,8 +1762,6 @@ int snd_hda_build_pcms(struct hda_bus *bus) | |||
1704 | return 0; | 1762 | return 0; |
1705 | } | 1763 | } |
1706 | 1764 | ||
1707 | EXPORT_SYMBOL(snd_hda_build_pcms); | ||
1708 | |||
1709 | /** | 1765 | /** |
1710 | * snd_hda_check_board_config - compare the current codec with the config table | 1766 | * snd_hda_check_board_config - compare the current codec with the config table |
1711 | * @codec: the HDA codec | 1767 | * @codec: the HDA codec |
@@ -1719,9 +1775,9 @@ EXPORT_SYMBOL(snd_hda_build_pcms); | |||
1719 | * | 1775 | * |
1720 | * If no entries are matching, the function returns a negative value. | 1776 | * If no entries are matching, the function returns a negative value. |
1721 | */ | 1777 | */ |
1722 | int snd_hda_check_board_config(struct hda_codec *codec, | 1778 | int __devinit snd_hda_check_board_config(struct hda_codec *codec, |
1723 | int num_configs, const char **models, | 1779 | int num_configs, const char **models, |
1724 | const struct snd_pci_quirk *tbl) | 1780 | const struct snd_pci_quirk *tbl) |
1725 | { | 1781 | { |
1726 | if (codec->bus->modelname && models) { | 1782 | if (codec->bus->modelname && models) { |
1727 | int i; | 1783 | int i; |
@@ -1771,24 +1827,26 @@ int snd_hda_check_board_config(struct hda_codec *codec, | |||
1771 | * | 1827 | * |
1772 | * Returns 0 if successful, or a negative error code. | 1828 | * Returns 0 if successful, or a negative error code. |
1773 | */ | 1829 | */ |
1774 | int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) | 1830 | int __devinit snd_hda_add_new_ctls(struct hda_codec *codec, |
1831 | struct snd_kcontrol_new *knew) | ||
1775 | { | 1832 | { |
1776 | int err; | 1833 | int err; |
1777 | 1834 | ||
1778 | for (; knew->name; knew++) { | 1835 | for (; knew->name; knew++) { |
1779 | struct snd_kcontrol *kctl; | 1836 | struct snd_kcontrol *kctl; |
1780 | kctl = snd_ctl_new1(knew, codec); | 1837 | kctl = snd_ctl_new1(knew, codec); |
1781 | if (! kctl) | 1838 | if (!kctl) |
1782 | return -ENOMEM; | 1839 | return -ENOMEM; |
1783 | err = snd_ctl_add(codec->bus->card, kctl); | 1840 | err = snd_ctl_add(codec->bus->card, kctl); |
1784 | if (err < 0) { | 1841 | if (err < 0) { |
1785 | if (! codec->addr) | 1842 | if (!codec->addr) |
1786 | return err; | 1843 | return err; |
1787 | kctl = snd_ctl_new1(knew, codec); | 1844 | kctl = snd_ctl_new1(knew, codec); |
1788 | if (! kctl) | 1845 | if (!kctl) |
1789 | return -ENOMEM; | 1846 | return -ENOMEM; |
1790 | kctl->id.device = codec->addr; | 1847 | kctl->id.device = codec->addr; |
1791 | if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) | 1848 | err = snd_ctl_add(codec->bus->card, kctl); |
1849 | if (err < 0) | ||
1792 | return err; | 1850 | return err; |
1793 | } | 1851 | } |
1794 | } | 1852 | } |
@@ -1799,8 +1857,10 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) | |||
1799 | /* | 1857 | /* |
1800 | * Channel mode helper | 1858 | * Channel mode helper |
1801 | */ | 1859 | */ |
1802 | int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, | 1860 | int snd_hda_ch_mode_info(struct hda_codec *codec, |
1803 | const struct hda_channel_mode *chmode, int num_chmodes) | 1861 | struct snd_ctl_elem_info *uinfo, |
1862 | const struct hda_channel_mode *chmode, | ||
1863 | int num_chmodes) | ||
1804 | { | 1864 | { |
1805 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1865 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
1806 | uinfo->count = 1; | 1866 | uinfo->count = 1; |
@@ -1812,8 +1872,10 @@ int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinf | |||
1812 | return 0; | 1872 | return 0; |
1813 | } | 1873 | } |
1814 | 1874 | ||
1815 | int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, | 1875 | int snd_hda_ch_mode_get(struct hda_codec *codec, |
1816 | const struct hda_channel_mode *chmode, int num_chmodes, | 1876 | struct snd_ctl_elem_value *ucontrol, |
1877 | const struct hda_channel_mode *chmode, | ||
1878 | int num_chmodes, | ||
1817 | int max_channels) | 1879 | int max_channels) |
1818 | { | 1880 | { |
1819 | int i; | 1881 | int i; |
@@ -1827,15 +1889,17 @@ int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucon | |||
1827 | return 0; | 1889 | return 0; |
1828 | } | 1890 | } |
1829 | 1891 | ||
1830 | int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, | 1892 | int snd_hda_ch_mode_put(struct hda_codec *codec, |
1831 | const struct hda_channel_mode *chmode, int num_chmodes, | 1893 | struct snd_ctl_elem_value *ucontrol, |
1894 | const struct hda_channel_mode *chmode, | ||
1895 | int num_chmodes, | ||
1832 | int *max_channelsp) | 1896 | int *max_channelsp) |
1833 | { | 1897 | { |
1834 | unsigned int mode; | 1898 | unsigned int mode; |
1835 | 1899 | ||
1836 | mode = ucontrol->value.enumerated.item[0]; | 1900 | mode = ucontrol->value.enumerated.item[0]; |
1837 | snd_assert(mode < num_chmodes, return -EINVAL); | 1901 | snd_assert(mode < num_chmodes, return -EINVAL); |
1838 | if (*max_channelsp == chmode[mode].channels && ! codec->in_resume) | 1902 | if (*max_channelsp == chmode[mode].channels && !codec->in_resume) |
1839 | return 0; | 1903 | return 0; |
1840 | /* change the current channel setting */ | 1904 | /* change the current channel setting */ |
1841 | *max_channelsp = chmode[mode].channels; | 1905 | *max_channelsp = chmode[mode].channels; |
@@ -1847,7 +1911,8 @@ int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucon | |||
1847 | /* | 1911 | /* |
1848 | * input MUX helper | 1912 | * input MUX helper |
1849 | */ | 1913 | */ |
1850 | int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo) | 1914 | int snd_hda_input_mux_info(const struct hda_input_mux *imux, |
1915 | struct snd_ctl_elem_info *uinfo) | ||
1851 | { | 1916 | { |
1852 | unsigned int index; | 1917 | unsigned int index; |
1853 | 1918 | ||
@@ -1861,8 +1926,10 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem | |||
1861 | return 0; | 1926 | return 0; |
1862 | } | 1927 | } |
1863 | 1928 | ||
1864 | int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, | 1929 | int snd_hda_input_mux_put(struct hda_codec *codec, |
1865 | struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, | 1930 | const struct hda_input_mux *imux, |
1931 | struct snd_ctl_elem_value *ucontrol, | ||
1932 | hda_nid_t nid, | ||
1866 | unsigned int *cur_val) | 1933 | unsigned int *cur_val) |
1867 | { | 1934 | { |
1868 | unsigned int idx; | 1935 | unsigned int idx; |
@@ -1870,7 +1937,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i | |||
1870 | idx = ucontrol->value.enumerated.item[0]; | 1937 | idx = ucontrol->value.enumerated.item[0]; |
1871 | if (idx >= imux->num_items) | 1938 | if (idx >= imux->num_items) |
1872 | idx = imux->num_items - 1; | 1939 | idx = imux->num_items - 1; |
1873 | if (*cur_val == idx && ! codec->in_resume) | 1940 | if (*cur_val == idx && !codec->in_resume) |
1874 | return 0; | 1941 | return 0; |
1875 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, | 1942 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, |
1876 | imux->items[idx].index); | 1943 | imux->items[idx].index); |
@@ -1883,25 +1950,53 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i | |||
1883 | * Multi-channel / digital-out PCM helper functions | 1950 | * Multi-channel / digital-out PCM helper functions |
1884 | */ | 1951 | */ |
1885 | 1952 | ||
1953 | /* setup SPDIF output stream */ | ||
1954 | static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, | ||
1955 | unsigned int stream_tag, unsigned int format) | ||
1956 | { | ||
1957 | /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ | ||
1958 | if (codec->spdif_ctls & AC_DIG1_ENABLE) | ||
1959 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, | ||
1960 | codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); | ||
1961 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); | ||
1962 | /* turn on again (if needed) */ | ||
1963 | if (codec->spdif_ctls & AC_DIG1_ENABLE) | ||
1964 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, | ||
1965 | codec->spdif_ctls & 0xff); | ||
1966 | } | ||
1967 | |||
1886 | /* | 1968 | /* |
1887 | * open the digital out in the exclusive mode | 1969 | * open the digital out in the exclusive mode |
1888 | */ | 1970 | */ |
1889 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout) | 1971 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, |
1972 | struct hda_multi_out *mout) | ||
1890 | { | 1973 | { |
1891 | mutex_lock(&codec->spdif_mutex); | 1974 | mutex_lock(&codec->spdif_mutex); |
1892 | if (mout->dig_out_used) { | 1975 | if (mout->dig_out_used == HDA_DIG_ANALOG_DUP) |
1893 | mutex_unlock(&codec->spdif_mutex); | 1976 | /* already opened as analog dup; reset it once */ |
1894 | return -EBUSY; /* already being used */ | 1977 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); |
1895 | } | ||
1896 | mout->dig_out_used = HDA_DIG_EXCLUSIVE; | 1978 | mout->dig_out_used = HDA_DIG_EXCLUSIVE; |
1897 | mutex_unlock(&codec->spdif_mutex); | 1979 | mutex_unlock(&codec->spdif_mutex); |
1898 | return 0; | 1980 | return 0; |
1899 | } | 1981 | } |
1900 | 1982 | ||
1983 | int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, | ||
1984 | struct hda_multi_out *mout, | ||
1985 | unsigned int stream_tag, | ||
1986 | unsigned int format, | ||
1987 | struct snd_pcm_substream *substream) | ||
1988 | { | ||
1989 | mutex_lock(&codec->spdif_mutex); | ||
1990 | setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format); | ||
1991 | mutex_unlock(&codec->spdif_mutex); | ||
1992 | return 0; | ||
1993 | } | ||
1994 | |||
1901 | /* | 1995 | /* |
1902 | * release the digital out | 1996 | * release the digital out |
1903 | */ | 1997 | */ |
1904 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout) | 1998 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, |
1999 | struct hda_multi_out *mout) | ||
1905 | { | 2000 | { |
1906 | mutex_lock(&codec->spdif_mutex); | 2001 | mutex_lock(&codec->spdif_mutex); |
1907 | mout->dig_out_used = 0; | 2002 | mout->dig_out_used = 0; |
@@ -1912,7 +2007,8 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *m | |||
1912 | /* | 2007 | /* |
1913 | * set up more restrictions for analog out | 2008 | * set up more restrictions for analog out |
1914 | */ | 2009 | */ |
1915 | int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, | 2010 | int snd_hda_multi_out_analog_open(struct hda_codec *codec, |
2011 | struct hda_multi_out *mout, | ||
1916 | struct snd_pcm_substream *substream) | 2012 | struct snd_pcm_substream *substream) |
1917 | { | 2013 | { |
1918 | substream->runtime->hw.channels_max = mout->max_channels; | 2014 | substream->runtime->hw.channels_max = mout->max_channels; |
@@ -1924,7 +2020,8 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out | |||
1924 | * set up the i/o for analog out | 2020 | * set up the i/o for analog out |
1925 | * when the digital out is available, copy the front out to digital out, too. | 2021 | * when the digital out is available, copy the front out to digital out, too. |
1926 | */ | 2022 | */ |
1927 | int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, | 2023 | int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, |
2024 | struct hda_multi_out *mout, | ||
1928 | unsigned int stream_tag, | 2025 | unsigned int stream_tag, |
1929 | unsigned int format, | 2026 | unsigned int format, |
1930 | struct snd_pcm_substream *substream) | 2027 | struct snd_pcm_substream *substream) |
@@ -1936,24 +2033,27 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o | |||
1936 | mutex_lock(&codec->spdif_mutex); | 2033 | mutex_lock(&codec->spdif_mutex); |
1937 | if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { | 2034 | if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { |
1938 | if (chs == 2 && | 2035 | if (chs == 2 && |
1939 | snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && | 2036 | snd_hda_is_supported_format(codec, mout->dig_out_nid, |
1940 | ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) { | 2037 | format) && |
2038 | !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { | ||
1941 | mout->dig_out_used = HDA_DIG_ANALOG_DUP; | 2039 | mout->dig_out_used = HDA_DIG_ANALOG_DUP; |
1942 | /* setup digital receiver */ | 2040 | setup_dig_out_stream(codec, mout->dig_out_nid, |
1943 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, | 2041 | stream_tag, format); |
1944 | stream_tag, 0, format); | ||
1945 | } else { | 2042 | } else { |
1946 | mout->dig_out_used = 0; | 2043 | mout->dig_out_used = 0; |
1947 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); | 2044 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, |
2045 | 0, 0, 0); | ||
1948 | } | 2046 | } |
1949 | } | 2047 | } |
1950 | mutex_unlock(&codec->spdif_mutex); | 2048 | mutex_unlock(&codec->spdif_mutex); |
1951 | 2049 | ||
1952 | /* front */ | 2050 | /* front */ |
1953 | snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format); | 2051 | snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, |
2052 | 0, format); | ||
1954 | if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]) | 2053 | if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]) |
1955 | /* headphone out will just decode front left/right (stereo) */ | 2054 | /* headphone out will just decode front left/right (stereo) */ |
1956 | snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format); | 2055 | snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, |
2056 | 0, format); | ||
1957 | /* extra outputs copied from front */ | 2057 | /* extra outputs copied from front */ |
1958 | for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) | 2058 | for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) |
1959 | if (mout->extra_out_nid[i]) | 2059 | if (mout->extra_out_nid[i]) |
@@ -1964,11 +2064,11 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o | |||
1964 | /* surrounds */ | 2064 | /* surrounds */ |
1965 | for (i = 1; i < mout->num_dacs; i++) { | 2065 | for (i = 1; i < mout->num_dacs; i++) { |
1966 | if (chs >= (i + 1) * 2) /* independent out */ | 2066 | if (chs >= (i + 1) * 2) /* independent out */ |
1967 | snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2, | 2067 | snd_hda_codec_setup_stream(codec, nids[i], stream_tag, |
1968 | format); | 2068 | i * 2, format); |
1969 | else /* copy front */ | 2069 | else /* copy front */ |
1970 | snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0, | 2070 | snd_hda_codec_setup_stream(codec, nids[i], stream_tag, |
1971 | format); | 2071 | 0, format); |
1972 | } | 2072 | } |
1973 | return 0; | 2073 | return 0; |
1974 | } | 2074 | } |
@@ -1976,7 +2076,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o | |||
1976 | /* | 2076 | /* |
1977 | * clean up the setting for analog out | 2077 | * clean up the setting for analog out |
1978 | */ | 2078 | */ |
1979 | int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout) | 2079 | int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, |
2080 | struct hda_multi_out *mout) | ||
1980 | { | 2081 | { |
1981 | hda_nid_t *nids = mout->dac_nids; | 2082 | hda_nid_t *nids = mout->dac_nids; |
1982 | int i; | 2083 | int i; |
@@ -2003,7 +2104,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_o | |||
2003 | * Helper for automatic ping configuration | 2104 | * Helper for automatic ping configuration |
2004 | */ | 2105 | */ |
2005 | 2106 | ||
2006 | static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) | 2107 | static int __devinit is_in_nid_list(hda_nid_t nid, hda_nid_t *list) |
2007 | { | 2108 | { |
2008 | for (; *list; list++) | 2109 | for (; *list; list++) |
2009 | if (*list == nid) | 2110 | if (*list == nid) |
@@ -2011,6 +2112,32 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) | |||
2011 | return 0; | 2112 | return 0; |
2012 | } | 2113 | } |
2013 | 2114 | ||
2115 | |||
2116 | /* | ||
2117 | * Sort an associated group of pins according to their sequence numbers. | ||
2118 | */ | ||
2119 | static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences, | ||
2120 | int num_pins) | ||
2121 | { | ||
2122 | int i, j; | ||
2123 | short seq; | ||
2124 | hda_nid_t nid; | ||
2125 | |||
2126 | for (i = 0; i < num_pins; i++) { | ||
2127 | for (j = i + 1; j < num_pins; j++) { | ||
2128 | if (sequences[i] > sequences[j]) { | ||
2129 | seq = sequences[i]; | ||
2130 | sequences[i] = sequences[j]; | ||
2131 | sequences[j] = seq; | ||
2132 | nid = pins[i]; | ||
2133 | pins[i] = pins[j]; | ||
2134 | pins[j] = nid; | ||
2135 | } | ||
2136 | } | ||
2137 | } | ||
2138 | } | ||
2139 | |||
2140 | |||
2014 | /* | 2141 | /* |
2015 | * Parse all pin widgets and store the useful pin nids to cfg | 2142 | * Parse all pin widgets and store the useful pin nids to cfg |
2016 | * | 2143 | * |
@@ -2028,22 +2155,27 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) | |||
2028 | * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, | 2155 | * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, |
2029 | * respectively. | 2156 | * respectively. |
2030 | */ | 2157 | */ |
2031 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, | 2158 | int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, |
2032 | hda_nid_t *ignore_nids) | 2159 | struct auto_pin_cfg *cfg, |
2160 | hda_nid_t *ignore_nids) | ||
2033 | { | 2161 | { |
2034 | hda_nid_t nid, nid_start; | 2162 | hda_nid_t nid, nid_start; |
2035 | int i, j, nodes; | 2163 | int nodes; |
2036 | short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)]; | 2164 | short seq, assoc_line_out, assoc_speaker; |
2165 | short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; | ||
2166 | short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; | ||
2037 | 2167 | ||
2038 | memset(cfg, 0, sizeof(*cfg)); | 2168 | memset(cfg, 0, sizeof(*cfg)); |
2039 | 2169 | ||
2040 | memset(sequences, 0, sizeof(sequences)); | 2170 | memset(sequences_line_out, 0, sizeof(sequences_line_out)); |
2041 | assoc_line_out = 0; | 2171 | memset(sequences_speaker, 0, sizeof(sequences_speaker)); |
2172 | assoc_line_out = assoc_speaker = 0; | ||
2042 | 2173 | ||
2043 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); | 2174 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); |
2044 | for (nid = nid_start; nid < nodes + nid_start; nid++) { | 2175 | for (nid = nid_start; nid < nodes + nid_start; nid++) { |
2045 | unsigned int wid_caps = get_wcaps(codec, nid); | 2176 | unsigned int wid_caps = get_wcaps(codec, nid); |
2046 | unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 2177 | unsigned int wid_type = |
2178 | (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
2047 | unsigned int def_conf; | 2179 | unsigned int def_conf; |
2048 | short assoc, loc; | 2180 | short assoc, loc; |
2049 | 2181 | ||
@@ -2054,7 +2186,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c | |||
2054 | if (ignore_nids && is_in_nid_list(nid, ignore_nids)) | 2186 | if (ignore_nids && is_in_nid_list(nid, ignore_nids)) |
2055 | continue; | 2187 | continue; |
2056 | 2188 | ||
2057 | def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); | 2189 | def_conf = snd_hda_codec_read(codec, nid, 0, |
2190 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
2058 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | 2191 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) |
2059 | continue; | 2192 | continue; |
2060 | loc = get_defcfg_location(def_conf); | 2193 | loc = get_defcfg_location(def_conf); |
@@ -2062,22 +2195,31 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c | |||
2062 | case AC_JACK_LINE_OUT: | 2195 | case AC_JACK_LINE_OUT: |
2063 | seq = get_defcfg_sequence(def_conf); | 2196 | seq = get_defcfg_sequence(def_conf); |
2064 | assoc = get_defcfg_association(def_conf); | 2197 | assoc = get_defcfg_association(def_conf); |
2065 | if (! assoc) | 2198 | if (!assoc) |
2066 | continue; | 2199 | continue; |
2067 | if (! assoc_line_out) | 2200 | if (!assoc_line_out) |
2068 | assoc_line_out = assoc; | 2201 | assoc_line_out = assoc; |
2069 | else if (assoc_line_out != assoc) | 2202 | else if (assoc_line_out != assoc) |
2070 | continue; | 2203 | continue; |
2071 | if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) | 2204 | if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) |
2072 | continue; | 2205 | continue; |
2073 | cfg->line_out_pins[cfg->line_outs] = nid; | 2206 | cfg->line_out_pins[cfg->line_outs] = nid; |
2074 | sequences[cfg->line_outs] = seq; | 2207 | sequences_line_out[cfg->line_outs] = seq; |
2075 | cfg->line_outs++; | 2208 | cfg->line_outs++; |
2076 | break; | 2209 | break; |
2077 | case AC_JACK_SPEAKER: | 2210 | case AC_JACK_SPEAKER: |
2211 | seq = get_defcfg_sequence(def_conf); | ||
2212 | assoc = get_defcfg_association(def_conf); | ||
2213 | if (! assoc) | ||
2214 | continue; | ||
2215 | if (! assoc_speaker) | ||
2216 | assoc_speaker = assoc; | ||
2217 | else if (assoc_speaker != assoc) | ||
2218 | continue; | ||
2078 | if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) | 2219 | if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) |
2079 | continue; | 2220 | continue; |
2080 | cfg->speaker_pins[cfg->speaker_outs] = nid; | 2221 | cfg->speaker_pins[cfg->speaker_outs] = nid; |
2222 | sequences_speaker[cfg->speaker_outs] = seq; | ||
2081 | cfg->speaker_outs++; | 2223 | cfg->speaker_outs++; |
2082 | break; | 2224 | break; |
2083 | case AC_JACK_HP_OUT: | 2225 | case AC_JACK_HP_OUT: |
@@ -2123,34 +2265,45 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c | |||
2123 | } | 2265 | } |
2124 | 2266 | ||
2125 | /* sort by sequence */ | 2267 | /* sort by sequence */ |
2126 | for (i = 0; i < cfg->line_outs; i++) | 2268 | sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out, |
2127 | for (j = i + 1; j < cfg->line_outs; j++) | 2269 | cfg->line_outs); |
2128 | if (sequences[i] > sequences[j]) { | 2270 | sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker, |
2129 | seq = sequences[i]; | 2271 | cfg->speaker_outs); |
2130 | sequences[i] = sequences[j]; | 2272 | |
2131 | sequences[j] = seq; | 2273 | /* |
2132 | nid = cfg->line_out_pins[i]; | 2274 | * FIX-UP: if no line-outs are detected, try to use speaker or HP pin |
2133 | cfg->line_out_pins[i] = cfg->line_out_pins[j]; | 2275 | * as a primary output |
2134 | cfg->line_out_pins[j] = nid; | 2276 | */ |
2135 | } | 2277 | if (!cfg->line_outs) { |
2278 | if (cfg->speaker_outs) { | ||
2279 | cfg->line_outs = cfg->speaker_outs; | ||
2280 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | ||
2281 | sizeof(cfg->speaker_pins)); | ||
2282 | cfg->speaker_outs = 0; | ||
2283 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | ||
2284 | cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; | ||
2285 | } else if (cfg->hp_outs) { | ||
2286 | cfg->line_outs = cfg->hp_outs; | ||
2287 | memcpy(cfg->line_out_pins, cfg->hp_pins, | ||
2288 | sizeof(cfg->hp_pins)); | ||
2289 | cfg->hp_outs = 0; | ||
2290 | memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); | ||
2291 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
2292 | } | ||
2293 | } | ||
2136 | 2294 | ||
2137 | /* Reorder the surround channels | 2295 | /* Reorder the surround channels |
2138 | * ALSA sequence is front/surr/clfe/side | 2296 | * ALSA sequence is front/surr/clfe/side |
2139 | * HDA sequence is: | 2297 | * HDA sequence is: |
2140 | * 4-ch: front/surr => OK as it is | 2298 | * 4-ch: front/surr => OK as it is |
2141 | * 6-ch: front/clfe/surr | 2299 | * 6-ch: front/clfe/surr |
2142 | * 8-ch: front/clfe/side/surr | 2300 | * 8-ch: front/clfe/rear/side|fc |
2143 | */ | 2301 | */ |
2144 | switch (cfg->line_outs) { | 2302 | switch (cfg->line_outs) { |
2145 | case 3: | 2303 | case 3: |
2146 | nid = cfg->line_out_pins[1]; | ||
2147 | cfg->line_out_pins[1] = cfg->line_out_pins[2]; | ||
2148 | cfg->line_out_pins[2] = nid; | ||
2149 | break; | ||
2150 | case 4: | 2304 | case 4: |
2151 | nid = cfg->line_out_pins[1]; | 2305 | nid = cfg->line_out_pins[1]; |
2152 | cfg->line_out_pins[1] = cfg->line_out_pins[3]; | 2306 | cfg->line_out_pins[1] = cfg->line_out_pins[2]; |
2153 | cfg->line_out_pins[3] = cfg->line_out_pins[2]; | ||
2154 | cfg->line_out_pins[2] = nid; | 2307 | cfg->line_out_pins[2] = nid; |
2155 | break; | 2308 | break; |
2156 | } | 2309 | } |
@@ -2179,26 +2332,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c | |||
2179 | cfg->input_pins[AUTO_PIN_CD], | 2332 | cfg->input_pins[AUTO_PIN_CD], |
2180 | cfg->input_pins[AUTO_PIN_AUX]); | 2333 | cfg->input_pins[AUTO_PIN_AUX]); |
2181 | 2334 | ||
2182 | /* | ||
2183 | * FIX-UP: if no line-outs are detected, try to use speaker or HP pin | ||
2184 | * as a primary output | ||
2185 | */ | ||
2186 | if (! cfg->line_outs) { | ||
2187 | if (cfg->speaker_outs) { | ||
2188 | cfg->line_outs = cfg->speaker_outs; | ||
2189 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | ||
2190 | sizeof(cfg->speaker_pins)); | ||
2191 | cfg->speaker_outs = 0; | ||
2192 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | ||
2193 | } else if (cfg->hp_outs) { | ||
2194 | cfg->line_outs = cfg->hp_outs; | ||
2195 | memcpy(cfg->line_out_pins, cfg->hp_pins, | ||
2196 | sizeof(cfg->hp_pins)); | ||
2197 | cfg->hp_outs = 0; | ||
2198 | memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); | ||
2199 | } | ||
2200 | } | ||
2201 | |||
2202 | return 0; | 2335 | return 0; |
2203 | } | 2336 | } |
2204 | 2337 | ||
@@ -2222,11 +2355,10 @@ const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = { | |||
2222 | */ | 2355 | */ |
2223 | int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) | 2356 | int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) |
2224 | { | 2357 | { |
2225 | struct list_head *p; | 2358 | struct hda_codec *codec; |
2226 | 2359 | ||
2227 | /* FIXME: should handle power widget capabilities */ | 2360 | /* FIXME: should handle power widget capabilities */ |
2228 | list_for_each(p, &bus->codec_list) { | 2361 | list_for_each_entry(codec, &bus->codec_list, list) { |
2229 | struct hda_codec *codec = list_entry(p, struct hda_codec, list); | ||
2230 | if (codec->patch_ops.suspend) | 2362 | if (codec->patch_ops.suspend) |
2231 | codec->patch_ops.suspend(codec, state); | 2363 | codec->patch_ops.suspend(codec, state); |
2232 | hda_set_power_state(codec, | 2364 | hda_set_power_state(codec, |
@@ -2236,8 +2368,6 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) | |||
2236 | return 0; | 2368 | return 0; |
2237 | } | 2369 | } |
2238 | 2370 | ||
2239 | EXPORT_SYMBOL(snd_hda_suspend); | ||
2240 | |||
2241 | /** | 2371 | /** |
2242 | * snd_hda_resume - resume the codecs | 2372 | * snd_hda_resume - resume the codecs |
2243 | * @bus: the HDA bus | 2373 | * @bus: the HDA bus |
@@ -2247,10 +2377,9 @@ EXPORT_SYMBOL(snd_hda_suspend); | |||
2247 | */ | 2377 | */ |
2248 | int snd_hda_resume(struct hda_bus *bus) | 2378 | int snd_hda_resume(struct hda_bus *bus) |
2249 | { | 2379 | { |
2250 | struct list_head *p; | 2380 | struct hda_codec *codec; |
2251 | 2381 | ||
2252 | list_for_each(p, &bus->codec_list) { | 2382 | list_for_each_entry(codec, &bus->codec_list, list) { |
2253 | struct hda_codec *codec = list_entry(p, struct hda_codec, list); | ||
2254 | hda_set_power_state(codec, | 2383 | hda_set_power_state(codec, |
2255 | codec->afg ? codec->afg : codec->mfg, | 2384 | codec->afg ? codec->afg : codec->mfg, |
2256 | AC_PWRST_D0); | 2385 | AC_PWRST_D0); |
@@ -2260,8 +2389,6 @@ int snd_hda_resume(struct hda_bus *bus) | |||
2260 | return 0; | 2389 | return 0; |
2261 | } | 2390 | } |
2262 | 2391 | ||
2263 | EXPORT_SYMBOL(snd_hda_resume); | ||
2264 | |||
2265 | /** | 2392 | /** |
2266 | * snd_hda_resume_ctls - resume controls in the new control list | 2393 | * snd_hda_resume_ctls - resume controls in the new control list |
2267 | * @codec: the HDA codec | 2394 | * @codec: the HDA codec |
@@ -2276,7 +2403,7 @@ int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) | |||
2276 | struct snd_ctl_elem_value *val; | 2403 | struct snd_ctl_elem_value *val; |
2277 | 2404 | ||
2278 | val = kmalloc(sizeof(*val), GFP_KERNEL); | 2405 | val = kmalloc(sizeof(*val), GFP_KERNEL); |
2279 | if (! val) | 2406 | if (!val) |
2280 | return -ENOMEM; | 2407 | return -ENOMEM; |
2281 | codec->in_resume = 1; | 2408 | codec->in_resume = 1; |
2282 | for (; knew->name; knew++) { | 2409 | for (; knew->name; knew++) { |
@@ -2320,19 +2447,3 @@ int snd_hda_resume_spdif_in(struct hda_codec *codec) | |||
2320 | return snd_hda_resume_ctls(codec, dig_in_ctls); | 2447 | return snd_hda_resume_ctls(codec, dig_in_ctls); |
2321 | } | 2448 | } |
2322 | #endif | 2449 | #endif |
2323 | |||
2324 | /* | ||
2325 | * INIT part | ||
2326 | */ | ||
2327 | |||
2328 | static int __init alsa_hda_init(void) | ||
2329 | { | ||
2330 | return 0; | ||
2331 | } | ||
2332 | |||
2333 | static void __exit alsa_hda_exit(void) | ||
2334 | { | ||
2335 | } | ||
2336 | |||
2337 | module_init(alsa_hda_init) | ||
2338 | module_exit(alsa_hda_exit) | ||
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index c12bc4e8840f..56c26e7ccdf1 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -233,7 +233,7 @@ enum { | |||
233 | */ | 233 | */ |
234 | 234 | ||
235 | /* Amp gain/mute */ | 235 | /* Amp gain/mute */ |
236 | #define AC_AMP_MUTE (1<<8) | 236 | #define AC_AMP_MUTE (1<<7) |
237 | #define AC_AMP_GAIN (0x7f) | 237 | #define AC_AMP_GAIN (0x7f) |
238 | #define AC_AMP_GET_INDEX (0xf<<0) | 238 | #define AC_AMP_GET_INDEX (0xf<<0) |
239 | 239 | ||
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 1e5ff0cd3709..000287f7da43 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -133,7 +133,7 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid | |||
133 | return -ENOMEM; | 133 | return -ENOMEM; |
134 | } | 134 | } |
135 | } | 135 | } |
136 | memcpy(node->conn_list, conn_list, nconns); | 136 | memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t)); |
137 | node->nconns = nconns; | 137 | node->nconns = nconns; |
138 | node->wid_caps = get_wcaps(codec, nid); | 138 | node->wid_caps = get_wcaps(codec, nid); |
139 | node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 139 | node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1672cace1ae7..2fa281cbef91 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -88,6 +88,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | |||
88 | "{ATI, SB600}," | 88 | "{ATI, SB600}," |
89 | "{ATI, RS600}," | 89 | "{ATI, RS600}," |
90 | "{ATI, RS690}," | 90 | "{ATI, RS690}," |
91 | "{ATI, RS780}," | ||
92 | "{ATI, R600}," | ||
91 | "{VIA, VT8251}," | 93 | "{VIA, VT8251}," |
92 | "{VIA, VT8237A}," | 94 | "{VIA, VT8237A}," |
93 | "{SiS, SIS966}," | 95 | "{SiS, SIS966}," |
@@ -198,6 +200,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
198 | #define RIRB_INT_MASK 0x05 | 200 | #define RIRB_INT_MASK 0x05 |
199 | 201 | ||
200 | /* STATESTS int mask: SD2,SD1,SD0 */ | 202 | /* STATESTS int mask: SD2,SD1,SD0 */ |
203 | #define AZX_MAX_CODECS 3 | ||
201 | #define STATESTS_INT_MASK 0x07 | 204 | #define STATESTS_INT_MASK 0x07 |
202 | 205 | ||
203 | /* SD_CTL bits */ | 206 | /* SD_CTL bits */ |
@@ -978,7 +981,7 @@ static unsigned int azx_max_codecs[] __devinitdata = { | |||
978 | static int __devinit azx_codec_create(struct azx *chip, const char *model) | 981 | static int __devinit azx_codec_create(struct azx *chip, const char *model) |
979 | { | 982 | { |
980 | struct hda_bus_template bus_temp; | 983 | struct hda_bus_template bus_temp; |
981 | int c, codecs, err; | 984 | int c, codecs, audio_codecs, err; |
982 | 985 | ||
983 | memset(&bus_temp, 0, sizeof(bus_temp)); | 986 | memset(&bus_temp, 0, sizeof(bus_temp)); |
984 | bus_temp.private_data = chip; | 987 | bus_temp.private_data = chip; |
@@ -990,16 +993,30 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) | |||
990 | if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0) | 993 | if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0) |
991 | return err; | 994 | return err; |
992 | 995 | ||
993 | codecs = 0; | 996 | codecs = audio_codecs = 0; |
994 | for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) { | 997 | for (c = 0; c < AZX_MAX_CODECS; c++) { |
995 | if ((chip->codec_mask & (1 << c)) & probe_mask) { | 998 | if ((chip->codec_mask & (1 << c)) & probe_mask) { |
996 | err = snd_hda_codec_new(chip->bus, c, NULL); | 999 | struct hda_codec *codec; |
1000 | err = snd_hda_codec_new(chip->bus, c, &codec); | ||
997 | if (err < 0) | 1001 | if (err < 0) |
998 | continue; | 1002 | continue; |
999 | codecs++; | 1003 | codecs++; |
1004 | if (codec->afg) | ||
1005 | audio_codecs++; | ||
1000 | } | 1006 | } |
1001 | } | 1007 | } |
1002 | if (! codecs) { | 1008 | if (!audio_codecs) { |
1009 | /* probe additional slots if no codec is found */ | ||
1010 | for (; c < azx_max_codecs[chip->driver_type]; c++) { | ||
1011 | if ((chip->codec_mask & (1 << c)) & probe_mask) { | ||
1012 | err = snd_hda_codec_new(chip->bus, c, NULL); | ||
1013 | if (err < 0) | ||
1014 | continue; | ||
1015 | codecs++; | ||
1016 | } | ||
1017 | } | ||
1018 | } | ||
1019 | if (!codecs) { | ||
1003 | snd_printk(KERN_ERR SFX "no codecs initialized\n"); | 1020 | snd_printk(KERN_ERR SFX "no codecs initialized\n"); |
1004 | return -ENXIO; | 1021 | return -ENXIO; |
1005 | } | 1022 | } |
@@ -1518,7 +1535,7 @@ static int azx_dev_free(struct snd_device *device) | |||
1518 | /* | 1535 | /* |
1519 | * white/black-listing for position_fix | 1536 | * white/black-listing for position_fix |
1520 | */ | 1537 | */ |
1521 | static const struct snd_pci_quirk position_fix_list[] __devinitdata = { | 1538 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { |
1522 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE), | 1539 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE), |
1523 | {} | 1540 | {} |
1524 | }; | 1541 | }; |
@@ -1758,6 +1775,8 @@ static struct pci_device_id azx_ids[] = { | |||
1758 | { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */ | 1775 | { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */ |
1759 | { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */ | 1776 | { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */ |
1760 | { 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */ | 1777 | { 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */ |
1778 | { 0x1002, 0x960c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS780 HDMI */ | ||
1779 | { 0x1002, 0xaa00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI R600 HDMI */ | ||
1761 | { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ | 1780 | { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ |
1762 | { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ | 1781 | { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ |
1763 | { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ | 1782 | { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 39718d6cdadd..be12b8814c39 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -148,6 +148,11 @@ struct hda_multi_out { | |||
148 | 148 | ||
149 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); | 149 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); |
150 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); | 150 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); |
151 | int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, | ||
152 | struct hda_multi_out *mout, | ||
153 | unsigned int stream_tag, | ||
154 | unsigned int format, | ||
155 | struct snd_pcm_substream *substream); | ||
151 | int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, | 156 | int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, |
152 | struct snd_pcm_substream *substream); | 157 | struct snd_pcm_substream *substream); |
153 | int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, | 158 | int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, |
@@ -217,6 +222,12 @@ enum { | |||
217 | AUTO_PIN_LAST | 222 | AUTO_PIN_LAST |
218 | }; | 223 | }; |
219 | 224 | ||
225 | enum { | ||
226 | AUTO_PIN_LINE_OUT, | ||
227 | AUTO_PIN_SPEAKER_OUT, | ||
228 | AUTO_PIN_HP_OUT | ||
229 | }; | ||
230 | |||
220 | extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST]; | 231 | extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST]; |
221 | 232 | ||
222 | struct auto_pin_cfg { | 233 | struct auto_pin_cfg { |
@@ -225,6 +236,7 @@ struct auto_pin_cfg { | |||
225 | int speaker_outs; | 236 | int speaker_outs; |
226 | hda_nid_t speaker_pins[5]; | 237 | hda_nid_t speaker_pins[5]; |
227 | int hp_outs; | 238 | int hp_outs; |
239 | int line_out_type; /* AUTO_PIN_XXX_OUT */ | ||
228 | hda_nid_t hp_pins[5]; | 240 | hda_nid_t hp_pins[5]; |
229 | hda_nid_t input_pins[AUTO_PIN_LAST]; | 241 | hda_nid_t input_pins[AUTO_PIN_LAST]; |
230 | hda_nid_t dig_out_pin; | 242 | hda_nid_t dig_out_pin; |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index f94f1f22889e..0e1a879663fa 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -192,6 +192,17 @@ static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
192 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 192 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
193 | } | 193 | } |
194 | 194 | ||
195 | static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
196 | struct hda_codec *codec, | ||
197 | unsigned int stream_tag, | ||
198 | unsigned int format, | ||
199 | struct snd_pcm_substream *substream) | ||
200 | { | ||
201 | struct ad198x_spec *spec = codec->spec; | ||
202 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | ||
203 | format, substream); | ||
204 | } | ||
205 | |||
195 | /* | 206 | /* |
196 | * Analog capture | 207 | * Analog capture |
197 | */ | 208 | */ |
@@ -250,7 +261,8 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = { | |||
250 | .nid = 0, /* fill later */ | 261 | .nid = 0, /* fill later */ |
251 | .ops = { | 262 | .ops = { |
252 | .open = ad198x_dig_playback_pcm_open, | 263 | .open = ad198x_dig_playback_pcm_open, |
253 | .close = ad198x_dig_playback_pcm_close | 264 | .close = ad198x_dig_playback_pcm_close, |
265 | .prepare = ad198x_dig_playback_pcm_prepare | ||
254 | }, | 266 | }, |
255 | }; | 267 | }; |
256 | 268 | ||
@@ -739,41 +751,35 @@ static struct hda_verb ad1986a_init_verbs[] = { | |||
739 | { } /* end */ | 751 | { } /* end */ |
740 | }; | 752 | }; |
741 | 753 | ||
742 | /* additional verbs for 3-stack model */ | ||
743 | static struct hda_verb ad1986a_3st_init_verbs[] = { | ||
744 | /* Mic and line-in selectors */ | ||
745 | {0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, | ||
746 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
747 | { } /* end */ | ||
748 | }; | ||
749 | |||
750 | static struct hda_verb ad1986a_ch2_init[] = { | 754 | static struct hda_verb ad1986a_ch2_init[] = { |
751 | /* Surround out -> Line In */ | 755 | /* Surround out -> Line In */ |
752 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 756 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
753 | { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 757 | /* Line-in selectors */ |
758 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 }, | ||
754 | /* CLFE -> Mic in */ | 759 | /* CLFE -> Mic in */ |
755 | { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 760 | { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
756 | { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 761 | /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */ |
762 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, | ||
757 | { } /* end */ | 763 | { } /* end */ |
758 | }; | 764 | }; |
759 | 765 | ||
760 | static struct hda_verb ad1986a_ch4_init[] = { | 766 | static struct hda_verb ad1986a_ch4_init[] = { |
761 | /* Surround out -> Surround */ | 767 | /* Surround out -> Surround */ |
762 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 768 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
763 | { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 769 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, |
764 | /* CLFE -> Mic in */ | 770 | /* CLFE -> Mic in */ |
765 | { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 771 | { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
766 | { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 772 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, |
767 | { } /* end */ | 773 | { } /* end */ |
768 | }; | 774 | }; |
769 | 775 | ||
770 | static struct hda_verb ad1986a_ch6_init[] = { | 776 | static struct hda_verb ad1986a_ch6_init[] = { |
771 | /* Surround out -> Surround out */ | 777 | /* Surround out -> Surround out */ |
772 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 778 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
773 | { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 779 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, |
774 | /* CLFE -> CLFE */ | 780 | /* CLFE -> CLFE */ |
775 | { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 781 | { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
776 | { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 782 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 }, |
777 | { } /* end */ | 783 | { } /* end */ |
778 | }; | 784 | }; |
779 | 785 | ||
@@ -828,6 +834,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = { | |||
828 | SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD), | 834 | SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD), |
829 | SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD), | 835 | SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD), |
830 | SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD), | 836 | SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD), |
837 | SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK), | ||
831 | SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK), | 838 | SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK), |
832 | SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP), | 839 | SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP), |
833 | SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK), | 840 | SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK), |
@@ -882,9 +889,8 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
882 | case AD1986A_3STACK: | 889 | case AD1986A_3STACK: |
883 | spec->num_mixers = 2; | 890 | spec->num_mixers = 2; |
884 | spec->mixers[1] = ad1986a_3st_mixers; | 891 | spec->mixers[1] = ad1986a_3st_mixers; |
885 | spec->num_init_verbs = 3; | 892 | spec->num_init_verbs = 2; |
886 | spec->init_verbs[1] = ad1986a_3st_init_verbs; | 893 | spec->init_verbs[1] = ad1986a_ch2_init; |
887 | spec->init_verbs[2] = ad1986a_ch2_init; | ||
888 | spec->channel_mode = ad1986a_modes; | 894 | spec->channel_mode = ad1986a_modes; |
889 | spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes); | 895 | spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes); |
890 | spec->need_dac_fix = 1; | 896 | spec->need_dac_fix = 1; |
@@ -1892,8 +1898,9 @@ static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol, | |||
1892 | 1898 | ||
1893 | sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); | 1899 | sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); |
1894 | if (sel > 0) { | 1900 | if (sel > 0) { |
1895 | sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0); | 1901 | sel = snd_hda_codec_read(codec, 0x0b, 0, |
1896 | if (sel <= 3) | 1902 | AC_VERB_GET_CONNECT_SEL, 0); |
1903 | if (sel < 3) | ||
1897 | sel++; | 1904 | sel++; |
1898 | else | 1905 | else |
1899 | sel = 0; | 1906 | sel = 0; |
@@ -1906,23 +1913,27 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, | |||
1906 | struct snd_ctl_elem_value *ucontrol) | 1913 | struct snd_ctl_elem_value *ucontrol) |
1907 | { | 1914 | { |
1908 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1915 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1909 | unsigned int sel; | 1916 | unsigned int val, sel; |
1910 | int change; | 1917 | int change; |
1911 | 1918 | ||
1919 | val = ucontrol->value.enumerated.item[0]; | ||
1912 | sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); | 1920 | sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); |
1913 | if (! ucontrol->value.enumerated.item[0]) { | 1921 | if (!val) { |
1914 | change = sel != 0; | 1922 | change = sel != 0; |
1915 | if (change) | 1923 | if (change || codec->in_resume) |
1916 | snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 0); | 1924 | snd_hda_codec_write(codec, 0x02, 0, |
1925 | AC_VERB_SET_CONNECT_SEL, 0); | ||
1917 | } else { | 1926 | } else { |
1918 | change = sel == 0; | 1927 | change = sel == 0; |
1919 | if (change) | 1928 | if (change || codec->in_resume) |
1920 | snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 1); | 1929 | snd_hda_codec_write(codec, 0x02, 0, |
1921 | sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1; | 1930 | AC_VERB_SET_CONNECT_SEL, 1); |
1922 | change |= sel == ucontrol->value.enumerated.item[0]; | 1931 | sel = snd_hda_codec_read(codec, 0x0b, 0, |
1923 | if (change) | 1932 | AC_VERB_GET_CONNECT_SEL, 0) + 1; |
1924 | snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, | 1933 | change |= sel != val; |
1925 | ucontrol->value.enumerated.item[0] - 1); | 1934 | if (change || codec->in_resume) |
1935 | snd_hda_codec_write(codec, 0x0b, 0, | ||
1936 | AC_VERB_SET_CONNECT_SEL, val - 1); | ||
1926 | } | 1937 | } |
1927 | return change; | 1938 | return change; |
1928 | } | 1939 | } |
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c index 831469d3a923..f8eb4c90f801 100644 --- a/sound/pci/hda/patch_atihdmi.c +++ b/sound/pci/hda/patch_atihdmi.c | |||
@@ -94,6 +94,17 @@ static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
94 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 94 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
95 | } | 95 | } |
96 | 96 | ||
97 | static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
98 | struct hda_codec *codec, | ||
99 | unsigned int stream_tag, | ||
100 | unsigned int format, | ||
101 | struct snd_pcm_substream *substream) | ||
102 | { | ||
103 | struct atihdmi_spec *spec = codec->spec; | ||
104 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | ||
105 | format, substream); | ||
106 | } | ||
107 | |||
97 | static struct hda_pcm_stream atihdmi_pcm_digital_playback = { | 108 | static struct hda_pcm_stream atihdmi_pcm_digital_playback = { |
98 | .substreams = 1, | 109 | .substreams = 1, |
99 | .channels_min = 2, | 110 | .channels_min = 2, |
@@ -101,7 +112,8 @@ static struct hda_pcm_stream atihdmi_pcm_digital_playback = { | |||
101 | .nid = 0x2, /* NID to query formats and rates and setup streams */ | 112 | .nid = 0x2, /* NID to query formats and rates and setup streams */ |
102 | .ops = { | 113 | .ops = { |
103 | .open = atihdmi_dig_playback_pcm_open, | 114 | .open = atihdmi_dig_playback_pcm_open, |
104 | .close = atihdmi_dig_playback_pcm_close | 115 | .close = atihdmi_dig_playback_pcm_close, |
116 | .prepare = atihdmi_dig_playback_pcm_prepare | ||
105 | }, | 117 | }, |
106 | }; | 118 | }; |
107 | 119 | ||
@@ -160,6 +172,7 @@ static int patch_atihdmi(struct hda_codec *codec) | |||
160 | */ | 172 | */ |
161 | struct hda_codec_preset snd_hda_preset_atihdmi[] = { | 173 | struct hda_codec_preset snd_hda_preset_atihdmi[] = { |
162 | { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, | 174 | { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, |
163 | { .id = 0x1002791a, .name = "ATI RS690 HDMI", .patch = patch_atihdmi }, | 175 | { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, |
176 | { .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi }, | ||
164 | {} /* terminator */ | 177 | {} /* terminator */ |
165 | }; | 178 | }; |
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 5b9d3a31a1ae..3c722e667bc8 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -497,6 +497,17 @@ static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
497 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 497 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
498 | } | 498 | } |
499 | 499 | ||
500 | static int cmi9880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
501 | struct hda_codec *codec, | ||
502 | unsigned int stream_tag, | ||
503 | unsigned int format, | ||
504 | struct snd_pcm_substream *substream) | ||
505 | { | ||
506 | struct cmi_spec *spec = codec->spec; | ||
507 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | ||
508 | format, substream); | ||
509 | } | ||
510 | |||
500 | /* | 511 | /* |
501 | * Analog capture | 512 | * Analog capture |
502 | */ | 513 | */ |
@@ -556,7 +567,8 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = { | |||
556 | /* NID is set in cmi9880_build_pcms */ | 567 | /* NID is set in cmi9880_build_pcms */ |
557 | .ops = { | 568 | .ops = { |
558 | .open = cmi9880_dig_playback_pcm_open, | 569 | .open = cmi9880_dig_playback_pcm_open, |
559 | .close = cmi9880_dig_playback_pcm_close | 570 | .close = cmi9880_dig_playback_pcm_close, |
571 | .prepare = cmi9880_dig_playback_pcm_prepare | ||
560 | }, | 572 | }, |
561 | }; | 573 | }; |
562 | 574 | ||
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 46e93c6b9a42..a5a4b2bddf20 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -136,6 +136,18 @@ static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
136 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 136 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
137 | } | 137 | } |
138 | 138 | ||
139 | static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
140 | struct hda_codec *codec, | ||
141 | unsigned int stream_tag, | ||
142 | unsigned int format, | ||
143 | struct snd_pcm_substream *substream) | ||
144 | { | ||
145 | struct conexant_spec *spec = codec->spec; | ||
146 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
147 | stream_tag, | ||
148 | format, substream); | ||
149 | } | ||
150 | |||
139 | /* | 151 | /* |
140 | * Analog capture | 152 | * Analog capture |
141 | */ | 153 | */ |
@@ -194,7 +206,8 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = { | |||
194 | .nid = 0, /* fill later */ | 206 | .nid = 0, /* fill later */ |
195 | .ops = { | 207 | .ops = { |
196 | .open = conexant_dig_playback_pcm_open, | 208 | .open = conexant_dig_playback_pcm_open, |
197 | .close = conexant_dig_playback_pcm_close | 209 | .close = conexant_dig_playback_pcm_close, |
210 | .prepare = conexant_dig_playback_pcm_prepare | ||
198 | }, | 211 | }, |
199 | }; | 212 | }; |
200 | 213 | ||
@@ -452,115 +465,6 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
452 | .put = conexant_ch_mode_put, \ | 465 | .put = conexant_ch_mode_put, \ |
453 | .private_value = nid | (dir<<16) } | 466 | .private_value = nid | (dir<<16) } |
454 | 467 | ||
455 | static int cxt_gpio_data_info(struct snd_kcontrol *kcontrol, | ||
456 | struct snd_ctl_elem_info *uinfo) | ||
457 | { | ||
458 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
459 | uinfo->count = 1; | ||
460 | uinfo->value.integer.min = 0; | ||
461 | uinfo->value.integer.max = 1; | ||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | static int cxt_gpio_data_get(struct snd_kcontrol *kcontrol, | ||
466 | struct snd_ctl_elem_value *ucontrol) | ||
467 | { | ||
468 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
469 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
470 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
471 | long *valp = ucontrol->value.integer.value; | ||
472 | unsigned int val = snd_hda_codec_read(codec, nid, 0, | ||
473 | AC_VERB_GET_GPIO_DATA, 0x00); | ||
474 | |||
475 | *valp = (val & mask) != 0; | ||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | static int cxt_gpio_data_put(struct snd_kcontrol *kcontrol, | ||
480 | struct snd_ctl_elem_value *ucontrol) | ||
481 | { | ||
482 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
483 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
484 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
485 | long val = *ucontrol->value.integer.value; | ||
486 | unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, | ||
487 | AC_VERB_GET_GPIO_DATA, | ||
488 | 0x00); | ||
489 | unsigned int old_data = gpio_data; | ||
490 | |||
491 | /* Set/unset the masked GPIO bit(s) as needed */ | ||
492 | if (val == 0) | ||
493 | gpio_data &= ~mask; | ||
494 | else | ||
495 | gpio_data |= mask; | ||
496 | if (gpio_data == old_data && !codec->in_resume) | ||
497 | return 0; | ||
498 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data); | ||
499 | return 1; | ||
500 | } | ||
501 | |||
502 | #define CXT_GPIO_DATA_SWITCH(xname, nid, mask) \ | ||
503 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
504 | .info = cxt_gpio_data_info, \ | ||
505 | .get = cxt_gpio_data_get, \ | ||
506 | .put = cxt_gpio_data_put, \ | ||
507 | .private_value = nid | (mask<<16) } | ||
508 | #if 0 | ||
509 | static int cxt_spdif_ctrl_info(struct snd_kcontrol *kcontrol, | ||
510 | struct snd_ctl_elem_info *uinfo) | ||
511 | { | ||
512 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
513 | uinfo->count = 1; | ||
514 | uinfo->value.integer.min = 0; | ||
515 | uinfo->value.integer.max = 1; | ||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | static int cxt_spdif_ctrl_get(struct snd_kcontrol *kcontrol, | ||
520 | struct snd_ctl_elem_value *ucontrol) | ||
521 | { | ||
522 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
523 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
524 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
525 | long *valp = ucontrol->value.integer.value; | ||
526 | unsigned int val = snd_hda_codec_read(codec, nid, 0, | ||
527 | AC_VERB_GET_DIGI_CONVERT, 0x00); | ||
528 | |||
529 | *valp = (val & mask) != 0; | ||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | static int cxt_spdif_ctrl_put(struct snd_kcontrol *kcontrol, | ||
534 | struct snd_ctl_elem_value *ucontrol) | ||
535 | { | ||
536 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
537 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
538 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
539 | long val = *ucontrol->value.integer.value; | ||
540 | unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, | ||
541 | AC_VERB_GET_DIGI_CONVERT, | ||
542 | 0x00); | ||
543 | unsigned int old_data = ctrl_data; | ||
544 | |||
545 | /* Set/unset the masked control bit(s) as needed */ | ||
546 | if (val == 0) | ||
547 | ctrl_data &= ~mask; | ||
548 | else | ||
549 | ctrl_data |= mask; | ||
550 | if (ctrl_data == old_data && !codec->in_resume) | ||
551 | return 0; | ||
552 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, | ||
553 | ctrl_data); | ||
554 | return 1; | ||
555 | } | ||
556 | |||
557 | #define CXT_SPDIF_CTRL_SWITCH(xname, nid, mask) \ | ||
558 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
559 | .info = cxt_spdif_ctrl_info, \ | ||
560 | .get = cxt_spdif_ctrl_get, \ | ||
561 | .put = cxt_spdif_ctrl_put, \ | ||
562 | .private_value = nid | (mask<<16) } | ||
563 | #endif | ||
564 | #endif /* CONFIG_SND_DEBUG */ | 468 | #endif /* CONFIG_SND_DEBUG */ |
565 | 469 | ||
566 | /* Conexant 5045 specific */ | 470 | /* Conexant 5045 specific */ |
@@ -599,6 +503,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
599 | bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80; | 503 | bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80; |
600 | snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); | 504 | snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); |
601 | snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); | 505 | snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); |
506 | |||
602 | bits = spec->cur_eapd ? 0 : 0x80; | 507 | bits = spec->cur_eapd ? 0 : 0x80; |
603 | snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits); | 508 | snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits); |
604 | snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits); | 509 | snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits); |
@@ -624,6 +529,29 @@ static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol, | |||
624 | return change; | 529 | return change; |
625 | } | 530 | } |
626 | 531 | ||
532 | /* toggle input of built-in and mic jack appropriately */ | ||
533 | static void cxt5045_hp_automic(struct hda_codec *codec) | ||
534 | { | ||
535 | static struct hda_verb mic_jack_on[] = { | ||
536 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
537 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
538 | {} | ||
539 | }; | ||
540 | static struct hda_verb mic_jack_off[] = { | ||
541 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
542 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
543 | {} | ||
544 | }; | ||
545 | unsigned int present; | ||
546 | |||
547 | present = snd_hda_codec_read(codec, 0x12, 0, | ||
548 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
549 | if (present) | ||
550 | snd_hda_sequence_write(codec, mic_jack_on); | ||
551 | else | ||
552 | snd_hda_sequence_write(codec, mic_jack_off); | ||
553 | } | ||
554 | |||
627 | 555 | ||
628 | /* mute internal speaker if HP is plugged */ | 556 | /* mute internal speaker if HP is plugged */ |
629 | static void cxt5045_hp_automute(struct hda_codec *codec) | 557 | static void cxt5045_hp_automute(struct hda_codec *codec) |
@@ -634,7 +562,7 @@ static void cxt5045_hp_automute(struct hda_codec *codec) | |||
634 | spec->hp_present = snd_hda_codec_read(codec, 0x11, 0, | 562 | spec->hp_present = snd_hda_codec_read(codec, 0x11, 0, |
635 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 563 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
636 | 564 | ||
637 | bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; | 565 | bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; |
638 | snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); | 566 | snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); |
639 | snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); | 567 | snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); |
640 | } | 568 | } |
@@ -648,6 +576,10 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, | |||
648 | case CONEXANT_HP_EVENT: | 576 | case CONEXANT_HP_EVENT: |
649 | cxt5045_hp_automute(codec); | 577 | cxt5045_hp_automute(codec); |
650 | break; | 578 | break; |
579 | case CONEXANT_MIC_EVENT: | ||
580 | cxt5045_hp_automic(codec); | ||
581 | break; | ||
582 | |||
651 | } | 583 | } |
652 | } | 584 | } |
653 | 585 | ||
@@ -659,12 +591,10 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { | |||
659 | .get = conexant_mux_enum_get, | 591 | .get = conexant_mux_enum_get, |
660 | .put = conexant_mux_enum_put | 592 | .put = conexant_mux_enum_put |
661 | }, | 593 | }, |
662 | HDA_CODEC_VOLUME("Int Mic Volume", 0x17, 0x01, HDA_INPUT), | 594 | HDA_CODEC_VOLUME("Int Mic Volume", 0x1a, 0x01, HDA_INPUT), |
663 | HDA_CODEC_MUTE("Int Mic Switch", 0x17, 0x01, HDA_INPUT), | 595 | HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT), |
664 | HDA_CODEC_VOLUME("Ext Mic Volume", 0x17, 0x02, HDA_INPUT), | 596 | HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT), |
665 | HDA_CODEC_MUTE("Ext Mic Switch", 0x17, 0x02, HDA_INPUT), | 597 | HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT), |
666 | HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT), | ||
667 | HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT), | ||
668 | { | 598 | { |
669 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 599 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
670 | .name = "Master Playback Volume", | 600 | .name = "Master Playback Volume", |
@@ -688,7 +618,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { | |||
688 | static struct hda_verb cxt5045_init_verbs[] = { | 618 | static struct hda_verb cxt5045_init_verbs[] = { |
689 | /* Line in, Mic */ | 619 | /* Line in, Mic */ |
690 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 620 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
691 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, | 621 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, |
692 | /* HP, Amp */ | 622 | /* HP, Amp */ |
693 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | 623 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
694 | {0x17, AC_VERB_SET_CONNECT_SEL,0x01}, | 624 | {0x17, AC_VERB_SET_CONNECT_SEL,0x01}, |
@@ -701,18 +631,29 @@ static struct hda_verb cxt5045_init_verbs[] = { | |||
701 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, | 631 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, |
702 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04}, | 632 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04}, |
703 | /* Record selector: Int mic */ | 633 | /* Record selector: Int mic */ |
704 | {0x1a, AC_VERB_SET_CONNECT_SEL,0x0}, | 634 | {0x1a, AC_VERB_SET_CONNECT_SEL,0x1}, |
705 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, | 635 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, |
706 | AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, | 636 | AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, |
707 | /* SPDIF route: PCM */ | 637 | /* SPDIF route: PCM */ |
708 | { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 }, | 638 | { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 }, |
709 | /* pin sensing on HP and Mic jacks */ | ||
710 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | ||
711 | /* EAPD */ | 639 | /* EAPD */ |
712 | {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ | 640 | {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ |
713 | { } /* end */ | 641 | { } /* end */ |
714 | }; | 642 | }; |
715 | 643 | ||
644 | |||
645 | static struct hda_verb cxt5045_hp_sense_init_verbs[] = { | ||
646 | /* pin sensing on HP jack */ | ||
647 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | ||
648 | { } /* end */ | ||
649 | }; | ||
650 | |||
651 | static struct hda_verb cxt5045_mic_sense_init_verbs[] = { | ||
652 | /* pin sensing on HP jack */ | ||
653 | {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | ||
654 | { } /* end */ | ||
655 | }; | ||
656 | |||
716 | #ifdef CONFIG_SND_DEBUG | 657 | #ifdef CONFIG_SND_DEBUG |
717 | /* Test configuration for debugging, modelled after the ALC260 test | 658 | /* Test configuration for debugging, modelled after the ALC260 test |
718 | * configuration. | 659 | * configuration. |
@@ -733,6 +674,10 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { | |||
733 | /* Output controls */ | 674 | /* Output controls */ |
734 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), | 675 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), |
735 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT), | 676 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT), |
677 | HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT), | ||
678 | HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT), | ||
679 | HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT), | ||
680 | HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT), | ||
736 | 681 | ||
737 | /* Modes for retasking pin widgets */ | 682 | /* Modes for retasking pin widgets */ |
738 | CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT), | 683 | CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT), |
@@ -742,25 +687,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { | |||
742 | CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0), | 687 | CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0), |
743 | 688 | ||
744 | /* Loopback mixer controls */ | 689 | /* Loopback mixer controls */ |
745 | HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x17, 0x01, HDA_INPUT), | 690 | |
746 | HDA_CODEC_MUTE("MIC1 Playback Switch", 0x17, 0x01, HDA_INPUT), | 691 | HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT), |
747 | HDA_CODEC_VOLUME("LINE loopback Playback Volume", 0x17, 0x02, HDA_INPUT), | 692 | HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT), |
748 | HDA_CODEC_MUTE("LINE loopback Playback Switch", 0x17, 0x02, HDA_INPUT), | 693 | HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT), |
749 | HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x17, 0x03, HDA_INPUT), | 694 | HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT), |
750 | HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x17, 0x03, HDA_INPUT), | 695 | HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT), |
751 | HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x04, HDA_INPUT), | 696 | HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT), |
752 | HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x04, HDA_INPUT), | 697 | HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT), |
753 | 698 | HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT), | |
754 | HDA_CODEC_VOLUME("Capture-1 Volume", 0x17, 0x0, HDA_INPUT), | 699 | HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT), |
755 | HDA_CODEC_MUTE("Capture-1 Switch", 0x17, 0x0, HDA_INPUT), | 700 | HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT), |
756 | HDA_CODEC_VOLUME("Capture-2 Volume", 0x17, 0x1, HDA_INPUT), | ||
757 | HDA_CODEC_MUTE("Capture-2 Switch", 0x17, 0x1, HDA_INPUT), | ||
758 | HDA_CODEC_VOLUME("Capture-3 Volume", 0x17, 0x2, HDA_INPUT), | ||
759 | HDA_CODEC_MUTE("Capture-3 Switch", 0x17, 0x2, HDA_INPUT), | ||
760 | HDA_CODEC_VOLUME("Capture-4 Volume", 0x17, 0x3, HDA_INPUT), | ||
761 | HDA_CODEC_MUTE("Capture-4 Switch", 0x17, 0x3, HDA_INPUT), | ||
762 | HDA_CODEC_VOLUME("Capture-5 Volume", 0x17, 0x4, HDA_INPUT), | ||
763 | HDA_CODEC_MUTE("Capture-5 Switch", 0x17, 0x4, HDA_INPUT), | ||
764 | { | 701 | { |
765 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 702 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
766 | .name = "Input Source", | 703 | .name = "Input Source", |
@@ -768,14 +705,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { | |||
768 | .get = conexant_mux_enum_get, | 705 | .get = conexant_mux_enum_get, |
769 | .put = conexant_mux_enum_put, | 706 | .put = conexant_mux_enum_put, |
770 | }, | 707 | }, |
771 | |||
772 | { } /* end */ | 708 | { } /* end */ |
773 | }; | 709 | }; |
774 | 710 | ||
775 | static struct hda_verb cxt5045_test_init_verbs[] = { | 711 | static struct hda_verb cxt5045_test_init_verbs[] = { |
712 | /* Set connections */ | ||
713 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, | ||
714 | { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 }, | ||
715 | { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 }, | ||
776 | /* Enable retasking pins as output, initially without power amp */ | 716 | /* Enable retasking pins as output, initially without power amp */ |
777 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 717 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
778 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 718 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
779 | 719 | ||
780 | /* Disable digital (SPDIF) pins initially, but users can enable | 720 | /* Disable digital (SPDIF) pins initially, but users can enable |
781 | * them via a mixer switch. In the case of SPDIF-out, this initverb | 721 | * them via a mixer switch. In the case of SPDIF-out, this initverb |
@@ -804,6 +744,7 @@ static struct hda_verb cxt5045_test_init_verbs[] = { | |||
804 | * pin) | 744 | * pin) |
805 | */ | 745 | */ |
806 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, | 746 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, |
747 | {0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
807 | 748 | ||
808 | /* Mute all inputs to mixer widget (even unconnected ones) */ | 749 | /* Mute all inputs to mixer widget (even unconnected ones) */ |
809 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */ | 750 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */ |
@@ -827,7 +768,8 @@ static int cxt5045_init(struct hda_codec *codec) | |||
827 | 768 | ||
828 | 769 | ||
829 | enum { | 770 | enum { |
830 | CXT5045_LAPTOP, /* Laptops w/ EAPD support */ | 771 | CXT5045_LAPTOP, /* Laptops w/ EAPD support */ |
772 | CXT5045_FUJITSU, /* Laptops w/ EAPD support */ | ||
831 | #ifdef CONFIG_SND_DEBUG | 773 | #ifdef CONFIG_SND_DEBUG |
832 | CXT5045_TEST, | 774 | CXT5045_TEST, |
833 | #endif | 775 | #endif |
@@ -836,6 +778,7 @@ enum { | |||
836 | 778 | ||
837 | static const char *cxt5045_models[CXT5045_MODELS] = { | 779 | static const char *cxt5045_models[CXT5045_MODELS] = { |
838 | [CXT5045_LAPTOP] = "laptop", | 780 | [CXT5045_LAPTOP] = "laptop", |
781 | [CXT5045_FUJITSU] = "fujitsu", | ||
839 | #ifdef CONFIG_SND_DEBUG | 782 | #ifdef CONFIG_SND_DEBUG |
840 | [CXT5045_TEST] = "test", | 783 | [CXT5045_TEST] = "test", |
841 | #endif | 784 | #endif |
@@ -844,7 +787,11 @@ static const char *cxt5045_models[CXT5045_MODELS] = { | |||
844 | static struct snd_pci_quirk cxt5045_cfg_tbl[] = { | 787 | static struct snd_pci_quirk cxt5045_cfg_tbl[] = { |
845 | SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP), | 788 | SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP), |
846 | SND_PCI_QUIRK(0x103c, 0x30bb, "HP DV8000", CXT5045_LAPTOP), | 789 | SND_PCI_QUIRK(0x103c, 0x30bb, "HP DV8000", CXT5045_LAPTOP), |
847 | SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP), | 790 | SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP), |
791 | SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP), | ||
792 | SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP), | ||
793 | SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU), | ||
794 | SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP), | ||
848 | {} | 795 | {} |
849 | }; | 796 | }; |
850 | 797 | ||
@@ -877,16 +824,23 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
877 | 824 | ||
878 | 825 | ||
879 | codec->patch_ops = conexant_patch_ops; | 826 | codec->patch_ops = conexant_patch_ops; |
880 | codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; | ||
881 | 827 | ||
882 | board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, | 828 | board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, |
883 | cxt5045_models, | 829 | cxt5045_models, |
884 | cxt5045_cfg_tbl); | 830 | cxt5045_cfg_tbl); |
885 | switch (board_config) { | 831 | switch (board_config) { |
886 | case CXT5045_LAPTOP: | 832 | case CXT5045_LAPTOP: |
833 | codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; | ||
834 | spec->input_mux = &cxt5045_capture_source; | ||
835 | spec->num_init_verbs = 2; | ||
836 | spec->init_verbs[1] = cxt5045_hp_sense_init_verbs; | ||
837 | spec->mixers[0] = cxt5045_mixers; | ||
838 | codec->patch_ops.init = cxt5045_init; | ||
839 | break; | ||
840 | case CXT5045_FUJITSU: | ||
887 | spec->input_mux = &cxt5045_capture_source; | 841 | spec->input_mux = &cxt5045_capture_source; |
888 | spec->num_init_verbs = 2; | 842 | spec->num_init_verbs = 2; |
889 | spec->init_verbs[1] = cxt5045_init_verbs; | 843 | spec->init_verbs[1] = cxt5045_mic_sense_init_verbs; |
890 | spec->mixers[0] = cxt5045_mixers; | 844 | spec->mixers[0] = cxt5045_mixers; |
891 | codec->patch_ops.init = cxt5045_init; | 845 | codec->patch_ops.init = cxt5045_init; |
892 | break; | 846 | break; |
@@ -913,10 +867,9 @@ static struct hda_channel_mode cxt5047_modes[1] = { | |||
913 | }; | 867 | }; |
914 | 868 | ||
915 | static struct hda_input_mux cxt5047_capture_source = { | 869 | static struct hda_input_mux cxt5047_capture_source = { |
916 | .num_items = 2, | 870 | .num_items = 1, |
917 | .items = { | 871 | .items = { |
918 | { "ExtMic", 0x0 }, | 872 | { "Mic", 0x2 }, |
919 | { "IntMic", 0x1 }, | ||
920 | } | 873 | } |
921 | }; | 874 | }; |
922 | 875 | ||
@@ -1009,7 +962,7 @@ static void cxt5047_hp_automic(struct hda_codec *codec) | |||
1009 | }; | 962 | }; |
1010 | unsigned int present; | 963 | unsigned int present; |
1011 | 964 | ||
1012 | present = snd_hda_codec_read(codec, 0x08, 0, | 965 | present = snd_hda_codec_read(codec, 0x15, 0, |
1013 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 966 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
1014 | if (present) | 967 | if (present) |
1015 | snd_hda_sequence_write(codec, mic_jack_on); | 968 | snd_hda_sequence_write(codec, mic_jack_on); |
@@ -1033,37 +986,20 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec, | |||
1033 | } | 986 | } |
1034 | 987 | ||
1035 | static struct snd_kcontrol_new cxt5047_mixers[] = { | 988 | static struct snd_kcontrol_new cxt5047_mixers[] = { |
1036 | { | ||
1037 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1038 | .name = "Capture Source", | ||
1039 | .info = conexant_mux_enum_info, | ||
1040 | .get = conexant_mux_enum_get, | ||
1041 | .put = conexant_mux_enum_put | ||
1042 | }, | ||
1043 | HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT), | 989 | HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT), |
1044 | HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT), | 990 | HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT), |
991 | HDA_CODEC_VOLUME("Mic Gain Volume", 0x1a, 0x0, HDA_OUTPUT), | ||
992 | HDA_CODEC_MUTE("Mic Gain Switch", 0x1a, 0x0, HDA_OUTPUT), | ||
1045 | HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT), | 993 | HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT), |
1046 | HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), | 994 | HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), |
1047 | HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), | 995 | HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), |
1048 | HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT), | 996 | HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT), |
1049 | HDA_CODEC_VOLUME("PCM-2 Volume", 0x1c, 0x00, HDA_OUTPUT), | 997 | HDA_CODEC_VOLUME("PCM-2 Volume", 0x1c, 0x00, HDA_OUTPUT), |
1050 | HDA_CODEC_MUTE("PCM-2 Switch", 0x1c, 0x00, HDA_OUTPUT), | 998 | HDA_CODEC_MUTE("PCM-2 Switch", 0x1c, 0x00, HDA_OUTPUT), |
1051 | { | 999 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x00, HDA_OUTPUT), |
1052 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1000 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x00, HDA_OUTPUT), |
1053 | .name = "Master Playback Volume", | 1001 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT), |
1054 | .info = snd_hda_mixer_amp_volume_info, | 1002 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x13, 0x00, HDA_OUTPUT), |
1055 | .get = snd_hda_mixer_amp_volume_get, | ||
1056 | .put = cxt5047_hp_master_vol_put, | ||
1057 | .private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT), | ||
1058 | }, | ||
1059 | { | ||
1060 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1061 | .name = "Master Playback Switch", | ||
1062 | .info = cxt_eapd_info, | ||
1063 | .get = cxt_eapd_get, | ||
1064 | .put = cxt5047_hp_master_sw_put, | ||
1065 | .private_value = 0x13, | ||
1066 | }, | ||
1067 | 1003 | ||
1068 | {} | 1004 | {} |
1069 | }; | 1005 | }; |
@@ -1133,18 +1069,19 @@ static struct hda_verb cxt5047_init_verbs[] = { | |||
1133 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 1069 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
1134 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, | 1070 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, |
1135 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, | 1071 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, |
1136 | /* HP, Amp, Speaker */ | 1072 | /* HP, Speaker */ |
1137 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 1073 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
1138 | {0x1A, AC_VERB_SET_CONNECT_SEL,0x00}, | 1074 | {0x13, AC_VERB_SET_CONNECT_SEL,0x1}, |
1139 | {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1140 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00}, | ||
1141 | {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1142 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, | ||
1143 | {0x1d, AC_VERB_SET_CONNECT_SEL,0x0}, | 1075 | {0x1d, AC_VERB_SET_CONNECT_SEL,0x0}, |
1144 | /* Record selector: Front mic */ | 1076 | /* Record selector: Mic */ |
1145 | {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, | 1077 | {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, |
1146 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, | 1078 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, |
1147 | AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, | 1079 | AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, |
1080 | {0x1A, AC_VERB_SET_CONNECT_SEL,0x02}, | ||
1081 | {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1082 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00}, | ||
1083 | {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1084 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, | ||
1148 | /* SPDIF route: PCM */ | 1085 | /* SPDIF route: PCM */ |
1149 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 }, | 1086 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 }, |
1150 | /* Enable unsolicited events */ | 1087 | /* Enable unsolicited events */ |
@@ -1161,8 +1098,6 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = { | |||
1161 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | 1098 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, |
1162 | /* Speaker routing */ | 1099 | /* Speaker routing */ |
1163 | {0x1d, AC_VERB_SET_CONNECT_SEL,0x1}, | 1100 | {0x1d, AC_VERB_SET_CONNECT_SEL,0x1}, |
1164 | /* Change default to ExtMic for recording */ | ||
1165 | {0x1a, AC_VERB_SET_CONNECT_SEL,0x2}, | ||
1166 | {} | 1101 | {} |
1167 | }; | 1102 | }; |
1168 | 1103 | ||
@@ -1172,7 +1107,6 @@ static struct hda_verb cxt5047_hp_init_verbs[] = { | |||
1172 | {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | 1107 | {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, |
1173 | /* Record selector: Ext Mic */ | 1108 | /* Record selector: Ext Mic */ |
1174 | {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, | 1109 | {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, |
1175 | {0x1a, AC_VERB_SET_CONNECT_SEL,0x02}, | ||
1176 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, | 1110 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, |
1177 | AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, | 1111 | AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, |
1178 | /* Speaker routing */ | 1112 | /* Speaker routing */ |
@@ -1242,14 +1176,6 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = { | |||
1242 | .get = conexant_mux_enum_get, | 1176 | .get = conexant_mux_enum_get, |
1243 | .put = conexant_mux_enum_put, | 1177 | .put = conexant_mux_enum_put, |
1244 | }, | 1178 | }, |
1245 | /* Controls for GPIO pins, assuming they exist and are configured | ||
1246 | * as outputs | ||
1247 | */ | ||
1248 | CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), | ||
1249 | CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), | ||
1250 | CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), | ||
1251 | CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), | ||
1252 | |||
1253 | { } /* end */ | 1179 | { } /* end */ |
1254 | }; | 1180 | }; |
1255 | 1181 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fba3cb11bc2a..a4ede27af021 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -74,6 +74,8 @@ enum { | |||
74 | ALC260_HP_3013, | 74 | ALC260_HP_3013, |
75 | ALC260_FUJITSU_S702X, | 75 | ALC260_FUJITSU_S702X, |
76 | ALC260_ACER, | 76 | ALC260_ACER, |
77 | ALC260_WILL, | ||
78 | ALC260_REPLACER_672V, | ||
77 | #ifdef CONFIG_SND_DEBUG | 79 | #ifdef CONFIG_SND_DEBUG |
78 | ALC260_TEST, | 80 | ALC260_TEST, |
79 | #endif | 81 | #endif |
@@ -115,15 +117,28 @@ enum { | |||
115 | ALC861VD_3ST, | 117 | ALC861VD_3ST, |
116 | ALC861VD_3ST_DIG, | 118 | ALC861VD_3ST_DIG, |
117 | ALC861VD_6ST_DIG, | 119 | ALC861VD_6ST_DIG, |
120 | ALC861VD_LENOVO, | ||
118 | ALC861VD_AUTO, | 121 | ALC861VD_AUTO, |
119 | ALC861VD_MODEL_LAST, | 122 | ALC861VD_MODEL_LAST, |
120 | }; | 123 | }; |
121 | 124 | ||
125 | /* ALC662 models */ | ||
126 | enum { | ||
127 | ALC662_3ST_2ch_DIG, | ||
128 | ALC662_3ST_6ch_DIG, | ||
129 | ALC662_3ST_6ch, | ||
130 | ALC662_5ST_DIG, | ||
131 | ALC662_LENOVO_101E, | ||
132 | ALC662_AUTO, | ||
133 | ALC662_MODEL_LAST, | ||
134 | }; | ||
135 | |||
122 | /* ALC882 models */ | 136 | /* ALC882 models */ |
123 | enum { | 137 | enum { |
124 | ALC882_3ST_DIG, | 138 | ALC882_3ST_DIG, |
125 | ALC882_6ST_DIG, | 139 | ALC882_6ST_DIG, |
126 | ALC882_ARIMA, | 140 | ALC882_ARIMA, |
141 | ALC882_W2JC, | ||
127 | ALC882_AUTO, | 142 | ALC882_AUTO, |
128 | ALC885_MACPRO, | 143 | ALC885_MACPRO, |
129 | ALC882_MODEL_LAST, | 144 | ALC882_MODEL_LAST, |
@@ -141,6 +156,7 @@ enum { | |||
141 | ALC883_ACER, | 156 | ALC883_ACER, |
142 | ALC883_MEDION, | 157 | ALC883_MEDION, |
143 | ALC883_LAPTOP_EAPD, | 158 | ALC883_LAPTOP_EAPD, |
159 | ALC883_LENOVO_101E_2ch, | ||
144 | ALC883_AUTO, | 160 | ALC883_AUTO, |
145 | ALC883_MODEL_LAST, | 161 | ALC883_MODEL_LAST, |
146 | }; | 162 | }; |
@@ -163,7 +179,7 @@ struct alc_spec { | |||
163 | struct hda_pcm_stream *stream_analog_playback; | 179 | struct hda_pcm_stream *stream_analog_playback; |
164 | struct hda_pcm_stream *stream_analog_capture; | 180 | struct hda_pcm_stream *stream_analog_capture; |
165 | 181 | ||
166 | char *stream_name_digital; /* digital PCM stream */ | 182 | char *stream_name_digital; /* digital PCM stream */ |
167 | struct hda_pcm_stream *stream_digital_playback; | 183 | struct hda_pcm_stream *stream_digital_playback; |
168 | struct hda_pcm_stream *stream_digital_capture; | 184 | struct hda_pcm_stream *stream_digital_capture; |
169 | 185 | ||
@@ -401,7 +417,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, | |||
401 | AC_VERB_GET_PIN_WIDGET_CONTROL, | 417 | AC_VERB_GET_PIN_WIDGET_CONTROL, |
402 | 0x00); | 418 | 0x00); |
403 | 419 | ||
404 | if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) | 420 | if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) |
405 | val = alc_pin_mode_min(dir); | 421 | val = alc_pin_mode_min(dir); |
406 | 422 | ||
407 | change = pinctl != alc_pin_mode_values[val]; | 423 | change = pinctl != alc_pin_mode_values[val]; |
@@ -460,7 +476,8 @@ static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, | |||
460 | uinfo->value.integer.min = 0; | 476 | uinfo->value.integer.min = 0; |
461 | uinfo->value.integer.max = 1; | 477 | uinfo->value.integer.max = 1; |
462 | return 0; | 478 | return 0; |
463 | } | 479 | } |
480 | |||
464 | static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, | 481 | static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, |
465 | struct snd_ctl_elem_value *ucontrol) | 482 | struct snd_ctl_elem_value *ucontrol) |
466 | { | 483 | { |
@@ -520,7 +537,8 @@ static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, | |||
520 | uinfo->value.integer.min = 0; | 537 | uinfo->value.integer.min = 0; |
521 | uinfo->value.integer.max = 1; | 538 | uinfo->value.integer.max = 1; |
522 | return 0; | 539 | return 0; |
523 | } | 540 | } |
541 | |||
524 | static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, | 542 | static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, |
525 | struct snd_ctl_elem_value *ucontrol) | 543 | struct snd_ctl_elem_value *ucontrol) |
526 | { | 544 | { |
@@ -592,7 +610,7 @@ static void setup_preset(struct alc_spec *spec, | |||
592 | spec->multiout.hp_nid = preset->hp_nid; | 610 | spec->multiout.hp_nid = preset->hp_nid; |
593 | 611 | ||
594 | spec->num_mux_defs = preset->num_mux_defs; | 612 | spec->num_mux_defs = preset->num_mux_defs; |
595 | if (! spec->num_mux_defs) | 613 | if (!spec->num_mux_defs) |
596 | spec->num_mux_defs = 1; | 614 | spec->num_mux_defs = 1; |
597 | spec->input_mux = preset->input_mux; | 615 | spec->input_mux = preset->input_mux; |
598 | 616 | ||
@@ -604,6 +622,90 @@ static void setup_preset(struct alc_spec *spec, | |||
604 | spec->init_hook = preset->init_hook; | 622 | spec->init_hook = preset->init_hook; |
605 | } | 623 | } |
606 | 624 | ||
625 | /* Enable GPIO mask and set output */ | ||
626 | static struct hda_verb alc_gpio1_init_verbs[] = { | ||
627 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||
628 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
629 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | ||
630 | { } | ||
631 | }; | ||
632 | |||
633 | static struct hda_verb alc_gpio2_init_verbs[] = { | ||
634 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, | ||
635 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, | ||
636 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, | ||
637 | { } | ||
638 | }; | ||
639 | |||
640 | static struct hda_verb alc_gpio3_init_verbs[] = { | ||
641 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | ||
642 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, | ||
643 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, | ||
644 | { } | ||
645 | }; | ||
646 | |||
647 | /* 32-bit subsystem ID for BIOS loading in HD Audio codec. | ||
648 | * 31 ~ 16 : Manufacture ID | ||
649 | * 15 ~ 8 : SKU ID | ||
650 | * 7 ~ 0 : Assembly ID | ||
651 | * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 | ||
652 | */ | ||
653 | static void alc_subsystem_id(struct hda_codec *codec, | ||
654 | unsigned int porta, unsigned int porte, | ||
655 | unsigned int portd) | ||
656 | { | ||
657 | unsigned int ass, tmp; | ||
658 | |||
659 | ass = codec->subsystem_id; | ||
660 | if (!(ass & 1)) | ||
661 | return; | ||
662 | |||
663 | /* Override */ | ||
664 | tmp = (ass & 0x38) >> 3; /* external Amp control */ | ||
665 | switch (tmp) { | ||
666 | case 1: | ||
667 | snd_hda_sequence_write(codec, alc_gpio1_init_verbs); | ||
668 | break; | ||
669 | case 3: | ||
670 | snd_hda_sequence_write(codec, alc_gpio2_init_verbs); | ||
671 | break; | ||
672 | case 7: | ||
673 | snd_hda_sequence_write(codec, alc_gpio3_init_verbs); | ||
674 | break; | ||
675 | case 5: | ||
676 | switch (codec->vendor_id) { | ||
677 | case 0x10ec0862: | ||
678 | case 0x10ec0660: | ||
679 | case 0x10ec0662: | ||
680 | case 0x10ec0267: | ||
681 | case 0x10ec0268: | ||
682 | snd_hda_codec_write(codec, 0x14, 0, | ||
683 | AC_VERB_SET_EAPD_BTLENABLE, 2); | ||
684 | snd_hda_codec_write(codec, 0x15, 0, | ||
685 | AC_VERB_SET_EAPD_BTLENABLE, 2); | ||
686 | return; | ||
687 | } | ||
688 | case 6: | ||
689 | if (ass & 4) { /* bit 2 : 0 = Desktop, 1 = Laptop */ | ||
690 | hda_nid_t port = 0; | ||
691 | tmp = (ass & 0x1800) >> 11; | ||
692 | switch (tmp) { | ||
693 | case 0: port = porta; break; | ||
694 | case 1: port = porte; break; | ||
695 | case 2: port = portd; break; | ||
696 | } | ||
697 | if (port) | ||
698 | snd_hda_codec_write(codec, port, 0, | ||
699 | AC_VERB_SET_EAPD_BTLENABLE, | ||
700 | 2); | ||
701 | } | ||
702 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); | ||
703 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, | ||
704 | (tmp == 5 ? 0x3040 : 0x3050)); | ||
705 | break; | ||
706 | } | ||
707 | } | ||
708 | |||
607 | /* | 709 | /* |
608 | * ALC880 3-stack model | 710 | * ALC880 3-stack model |
609 | * | 711 | * |
@@ -801,7 +903,7 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = { | |||
801 | static hda_nid_t alc880_6st_dac_nids[4] = { | 903 | static hda_nid_t alc880_6st_dac_nids[4] = { |
802 | /* front, rear, clfe, rear_surr */ | 904 | /* front, rear, clfe, rear_surr */ |
803 | 0x02, 0x03, 0x04, 0x05 | 905 | 0x02, 0x03, 0x04, 0x05 |
804 | }; | 906 | }; |
805 | 907 | ||
806 | static struct hda_input_mux alc880_6stack_capture_source = { | 908 | static struct hda_input_mux alc880_6stack_capture_source = { |
807 | .num_items = 4, | 909 | .num_items = 4, |
@@ -1409,25 +1511,43 @@ static struct hda_verb alc880_beep_init_verbs[] = { | |||
1409 | }; | 1511 | }; |
1410 | 1512 | ||
1411 | /* toggle speaker-output according to the hp-jack state */ | 1513 | /* toggle speaker-output according to the hp-jack state */ |
1412 | static void alc880_uniwill_automute(struct hda_codec *codec) | 1514 | static void alc880_uniwill_hp_automute(struct hda_codec *codec) |
1413 | { | 1515 | { |
1414 | unsigned int present; | 1516 | unsigned int present; |
1517 | unsigned char bits; | ||
1415 | 1518 | ||
1416 | present = snd_hda_codec_read(codec, 0x14, 0, | 1519 | present = snd_hda_codec_read(codec, 0x14, 0, |
1417 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1520 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
1521 | bits = present ? 0x80 : 0; | ||
1418 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | 1522 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, |
1419 | 0x80, present ? 0x80 : 0); | 1523 | 0x80, bits); |
1420 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | 1524 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, |
1421 | 0x80, present ? 0x80 : 0); | 1525 | 0x80, bits); |
1422 | snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0, | 1526 | snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0, |
1423 | 0x80, present ? 0x80 : 0); | 1527 | 0x80, bits); |
1424 | snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0, | 1528 | snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0, |
1425 | 0x80, present ? 0x80 : 0); | 1529 | 0x80, bits); |
1530 | } | ||
1531 | |||
1532 | /* auto-toggle front mic */ | ||
1533 | static void alc880_uniwill_mic_automute(struct hda_codec *codec) | ||
1534 | { | ||
1535 | unsigned int present; | ||
1536 | unsigned char bits; | ||
1426 | 1537 | ||
1427 | present = snd_hda_codec_read(codec, 0x18, 0, | 1538 | present = snd_hda_codec_read(codec, 0x18, 0, |
1428 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1539 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
1429 | snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 1540 | bits = present ? 0x80 : 0; |
1430 | 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); | 1541 | snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1, |
1542 | 0x80, bits); | ||
1543 | snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1, | ||
1544 | 0x80, bits); | ||
1545 | } | ||
1546 | |||
1547 | static void alc880_uniwill_automute(struct hda_codec *codec) | ||
1548 | { | ||
1549 | alc880_uniwill_hp_automute(codec); | ||
1550 | alc880_uniwill_mic_automute(codec); | ||
1431 | } | 1551 | } |
1432 | 1552 | ||
1433 | static void alc880_uniwill_unsol_event(struct hda_codec *codec, | 1553 | static void alc880_uniwill_unsol_event(struct hda_codec *codec, |
@@ -1436,22 +1556,28 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, | |||
1436 | /* Looks like the unsol event is incompatible with the standard | 1556 | /* Looks like the unsol event is incompatible with the standard |
1437 | * definition. 4bit tag is placed at 28 bit! | 1557 | * definition. 4bit tag is placed at 28 bit! |
1438 | */ | 1558 | */ |
1439 | if ((res >> 28) == ALC880_HP_EVENT || | 1559 | switch (res >> 28) { |
1440 | (res >> 28) == ALC880_MIC_EVENT) | 1560 | case ALC880_HP_EVENT: |
1441 | alc880_uniwill_automute(codec); | 1561 | alc880_uniwill_hp_automute(codec); |
1562 | break; | ||
1563 | case ALC880_MIC_EVENT: | ||
1564 | alc880_uniwill_mic_automute(codec); | ||
1565 | break; | ||
1566 | } | ||
1442 | } | 1567 | } |
1443 | 1568 | ||
1444 | static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) | 1569 | static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) |
1445 | { | 1570 | { |
1446 | unsigned int present; | 1571 | unsigned int present; |
1572 | unsigned char bits; | ||
1447 | 1573 | ||
1448 | present = snd_hda_codec_read(codec, 0x14, 0, | 1574 | present = snd_hda_codec_read(codec, 0x14, 0, |
1449 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1575 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
1450 | 1576 | bits = present ? 0x80 : 0; | |
1451 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0, | 1577 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0, |
1452 | 0x80, present ? 0x80 : 0); | 1578 | 0x80, bits); |
1453 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0, | 1579 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0, |
1454 | 0x80, present ? 0x80 : 0); | 1580 | 0x80, bits); |
1455 | } | 1581 | } |
1456 | 1582 | ||
1457 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) | 1583 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) |
@@ -1480,7 +1606,7 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, | |||
1480 | */ | 1606 | */ |
1481 | if ((res >> 28) == ALC880_HP_EVENT) | 1607 | if ((res >> 28) == ALC880_HP_EVENT) |
1482 | alc880_uniwill_p53_hp_automute(codec); | 1608 | alc880_uniwill_p53_hp_automute(codec); |
1483 | if ((res >> 28) == ALC880_DCVOL_EVENT) | 1609 | if ((res >> 28) == ALC880_DCVOL_EVENT) |
1484 | alc880_uniwill_p53_dcvol_automute(codec); | 1610 | alc880_uniwill_p53_dcvol_automute(codec); |
1485 | } | 1611 | } |
1486 | 1612 | ||
@@ -1547,22 +1673,8 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = { | |||
1547 | }; | 1673 | }; |
1548 | 1674 | ||
1549 | /* Enable GPIO mask and set output */ | 1675 | /* Enable GPIO mask and set output */ |
1550 | static struct hda_verb alc880_gpio1_init_verbs[] = { | 1676 | #define alc880_gpio1_init_verbs alc_gpio1_init_verbs |
1551 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | 1677 | #define alc880_gpio2_init_verbs alc_gpio2_init_verbs |
1552 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
1553 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | ||
1554 | |||
1555 | { } | ||
1556 | }; | ||
1557 | |||
1558 | /* Enable GPIO mask and set output */ | ||
1559 | static struct hda_verb alc880_gpio2_init_verbs[] = { | ||
1560 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, | ||
1561 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, | ||
1562 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, | ||
1563 | |||
1564 | { } | ||
1565 | }; | ||
1566 | 1678 | ||
1567 | /* Clevo m520g init */ | 1679 | /* Clevo m520g init */ |
1568 | static struct hda_verb alc880_pin_clevo_init_verbs[] = { | 1680 | static struct hda_verb alc880_pin_clevo_init_verbs[] = { |
@@ -1734,13 +1846,15 @@ static struct hda_verb alc880_lg_init_verbs[] = { | |||
1734 | static void alc880_lg_automute(struct hda_codec *codec) | 1846 | static void alc880_lg_automute(struct hda_codec *codec) |
1735 | { | 1847 | { |
1736 | unsigned int present; | 1848 | unsigned int present; |
1849 | unsigned char bits; | ||
1737 | 1850 | ||
1738 | present = snd_hda_codec_read(codec, 0x1b, 0, | 1851 | present = snd_hda_codec_read(codec, 0x1b, 0, |
1739 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1852 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
1853 | bits = present ? 0x80 : 0; | ||
1740 | snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0, | 1854 | snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0, |
1741 | 0x80, present ? 0x80 : 0); | 1855 | 0x80, bits); |
1742 | snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0, | 1856 | snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0, |
1743 | 0x80, present ? 0x80 : 0); | 1857 | 0x80, bits); |
1744 | } | 1858 | } |
1745 | 1859 | ||
1746 | static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) | 1860 | static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -1810,13 +1924,15 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { | |||
1810 | static void alc880_lg_lw_automute(struct hda_codec *codec) | 1924 | static void alc880_lg_lw_automute(struct hda_codec *codec) |
1811 | { | 1925 | { |
1812 | unsigned int present; | 1926 | unsigned int present; |
1927 | unsigned char bits; | ||
1813 | 1928 | ||
1814 | present = snd_hda_codec_read(codec, 0x1b, 0, | 1929 | present = snd_hda_codec_read(codec, 0x1b, 0, |
1815 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1930 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
1931 | bits = present ? 0x80 : 0; | ||
1816 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | 1932 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, |
1817 | 0x80, present ? 0x80 : 0); | 1933 | 0x80, bits); |
1818 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | 1934 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, |
1819 | 0x80, present ? 0x80 : 0); | 1935 | 0x80, bits); |
1820 | } | 1936 | } |
1821 | 1937 | ||
1822 | static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) | 1938 | static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -1916,6 +2032,17 @@ static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | |||
1916 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | 2032 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); |
1917 | } | 2033 | } |
1918 | 2034 | ||
2035 | static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
2036 | struct hda_codec *codec, | ||
2037 | unsigned int stream_tag, | ||
2038 | unsigned int format, | ||
2039 | struct snd_pcm_substream *substream) | ||
2040 | { | ||
2041 | struct alc_spec *spec = codec->spec; | ||
2042 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
2043 | stream_tag, format, substream); | ||
2044 | } | ||
2045 | |||
1919 | static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | 2046 | static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, |
1920 | struct hda_codec *codec, | 2047 | struct hda_codec *codec, |
1921 | struct snd_pcm_substream *substream) | 2048 | struct snd_pcm_substream *substream) |
@@ -1984,7 +2111,8 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = { | |||
1984 | /* NID is set in alc_build_pcms */ | 2111 | /* NID is set in alc_build_pcms */ |
1985 | .ops = { | 2112 | .ops = { |
1986 | .open = alc880_dig_playback_pcm_open, | 2113 | .open = alc880_dig_playback_pcm_open, |
1987 | .close = alc880_dig_playback_pcm_close | 2114 | .close = alc880_dig_playback_pcm_close, |
2115 | .prepare = alc880_dig_playback_pcm_prepare | ||
1988 | }, | 2116 | }, |
1989 | }; | 2117 | }; |
1990 | 2118 | ||
@@ -2075,7 +2203,7 @@ static void alc_free(struct hda_codec *codec) | |||
2075 | struct alc_spec *spec = codec->spec; | 2203 | struct alc_spec *spec = codec->spec; |
2076 | unsigned int i; | 2204 | unsigned int i; |
2077 | 2205 | ||
2078 | if (! spec) | 2206 | if (!spec) |
2079 | return; | 2207 | return; |
2080 | 2208 | ||
2081 | if (spec->kctl_alloc) { | 2209 | if (spec->kctl_alloc) { |
@@ -2477,7 +2605,8 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
2477 | static struct alc_config_preset alc880_presets[] = { | 2605 | static struct alc_config_preset alc880_presets[] = { |
2478 | [ALC880_3ST] = { | 2606 | [ALC880_3ST] = { |
2479 | .mixers = { alc880_three_stack_mixer }, | 2607 | .mixers = { alc880_three_stack_mixer }, |
2480 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, | 2608 | .init_verbs = { alc880_volume_init_verbs, |
2609 | alc880_pin_3stack_init_verbs }, | ||
2481 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 2610 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
2482 | .dac_nids = alc880_dac_nids, | 2611 | .dac_nids = alc880_dac_nids, |
2483 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | 2612 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), |
@@ -2487,7 +2616,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2487 | }, | 2616 | }, |
2488 | [ALC880_3ST_DIG] = { | 2617 | [ALC880_3ST_DIG] = { |
2489 | .mixers = { alc880_three_stack_mixer }, | 2618 | .mixers = { alc880_three_stack_mixer }, |
2490 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, | 2619 | .init_verbs = { alc880_volume_init_verbs, |
2620 | alc880_pin_3stack_init_verbs }, | ||
2491 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 2621 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
2492 | .dac_nids = alc880_dac_nids, | 2622 | .dac_nids = alc880_dac_nids, |
2493 | .dig_out_nid = ALC880_DIGOUT_NID, | 2623 | .dig_out_nid = ALC880_DIGOUT_NID, |
@@ -2509,8 +2639,10 @@ static struct alc_config_preset alc880_presets[] = { | |||
2509 | .input_mux = &alc880_capture_source, | 2639 | .input_mux = &alc880_capture_source, |
2510 | }, | 2640 | }, |
2511 | [ALC880_5ST] = { | 2641 | [ALC880_5ST] = { |
2512 | .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer}, | 2642 | .mixers = { alc880_three_stack_mixer, |
2513 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, | 2643 | alc880_five_stack_mixer}, |
2644 | .init_verbs = { alc880_volume_init_verbs, | ||
2645 | alc880_pin_5stack_init_verbs }, | ||
2514 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 2646 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
2515 | .dac_nids = alc880_dac_nids, | 2647 | .dac_nids = alc880_dac_nids, |
2516 | .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), | 2648 | .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), |
@@ -2518,8 +2650,10 @@ static struct alc_config_preset alc880_presets[] = { | |||
2518 | .input_mux = &alc880_capture_source, | 2650 | .input_mux = &alc880_capture_source, |
2519 | }, | 2651 | }, |
2520 | [ALC880_5ST_DIG] = { | 2652 | [ALC880_5ST_DIG] = { |
2521 | .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer }, | 2653 | .mixers = { alc880_three_stack_mixer, |
2522 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, | 2654 | alc880_five_stack_mixer }, |
2655 | .init_verbs = { alc880_volume_init_verbs, | ||
2656 | alc880_pin_5stack_init_verbs }, | ||
2523 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 2657 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
2524 | .dac_nids = alc880_dac_nids, | 2658 | .dac_nids = alc880_dac_nids, |
2525 | .dig_out_nid = ALC880_DIGOUT_NID, | 2659 | .dig_out_nid = ALC880_DIGOUT_NID, |
@@ -2529,7 +2663,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2529 | }, | 2663 | }, |
2530 | [ALC880_6ST] = { | 2664 | [ALC880_6ST] = { |
2531 | .mixers = { alc880_six_stack_mixer }, | 2665 | .mixers = { alc880_six_stack_mixer }, |
2532 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, | 2666 | .init_verbs = { alc880_volume_init_verbs, |
2667 | alc880_pin_6stack_init_verbs }, | ||
2533 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), | 2668 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), |
2534 | .dac_nids = alc880_6st_dac_nids, | 2669 | .dac_nids = alc880_6st_dac_nids, |
2535 | .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), | 2670 | .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), |
@@ -2538,7 +2673,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2538 | }, | 2673 | }, |
2539 | [ALC880_6ST_DIG] = { | 2674 | [ALC880_6ST_DIG] = { |
2540 | .mixers = { alc880_six_stack_mixer }, | 2675 | .mixers = { alc880_six_stack_mixer }, |
2541 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, | 2676 | .init_verbs = { alc880_volume_init_verbs, |
2677 | alc880_pin_6stack_init_verbs }, | ||
2542 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), | 2678 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), |
2543 | .dac_nids = alc880_6st_dac_nids, | 2679 | .dac_nids = alc880_6st_dac_nids, |
2544 | .dig_out_nid = ALC880_DIGOUT_NID, | 2680 | .dig_out_nid = ALC880_DIGOUT_NID, |
@@ -2548,7 +2684,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2548 | }, | 2684 | }, |
2549 | [ALC880_W810] = { | 2685 | [ALC880_W810] = { |
2550 | .mixers = { alc880_w810_base_mixer }, | 2686 | .mixers = { alc880_w810_base_mixer }, |
2551 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs, | 2687 | .init_verbs = { alc880_volume_init_verbs, |
2688 | alc880_pin_w810_init_verbs, | ||
2552 | alc880_gpio2_init_verbs }, | 2689 | alc880_gpio2_init_verbs }, |
2553 | .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), | 2690 | .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), |
2554 | .dac_nids = alc880_w810_dac_nids, | 2691 | .dac_nids = alc880_w810_dac_nids, |
@@ -2559,7 +2696,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2559 | }, | 2696 | }, |
2560 | [ALC880_Z71V] = { | 2697 | [ALC880_Z71V] = { |
2561 | .mixers = { alc880_z71v_mixer }, | 2698 | .mixers = { alc880_z71v_mixer }, |
2562 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs }, | 2699 | .init_verbs = { alc880_volume_init_verbs, |
2700 | alc880_pin_z71v_init_verbs }, | ||
2563 | .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), | 2701 | .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), |
2564 | .dac_nids = alc880_z71v_dac_nids, | 2702 | .dac_nids = alc880_z71v_dac_nids, |
2565 | .dig_out_nid = ALC880_DIGOUT_NID, | 2703 | .dig_out_nid = ALC880_DIGOUT_NID, |
@@ -2570,7 +2708,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2570 | }, | 2708 | }, |
2571 | [ALC880_F1734] = { | 2709 | [ALC880_F1734] = { |
2572 | .mixers = { alc880_f1734_mixer }, | 2710 | .mixers = { alc880_f1734_mixer }, |
2573 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs }, | 2711 | .init_verbs = { alc880_volume_init_verbs, |
2712 | alc880_pin_f1734_init_verbs }, | ||
2574 | .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), | 2713 | .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), |
2575 | .dac_nids = alc880_f1734_dac_nids, | 2714 | .dac_nids = alc880_f1734_dac_nids, |
2576 | .hp_nid = 0x02, | 2715 | .hp_nid = 0x02, |
@@ -2580,7 +2719,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2580 | }, | 2719 | }, |
2581 | [ALC880_ASUS] = { | 2720 | [ALC880_ASUS] = { |
2582 | .mixers = { alc880_asus_mixer }, | 2721 | .mixers = { alc880_asus_mixer }, |
2583 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, | 2722 | .init_verbs = { alc880_volume_init_verbs, |
2723 | alc880_pin_asus_init_verbs, | ||
2584 | alc880_gpio1_init_verbs }, | 2724 | alc880_gpio1_init_verbs }, |
2585 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | 2725 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
2586 | .dac_nids = alc880_asus_dac_nids, | 2726 | .dac_nids = alc880_asus_dac_nids, |
@@ -2591,7 +2731,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2591 | }, | 2731 | }, |
2592 | [ALC880_ASUS_DIG] = { | 2732 | [ALC880_ASUS_DIG] = { |
2593 | .mixers = { alc880_asus_mixer }, | 2733 | .mixers = { alc880_asus_mixer }, |
2594 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, | 2734 | .init_verbs = { alc880_volume_init_verbs, |
2735 | alc880_pin_asus_init_verbs, | ||
2595 | alc880_gpio1_init_verbs }, | 2736 | alc880_gpio1_init_verbs }, |
2596 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | 2737 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
2597 | .dac_nids = alc880_asus_dac_nids, | 2738 | .dac_nids = alc880_asus_dac_nids, |
@@ -2603,7 +2744,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2603 | }, | 2744 | }, |
2604 | [ALC880_ASUS_DIG2] = { | 2745 | [ALC880_ASUS_DIG2] = { |
2605 | .mixers = { alc880_asus_mixer }, | 2746 | .mixers = { alc880_asus_mixer }, |
2606 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, | 2747 | .init_verbs = { alc880_volume_init_verbs, |
2748 | alc880_pin_asus_init_verbs, | ||
2607 | alc880_gpio2_init_verbs }, /* use GPIO2 */ | 2749 | alc880_gpio2_init_verbs }, /* use GPIO2 */ |
2608 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | 2750 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
2609 | .dac_nids = alc880_asus_dac_nids, | 2751 | .dac_nids = alc880_asus_dac_nids, |
@@ -2615,7 +2757,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2615 | }, | 2757 | }, |
2616 | [ALC880_ASUS_W1V] = { | 2758 | [ALC880_ASUS_W1V] = { |
2617 | .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, | 2759 | .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, |
2618 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, | 2760 | .init_verbs = { alc880_volume_init_verbs, |
2761 | alc880_pin_asus_init_verbs, | ||
2619 | alc880_gpio1_init_verbs }, | 2762 | alc880_gpio1_init_verbs }, |
2620 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | 2763 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
2621 | .dac_nids = alc880_asus_dac_nids, | 2764 | .dac_nids = alc880_asus_dac_nids, |
@@ -2664,7 +2807,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2664 | .init_hook = alc880_uniwill_p53_hp_automute, | 2807 | .init_hook = alc880_uniwill_p53_hp_automute, |
2665 | }, | 2808 | }, |
2666 | [ALC880_FUJITSU] = { | 2809 | [ALC880_FUJITSU] = { |
2667 | .mixers = { alc880_fujitsu_mixer, | 2810 | .mixers = { alc880_fujitsu_mixer, |
2668 | alc880_pcbeep_mixer, }, | 2811 | alc880_pcbeep_mixer, }, |
2669 | .init_verbs = { alc880_volume_init_verbs, | 2812 | .init_verbs = { alc880_volume_init_verbs, |
2670 | alc880_uniwill_p53_init_verbs, | 2813 | alc880_uniwill_p53_init_verbs, |
@@ -2707,7 +2850,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2707 | .mixers = { alc880_lg_lw_mixer }, | 2850 | .mixers = { alc880_lg_lw_mixer }, |
2708 | .init_verbs = { alc880_volume_init_verbs, | 2851 | .init_verbs = { alc880_volume_init_verbs, |
2709 | alc880_lg_lw_init_verbs }, | 2852 | alc880_lg_lw_init_verbs }, |
2710 | .num_dacs = 1, | 2853 | .num_dacs = 1, |
2711 | .dac_nids = alc880_dac_nids, | 2854 | .dac_nids = alc880_dac_nids, |
2712 | .dig_out_nid = ALC880_DIGOUT_NID, | 2855 | .dig_out_nid = ALC880_DIGOUT_NID, |
2713 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), | 2856 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), |
@@ -2749,18 +2892,21 @@ static struct snd_kcontrol_new alc880_control_templates[] = { | |||
2749 | }; | 2892 | }; |
2750 | 2893 | ||
2751 | /* add dynamic controls */ | 2894 | /* add dynamic controls */ |
2752 | static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val) | 2895 | static int add_control(struct alc_spec *spec, int type, const char *name, |
2896 | unsigned long val) | ||
2753 | { | 2897 | { |
2754 | struct snd_kcontrol_new *knew; | 2898 | struct snd_kcontrol_new *knew; |
2755 | 2899 | ||
2756 | if (spec->num_kctl_used >= spec->num_kctl_alloc) { | 2900 | if (spec->num_kctl_used >= spec->num_kctl_alloc) { |
2757 | int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; | 2901 | int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; |
2758 | 2902 | ||
2759 | knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ | 2903 | /* array + terminator */ |
2760 | if (! knew) | 2904 | knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); |
2905 | if (!knew) | ||
2761 | return -ENOMEM; | 2906 | return -ENOMEM; |
2762 | if (spec->kctl_alloc) { | 2907 | if (spec->kctl_alloc) { |
2763 | memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); | 2908 | memcpy(knew, spec->kctl_alloc, |
2909 | sizeof(*knew) * spec->num_kctl_alloc); | ||
2764 | kfree(spec->kctl_alloc); | 2910 | kfree(spec->kctl_alloc); |
2765 | } | 2911 | } |
2766 | spec->kctl_alloc = knew; | 2912 | spec->kctl_alloc = knew; |
@@ -2770,7 +2916,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign | |||
2770 | knew = &spec->kctl_alloc[spec->num_kctl_used]; | 2916 | knew = &spec->kctl_alloc[spec->num_kctl_used]; |
2771 | *knew = alc880_control_templates[type]; | 2917 | *knew = alc880_control_templates[type]; |
2772 | knew->name = kstrdup(name, GFP_KERNEL); | 2918 | knew->name = kstrdup(name, GFP_KERNEL); |
2773 | if (! knew->name) | 2919 | if (!knew->name) |
2774 | return -ENOMEM; | 2920 | return -ENOMEM; |
2775 | knew->private_value = val; | 2921 | knew->private_value = val; |
2776 | spec->num_kctl_used++; | 2922 | spec->num_kctl_used++; |
@@ -2790,7 +2936,8 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign | |||
2790 | #define ALC880_PIN_CD_NID 0x1c | 2936 | #define ALC880_PIN_CD_NID 0x1c |
2791 | 2937 | ||
2792 | /* fill in the dac_nids table from the parsed pin configuration */ | 2938 | /* fill in the dac_nids table from the parsed pin configuration */ |
2793 | static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) | 2939 | static int alc880_auto_fill_dac_nids(struct alc_spec *spec, |
2940 | const struct auto_pin_cfg *cfg) | ||
2794 | { | 2941 | { |
2795 | hda_nid_t nid; | 2942 | hda_nid_t nid; |
2796 | int assigned[4]; | 2943 | int assigned[4]; |
@@ -2815,8 +2962,9 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pi | |||
2815 | continue; | 2962 | continue; |
2816 | /* search for an empty channel */ | 2963 | /* search for an empty channel */ |
2817 | for (j = 0; j < cfg->line_outs; j++) { | 2964 | for (j = 0; j < cfg->line_outs; j++) { |
2818 | if (! assigned[j]) { | 2965 | if (!assigned[j]) { |
2819 | spec->multiout.dac_nids[i] = alc880_idx_to_dac(j); | 2966 | spec->multiout.dac_nids[i] = |
2967 | alc880_idx_to_dac(j); | ||
2820 | assigned[j] = 1; | 2968 | assigned[j] = 1; |
2821 | break; | 2969 | break; |
2822 | } | 2970 | } |
@@ -2831,36 +2979,54 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
2831 | const struct auto_pin_cfg *cfg) | 2979 | const struct auto_pin_cfg *cfg) |
2832 | { | 2980 | { |
2833 | char name[32]; | 2981 | char name[32]; |
2834 | static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; | 2982 | static const char *chname[4] = { |
2983 | "Front", "Surround", NULL /*CLFE*/, "Side" | ||
2984 | }; | ||
2835 | hda_nid_t nid; | 2985 | hda_nid_t nid; |
2836 | int i, err; | 2986 | int i, err; |
2837 | 2987 | ||
2838 | for (i = 0; i < cfg->line_outs; i++) { | 2988 | for (i = 0; i < cfg->line_outs; i++) { |
2839 | if (! spec->multiout.dac_nids[i]) | 2989 | if (!spec->multiout.dac_nids[i]) |
2840 | continue; | 2990 | continue; |
2841 | nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); | 2991 | nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); |
2842 | if (i == 2) { | 2992 | if (i == 2) { |
2843 | /* Center/LFE */ | 2993 | /* Center/LFE */ |
2844 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume", | 2994 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
2845 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) | 2995 | "Center Playback Volume", |
2996 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, | ||
2997 | HDA_OUTPUT)); | ||
2998 | if (err < 0) | ||
2846 | return err; | 2999 | return err; |
2847 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume", | 3000 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
2848 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 3001 | "LFE Playback Volume", |
3002 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
3003 | HDA_OUTPUT)); | ||
3004 | if (err < 0) | ||
2849 | return err; | 3005 | return err; |
2850 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", | 3006 | err = add_control(spec, ALC_CTL_BIND_MUTE, |
2851 | HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0) | 3007 | "Center Playback Switch", |
3008 | HDA_COMPOSE_AMP_VAL(nid, 1, 2, | ||
3009 | HDA_INPUT)); | ||
3010 | if (err < 0) | ||
2852 | return err; | 3011 | return err; |
2853 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", | 3012 | err = add_control(spec, ALC_CTL_BIND_MUTE, |
2854 | HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0) | 3013 | "LFE Playback Switch", |
3014 | HDA_COMPOSE_AMP_VAL(nid, 2, 2, | ||
3015 | HDA_INPUT)); | ||
3016 | if (err < 0) | ||
2855 | return err; | 3017 | return err; |
2856 | } else { | 3018 | } else { |
2857 | sprintf(name, "%s Playback Volume", chname[i]); | 3019 | sprintf(name, "%s Playback Volume", chname[i]); |
2858 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 3020 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, |
2859 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 3021 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, |
3022 | HDA_OUTPUT)); | ||
3023 | if (err < 0) | ||
2860 | return err; | 3024 | return err; |
2861 | sprintf(name, "%s Playback Switch", chname[i]); | 3025 | sprintf(name, "%s Playback Switch", chname[i]); |
2862 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | 3026 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, |
2863 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) | 3027 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, |
3028 | HDA_INPUT)); | ||
3029 | if (err < 0) | ||
2864 | return err; | 3030 | return err; |
2865 | } | 3031 | } |
2866 | } | 3032 | } |
@@ -2875,51 +3041,57 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
2875 | int err; | 3041 | int err; |
2876 | char name[32]; | 3042 | char name[32]; |
2877 | 3043 | ||
2878 | if (! pin) | 3044 | if (!pin) |
2879 | return 0; | 3045 | return 0; |
2880 | 3046 | ||
2881 | if (alc880_is_fixed_pin(pin)) { | 3047 | if (alc880_is_fixed_pin(pin)) { |
2882 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | 3048 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); |
2883 | /* specify the DAC as the extra output */ | 3049 | /* specify the DAC as the extra output */ |
2884 | if (! spec->multiout.hp_nid) | 3050 | if (!spec->multiout.hp_nid) |
2885 | spec->multiout.hp_nid = nid; | 3051 | spec->multiout.hp_nid = nid; |
2886 | else | 3052 | else |
2887 | spec->multiout.extra_out_nid[0] = nid; | 3053 | spec->multiout.extra_out_nid[0] = nid; |
2888 | /* control HP volume/switch on the output mixer amp */ | 3054 | /* control HP volume/switch on the output mixer amp */ |
2889 | nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); | 3055 | nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); |
2890 | sprintf(name, "%s Playback Volume", pfx); | 3056 | sprintf(name, "%s Playback Volume", pfx); |
2891 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 3057 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, |
2892 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 3058 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); |
3059 | if (err < 0) | ||
2893 | return err; | 3060 | return err; |
2894 | sprintf(name, "%s Playback Switch", pfx); | 3061 | sprintf(name, "%s Playback Switch", pfx); |
2895 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | 3062 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, |
2896 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) | 3063 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); |
3064 | if (err < 0) | ||
2897 | return err; | 3065 | return err; |
2898 | } else if (alc880_is_multi_pin(pin)) { | 3066 | } else if (alc880_is_multi_pin(pin)) { |
2899 | /* set manual connection */ | 3067 | /* set manual connection */ |
2900 | /* we have only a switch on HP-out PIN */ | 3068 | /* we have only a switch on HP-out PIN */ |
2901 | sprintf(name, "%s Playback Switch", pfx); | 3069 | sprintf(name, "%s Playback Switch", pfx); |
2902 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | 3070 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, |
2903 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0) | 3071 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); |
3072 | if (err < 0) | ||
2904 | return err; | 3073 | return err; |
2905 | } | 3074 | } |
2906 | return 0; | 3075 | return 0; |
2907 | } | 3076 | } |
2908 | 3077 | ||
2909 | /* create input playback/capture controls for the given pin */ | 3078 | /* create input playback/capture controls for the given pin */ |
2910 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname, | 3079 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, |
3080 | const char *ctlname, | ||
2911 | int idx, hda_nid_t mix_nid) | 3081 | int idx, hda_nid_t mix_nid) |
2912 | { | 3082 | { |
2913 | char name[32]; | 3083 | char name[32]; |
2914 | int err; | 3084 | int err; |
2915 | 3085 | ||
2916 | sprintf(name, "%s Playback Volume", ctlname); | 3086 | sprintf(name, "%s Playback Volume", ctlname); |
2917 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 3087 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, |
2918 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0) | 3088 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); |
3089 | if (err < 0) | ||
2919 | return err; | 3090 | return err; |
2920 | sprintf(name, "%s Playback Switch", ctlname); | 3091 | sprintf(name, "%s Playback Switch", ctlname); |
2921 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | 3092 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, |
2922 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0) | 3093 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); |
3094 | if (err < 0) | ||
2923 | return err; | 3095 | return err; |
2924 | return 0; | 3096 | return 0; |
2925 | } | 3097 | } |
@@ -2939,8 +3111,10 @@ static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, | |||
2939 | idx, 0x0b); | 3111 | idx, 0x0b); |
2940 | if (err < 0) | 3112 | if (err < 0) |
2941 | return err; | 3113 | return err; |
2942 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 3114 | imux->items[imux->num_items].label = |
2943 | imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]); | 3115 | auto_pin_cfg_labels[i]; |
3116 | imux->items[imux->num_items].index = | ||
3117 | alc880_input_pin_idx(cfg->input_pins[i]); | ||
2944 | imux->num_items++; | 3118 | imux->num_items++; |
2945 | } | 3119 | } |
2946 | } | 3120 | } |
@@ -2952,8 +3126,10 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, | |||
2952 | int dac_idx) | 3126 | int dac_idx) |
2953 | { | 3127 | { |
2954 | /* set as output */ | 3128 | /* set as output */ |
2955 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | 3129 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
2956 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 3130 | pin_type); |
3131 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
3132 | AMP_OUT_UNMUTE); | ||
2957 | /* need the manual connection? */ | 3133 | /* need the manual connection? */ |
2958 | if (alc880_is_multi_pin(nid)) { | 3134 | if (alc880_is_multi_pin(nid)) { |
2959 | struct alc_spec *spec = codec->spec; | 3135 | struct alc_spec *spec = codec->spec; |
@@ -2964,14 +3140,24 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, | |||
2964 | } | 3140 | } |
2965 | } | 3141 | } |
2966 | 3142 | ||
3143 | static int get_pin_type(int line_out_type) | ||
3144 | { | ||
3145 | if (line_out_type == AUTO_PIN_HP_OUT) | ||
3146 | return PIN_HP; | ||
3147 | else | ||
3148 | return PIN_OUT; | ||
3149 | } | ||
3150 | |||
2967 | static void alc880_auto_init_multi_out(struct hda_codec *codec) | 3151 | static void alc880_auto_init_multi_out(struct hda_codec *codec) |
2968 | { | 3152 | { |
2969 | struct alc_spec *spec = codec->spec; | 3153 | struct alc_spec *spec = codec->spec; |
2970 | int i; | 3154 | int i; |
2971 | 3155 | ||
3156 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
2972 | for (i = 0; i < spec->autocfg.line_outs; i++) { | 3157 | for (i = 0; i < spec->autocfg.line_outs; i++) { |
2973 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 3158 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
2974 | alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); | 3159 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
3160 | alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); | ||
2975 | } | 3161 | } |
2976 | } | 3162 | } |
2977 | 3163 | ||
@@ -2996,37 +3182,52 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec) | |||
2996 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 3182 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
2997 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 3183 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
2998 | if (alc880_is_input_pin(nid)) { | 3184 | if (alc880_is_input_pin(nid)) { |
2999 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 3185 | snd_hda_codec_write(codec, nid, 0, |
3000 | i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); | 3186 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
3187 | i <= AUTO_PIN_FRONT_MIC ? | ||
3188 | PIN_VREF80 : PIN_IN); | ||
3001 | if (nid != ALC880_PIN_CD_NID) | 3189 | if (nid != ALC880_PIN_CD_NID) |
3002 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 3190 | snd_hda_codec_write(codec, nid, 0, |
3191 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
3003 | AMP_OUT_MUTE); | 3192 | AMP_OUT_MUTE); |
3004 | } | 3193 | } |
3005 | } | 3194 | } |
3006 | } | 3195 | } |
3007 | 3196 | ||
3008 | /* parse the BIOS configuration and set up the alc_spec */ | 3197 | /* parse the BIOS configuration and set up the alc_spec */ |
3009 | /* return 1 if successful, 0 if the proper config is not found, or a negative error code */ | 3198 | /* return 1 if successful, 0 if the proper config is not found, |
3199 | * or a negative error code | ||
3200 | */ | ||
3010 | static int alc880_parse_auto_config(struct hda_codec *codec) | 3201 | static int alc880_parse_auto_config(struct hda_codec *codec) |
3011 | { | 3202 | { |
3012 | struct alc_spec *spec = codec->spec; | 3203 | struct alc_spec *spec = codec->spec; |
3013 | int err; | 3204 | int err; |
3014 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; | 3205 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; |
3015 | 3206 | ||
3016 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 3207 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
3017 | alc880_ignore)) < 0) | 3208 | alc880_ignore); |
3209 | if (err < 0) | ||
3018 | return err; | 3210 | return err; |
3019 | if (! spec->autocfg.line_outs) | 3211 | if (!spec->autocfg.line_outs) |
3020 | return 0; /* can't find valid BIOS pin config */ | 3212 | return 0; /* can't find valid BIOS pin config */ |
3021 | 3213 | ||
3022 | if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || | 3214 | err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); |
3023 | (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 3215 | if (err < 0) |
3024 | (err = alc880_auto_create_extra_out(spec, | 3216 | return err; |
3025 | spec->autocfg.speaker_pins[0], | 3217 | err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); |
3026 | "Speaker")) < 0 || | 3218 | if (err < 0) |
3027 | (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], | 3219 | return err; |
3028 | "Headphone")) < 0 || | 3220 | err = alc880_auto_create_extra_out(spec, |
3029 | (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 3221 | spec->autocfg.speaker_pins[0], |
3222 | "Speaker"); | ||
3223 | if (err < 0) | ||
3224 | return err; | ||
3225 | err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], | ||
3226 | "Headphone"); | ||
3227 | if (err < 0) | ||
3228 | return err; | ||
3229 | err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); | ||
3230 | if (err < 0) | ||
3030 | return err; | 3231 | return err; |
3031 | 3232 | ||
3032 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 3233 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
@@ -3086,7 +3287,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
3086 | if (err < 0) { | 3287 | if (err < 0) { |
3087 | alc_free(codec); | 3288 | alc_free(codec); |
3088 | return err; | 3289 | return err; |
3089 | } else if (! err) { | 3290 | } else if (!err) { |
3090 | printk(KERN_INFO | 3291 | printk(KERN_INFO |
3091 | "hda_codec: Cannot set up configuration " | 3292 | "hda_codec: Cannot set up configuration " |
3092 | "from BIOS. Using 3-stack mode...\n"); | 3293 | "from BIOS. Using 3-stack mode...\n"); |
@@ -3105,14 +3306,16 @@ static int patch_alc880(struct hda_codec *codec) | |||
3105 | spec->stream_digital_playback = &alc880_pcm_digital_playback; | 3306 | spec->stream_digital_playback = &alc880_pcm_digital_playback; |
3106 | spec->stream_digital_capture = &alc880_pcm_digital_capture; | 3307 | spec->stream_digital_capture = &alc880_pcm_digital_capture; |
3107 | 3308 | ||
3108 | if (! spec->adc_nids && spec->input_mux) { | 3309 | if (!spec->adc_nids && spec->input_mux) { |
3109 | /* check whether NID 0x07 is valid */ | 3310 | /* check whether NID 0x07 is valid */ |
3110 | unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); | 3311 | unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); |
3111 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ | 3312 | /* get type */ |
3313 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
3112 | if (wcap != AC_WID_AUD_IN) { | 3314 | if (wcap != AC_WID_AUD_IN) { |
3113 | spec->adc_nids = alc880_adc_nids_alt; | 3315 | spec->adc_nids = alc880_adc_nids_alt; |
3114 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); | 3316 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); |
3115 | spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer; | 3317 | spec->mixers[spec->num_mixers] = |
3318 | alc880_capture_alt_mixer; | ||
3116 | spec->num_mixers++; | 3319 | spec->num_mixers++; |
3117 | } else { | 3320 | } else { |
3118 | spec->adc_nids = alc880_adc_nids; | 3321 | spec->adc_nids = alc880_adc_nids; |
@@ -3254,7 +3457,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = { | |||
3254 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | 3457 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), |
3255 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | 3458 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), |
3256 | { } /* end */ | 3459 | { } /* end */ |
3257 | }; | 3460 | }; |
3258 | 3461 | ||
3259 | static struct snd_kcontrol_new alc260_input_mixer[] = { | 3462 | static struct snd_kcontrol_new alc260_input_mixer[] = { |
3260 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 3463 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
@@ -3349,6 +3552,42 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = { | |||
3349 | { } /* end */ | 3552 | { } /* end */ |
3350 | }; | 3553 | }; |
3351 | 3554 | ||
3555 | /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, | ||
3556 | * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. | ||
3557 | */ | ||
3558 | static struct snd_kcontrol_new alc260_will_mixer[] = { | ||
3559 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
3560 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), | ||
3561 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
3562 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
3563 | ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
3564 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
3565 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
3566 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
3567 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
3568 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
3569 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), | ||
3570 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), | ||
3571 | { } /* end */ | ||
3572 | }; | ||
3573 | |||
3574 | /* Replacer 672V ALC260 pin usage: Mic jack = 0x12, | ||
3575 | * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. | ||
3576 | */ | ||
3577 | static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { | ||
3578 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
3579 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), | ||
3580 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
3581 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
3582 | ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
3583 | HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), | ||
3584 | HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), | ||
3585 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
3586 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
3587 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
3588 | { } /* end */ | ||
3589 | }; | ||
3590 | |||
3352 | /* capture mixer elements */ | 3591 | /* capture mixer elements */ |
3353 | static struct snd_kcontrol_new alc260_capture_mixer[] = { | 3592 | static struct snd_kcontrol_new alc260_capture_mixer[] = { |
3354 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), | 3593 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), |
@@ -3434,7 +3673,9 @@ static struct hda_verb alc260_init_verbs[] = { | |||
3434 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 3673 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
3435 | /* unmute LINE-2 out pin */ | 3674 | /* unmute LINE-2 out pin */ |
3436 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 3675 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
3437 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ | 3676 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & |
3677 | * Line In 2 = 0x03 | ||
3678 | */ | ||
3438 | /* mute CD */ | 3679 | /* mute CD */ |
3439 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | 3680 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, |
3440 | /* mute Line In */ | 3681 | /* mute Line In */ |
@@ -3482,7 +3723,9 @@ static struct hda_verb alc260_hp_init_verbs[] = { | |||
3482 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 3723 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, |
3483 | /* mute pin widget amp left and right (no gain on this amp) */ | 3724 | /* mute pin widget amp left and right (no gain on this amp) */ |
3484 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | 3725 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, |
3485 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ | 3726 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & |
3727 | * Line In 2 = 0x03 | ||
3728 | */ | ||
3486 | /* unmute CD */ | 3729 | /* unmute CD */ |
3487 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | 3730 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, |
3488 | /* unmute Line In */ | 3731 | /* unmute Line In */ |
@@ -3530,7 +3773,9 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = { | |||
3530 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 3773 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, |
3531 | /* mute pin widget amp left and right (no gain on this amp) */ | 3774 | /* mute pin widget amp left and right (no gain on this amp) */ |
3532 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | 3775 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, |
3533 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ | 3776 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & |
3777 | * Line In 2 = 0x03 | ||
3778 | */ | ||
3534 | /* unmute CD */ | 3779 | /* unmute CD */ |
3535 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | 3780 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, |
3536 | /* unmute Line In */ | 3781 | /* unmute Line In */ |
@@ -3680,7 +3925,9 @@ static struct hda_verb alc260_acer_init_verbs[] = { | |||
3680 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 3925 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
3681 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 3926 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
3682 | 3927 | ||
3683 | /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */ | 3928 | /* Unmute Line-out pin widget amp left and right |
3929 | * (no equiv mixer ctrl) | ||
3930 | */ | ||
3684 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 3931 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
3685 | /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ | 3932 | /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ |
3686 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 3933 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -3719,6 +3966,55 @@ static struct hda_verb alc260_acer_init_verbs[] = { | |||
3719 | { } | 3966 | { } |
3720 | }; | 3967 | }; |
3721 | 3968 | ||
3969 | static struct hda_verb alc260_will_verbs[] = { | ||
3970 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
3971 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
3972 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
3973 | {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
3974 | {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
3975 | {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, | ||
3976 | {} | ||
3977 | }; | ||
3978 | |||
3979 | static struct hda_verb alc260_replacer_672v_verbs[] = { | ||
3980 | {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
3981 | {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
3982 | {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, | ||
3983 | |||
3984 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||
3985 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
3986 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | ||
3987 | |||
3988 | {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
3989 | {} | ||
3990 | }; | ||
3991 | |||
3992 | /* toggle speaker-output according to the hp-jack state */ | ||
3993 | static void alc260_replacer_672v_automute(struct hda_codec *codec) | ||
3994 | { | ||
3995 | unsigned int present; | ||
3996 | |||
3997 | /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ | ||
3998 | present = snd_hda_codec_read(codec, 0x0f, 0, | ||
3999 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
4000 | if (present) { | ||
4001 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1); | ||
4002 | snd_hda_codec_write(codec, 0x0f, 0, | ||
4003 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); | ||
4004 | } else { | ||
4005 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); | ||
4006 | snd_hda_codec_write(codec, 0x0f, 0, | ||
4007 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
4008 | } | ||
4009 | } | ||
4010 | |||
4011 | static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, | ||
4012 | unsigned int res) | ||
4013 | { | ||
4014 | if ((res >> 26) == ALC880_HP_EVENT) | ||
4015 | alc260_replacer_672v_automute(codec); | ||
4016 | } | ||
4017 | |||
3722 | /* Test configuration for debugging, modelled after the ALC880 test | 4018 | /* Test configuration for debugging, modelled after the ALC880 test |
3723 | * configuration. | 4019 | * configuration. |
3724 | */ | 4020 | */ |
@@ -3946,10 +4242,12 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, | |||
3946 | return 0; /* N/A */ | 4242 | return 0; /* N/A */ |
3947 | 4243 | ||
3948 | snprintf(name, sizeof(name), "%s Playback Volume", pfx); | 4244 | snprintf(name, sizeof(name), "%s Playback Volume", pfx); |
3949 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0) | 4245 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); |
4246 | if (err < 0) | ||
3950 | return err; | 4247 | return err; |
3951 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); | 4248 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); |
3952 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0) | 4249 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); |
4250 | if (err < 0) | ||
3953 | return err; | 4251 | return err; |
3954 | return 1; | 4252 | return 1; |
3955 | } | 4253 | } |
@@ -3985,7 +4283,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
3985 | if (err < 0) | 4283 | if (err < 0) |
3986 | return err; | 4284 | return err; |
3987 | } | 4285 | } |
3988 | return 0; | 4286 | return 0; |
3989 | } | 4287 | } |
3990 | 4288 | ||
3991 | /* create playback/capture controls for input pins */ | 4289 | /* create playback/capture controls for input pins */ |
@@ -3999,20 +4297,24 @@ static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, | |||
3999 | if (cfg->input_pins[i] >= 0x12) { | 4297 | if (cfg->input_pins[i] >= 0x12) { |
4000 | idx = cfg->input_pins[i] - 0x12; | 4298 | idx = cfg->input_pins[i] - 0x12; |
4001 | err = new_analog_input(spec, cfg->input_pins[i], | 4299 | err = new_analog_input(spec, cfg->input_pins[i], |
4002 | auto_pin_cfg_labels[i], idx, 0x07); | 4300 | auto_pin_cfg_labels[i], idx, |
4301 | 0x07); | ||
4003 | if (err < 0) | 4302 | if (err < 0) |
4004 | return err; | 4303 | return err; |
4005 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 4304 | imux->items[imux->num_items].label = |
4305 | auto_pin_cfg_labels[i]; | ||
4006 | imux->items[imux->num_items].index = idx; | 4306 | imux->items[imux->num_items].index = idx; |
4007 | imux->num_items++; | 4307 | imux->num_items++; |
4008 | } | 4308 | } |
4009 | if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){ | 4309 | if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){ |
4010 | idx = cfg->input_pins[i] - 0x09; | 4310 | idx = cfg->input_pins[i] - 0x09; |
4011 | err = new_analog_input(spec, cfg->input_pins[i], | 4311 | err = new_analog_input(spec, cfg->input_pins[i], |
4012 | auto_pin_cfg_labels[i], idx, 0x07); | 4312 | auto_pin_cfg_labels[i], idx, |
4313 | 0x07); | ||
4013 | if (err < 0) | 4314 | if (err < 0) |
4014 | return err; | 4315 | return err; |
4015 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 4316 | imux->items[imux->num_items].label = |
4317 | auto_pin_cfg_labels[i]; | ||
4016 | imux->items[imux->num_items].index = idx; | 4318 | imux->items[imux->num_items].index = idx; |
4017 | imux->num_items++; | 4319 | imux->num_items++; |
4018 | } | 4320 | } |
@@ -4025,14 +4327,15 @@ static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, | |||
4025 | int sel_idx) | 4327 | int sel_idx) |
4026 | { | 4328 | { |
4027 | /* set as output */ | 4329 | /* set as output */ |
4028 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | 4330 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
4029 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 4331 | pin_type); |
4332 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
4333 | AMP_OUT_UNMUTE); | ||
4030 | /* need the manual connection? */ | 4334 | /* need the manual connection? */ |
4031 | if (nid >= 0x12) { | 4335 | if (nid >= 0x12) { |
4032 | int idx = nid - 0x12; | 4336 | int idx = nid - 0x12; |
4033 | snd_hda_codec_write(codec, idx + 0x0b, 0, | 4337 | snd_hda_codec_write(codec, idx + 0x0b, 0, |
4034 | AC_VERB_SET_CONNECT_SEL, sel_idx); | 4338 | AC_VERB_SET_CONNECT_SEL, sel_idx); |
4035 | |||
4036 | } | 4339 | } |
4037 | } | 4340 | } |
4038 | 4341 | ||
@@ -4041,9 +4344,12 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) | |||
4041 | struct alc_spec *spec = codec->spec; | 4344 | struct alc_spec *spec = codec->spec; |
4042 | hda_nid_t nid; | 4345 | hda_nid_t nid; |
4043 | 4346 | ||
4044 | nid = spec->autocfg.line_out_pins[0]; | 4347 | alc_subsystem_id(codec, 0x10, 0x15, 0x0f); |
4045 | if (nid) | 4348 | nid = spec->autocfg.line_out_pins[0]; |
4046 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); | 4349 | if (nid) { |
4350 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
4351 | alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); | ||
4352 | } | ||
4047 | 4353 | ||
4048 | nid = spec->autocfg.speaker_pins[0]; | 4354 | nid = spec->autocfg.speaker_pins[0]; |
4049 | if (nid) | 4355 | if (nid) |
@@ -4051,8 +4357,8 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) | |||
4051 | 4357 | ||
4052 | nid = spec->autocfg.hp_pins[0]; | 4358 | nid = spec->autocfg.hp_pins[0]; |
4053 | if (nid) | 4359 | if (nid) |
4054 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); | 4360 | alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); |
4055 | } | 4361 | } |
4056 | 4362 | ||
4057 | #define ALC260_PIN_CD_NID 0x16 | 4363 | #define ALC260_PIN_CD_NID 0x16 |
4058 | static void alc260_auto_init_analog_input(struct hda_codec *codec) | 4364 | static void alc260_auto_init_analog_input(struct hda_codec *codec) |
@@ -4063,10 +4369,13 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec) | |||
4063 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 4369 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
4064 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 4370 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
4065 | if (nid >= 0x12) { | 4371 | if (nid >= 0x12) { |
4066 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 4372 | snd_hda_codec_write(codec, nid, 0, |
4067 | i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); | 4373 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
4374 | i <= AUTO_PIN_FRONT_MIC ? | ||
4375 | PIN_VREF80 : PIN_IN); | ||
4068 | if (nid != ALC260_PIN_CD_NID) | 4376 | if (nid != ALC260_PIN_CD_NID) |
4069 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 4377 | snd_hda_codec_write(codec, nid, 0, |
4378 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
4070 | AMP_OUT_MUTE); | 4379 | AMP_OUT_MUTE); |
4071 | } | 4380 | } |
4072 | } | 4381 | } |
@@ -4086,8 +4395,8 @@ static struct hda_verb alc260_volume_init_verbs[] = { | |||
4086 | 4395 | ||
4087 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 4396 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
4088 | * mixer widget | 4397 | * mixer widget |
4089 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 4398 | * Note: PASD motherboards uses the Line In 2 as the input for |
4090 | * mic (mic 2) | 4399 | * front panel mic (mic 2) |
4091 | */ | 4400 | */ |
4092 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 4401 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
4093 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 4402 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -4122,14 +4431,17 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
4122 | int err; | 4431 | int err; |
4123 | static hda_nid_t alc260_ignore[] = { 0x17, 0 }; | 4432 | static hda_nid_t alc260_ignore[] = { 0x17, 0 }; |
4124 | 4433 | ||
4125 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 4434 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
4126 | alc260_ignore)) < 0) | 4435 | alc260_ignore); |
4436 | if (err < 0) | ||
4127 | return err; | 4437 | return err; |
4128 | if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0) | 4438 | err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); |
4439 | if (err < 0) | ||
4129 | return err; | 4440 | return err; |
4130 | if (! spec->kctl_alloc) | 4441 | if (!spec->kctl_alloc) |
4131 | return 0; /* can't find valid BIOS pin config */ | 4442 | return 0; /* can't find valid BIOS pin config */ |
4132 | if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 4443 | err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); |
4444 | if (err < 0) | ||
4133 | return err; | 4445 | return err; |
4134 | 4446 | ||
4135 | spec->multiout.max_channels = 2; | 4447 | spec->multiout.max_channels = 2; |
@@ -4177,6 +4489,8 @@ static const char *alc260_models[ALC260_MODEL_LAST] = { | |||
4177 | [ALC260_HP_3013] = "hp-3013", | 4489 | [ALC260_HP_3013] = "hp-3013", |
4178 | [ALC260_FUJITSU_S702X] = "fujitsu", | 4490 | [ALC260_FUJITSU_S702X] = "fujitsu", |
4179 | [ALC260_ACER] = "acer", | 4491 | [ALC260_ACER] = "acer", |
4492 | [ALC260_WILL] = "will", | ||
4493 | [ALC260_REPLACER_672V] = "replacer", | ||
4180 | #ifdef CONFIG_SND_DEBUG | 4494 | #ifdef CONFIG_SND_DEBUG |
4181 | [ALC260_TEST] = "test", | 4495 | [ALC260_TEST] = "test", |
4182 | #endif | 4496 | #endif |
@@ -4200,6 +4514,8 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { | |||
4200 | SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), | 4514 | SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), |
4201 | SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), | 4515 | SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), |
4202 | SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), | 4516 | SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), |
4517 | SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), | ||
4518 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), | ||
4203 | {} | 4519 | {} |
4204 | }; | 4520 | }; |
4205 | 4521 | ||
@@ -4270,6 +4586,34 @@ static struct alc_config_preset alc260_presets[] = { | |||
4270 | .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), | 4586 | .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), |
4271 | .input_mux = alc260_acer_capture_sources, | 4587 | .input_mux = alc260_acer_capture_sources, |
4272 | }, | 4588 | }, |
4589 | [ALC260_WILL] = { | ||
4590 | .mixers = { alc260_will_mixer, | ||
4591 | alc260_capture_mixer }, | ||
4592 | .init_verbs = { alc260_init_verbs, alc260_will_verbs }, | ||
4593 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
4594 | .dac_nids = alc260_dac_nids, | ||
4595 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), | ||
4596 | .adc_nids = alc260_adc_nids, | ||
4597 | .dig_out_nid = ALC260_DIGOUT_NID, | ||
4598 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
4599 | .channel_mode = alc260_modes, | ||
4600 | .input_mux = &alc260_capture_source, | ||
4601 | }, | ||
4602 | [ALC260_REPLACER_672V] = { | ||
4603 | .mixers = { alc260_replacer_672v_mixer, | ||
4604 | alc260_capture_mixer }, | ||
4605 | .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, | ||
4606 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
4607 | .dac_nids = alc260_dac_nids, | ||
4608 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), | ||
4609 | .adc_nids = alc260_adc_nids, | ||
4610 | .dig_out_nid = ALC260_DIGOUT_NID, | ||
4611 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
4612 | .channel_mode = alc260_modes, | ||
4613 | .input_mux = &alc260_capture_source, | ||
4614 | .unsol_event = alc260_replacer_672v_unsol_event, | ||
4615 | .init_hook = alc260_replacer_672v_automute, | ||
4616 | }, | ||
4273 | #ifdef CONFIG_SND_DEBUG | 4617 | #ifdef CONFIG_SND_DEBUG |
4274 | [ALC260_TEST] = { | 4618 | [ALC260_TEST] = { |
4275 | .mixers = { alc260_test_mixer, | 4619 | .mixers = { alc260_test_mixer, |
@@ -4313,7 +4657,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
4313 | if (err < 0) { | 4657 | if (err < 0) { |
4314 | alc_free(codec); | 4658 | alc_free(codec); |
4315 | return err; | 4659 | return err; |
4316 | } else if (! err) { | 4660 | } else if (!err) { |
4317 | printk(KERN_INFO | 4661 | printk(KERN_INFO |
4318 | "hda_codec: Cannot set up configuration " | 4662 | "hda_codec: Cannot set up configuration " |
4319 | "from BIOS. Using base mode...\n"); | 4663 | "from BIOS. Using base mode...\n"); |
@@ -4382,7 +4726,8 @@ static struct hda_input_mux alc882_capture_source = { | |||
4382 | #define alc882_mux_enum_info alc_mux_enum_info | 4726 | #define alc882_mux_enum_info alc_mux_enum_info |
4383 | #define alc882_mux_enum_get alc_mux_enum_get | 4727 | #define alc882_mux_enum_get alc_mux_enum_get |
4384 | 4728 | ||
4385 | static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 4729 | static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, |
4730 | struct snd_ctl_elem_value *ucontrol) | ||
4386 | { | 4731 | { |
4387 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 4732 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
4388 | struct alc_spec *spec = codec->spec; | 4733 | struct alc_spec *spec = codec->spec; |
@@ -4396,7 +4741,7 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
4396 | idx = ucontrol->value.enumerated.item[0]; | 4741 | idx = ucontrol->value.enumerated.item[0]; |
4397 | if (idx >= imux->num_items) | 4742 | if (idx >= imux->num_items) |
4398 | idx = imux->num_items - 1; | 4743 | idx = imux->num_items - 1; |
4399 | if (*cur_val == idx && ! codec->in_resume) | 4744 | if (*cur_val == idx && !codec->in_resume) |
4400 | return 0; | 4745 | return 0; |
4401 | for (i = 0; i < imux->num_items; i++) { | 4746 | for (i = 0; i < imux->num_items; i++) { |
4402 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | 4747 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; |
@@ -4464,6 +4809,21 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { | |||
4464 | { } /* end */ | 4809 | { } /* end */ |
4465 | }; | 4810 | }; |
4466 | 4811 | ||
4812 | static struct snd_kcontrol_new alc882_w2jc_mixer[] = { | ||
4813 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
4814 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
4815 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
4816 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
4817 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
4818 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
4819 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
4820 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
4821 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
4822 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
4823 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
4824 | { } /* end */ | ||
4825 | }; | ||
4826 | |||
4467 | static struct snd_kcontrol_new alc882_chmode_mixer[] = { | 4827 | static struct snd_kcontrol_new alc882_chmode_mixer[] = { |
4468 | { | 4828 | { |
4469 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 4829 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -4559,7 +4919,7 @@ static struct hda_verb alc882_eapd_verbs[] = { | |||
4559 | /* change to EAPD mode */ | 4919 | /* change to EAPD mode */ |
4560 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | 4920 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, |
4561 | {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, | 4921 | {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, |
4562 | { } | 4922 | { } |
4563 | }; | 4923 | }; |
4564 | 4924 | ||
4565 | /* Mac Pro test */ | 4925 | /* Mac Pro test */ |
@@ -4624,6 +4984,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = { | |||
4624 | 4984 | ||
4625 | { } | 4985 | { } |
4626 | }; | 4986 | }; |
4987 | |||
4627 | static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) | 4988 | static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) |
4628 | { | 4989 | { |
4629 | unsigned int gpiostate, gpiomask, gpiodir; | 4990 | unsigned int gpiostate, gpiomask, gpiodir; |
@@ -4672,8 +5033,8 @@ static struct hda_verb alc882_auto_init_verbs[] = { | |||
4672 | 5033 | ||
4673 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 5034 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
4674 | * mixer widget | 5035 | * mixer widget |
4675 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 5036 | * Note: PASD motherboards uses the Line In 2 as the input for |
4676 | * mic (mic 2) | 5037 | * front panel mic (mic 2) |
4677 | */ | 5038 | */ |
4678 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 5039 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
4679 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 5040 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -4782,6 +5143,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { | |||
4782 | [ALC882_3ST_DIG] = "3stack-dig", | 5143 | [ALC882_3ST_DIG] = "3stack-dig", |
4783 | [ALC882_6ST_DIG] = "6stack-dig", | 5144 | [ALC882_6ST_DIG] = "6stack-dig", |
4784 | [ALC882_ARIMA] = "arima", | 5145 | [ALC882_ARIMA] = "arima", |
5146 | [ALC882_W2JC] = "w2jc", | ||
4785 | [ALC885_MACPRO] = "macpro", | 5147 | [ALC885_MACPRO] = "macpro", |
4786 | [ALC882_AUTO] = "auto", | 5148 | [ALC882_AUTO] = "auto", |
4787 | }; | 5149 | }; |
@@ -4792,6 +5154,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { | |||
4792 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), | 5154 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), |
4793 | SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), | 5155 | SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), |
4794 | SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), | 5156 | SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), |
5157 | SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), | ||
4795 | {} | 5158 | {} |
4796 | }; | 5159 | }; |
4797 | 5160 | ||
@@ -4828,6 +5191,18 @@ static struct alc_config_preset alc882_presets[] = { | |||
4828 | .channel_mode = alc882_sixstack_modes, | 5191 | .channel_mode = alc882_sixstack_modes, |
4829 | .input_mux = &alc882_capture_source, | 5192 | .input_mux = &alc882_capture_source, |
4830 | }, | 5193 | }, |
5194 | [ALC882_W2JC] = { | ||
5195 | .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, | ||
5196 | .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, | ||
5197 | alc880_gpio1_init_verbs }, | ||
5198 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
5199 | .dac_nids = alc882_dac_nids, | ||
5200 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
5201 | .channel_mode = alc880_threestack_modes, | ||
5202 | .need_dac_fix = 1, | ||
5203 | .input_mux = &alc882_capture_source, | ||
5204 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
5205 | }, | ||
4831 | [ALC885_MACPRO] = { | 5206 | [ALC885_MACPRO] = { |
4832 | .mixers = { alc882_macpro_mixer }, | 5207 | .mixers = { alc882_macpro_mixer }, |
4833 | .init_verbs = { alc882_macpro_init_verbs }, | 5208 | .init_verbs = { alc882_macpro_init_verbs }, |
@@ -4851,15 +5226,17 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, | |||
4851 | { | 5226 | { |
4852 | /* set as output */ | 5227 | /* set as output */ |
4853 | struct alc_spec *spec = codec->spec; | 5228 | struct alc_spec *spec = codec->spec; |
4854 | int idx; | 5229 | int idx; |
4855 | 5230 | ||
4856 | if (spec->multiout.dac_nids[dac_idx] == 0x25) | 5231 | if (spec->multiout.dac_nids[dac_idx] == 0x25) |
4857 | idx = 4; | 5232 | idx = 4; |
4858 | else | 5233 | else |
4859 | idx = spec->multiout.dac_nids[dac_idx] - 2; | 5234 | idx = spec->multiout.dac_nids[dac_idx] - 2; |
4860 | 5235 | ||
4861 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | 5236 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
4862 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 5237 | pin_type); |
5238 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
5239 | AMP_OUT_UNMUTE); | ||
4863 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); | 5240 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); |
4864 | 5241 | ||
4865 | } | 5242 | } |
@@ -4869,10 +5246,13 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec) | |||
4869 | struct alc_spec *spec = codec->spec; | 5246 | struct alc_spec *spec = codec->spec; |
4870 | int i; | 5247 | int i; |
4871 | 5248 | ||
5249 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
4872 | for (i = 0; i <= HDA_SIDE; i++) { | 5250 | for (i = 0; i <= HDA_SIDE; i++) { |
4873 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 5251 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
5252 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
4874 | if (nid) | 5253 | if (nid) |
4875 | alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); | 5254 | alc882_auto_set_output_and_unmute(codec, nid, pin_type, |
5255 | i); | ||
4876 | } | 5256 | } |
4877 | } | 5257 | } |
4878 | 5258 | ||
@@ -4883,7 +5263,8 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec) | |||
4883 | 5263 | ||
4884 | pin = spec->autocfg.hp_pins[0]; | 5264 | pin = spec->autocfg.hp_pins[0]; |
4885 | if (pin) /* connect to front */ | 5265 | if (pin) /* connect to front */ |
4886 | alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */ | 5266 | /* use dac 0 */ |
5267 | alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); | ||
4887 | } | 5268 | } |
4888 | 5269 | ||
4889 | #define alc882_is_input_pin(nid) alc880_is_input_pin(nid) | 5270 | #define alc882_is_input_pin(nid) alc880_is_input_pin(nid) |
@@ -4897,10 +5278,13 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) | |||
4897 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 5278 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
4898 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 5279 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
4899 | if (alc882_is_input_pin(nid)) { | 5280 | if (alc882_is_input_pin(nid)) { |
4900 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 5281 | snd_hda_codec_write(codec, nid, 0, |
4901 | i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); | 5282 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
5283 | i <= AUTO_PIN_FRONT_MIC ? | ||
5284 | PIN_VREF80 : PIN_IN); | ||
4902 | if (nid != ALC882_PIN_CD_NID) | 5285 | if (nid != ALC882_PIN_CD_NID) |
4903 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 5286 | snd_hda_codec_write(codec, nid, 0, |
5287 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
4904 | AMP_OUT_MUTE); | 5288 | AMP_OUT_MUTE); |
4905 | } | 5289 | } |
4906 | } | 5290 | } |
@@ -4962,7 +5346,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
4962 | if (err < 0) { | 5346 | if (err < 0) { |
4963 | alc_free(codec); | 5347 | alc_free(codec); |
4964 | return err; | 5348 | return err; |
4965 | } else if (! err) { | 5349 | } else if (!err) { |
4966 | printk(KERN_INFO | 5350 | printk(KERN_INFO |
4967 | "hda_codec: Cannot set up configuration " | 5351 | "hda_codec: Cannot set up configuration " |
4968 | "from BIOS. Using base mode...\n"); | 5352 | "from BIOS. Using base mode...\n"); |
@@ -4986,14 +5370,16 @@ static int patch_alc882(struct hda_codec *codec) | |||
4986 | spec->stream_digital_playback = &alc882_pcm_digital_playback; | 5370 | spec->stream_digital_playback = &alc882_pcm_digital_playback; |
4987 | spec->stream_digital_capture = &alc882_pcm_digital_capture; | 5371 | spec->stream_digital_capture = &alc882_pcm_digital_capture; |
4988 | 5372 | ||
4989 | if (! spec->adc_nids && spec->input_mux) { | 5373 | if (!spec->adc_nids && spec->input_mux) { |
4990 | /* check whether NID 0x07 is valid */ | 5374 | /* check whether NID 0x07 is valid */ |
4991 | unsigned int wcap = get_wcaps(codec, 0x07); | 5375 | unsigned int wcap = get_wcaps(codec, 0x07); |
4992 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ | 5376 | /* get type */ |
5377 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
4993 | if (wcap != AC_WID_AUD_IN) { | 5378 | if (wcap != AC_WID_AUD_IN) { |
4994 | spec->adc_nids = alc882_adc_nids_alt; | 5379 | spec->adc_nids = alc882_adc_nids_alt; |
4995 | spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); | 5380 | spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); |
4996 | spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer; | 5381 | spec->mixers[spec->num_mixers] = |
5382 | alc882_capture_alt_mixer; | ||
4997 | spec->num_mixers++; | 5383 | spec->num_mixers++; |
4998 | } else { | 5384 | } else { |
4999 | spec->adc_nids = alc882_adc_nids; | 5385 | spec->adc_nids = alc882_adc_nids; |
@@ -5033,6 +5419,7 @@ static hda_nid_t alc883_adc_nids[2] = { | |||
5033 | /* ADC1-2 */ | 5419 | /* ADC1-2 */ |
5034 | 0x08, 0x09, | 5420 | 0x08, 0x09, |
5035 | }; | 5421 | }; |
5422 | |||
5036 | /* input MUX */ | 5423 | /* input MUX */ |
5037 | /* FIXME: should be a matrix-type input source selection */ | 5424 | /* FIXME: should be a matrix-type input source selection */ |
5038 | 5425 | ||
@@ -5045,6 +5432,15 @@ static struct hda_input_mux alc883_capture_source = { | |||
5045 | { "CD", 0x4 }, | 5432 | { "CD", 0x4 }, |
5046 | }, | 5433 | }, |
5047 | }; | 5434 | }; |
5435 | |||
5436 | static struct hda_input_mux alc883_lenovo_101e_capture_source = { | ||
5437 | .num_items = 2, | ||
5438 | .items = { | ||
5439 | { "Mic", 0x1 }, | ||
5440 | { "Line", 0x2 }, | ||
5441 | }, | ||
5442 | }; | ||
5443 | |||
5048 | #define alc883_mux_enum_info alc_mux_enum_info | 5444 | #define alc883_mux_enum_info alc_mux_enum_info |
5049 | #define alc883_mux_enum_get alc_mux_enum_get | 5445 | #define alc883_mux_enum_get alc_mux_enum_get |
5050 | 5446 | ||
@@ -5063,7 +5459,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
5063 | idx = ucontrol->value.enumerated.item[0]; | 5459 | idx = ucontrol->value.enumerated.item[0]; |
5064 | if (idx >= imux->num_items) | 5460 | if (idx >= imux->num_items) |
5065 | idx = imux->num_items - 1; | 5461 | idx = imux->num_items - 1; |
5066 | if (*cur_val == idx && ! codec->in_resume) | 5462 | if (*cur_val == idx && !codec->in_resume) |
5067 | return 0; | 5463 | return 0; |
5068 | for (i = 0; i < imux->num_items; i++) { | 5464 | for (i = 0; i < imux->num_items; i++) { |
5069 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | 5465 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; |
@@ -5073,6 +5469,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
5073 | *cur_val = idx; | 5469 | *cur_val = idx; |
5074 | return 1; | 5470 | return 1; |
5075 | } | 5471 | } |
5472 | |||
5076 | /* | 5473 | /* |
5077 | * 2ch mode | 5474 | * 2ch mode |
5078 | */ | 5475 | */ |
@@ -5325,7 +5722,7 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = { | |||
5325 | .put = alc883_mux_enum_put, | 5722 | .put = alc883_mux_enum_put, |
5326 | }, | 5723 | }, |
5327 | { } /* end */ | 5724 | { } /* end */ |
5328 | }; | 5725 | }; |
5329 | 5726 | ||
5330 | static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { | 5727 | static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { |
5331 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 5728 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
@@ -5350,7 +5747,30 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { | |||
5350 | .put = alc883_mux_enum_put, | 5747 | .put = alc883_mux_enum_put, |
5351 | }, | 5748 | }, |
5352 | { } /* end */ | 5749 | { } /* end */ |
5353 | }; | 5750 | }; |
5751 | |||
5752 | static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { | ||
5753 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
5754 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
5755 | HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
5756 | HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), | ||
5757 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
5758 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
5759 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
5760 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
5761 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
5762 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
5763 | { | ||
5764 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5765 | /* .name = "Capture Source", */ | ||
5766 | .name = "Input Source", | ||
5767 | .count = 1, | ||
5768 | .info = alc883_mux_enum_info, | ||
5769 | .get = alc883_mux_enum_get, | ||
5770 | .put = alc883_mux_enum_put, | ||
5771 | }, | ||
5772 | { } /* end */ | ||
5773 | }; | ||
5354 | 5774 | ||
5355 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { | 5775 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { |
5356 | { | 5776 | { |
@@ -5452,10 +5872,17 @@ static struct hda_verb alc883_tagra_verbs[] = { | |||
5452 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | 5872 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ |
5453 | 5873 | ||
5454 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 5874 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
5455 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | 5875 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, |
5456 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, | 5876 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, |
5457 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, | 5877 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, |
5878 | |||
5879 | { } /* end */ | ||
5880 | }; | ||
5458 | 5881 | ||
5882 | static struct hda_verb alc883_lenovo_101e_verbs[] = { | ||
5883 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5884 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, | ||
5885 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, | ||
5459 | { } /* end */ | 5886 | { } /* end */ |
5460 | }; | 5887 | }; |
5461 | 5888 | ||
@@ -5463,14 +5890,17 @@ static struct hda_verb alc883_tagra_verbs[] = { | |||
5463 | static void alc883_tagra_automute(struct hda_codec *codec) | 5890 | static void alc883_tagra_automute(struct hda_codec *codec) |
5464 | { | 5891 | { |
5465 | unsigned int present; | 5892 | unsigned int present; |
5893 | unsigned char bits; | ||
5466 | 5894 | ||
5467 | present = snd_hda_codec_read(codec, 0x14, 0, | 5895 | present = snd_hda_codec_read(codec, 0x14, 0, |
5468 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 5896 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
5897 | bits = present ? 0x80 : 0; | ||
5469 | snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, | 5898 | snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, |
5470 | 0x80, present ? 0x80 : 0); | 5899 | 0x80, bits); |
5471 | snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, | 5900 | snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, |
5472 | 0x80, present ? 0x80 : 0); | 5901 | 0x80, bits); |
5473 | snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3); | 5902 | snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, |
5903 | present ? 1 : 3); | ||
5474 | } | 5904 | } |
5475 | 5905 | ||
5476 | static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) | 5906 | static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -5479,6 +5909,47 @@ static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) | |||
5479 | alc883_tagra_automute(codec); | 5909 | alc883_tagra_automute(codec); |
5480 | } | 5910 | } |
5481 | 5911 | ||
5912 | static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | ||
5913 | { | ||
5914 | unsigned int present; | ||
5915 | unsigned char bits; | ||
5916 | |||
5917 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
5918 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
5919 | bits = present ? 0x80 : 0; | ||
5920 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | ||
5921 | 0x80, bits); | ||
5922 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | ||
5923 | 0x80, bits); | ||
5924 | } | ||
5925 | |||
5926 | static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) | ||
5927 | { | ||
5928 | unsigned int present; | ||
5929 | unsigned char bits; | ||
5930 | |||
5931 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
5932 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
5933 | bits = present ? 0x80 : 0; | ||
5934 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | ||
5935 | 0x80, bits); | ||
5936 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | ||
5937 | 0x80, bits); | ||
5938 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | ||
5939 | 0x80, bits); | ||
5940 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | ||
5941 | 0x80, bits); | ||
5942 | } | ||
5943 | |||
5944 | static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, | ||
5945 | unsigned int res) | ||
5946 | { | ||
5947 | if ((res >> 26) == ALC880_HP_EVENT) | ||
5948 | alc883_lenovo_101e_all_automute(codec); | ||
5949 | if ((res >> 26) == ALC880_FRONT_EVENT) | ||
5950 | alc883_lenovo_101e_ispeaker_automute(codec); | ||
5951 | } | ||
5952 | |||
5482 | /* | 5953 | /* |
5483 | * generic initialization of ADC, input mixers and output mixers | 5954 | * generic initialization of ADC, input mixers and output mixers |
5484 | */ | 5955 | */ |
@@ -5493,8 +5964,8 @@ static struct hda_verb alc883_auto_init_verbs[] = { | |||
5493 | 5964 | ||
5494 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 5965 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
5495 | * mixer widget | 5966 | * mixer widget |
5496 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 5967 | * Note: PASD motherboards uses the Line In 2 as the input for |
5497 | * mic (mic 2) | 5968 | * front panel mic (mic 2) |
5498 | */ | 5969 | */ |
5499 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 5970 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
5500 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 5971 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -5530,13 +6001,13 @@ static struct hda_verb alc883_auto_init_verbs[] = { | |||
5530 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 6001 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
5531 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 6002 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
5532 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 6003 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
5533 | //{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 6004 | /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ |
5534 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | 6005 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, |
5535 | /* Input mixer2 */ | 6006 | /* Input mixer2 */ |
5536 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 6007 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
5537 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 6008 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
5538 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 6009 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
5539 | //{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 6010 | /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ |
5540 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | 6011 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, |
5541 | 6012 | ||
5542 | { } | 6013 | { } |
@@ -5584,6 +6055,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { | |||
5584 | [ALC883_ACER] = "acer", | 6055 | [ALC883_ACER] = "acer", |
5585 | [ALC883_MEDION] = "medion", | 6056 | [ALC883_MEDION] = "medion", |
5586 | [ALC883_LAPTOP_EAPD] = "laptop-eapd", | 6057 | [ALC883_LAPTOP_EAPD] = "laptop-eapd", |
6058 | [ALC883_LENOVO_101E_2ch] = "lenovo-101e", | ||
5587 | [ALC883_AUTO] = "auto", | 6059 | [ALC883_AUTO] = "auto", |
5588 | }; | 6060 | }; |
5589 | 6061 | ||
@@ -5592,6 +6064,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
5592 | SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), | 6064 | SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), |
5593 | SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), | 6065 | SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), |
5594 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), | 6066 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), |
6067 | SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), | ||
5595 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), | 6068 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), |
5596 | SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), | 6069 | SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), |
5597 | SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), | 6070 | SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), |
@@ -5609,6 +6082,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
5609 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), | 6082 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), |
5610 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), | 6083 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), |
5611 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), | 6084 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), |
6085 | SND_PCI_QUIRK(0x17aa, 0x101e, "lenovo 101e", ALC883_LENOVO_101E_2ch), | ||
5612 | {} | 6086 | {} |
5613 | }; | 6087 | }; |
5614 | 6088 | ||
@@ -5639,7 +6113,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
5639 | .channel_mode = alc883_3ST_6ch_modes, | 6113 | .channel_mode = alc883_3ST_6ch_modes, |
5640 | .need_dac_fix = 1, | 6114 | .need_dac_fix = 1, |
5641 | .input_mux = &alc883_capture_source, | 6115 | .input_mux = &alc883_capture_source, |
5642 | }, | 6116 | }, |
5643 | [ALC883_3ST_6ch] = { | 6117 | [ALC883_3ST_6ch] = { |
5644 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 6118 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
5645 | .init_verbs = { alc883_init_verbs }, | 6119 | .init_verbs = { alc883_init_verbs }, |
@@ -5651,7 +6125,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
5651 | .channel_mode = alc883_3ST_6ch_modes, | 6125 | .channel_mode = alc883_3ST_6ch_modes, |
5652 | .need_dac_fix = 1, | 6126 | .need_dac_fix = 1, |
5653 | .input_mux = &alc883_capture_source, | 6127 | .input_mux = &alc883_capture_source, |
5654 | }, | 6128 | }, |
5655 | [ALC883_6ST_DIG] = { | 6129 | [ALC883_6ST_DIG] = { |
5656 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | 6130 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, |
5657 | .init_verbs = { alc883_init_verbs }, | 6131 | .init_verbs = { alc883_init_verbs }, |
@@ -5749,6 +6223,19 @@ static struct alc_config_preset alc883_presets[] = { | |||
5749 | .channel_mode = alc883_3ST_2ch_modes, | 6223 | .channel_mode = alc883_3ST_2ch_modes, |
5750 | .input_mux = &alc883_capture_source, | 6224 | .input_mux = &alc883_capture_source, |
5751 | }, | 6225 | }, |
6226 | [ALC883_LENOVO_101E_2ch] = { | ||
6227 | .mixers = { alc883_lenovo_101e_2ch_mixer}, | ||
6228 | .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, | ||
6229 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
6230 | .dac_nids = alc883_dac_nids, | ||
6231 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
6232 | .adc_nids = alc883_adc_nids, | ||
6233 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
6234 | .channel_mode = alc883_3ST_2ch_modes, | ||
6235 | .input_mux = &alc883_lenovo_101e_capture_source, | ||
6236 | .unsol_event = alc883_lenovo_101e_unsol_event, | ||
6237 | .init_hook = alc883_lenovo_101e_all_automute, | ||
6238 | }, | ||
5752 | }; | 6239 | }; |
5753 | 6240 | ||
5754 | 6241 | ||
@@ -5761,8 +6248,8 @@ static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, | |||
5761 | { | 6248 | { |
5762 | /* set as output */ | 6249 | /* set as output */ |
5763 | struct alc_spec *spec = codec->spec; | 6250 | struct alc_spec *spec = codec->spec; |
5764 | int idx; | 6251 | int idx; |
5765 | 6252 | ||
5766 | if (spec->multiout.dac_nids[dac_idx] == 0x25) | 6253 | if (spec->multiout.dac_nids[dac_idx] == 0x25) |
5767 | idx = 4; | 6254 | idx = 4; |
5768 | else | 6255 | else |
@@ -5781,10 +6268,13 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec) | |||
5781 | struct alc_spec *spec = codec->spec; | 6268 | struct alc_spec *spec = codec->spec; |
5782 | int i; | 6269 | int i; |
5783 | 6270 | ||
6271 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
5784 | for (i = 0; i <= HDA_SIDE; i++) { | 6272 | for (i = 0; i <= HDA_SIDE; i++) { |
5785 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 6273 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
6274 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
5786 | if (nid) | 6275 | if (nid) |
5787 | alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); | 6276 | alc883_auto_set_output_and_unmute(codec, nid, pin_type, |
6277 | i); | ||
5788 | } | 6278 | } |
5789 | } | 6279 | } |
5790 | 6280 | ||
@@ -5833,8 +6323,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec) | |||
5833 | else if (err > 0) | 6323 | else if (err > 0) |
5834 | /* hack - override the init verbs */ | 6324 | /* hack - override the init verbs */ |
5835 | spec->init_verbs[0] = alc883_auto_init_verbs; | 6325 | spec->init_verbs[0] = alc883_auto_init_verbs; |
5836 | spec->mixers[spec->num_mixers] = alc883_capture_mixer; | 6326 | spec->mixers[spec->num_mixers] = alc883_capture_mixer; |
5837 | spec->num_mixers++; | 6327 | spec->num_mixers++; |
5838 | return err; | 6328 | return err; |
5839 | } | 6329 | } |
5840 | 6330 | ||
@@ -5872,7 +6362,7 @@ static int patch_alc883(struct hda_codec *codec) | |||
5872 | if (err < 0) { | 6362 | if (err < 0) { |
5873 | alc_free(codec); | 6363 | alc_free(codec); |
5874 | return err; | 6364 | return err; |
5875 | } else if (! err) { | 6365 | } else if (!err) { |
5876 | printk(KERN_INFO | 6366 | printk(KERN_INFO |
5877 | "hda_codec: Cannot set up configuration " | 6367 | "hda_codec: Cannot set up configuration " |
5878 | "from BIOS. Using base mode...\n"); | 6368 | "from BIOS. Using base mode...\n"); |
@@ -5891,7 +6381,7 @@ static int patch_alc883(struct hda_codec *codec) | |||
5891 | spec->stream_digital_playback = &alc883_pcm_digital_playback; | 6381 | spec->stream_digital_playback = &alc883_pcm_digital_playback; |
5892 | spec->stream_digital_capture = &alc883_pcm_digital_capture; | 6382 | spec->stream_digital_capture = &alc883_pcm_digital_capture; |
5893 | 6383 | ||
5894 | if (! spec->adc_nids && spec->input_mux) { | 6384 | if (!spec->adc_nids && spec->input_mux) { |
5895 | spec->adc_nids = alc883_adc_nids; | 6385 | spec->adc_nids = alc883_adc_nids; |
5896 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | 6386 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); |
5897 | } | 6387 | } |
@@ -6028,8 +6518,8 @@ static struct hda_verb alc262_init_verbs[] = { | |||
6028 | 6518 | ||
6029 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 6519 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
6030 | * mixer widget | 6520 | * mixer widget |
6031 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 6521 | * Note: PASD motherboards uses the Line In 2 as the input for |
6032 | * mic (mic 2) | 6522 | * front panel mic (mic 2) |
6033 | */ | 6523 | */ |
6034 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 6524 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
6035 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 6525 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -6086,7 +6576,7 @@ static struct hda_verb alc262_init_verbs[] = { | |||
6086 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | 6576 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, |
6087 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, | 6577 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, |
6088 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, | 6578 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, |
6089 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, | 6579 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, |
6090 | 6580 | ||
6091 | { } | 6581 | { } |
6092 | }; | 6582 | }; |
@@ -6113,7 +6603,7 @@ static void alc262_hippo_automute(struct hda_codec *codec, int force) | |||
6113 | struct alc_spec *spec = codec->spec; | 6603 | struct alc_spec *spec = codec->spec; |
6114 | unsigned int mute; | 6604 | unsigned int mute; |
6115 | 6605 | ||
6116 | if (force || ! spec->sense_updated) { | 6606 | if (force || !spec->sense_updated) { |
6117 | unsigned int present; | 6607 | unsigned int present; |
6118 | /* need to execute and sync at first */ | 6608 | /* need to execute and sync at first */ |
6119 | snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); | 6609 | snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); |
@@ -6153,7 +6643,7 @@ static void alc262_hippo1_automute(struct hda_codec *codec, int force) | |||
6153 | struct alc_spec *spec = codec->spec; | 6643 | struct alc_spec *spec = codec->spec; |
6154 | unsigned int mute; | 6644 | unsigned int mute; |
6155 | 6645 | ||
6156 | if (force || ! spec->sense_updated) { | 6646 | if (force || !spec->sense_updated) { |
6157 | unsigned int present; | 6647 | unsigned int present; |
6158 | /* need to execute and sync at first */ | 6648 | /* need to execute and sync at first */ |
6159 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); | 6649 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); |
@@ -6226,7 +6716,7 @@ static void alc262_fujitsu_automute(struct hda_codec *codec, int force) | |||
6226 | struct alc_spec *spec = codec->spec; | 6716 | struct alc_spec *spec = codec->spec; |
6227 | unsigned int mute; | 6717 | unsigned int mute; |
6228 | 6718 | ||
6229 | if (force || ! spec->sense_updated) { | 6719 | if (force || !spec->sense_updated) { |
6230 | unsigned int present; | 6720 | unsigned int present; |
6231 | /* need to execute and sync at first */ | 6721 | /* need to execute and sync at first */ |
6232 | snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); | 6722 | snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); |
@@ -6331,7 +6821,8 @@ static struct hda_verb alc262_EAPD_verbs[] = { | |||
6331 | }; | 6821 | }; |
6332 | 6822 | ||
6333 | /* add playback controls from the parsed DAC table */ | 6823 | /* add playback controls from the parsed DAC table */ |
6334 | static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) | 6824 | static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, |
6825 | const struct auto_pin_cfg *cfg) | ||
6335 | { | 6826 | { |
6336 | hda_nid_t nid; | 6827 | hda_nid_t nid; |
6337 | int err; | 6828 | int err; |
@@ -6342,26 +6833,39 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct | |||
6342 | 6833 | ||
6343 | nid = cfg->line_out_pins[0]; | 6834 | nid = cfg->line_out_pins[0]; |
6344 | if (nid) { | 6835 | if (nid) { |
6345 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume", | 6836 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
6346 | HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) | 6837 | "Front Playback Volume", |
6838 | HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT)); | ||
6839 | if (err < 0) | ||
6347 | return err; | 6840 | return err; |
6348 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch", | 6841 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
6349 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 6842 | "Front Playback Switch", |
6843 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | ||
6844 | if (err < 0) | ||
6350 | return err; | 6845 | return err; |
6351 | } | 6846 | } |
6352 | 6847 | ||
6353 | nid = cfg->speaker_pins[0]; | 6848 | nid = cfg->speaker_pins[0]; |
6354 | if (nid) { | 6849 | if (nid) { |
6355 | if (nid == 0x16) { | 6850 | if (nid == 0x16) { |
6356 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", | 6851 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
6357 | HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0) | 6852 | "Speaker Playback Volume", |
6853 | HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, | ||
6854 | HDA_OUTPUT)); | ||
6855 | if (err < 0) | ||
6358 | return err; | 6856 | return err; |
6359 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", | 6857 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
6360 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 6858 | "Speaker Playback Switch", |
6859 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
6860 | HDA_OUTPUT)); | ||
6861 | if (err < 0) | ||
6361 | return err; | 6862 | return err; |
6362 | } else { | 6863 | } else { |
6363 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", | 6864 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
6364 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 6865 | "Speaker Playback Switch", |
6866 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | ||
6867 | HDA_OUTPUT)); | ||
6868 | if (err < 0) | ||
6365 | return err; | 6869 | return err; |
6366 | } | 6870 | } |
6367 | } | 6871 | } |
@@ -6369,23 +6873,33 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct | |||
6369 | if (nid) { | 6873 | if (nid) { |
6370 | /* spec->multiout.hp_nid = 2; */ | 6874 | /* spec->multiout.hp_nid = 2; */ |
6371 | if (nid == 0x16) { | 6875 | if (nid == 0x16) { |
6372 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume", | 6876 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
6373 | HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0) | 6877 | "Headphone Playback Volume", |
6878 | HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, | ||
6879 | HDA_OUTPUT)); | ||
6880 | if (err < 0) | ||
6374 | return err; | 6881 | return err; |
6375 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", | 6882 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
6376 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 6883 | "Headphone Playback Switch", |
6884 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
6885 | HDA_OUTPUT)); | ||
6886 | if (err < 0) | ||
6377 | return err; | 6887 | return err; |
6378 | } else { | 6888 | } else { |
6379 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", | 6889 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
6380 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 6890 | "Headphone Playback Switch", |
6891 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | ||
6892 | HDA_OUTPUT)); | ||
6893 | if (err < 0) | ||
6381 | return err; | 6894 | return err; |
6382 | } | 6895 | } |
6383 | } | 6896 | } |
6384 | return 0; | 6897 | return 0; |
6385 | } | 6898 | } |
6386 | 6899 | ||
6387 | /* identical with ALC880 */ | 6900 | /* identical with ALC880 */ |
6388 | #define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls | 6901 | #define alc262_auto_create_analog_input_ctls \ |
6902 | alc880_auto_create_analog_input_ctls | ||
6389 | 6903 | ||
6390 | /* | 6904 | /* |
6391 | * generic initialization of ADC, input mixers and output mixers | 6905 | * generic initialization of ADC, input mixers and output mixers |
@@ -6403,8 +6917,8 @@ static struct hda_verb alc262_volume_init_verbs[] = { | |||
6403 | 6917 | ||
6404 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 6918 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
6405 | * mixer widget | 6919 | * mixer widget |
6406 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 6920 | * Note: PASD motherboards uses the Line In 2 as the input for |
6407 | * mic (mic 2) | 6921 | * front panel mic (mic 2) |
6408 | */ | 6922 | */ |
6409 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 6923 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
6410 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 6924 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -6464,8 +6978,8 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = { | |||
6464 | 6978 | ||
6465 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 6979 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
6466 | * mixer widget | 6980 | * mixer widget |
6467 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 6981 | * Note: PASD motherboards uses the Line In 2 as the input for |
6468 | * mic (mic 2) | 6982 | * front panel mic (mic 2) |
6469 | */ | 6983 | */ |
6470 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 6984 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
6471 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 6985 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -6647,13 +7161,17 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
6647 | int err; | 7161 | int err; |
6648 | static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; | 7162 | static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; |
6649 | 7163 | ||
6650 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 7164 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
6651 | alc262_ignore)) < 0) | 7165 | alc262_ignore); |
7166 | if (err < 0) | ||
6652 | return err; | 7167 | return err; |
6653 | if (! spec->autocfg.line_outs) | 7168 | if (!spec->autocfg.line_outs) |
6654 | return 0; /* can't find valid BIOS pin config */ | 7169 | return 0; /* can't find valid BIOS pin config */ |
6655 | if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 7170 | err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); |
6656 | (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 7171 | if (err < 0) |
7172 | return err; | ||
7173 | err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg); | ||
7174 | if (err < 0) | ||
6657 | return err; | 7175 | return err; |
6658 | 7176 | ||
6659 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 7177 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
@@ -6777,7 +7295,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
6777 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 7295 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
6778 | .channel_mode = alc262_modes, | 7296 | .channel_mode = alc262_modes, |
6779 | .input_mux = &alc262_HP_capture_source, | 7297 | .input_mux = &alc262_HP_capture_source, |
6780 | }, | 7298 | }, |
6781 | [ALC262_HP_BPC_D7000_WF] = { | 7299 | [ALC262_HP_BPC_D7000_WF] = { |
6782 | .mixers = { alc262_HP_BPC_WildWest_mixer }, | 7300 | .mixers = { alc262_HP_BPC_WildWest_mixer }, |
6783 | .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, | 7301 | .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, |
@@ -6787,7 +7305,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
6787 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 7305 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
6788 | .channel_mode = alc262_modes, | 7306 | .channel_mode = alc262_modes, |
6789 | .input_mux = &alc262_HP_capture_source, | 7307 | .input_mux = &alc262_HP_capture_source, |
6790 | }, | 7308 | }, |
6791 | [ALC262_HP_BPC_D7000_WL] = { | 7309 | [ALC262_HP_BPC_D7000_WL] = { |
6792 | .mixers = { alc262_HP_BPC_WildWest_mixer, | 7310 | .mixers = { alc262_HP_BPC_WildWest_mixer, |
6793 | alc262_HP_BPC_WildWest_option_mixer }, | 7311 | alc262_HP_BPC_WildWest_option_mixer }, |
@@ -6798,7 +7316,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
6798 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 7316 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
6799 | .channel_mode = alc262_modes, | 7317 | .channel_mode = alc262_modes, |
6800 | .input_mux = &alc262_HP_capture_source, | 7318 | .input_mux = &alc262_HP_capture_source, |
6801 | }, | 7319 | }, |
6802 | [ALC262_BENQ_ED8] = { | 7320 | [ALC262_BENQ_ED8] = { |
6803 | .mixers = { alc262_base_mixer }, | 7321 | .mixers = { alc262_base_mixer }, |
6804 | .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, | 7322 | .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, |
@@ -6808,7 +7326,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
6808 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 7326 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
6809 | .channel_mode = alc262_modes, | 7327 | .channel_mode = alc262_modes, |
6810 | .input_mux = &alc262_capture_source, | 7328 | .input_mux = &alc262_capture_source, |
6811 | }, | 7329 | }, |
6812 | }; | 7330 | }; |
6813 | 7331 | ||
6814 | static int patch_alc262(struct hda_codec *codec) | 7332 | static int patch_alc262(struct hda_codec *codec) |
@@ -6823,7 +7341,9 @@ static int patch_alc262(struct hda_codec *codec) | |||
6823 | 7341 | ||
6824 | codec->spec = spec; | 7342 | codec->spec = spec; |
6825 | #if 0 | 7343 | #if 0 |
6826 | /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is under-run */ | 7344 | /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is |
7345 | * under-run | ||
7346 | */ | ||
6827 | { | 7347 | { |
6828 | int tmp; | 7348 | int tmp; |
6829 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); | 7349 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); |
@@ -6849,7 +7369,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
6849 | if (err < 0) { | 7369 | if (err < 0) { |
6850 | alc_free(codec); | 7370 | alc_free(codec); |
6851 | return err; | 7371 | return err; |
6852 | } else if (! err) { | 7372 | } else if (!err) { |
6853 | printk(KERN_INFO | 7373 | printk(KERN_INFO |
6854 | "hda_codec: Cannot set up configuration " | 7374 | "hda_codec: Cannot set up configuration " |
6855 | "from BIOS. Using base mode...\n"); | 7375 | "from BIOS. Using base mode...\n"); |
@@ -6868,15 +7388,17 @@ static int patch_alc262(struct hda_codec *codec) | |||
6868 | spec->stream_digital_playback = &alc262_pcm_digital_playback; | 7388 | spec->stream_digital_playback = &alc262_pcm_digital_playback; |
6869 | spec->stream_digital_capture = &alc262_pcm_digital_capture; | 7389 | spec->stream_digital_capture = &alc262_pcm_digital_capture; |
6870 | 7390 | ||
6871 | if (! spec->adc_nids && spec->input_mux) { | 7391 | if (!spec->adc_nids && spec->input_mux) { |
6872 | /* check whether NID 0x07 is valid */ | 7392 | /* check whether NID 0x07 is valid */ |
6873 | unsigned int wcap = get_wcaps(codec, 0x07); | 7393 | unsigned int wcap = get_wcaps(codec, 0x07); |
6874 | 7394 | ||
6875 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ | 7395 | /* get type */ |
7396 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
6876 | if (wcap != AC_WID_AUD_IN) { | 7397 | if (wcap != AC_WID_AUD_IN) { |
6877 | spec->adc_nids = alc262_adc_nids_alt; | 7398 | spec->adc_nids = alc262_adc_nids_alt; |
6878 | spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); | 7399 | spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); |
6879 | spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer; | 7400 | spec->mixers[spec->num_mixers] = |
7401 | alc262_capture_alt_mixer; | ||
6880 | spec->num_mixers++; | 7402 | spec->num_mixers++; |
6881 | } else { | 7403 | } else { |
6882 | spec->adc_nids = alc262_adc_nids; | 7404 | spec->adc_nids = alc262_adc_nids; |
@@ -6904,7 +7426,9 @@ static int patch_alc262(struct hda_codec *codec) | |||
6904 | static struct hda_verb alc861_threestack_ch2_init[] = { | 7426 | static struct hda_verb alc861_threestack_ch2_init[] = { |
6905 | /* set pin widget 1Ah (line in) for input */ | 7427 | /* set pin widget 1Ah (line in) for input */ |
6906 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | 7428 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, |
6907 | /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ | 7429 | /* set pin widget 18h (mic1/2) for input, for mic also enable |
7430 | * the vref | ||
7431 | */ | ||
6908 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 7432 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, |
6909 | 7433 | ||
6910 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, | 7434 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, |
@@ -6961,7 +7485,9 @@ static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { | |||
6961 | static struct hda_verb alc861_asus_ch2_init[] = { | 7485 | static struct hda_verb alc861_asus_ch2_init[] = { |
6962 | /* set pin widget 1Ah (line in) for input */ | 7486 | /* set pin widget 1Ah (line in) for input */ |
6963 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | 7487 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, |
6964 | /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ | 7488 | /* set pin widget 18h (mic1/2) for input, for mic also enable |
7489 | * the vref | ||
7490 | */ | ||
6965 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 7491 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, |
6966 | 7492 | ||
6967 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, | 7493 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, |
@@ -7016,7 +7542,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = { | |||
7016 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | 7542 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), |
7017 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | 7543 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), |
7018 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), | 7544 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), |
7019 | 7545 | ||
7020 | /* Capture mixer control */ | 7546 | /* Capture mixer control */ |
7021 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | 7547 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
7022 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | 7548 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
@@ -7050,7 +7576,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = { | |||
7050 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | 7576 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), |
7051 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | 7577 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), |
7052 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), | 7578 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), |
7053 | 7579 | ||
7054 | /* Capture mixer control */ | 7580 | /* Capture mixer control */ |
7055 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | 7581 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
7056 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | 7582 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
@@ -7092,7 +7618,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = { | |||
7092 | }, | 7618 | }, |
7093 | 7619 | ||
7094 | { } /* end */ | 7620 | { } /* end */ |
7095 | }; | 7621 | }; |
7096 | 7622 | ||
7097 | static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { | 7623 | static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { |
7098 | /* output mixer control */ | 7624 | /* output mixer control */ |
@@ -7113,7 +7639,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { | |||
7113 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | 7639 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), |
7114 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | 7640 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), |
7115 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), | 7641 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), |
7116 | 7642 | ||
7117 | /* Capture mixer control */ | 7643 | /* Capture mixer control */ |
7118 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | 7644 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
7119 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | 7645 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
@@ -7134,7 +7660,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { | |||
7134 | .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), | 7660 | .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), |
7135 | }, | 7661 | }, |
7136 | { } /* end */ | 7662 | { } /* end */ |
7137 | }; | 7663 | }; |
7138 | 7664 | ||
7139 | static struct snd_kcontrol_new alc861_asus_mixer[] = { | 7665 | static struct snd_kcontrol_new alc861_asus_mixer[] = { |
7140 | /* output mixer control */ | 7666 | /* output mixer control */ |
@@ -7154,8 +7680,8 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = { | |||
7154 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), | 7680 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), |
7155 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | 7681 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), |
7156 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | 7682 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), |
7157 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */ | 7683 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), |
7158 | 7684 | ||
7159 | /* Capture mixer control */ | 7685 | /* Capture mixer control */ |
7160 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | 7686 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
7161 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | 7687 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
@@ -7239,7 +7765,7 @@ static struct hda_verb alc861_base_init_verbs[] = { | |||
7239 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7765 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7240 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7766 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7241 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7767 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7242 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step | 7768 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ |
7243 | 7769 | ||
7244 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7770 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7245 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7771 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -7249,7 +7775,8 @@ static struct hda_verb alc861_base_init_verbs[] = { | |||
7249 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7775 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7250 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7776 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7251 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7777 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7252 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) | 7778 | /* hp used DAC 3 (Front) */ |
7779 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
7253 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7780 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7254 | 7781 | ||
7255 | { } | 7782 | { } |
@@ -7300,7 +7827,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = { | |||
7300 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7827 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7301 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7828 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7302 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7829 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7303 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step | 7830 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ |
7304 | 7831 | ||
7305 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7832 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7306 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7833 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -7310,7 +7837,8 @@ static struct hda_verb alc861_threestack_init_verbs[] = { | |||
7310 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7837 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7311 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7838 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7312 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7839 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7313 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) | 7840 | /* hp used DAC 3 (Front) */ |
7841 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
7314 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7842 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7315 | { } | 7843 | { } |
7316 | }; | 7844 | }; |
@@ -7329,7 +7857,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { | |||
7329 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 7857 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, |
7330 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 7858 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
7331 | /* port-E for HP out (front panel) */ | 7859 | /* port-E for HP out (front panel) */ |
7332 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80 | 7860 | /* this has to be set to VREF80 */ |
7861 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
7333 | /* route front PCM to HP */ | 7862 | /* route front PCM to HP */ |
7334 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 7863 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
7335 | /* port-F for mic-in (front panel) with vref */ | 7864 | /* port-F for mic-in (front panel) with vref */ |
@@ -7360,7 +7889,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { | |||
7360 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7889 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7361 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7890 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7362 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7891 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7363 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step | 7892 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ |
7364 | 7893 | ||
7365 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7894 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7366 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7895 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -7370,7 +7899,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { | |||
7370 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7899 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7371 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7900 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7372 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7901 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7373 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) | 7902 | /* hp used DAC 3 (Front) */ |
7903 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
7374 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7904 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7375 | { } | 7905 | { } |
7376 | }; | 7906 | }; |
@@ -7379,7 +7909,9 @@ static struct hda_verb alc861_asus_init_verbs[] = { | |||
7379 | /* | 7909 | /* |
7380 | * Unmute ADC0 and set the default input to mic-in | 7910 | * Unmute ADC0 and set the default input to mic-in |
7381 | */ | 7911 | */ |
7382 | /* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/ | 7912 | /* port-A for surround (rear panel) |
7913 | * according to codec#0 this is the HP jack | ||
7914 | */ | ||
7383 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ | 7915 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ |
7384 | /* route front PCM to HP */ | 7916 | /* route front PCM to HP */ |
7385 | { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, | 7917 | { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, |
@@ -7391,7 +7923,8 @@ static struct hda_verb alc861_asus_init_verbs[] = { | |||
7391 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 7923 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, |
7392 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 7924 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
7393 | /* port-E for HP out (front panel) */ | 7925 | /* port-E for HP out (front panel) */ |
7394 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */ | 7926 | /* this has to be set to VREF80 */ |
7927 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
7395 | /* route front PCM to HP */ | 7928 | /* route front PCM to HP */ |
7396 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 7929 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
7397 | /* port-F for mic-in (front panel) with vref */ | 7930 | /* port-F for mic-in (front panel) with vref */ |
@@ -7421,7 +7954,7 @@ static struct hda_verb alc861_asus_init_verbs[] = { | |||
7421 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7954 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7422 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7955 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7423 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7956 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7424 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, /* Output 0~12 step */ | 7957 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ |
7425 | 7958 | ||
7426 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7959 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7427 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7960 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -7431,7 +7964,8 @@ static struct hda_verb alc861_asus_init_verbs[] = { | |||
7431 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7964 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7432 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7965 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7433 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7966 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7434 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */ | 7967 | /* hp used DAC 3 (Front) */ |
7968 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
7435 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7969 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7436 | { } | 7970 | { } |
7437 | }; | 7971 | }; |
@@ -7450,7 +7984,7 @@ static struct hda_verb alc861_auto_init_verbs[] = { | |||
7450 | /* | 7984 | /* |
7451 | * Unmute ADC0 and set the default input to mic-in | 7985 | * Unmute ADC0 and set the default input to mic-in |
7452 | */ | 7986 | */ |
7453 | // {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | 7987 | /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ |
7454 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7988 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7455 | 7989 | ||
7456 | /* Unmute DAC0~3 & spdif out*/ | 7990 | /* Unmute DAC0~3 & spdif out*/ |
@@ -7483,21 +8017,21 @@ static struct hda_verb alc861_auto_init_verbs[] = { | |||
7483 | 8017 | ||
7484 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8018 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
7485 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 8019 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
7486 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 8020 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7487 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 8021 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, |
7488 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8022 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
7489 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 8023 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
7490 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 8024 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7491 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 8025 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, |
7492 | 8026 | ||
7493 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, // set Mic 1 | 8027 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ |
7494 | 8028 | ||
7495 | { } | 8029 | { } |
7496 | }; | 8030 | }; |
7497 | 8031 | ||
7498 | static struct hda_verb alc861_toshiba_init_verbs[] = { | 8032 | static struct hda_verb alc861_toshiba_init_verbs[] = { |
7499 | {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | 8033 | {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
7500 | 8034 | ||
7501 | { } | 8035 | { } |
7502 | }; | 8036 | }; |
7503 | 8037 | ||
@@ -7521,9 +8055,6 @@ static void alc861_toshiba_automute(struct hda_codec *codec) | |||
7521 | static void alc861_toshiba_unsol_event(struct hda_codec *codec, | 8055 | static void alc861_toshiba_unsol_event(struct hda_codec *codec, |
7522 | unsigned int res) | 8056 | unsigned int res) |
7523 | { | 8057 | { |
7524 | /* Looks like the unsol event is incompatible with the standard | ||
7525 | * definition. 6bit tag is placed at 26 bit! | ||
7526 | */ | ||
7527 | if ((res >> 26) == ALC880_HP_EVENT) | 8058 | if ((res >> 26) == ALC880_HP_EVENT) |
7528 | alc861_toshiba_automute(codec); | 8059 | alc861_toshiba_automute(codec); |
7529 | } | 8060 | } |
@@ -7568,7 +8099,8 @@ static struct hda_input_mux alc861_capture_source = { | |||
7568 | }; | 8099 | }; |
7569 | 8100 | ||
7570 | /* fill in the dac_nids table from the parsed pin configuration */ | 8101 | /* fill in the dac_nids table from the parsed pin configuration */ |
7571 | static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) | 8102 | static int alc861_auto_fill_dac_nids(struct alc_spec *spec, |
8103 | const struct auto_pin_cfg *cfg) | ||
7572 | { | 8104 | { |
7573 | int i; | 8105 | int i; |
7574 | hda_nid_t nid; | 8106 | hda_nid_t nid; |
@@ -7591,29 +8123,40 @@ static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
7591 | const struct auto_pin_cfg *cfg) | 8123 | const struct auto_pin_cfg *cfg) |
7592 | { | 8124 | { |
7593 | char name[32]; | 8125 | char name[32]; |
7594 | static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; | 8126 | static const char *chname[4] = { |
8127 | "Front", "Surround", NULL /*CLFE*/, "Side" | ||
8128 | }; | ||
7595 | hda_nid_t nid; | 8129 | hda_nid_t nid; |
7596 | int i, idx, err; | 8130 | int i, idx, err; |
7597 | 8131 | ||
7598 | for (i = 0; i < cfg->line_outs; i++) { | 8132 | for (i = 0; i < cfg->line_outs; i++) { |
7599 | nid = spec->multiout.dac_nids[i]; | 8133 | nid = spec->multiout.dac_nids[i]; |
7600 | if (! nid) | 8134 | if (!nid) |
7601 | continue; | 8135 | continue; |
7602 | if (nid == 0x05) { | 8136 | if (nid == 0x05) { |
7603 | /* Center/LFE */ | 8137 | /* Center/LFE */ |
7604 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", | 8138 | err = add_control(spec, ALC_CTL_BIND_MUTE, |
7605 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) | 8139 | "Center Playback Switch", |
8140 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, | ||
8141 | HDA_OUTPUT)); | ||
8142 | if (err < 0) | ||
7606 | return err; | 8143 | return err; |
7607 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", | 8144 | err = add_control(spec, ALC_CTL_BIND_MUTE, |
7608 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 8145 | "LFE Playback Switch", |
8146 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
8147 | HDA_OUTPUT)); | ||
8148 | if (err < 0) | ||
7609 | return err; | 8149 | return err; |
7610 | } else { | 8150 | } else { |
7611 | for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++) | 8151 | for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; |
8152 | idx++) | ||
7612 | if (nid == alc861_dac_nids[idx]) | 8153 | if (nid == alc861_dac_nids[idx]) |
7613 | break; | 8154 | break; |
7614 | sprintf(name, "%s Playback Switch", chname[idx]); | 8155 | sprintf(name, "%s Playback Switch", chname[idx]); |
7615 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | 8156 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, |
7616 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 8157 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, |
8158 | HDA_OUTPUT)); | ||
8159 | if (err < 0) | ||
7617 | return err; | 8160 | return err; |
7618 | } | 8161 | } |
7619 | } | 8162 | } |
@@ -7625,13 +8168,15 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) | |||
7625 | int err; | 8168 | int err; |
7626 | hda_nid_t nid; | 8169 | hda_nid_t nid; |
7627 | 8170 | ||
7628 | if (! pin) | 8171 | if (!pin) |
7629 | return 0; | 8172 | return 0; |
7630 | 8173 | ||
7631 | if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { | 8174 | if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { |
7632 | nid = 0x03; | 8175 | nid = 0x03; |
7633 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", | 8176 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
7634 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 8177 | "Headphone Playback Switch", |
8178 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | ||
8179 | if (err < 0) | ||
7635 | return err; | 8180 | return err; |
7636 | spec->multiout.hp_nid = nid; | 8181 | spec->multiout.hp_nid = nid; |
7637 | } | 8182 | } |
@@ -7639,32 +8184,33 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) | |||
7639 | } | 8184 | } |
7640 | 8185 | ||
7641 | /* create playback/capture controls for input pins */ | 8186 | /* create playback/capture controls for input pins */ |
7642 | static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) | 8187 | static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, |
8188 | const struct auto_pin_cfg *cfg) | ||
7643 | { | 8189 | { |
7644 | struct hda_input_mux *imux = &spec->private_imux; | 8190 | struct hda_input_mux *imux = &spec->private_imux; |
7645 | int i, err, idx, idx1; | 8191 | int i, err, idx, idx1; |
7646 | 8192 | ||
7647 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 8193 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
7648 | switch(cfg->input_pins[i]) { | 8194 | switch (cfg->input_pins[i]) { |
7649 | case 0x0c: | 8195 | case 0x0c: |
7650 | idx1 = 1; | 8196 | idx1 = 1; |
7651 | idx = 2; // Line In | 8197 | idx = 2; /* Line In */ |
7652 | break; | 8198 | break; |
7653 | case 0x0f: | 8199 | case 0x0f: |
7654 | idx1 = 2; | 8200 | idx1 = 2; |
7655 | idx = 2; // Line In | 8201 | idx = 2; /* Line In */ |
7656 | break; | 8202 | break; |
7657 | case 0x0d: | 8203 | case 0x0d: |
7658 | idx1 = 0; | 8204 | idx1 = 0; |
7659 | idx = 1; // Mic In | 8205 | idx = 1; /* Mic In */ |
7660 | break; | 8206 | break; |
7661 | case 0x10: | 8207 | case 0x10: |
7662 | idx1 = 3; | 8208 | idx1 = 3; |
7663 | idx = 1; // Mic In | 8209 | idx = 1; /* Mic In */ |
7664 | break; | 8210 | break; |
7665 | case 0x11: | 8211 | case 0x11: |
7666 | idx1 = 4; | 8212 | idx1 = 4; |
7667 | idx = 0; // CD | 8213 | idx = 0; /* CD */ |
7668 | break; | 8214 | break; |
7669 | default: | 8215 | default: |
7670 | continue; | 8216 | continue; |
@@ -7677,7 +8223,7 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const str | |||
7677 | 8223 | ||
7678 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 8224 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; |
7679 | imux->items[imux->num_items].index = idx1; | 8225 | imux->items[imux->num_items].index = idx1; |
7680 | imux->num_items++; | 8226 | imux->num_items++; |
7681 | } | 8227 | } |
7682 | return 0; | 8228 | return 0; |
7683 | } | 8229 | } |
@@ -7702,13 +8248,16 @@ static struct snd_kcontrol_new alc861_capture_mixer[] = { | |||
7702 | { } /* end */ | 8248 | { } /* end */ |
7703 | }; | 8249 | }; |
7704 | 8250 | ||
7705 | static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, | 8251 | static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, |
8252 | hda_nid_t nid, | ||
7706 | int pin_type, int dac_idx) | 8253 | int pin_type, int dac_idx) |
7707 | { | 8254 | { |
7708 | /* set as output */ | 8255 | /* set as output */ |
7709 | 8256 | ||
7710 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | 8257 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
7711 | snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 8258 | pin_type); |
8259 | snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
8260 | AMP_OUT_UNMUTE); | ||
7712 | 8261 | ||
7713 | } | 8262 | } |
7714 | 8263 | ||
@@ -7717,10 +8266,13 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec) | |||
7717 | struct alc_spec *spec = codec->spec; | 8266 | struct alc_spec *spec = codec->spec; |
7718 | int i; | 8267 | int i; |
7719 | 8268 | ||
8269 | alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); | ||
7720 | for (i = 0; i < spec->autocfg.line_outs; i++) { | 8270 | for (i = 0; i < spec->autocfg.line_outs; i++) { |
7721 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 8271 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
8272 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
7722 | if (nid) | 8273 | if (nid) |
7723 | alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]); | 8274 | alc861_auto_set_output_and_unmute(codec, nid, pin_type, |
8275 | spec->multiout.dac_nids[i]); | ||
7724 | } | 8276 | } |
7725 | } | 8277 | } |
7726 | 8278 | ||
@@ -7731,7 +8283,8 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec) | |||
7731 | 8283 | ||
7732 | pin = spec->autocfg.hp_pins[0]; | 8284 | pin = spec->autocfg.hp_pins[0]; |
7733 | if (pin) /* connect to front */ | 8285 | if (pin) /* connect to front */ |
7734 | alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]); | 8286 | alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, |
8287 | spec->multiout.dac_nids[0]); | ||
7735 | } | 8288 | } |
7736 | 8289 | ||
7737 | static void alc861_auto_init_analog_input(struct hda_codec *codec) | 8290 | static void alc861_auto_init_analog_input(struct hda_codec *codec) |
@@ -7741,31 +8294,43 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec) | |||
7741 | 8294 | ||
7742 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 8295 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
7743 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 8296 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
7744 | if ((nid>=0x0c) && (nid <=0x11)) { | 8297 | if (nid >= 0x0c && nid <= 0x11) { |
7745 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 8298 | snd_hda_codec_write(codec, nid, 0, |
7746 | i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); | 8299 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
8300 | i <= AUTO_PIN_FRONT_MIC ? | ||
8301 | PIN_VREF80 : PIN_IN); | ||
7747 | } | 8302 | } |
7748 | } | 8303 | } |
7749 | } | 8304 | } |
7750 | 8305 | ||
7751 | /* parse the BIOS configuration and set up the alc_spec */ | 8306 | /* parse the BIOS configuration and set up the alc_spec */ |
7752 | /* return 1 if successful, 0 if the proper config is not found, or a negative error code */ | 8307 | /* return 1 if successful, 0 if the proper config is not found, |
8308 | * or a negative error code | ||
8309 | */ | ||
7753 | static int alc861_parse_auto_config(struct hda_codec *codec) | 8310 | static int alc861_parse_auto_config(struct hda_codec *codec) |
7754 | { | 8311 | { |
7755 | struct alc_spec *spec = codec->spec; | 8312 | struct alc_spec *spec = codec->spec; |
7756 | int err; | 8313 | int err; |
7757 | static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; | 8314 | static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; |
7758 | 8315 | ||
7759 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 8316 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
7760 | alc861_ignore)) < 0) | 8317 | alc861_ignore); |
8318 | if (err < 0) | ||
7761 | return err; | 8319 | return err; |
7762 | if (! spec->autocfg.line_outs) | 8320 | if (!spec->autocfg.line_outs) |
7763 | return 0; /* can't find valid BIOS pin config */ | 8321 | return 0; /* can't find valid BIOS pin config */ |
7764 | 8322 | ||
7765 | if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || | 8323 | err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); |
7766 | (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 8324 | if (err < 0) |
7767 | (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0])) < 0 || | 8325 | return err; |
7768 | (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 8326 | err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); |
8327 | if (err < 0) | ||
8328 | return err; | ||
8329 | err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); | ||
8330 | if (err < 0) | ||
8331 | return err; | ||
8332 | err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); | ||
8333 | if (err < 0) | ||
7769 | return err; | 8334 | return err; |
7770 | 8335 | ||
7771 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 8336 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
@@ -7817,12 +8382,14 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = { | |||
7817 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), | 8382 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), |
7818 | SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), | 8383 | SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), |
7819 | SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), | 8384 | SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), |
8385 | SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), | ||
7820 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), | 8386 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), |
7821 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST), | 8387 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST), |
7822 | SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), | 8388 | SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), |
7823 | SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), | 8389 | SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), |
7824 | SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), | 8390 | SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), |
7825 | SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), | 8391 | SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), |
8392 | SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), | ||
7826 | SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), | 8393 | SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), |
7827 | {} | 8394 | {} |
7828 | }; | 8395 | }; |
@@ -7892,7 +8459,8 @@ static struct alc_config_preset alc861_presets[] = { | |||
7892 | }, | 8459 | }, |
7893 | [ALC861_TOSHIBA] = { | 8460 | [ALC861_TOSHIBA] = { |
7894 | .mixers = { alc861_toshiba_mixer }, | 8461 | .mixers = { alc861_toshiba_mixer }, |
7895 | .init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs }, | 8462 | .init_verbs = { alc861_base_init_verbs, |
8463 | alc861_toshiba_init_verbs }, | ||
7896 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), | 8464 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), |
7897 | .dac_nids = alc861_dac_nids, | 8465 | .dac_nids = alc861_dac_nids, |
7898 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 8466 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
@@ -7944,7 +8512,7 @@ static int patch_alc861(struct hda_codec *codec) | |||
7944 | if (spec == NULL) | 8512 | if (spec == NULL) |
7945 | return -ENOMEM; | 8513 | return -ENOMEM; |
7946 | 8514 | ||
7947 | codec->spec = spec; | 8515 | codec->spec = spec; |
7948 | 8516 | ||
7949 | board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, | 8517 | board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, |
7950 | alc861_models, | 8518 | alc861_models, |
@@ -7962,7 +8530,7 @@ static int patch_alc861(struct hda_codec *codec) | |||
7962 | if (err < 0) { | 8530 | if (err < 0) { |
7963 | alc_free(codec); | 8531 | alc_free(codec); |
7964 | return err; | 8532 | return err; |
7965 | } else if (! err) { | 8533 | } else if (!err) { |
7966 | printk(KERN_INFO | 8534 | printk(KERN_INFO |
7967 | "hda_codec: Cannot set up configuration " | 8535 | "hda_codec: Cannot set up configuration " |
7968 | "from BIOS. Using base mode...\n"); | 8536 | "from BIOS. Using base mode...\n"); |
@@ -8049,7 +8617,7 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
8049 | idx = ucontrol->value.enumerated.item[0]; | 8617 | idx = ucontrol->value.enumerated.item[0]; |
8050 | if (idx >= imux->num_items) | 8618 | if (idx >= imux->num_items) |
8051 | idx = imux->num_items - 1; | 8619 | idx = imux->num_items - 1; |
8052 | if (*cur_val == idx && ! codec->in_resume) | 8620 | if (*cur_val == idx && !codec->in_resume) |
8053 | return 0; | 8621 | return 0; |
8054 | for (i = 0; i < imux->num_items; i++) { | 8622 | for (i = 0; i < imux->num_items; i++) { |
8055 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | 8623 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; |
@@ -8193,6 +8761,27 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = { | |||
8193 | { } /* end */ | 8761 | { } /* end */ |
8194 | }; | 8762 | }; |
8195 | 8763 | ||
8764 | static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { | ||
8765 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
8766 | /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ | ||
8767 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
8768 | |||
8769 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
8770 | |||
8771 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
8772 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
8773 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
8774 | |||
8775 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
8776 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
8777 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
8778 | |||
8779 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
8780 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
8781 | |||
8782 | { } /* end */ | ||
8783 | }; | ||
8784 | |||
8196 | /* | 8785 | /* |
8197 | * generic initialization of ADC, input mixers and output mixers | 8786 | * generic initialization of ADC, input mixers and output mixers |
8198 | */ | 8787 | */ |
@@ -8214,10 +8803,10 @@ static struct hda_verb alc861vd_volume_init_verbs[] = { | |||
8214 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | 8803 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, |
8215 | 8804 | ||
8216 | /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ | 8805 | /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ |
8806 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8807 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8808 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
8217 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | 8809 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, |
8218 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, | ||
8219 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, | ||
8220 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(8)}, | ||
8221 | 8810 | ||
8222 | /* | 8811 | /* |
8223 | * Set up output mixers (0x02 - 0x05) | 8812 | * Set up output mixers (0x02 - 0x05) |
@@ -8318,6 +8907,68 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = { | |||
8318 | { } | 8907 | { } |
8319 | }; | 8908 | }; |
8320 | 8909 | ||
8910 | static struct hda_verb alc861vd_eapd_verbs[] = { | ||
8911 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
8912 | { } | ||
8913 | }; | ||
8914 | |||
8915 | static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { | ||
8916 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8917 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8918 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | ||
8919 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
8920 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
8921 | {} | ||
8922 | }; | ||
8923 | |||
8924 | /* toggle speaker-output according to the hp-jack state */ | ||
8925 | static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) | ||
8926 | { | ||
8927 | unsigned int present; | ||
8928 | unsigned char bits; | ||
8929 | |||
8930 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
8931 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8932 | bits = present ? 0x80 : 0; | ||
8933 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | ||
8934 | 0x80, bits); | ||
8935 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | ||
8936 | 0x80, bits); | ||
8937 | } | ||
8938 | |||
8939 | static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) | ||
8940 | { | ||
8941 | unsigned int present; | ||
8942 | unsigned char bits; | ||
8943 | |||
8944 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
8945 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8946 | bits = present ? 0x80 : 0; | ||
8947 | snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1, | ||
8948 | 0x80, bits); | ||
8949 | snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1, | ||
8950 | 0x80, bits); | ||
8951 | } | ||
8952 | |||
8953 | static void alc861vd_lenovo_automute(struct hda_codec *codec) | ||
8954 | { | ||
8955 | alc861vd_lenovo_hp_automute(codec); | ||
8956 | alc861vd_lenovo_mic_automute(codec); | ||
8957 | } | ||
8958 | |||
8959 | static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, | ||
8960 | unsigned int res) | ||
8961 | { | ||
8962 | switch (res >> 26) { | ||
8963 | case ALC880_HP_EVENT: | ||
8964 | alc861vd_lenovo_hp_automute(codec); | ||
8965 | break; | ||
8966 | case ALC880_MIC_EVENT: | ||
8967 | alc861vd_lenovo_mic_automute(codec); | ||
8968 | break; | ||
8969 | } | ||
8970 | } | ||
8971 | |||
8321 | /* pcm configuration: identiacal with ALC880 */ | 8972 | /* pcm configuration: identiacal with ALC880 */ |
8322 | #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback | 8973 | #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback |
8323 | #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture | 8974 | #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture |
@@ -8332,15 +8983,18 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { | |||
8332 | [ALC861VD_3ST] = "3stack", | 8983 | [ALC861VD_3ST] = "3stack", |
8333 | [ALC861VD_3ST_DIG] = "3stack-digout", | 8984 | [ALC861VD_3ST_DIG] = "3stack-digout", |
8334 | [ALC861VD_6ST_DIG] = "6stack-digout", | 8985 | [ALC861VD_6ST_DIG] = "6stack-digout", |
8986 | [ALC861VD_LENOVO] = "lenovo", | ||
8335 | [ALC861VD_AUTO] = "auto", | 8987 | [ALC861VD_AUTO] = "auto", |
8336 | }; | 8988 | }; |
8337 | 8989 | ||
8338 | static struct snd_pci_quirk alc861vd_cfg_tbl[] = { | 8990 | static struct snd_pci_quirk alc861vd_cfg_tbl[] = { |
8991 | SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), | ||
8339 | SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), | 8992 | SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), |
8340 | SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), | 8993 | SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), |
8341 | SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), | 8994 | SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), |
8342 | 8995 | ||
8343 | SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_3ST), | 8996 | SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), |
8997 | SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), | ||
8344 | {} | 8998 | {} |
8345 | }; | 8999 | }; |
8346 | 9000 | ||
@@ -8389,6 +9043,22 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
8389 | .channel_mode = alc861vd_6stack_modes, | 9043 | .channel_mode = alc861vd_6stack_modes, |
8390 | .input_mux = &alc861vd_capture_source, | 9044 | .input_mux = &alc861vd_capture_source, |
8391 | }, | 9045 | }, |
9046 | [ALC861VD_LENOVO] = { | ||
9047 | .mixers = { alc861vd_lenovo_mixer }, | ||
9048 | .init_verbs = { alc861vd_volume_init_verbs, | ||
9049 | alc861vd_3stack_init_verbs, | ||
9050 | alc861vd_eapd_verbs, | ||
9051 | alc861vd_lenovo_unsol_verbs }, | ||
9052 | .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), | ||
9053 | .dac_nids = alc660vd_dac_nids, | ||
9054 | .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), | ||
9055 | .adc_nids = alc861vd_adc_nids, | ||
9056 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
9057 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
9058 | .input_mux = &alc861vd_capture_source, | ||
9059 | .unsol_event = alc861vd_lenovo_unsol_event, | ||
9060 | .init_hook = alc861vd_lenovo_automute, | ||
9061 | }, | ||
8392 | }; | 9062 | }; |
8393 | 9063 | ||
8394 | /* | 9064 | /* |
@@ -8409,11 +9079,13 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec) | |||
8409 | struct alc_spec *spec = codec->spec; | 9079 | struct alc_spec *spec = codec->spec; |
8410 | int i; | 9080 | int i; |
8411 | 9081 | ||
9082 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
8412 | for (i = 0; i <= HDA_SIDE; i++) { | 9083 | for (i = 0; i <= HDA_SIDE; i++) { |
8413 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 9084 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
9085 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
8414 | if (nid) | 9086 | if (nid) |
8415 | alc861vd_auto_set_output_and_unmute(codec, nid, | 9087 | alc861vd_auto_set_output_and_unmute(codec, nid, |
8416 | PIN_OUT, i); | 9088 | pin_type, i); |
8417 | } | 9089 | } |
8418 | } | 9090 | } |
8419 | 9091 | ||
@@ -8466,7 +9138,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
8466 | int i, err; | 9138 | int i, err; |
8467 | 9139 | ||
8468 | for (i = 0; i < cfg->line_outs; i++) { | 9140 | for (i = 0; i < cfg->line_outs; i++) { |
8469 | if (! spec->multiout.dac_nids[i]) | 9141 | if (!spec->multiout.dac_nids[i]) |
8470 | continue; | 9142 | continue; |
8471 | nid_v = alc861vd_idx_to_mixer_vol( | 9143 | nid_v = alc861vd_idx_to_mixer_vol( |
8472 | alc880_dac_to_idx( | 9144 | alc880_dac_to_idx( |
@@ -8477,36 +9149,42 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
8477 | 9149 | ||
8478 | if (i == 2) { | 9150 | if (i == 2) { |
8479 | /* Center/LFE */ | 9151 | /* Center/LFE */ |
8480 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, | 9152 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
8481 | "Center Playback Volume", | 9153 | "Center Playback Volume", |
8482 | HDA_COMPOSE_AMP_VAL(nid_v, 1, | 9154 | HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, |
8483 | 0, HDA_OUTPUT))) < 0) | 9155 | HDA_OUTPUT)); |
9156 | if (err < 0) | ||
8484 | return err; | 9157 | return err; |
8485 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, | 9158 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
8486 | "LFE Playback Volume", | 9159 | "LFE Playback Volume", |
8487 | HDA_COMPOSE_AMP_VAL(nid_v, 2, | 9160 | HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, |
8488 | 0, HDA_OUTPUT))) < 0) | 9161 | HDA_OUTPUT)); |
9162 | if (err < 0) | ||
8489 | return err; | 9163 | return err; |
8490 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, | 9164 | err = add_control(spec, ALC_CTL_BIND_MUTE, |
8491 | "Center Playback Switch", | 9165 | "Center Playback Switch", |
8492 | HDA_COMPOSE_AMP_VAL(nid_s, 1, | 9166 | HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, |
8493 | 2, HDA_INPUT))) < 0) | 9167 | HDA_INPUT)); |
9168 | if (err < 0) | ||
8494 | return err; | 9169 | return err; |
8495 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, | 9170 | err = add_control(spec, ALC_CTL_BIND_MUTE, |
8496 | "LFE Playback Switch", | 9171 | "LFE Playback Switch", |
8497 | HDA_COMPOSE_AMP_VAL(nid_s, 2, | 9172 | HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, |
8498 | 2, HDA_INPUT))) < 0) | 9173 | HDA_INPUT)); |
9174 | if (err < 0) | ||
8499 | return err; | 9175 | return err; |
8500 | } else { | 9176 | } else { |
8501 | sprintf(name, "%s Playback Volume", chname[i]); | 9177 | sprintf(name, "%s Playback Volume", chname[i]); |
8502 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 9178 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, |
8503 | HDA_COMPOSE_AMP_VAL(nid_v, 3, | 9179 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, |
8504 | 0, HDA_OUTPUT))) < 0) | 9180 | HDA_OUTPUT)); |
9181 | if (err < 0) | ||
8505 | return err; | 9182 | return err; |
8506 | sprintf(name, "%s Playback Switch", chname[i]); | 9183 | sprintf(name, "%s Playback Switch", chname[i]); |
8507 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | 9184 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, |
8508 | HDA_COMPOSE_AMP_VAL(nid_v, 3, | 9185 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, |
8509 | 2, HDA_INPUT))) < 0) | 9186 | HDA_INPUT)); |
9187 | if (err < 0) | ||
8510 | return err; | 9188 | return err; |
8511 | } | 9189 | } |
8512 | } | 9190 | } |
@@ -8523,13 +9201,13 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec, | |||
8523 | int err; | 9201 | int err; |
8524 | char name[32]; | 9202 | char name[32]; |
8525 | 9203 | ||
8526 | if (! pin) | 9204 | if (!pin) |
8527 | return 0; | 9205 | return 0; |
8528 | 9206 | ||
8529 | if (alc880_is_fixed_pin(pin)) { | 9207 | if (alc880_is_fixed_pin(pin)) { |
8530 | nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | 9208 | nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); |
8531 | /* specify the DAC as the extra output */ | 9209 | /* specify the DAC as the extra output */ |
8532 | if (! spec->multiout.hp_nid) | 9210 | if (!spec->multiout.hp_nid) |
8533 | spec->multiout.hp_nid = nid_v; | 9211 | spec->multiout.hp_nid = nid_v; |
8534 | else | 9212 | else |
8535 | spec->multiout.extra_out_nid[0] = nid_v; | 9213 | spec->multiout.extra_out_nid[0] = nid_v; |
@@ -8540,22 +9218,22 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec, | |||
8540 | alc880_fixed_pin_idx(pin)); | 9218 | alc880_fixed_pin_idx(pin)); |
8541 | 9219 | ||
8542 | sprintf(name, "%s Playback Volume", pfx); | 9220 | sprintf(name, "%s Playback Volume", pfx); |
8543 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 9221 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, |
8544 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, | 9222 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); |
8545 | HDA_OUTPUT))) < 0) | 9223 | if (err < 0) |
8546 | return err; | 9224 | return err; |
8547 | sprintf(name, "%s Playback Switch", pfx); | 9225 | sprintf(name, "%s Playback Switch", pfx); |
8548 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | 9226 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, |
8549 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, | 9227 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); |
8550 | HDA_INPUT))) < 0) | 9228 | if (err < 0) |
8551 | return err; | 9229 | return err; |
8552 | } else if (alc880_is_multi_pin(pin)) { | 9230 | } else if (alc880_is_multi_pin(pin)) { |
8553 | /* set manual connection */ | 9231 | /* set manual connection */ |
8554 | /* we have only a switch on HP-out PIN */ | 9232 | /* we have only a switch on HP-out PIN */ |
8555 | sprintf(name, "%s Playback Switch", pfx); | 9233 | sprintf(name, "%s Playback Switch", pfx); |
8556 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | 9234 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, |
8557 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, | 9235 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); |
8558 | HDA_OUTPUT))) < 0) | 9236 | if (err < 0) |
8559 | return err; | 9237 | return err; |
8560 | } | 9238 | } |
8561 | return 0; | 9239 | return 0; |
@@ -8572,21 +9250,31 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
8572 | int err; | 9250 | int err; |
8573 | static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; | 9251 | static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; |
8574 | 9252 | ||
8575 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 9253 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
8576 | alc861vd_ignore)) < 0) | 9254 | alc861vd_ignore); |
9255 | if (err < 0) | ||
8577 | return err; | 9256 | return err; |
8578 | if (! spec->autocfg.line_outs) | 9257 | if (!spec->autocfg.line_outs) |
8579 | return 0; /* can't find valid BIOS pin config */ | 9258 | return 0; /* can't find valid BIOS pin config */ |
8580 | 9259 | ||
8581 | if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || | 9260 | err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); |
8582 | (err = alc861vd_auto_create_multi_out_ctls(spec, | 9261 | if (err < 0) |
8583 | &spec->autocfg)) < 0 || | 9262 | return err; |
8584 | (err = alc861vd_auto_create_extra_out(spec, | 9263 | err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); |
8585 | spec->autocfg.speaker_pins[0], "Speaker")) < 0 || | 9264 | if (err < 0) |
8586 | (err = alc861vd_auto_create_extra_out(spec, | 9265 | return err; |
8587 | spec->autocfg.hp_pins[0], "Headphone")) < 0 || | 9266 | err = alc861vd_auto_create_extra_out(spec, |
8588 | (err = alc880_auto_create_analog_input_ctls(spec, | 9267 | spec->autocfg.speaker_pins[0], |
8589 | &spec->autocfg)) < 0) | 9268 | "Speaker"); |
9269 | if (err < 0) | ||
9270 | return err; | ||
9271 | err = alc861vd_auto_create_extra_out(spec, | ||
9272 | spec->autocfg.hp_pins[0], | ||
9273 | "Headphone"); | ||
9274 | if (err < 0) | ||
9275 | return err; | ||
9276 | err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); | ||
9277 | if (err < 0) | ||
8590 | return err; | 9278 | return err; |
8591 | 9279 | ||
8592 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 9280 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
@@ -8641,7 +9329,7 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
8641 | if (err < 0) { | 9329 | if (err < 0) { |
8642 | alc_free(codec); | 9330 | alc_free(codec); |
8643 | return err; | 9331 | return err; |
8644 | } else if (! err) { | 9332 | } else if (!err) { |
8645 | printk(KERN_INFO | 9333 | printk(KERN_INFO |
8646 | "hda_codec: Cannot set up configuration " | 9334 | "hda_codec: Cannot set up configuration " |
8647 | "from BIOS. Using base mode...\n"); | 9335 | "from BIOS. Using base mode...\n"); |
@@ -8675,16 +9363,875 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
8675 | } | 9363 | } |
8676 | 9364 | ||
8677 | /* | 9365 | /* |
9366 | * ALC662 support | ||
9367 | * | ||
9368 | * ALC662 is almost identical with ALC880 but has cleaner and more flexible | ||
9369 | * configuration. Each pin widget can choose any input DACs and a mixer. | ||
9370 | * Each ADC is connected from a mixer of all inputs. This makes possible | ||
9371 | * 6-channel independent captures. | ||
9372 | * | ||
9373 | * In addition, an independent DAC for the multi-playback (not used in this | ||
9374 | * driver yet). | ||
9375 | */ | ||
9376 | #define ALC662_DIGOUT_NID 0x06 | ||
9377 | #define ALC662_DIGIN_NID 0x0a | ||
9378 | |||
9379 | static hda_nid_t alc662_dac_nids[4] = { | ||
9380 | /* front, rear, clfe, rear_surr */ | ||
9381 | 0x02, 0x03, 0x04 | ||
9382 | }; | ||
9383 | |||
9384 | static hda_nid_t alc662_adc_nids[1] = { | ||
9385 | /* ADC1-2 */ | ||
9386 | 0x09, | ||
9387 | }; | ||
9388 | /* input MUX */ | ||
9389 | /* FIXME: should be a matrix-type input source selection */ | ||
9390 | |||
9391 | static struct hda_input_mux alc662_capture_source = { | ||
9392 | .num_items = 4, | ||
9393 | .items = { | ||
9394 | { "Mic", 0x0 }, | ||
9395 | { "Front Mic", 0x1 }, | ||
9396 | { "Line", 0x2 }, | ||
9397 | { "CD", 0x4 }, | ||
9398 | }, | ||
9399 | }; | ||
9400 | |||
9401 | static struct hda_input_mux alc662_lenovo_101e_capture_source = { | ||
9402 | .num_items = 2, | ||
9403 | .items = { | ||
9404 | { "Mic", 0x1 }, | ||
9405 | { "Line", 0x2 }, | ||
9406 | }, | ||
9407 | }; | ||
9408 | #define alc662_mux_enum_info alc_mux_enum_info | ||
9409 | #define alc662_mux_enum_get alc_mux_enum_get | ||
9410 | |||
9411 | static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, | ||
9412 | struct snd_ctl_elem_value *ucontrol) | ||
9413 | { | ||
9414 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
9415 | struct alc_spec *spec = codec->spec; | ||
9416 | const struct hda_input_mux *imux = spec->input_mux; | ||
9417 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
9418 | static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; | ||
9419 | hda_nid_t nid = capture_mixers[adc_idx]; | ||
9420 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; | ||
9421 | unsigned int i, idx; | ||
9422 | |||
9423 | idx = ucontrol->value.enumerated.item[0]; | ||
9424 | if (idx >= imux->num_items) | ||
9425 | idx = imux->num_items - 1; | ||
9426 | if (*cur_val == idx && !codec->in_resume) | ||
9427 | return 0; | ||
9428 | for (i = 0; i < imux->num_items; i++) { | ||
9429 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | ||
9430 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
9431 | v | (imux->items[i].index << 8)); | ||
9432 | } | ||
9433 | *cur_val = idx; | ||
9434 | return 1; | ||
9435 | } | ||
9436 | /* | ||
9437 | * 2ch mode | ||
9438 | */ | ||
9439 | static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { | ||
9440 | { 2, NULL } | ||
9441 | }; | ||
9442 | |||
9443 | /* | ||
9444 | * 2ch mode | ||
9445 | */ | ||
9446 | static struct hda_verb alc662_3ST_ch2_init[] = { | ||
9447 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
9448 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
9449 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
9450 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
9451 | { } /* end */ | ||
9452 | }; | ||
9453 | |||
9454 | /* | ||
9455 | * 6ch mode | ||
9456 | */ | ||
9457 | static struct hda_verb alc662_3ST_ch6_init[] = { | ||
9458 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
9459 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
9460 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
9461 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
9462 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
9463 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
9464 | { } /* end */ | ||
9465 | }; | ||
9466 | |||
9467 | static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { | ||
9468 | { 2, alc662_3ST_ch2_init }, | ||
9469 | { 6, alc662_3ST_ch6_init }, | ||
9470 | }; | ||
9471 | |||
9472 | /* | ||
9473 | * 2ch mode | ||
9474 | */ | ||
9475 | static struct hda_verb alc662_sixstack_ch6_init[] = { | ||
9476 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
9477 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
9478 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
9479 | { } /* end */ | ||
9480 | }; | ||
9481 | |||
9482 | /* | ||
9483 | * 6ch mode | ||
9484 | */ | ||
9485 | static struct hda_verb alc662_sixstack_ch8_init[] = { | ||
9486 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
9487 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
9488 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
9489 | { } /* end */ | ||
9490 | }; | ||
9491 | |||
9492 | static struct hda_channel_mode alc662_5stack_modes[2] = { | ||
9493 | { 2, alc662_sixstack_ch6_init }, | ||
9494 | { 6, alc662_sixstack_ch8_init }, | ||
9495 | }; | ||
9496 | |||
9497 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | ||
9498 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | ||
9499 | */ | ||
9500 | |||
9501 | static struct snd_kcontrol_new alc662_base_mixer[] = { | ||
9502 | /* output mixer control */ | ||
9503 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
9504 | HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT), | ||
9505 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), | ||
9506 | HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
9507 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), | ||
9508 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), | ||
9509 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), | ||
9510 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), | ||
9511 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
9512 | |||
9513 | /*Input mixer control */ | ||
9514 | HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), | ||
9515 | HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), | ||
9516 | HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), | ||
9517 | HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), | ||
9518 | HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), | ||
9519 | HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), | ||
9520 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), | ||
9521 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), | ||
9522 | |||
9523 | /* Capture mixer control */ | ||
9524 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
9525 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
9526 | { | ||
9527 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9528 | .name = "Capture Source", | ||
9529 | .count = 1, | ||
9530 | .info = alc_mux_enum_info, | ||
9531 | .get = alc_mux_enum_get, | ||
9532 | .put = alc_mux_enum_put, | ||
9533 | }, | ||
9534 | { } /* end */ | ||
9535 | }; | ||
9536 | |||
9537 | static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { | ||
9538 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
9539 | HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), | ||
9540 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
9541 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
9542 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
9543 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
9544 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
9545 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
9546 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
9547 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
9548 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
9549 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
9550 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
9551 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
9552 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
9553 | { | ||
9554 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9555 | /* .name = "Capture Source", */ | ||
9556 | .name = "Input Source", | ||
9557 | .count = 1, | ||
9558 | .info = alc662_mux_enum_info, | ||
9559 | .get = alc662_mux_enum_get, | ||
9560 | .put = alc662_mux_enum_put, | ||
9561 | }, | ||
9562 | { } /* end */ | ||
9563 | }; | ||
9564 | |||
9565 | static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { | ||
9566 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
9567 | HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), | ||
9568 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
9569 | HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), | ||
9570 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), | ||
9571 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), | ||
9572 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), | ||
9573 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), | ||
9574 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
9575 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
9576 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
9577 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
9578 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
9579 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
9580 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
9581 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
9582 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
9583 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
9584 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
9585 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
9586 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
9587 | { | ||
9588 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9589 | /* .name = "Capture Source", */ | ||
9590 | .name = "Input Source", | ||
9591 | .count = 1, | ||
9592 | .info = alc662_mux_enum_info, | ||
9593 | .get = alc662_mux_enum_get, | ||
9594 | .put = alc662_mux_enum_put, | ||
9595 | }, | ||
9596 | { } /* end */ | ||
9597 | }; | ||
9598 | |||
9599 | static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { | ||
9600 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
9601 | HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), | ||
9602 | HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
9603 | HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT), | ||
9604 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
9605 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
9606 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
9607 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
9608 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
9609 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
9610 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
9611 | { | ||
9612 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9613 | /* .name = "Capture Source", */ | ||
9614 | .name = "Input Source", | ||
9615 | .count = 1, | ||
9616 | .info = alc662_mux_enum_info, | ||
9617 | .get = alc662_mux_enum_get, | ||
9618 | .put = alc662_mux_enum_put, | ||
9619 | }, | ||
9620 | { } /* end */ | ||
9621 | }; | ||
9622 | |||
9623 | static struct snd_kcontrol_new alc662_chmode_mixer[] = { | ||
9624 | { | ||
9625 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9626 | .name = "Channel Mode", | ||
9627 | .info = alc_ch_mode_info, | ||
9628 | .get = alc_ch_mode_get, | ||
9629 | .put = alc_ch_mode_put, | ||
9630 | }, | ||
9631 | { } /* end */ | ||
9632 | }; | ||
9633 | |||
9634 | static struct hda_verb alc662_init_verbs[] = { | ||
9635 | /* ADC: mute amp left and right */ | ||
9636 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
9637 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
9638 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | ||
9639 | |||
9640 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9641 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9642 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
9643 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
9644 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
9645 | |||
9646 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9647 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9648 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9649 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9650 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9651 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9652 | |||
9653 | /* Front Pin: output 0 (0x0c) */ | ||
9654 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
9655 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
9656 | |||
9657 | /* Rear Pin: output 1 (0x0d) */ | ||
9658 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
9659 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
9660 | |||
9661 | /* CLFE Pin: output 2 (0x0e) */ | ||
9662 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
9663 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
9664 | |||
9665 | /* Mic (rear) pin: input vref at 80% */ | ||
9666 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
9667 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
9668 | /* Front Mic pin: input vref at 80% */ | ||
9669 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
9670 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
9671 | /* Line In pin: input */ | ||
9672 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
9673 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
9674 | /* Line-2 In: Headphone output (output 0 - 0x0c) */ | ||
9675 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
9676 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
9677 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
9678 | /* CD pin widget for input */ | ||
9679 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
9680 | |||
9681 | /* FIXME: use matrix-type input source selection */ | ||
9682 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
9683 | /* Input mixer */ | ||
9684 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9685 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9686 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
9687 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
9688 | { } | ||
9689 | }; | ||
9690 | |||
9691 | static struct hda_verb alc662_sue_init_verbs[] = { | ||
9692 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, | ||
9693 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, | ||
9694 | {} | ||
9695 | }; | ||
9696 | |||
9697 | /* | ||
9698 | * generic initialization of ADC, input mixers and output mixers | ||
9699 | */ | ||
9700 | static struct hda_verb alc662_auto_init_verbs[] = { | ||
9701 | /* | ||
9702 | * Unmute ADC and set the default input to mic-in | ||
9703 | */ | ||
9704 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
9705 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9706 | |||
9707 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | ||
9708 | * mixer widget | ||
9709 | * Note: PASD motherboards uses the Line In 2 as the input for front | ||
9710 | * panel mic (mic 2) | ||
9711 | */ | ||
9712 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | ||
9713 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9714 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9715 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
9716 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
9717 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
9718 | |||
9719 | /* | ||
9720 | * Set up output mixers (0x0c - 0x0f) | ||
9721 | */ | ||
9722 | /* set vol=0 to output mixers */ | ||
9723 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
9724 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
9725 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
9726 | |||
9727 | /* set up input amps for analog loopback */ | ||
9728 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
9729 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9730 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9731 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9732 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9733 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9734 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9735 | |||
9736 | |||
9737 | /* FIXME: use matrix-type input source selection */ | ||
9738 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
9739 | /* Input mixer */ | ||
9740 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9741 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9742 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
9743 | /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/ | ||
9744 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
9745 | |||
9746 | { } | ||
9747 | }; | ||
9748 | |||
9749 | /* capture mixer elements */ | ||
9750 | static struct snd_kcontrol_new alc662_capture_mixer[] = { | ||
9751 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
9752 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
9753 | { | ||
9754 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9755 | /* The multiple "Capture Source" controls confuse alsamixer | ||
9756 | * So call somewhat different.. | ||
9757 | * FIXME: the controls appear in the "playback" view! | ||
9758 | */ | ||
9759 | /* .name = "Capture Source", */ | ||
9760 | .name = "Input Source", | ||
9761 | .count = 1, | ||
9762 | .info = alc882_mux_enum_info, | ||
9763 | .get = alc882_mux_enum_get, | ||
9764 | .put = alc882_mux_enum_put, | ||
9765 | }, | ||
9766 | { } /* end */ | ||
9767 | }; | ||
9768 | |||
9769 | static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | ||
9770 | { | ||
9771 | unsigned int present; | ||
9772 | unsigned char bits; | ||
9773 | |||
9774 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
9775 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
9776 | bits = present ? 0x80 : 0; | ||
9777 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | ||
9778 | 0x80, bits); | ||
9779 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | ||
9780 | 0x80, bits); | ||
9781 | } | ||
9782 | |||
9783 | static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) | ||
9784 | { | ||
9785 | unsigned int present; | ||
9786 | unsigned char bits; | ||
9787 | |||
9788 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
9789 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
9790 | bits = present ? 0x80 : 0; | ||
9791 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | ||
9792 | 0x80, bits); | ||
9793 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | ||
9794 | 0x80, bits); | ||
9795 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | ||
9796 | 0x80, bits); | ||
9797 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | ||
9798 | 0x80, bits); | ||
9799 | } | ||
9800 | |||
9801 | static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, | ||
9802 | unsigned int res) | ||
9803 | { | ||
9804 | if ((res >> 26) == ALC880_HP_EVENT) | ||
9805 | alc662_lenovo_101e_all_automute(codec); | ||
9806 | if ((res >> 26) == ALC880_FRONT_EVENT) | ||
9807 | alc662_lenovo_101e_ispeaker_automute(codec); | ||
9808 | } | ||
9809 | |||
9810 | |||
9811 | /* pcm configuration: identiacal with ALC880 */ | ||
9812 | #define alc662_pcm_analog_playback alc880_pcm_analog_playback | ||
9813 | #define alc662_pcm_analog_capture alc880_pcm_analog_capture | ||
9814 | #define alc662_pcm_digital_playback alc880_pcm_digital_playback | ||
9815 | #define alc662_pcm_digital_capture alc880_pcm_digital_capture | ||
9816 | |||
9817 | /* | ||
9818 | * configuration and preset | ||
9819 | */ | ||
9820 | static const char *alc662_models[ALC662_MODEL_LAST] = { | ||
9821 | [ALC662_3ST_2ch_DIG] = "3stack-dig", | ||
9822 | [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", | ||
9823 | [ALC662_3ST_6ch] = "3stack-6ch", | ||
9824 | [ALC662_5ST_DIG] = "6stack-dig", | ||
9825 | [ALC662_LENOVO_101E] = "lenovo-101e", | ||
9826 | [ALC662_AUTO] = "auto", | ||
9827 | }; | ||
9828 | |||
9829 | static struct snd_pci_quirk alc662_cfg_tbl[] = { | ||
9830 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), | ||
9831 | {} | ||
9832 | }; | ||
9833 | |||
9834 | static struct alc_config_preset alc662_presets[] = { | ||
9835 | [ALC662_3ST_2ch_DIG] = { | ||
9836 | .mixers = { alc662_3ST_2ch_mixer }, | ||
9837 | .init_verbs = { alc662_init_verbs }, | ||
9838 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
9839 | .dac_nids = alc662_dac_nids, | ||
9840 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
9841 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | ||
9842 | .adc_nids = alc662_adc_nids, | ||
9843 | .dig_in_nid = ALC662_DIGIN_NID, | ||
9844 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
9845 | .channel_mode = alc662_3ST_2ch_modes, | ||
9846 | .input_mux = &alc662_capture_source, | ||
9847 | }, | ||
9848 | [ALC662_3ST_6ch_DIG] = { | ||
9849 | .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, | ||
9850 | .init_verbs = { alc662_init_verbs }, | ||
9851 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
9852 | .dac_nids = alc662_dac_nids, | ||
9853 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
9854 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | ||
9855 | .adc_nids = alc662_adc_nids, | ||
9856 | .dig_in_nid = ALC662_DIGIN_NID, | ||
9857 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | ||
9858 | .channel_mode = alc662_3ST_6ch_modes, | ||
9859 | .need_dac_fix = 1, | ||
9860 | .input_mux = &alc662_capture_source, | ||
9861 | }, | ||
9862 | [ALC662_3ST_6ch] = { | ||
9863 | .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, | ||
9864 | .init_verbs = { alc662_init_verbs }, | ||
9865 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
9866 | .dac_nids = alc662_dac_nids, | ||
9867 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | ||
9868 | .adc_nids = alc662_adc_nids, | ||
9869 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | ||
9870 | .channel_mode = alc662_3ST_6ch_modes, | ||
9871 | .need_dac_fix = 1, | ||
9872 | .input_mux = &alc662_capture_source, | ||
9873 | }, | ||
9874 | [ALC662_5ST_DIG] = { | ||
9875 | .mixers = { alc662_base_mixer, alc662_chmode_mixer }, | ||
9876 | .init_verbs = { alc662_init_verbs }, | ||
9877 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
9878 | .dac_nids = alc662_dac_nids, | ||
9879 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
9880 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | ||
9881 | .adc_nids = alc662_adc_nids, | ||
9882 | .dig_in_nid = ALC662_DIGIN_NID, | ||
9883 | .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), | ||
9884 | .channel_mode = alc662_5stack_modes, | ||
9885 | .input_mux = &alc662_capture_source, | ||
9886 | }, | ||
9887 | [ALC662_LENOVO_101E] = { | ||
9888 | .mixers = { alc662_lenovo_101e_mixer }, | ||
9889 | .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, | ||
9890 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
9891 | .dac_nids = alc662_dac_nids, | ||
9892 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | ||
9893 | .adc_nids = alc662_adc_nids, | ||
9894 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
9895 | .channel_mode = alc662_3ST_2ch_modes, | ||
9896 | .input_mux = &alc662_lenovo_101e_capture_source, | ||
9897 | .unsol_event = alc662_lenovo_101e_unsol_event, | ||
9898 | .init_hook = alc662_lenovo_101e_all_automute, | ||
9899 | }, | ||
9900 | |||
9901 | }; | ||
9902 | |||
9903 | |||
9904 | /* | ||
9905 | * BIOS auto configuration | ||
9906 | */ | ||
9907 | |||
9908 | /* add playback controls from the parsed DAC table */ | ||
9909 | static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, | ||
9910 | const struct auto_pin_cfg *cfg) | ||
9911 | { | ||
9912 | char name[32]; | ||
9913 | static const char *chname[4] = { | ||
9914 | "Front", "Surround", NULL /*CLFE*/, "Side" | ||
9915 | }; | ||
9916 | hda_nid_t nid; | ||
9917 | int i, err; | ||
9918 | |||
9919 | for (i = 0; i < cfg->line_outs; i++) { | ||
9920 | if (!spec->multiout.dac_nids[i]) | ||
9921 | continue; | ||
9922 | nid = alc880_idx_to_dac(i); | ||
9923 | if (i == 2) { | ||
9924 | /* Center/LFE */ | ||
9925 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | ||
9926 | "Center Playback Volume", | ||
9927 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, | ||
9928 | HDA_OUTPUT)); | ||
9929 | if (err < 0) | ||
9930 | return err; | ||
9931 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | ||
9932 | "LFE Playback Volume", | ||
9933 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
9934 | HDA_OUTPUT)); | ||
9935 | if (err < 0) | ||
9936 | return err; | ||
9937 | err = add_control(spec, ALC_CTL_BIND_MUTE, | ||
9938 | "Center Playback Switch", | ||
9939 | HDA_COMPOSE_AMP_VAL(nid, 1, 2, | ||
9940 | HDA_INPUT)); | ||
9941 | if (err < 0) | ||
9942 | return err; | ||
9943 | err = add_control(spec, ALC_CTL_BIND_MUTE, | ||
9944 | "LFE Playback Switch", | ||
9945 | HDA_COMPOSE_AMP_VAL(nid, 2, 2, | ||
9946 | HDA_INPUT)); | ||
9947 | if (err < 0) | ||
9948 | return err; | ||
9949 | } else { | ||
9950 | sprintf(name, "%s Playback Volume", chname[i]); | ||
9951 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
9952 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | ||
9953 | HDA_OUTPUT)); | ||
9954 | if (err < 0) | ||
9955 | return err; | ||
9956 | sprintf(name, "%s Playback Switch", chname[i]); | ||
9957 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
9958 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, | ||
9959 | HDA_INPUT)); | ||
9960 | if (err < 0) | ||
9961 | return err; | ||
9962 | } | ||
9963 | } | ||
9964 | return 0; | ||
9965 | } | ||
9966 | |||
9967 | /* add playback controls for speaker and HP outputs */ | ||
9968 | static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | ||
9969 | const char *pfx) | ||
9970 | { | ||
9971 | hda_nid_t nid; | ||
9972 | int err; | ||
9973 | char name[32]; | ||
9974 | |||
9975 | if (!pin) | ||
9976 | return 0; | ||
9977 | |||
9978 | if (alc880_is_fixed_pin(pin)) { | ||
9979 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | ||
9980 | /* printk("DAC nid=%x\n",nid); */ | ||
9981 | /* specify the DAC as the extra output */ | ||
9982 | if (!spec->multiout.hp_nid) | ||
9983 | spec->multiout.hp_nid = nid; | ||
9984 | else | ||
9985 | spec->multiout.extra_out_nid[0] = nid; | ||
9986 | /* control HP volume/switch on the output mixer amp */ | ||
9987 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | ||
9988 | sprintf(name, "%s Playback Volume", pfx); | ||
9989 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
9990 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | ||
9991 | if (err < 0) | ||
9992 | return err; | ||
9993 | sprintf(name, "%s Playback Switch", pfx); | ||
9994 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
9995 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); | ||
9996 | if (err < 0) | ||
9997 | return err; | ||
9998 | } else if (alc880_is_multi_pin(pin)) { | ||
9999 | /* set manual connection */ | ||
10000 | /* we have only a switch on HP-out PIN */ | ||
10001 | sprintf(name, "%s Playback Switch", pfx); | ||
10002 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
10003 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); | ||
10004 | if (err < 0) | ||
10005 | return err; | ||
10006 | } | ||
10007 | return 0; | ||
10008 | } | ||
10009 | |||
10010 | /* create playback/capture controls for input pins */ | ||
10011 | static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec, | ||
10012 | const struct auto_pin_cfg *cfg) | ||
10013 | { | ||
10014 | struct hda_input_mux *imux = &spec->private_imux; | ||
10015 | int i, err, idx; | ||
10016 | |||
10017 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
10018 | if (alc880_is_input_pin(cfg->input_pins[i])) { | ||
10019 | idx = alc880_input_pin_idx(cfg->input_pins[i]); | ||
10020 | err = new_analog_input(spec, cfg->input_pins[i], | ||
10021 | auto_pin_cfg_labels[i], | ||
10022 | idx, 0x0b); | ||
10023 | if (err < 0) | ||
10024 | return err; | ||
10025 | imux->items[imux->num_items].label = | ||
10026 | auto_pin_cfg_labels[i]; | ||
10027 | imux->items[imux->num_items].index = | ||
10028 | alc880_input_pin_idx(cfg->input_pins[i]); | ||
10029 | imux->num_items++; | ||
10030 | } | ||
10031 | } | ||
10032 | return 0; | ||
10033 | } | ||
10034 | |||
10035 | static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, | ||
10036 | hda_nid_t nid, int pin_type, | ||
10037 | int dac_idx) | ||
10038 | { | ||
10039 | /* set as output */ | ||
10040 | snd_hda_codec_write(codec, nid, 0, | ||
10041 | AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | ||
10042 | snd_hda_codec_write(codec, nid, 0, | ||
10043 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | ||
10044 | /* need the manual connection? */ | ||
10045 | if (alc880_is_multi_pin(nid)) { | ||
10046 | struct alc_spec *spec = codec->spec; | ||
10047 | int idx = alc880_multi_pin_idx(nid); | ||
10048 | snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, | ||
10049 | AC_VERB_SET_CONNECT_SEL, | ||
10050 | alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); | ||
10051 | } | ||
10052 | } | ||
10053 | |||
10054 | static void alc662_auto_init_multi_out(struct hda_codec *codec) | ||
10055 | { | ||
10056 | struct alc_spec *spec = codec->spec; | ||
10057 | int i; | ||
10058 | |||
10059 | for (i = 0; i <= HDA_SIDE; i++) { | ||
10060 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
10061 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
10062 | if (nid) | ||
10063 | alc662_auto_set_output_and_unmute(codec, nid, pin_type, | ||
10064 | i); | ||
10065 | } | ||
10066 | } | ||
10067 | |||
10068 | static void alc662_auto_init_hp_out(struct hda_codec *codec) | ||
10069 | { | ||
10070 | struct alc_spec *spec = codec->spec; | ||
10071 | hda_nid_t pin; | ||
10072 | |||
10073 | pin = spec->autocfg.hp_pins[0]; | ||
10074 | if (pin) /* connect to front */ | ||
10075 | /* use dac 0 */ | ||
10076 | alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); | ||
10077 | } | ||
10078 | |||
10079 | #define alc662_is_input_pin(nid) alc880_is_input_pin(nid) | ||
10080 | #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID | ||
10081 | |||
10082 | static void alc662_auto_init_analog_input(struct hda_codec *codec) | ||
10083 | { | ||
10084 | struct alc_spec *spec = codec->spec; | ||
10085 | int i; | ||
10086 | |||
10087 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
10088 | hda_nid_t nid = spec->autocfg.input_pins[i]; | ||
10089 | if (alc662_is_input_pin(nid)) { | ||
10090 | snd_hda_codec_write(codec, nid, 0, | ||
10091 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
10092 | (i <= AUTO_PIN_FRONT_MIC ? | ||
10093 | PIN_VREF80 : PIN_IN)); | ||
10094 | if (nid != ALC662_PIN_CD_NID) | ||
10095 | snd_hda_codec_write(codec, nid, 0, | ||
10096 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
10097 | AMP_OUT_MUTE); | ||
10098 | } | ||
10099 | } | ||
10100 | } | ||
10101 | |||
10102 | static int alc662_parse_auto_config(struct hda_codec *codec) | ||
10103 | { | ||
10104 | struct alc_spec *spec = codec->spec; | ||
10105 | int err; | ||
10106 | static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; | ||
10107 | |||
10108 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | ||
10109 | alc662_ignore); | ||
10110 | if (err < 0) | ||
10111 | return err; | ||
10112 | if (!spec->autocfg.line_outs) | ||
10113 | return 0; /* can't find valid BIOS pin config */ | ||
10114 | |||
10115 | err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); | ||
10116 | if (err < 0) | ||
10117 | return err; | ||
10118 | err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); | ||
10119 | if (err < 0) | ||
10120 | return err; | ||
10121 | err = alc662_auto_create_extra_out(spec, | ||
10122 | spec->autocfg.speaker_pins[0], | ||
10123 | "Speaker"); | ||
10124 | if (err < 0) | ||
10125 | return err; | ||
10126 | err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], | ||
10127 | "Headphone"); | ||
10128 | if (err < 0) | ||
10129 | return err; | ||
10130 | err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg); | ||
10131 | if (err < 0) | ||
10132 | return err; | ||
10133 | |||
10134 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | ||
10135 | |||
10136 | if (spec->autocfg.dig_out_pin) | ||
10137 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; | ||
10138 | |||
10139 | if (spec->kctl_alloc) | ||
10140 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | ||
10141 | |||
10142 | spec->num_mux_defs = 1; | ||
10143 | spec->input_mux = &spec->private_imux; | ||
10144 | |||
10145 | if (err < 0) | ||
10146 | return err; | ||
10147 | else if (err > 0) | ||
10148 | /* hack - override the init verbs */ | ||
10149 | spec->init_verbs[0] = alc662_auto_init_verbs; | ||
10150 | spec->mixers[spec->num_mixers] = alc662_capture_mixer; | ||
10151 | spec->num_mixers++; | ||
10152 | return err; | ||
10153 | } | ||
10154 | |||
10155 | /* additional initialization for auto-configuration model */ | ||
10156 | static void alc662_auto_init(struct hda_codec *codec) | ||
10157 | { | ||
10158 | alc662_auto_init_multi_out(codec); | ||
10159 | alc662_auto_init_hp_out(codec); | ||
10160 | alc662_auto_init_analog_input(codec); | ||
10161 | } | ||
10162 | |||
10163 | static int patch_alc662(struct hda_codec *codec) | ||
10164 | { | ||
10165 | struct alc_spec *spec; | ||
10166 | int err, board_config; | ||
10167 | |||
10168 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
10169 | if (!spec) | ||
10170 | return -ENOMEM; | ||
10171 | |||
10172 | codec->spec = spec; | ||
10173 | |||
10174 | board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, | ||
10175 | alc662_models, | ||
10176 | alc662_cfg_tbl); | ||
10177 | if (board_config < 0) { | ||
10178 | printk(KERN_INFO "hda_codec: Unknown model for ALC662, " | ||
10179 | "trying auto-probe from BIOS...\n"); | ||
10180 | board_config = ALC662_AUTO; | ||
10181 | } | ||
10182 | |||
10183 | if (board_config == ALC662_AUTO) { | ||
10184 | /* automatic parse from the BIOS config */ | ||
10185 | err = alc662_parse_auto_config(codec); | ||
10186 | if (err < 0) { | ||
10187 | alc_free(codec); | ||
10188 | return err; | ||
10189 | } else if (err) { | ||
10190 | printk(KERN_INFO | ||
10191 | "hda_codec: Cannot set up configuration " | ||
10192 | "from BIOS. Using base mode...\n"); | ||
10193 | board_config = ALC662_3ST_2ch_DIG; | ||
10194 | } | ||
10195 | } | ||
10196 | |||
10197 | if (board_config != ALC662_AUTO) | ||
10198 | setup_preset(spec, &alc662_presets[board_config]); | ||
10199 | |||
10200 | spec->stream_name_analog = "ALC662 Analog"; | ||
10201 | spec->stream_analog_playback = &alc662_pcm_analog_playback; | ||
10202 | spec->stream_analog_capture = &alc662_pcm_analog_capture; | ||
10203 | |||
10204 | spec->stream_name_digital = "ALC662 Digital"; | ||
10205 | spec->stream_digital_playback = &alc662_pcm_digital_playback; | ||
10206 | spec->stream_digital_capture = &alc662_pcm_digital_capture; | ||
10207 | |||
10208 | if (!spec->adc_nids && spec->input_mux) { | ||
10209 | spec->adc_nids = alc662_adc_nids; | ||
10210 | spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); | ||
10211 | } | ||
10212 | |||
10213 | codec->patch_ops = alc_patch_ops; | ||
10214 | if (board_config == ALC662_AUTO) | ||
10215 | spec->init_hook = alc662_auto_init; | ||
10216 | |||
10217 | return 0; | ||
10218 | } | ||
10219 | |||
10220 | /* | ||
8678 | * patch entries | 10221 | * patch entries |
8679 | */ | 10222 | */ |
8680 | struct hda_codec_preset snd_hda_preset_realtek[] = { | 10223 | struct hda_codec_preset snd_hda_preset_realtek[] = { |
8681 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, | 10224 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, |
8682 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, | 10225 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, |
8683 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | 10226 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
8684 | .patch = patch_alc861 }, | 10227 | .patch = patch_alc861 }, |
8685 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, | 10228 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, |
8686 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, | 10229 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, |
8687 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, | 10230 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, |
10231 | { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", | ||
10232 | .patch = patch_alc883 }, | ||
10233 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", | ||
10234 | .patch = patch_alc662 }, | ||
8688 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 10235 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
8689 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, | 10236 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
8690 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, | 10237 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c94291bc5367..93ae9c250767 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -62,6 +62,7 @@ enum { | |||
62 | STAC_MACBOOK, | 62 | STAC_MACBOOK, |
63 | STAC_MACBOOK_PRO_V1, | 63 | STAC_MACBOOK_PRO_V1, |
64 | STAC_MACBOOK_PRO_V2, | 64 | STAC_MACBOOK_PRO_V2, |
65 | STAC_IMAC_INTEL, | ||
65 | STAC_922X_MODELS | 66 | STAC_922X_MODELS |
66 | }; | 67 | }; |
67 | 68 | ||
@@ -175,8 +176,8 @@ static hda_nid_t stac9205_mux_nids[2] = { | |||
175 | 0x19, 0x1a | 176 | 0x19, 0x1a |
176 | }; | 177 | }; |
177 | 178 | ||
178 | static hda_nid_t stac9205_dmic_nids[3] = { | 179 | static hda_nid_t stac9205_dmic_nids[2] = { |
179 | 0x17, 0x18, 0 | 180 | 0x17, 0x18, |
180 | }; | 181 | }; |
181 | 182 | ||
182 | static hda_nid_t stac9200_pin_nids[8] = { | 183 | static hda_nid_t stac9200_pin_nids[8] = { |
@@ -524,12 +525,6 @@ static unsigned int d945gtp5_pin_configs[10] = { | |||
524 | 0x02a19320, 0x40000100, | 525 | 0x02a19320, 0x40000100, |
525 | }; | 526 | }; |
526 | 527 | ||
527 | static unsigned int macbook_pin_configs[10] = { | ||
528 | 0x0321e230, 0x03a1e020, 0x400000fd, 0x9017e110, | ||
529 | 0x400000fe, 0x0381e021, 0x1345e240, 0x13c5e22e, | ||
530 | 0x400000fc, 0x400000fb, | ||
531 | }; | ||
532 | |||
533 | static unsigned int macbook_pro_v1_pin_configs[10] = { | 528 | static unsigned int macbook_pro_v1_pin_configs[10] = { |
534 | 0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010, | 529 | 0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010, |
535 | 0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e, | 530 | 0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e, |
@@ -542,14 +537,21 @@ static unsigned int macbook_pro_v2_pin_configs[10] = { | |||
542 | 0x400000fc, 0x400000fb, | 537 | 0x400000fc, 0x400000fb, |
543 | }; | 538 | }; |
544 | 539 | ||
540 | static unsigned int imac_intel_pin_configs[10] = { | ||
541 | 0x0121e230, 0x90a70120, 0x9017e110, 0x400000fe, | ||
542 | 0x400000fd, 0x0181e021, 0x1145e040, 0x400000fa, | ||
543 | 0x400000fc, 0x400000fb, | ||
544 | }; | ||
545 | |||
545 | static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | 546 | static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { |
546 | [STAC_D945_REF] = ref922x_pin_configs, | 547 | [STAC_D945_REF] = ref922x_pin_configs, |
547 | [STAC_D945GTP3] = d945gtp3_pin_configs, | 548 | [STAC_D945GTP3] = d945gtp3_pin_configs, |
548 | [STAC_D945GTP5] = d945gtp5_pin_configs, | 549 | [STAC_D945GTP5] = d945gtp5_pin_configs, |
549 | [STAC_MACMINI] = d945gtp5_pin_configs, | 550 | [STAC_MACMINI] = macbook_pro_v1_pin_configs, |
550 | [STAC_MACBOOK] = macbook_pin_configs, | 551 | [STAC_MACBOOK] = macbook_pro_v1_pin_configs, |
551 | [STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs, | 552 | [STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs, |
552 | [STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs, | 553 | [STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs, |
554 | [STAC_IMAC_INTEL] = imac_intel_pin_configs, | ||
553 | }; | 555 | }; |
554 | 556 | ||
555 | static const char *stac922x_models[STAC_922X_MODELS] = { | 557 | static const char *stac922x_models[STAC_922X_MODELS] = { |
@@ -560,6 +562,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = { | |||
560 | [STAC_MACBOOK] = "macbook", | 562 | [STAC_MACBOOK] = "macbook", |
561 | [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", | 563 | [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", |
562 | [STAC_MACBOOK_PRO_V2] = "macbook-pro", | 564 | [STAC_MACBOOK_PRO_V2] = "macbook-pro", |
565 | [STAC_IMAC_INTEL] = "imac-intel", | ||
563 | }; | 566 | }; |
564 | 567 | ||
565 | static struct snd_pci_quirk stac922x_cfg_tbl[] = { | 568 | static struct snd_pci_quirk stac922x_cfg_tbl[] = { |
@@ -820,6 +823,17 @@ static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
820 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 823 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
821 | } | 824 | } |
822 | 825 | ||
826 | static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
827 | struct hda_codec *codec, | ||
828 | unsigned int stream_tag, | ||
829 | unsigned int format, | ||
830 | struct snd_pcm_substream *substream) | ||
831 | { | ||
832 | struct sigmatel_spec *spec = codec->spec; | ||
833 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
834 | stream_tag, format, substream); | ||
835 | } | ||
836 | |||
823 | 837 | ||
824 | /* | 838 | /* |
825 | * Analog capture callbacks | 839 | * Analog capture callbacks |
@@ -854,7 +868,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { | |||
854 | /* NID is set in stac92xx_build_pcms */ | 868 | /* NID is set in stac92xx_build_pcms */ |
855 | .ops = { | 869 | .ops = { |
856 | .open = stac92xx_dig_playback_pcm_open, | 870 | .open = stac92xx_dig_playback_pcm_open, |
857 | .close = stac92xx_dig_playback_pcm_close | 871 | .close = stac92xx_dig_playback_pcm_close, |
872 | .prepare = stac92xx_dig_playback_pcm_prepare | ||
858 | }, | 873 | }, |
859 | }; | 874 | }; |
860 | 875 | ||
@@ -1055,11 +1070,23 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char | |||
1055 | static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) | 1070 | static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) |
1056 | { | 1071 | { |
1057 | struct sigmatel_spec *spec = codec->spec; | 1072 | struct sigmatel_spec *spec = codec->spec; |
1073 | unsigned int wcaps, wtype; | ||
1074 | int i, num_dacs = 0; | ||
1075 | |||
1076 | /* use the wcaps cache to count all DACs available for line-outs */ | ||
1077 | for (i = 0; i < codec->num_nodes; i++) { | ||
1078 | wcaps = codec->wcaps[i]; | ||
1079 | wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
1080 | if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) | ||
1081 | num_dacs++; | ||
1082 | } | ||
1058 | 1083 | ||
1084 | snd_printdd("%s: total dac count=%d\n", __func__, num_dacs); | ||
1085 | |||
1059 | switch (cfg->line_outs) { | 1086 | switch (cfg->line_outs) { |
1060 | case 3: | 1087 | case 3: |
1061 | /* add line-in as side */ | 1088 | /* add line-in as side */ |
1062 | if (cfg->input_pins[AUTO_PIN_LINE]) { | 1089 | if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { |
1063 | cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE]; | 1090 | cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE]; |
1064 | spec->line_switch = 1; | 1091 | spec->line_switch = 1; |
1065 | cfg->line_outs++; | 1092 | cfg->line_outs++; |
@@ -1067,12 +1094,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf | |||
1067 | break; | 1094 | break; |
1068 | case 2: | 1095 | case 2: |
1069 | /* add line-in as clfe and mic as side */ | 1096 | /* add line-in as clfe and mic as side */ |
1070 | if (cfg->input_pins[AUTO_PIN_LINE]) { | 1097 | if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { |
1071 | cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE]; | 1098 | cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE]; |
1072 | spec->line_switch = 1; | 1099 | spec->line_switch = 1; |
1073 | cfg->line_outs++; | 1100 | cfg->line_outs++; |
1074 | } | 1101 | } |
1075 | if (cfg->input_pins[AUTO_PIN_MIC]) { | 1102 | if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { |
1076 | cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC]; | 1103 | cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC]; |
1077 | spec->mic_switch = 1; | 1104 | spec->mic_switch = 1; |
1078 | cfg->line_outs++; | 1105 | cfg->line_outs++; |
@@ -1080,12 +1107,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf | |||
1080 | break; | 1107 | break; |
1081 | case 1: | 1108 | case 1: |
1082 | /* add line-in as surr and mic as clfe */ | 1109 | /* add line-in as surr and mic as clfe */ |
1083 | if (cfg->input_pins[AUTO_PIN_LINE]) { | 1110 | if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) { |
1084 | cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE]; | 1111 | cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE]; |
1085 | spec->line_switch = 1; | 1112 | spec->line_switch = 1; |
1086 | cfg->line_outs++; | 1113 | cfg->line_outs++; |
1087 | } | 1114 | } |
1088 | if (cfg->input_pins[AUTO_PIN_MIC]) { | 1115 | if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) { |
1089 | cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC]; | 1116 | cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC]; |
1090 | spec->mic_switch = 1; | 1117 | spec->mic_switch = 1; |
1091 | cfg->line_outs++; | 1118 | cfg->line_outs++; |
@@ -1096,33 +1123,76 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf | |||
1096 | return 0; | 1123 | return 0; |
1097 | } | 1124 | } |
1098 | 1125 | ||
1126 | |||
1127 | static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | ||
1128 | { | ||
1129 | int i; | ||
1130 | |||
1131 | for (i = 0; i < spec->multiout.num_dacs; i++) { | ||
1132 | if (spec->multiout.dac_nids[i] == nid) | ||
1133 | return 1; | ||
1134 | } | ||
1135 | |||
1136 | return 0; | ||
1137 | } | ||
1138 | |||
1099 | /* | 1139 | /* |
1100 | * XXX The line_out pin widget connection list may not be set to the | 1140 | * Fill in the dac_nids table from the parsed pin configuration |
1101 | * desired DAC nid. This is the case on 927x where ports A and B can | 1141 | * This function only works when every pin in line_out_pins[] |
1102 | * be routed to several DACs. | 1142 | * contains atleast one DAC in its connection list. Some 92xx |
1103 | * | 1143 | * codecs are not connected directly to a DAC, such as the 9200 |
1104 | * This requires an analysis of the line-out/hp pin configuration | 1144 | * and 9202/925x. For those, dac_nids[] must be hard-coded. |
1105 | * to provide a best fit for pin/DAC configurations that are routable. | ||
1106 | * For now, 927x DAC4 is not supported and 927x DAC1 output to ports | ||
1107 | * A and B is not supported. | ||
1108 | */ | 1145 | */ |
1109 | /* fill in the dac_nids table from the parsed pin configuration */ | ||
1110 | static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, | 1146 | static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, |
1111 | const struct auto_pin_cfg *cfg) | 1147 | const struct auto_pin_cfg *cfg) |
1112 | { | 1148 | { |
1113 | struct sigmatel_spec *spec = codec->spec; | 1149 | struct sigmatel_spec *spec = codec->spec; |
1114 | hda_nid_t nid; | 1150 | int i, j, conn_len = 0; |
1115 | int i; | 1151 | hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; |
1116 | 1152 | unsigned int wcaps, wtype; | |
1117 | /* check the pins hardwired to audio widget */ | 1153 | |
1118 | for (i = 0; i < cfg->line_outs; i++) { | 1154 | for (i = 0; i < cfg->line_outs; i++) { |
1119 | nid = cfg->line_out_pins[i]; | 1155 | nid = cfg->line_out_pins[i]; |
1120 | spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0, | 1156 | conn_len = snd_hda_get_connections(codec, nid, conn, |
1121 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | 1157 | HDA_MAX_CONNECTIONS); |
1122 | } | 1158 | for (j = 0; j < conn_len; j++) { |
1159 | wcaps = snd_hda_param_read(codec, conn[j], | ||
1160 | AC_PAR_AUDIO_WIDGET_CAP); | ||
1161 | wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
1162 | |||
1163 | if (wtype != AC_WID_AUD_OUT || | ||
1164 | (wcaps & AC_WCAP_DIGITAL)) | ||
1165 | continue; | ||
1166 | /* conn[j] is a DAC routed to this line-out */ | ||
1167 | if (!is_in_dac_nids(spec, conn[j])) | ||
1168 | break; | ||
1169 | } | ||
1170 | |||
1171 | if (j == conn_len) { | ||
1172 | /* error out, no available DAC found */ | ||
1173 | snd_printk(KERN_ERR | ||
1174 | "%s: No available DAC for pin 0x%x\n", | ||
1175 | __func__, nid); | ||
1176 | return -ENODEV; | ||
1177 | } | ||
1123 | 1178 | ||
1124 | spec->multiout.num_dacs = cfg->line_outs; | 1179 | spec->multiout.dac_nids[i] = conn[j]; |
1180 | spec->multiout.num_dacs++; | ||
1181 | if (conn_len > 1) { | ||
1182 | /* select this DAC in the pin's input mux */ | ||
1183 | snd_hda_codec_write(codec, nid, 0, | ||
1184 | AC_VERB_SET_CONNECT_SEL, j); | ||
1185 | |||
1186 | } | ||
1187 | } | ||
1125 | 1188 | ||
1189 | snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | ||
1190 | spec->multiout.num_dacs, | ||
1191 | spec->multiout.dac_nids[0], | ||
1192 | spec->multiout.dac_nids[1], | ||
1193 | spec->multiout.dac_nids[2], | ||
1194 | spec->multiout.dac_nids[3], | ||
1195 | spec->multiout.dac_nids[4]); | ||
1126 | return 0; | 1196 | return 0; |
1127 | } | 1197 | } |
1128 | 1198 | ||
@@ -1189,12 +1259,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, | |||
1189 | 1259 | ||
1190 | static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | 1260 | static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) |
1191 | { | 1261 | { |
1192 | int i; | 1262 | if (is_in_dac_nids(spec, nid)) |
1193 | 1263 | return 1; | |
1194 | for (i = 0; i < spec->multiout.num_dacs; i++) { | ||
1195 | if (spec->multiout.dac_nids[i] == nid) | ||
1196 | return 1; | ||
1197 | } | ||
1198 | if (spec->multiout.hp_nid == nid) | 1264 | if (spec->multiout.hp_nid == nid) |
1199 | return 1; | 1265 | return 1; |
1200 | return 0; | 1266 | return 0; |
@@ -1236,12 +1302,10 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, | |||
1236 | add_spec_dacs(spec, nid); | 1302 | add_spec_dacs(spec, nid); |
1237 | } | 1303 | } |
1238 | for (i = 0; i < cfg->speaker_outs; i++) { | 1304 | for (i = 0; i < cfg->speaker_outs; i++) { |
1239 | nid = snd_hda_codec_read(codec, cfg->speaker_pins[0], 0, | 1305 | nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0, |
1240 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | 1306 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; |
1241 | if (check_in_dac_nids(spec, nid)) | 1307 | if (check_in_dac_nids(spec, nid)) |
1242 | nid = 0; | 1308 | nid = 0; |
1243 | if (check_in_dac_nids(spec, nid)) | ||
1244 | nid = 0; | ||
1245 | if (! nid) | 1309 | if (! nid) |
1246 | continue; | 1310 | continue; |
1247 | add_spec_dacs(spec, nid); | 1311 | add_spec_dacs(spec, nid); |
@@ -1355,7 +1419,7 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const | |||
1355 | imux->num_items++; | 1419 | imux->num_items++; |
1356 | } | 1420 | } |
1357 | 1421 | ||
1358 | if (imux->num_items == 1) { | 1422 | if (imux->num_items) { |
1359 | /* | 1423 | /* |
1360 | * Set the current input for the muxes. | 1424 | * Set the current input for the muxes. |
1361 | * The STAC9221 has two input muxes with identical source | 1425 | * The STAC9221 has two input muxes with identical source |
@@ -1675,8 +1739,12 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | |||
1675 | { | 1739 | { |
1676 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, | 1740 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, |
1677 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); | 1741 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); |
1678 | if (flag == AC_PINCTL_OUT_EN && (pin_ctl & AC_PINCTL_IN_EN)) | 1742 | |
1679 | return; | 1743 | /* if setting pin direction bits, clear the current |
1744 | direction bits first */ | ||
1745 | if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) | ||
1746 | pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); | ||
1747 | |||
1680 | snd_hda_codec_write(codec, nid, 0, | 1748 | snd_hda_codec_write(codec, nid, 0, |
1681 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 1749 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
1682 | pin_ctl | flag); | 1750 | pin_ctl | flag); |
@@ -1751,6 +1819,7 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
1751 | 1819 | ||
1752 | stac92xx_init(codec); | 1820 | stac92xx_init(codec); |
1753 | stac92xx_set_config_regs(codec); | 1821 | stac92xx_set_config_regs(codec); |
1822 | snd_hda_resume_ctls(codec, spec->mixer); | ||
1754 | for (i = 0; i < spec->num_mixers; i++) | 1823 | for (i = 0; i < spec->num_mixers; i++) |
1755 | snd_hda_resume_ctls(codec, spec->mixers[i]); | 1824 | snd_hda_resume_ctls(codec, spec->mixers[i]); |
1756 | if (spec->multiout.dig_out_nid) | 1825 | if (spec->multiout.dig_out_nid) |
@@ -1905,12 +1974,18 @@ static int patch_stac922x(struct hda_codec *codec) | |||
1905 | */ | 1974 | */ |
1906 | printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); | 1975 | printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); |
1907 | switch (codec->subsystem_id) { | 1976 | switch (codec->subsystem_id) { |
1977 | case 0x106b0a00: /* MacBook First generatoin */ | ||
1978 | spec->board_config = STAC_MACBOOK; | ||
1979 | break; | ||
1908 | case 0x106b0200: /* MacBook Pro first generation */ | 1980 | case 0x106b0200: /* MacBook Pro first generation */ |
1909 | spec->board_config = STAC_MACBOOK_PRO_V1; | 1981 | spec->board_config = STAC_MACBOOK_PRO_V1; |
1910 | break; | 1982 | break; |
1911 | case 0x106b1e00: /* MacBook Pro second generation */ | 1983 | case 0x106b1e00: /* MacBook Pro second generation */ |
1912 | spec->board_config = STAC_MACBOOK_PRO_V2; | 1984 | spec->board_config = STAC_MACBOOK_PRO_V2; |
1913 | break; | 1985 | break; |
1986 | case 0x106b0700: /* Intel-based iMac */ | ||
1987 | spec->board_config = STAC_IMAC_INTEL; | ||
1988 | break; | ||
1914 | } | 1989 | } |
1915 | } | 1990 | } |
1916 | 1991 | ||
@@ -1931,7 +2006,7 @@ static int patch_stac922x(struct hda_codec *codec) | |||
1931 | 2006 | ||
1932 | spec->adc_nids = stac922x_adc_nids; | 2007 | spec->adc_nids = stac922x_adc_nids; |
1933 | spec->mux_nids = stac922x_mux_nids; | 2008 | spec->mux_nids = stac922x_mux_nids; |
1934 | spec->num_muxes = 2; | 2009 | spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids); |
1935 | spec->num_dmics = 0; | 2010 | spec->num_dmics = 0; |
1936 | 2011 | ||
1937 | spec->init = stac922x_core_init; | 2012 | spec->init = stac922x_core_init; |
@@ -1992,7 +2067,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
1992 | case STAC_D965_3ST: | 2067 | case STAC_D965_3ST: |
1993 | spec->adc_nids = stac927x_adc_nids; | 2068 | spec->adc_nids = stac927x_adc_nids; |
1994 | spec->mux_nids = stac927x_mux_nids; | 2069 | spec->mux_nids = stac927x_mux_nids; |
1995 | spec->num_muxes = 3; | 2070 | spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); |
1996 | spec->num_dmics = 0; | 2071 | spec->num_dmics = 0; |
1997 | spec->init = d965_core_init; | 2072 | spec->init = d965_core_init; |
1998 | spec->mixer = stac9227_mixer; | 2073 | spec->mixer = stac9227_mixer; |
@@ -2000,7 +2075,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
2000 | case STAC_D965_5ST: | 2075 | case STAC_D965_5ST: |
2001 | spec->adc_nids = stac927x_adc_nids; | 2076 | spec->adc_nids = stac927x_adc_nids; |
2002 | spec->mux_nids = stac927x_mux_nids; | 2077 | spec->mux_nids = stac927x_mux_nids; |
2003 | spec->num_muxes = 3; | 2078 | spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); |
2004 | spec->num_dmics = 0; | 2079 | spec->num_dmics = 0; |
2005 | spec->init = d965_core_init; | 2080 | spec->init = d965_core_init; |
2006 | spec->mixer = stac9227_mixer; | 2081 | spec->mixer = stac9227_mixer; |
@@ -2008,7 +2083,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
2008 | default: | 2083 | default: |
2009 | spec->adc_nids = stac927x_adc_nids; | 2084 | spec->adc_nids = stac927x_adc_nids; |
2010 | spec->mux_nids = stac927x_mux_nids; | 2085 | spec->mux_nids = stac927x_mux_nids; |
2011 | spec->num_muxes = 3; | 2086 | spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); |
2012 | spec->num_dmics = 0; | 2087 | spec->num_dmics = 0; |
2013 | spec->init = stac927x_core_init; | 2088 | spec->init = stac927x_core_init; |
2014 | spec->mixer = stac927x_mixer; | 2089 | spec->mixer = stac927x_mixer; |
@@ -2067,9 +2142,9 @@ static int patch_stac9205(struct hda_codec *codec) | |||
2067 | 2142 | ||
2068 | spec->adc_nids = stac9205_adc_nids; | 2143 | spec->adc_nids = stac9205_adc_nids; |
2069 | spec->mux_nids = stac9205_mux_nids; | 2144 | spec->mux_nids = stac9205_mux_nids; |
2070 | spec->num_muxes = 2; | 2145 | spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); |
2071 | spec->dmic_nids = stac9205_dmic_nids; | 2146 | spec->dmic_nids = stac9205_dmic_nids; |
2072 | spec->num_dmics = 2; | 2147 | spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids); |
2073 | spec->dmux_nid = 0x1d; | 2148 | spec->dmux_nid = 0x1d; |
2074 | 2149 | ||
2075 | spec->init = stac9205_core_init; | 2150 | spec->init = stac9205_core_init; |
@@ -2294,6 +2369,7 @@ static struct snd_pci_quirk stac9872_cfg_tbl[] = { | |||
2294 | SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO), | 2369 | SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO), |
2295 | SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO), | 2370 | SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO), |
2296 | SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO), | 2371 | SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO), |
2372 | SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO), | ||
2297 | {} | 2373 | {} |
2298 | }; | 2374 | }; |
2299 | 2375 | ||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 2b11ac8689b9..ba32d1e52cb8 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -377,6 +377,17 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
377 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 377 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
378 | } | 378 | } |
379 | 379 | ||
380 | static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
381 | struct hda_codec *codec, | ||
382 | unsigned int stream_tag, | ||
383 | unsigned int format, | ||
384 | struct snd_pcm_substream *substream) | ||
385 | { | ||
386 | struct via_spec *spec = codec->spec; | ||
387 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
388 | stream_tag, format, substream); | ||
389 | } | ||
390 | |||
380 | /* | 391 | /* |
381 | * Analog capture | 392 | * Analog capture |
382 | */ | 393 | */ |
@@ -433,7 +444,8 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = { | |||
433 | /* NID is set in via_build_pcms */ | 444 | /* NID is set in via_build_pcms */ |
434 | .ops = { | 445 | .ops = { |
435 | .open = via_dig_playback_pcm_open, | 446 | .open = via_dig_playback_pcm_open, |
436 | .close = via_dig_playback_pcm_close | 447 | .close = via_dig_playback_pcm_close, |
448 | .prepare = via_dig_playback_pcm_prepare | ||
437 | }, | 449 | }, |
438 | }; | 450 | }; |
439 | 451 | ||
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c index 6e22d326df32..44bbb630b949 100644 --- a/sound/pci/ice1712/amp.c +++ b/sound/pci/ice1712/amp.c | |||
@@ -75,7 +75,7 @@ static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice) | |||
75 | 75 | ||
76 | 76 | ||
77 | /* entry point */ | 77 | /* entry point */ |
78 | const struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = { | 78 | struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = { |
79 | { | 79 | { |
80 | .subvendor = VT1724_SUBDEVICE_AV710, | 80 | .subvendor = VT1724_SUBDEVICE_AV710, |
81 | .name = "Chaintech AV-710", | 81 | .name = "Chaintech AV-710", |
diff --git a/sound/pci/ice1712/amp.h b/sound/pci/ice1712/amp.h index 7b667bad0c6b..a0fc89b48122 100644 --- a/sound/pci/ice1712/amp.h +++ b/sound/pci/ice1712/amp.h | |||
@@ -42,7 +42,7 @@ | |||
42 | #define WM_DAC_CTRL 0x02 | 42 | #define WM_DAC_CTRL 0x02 |
43 | #define WM_INT_CTRL 0x03 | 43 | #define WM_INT_CTRL 0x03 |
44 | 44 | ||
45 | extern const struct snd_ice1712_card_info snd_vt1724_amp_cards[]; | 45 | extern struct snd_ice1712_card_info snd_vt1724_amp_cards[]; |
46 | 46 | ||
47 | 47 | ||
48 | #endif /* __SOUND_AMP_H */ | 48 | #endif /* __SOUND_AMP_H */ |
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 6941d85dfec9..66bacde1ead3 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c | |||
@@ -1411,7 +1411,7 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
1411 | * mixers | 1411 | * mixers |
1412 | */ | 1412 | */ |
1413 | 1413 | ||
1414 | static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { | 1414 | static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { |
1415 | { | 1415 | { |
1416 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1416 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1417 | .name = "Master Playback Switch", | 1417 | .name = "Master Playback Switch", |
@@ -1526,7 +1526,7 @@ static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { | |||
1526 | } | 1526 | } |
1527 | }; | 1527 | }; |
1528 | 1528 | ||
1529 | static const struct snd_kcontrol_new wm_controls[] __devinitdata = { | 1529 | static struct snd_kcontrol_new wm_controls[] __devinitdata = { |
1530 | { | 1530 | { |
1531 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1531 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1532 | .name = "PCM Playback Switch", | 1532 | .name = "PCM Playback Switch", |
@@ -1592,7 +1592,7 @@ static const struct snd_kcontrol_new wm_controls[] __devinitdata = { | |||
1592 | } | 1592 | } |
1593 | }; | 1593 | }; |
1594 | 1594 | ||
1595 | static const struct snd_kcontrol_new ac97_controls[] __devinitdata = { | 1595 | static struct snd_kcontrol_new ac97_controls[] __devinitdata = { |
1596 | { | 1596 | { |
1597 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1597 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1598 | .name = "AC97 Playback Switch", | 1598 | .name = "AC97 Playback Switch", |
@@ -1697,7 +1697,7 @@ static const struct snd_kcontrol_new ac97_controls[] __devinitdata = { | |||
1697 | } | 1697 | } |
1698 | }; | 1698 | }; |
1699 | 1699 | ||
1700 | static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { | 1700 | static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { |
1701 | { | 1701 | { |
1702 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1702 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1703 | .name = "AC97 Playback Switch", | 1703 | .name = "AC97 Playback Switch", |
@@ -1829,7 +1829,7 @@ static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { | |||
1829 | 1829 | ||
1830 | }; | 1830 | }; |
1831 | 1831 | ||
1832 | static const struct snd_kcontrol_new cs8415_controls[] __devinitdata = { | 1832 | static struct snd_kcontrol_new cs8415_controls[] __devinitdata = { |
1833 | { | 1833 | { |
1834 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1834 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1835 | .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), | 1835 | .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), |
@@ -2107,7 +2107,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) | |||
2107 | * hence the driver needs to sets up it properly. | 2107 | * hence the driver needs to sets up it properly. |
2108 | */ | 2108 | */ |
2109 | 2109 | ||
2110 | static const unsigned char aureon51_eeprom[] __devinitdata = { | 2110 | static unsigned char aureon51_eeprom[] __devinitdata = { |
2111 | [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */ | 2111 | [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */ |
2112 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ | 2112 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ |
2113 | [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ | 2113 | [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ |
@@ -2123,7 +2123,7 @@ static const unsigned char aureon51_eeprom[] __devinitdata = { | |||
2123 | [ICE_EEP2_GPIO_STATE2] = 0x00, | 2123 | [ICE_EEP2_GPIO_STATE2] = 0x00, |
2124 | }; | 2124 | }; |
2125 | 2125 | ||
2126 | static const unsigned char aureon71_eeprom[] __devinitdata = { | 2126 | static unsigned char aureon71_eeprom[] __devinitdata = { |
2127 | [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ | 2127 | [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ |
2128 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ | 2128 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ |
2129 | [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ | 2129 | [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ |
@@ -2140,7 +2140,7 @@ static const unsigned char aureon71_eeprom[] __devinitdata = { | |||
2140 | }; | 2140 | }; |
2141 | #define prodigy71_eeprom aureon71_eeprom | 2141 | #define prodigy71_eeprom aureon71_eeprom |
2142 | 2142 | ||
2143 | static const unsigned char prodigy71lt_eeprom[] __devinitdata = { | 2143 | static unsigned char prodigy71lt_eeprom[] __devinitdata = { |
2144 | [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */ | 2144 | [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */ |
2145 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ | 2145 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ |
2146 | [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ | 2146 | [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ |
@@ -2158,7 +2158,7 @@ static const unsigned char prodigy71lt_eeprom[] __devinitdata = { | |||
2158 | #define prodigy71xt_eeprom prodigy71lt_eeprom | 2158 | #define prodigy71xt_eeprom prodigy71lt_eeprom |
2159 | 2159 | ||
2160 | /* entry point */ | 2160 | /* entry point */ |
2161 | const struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { | 2161 | struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { |
2162 | { | 2162 | { |
2163 | .subvendor = VT1724_SUBDEVICE_AUREON51_SKY, | 2163 | .subvendor = VT1724_SUBDEVICE_AUREON51_SKY, |
2164 | .name = "Terratec Aureon 5.1-Sky", | 2164 | .name = "Terratec Aureon 5.1-Sky", |
diff --git a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h index 79e58e88ed47..c253b8e2c789 100644 --- a/sound/pci/ice1712/aureon.h +++ b/sound/pci/ice1712/aureon.h | |||
@@ -38,7 +38,7 @@ | |||
38 | #define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */ | 38 | #define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */ |
39 | #define VT1724_SUBDEVICE_PRODIGY71XT 0x36315441 /* PRODIGY 7.1 XT*/ | 39 | #define VT1724_SUBDEVICE_PRODIGY71XT 0x36315441 /* PRODIGY 7.1 XT*/ |
40 | 40 | ||
41 | extern const struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; | 41 | extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; |
42 | 42 | ||
43 | /* GPIO bits */ | 43 | /* GPIO bits */ |
44 | #define AUREON_CS8415_CS (1 << 22) | 44 | #define AUREON_CS8415_CS (1 << 22) |
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 3eeb36c6e985..af659800c9b0 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c | |||
@@ -416,7 +416,7 @@ static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kco | |||
416 | return 0; | 416 | return 0; |
417 | } | 417 | } |
418 | 418 | ||
419 | static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = | 419 | static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = |
420 | { | 420 | { |
421 | .access = (SNDRV_CTL_ELEM_ACCESS_READ), | 421 | .access = (SNDRV_CTL_ELEM_ACCESS_READ), |
422 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 422 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -429,7 +429,7 @@ static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __ | |||
429 | * initialize the chips on M-Audio cards | 429 | * initialize the chips on M-Audio cards |
430 | */ | 430 | */ |
431 | 431 | ||
432 | static const struct snd_akm4xxx akm_audiophile __devinitdata = { | 432 | static struct snd_akm4xxx akm_audiophile __devinitdata = { |
433 | .type = SND_AK4528, | 433 | .type = SND_AK4528, |
434 | .num_adcs = 2, | 434 | .num_adcs = 2, |
435 | .num_dacs = 2, | 435 | .num_dacs = 2, |
@@ -438,7 +438,7 @@ static const struct snd_akm4xxx akm_audiophile __devinitdata = { | |||
438 | } | 438 | } |
439 | }; | 439 | }; |
440 | 440 | ||
441 | static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { | 441 | static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { |
442 | .caddr = 2, | 442 | .caddr = 2, |
443 | .cif = 0, | 443 | .cif = 0, |
444 | .data_mask = ICE1712_DELTA_AP_DOUT, | 444 | .data_mask = ICE1712_DELTA_AP_DOUT, |
@@ -450,7 +450,7 @@ static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { | |||
450 | .mask_flags = 0, | 450 | .mask_flags = 0, |
451 | }; | 451 | }; |
452 | 452 | ||
453 | static const struct snd_akm4xxx akm_delta410 __devinitdata = { | 453 | static struct snd_akm4xxx akm_delta410 __devinitdata = { |
454 | .type = SND_AK4529, | 454 | .type = SND_AK4529, |
455 | .num_adcs = 2, | 455 | .num_adcs = 2, |
456 | .num_dacs = 8, | 456 | .num_dacs = 8, |
@@ -459,7 +459,7 @@ static const struct snd_akm4xxx akm_delta410 __devinitdata = { | |||
459 | } | 459 | } |
460 | }; | 460 | }; |
461 | 461 | ||
462 | static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { | 462 | static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { |
463 | .caddr = 0, | 463 | .caddr = 0, |
464 | .cif = 0, | 464 | .cif = 0, |
465 | .data_mask = ICE1712_DELTA_AP_DOUT, | 465 | .data_mask = ICE1712_DELTA_AP_DOUT, |
@@ -471,7 +471,7 @@ static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { | |||
471 | .mask_flags = 0, | 471 | .mask_flags = 0, |
472 | }; | 472 | }; |
473 | 473 | ||
474 | static const struct snd_akm4xxx akm_delta1010lt __devinitdata = { | 474 | static struct snd_akm4xxx akm_delta1010lt __devinitdata = { |
475 | .type = SND_AK4524, | 475 | .type = SND_AK4524, |
476 | .num_adcs = 8, | 476 | .num_adcs = 8, |
477 | .num_dacs = 8, | 477 | .num_dacs = 8, |
@@ -481,7 +481,7 @@ static const struct snd_akm4xxx akm_delta1010lt __devinitdata = { | |||
481 | } | 481 | } |
482 | }; | 482 | }; |
483 | 483 | ||
484 | static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { | 484 | static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { |
485 | .caddr = 2, | 485 | .caddr = 2, |
486 | .cif = 0, /* the default level of the CIF pin from AK4524 */ | 486 | .cif = 0, /* the default level of the CIF pin from AK4524 */ |
487 | .data_mask = ICE1712_DELTA_1010LT_DOUT, | 487 | .data_mask = ICE1712_DELTA_1010LT_DOUT, |
@@ -493,7 +493,7 @@ static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { | |||
493 | .mask_flags = 0, | 493 | .mask_flags = 0, |
494 | }; | 494 | }; |
495 | 495 | ||
496 | static const struct snd_akm4xxx akm_delta44 __devinitdata = { | 496 | static struct snd_akm4xxx akm_delta44 __devinitdata = { |
497 | .type = SND_AK4524, | 497 | .type = SND_AK4524, |
498 | .num_adcs = 4, | 498 | .num_adcs = 4, |
499 | .num_dacs = 4, | 499 | .num_dacs = 4, |
@@ -503,7 +503,7 @@ static const struct snd_akm4xxx akm_delta44 __devinitdata = { | |||
503 | } | 503 | } |
504 | }; | 504 | }; |
505 | 505 | ||
506 | static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { | 506 | static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { |
507 | .caddr = 2, | 507 | .caddr = 2, |
508 | .cif = 0, /* the default level of the CIF pin from AK4524 */ | 508 | .cif = 0, /* the default level of the CIF pin from AK4524 */ |
509 | .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA, | 509 | .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA, |
@@ -515,7 +515,7 @@ static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { | |||
515 | .mask_flags = 0, | 515 | .mask_flags = 0, |
516 | }; | 516 | }; |
517 | 517 | ||
518 | static const struct snd_akm4xxx akm_vx442 __devinitdata = { | 518 | static struct snd_akm4xxx akm_vx442 __devinitdata = { |
519 | .type = SND_AK4524, | 519 | .type = SND_AK4524, |
520 | .num_adcs = 4, | 520 | .num_adcs = 4, |
521 | .num_dacs = 4, | 521 | .num_dacs = 4, |
@@ -525,7 +525,7 @@ static const struct snd_akm4xxx akm_vx442 __devinitdata = { | |||
525 | } | 525 | } |
526 | }; | 526 | }; |
527 | 527 | ||
528 | static const struct snd_ak4xxx_private akm_vx442_priv __devinitdata = { | 528 | static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = { |
529 | .caddr = 2, | 529 | .caddr = 2, |
530 | .cif = 0, | 530 | .cif = 0, |
531 | .data_mask = ICE1712_VX442_DOUT, | 531 | .data_mask = ICE1712_VX442_DOUT, |
@@ -650,15 +650,15 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) | |||
650 | * additional controls for M-Audio cards | 650 | * additional controls for M-Audio cards |
651 | */ | 651 | */ |
652 | 652 | ||
653 | static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = | 653 | static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = |
654 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); | 654 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); |
655 | static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = | 655 | static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = |
656 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0); | 656 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0); |
657 | static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = | 657 | static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = |
658 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); | 658 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); |
659 | static const struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = | 659 | static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = |
660 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); | 660 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); |
661 | static const struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata = | 661 | static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata = |
662 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); | 662 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); |
663 | 663 | ||
664 | 664 | ||
@@ -735,7 +735,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice) | |||
735 | 735 | ||
736 | 736 | ||
737 | /* entry point */ | 737 | /* entry point */ |
738 | const struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = { | 738 | struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = { |
739 | { | 739 | { |
740 | .subvendor = ICE1712_SUBDEVICE_DELTA1010, | 740 | .subvendor = ICE1712_SUBDEVICE_DELTA1010, |
741 | .name = "M Audio Delta 1010", | 741 | .name = "M Audio Delta 1010", |
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h index e47861ccd6e7..2697156607e4 100644 --- a/sound/pci/ice1712/delta.h +++ b/sound/pci/ice1712/delta.h | |||
@@ -46,7 +46,7 @@ | |||
46 | #define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100 | 46 | #define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100 |
47 | 47 | ||
48 | /* entry point */ | 48 | /* entry point */ |
49 | extern const struct snd_ice1712_card_info snd_ice1712_delta_cards[]; | 49 | extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; |
50 | 50 | ||
51 | 51 | ||
52 | /* | 52 | /* |
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index 9b7ff302c072..b135389fec6c 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c | |||
@@ -332,7 +332,7 @@ static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate) | |||
332 | 332 | ||
333 | /* | 333 | /* |
334 | */ | 334 | */ |
335 | static const struct snd_akm4xxx akm_ews88mt __devinitdata = { | 335 | static struct snd_akm4xxx akm_ews88mt __devinitdata = { |
336 | .num_adcs = 8, | 336 | .num_adcs = 8, |
337 | .num_dacs = 8, | 337 | .num_dacs = 8, |
338 | .type = SND_AK4524, | 338 | .type = SND_AK4524, |
@@ -342,7 +342,7 @@ static const struct snd_akm4xxx akm_ews88mt __devinitdata = { | |||
342 | } | 342 | } |
343 | }; | 343 | }; |
344 | 344 | ||
345 | static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { | 345 | static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { |
346 | .caddr = 2, | 346 | .caddr = 2, |
347 | .cif = 1, /* CIF high */ | 347 | .cif = 1, /* CIF high */ |
348 | .data_mask = ICE1712_EWS88_SERIAL_DATA, | 348 | .data_mask = ICE1712_EWS88_SERIAL_DATA, |
@@ -354,7 +354,7 @@ static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { | |||
354 | .mask_flags = 0, | 354 | .mask_flags = 0, |
355 | }; | 355 | }; |
356 | 356 | ||
357 | static const struct snd_akm4xxx akm_ewx2496 __devinitdata = { | 357 | static struct snd_akm4xxx akm_ewx2496 __devinitdata = { |
358 | .num_adcs = 2, | 358 | .num_adcs = 2, |
359 | .num_dacs = 2, | 359 | .num_dacs = 2, |
360 | .type = SND_AK4524, | 360 | .type = SND_AK4524, |
@@ -363,7 +363,7 @@ static const struct snd_akm4xxx akm_ewx2496 __devinitdata = { | |||
363 | } | 363 | } |
364 | }; | 364 | }; |
365 | 365 | ||
366 | static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { | 366 | static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { |
367 | .caddr = 2, | 367 | .caddr = 2, |
368 | .cif = 1, /* CIF high */ | 368 | .cif = 1, /* CIF high */ |
369 | .data_mask = ICE1712_EWS88_SERIAL_DATA, | 369 | .data_mask = ICE1712_EWS88_SERIAL_DATA, |
@@ -375,7 +375,7 @@ static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { | |||
375 | .mask_flags = 0, | 375 | .mask_flags = 0, |
376 | }; | 376 | }; |
377 | 377 | ||
378 | static const struct snd_akm4xxx akm_6fire __devinitdata = { | 378 | static struct snd_akm4xxx akm_6fire __devinitdata = { |
379 | .num_adcs = 6, | 379 | .num_adcs = 6, |
380 | .num_dacs = 6, | 380 | .num_dacs = 6, |
381 | .type = SND_AK4524, | 381 | .type = SND_AK4524, |
@@ -384,7 +384,7 @@ static const struct snd_akm4xxx akm_6fire __devinitdata = { | |||
384 | } | 384 | } |
385 | }; | 385 | }; |
386 | 386 | ||
387 | static const struct snd_ak4xxx_private akm_6fire_priv __devinitdata = { | 387 | static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = { |
388 | .caddr = 2, | 388 | .caddr = 2, |
389 | .cif = 1, /* CIF high */ | 389 | .cif = 1, /* CIF high */ |
390 | .data_mask = ICE1712_6FIRE_SERIAL_DATA, | 390 | .data_mask = ICE1712_6FIRE_SERIAL_DATA, |
@@ -578,7 +578,7 @@ static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct sn | |||
578 | return val != nval; | 578 | return val != nval; |
579 | } | 579 | } |
580 | 580 | ||
581 | static const struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = { | 581 | static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = { |
582 | { | 582 | { |
583 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 583 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
584 | .name = "Input Sensitivity Switch", | 584 | .name = "Input Sensitivity Switch", |
@@ -678,7 +678,7 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st | |||
678 | return ndata != data; | 678 | return ndata != data; |
679 | } | 679 | } |
680 | 680 | ||
681 | static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = { | 681 | static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = { |
682 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 682 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
683 | .name = "Input Sensitivity Switch", | 683 | .name = "Input Sensitivity Switch", |
684 | .info = snd_ice1712_ewx_io_sense_info, | 684 | .info = snd_ice1712_ewx_io_sense_info, |
@@ -687,7 +687,7 @@ static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitda | |||
687 | .count = 8, | 687 | .count = 8, |
688 | }; | 688 | }; |
689 | 689 | ||
690 | static const struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = { | 690 | static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = { |
691 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 691 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
692 | .name = "Output Sensitivity Switch", | 692 | .name = "Output Sensitivity Switch", |
693 | .info = snd_ice1712_ewx_io_sense_info, | 693 | .info = snd_ice1712_ewx_io_sense_info, |
@@ -769,7 +769,7 @@ static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct | |||
769 | .private_value = xshift | (xinvert << 8),\ | 769 | .private_value = xshift | (xinvert << 8),\ |
770 | } | 770 | } |
771 | 771 | ||
772 | static const struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { | 772 | static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { |
773 | EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */ | 773 | EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */ |
774 | EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0), | 774 | EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0), |
775 | EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0), | 775 | EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0), |
@@ -909,7 +909,7 @@ static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, str | |||
909 | .private_value = xshift | (xinvert << 8),\ | 909 | .private_value = xshift | (xinvert << 8),\ |
910 | } | 910 | } |
911 | 911 | ||
912 | static const struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = { | 912 | static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = { |
913 | { | 913 | { |
914 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 914 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
915 | .name = "Analog Input Select", | 915 | .name = "Analog Input Select", |
@@ -989,7 +989,7 @@ static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice) | |||
989 | 989 | ||
990 | 990 | ||
991 | /* entry point */ | 991 | /* entry point */ |
992 | const struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = { | 992 | struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = { |
993 | { | 993 | { |
994 | .subvendor = ICE1712_SUBDEVICE_EWX2496, | 994 | .subvendor = ICE1712_SUBDEVICE_EWX2496, |
995 | .name = "TerraTec EWX24/96", | 995 | .name = "TerraTec EWX24/96", |
diff --git a/sound/pci/ice1712/ews.h b/sound/pci/ice1712/ews.h index df449b4741f6..a12a0b053558 100644 --- a/sound/pci/ice1712/ews.h +++ b/sound/pci/ice1712/ews.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #define ICE1712_SUBDEVICE_PHASE88 0x3b155111 | 40 | #define ICE1712_SUBDEVICE_PHASE88 0x3b155111 |
41 | 41 | ||
42 | /* entry point */ | 42 | /* entry point */ |
43 | extern const struct snd_ice1712_card_info snd_ice1712_ews_cards[]; | 43 | extern struct snd_ice1712_card_info snd_ice1712_ews_cards[]; |
44 | 44 | ||
45 | 45 | ||
46 | /* TerraTec EWX 24/96 configuration definitions */ | 46 | /* TerraTec EWX 24/96 configuration definitions */ |
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c index df97313aaf83..8203562ef7e7 100644 --- a/sound/pci/ice1712/hoontech.c +++ b/sound/pci/ice1712/hoontech.c | |||
@@ -239,7 +239,7 @@ static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip) | |||
239 | static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice) | 239 | static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice) |
240 | { | 240 | { |
241 | /* Hoontech STDSP24 with modified hardware */ | 241 | /* Hoontech STDSP24 with modified hardware */ |
242 | static const struct snd_akm4xxx akm_stdsp24_mv __devinitdata = { | 242 | static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = { |
243 | .num_adcs = 2, | 243 | .num_adcs = 2, |
244 | .num_dacs = 2, | 244 | .num_dacs = 2, |
245 | .type = SND_AK4524, | 245 | .type = SND_AK4524, |
@@ -248,7 +248,7 @@ static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice) | |||
248 | } | 248 | } |
249 | }; | 249 | }; |
250 | 250 | ||
251 | static const struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = { | 251 | static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = { |
252 | .caddr = 2, | 252 | .caddr = 2, |
253 | .cif = 1, /* CIF high */ | 253 | .cif = 1, /* CIF high */ |
254 | .data_mask = ICE1712_STDSP24_SERIAL_DATA, | 254 | .data_mask = ICE1712_STDSP24_SERIAL_DATA, |
@@ -298,7 +298,7 @@ static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice) | |||
298 | 298 | ||
299 | 299 | ||
300 | /* entry point */ | 300 | /* entry point */ |
301 | const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = { | 301 | struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = { |
302 | { | 302 | { |
303 | .subvendor = ICE1712_SUBDEVICE_STDSP24, | 303 | .subvendor = ICE1712_SUBDEVICE_STDSP24, |
304 | .name = "Hoontech SoundTrack Audio DSP24", | 304 | .name = "Hoontech SoundTrack Audio DSP24", |
diff --git a/sound/pci/ice1712/hoontech.h b/sound/pci/ice1712/hoontech.h index b62d6e4f6c71..1ee538b20fbf 100644 --- a/sound/pci/ice1712/hoontech.h +++ b/sound/pci/ice1712/hoontech.h | |||
@@ -35,7 +35,7 @@ | |||
35 | #define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */ | 35 | #define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */ |
36 | #define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */ | 36 | #define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */ |
37 | 37 | ||
38 | extern const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[]; | 38 | extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[]; |
39 | 39 | ||
40 | 40 | ||
41 | /* Hoontech SoundTrack Audio DSP 24 GPIO definitions */ | 41 | /* Hoontech SoundTrack Audio DSP 24 GPIO definitions */ |
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 830a1bbd7110..6630a0ae9527 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
@@ -287,7 +287,7 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru | |||
287 | return val != nval; | 287 | return val != nval; |
288 | } | 288 | } |
289 | 289 | ||
290 | static const struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = { | 290 | static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = { |
291 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 291 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
292 | .name = "Digital Mixer To AC97", | 292 | .name = "Digital Mixer To AC97", |
293 | .info = snd_ice1712_digmix_route_ac97_info, | 293 | .info = snd_ice1712_digmix_route_ac97_info, |
@@ -977,11 +977,9 @@ static int snd_ice1712_pro_trigger(struct snd_pcm_substream *substream, | |||
977 | { | 977 | { |
978 | unsigned int what = 0; | 978 | unsigned int what = 0; |
979 | unsigned int old; | 979 | unsigned int old; |
980 | struct list_head *pos; | ||
981 | struct snd_pcm_substream *s; | 980 | struct snd_pcm_substream *s; |
982 | 981 | ||
983 | snd_pcm_group_for_each(pos, substream) { | 982 | snd_pcm_group_for_each_entry(s, substream) { |
984 | s = snd_pcm_group_substream_entry(pos); | ||
985 | if (s == ice->playback_pro_substream) { | 983 | if (s == ice->playback_pro_substream) { |
986 | what |= ICE1712_PLAYBACK_START; | 984 | what |= ICE1712_PLAYBACK_START; |
987 | snd_pcm_trigger_done(s, substream); | 985 | snd_pcm_trigger_done(s, substream); |
@@ -1380,7 +1378,7 @@ static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struc | |||
1380 | 1378 | ||
1381 | static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0); | 1379 | static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0); |
1382 | 1380 | ||
1383 | static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = { | 1381 | static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = { |
1384 | { | 1382 | { |
1385 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1383 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1386 | .name = "Multi Playback Switch", | 1384 | .name = "Multi Playback Switch", |
@@ -1404,7 +1402,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devini | |||
1404 | }, | 1402 | }, |
1405 | }; | 1403 | }; |
1406 | 1404 | ||
1407 | static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = { | 1405 | static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = { |
1408 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1406 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1409 | .name = "H/W Multi Capture Switch", | 1407 | .name = "H/W Multi Capture Switch", |
1410 | .info = snd_ice1712_pro_mixer_switch_info, | 1408 | .info = snd_ice1712_pro_mixer_switch_info, |
@@ -1413,7 +1411,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __d | |||
1413 | .private_value = 10, | 1411 | .private_value = 10, |
1414 | }; | 1412 | }; |
1415 | 1413 | ||
1416 | static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { | 1414 | static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { |
1417 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1415 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1418 | .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH), | 1416 | .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH), |
1419 | .info = snd_ice1712_pro_mixer_switch_info, | 1417 | .info = snd_ice1712_pro_mixer_switch_info, |
@@ -1423,7 +1421,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __de | |||
1423 | .count = 2, | 1421 | .count = 2, |
1424 | }; | 1422 | }; |
1425 | 1423 | ||
1426 | static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = { | 1424 | static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = { |
1427 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1425 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1428 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | 1426 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
1429 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), | 1427 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), |
@@ -1435,7 +1433,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __d | |||
1435 | .tlv = { .p = db_scale_playback } | 1433 | .tlv = { .p = db_scale_playback } |
1436 | }; | 1434 | }; |
1437 | 1435 | ||
1438 | static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { | 1436 | static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { |
1439 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1437 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1440 | .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME), | 1438 | .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME), |
1441 | .info = snd_ice1712_pro_mixer_volume_info, | 1439 | .info = snd_ice1712_pro_mixer_volume_info, |
@@ -1627,7 +1625,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol, | |||
1627 | return 0; | 1625 | return 0; |
1628 | } | 1626 | } |
1629 | 1627 | ||
1630 | static const struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = { | 1628 | static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = { |
1631 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | 1629 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, |
1632 | .name = "ICE1712 EEPROM", | 1630 | .name = "ICE1712 EEPROM", |
1633 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1631 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
@@ -1663,7 +1661,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol, | |||
1663 | return 0; | 1661 | return 0; |
1664 | } | 1662 | } |
1665 | 1663 | ||
1666 | static const struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = | 1664 | static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = |
1667 | { | 1665 | { |
1668 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 1666 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
1669 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), | 1667 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
@@ -1714,7 +1712,7 @@ static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol, | |||
1714 | return 0; | 1712 | return 0; |
1715 | } | 1713 | } |
1716 | 1714 | ||
1717 | static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = | 1715 | static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = |
1718 | { | 1716 | { |
1719 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1717 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
1720 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 1718 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -1723,7 +1721,7 @@ static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = | |||
1723 | .get = snd_ice1712_spdif_maskc_get, | 1721 | .get = snd_ice1712_spdif_maskc_get, |
1724 | }; | 1722 | }; |
1725 | 1723 | ||
1726 | static const struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = | 1724 | static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = |
1727 | { | 1725 | { |
1728 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1726 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
1729 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 1727 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -1750,7 +1748,7 @@ static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol, | |||
1750 | return 0; | 1748 | return 0; |
1751 | } | 1749 | } |
1752 | 1750 | ||
1753 | static const struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = | 1751 | static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = |
1754 | { | 1752 | { |
1755 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | 1753 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
1756 | SNDRV_CTL_ELEM_ACCESS_INACTIVE), | 1754 | SNDRV_CTL_ELEM_ACCESS_INACTIVE), |
@@ -1891,7 +1889,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol, | |||
1891 | return change; | 1889 | return change; |
1892 | } | 1890 | } |
1893 | 1891 | ||
1894 | static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = { | 1892 | static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = { |
1895 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1893 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1896 | .name = "Multi Track Internal Clock", | 1894 | .name = "Multi Track Internal Clock", |
1897 | .info = snd_ice1712_pro_internal_clock_info, | 1895 | .info = snd_ice1712_pro_internal_clock_info, |
@@ -1962,7 +1960,7 @@ static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcont | |||
1962 | return change; | 1960 | return change; |
1963 | } | 1961 | } |
1964 | 1962 | ||
1965 | static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = { | 1963 | static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = { |
1966 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1964 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1967 | .name = "Multi Track Internal Clock Default", | 1965 | .name = "Multi Track Internal Clock Default", |
1968 | .info = snd_ice1712_pro_internal_clock_default_info, | 1966 | .info = snd_ice1712_pro_internal_clock_default_info, |
@@ -2001,7 +1999,7 @@ static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol, | |||
2001 | return change; | 1999 | return change; |
2002 | } | 2000 | } |
2003 | 2001 | ||
2004 | static const struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { | 2002 | static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { |
2005 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2003 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2006 | .name = "Multi Track Rate Locking", | 2004 | .name = "Multi Track Rate Locking", |
2007 | .info = snd_ice1712_pro_rate_locking_info, | 2005 | .info = snd_ice1712_pro_rate_locking_info, |
@@ -2040,7 +2038,7 @@ static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol, | |||
2040 | return change; | 2038 | return change; |
2041 | } | 2039 | } |
2042 | 2040 | ||
2043 | static const struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = { | 2041 | static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = { |
2044 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2042 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2045 | .name = "Multi Track Rate Reset", | 2043 | .name = "Multi Track Rate Reset", |
2046 | .info = snd_ice1712_pro_rate_reset_info, | 2044 | .info = snd_ice1712_pro_rate_reset_info, |
@@ -2207,7 +2205,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol, | |||
2207 | return change; | 2205 | return change; |
2208 | } | 2206 | } |
2209 | 2207 | ||
2210 | static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = { | 2208 | static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = { |
2211 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2209 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2212 | .name = "H/W Playback Route", | 2210 | .name = "H/W Playback Route", |
2213 | .info = snd_ice1712_pro_route_info, | 2211 | .info = snd_ice1712_pro_route_info, |
@@ -2215,7 +2213,7 @@ static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devini | |||
2215 | .put = snd_ice1712_pro_route_analog_put, | 2213 | .put = snd_ice1712_pro_route_analog_put, |
2216 | }; | 2214 | }; |
2217 | 2215 | ||
2218 | static const struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { | 2216 | static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { |
2219 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2217 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2220 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", | 2218 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", |
2221 | .info = snd_ice1712_pro_route_info, | 2219 | .info = snd_ice1712_pro_route_info, |
@@ -2257,7 +2255,7 @@ static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol, | |||
2257 | return change; | 2255 | return change; |
2258 | } | 2256 | } |
2259 | 2257 | ||
2260 | static const struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = { | 2258 | static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = { |
2261 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2259 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2262 | .name = "Multi Track Volume Rate", | 2260 | .name = "Multi Track Volume Rate", |
2263 | .info = snd_ice1712_pro_volume_rate_info, | 2261 | .info = snd_ice1712_pro_volume_rate_info, |
@@ -2290,7 +2288,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol, | |||
2290 | return 0; | 2288 | return 0; |
2291 | } | 2289 | } |
2292 | 2290 | ||
2293 | static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { | 2291 | static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { |
2294 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2292 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2295 | .name = "Multi Track Peak", | 2293 | .name = "Multi Track Peak", |
2296 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 2294 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
@@ -2305,7 +2303,7 @@ static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = | |||
2305 | /* | 2303 | /* |
2306 | * list of available boards | 2304 | * list of available boards |
2307 | */ | 2305 | */ |
2308 | static const struct snd_ice1712_card_info *card_tables[] __devinitdata = { | 2306 | static struct snd_ice1712_card_info *card_tables[] __devinitdata = { |
2309 | snd_ice1712_hoontech_cards, | 2307 | snd_ice1712_hoontech_cards, |
2310 | snd_ice1712_delta_cards, | 2308 | snd_ice1712_delta_cards, |
2311 | snd_ice1712_ews_cards, | 2309 | snd_ice1712_ews_cards, |
@@ -2329,7 +2327,7 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice, | |||
2329 | { | 2327 | { |
2330 | int dev = 0xa0; /* EEPROM device address */ | 2328 | int dev = 0xa0; /* EEPROM device address */ |
2331 | unsigned int i, size; | 2329 | unsigned int i, size; |
2332 | const struct snd_ice1712_card_info **tbl, *c; | 2330 | struct snd_ice1712_card_info * const *tbl, *c; |
2333 | 2331 | ||
2334 | if (! modelname || ! *modelname) { | 2332 | if (! modelname || ! *modelname) { |
2335 | ice->eeprom.subvendor = 0; | 2333 | ice->eeprom.subvendor = 0; |
@@ -2658,7 +2656,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card, | |||
2658 | * | 2656 | * |
2659 | */ | 2657 | */ |
2660 | 2658 | ||
2661 | static const struct snd_ice1712_card_info no_matched __devinitdata; | 2659 | static struct snd_ice1712_card_info no_matched __devinitdata; |
2662 | 2660 | ||
2663 | static int __devinit snd_ice1712_probe(struct pci_dev *pci, | 2661 | static int __devinit snd_ice1712_probe(struct pci_dev *pci, |
2664 | const struct pci_device_id *pci_id) | 2662 | const struct pci_device_id *pci_id) |
@@ -2667,7 +2665,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, | |||
2667 | struct snd_card *card; | 2665 | struct snd_card *card; |
2668 | struct snd_ice1712 *ice; | 2666 | struct snd_ice1712 *ice; |
2669 | int pcm_dev = 0, err; | 2667 | int pcm_dev = 0, err; |
2670 | const struct snd_ice1712_card_info **tbl, *c; | 2668 | struct snd_ice1712_card_info * const *tbl, *c; |
2671 | 2669 | ||
2672 | if (dev >= SNDRV_CARDS) | 2670 | if (dev >= SNDRV_CARDS) |
2673 | return -ENODEV; | 2671 | return -ENODEV; |
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index c3d9feaaf57d..6ac486d9c138 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h | |||
@@ -397,6 +397,9 @@ struct snd_ice1712 { | |||
397 | struct ak4114 *ak4114; | 397 | struct ak4114 *ak4114; |
398 | unsigned int analog: 1; | 398 | unsigned int analog: 1; |
399 | } juli; | 399 | } juli; |
400 | struct { | ||
401 | struct ak4114 *ak4114; | ||
402 | } prodigy192; | ||
400 | } spec; | 403 | } spec; |
401 | 404 | ||
402 | }; | 405 | }; |
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 1127ebdf5fec..ee620dea7ef3 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
@@ -337,13 +337,11 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
337 | struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); | 337 | struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); |
338 | unsigned char what; | 338 | unsigned char what; |
339 | unsigned char old; | 339 | unsigned char old; |
340 | struct list_head *pos; | ||
341 | struct snd_pcm_substream *s; | 340 | struct snd_pcm_substream *s; |
342 | 341 | ||
343 | what = 0; | 342 | what = 0; |
344 | snd_pcm_group_for_each(pos, substream) { | 343 | snd_pcm_group_for_each_entry(s, substream) { |
345 | const struct vt1724_pcm_reg *reg; | 344 | const struct vt1724_pcm_reg *reg; |
346 | s = snd_pcm_group_substream_entry(pos); | ||
347 | reg = s->runtime->private_data; | 345 | reg = s->runtime->private_data; |
348 | what |= reg->start; | 346 | what |= reg->start; |
349 | snd_pcm_trigger_done(s, substream); | 347 | snd_pcm_trigger_done(s, substream); |
@@ -1318,7 +1316,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol, | |||
1318 | return 0; | 1316 | return 0; |
1319 | } | 1317 | } |
1320 | 1318 | ||
1321 | static const struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = { | 1319 | static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = { |
1322 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | 1320 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, |
1323 | .name = "ICE1724 EEPROM", | 1321 | .name = "ICE1724 EEPROM", |
1324 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1322 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
@@ -1431,7 +1429,7 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol, | |||
1431 | return (val != old); | 1429 | return (val != old); |
1432 | } | 1430 | } |
1433 | 1431 | ||
1434 | static const struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = | 1432 | static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = |
1435 | { | 1433 | { |
1436 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 1434 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
1437 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), | 1435 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
@@ -1463,7 +1461,7 @@ static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol, | |||
1463 | return 0; | 1461 | return 0; |
1464 | } | 1462 | } |
1465 | 1463 | ||
1466 | static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = | 1464 | static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = |
1467 | { | 1465 | { |
1468 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1466 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
1469 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 1467 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -1472,7 +1470,7 @@ static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = | |||
1472 | .get = snd_vt1724_spdif_maskc_get, | 1470 | .get = snd_vt1724_spdif_maskc_get, |
1473 | }; | 1471 | }; |
1474 | 1472 | ||
1475 | static const struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = | 1473 | static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = |
1476 | { | 1474 | { |
1477 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1475 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
1478 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 1476 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -1517,7 +1515,7 @@ static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol, | |||
1517 | return old != val; | 1515 | return old != val; |
1518 | } | 1516 | } |
1519 | 1517 | ||
1520 | static const struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = | 1518 | static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = |
1521 | { | 1519 | { |
1522 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1520 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1523 | /* FIXME: the following conflict with IEC958 Playback Route */ | 1521 | /* FIXME: the following conflict with IEC958 Playback Route */ |
@@ -1668,7 +1666,12 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol, | |||
1668 | spin_lock_irq(&ice->reg_lock); | 1666 | spin_lock_irq(&ice->reg_lock); |
1669 | oval = inb(ICEMT1724(ice, RATE)); | 1667 | oval = inb(ICEMT1724(ice, RATE)); |
1670 | if (ucontrol->value.enumerated.item[0] == spdif) { | 1668 | if (ucontrol->value.enumerated.item[0] == spdif) { |
1669 | unsigned char i2s_oval; | ||
1671 | outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE)); | 1670 | outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE)); |
1671 | /* setting 256fs */ | ||
1672 | i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT)); | ||
1673 | outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X, | ||
1674 | ICEMT1724(ice, I2S_FORMAT)); | ||
1672 | } else { | 1675 | } else { |
1673 | rate = rates[ucontrol->value.integer.value[0] % 15]; | 1676 | rate = rates[ucontrol->value.integer.value[0] % 15]; |
1674 | if (rate <= get_max_rate(ice)) { | 1677 | if (rate <= get_max_rate(ice)) { |
@@ -1695,7 +1698,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol, | |||
1695 | return change; | 1698 | return change; |
1696 | } | 1699 | } |
1697 | 1700 | ||
1698 | static const struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { | 1701 | static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { |
1699 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1702 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1700 | .name = "Multi Track Internal Clock", | 1703 | .name = "Multi Track Internal Clock", |
1701 | .info = snd_vt1724_pro_internal_clock_info, | 1704 | .info = snd_vt1724_pro_internal_clock_info, |
@@ -1734,7 +1737,7 @@ static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol, | |||
1734 | return change; | 1737 | return change; |
1735 | } | 1738 | } |
1736 | 1739 | ||
1737 | static const struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { | 1740 | static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { |
1738 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1741 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1739 | .name = "Multi Track Rate Locking", | 1742 | .name = "Multi Track Rate Locking", |
1740 | .info = snd_vt1724_pro_rate_locking_info, | 1743 | .info = snd_vt1724_pro_rate_locking_info, |
@@ -1773,7 +1776,7 @@ static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol, | |||
1773 | return change; | 1776 | return change; |
1774 | } | 1777 | } |
1775 | 1778 | ||
1776 | static const struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = { | 1779 | static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = { |
1777 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1780 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1778 | .name = "Multi Track Rate Reset", | 1781 | .name = "Multi Track Rate Reset", |
1779 | .info = snd_vt1724_pro_rate_reset_info, | 1782 | .info = snd_vt1724_pro_rate_reset_info, |
@@ -1892,7 +1895,7 @@ static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol, | |||
1892 | digital_route_shift(idx)); | 1895 | digital_route_shift(idx)); |
1893 | } | 1896 | } |
1894 | 1897 | ||
1895 | static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = { | 1898 | static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = { |
1896 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1899 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1897 | .name = "H/W Playback Route", | 1900 | .name = "H/W Playback Route", |
1898 | .info = snd_vt1724_pro_route_info, | 1901 | .info = snd_vt1724_pro_route_info, |
@@ -1900,7 +1903,7 @@ static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinit | |||
1900 | .put = snd_vt1724_pro_route_analog_put, | 1903 | .put = snd_vt1724_pro_route_analog_put, |
1901 | }; | 1904 | }; |
1902 | 1905 | ||
1903 | static const struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { | 1906 | static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { |
1904 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1907 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1905 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", | 1908 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", |
1906 | .info = snd_vt1724_pro_route_info, | 1909 | .info = snd_vt1724_pro_route_info, |
@@ -1936,7 +1939,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol, | |||
1936 | return 0; | 1939 | return 0; |
1937 | } | 1940 | } |
1938 | 1941 | ||
1939 | static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { | 1942 | static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { |
1940 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1943 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1941 | .name = "Multi Track Peak", | 1944 | .name = "Multi Track Peak", |
1942 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 1945 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
@@ -1948,9 +1951,9 @@ static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { | |||
1948 | * | 1951 | * |
1949 | */ | 1952 | */ |
1950 | 1953 | ||
1951 | static const struct snd_ice1712_card_info no_matched __devinitdata; | 1954 | static struct snd_ice1712_card_info no_matched __devinitdata; |
1952 | 1955 | ||
1953 | static const struct snd_ice1712_card_info *card_tables[] __devinitdata = { | 1956 | static struct snd_ice1712_card_info *card_tables[] __devinitdata = { |
1954 | snd_vt1724_revo_cards, | 1957 | snd_vt1724_revo_cards, |
1955 | snd_vt1724_amp_cards, | 1958 | snd_vt1724_amp_cards, |
1956 | snd_vt1724_aureon_cards, | 1959 | snd_vt1724_aureon_cards, |
@@ -2009,7 +2012,7 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, | |||
2009 | { | 2012 | { |
2010 | const int dev = 0xa0; /* EEPROM device address */ | 2013 | const int dev = 0xa0; /* EEPROM device address */ |
2011 | unsigned int i, size; | 2014 | unsigned int i, size; |
2012 | const struct snd_ice1712_card_info **tbl, *c; | 2015 | struct snd_ice1712_card_info * const *tbl, *c; |
2013 | 2016 | ||
2014 | if (! modelname || ! *modelname) { | 2017 | if (! modelname || ! *modelname) { |
2015 | ice->eeprom.subvendor = 0; | 2018 | ice->eeprom.subvendor = 0; |
@@ -2308,7 +2311,7 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, | |||
2308 | struct snd_card *card; | 2311 | struct snd_card *card; |
2309 | struct snd_ice1712 *ice; | 2312 | struct snd_ice1712 *ice; |
2310 | int pcm_dev = 0, err; | 2313 | int pcm_dev = 0, err; |
2311 | const struct snd_ice1712_card_info **tbl, *c; | 2314 | struct snd_ice1712_card_info * const *tbl, *c; |
2312 | 2315 | ||
2313 | if (dev >= SNDRV_CARDS) | 2316 | if (dev >= SNDRV_CARDS) |
2314 | return -ENODEV; | 2317 | return -ENODEV; |
@@ -2347,6 +2350,14 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, | |||
2347 | } | 2350 | } |
2348 | c = &no_matched; | 2351 | c = &no_matched; |
2349 | __found: | 2352 | __found: |
2353 | /* | ||
2354 | * VT1724 has separate DMAs for the analog and the SPDIF streams while | ||
2355 | * ICE1712 has only one for both (mixed up). | ||
2356 | * | ||
2357 | * Confusingly the analog PCM is named "professional" here because it | ||
2358 | * was called so in ice1712 driver, and vt1724 driver is derived from | ||
2359 | * ice1712 driver. | ||
2360 | */ | ||
2350 | 2361 | ||
2351 | if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) { | 2362 | if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) { |
2352 | snd_card_free(card); | 2363 | snd_card_free(card); |
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index d88172fa95da..3d8e74e493d7 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c | |||
@@ -125,7 +125,7 @@ static void juli_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | |||
125 | snd_akm4xxx_reset(ak, 0); | 125 | snd_akm4xxx_reset(ak, 0); |
126 | } | 126 | } |
127 | 127 | ||
128 | static const struct snd_akm4xxx akm_juli_dac __devinitdata = { | 128 | static struct snd_akm4xxx akm_juli_dac __devinitdata = { |
129 | .type = SND_AK4358, | 129 | .type = SND_AK4358, |
130 | .num_dacs = 2, | 130 | .num_dacs = 2, |
131 | .ops = { | 131 | .ops = { |
@@ -138,7 +138,16 @@ static const struct snd_akm4xxx akm_juli_dac __devinitdata = { | |||
138 | 138 | ||
139 | static int __devinit juli_add_controls(struct snd_ice1712 *ice) | 139 | static int __devinit juli_add_controls(struct snd_ice1712 *ice) |
140 | { | 140 | { |
141 | return snd_ice1712_akm4xxx_build_controls(ice); | 141 | int err; |
142 | err = snd_ice1712_akm4xxx_build_controls(ice); | ||
143 | if (err < 0) | ||
144 | return err; | ||
145 | /* only capture SPDIF over AK4114 */ | ||
146 | err = snd_ak4114_build(ice->spec.juli.ak4114, NULL, | ||
147 | ice->pcm_pro->streams[SNDRV_PCM_STREAM_CAPTURE].substream); | ||
148 | if (err < 0) | ||
149 | return err; | ||
150 | return 0; | ||
142 | } | 151 | } |
143 | 152 | ||
144 | /* | 153 | /* |
@@ -160,13 +169,6 @@ static int __devinit juli_init(struct snd_ice1712 *ice) | |||
160 | int err; | 169 | int err; |
161 | struct snd_akm4xxx *ak; | 170 | struct snd_akm4xxx *ak; |
162 | 171 | ||
163 | #if 0 | ||
164 | for (err = 0; err < 0x20; err++) | ||
165 | juli_ak4114_read(ice, err); | ||
166 | juli_ak4114_write(ice, 0, 0x0f); | ||
167 | juli_ak4114_read(ice, 0); | ||
168 | juli_ak4114_read(ice, 1); | ||
169 | #endif | ||
170 | err = snd_ak4114_create(ice->card, | 172 | err = snd_ak4114_create(ice->card, |
171 | juli_ak4114_read, | 173 | juli_ak4114_read, |
172 | juli_ak4114_write, | 174 | juli_ak4114_write, |
@@ -206,7 +208,7 @@ static int __devinit juli_init(struct snd_ice1712 *ice) | |||
206 | * hence the driver needs to sets up it properly. | 208 | * hence the driver needs to sets up it properly. |
207 | */ | 209 | */ |
208 | 210 | ||
209 | static const unsigned char juli_eeprom[] __devinitdata = { | 211 | static unsigned char juli_eeprom[] __devinitdata = { |
210 | [ICE_EEP2_SYSCONF] = 0x20, /* clock 512, mpu401, 1xADC, 1xDACs */ | 212 | [ICE_EEP2_SYSCONF] = 0x20, /* clock 512, mpu401, 1xADC, 1xDACs */ |
211 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ | 213 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ |
212 | [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ | 214 | [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ |
@@ -223,7 +225,7 @@ static const unsigned char juli_eeprom[] __devinitdata = { | |||
223 | }; | 225 | }; |
224 | 226 | ||
225 | /* entry point */ | 227 | /* entry point */ |
226 | const struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = { | 228 | struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = { |
227 | { | 229 | { |
228 | .subvendor = VT1724_SUBDEVICE_JULI, | 230 | .subvendor = VT1724_SUBDEVICE_JULI, |
229 | .name = "ESI Juli@", | 231 | .name = "ESI Juli@", |
diff --git a/sound/pci/ice1712/juli.h b/sound/pci/ice1712/juli.h index 1b9294f8bce3..d9f8534fd92e 100644 --- a/sound/pci/ice1712/juli.h +++ b/sound/pci/ice1712/juli.h | |||
@@ -5,6 +5,6 @@ | |||
5 | 5 | ||
6 | #define VT1724_SUBDEVICE_JULI 0x31305345 /* Juli@ */ | 6 | #define VT1724_SUBDEVICE_JULI 0x31305345 /* Juli@ */ |
7 | 7 | ||
8 | extern const struct snd_ice1712_card_info snd_vt1724_juli_cards[]; | 8 | extern struct snd_ice1712_card_info snd_vt1724_juli_cards[]; |
9 | 9 | ||
10 | #endif /* __SOUND_JULI_H */ | 10 | #endif /* __SOUND_JULI_H */ |
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 0751718f4d7b..40a9098af777 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c | |||
@@ -89,13 +89,13 @@ static const unsigned char wm_vol[256] = { | |||
89 | #define WM_VOL_MAX (sizeof(wm_vol) - 1) | 89 | #define WM_VOL_MAX (sizeof(wm_vol) - 1) |
90 | #define WM_VOL_MUTE 0x8000 | 90 | #define WM_VOL_MUTE 0x8000 |
91 | 91 | ||
92 | static const struct snd_akm4xxx akm_phase22 __devinitdata = { | 92 | static struct snd_akm4xxx akm_phase22 __devinitdata = { |
93 | .type = SND_AK4524, | 93 | .type = SND_AK4524, |
94 | .num_dacs = 2, | 94 | .num_dacs = 2, |
95 | .num_adcs = 2, | 95 | .num_adcs = 2, |
96 | }; | 96 | }; |
97 | 97 | ||
98 | static const struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { | 98 | static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { |
99 | .caddr = 2, | 99 | .caddr = 2, |
100 | .cif = 1, | 100 | .cif = 1, |
101 | .data_mask = 1 << 4, | 101 | .data_mask = 1 << 4, |
@@ -152,7 +152,7 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice) | |||
152 | return 0; | 152 | return 0; |
153 | } | 153 | } |
154 | 154 | ||
155 | static const unsigned char phase22_eeprom[] __devinitdata = { | 155 | static unsigned char phase22_eeprom[] __devinitdata = { |
156 | [ICE_EEP2_SYSCONF] = 0x00, /* 1xADC, 1xDACs */ | 156 | [ICE_EEP2_SYSCONF] = 0x00, /* 1xADC, 1xDACs */ |
157 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ | 157 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ |
158 | [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit */ | 158 | [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit */ |
@@ -168,7 +168,7 @@ static const unsigned char phase22_eeprom[] __devinitdata = { | |||
168 | [ICE_EEP2_GPIO_STATE2] = 0x00, | 168 | [ICE_EEP2_GPIO_STATE2] = 0x00, |
169 | }; | 169 | }; |
170 | 170 | ||
171 | static const unsigned char phase28_eeprom[] __devinitdata = { | 171 | static unsigned char phase28_eeprom[] __devinitdata = { |
172 | [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ | 172 | [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ |
173 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ | 173 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ |
174 | [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ | 174 | [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ |
@@ -700,7 +700,7 @@ static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ct | |||
700 | static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); | 700 | static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); |
701 | static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); | 701 | static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); |
702 | 702 | ||
703 | static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { | 703 | static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { |
704 | { | 704 | { |
705 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 705 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
706 | .name = "Master Playback Switch", | 706 | .name = "Master Playback Switch", |
@@ -815,7 +815,7 @@ static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { | |||
815 | } | 815 | } |
816 | }; | 816 | }; |
817 | 817 | ||
818 | static const struct snd_kcontrol_new wm_controls[] __devinitdata = { | 818 | static struct snd_kcontrol_new wm_controls[] __devinitdata = { |
819 | { | 819 | { |
820 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 820 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
821 | .name = "PCM Playback Switch", | 821 | .name = "PCM Playback Switch", |
@@ -870,7 +870,7 @@ static int __devinit phase28_add_controls(struct snd_ice1712 *ice) | |||
870 | return 0; | 870 | return 0; |
871 | } | 871 | } |
872 | 872 | ||
873 | const struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { | 873 | struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { |
874 | { | 874 | { |
875 | .subvendor = VT1724_SUBDEVICE_PHASE22, | 875 | .subvendor = VT1724_SUBDEVICE_PHASE22, |
876 | .name = "Terratec PHASE 22", | 876 | .name = "Terratec PHASE 22", |
diff --git a/sound/pci/ice1712/phase.h b/sound/pci/ice1712/phase.h index ad379a99bf92..13e841b55488 100644 --- a/sound/pci/ice1712/phase.h +++ b/sound/pci/ice1712/phase.h | |||
@@ -31,7 +31,7 @@ | |||
31 | #define VT1724_SUBDEVICE_PHASE28 0x3b154911 | 31 | #define VT1724_SUBDEVICE_PHASE28 0x3b154911 |
32 | 32 | ||
33 | /* entry point */ | 33 | /* entry point */ |
34 | extern const struct snd_ice1712_card_info snd_vt1724_phase_cards[]; | 34 | extern struct snd_ice1712_card_info snd_vt1724_phase_cards[]; |
35 | 35 | ||
36 | /* PHASE28 GPIO bits */ | 36 | /* PHASE28 GPIO bits */ |
37 | #define PHASE28_SPI_MISO (1 << 21) | 37 | #define PHASE28_SPI_MISO (1 << 21) |
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index 9552497f0765..01c69453ddeb 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c | |||
@@ -571,7 +571,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1); | |||
571 | * mixers | 571 | * mixers |
572 | */ | 572 | */ |
573 | 573 | ||
574 | static const struct snd_kcontrol_new pontis_controls[] __devinitdata = { | 574 | static struct snd_kcontrol_new pontis_controls[] __devinitdata = { |
575 | { | 575 | { |
576 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 576 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
577 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | 577 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
@@ -826,7 +826,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice) | |||
826 | * hence the driver needs to sets up it properly. | 826 | * hence the driver needs to sets up it properly. |
827 | */ | 827 | */ |
828 | 828 | ||
829 | static const unsigned char pontis_eeprom[] __devinitdata = { | 829 | static unsigned char pontis_eeprom[] __devinitdata = { |
830 | [ICE_EEP2_SYSCONF] = 0x08, /* clock 256, mpu401, spdif-in/ADC, 1DAC */ | 830 | [ICE_EEP2_SYSCONF] = 0x08, /* clock 256, mpu401, spdif-in/ADC, 1DAC */ |
831 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ | 831 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ |
832 | [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ | 832 | [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ |
@@ -843,7 +843,7 @@ static const unsigned char pontis_eeprom[] __devinitdata = { | |||
843 | }; | 843 | }; |
844 | 844 | ||
845 | /* entry point */ | 845 | /* entry point */ |
846 | const struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = { | 846 | struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = { |
847 | { | 847 | { |
848 | .subvendor = VT1720_SUBDEVICE_PONTIS_MS300, | 848 | .subvendor = VT1720_SUBDEVICE_PONTIS_MS300, |
849 | .name = "Pontis MS300", | 849 | .name = "Pontis MS300", |
diff --git a/sound/pci/ice1712/pontis.h b/sound/pci/ice1712/pontis.h index 1a418255c19e..d0d1378b935c 100644 --- a/sound/pci/ice1712/pontis.h +++ b/sound/pci/ice1712/pontis.h | |||
@@ -28,6 +28,6 @@ | |||
28 | 28 | ||
29 | #define VT1720_SUBDEVICE_PONTIS_MS300 0x00020002 /* a dummy id for MS300 */ | 29 | #define VT1720_SUBDEVICE_PONTIS_MS300 0x00020002 /* a dummy id for MS300 */ |
30 | 30 | ||
31 | extern const struct snd_ice1712_card_info snd_vt1720_pontis_cards[]; | 31 | extern struct snd_ice1712_card_info snd_vt1720_pontis_cards[]; |
32 | 32 | ||
33 | #endif /* __SOUND_PONTIS_H */ | 33 | #endif /* __SOUND_PONTIS_H */ |
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index 31cc66eb9f8f..f03c02c07743 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c | |||
@@ -2,6 +2,37 @@ | |||
2 | * ALSA driver for ICEnsemble VT1724 (Envy24HT) | 2 | * ALSA driver for ICEnsemble VT1724 (Envy24HT) |
3 | * | 3 | * |
4 | * Lowlevel functions for AudioTrak Prodigy 192 cards | 4 | * Lowlevel functions for AudioTrak Prodigy 192 cards |
5 | * Supported IEC958 input from optional MI/ODI/O add-on card. | ||
6 | * | ||
7 | * Specifics (SW, HW): | ||
8 | * ------------------- | ||
9 | * * 49.5MHz crystal | ||
10 | * * SPDIF-OUT on the card: | ||
11 | * - coax (through isolation transformer)/toslink supplied by | ||
12 | * 74HC04 gates - 3 in parallel | ||
13 | * - output switched between on-board CD drive dig-out connector | ||
14 | * and ice1724 SPDTX pin, using 74HC02 NOR gates, controlled | ||
15 | * by GPIO20 (0 = CD dig-out, 1 = SPDTX) | ||
16 | * * SPDTX goes straight to MI/ODI/O card's SPDIF-OUT coax | ||
17 | * | ||
18 | * * MI/ODI/O card: AK4114 based, used for iec958 input only | ||
19 | * - toslink input -> RX0 | ||
20 | * - coax input -> RX1 | ||
21 | * - 4wire protocol: | ||
22 | * AK4114 ICE1724 | ||
23 | * ------------------------------ | ||
24 | * CDTO (pin 32) -- GPIO11 pin 86 | ||
25 | * CDTI (pin 33) -- GPIO10 pin 77 | ||
26 | * CCLK (pin 34) -- GPIO9 pin 76 | ||
27 | * CSN (pin 35) -- GPIO8 pin 75 | ||
28 | * - output data Mode 7 (24bit, I2S, slave) | ||
29 | * - both MCKO1 and MCKO2 of ak4114 are fed to FPGA, which | ||
30 | * outputs master clock to SPMCLKIN of ice1724. | ||
31 | * Experimentally I found out that only a combination of | ||
32 | * OCKS0=1, OCKS1=1 (128fs, 64fs output) and ice1724 - | ||
33 | * VT1724_MT_I2S_MCLK_128X=0 (256fs input) yields correct | ||
34 | * sampling rate. That means the the FPGA doubles the | ||
35 | * MCK01 rate. | ||
5 | * | 36 | * |
6 | * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de> | 37 | * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de> |
7 | * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca> | 38 | * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca> |
@@ -356,6 +387,47 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
356 | return 0; | 387 | return 0; |
357 | } | 388 | } |
358 | #endif | 389 | #endif |
390 | static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol, | ||
391 | struct snd_ctl_elem_info *uinfo) | ||
392 | { | ||
393 | static char *texts[2] = { "Line In", "Mic" }; | ||
394 | |||
395 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
396 | uinfo->count = 1; | ||
397 | uinfo->value.enumerated.items = 2; | ||
398 | |||
399 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
400 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
401 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | |||
407 | static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol, | ||
408 | struct snd_ctl_elem_value *ucontrol) | ||
409 | { | ||
410 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | ||
411 | unsigned char val; | ||
412 | |||
413 | val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); | ||
414 | ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1; | ||
415 | return 0; | ||
416 | } | ||
417 | |||
418 | static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, | ||
419 | struct snd_ctl_elem_value *ucontrol) | ||
420 | { | ||
421 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | ||
422 | unsigned char new, old; | ||
423 | int change; | ||
424 | old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); | ||
425 | new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80); | ||
426 | change = (new != old); | ||
427 | if (change) | ||
428 | stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); | ||
429 | return change; | ||
430 | } | ||
359 | 431 | ||
360 | static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); | 432 | static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); |
361 | static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); | 433 | static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); |
@@ -364,7 +436,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); | |||
364 | * mixers | 436 | * mixers |
365 | */ | 437 | */ |
366 | 438 | ||
367 | static const struct snd_kcontrol_new stac_controls[] __devinitdata = { | 439 | static struct snd_kcontrol_new stac_controls[] __devinitdata = { |
368 | { | 440 | { |
369 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 441 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
370 | .name = "Master Playback Switch", | 442 | .name = "Master Playback Switch", |
@@ -406,7 +478,7 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = { | |||
406 | }, | 478 | }, |
407 | { | 479 | { |
408 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 480 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
409 | .name = "ADC Switch", | 481 | .name = "ADC Capture Switch", |
410 | .count = 1, | 482 | .count = 1, |
411 | .info = stac9460_adc_mute_info, | 483 | .info = stac9460_adc_mute_info, |
412 | .get = stac9460_adc_mute_get, | 484 | .get = stac9460_adc_mute_get, |
@@ -417,13 +489,21 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = { | |||
417 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 489 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
418 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | 490 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
419 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), | 491 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), |
420 | .name = "ADC Volume", | 492 | .name = "ADC Capture Volume", |
421 | .count = 1, | 493 | .count = 1, |
422 | .info = stac9460_adc_vol_info, | 494 | .info = stac9460_adc_vol_info, |
423 | .get = stac9460_adc_vol_get, | 495 | .get = stac9460_adc_vol_get, |
424 | .put = stac9460_adc_vol_put, | 496 | .put = stac9460_adc_vol_put, |
425 | .tlv = { .p = db_scale_adc } | 497 | .tlv = { .p = db_scale_adc } |
426 | }, | 498 | }, |
499 | { | ||
500 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
501 | .name = "Analog Capture Input", | ||
502 | .info = stac9460_mic_sw_info, | ||
503 | .get = stac9460_mic_sw_get, | ||
504 | .put = stac9460_mic_sw_put, | ||
505 | |||
506 | }, | ||
427 | #if 0 | 507 | #if 0 |
428 | { | 508 | { |
429 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 509 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -456,19 +536,261 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = { | |||
456 | #endif | 536 | #endif |
457 | }; | 537 | }; |
458 | 538 | ||
539 | |||
540 | /* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */ | ||
541 | /* CDTO (pin 32) -- GPIO11 pin 86 | ||
542 | * CDTI (pin 33) -- GPIO10 pin 77 | ||
543 | * CCLK (pin 34) -- GPIO9 pin 76 | ||
544 | * CSN (pin 35) -- GPIO8 pin 75 | ||
545 | */ | ||
546 | #define AK4114_ADDR 0x00 /* C1-C0: Chip Address | ||
547 | * (According to datasheet fixed to “00”) | ||
548 | */ | ||
549 | |||
550 | /* | ||
551 | * 4wire ak4114 protocol - writing data | ||
552 | */ | ||
553 | static void write_data(struct snd_ice1712 *ice, unsigned int gpio, | ||
554 | unsigned int data, int idx) | ||
555 | { | ||
556 | for (; idx >= 0; idx--) { | ||
557 | /* drop clock */ | ||
558 | gpio &= ~VT1724_PRODIGY192_CCLK; | ||
559 | snd_ice1712_gpio_write(ice, gpio); | ||
560 | udelay(1); | ||
561 | /* set data */ | ||
562 | if (data & (1 << idx)) | ||
563 | gpio |= VT1724_PRODIGY192_CDOUT; | ||
564 | else | ||
565 | gpio &= ~VT1724_PRODIGY192_CDOUT; | ||
566 | snd_ice1712_gpio_write(ice, gpio); | ||
567 | udelay(1); | ||
568 | /* raise clock */ | ||
569 | gpio |= VT1724_PRODIGY192_CCLK; | ||
570 | snd_ice1712_gpio_write(ice, gpio); | ||
571 | udelay(1); | ||
572 | } | ||
573 | } | ||
574 | |||
575 | /* | ||
576 | * 4wire ak4114 protocol - reading data | ||
577 | */ | ||
578 | static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, | ||
579 | int idx) | ||
580 | { | ||
581 | unsigned char data = 0; | ||
582 | |||
583 | for (; idx >= 0; idx--) { | ||
584 | /* drop clock */ | ||
585 | gpio &= ~VT1724_PRODIGY192_CCLK; | ||
586 | snd_ice1712_gpio_write(ice, gpio); | ||
587 | udelay(1); | ||
588 | /* read data */ | ||
589 | if (snd_ice1712_gpio_read(ice) & VT1724_PRODIGY192_CDIN) | ||
590 | data |= (1 << idx); | ||
591 | udelay(1); | ||
592 | /* raise clock */ | ||
593 | gpio |= VT1724_PRODIGY192_CCLK; | ||
594 | snd_ice1712_gpio_write(ice, gpio); | ||
595 | udelay(1); | ||
596 | } | ||
597 | return data; | ||
598 | } | ||
599 | /* | ||
600 | * 4wire ak4114 protocol - starting sequence | ||
601 | */ | ||
602 | static unsigned int prodigy192_4wire_start(struct snd_ice1712 *ice) | ||
603 | { | ||
604 | unsigned int tmp; | ||
605 | |||
606 | snd_ice1712_save_gpio_status(ice); | ||
607 | tmp = snd_ice1712_gpio_read(ice); | ||
608 | |||
609 | tmp |= VT1724_PRODIGY192_CCLK; /* high at init */ | ||
610 | tmp &= ~VT1724_PRODIGY192_CS; /* drop chip select */ | ||
611 | snd_ice1712_gpio_write(ice, tmp); | ||
612 | udelay(1); | ||
613 | return tmp; | ||
614 | } | ||
615 | |||
616 | /* | ||
617 | * 4wire ak4114 protocol - final sequence | ||
618 | */ | ||
619 | static void prodigy192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) | ||
620 | { | ||
621 | tmp |= VT1724_PRODIGY192_CS; /* raise chip select */ | ||
622 | snd_ice1712_gpio_write(ice, tmp); | ||
623 | udelay(1); | ||
624 | snd_ice1712_restore_gpio_status(ice); | ||
625 | } | ||
626 | |||
627 | /* | ||
628 | * Write data to addr register of ak4114 | ||
629 | */ | ||
630 | static void prodigy192_ak4114_write(void *private_data, unsigned char addr, | ||
631 | unsigned char data) | ||
632 | { | ||
633 | struct snd_ice1712 *ice = private_data; | ||
634 | unsigned int tmp, addrdata; | ||
635 | tmp = prodigy192_4wire_start(ice); | ||
636 | addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f); | ||
637 | addrdata = (addrdata << 8) | data; | ||
638 | write_data(ice, tmp, addrdata, 15); | ||
639 | prodigy192_4wire_finish(ice, tmp); | ||
640 | } | ||
641 | |||
642 | /* | ||
643 | * Read data from addr register of ak4114 | ||
644 | */ | ||
645 | static unsigned char prodigy192_ak4114_read(void *private_data, | ||
646 | unsigned char addr) | ||
647 | { | ||
648 | struct snd_ice1712 *ice = private_data; | ||
649 | unsigned int tmp; | ||
650 | unsigned char data; | ||
651 | |||
652 | tmp = prodigy192_4wire_start(ice); | ||
653 | write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7); | ||
654 | data = read_data(ice, tmp, 7); | ||
655 | prodigy192_4wire_finish(ice, tmp); | ||
656 | return data; | ||
657 | } | ||
658 | |||
659 | |||
660 | static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol, | ||
661 | struct snd_ctl_elem_info *uinfo) | ||
662 | { | ||
663 | static char *texts[2] = { "Toslink", "Coax" }; | ||
664 | |||
665 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
666 | uinfo->count = 1; | ||
667 | uinfo->value.enumerated.items = 2; | ||
668 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
669 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
670 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
671 | return 0; | ||
672 | } | ||
673 | |||
674 | |||
675 | static int ak4114_input_sw_get(struct snd_kcontrol *kcontrol, | ||
676 | struct snd_ctl_elem_value *ucontrol) | ||
677 | { | ||
678 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | ||
679 | unsigned char val; | ||
680 | |||
681 | val = prodigy192_ak4114_read(ice, AK4114_REG_IO1); | ||
682 | /* AK4114_IPS0 bit = 0 -> RX0 = Toslink | ||
683 | * AK4114_IPS0 bit = 1 -> RX1 = Coax | ||
684 | */ | ||
685 | ucontrol->value.enumerated.item[0] = (val & AK4114_IPS0) ? 1 : 0; | ||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol, | ||
690 | struct snd_ctl_elem_value *ucontrol) | ||
691 | { | ||
692 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | ||
693 | unsigned char new, old, itemvalue; | ||
694 | int change; | ||
695 | |||
696 | old = prodigy192_ak4114_read(ice, AK4114_REG_IO1); | ||
697 | /* AK4114_IPS0 could be any bit */ | ||
698 | itemvalue = (ucontrol->value.enumerated.item[0]) ? 0xff : 0x00; | ||
699 | |||
700 | new = (itemvalue & AK4114_IPS0) | (old & ~AK4114_IPS0); | ||
701 | change = (new != old); | ||
702 | if (change) | ||
703 | prodigy192_ak4114_write(ice, AK4114_REG_IO1, new); | ||
704 | return change; | ||
705 | } | ||
706 | |||
707 | |||
708 | static const struct snd_kcontrol_new ak4114_controls[] __devinitdata = { | ||
709 | { | ||
710 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
711 | .name = "MIODIO IEC958 Capture Input", | ||
712 | .info = ak4114_input_sw_info, | ||
713 | .get = ak4114_input_sw_get, | ||
714 | .put = ak4114_input_sw_put, | ||
715 | |||
716 | } | ||
717 | }; | ||
718 | |||
719 | |||
720 | static int prodigy192_ak4114_init(struct snd_ice1712 *ice) | ||
721 | { | ||
722 | static const unsigned char ak4114_init_vals[] = { | ||
723 | AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, | ||
724 | /* ice1724 expects I2S and provides clock, | ||
725 | * DEM0 disables the deemphasis filter | ||
726 | */ | ||
727 | AK4114_DIF_I24I2S | AK4114_DEM0 , | ||
728 | AK4114_TX1E, | ||
729 | AK4114_EFH_1024 | AK4114_DIT, /* default input RX0 */ | ||
730 | 0, | ||
731 | 0 | ||
732 | }; | ||
733 | static const unsigned char ak4114_init_txcsb[] = { | ||
734 | 0x41, 0x02, 0x2c, 0x00, 0x00 | ||
735 | }; | ||
736 | |||
737 | return snd_ak4114_create(ice->card, | ||
738 | prodigy192_ak4114_read, | ||
739 | prodigy192_ak4114_write, | ||
740 | ak4114_init_vals, ak4114_init_txcsb, | ||
741 | ice, &ice->spec.prodigy192.ak4114); | ||
742 | } | ||
743 | |||
459 | static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) | 744 | static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) |
460 | { | 745 | { |
461 | unsigned int i; | 746 | unsigned int i; |
462 | int err; | 747 | int err; |
463 | 748 | ||
464 | for (i = 0; i < ARRAY_SIZE(stac_controls); i++) { | 749 | for (i = 0; i < ARRAY_SIZE(stac_controls); i++) { |
465 | err = snd_ctl_add(ice->card, snd_ctl_new1(&stac_controls[i], ice)); | 750 | err = snd_ctl_add(ice->card, |
751 | snd_ctl_new1(&stac_controls[i], ice)); | ||
752 | if (err < 0) | ||
753 | return err; | ||
754 | } | ||
755 | if (ice->spec.prodigy192.ak4114) { | ||
756 | /* ak4114 is connected */ | ||
757 | for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) { | ||
758 | err = snd_ctl_add(ice->card, | ||
759 | snd_ctl_new1(&ak4114_controls[i], | ||
760 | ice)); | ||
761 | if (err < 0) | ||
762 | return err; | ||
763 | } | ||
764 | err = snd_ak4114_build(ice->spec.prodigy192.ak4114, | ||
765 | NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */ | ||
766 | ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); | ||
466 | if (err < 0) | 767 | if (err < 0) |
467 | return err; | 768 | return err; |
468 | } | 769 | } |
469 | return 0; | 770 | return 0; |
470 | } | 771 | } |
471 | 772 | ||
773 | /* | ||
774 | * check for presence of MI/ODI/O add-on card with digital inputs | ||
775 | */ | ||
776 | static int prodigy192_miodio_exists(struct snd_ice1712 *ice) | ||
777 | { | ||
778 | |||
779 | unsigned char orig_value; | ||
780 | const unsigned char test_data = 0xd1; /* random value */ | ||
781 | unsigned char addr = AK4114_REG_INT0_MASK; /* random SAFE address */ | ||
782 | int exists = 0; | ||
783 | |||
784 | orig_value = prodigy192_ak4114_read(ice, addr); | ||
785 | prodigy192_ak4114_write(ice, addr, test_data); | ||
786 | if (prodigy192_ak4114_read(ice, addr) == test_data) { | ||
787 | /* ak4114 seems to communicate, apparently exists */ | ||
788 | /* writing back original value */ | ||
789 | prodigy192_ak4114_write(ice, addr, orig_value); | ||
790 | exists = 1; | ||
791 | } | ||
792 | return exists; | ||
793 | } | ||
472 | 794 | ||
473 | /* | 795 | /* |
474 | * initialize the chip | 796 | * initialize the chip |
@@ -487,16 +809,30 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) | |||
487 | (unsigned short)-1 | 809 | (unsigned short)-1 |
488 | }; | 810 | }; |
489 | const unsigned short *p; | 811 | const unsigned short *p; |
812 | int err = 0; | ||
490 | 813 | ||
491 | /* prodigy 192 */ | 814 | /* prodigy 192 */ |
492 | ice->num_total_dacs = 6; | 815 | ice->num_total_dacs = 6; |
493 | ice->num_total_adcs = 2; | 816 | ice->num_total_adcs = 2; |
817 | ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */ | ||
494 | 818 | ||
495 | /* initialize codec */ | 819 | /* initialize codec */ |
496 | p = stac_inits_prodigy; | 820 | p = stac_inits_prodigy; |
497 | for (; *p != (unsigned short)-1; p += 2) | 821 | for (; *p != (unsigned short)-1; p += 2) |
498 | stac9460_put(ice, p[0], p[1]); | 822 | stac9460_put(ice, p[0], p[1]); |
499 | 823 | ||
824 | /* MI/ODI/O add on card with AK4114 */ | ||
825 | if (prodigy192_miodio_exists(ice)) { | ||
826 | err = prodigy192_ak4114_init(ice); | ||
827 | /* from this moment if err = 0 then | ||
828 | * ice->spec.prodigy192.ak4114 should not be null | ||
829 | */ | ||
830 | snd_printdd("AK4114 initialized with status %d\n", err); | ||
831 | } else | ||
832 | snd_printdd("AK4114 not found\n"); | ||
833 | if (err < 0) | ||
834 | return err; | ||
835 | |||
500 | return 0; | 836 | return 0; |
501 | } | 837 | } |
502 | 838 | ||
@@ -506,25 +842,31 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) | |||
506 | * hence the driver needs to sets up it properly. | 842 | * hence the driver needs to sets up it properly. |
507 | */ | 843 | */ |
508 | 844 | ||
509 | static const unsigned char prodigy71_eeprom[] __devinitdata = { | 845 | static unsigned char prodigy71_eeprom[] __devinitdata = { |
510 | [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC, 4DACs */ | 846 | [ICE_EEP2_SYSCONF] = 0x6a, /* 49MHz crystal, mpu401, |
847 | * spdif-in+ 1 stereo ADC, | ||
848 | * 3 stereo DACs | ||
849 | */ | ||
511 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ | 850 | [ICE_EEP2_ACLINK] = 0x80, /* I2S */ |
512 | [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ | 851 | [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ |
513 | [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ | 852 | [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ |
514 | [ICE_EEP2_GPIO_DIR] = 0xff, | 853 | [ICE_EEP2_GPIO_DIR] = 0xff, |
515 | [ICE_EEP2_GPIO_DIR1] = 0xff, | 854 | [ICE_EEP2_GPIO_DIR1] = ~(VT1724_PRODIGY192_CDIN >> 8) , |
516 | [ICE_EEP2_GPIO_DIR2] = 0xbf, | 855 | [ICE_EEP2_GPIO_DIR2] = 0xbf, |
517 | [ICE_EEP2_GPIO_MASK] = 0x00, | 856 | [ICE_EEP2_GPIO_MASK] = 0x00, |
518 | [ICE_EEP2_GPIO_MASK1] = 0x00, | 857 | [ICE_EEP2_GPIO_MASK1] = 0x00, |
519 | [ICE_EEP2_GPIO_MASK2] = 0x00, | 858 | [ICE_EEP2_GPIO_MASK2] = 0x00, |
520 | [ICE_EEP2_GPIO_STATE] = 0x00, | 859 | [ICE_EEP2_GPIO_STATE] = 0x00, |
521 | [ICE_EEP2_GPIO_STATE1] = 0x00, | 860 | [ICE_EEP2_GPIO_STATE1] = 0x00, |
522 | [ICE_EEP2_GPIO_STATE2] = 0x00, | 861 | [ICE_EEP2_GPIO_STATE2] = 0x10, /* GPIO20: 0 = CD drive dig. input |
862 | * passthrough, | ||
863 | * 1 = SPDIF-OUT from ice1724 | ||
864 | */ | ||
523 | }; | 865 | }; |
524 | 866 | ||
525 | 867 | ||
526 | /* entry point */ | 868 | /* entry point */ |
527 | const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { | 869 | struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { |
528 | { | 870 | { |
529 | .subvendor = VT1724_SUBDEVICE_PRODIGY192VE, | 871 | .subvendor = VT1724_SUBDEVICE_PRODIGY192VE, |
530 | .name = "Audiotrak Prodigy 192", | 872 | .name = "Audiotrak Prodigy 192", |
diff --git a/sound/pci/ice1712/prodigy192.h b/sound/pci/ice1712/prodigy192.h index 2fa2e62b9e04..16a53b459c72 100644 --- a/sound/pci/ice1712/prodigy192.h +++ b/sound/pci/ice1712/prodigy192.h | |||
@@ -5,7 +5,15 @@ | |||
5 | #define PRODIGY192_STAC9460_ADDR 0x54 | 5 | #define PRODIGY192_STAC9460_ADDR 0x54 |
6 | 6 | ||
7 | #define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */ | 7 | #define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */ |
8 | /* | ||
9 | * AudioTrak Prodigy192 GPIO definitions for MI/ODI/O card with | ||
10 | * AK4114 (SPDIF-IN) | ||
11 | */ | ||
12 | #define VT1724_PRODIGY192_CS (1 << 8) /* GPIO8, pin 75 */ | ||
13 | #define VT1724_PRODIGY192_CCLK (1 << 9) /* GPIO9, pin 76 */ | ||
14 | #define VT1724_PRODIGY192_CDOUT (1 << 10) /* GPIO10, pin 77 */ | ||
15 | #define VT1724_PRODIGY192_CDIN (1 << 11) /* GPIO11, pin 86 */ | ||
8 | 16 | ||
9 | extern const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[]; | 17 | extern struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[]; |
10 | 18 | ||
11 | #endif /* __SOUND_PRODIGY192_H */ | 19 | #endif /* __SOUND_PRODIGY192_H */ |
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 025a7e8497c3..690ceb340644 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c | |||
@@ -219,7 +219,7 @@ static const struct snd_akm4xxx_adc_channel revo51_adc[] = { | |||
219 | }, | 219 | }, |
220 | }; | 220 | }; |
221 | 221 | ||
222 | static const struct snd_akm4xxx akm_revo_front __devinitdata = { | 222 | static struct snd_akm4xxx akm_revo_front __devinitdata = { |
223 | .type = SND_AK4381, | 223 | .type = SND_AK4381, |
224 | .num_dacs = 2, | 224 | .num_dacs = 2, |
225 | .ops = { | 225 | .ops = { |
@@ -228,7 +228,7 @@ static const struct snd_akm4xxx akm_revo_front __devinitdata = { | |||
228 | .dac_info = revo71_front, | 228 | .dac_info = revo71_front, |
229 | }; | 229 | }; |
230 | 230 | ||
231 | static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { | 231 | static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { |
232 | .caddr = 1, | 232 | .caddr = 1, |
233 | .cif = 0, | 233 | .cif = 0, |
234 | .data_mask = VT1724_REVO_CDOUT, | 234 | .data_mask = VT1724_REVO_CDOUT, |
@@ -240,7 +240,7 @@ static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { | |||
240 | .mask_flags = 0, | 240 | .mask_flags = 0, |
241 | }; | 241 | }; |
242 | 242 | ||
243 | static const struct snd_akm4xxx akm_revo_surround __devinitdata = { | 243 | static struct snd_akm4xxx akm_revo_surround __devinitdata = { |
244 | .type = SND_AK4355, | 244 | .type = SND_AK4355, |
245 | .idx_offset = 1, | 245 | .idx_offset = 1, |
246 | .num_dacs = 6, | 246 | .num_dacs = 6, |
@@ -250,7 +250,7 @@ static const struct snd_akm4xxx akm_revo_surround __devinitdata = { | |||
250 | .dac_info = revo71_surround, | 250 | .dac_info = revo71_surround, |
251 | }; | 251 | }; |
252 | 252 | ||
253 | static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { | 253 | static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { |
254 | .caddr = 3, | 254 | .caddr = 3, |
255 | .cif = 0, | 255 | .cif = 0, |
256 | .data_mask = VT1724_REVO_CDOUT, | 256 | .data_mask = VT1724_REVO_CDOUT, |
@@ -262,7 +262,7 @@ static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { | |||
262 | .mask_flags = 0, | 262 | .mask_flags = 0, |
263 | }; | 263 | }; |
264 | 264 | ||
265 | static const struct snd_akm4xxx akm_revo51 __devinitdata = { | 265 | static struct snd_akm4xxx akm_revo51 __devinitdata = { |
266 | .type = SND_AK4358, | 266 | .type = SND_AK4358, |
267 | .num_dacs = 6, | 267 | .num_dacs = 6, |
268 | .ops = { | 268 | .ops = { |
@@ -271,7 +271,7 @@ static const struct snd_akm4xxx akm_revo51 __devinitdata = { | |||
271 | .dac_info = revo51_dac, | 271 | .dac_info = revo51_dac, |
272 | }; | 272 | }; |
273 | 273 | ||
274 | static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { | 274 | static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { |
275 | .caddr = 2, | 275 | .caddr = 2, |
276 | .cif = 0, | 276 | .cif = 0, |
277 | .data_mask = VT1724_REVO_CDOUT, | 277 | .data_mask = VT1724_REVO_CDOUT, |
@@ -283,13 +283,13 @@ static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { | |||
283 | .mask_flags = 0, | 283 | .mask_flags = 0, |
284 | }; | 284 | }; |
285 | 285 | ||
286 | static const struct snd_akm4xxx akm_revo51_adc __devinitdata = { | 286 | static struct snd_akm4xxx akm_revo51_adc __devinitdata = { |
287 | .type = SND_AK5365, | 287 | .type = SND_AK5365, |
288 | .num_adcs = 2, | 288 | .num_adcs = 2, |
289 | .adc_info = revo51_adc, | 289 | .adc_info = revo51_adc, |
290 | }; | 290 | }; |
291 | 291 | ||
292 | static const struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { | 292 | static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { |
293 | .caddr = 2, | 293 | .caddr = 2, |
294 | .cif = 0, | 294 | .cif = 0, |
295 | .data_mask = VT1724_REVO_CDOUT, | 295 | .data_mask = VT1724_REVO_CDOUT, |
@@ -324,7 +324,7 @@ static const struct snd_akm4xxx_dac_channel ap192_dac[] = { | |||
324 | AK_DAC("PCM Playback Volume", 2) | 324 | AK_DAC("PCM Playback Volume", 2) |
325 | }; | 325 | }; |
326 | 326 | ||
327 | static const struct snd_akm4xxx akm_ap192 __devinitdata = { | 327 | static struct snd_akm4xxx akm_ap192 __devinitdata = { |
328 | .type = SND_AK4358, | 328 | .type = SND_AK4358, |
329 | .num_dacs = 2, | 329 | .num_dacs = 2, |
330 | .ops = { | 330 | .ops = { |
@@ -333,7 +333,7 @@ static const struct snd_akm4xxx akm_ap192 __devinitdata = { | |||
333 | .dac_info = ap192_dac, | 333 | .dac_info = ap192_dac, |
334 | }; | 334 | }; |
335 | 335 | ||
336 | static const struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { | 336 | static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { |
337 | .caddr = 2, | 337 | .caddr = 2, |
338 | .cif = 0, | 338 | .cif = 0, |
339 | .data_mask = VT1724_REVO_CDOUT, | 339 | .data_mask = VT1724_REVO_CDOUT, |
@@ -405,7 +405,7 @@ static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, | |||
405 | return data; | 405 | return data; |
406 | } | 406 | } |
407 | 407 | ||
408 | static unsigned char ap192_4wire_start(struct snd_ice1712 *ice) | 408 | static unsigned int ap192_4wire_start(struct snd_ice1712 *ice) |
409 | { | 409 | { |
410 | unsigned int tmp; | 410 | unsigned int tmp; |
411 | 411 | ||
@@ -454,7 +454,7 @@ static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr) | |||
454 | return data; | 454 | return data; |
455 | } | 455 | } |
456 | 456 | ||
457 | static int ap192_ak4114_init(struct snd_ice1712 *ice) | 457 | static int __devinit ap192_ak4114_init(struct snd_ice1712 *ice) |
458 | { | 458 | { |
459 | static const unsigned char ak4114_init_vals[] = { | 459 | static const unsigned char ak4114_init_vals[] = { |
460 | AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, | 460 | AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, |
@@ -582,7 +582,7 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice) | |||
582 | } | 582 | } |
583 | 583 | ||
584 | /* entry point */ | 584 | /* entry point */ |
585 | const struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { | 585 | struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { |
586 | { | 586 | { |
587 | .subvendor = VT1724_SUBDEVICE_REVOLUTION71, | 587 | .subvendor = VT1724_SUBDEVICE_REVOLUTION71, |
588 | .name = "M Audio Revolution-7.1", | 588 | .name = "M Audio Revolution-7.1", |
diff --git a/sound/pci/ice1712/revo.h b/sound/pci/ice1712/revo.h index 2a24488fad80..a3ba425911cc 100644 --- a/sound/pci/ice1712/revo.h +++ b/sound/pci/ice1712/revo.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #define VT1724_SUBDEVICE_AUDIOPHILE192 0x12143236 | 34 | #define VT1724_SUBDEVICE_AUDIOPHILE192 0x12143236 |
35 | 35 | ||
36 | /* entry point */ | 36 | /* entry point */ |
37 | extern const struct snd_ice1712_card_info snd_vt1724_revo_cards[]; | 37 | extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; |
38 | 38 | ||
39 | 39 | ||
40 | /* | 40 | /* |
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c index 72b060d63c29..239524158fe7 100644 --- a/sound/pci/ice1712/vt1720_mobo.c +++ b/sound/pci/ice1712/vt1720_mobo.c | |||
@@ -56,7 +56,7 @@ static int __devinit k8x800_add_controls(struct snd_ice1712 *ice) | |||
56 | 56 | ||
57 | /* EEPROM image */ | 57 | /* EEPROM image */ |
58 | 58 | ||
59 | static const unsigned char k8x800_eeprom[] __devinitdata = { | 59 | static unsigned char k8x800_eeprom[] __devinitdata = { |
60 | [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ | 60 | [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ |
61 | [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ | 61 | [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ |
62 | [ICE_EEP2_I2S] = 0x00, /* - */ | 62 | [ICE_EEP2_I2S] = 0x00, /* - */ |
@@ -72,7 +72,7 @@ static const unsigned char k8x800_eeprom[] __devinitdata = { | |||
72 | [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */ | 72 | [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */ |
73 | }; | 73 | }; |
74 | 74 | ||
75 | static const unsigned char sn25p_eeprom[] __devinitdata = { | 75 | static unsigned char sn25p_eeprom[] __devinitdata = { |
76 | [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ | 76 | [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ |
77 | [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ | 77 | [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ |
78 | [ICE_EEP2_I2S] = 0x00, /* - */ | 78 | [ICE_EEP2_I2S] = 0x00, /* - */ |
@@ -90,7 +90,7 @@ static const unsigned char sn25p_eeprom[] __devinitdata = { | |||
90 | 90 | ||
91 | 91 | ||
92 | /* entry point */ | 92 | /* entry point */ |
93 | const struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { | 93 | struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { |
94 | { | 94 | { |
95 | .subvendor = VT1720_SUBDEVICE_K8X800, | 95 | .subvendor = VT1720_SUBDEVICE_K8X800, |
96 | .name = "Albatron K8X800 Pro II", | 96 | .name = "Albatron K8X800 Pro II", |
diff --git a/sound/pci/ice1712/vt1720_mobo.h b/sound/pci/ice1712/vt1720_mobo.h index 70af3ad64a5d..0b1b0ee1bea7 100644 --- a/sound/pci/ice1712/vt1720_mobo.h +++ b/sound/pci/ice1712/vt1720_mobo.h | |||
@@ -36,6 +36,6 @@ | |||
36 | #define VT1720_SUBDEVICE_9CJS 0x0f272327 | 36 | #define VT1720_SUBDEVICE_9CJS 0x0f272327 |
37 | #define VT1720_SUBDEVICE_SN25P 0x97123650 | 37 | #define VT1720_SUBDEVICE_SN25P 0x97123650 |
38 | 38 | ||
39 | extern const struct snd_ice1712_card_info snd_vt1720_mobo_cards[]; | 39 | extern struct snd_ice1712_card_info snd_vt1720_mobo_cards[]; |
40 | 40 | ||
41 | #endif /* __SOUND_VT1720_MOBO_H */ | 41 | #endif /* __SOUND_VT1720_MOBO_H */ |
diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c index 4a706b16a0b9..04e535c8542b 100644 --- a/sound/pci/ice1712/wtm.c +++ b/sound/pci/ice1712/wtm.c | |||
@@ -409,7 +409,7 @@ static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, | |||
409 | /* | 409 | /* |
410 | * Control tabs | 410 | * Control tabs |
411 | */ | 411 | */ |
412 | static const struct snd_kcontrol_new stac9640_controls[] __devinitdata = { | 412 | static struct snd_kcontrol_new stac9640_controls[] __devinitdata = { |
413 | { | 413 | { |
414 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 414 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
415 | .name = "Master Playback Switch", | 415 | .name = "Master Playback Switch", |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 7cf2dcb9d8d4..202f720b34b9 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -2493,6 +2493,7 @@ static int intel8x0_resume(struct pci_dev *pci) | |||
2493 | return -EIO; | 2493 | return -EIO; |
2494 | } | 2494 | } |
2495 | pci_set_master(pci); | 2495 | pci_set_master(pci); |
2496 | snd_intel8x0_chip_init(chip, 0); | ||
2496 | if (request_irq(pci->irq, snd_intel8x0_interrupt, | 2497 | if (request_irq(pci->irq, snd_intel8x0_interrupt, |
2497 | IRQF_SHARED, card->shortname, chip)) { | 2498 | IRQF_SHARED, card->shortname, chip)) { |
2498 | printk(KERN_ERR "intel8x0: unable to grab IRQ %d, " | 2499 | printk(KERN_ERR "intel8x0: unable to grab IRQ %d, " |
@@ -2502,7 +2503,6 @@ static int intel8x0_resume(struct pci_dev *pci) | |||
2502 | } | 2503 | } |
2503 | chip->irq = pci->irq; | 2504 | chip->irq = pci->irq; |
2504 | synchronize_irq(chip->irq); | 2505 | synchronize_irq(chip->irq); |
2505 | snd_intel8x0_chip_init(chip, 0); | ||
2506 | 2506 | ||
2507 | /* re-initialize mixer stuff */ | 2507 | /* re-initialize mixer stuff */ |
2508 | if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) { | 2508 | if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) { |
@@ -2862,16 +2862,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, | |||
2862 | ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA; | 2862 | ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA; |
2863 | chip->int_sta_mask = int_sta_masks; | 2863 | chip->int_sta_mask = int_sta_masks; |
2864 | 2864 | ||
2865 | /* request irq after initializaing int_sta_mask, etc */ | ||
2866 | if (request_irq(pci->irq, snd_intel8x0_interrupt, | ||
2867 | IRQF_SHARED, card->shortname, chip)) { | ||
2868 | snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); | ||
2869 | snd_intel8x0_free(chip); | ||
2870 | return -EBUSY; | ||
2871 | } | ||
2872 | chip->irq = pci->irq; | ||
2873 | pci_set_master(pci); | 2865 | pci_set_master(pci); |
2874 | synchronize_irq(chip->irq); | ||
2875 | 2866 | ||
2876 | switch(chip->device_type) { | 2867 | switch(chip->device_type) { |
2877 | case DEVICE_INTEL_ICH4: | 2868 | case DEVICE_INTEL_ICH4: |
@@ -2901,6 +2892,15 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, | |||
2901 | return err; | 2892 | return err; |
2902 | } | 2893 | } |
2903 | 2894 | ||
2895 | /* request irq after initializaing int_sta_mask, etc */ | ||
2896 | if (request_irq(pci->irq, snd_intel8x0_interrupt, | ||
2897 | IRQF_SHARED, card->shortname, chip)) { | ||
2898 | snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); | ||
2899 | snd_intel8x0_free(chip); | ||
2900 | return -EBUSY; | ||
2901 | } | ||
2902 | chip->irq = pci->irq; | ||
2903 | |||
2904 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | 2904 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { |
2905 | snd_intel8x0_free(chip); | 2905 | snd_intel8x0_free(chip); |
2906 | return err; | 2906 | return err; |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 21d0899ac382..5338243fb035 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
@@ -264,9 +264,7 @@ enum MonitorModeSelector { | |||
264 | #define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement | 264 | #define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement |
265 | // from the card after sending a command. | 265 | // from the card after sending a command. |
266 | 266 | ||
267 | #define FIRMWARE_IN_THE_KERNEL | 267 | #ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL |
268 | |||
269 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
270 | #include "korg1212-firmware.h" | 268 | #include "korg1212-firmware.h" |
271 | static const struct firmware static_dsp_code = { | 269 | static const struct firmware static_dsp_code = { |
272 | .data = (u8 *)dspCode, | 270 | .data = (u8 *)dspCode, |
@@ -418,6 +416,9 @@ struct snd_korg1212 { | |||
418 | MODULE_DESCRIPTION("korg1212"); | 416 | MODULE_DESCRIPTION("korg1212"); |
419 | MODULE_LICENSE("GPL"); | 417 | MODULE_LICENSE("GPL"); |
420 | MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}"); | 418 | MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}"); |
419 | #ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL | ||
420 | MODULE_FIRMWARE("korg/k1212.dsp"); | ||
421 | #endif | ||
421 | 422 | ||
422 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 423 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
423 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 424 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
@@ -2342,26 +2343,25 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * | |||
2342 | korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy + | 2343 | korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy + |
2343 | offsetof(struct KorgSharedBuffer, AdatTimeCode); | 2344 | offsetof(struct KorgSharedBuffer, AdatTimeCode); |
2344 | 2345 | ||
2346 | #ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL | ||
2347 | dsp_code = &static_dsp_code; | ||
2348 | #else | ||
2345 | err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); | 2349 | err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); |
2346 | if (err < 0) { | 2350 | if (err < 0) { |
2347 | release_firmware(dsp_code); | 2351 | release_firmware(dsp_code); |
2348 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
2349 | dsp_code = &static_dsp_code; | ||
2350 | #else | ||
2351 | snd_printk(KERN_ERR "firmware not available\n"); | 2352 | snd_printk(KERN_ERR "firmware not available\n"); |
2352 | snd_korg1212_free(korg1212); | 2353 | snd_korg1212_free(korg1212); |
2353 | return err; | 2354 | return err; |
2354 | #endif | ||
2355 | } | 2355 | } |
2356 | #endif | ||
2356 | 2357 | ||
2357 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), | 2358 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), |
2358 | dsp_code->size, &korg1212->dma_dsp) < 0) { | 2359 | dsp_code->size, &korg1212->dma_dsp) < 0) { |
2359 | snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size); | 2360 | snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size); |
2360 | snd_korg1212_free(korg1212); | 2361 | snd_korg1212_free(korg1212); |
2361 | #ifdef FIRMWARE_IN_THE_KERNEL | 2362 | #ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL |
2362 | if (dsp_code != &static_dsp_code) | 2363 | release_firmware(dsp_code); |
2363 | #endif | 2364 | #endif |
2364 | release_firmware(dsp_code); | ||
2365 | return -ENOMEM; | 2365 | return -ENOMEM; |
2366 | } | 2366 | } |
2367 | 2367 | ||
@@ -2371,10 +2371,9 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * | |||
2371 | 2371 | ||
2372 | memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size); | 2372 | memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size); |
2373 | 2373 | ||
2374 | #ifdef FIRMWARE_IN_THE_KERNEL | 2374 | #ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL |
2375 | if (dsp_code != &static_dsp_code) | 2375 | release_firmware(dsp_code); |
2376 | #endif | 2376 | #endif |
2377 | release_firmware(dsp_code); | ||
2378 | 2377 | ||
2379 | rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0); | 2378 | rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0); |
2380 | 2379 | ||
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 4526904e3f86..8a5ff1cb5362 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -59,6 +59,10 @@ MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI}," | |||
59 | "{ESS,Allegro PCI}," | 59 | "{ESS,Allegro PCI}," |
60 | "{ESS,Allegro-1 PCI}," | 60 | "{ESS,Allegro-1 PCI}," |
61 | "{ESS,Canyon3D-2/LE PCI}}"); | 61 | "{ESS,Canyon3D-2/LE PCI}}"); |
62 | #ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL | ||
63 | MODULE_FIRMWARE("ess/maestro3_assp_kernel.fw"); | ||
64 | MODULE_FIRMWARE("ess/maestro3_assp_minisrc.fw"); | ||
65 | #endif | ||
62 | 66 | ||
63 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 67 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
64 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 68 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
@@ -2101,9 +2105,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) | |||
2101 | } | 2105 | } |
2102 | 2106 | ||
2103 | 2107 | ||
2104 | #define FIRMWARE_IN_THE_KERNEL | 2108 | #ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL |
2105 | |||
2106 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
2107 | 2109 | ||
2108 | /* | 2110 | /* |
2109 | * DSP Code images | 2111 | * DSP Code images |
@@ -2242,7 +2244,7 @@ static const struct firmware assp_minisrc = { | |||
2242 | .size = sizeof assp_minisrc_image | 2244 | .size = sizeof assp_minisrc_image |
2243 | }; | 2245 | }; |
2244 | 2246 | ||
2245 | #endif /* FIRMWARE_IN_THE_KERNEL */ | 2247 | #else /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */ |
2246 | 2248 | ||
2247 | #ifdef __LITTLE_ENDIAN | 2249 | #ifdef __LITTLE_ENDIAN |
2248 | static inline void snd_m3_convert_from_le(const struct firmware *fw) { } | 2250 | static inline void snd_m3_convert_from_le(const struct firmware *fw) { } |
@@ -2257,6 +2259,8 @@ static void snd_m3_convert_from_le(const struct firmware *fw) | |||
2257 | } | 2259 | } |
2258 | #endif | 2260 | #endif |
2259 | 2261 | ||
2262 | #endif /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */ | ||
2263 | |||
2260 | 2264 | ||
2261 | /* | 2265 | /* |
2262 | * initialize ASSP | 2266 | * initialize ASSP |
@@ -2550,14 +2554,10 @@ static int snd_m3_free(struct snd_m3 *chip) | |||
2550 | if (chip->iobase) | 2554 | if (chip->iobase) |
2551 | pci_release_regions(chip->pci); | 2555 | pci_release_regions(chip->pci); |
2552 | 2556 | ||
2553 | #ifdef FIRMWARE_IN_THE_KERNEL | 2557 | #ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL |
2554 | if (chip->assp_kernel_image != &assp_kernel) | 2558 | release_firmware(chip->assp_kernel_image); |
2559 | release_firmware(chip->assp_minisrc_image); | ||
2555 | #endif | 2560 | #endif |
2556 | release_firmware(chip->assp_kernel_image); | ||
2557 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
2558 | if (chip->assp_minisrc_image != &assp_minisrc) | ||
2559 | #endif | ||
2560 | release_firmware(chip->assp_minisrc_image); | ||
2561 | 2561 | ||
2562 | pci_disable_device(chip->pci); | 2562 | pci_disable_device(chip->pci); |
2563 | kfree(chip); | 2563 | kfree(chip); |
@@ -2747,29 +2747,29 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, | |||
2747 | return -ENOMEM; | 2747 | return -ENOMEM; |
2748 | } | 2748 | } |
2749 | 2749 | ||
2750 | #ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL | ||
2751 | chip->assp_kernel_image = &assp_kernel; | ||
2752 | #else | ||
2750 | err = request_firmware(&chip->assp_kernel_image, | 2753 | err = request_firmware(&chip->assp_kernel_image, |
2751 | "ess/maestro3_assp_kernel.fw", &pci->dev); | 2754 | "ess/maestro3_assp_kernel.fw", &pci->dev); |
2752 | if (err < 0) { | 2755 | if (err < 0) { |
2753 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
2754 | chip->assp_kernel_image = &assp_kernel; | ||
2755 | #else | ||
2756 | snd_m3_free(chip); | 2756 | snd_m3_free(chip); |
2757 | return err; | 2757 | return err; |
2758 | #endif | ||
2759 | } else | 2758 | } else |
2760 | snd_m3_convert_from_le(chip->assp_kernel_image); | 2759 | snd_m3_convert_from_le(chip->assp_kernel_image); |
2760 | #endif | ||
2761 | 2761 | ||
2762 | #ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL | ||
2763 | chip->assp_minisrc_image = &assp_minisrc; | ||
2764 | #else | ||
2762 | err = request_firmware(&chip->assp_minisrc_image, | 2765 | err = request_firmware(&chip->assp_minisrc_image, |
2763 | "ess/maestro3_assp_minisrc.fw", &pci->dev); | 2766 | "ess/maestro3_assp_minisrc.fw", &pci->dev); |
2764 | if (err < 0) { | 2767 | if (err < 0) { |
2765 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
2766 | chip->assp_minisrc_image = &assp_minisrc; | ||
2767 | #else | ||
2768 | snd_m3_free(chip); | 2768 | snd_m3_free(chip); |
2769 | return err; | 2769 | return err; |
2770 | #endif | ||
2771 | } else | 2770 | } else |
2772 | snd_m3_convert_from_le(chip->assp_minisrc_image); | 2771 | snd_m3_convert_from_le(chip->assp_minisrc_image); |
2772 | #endif | ||
2773 | 2773 | ||
2774 | if ((err = pci_request_regions(pci, card->driver)) < 0) { | 2774 | if ((err = pci_request_regions(pci, card->driver)) < 0) { |
2775 | snd_m3_free(chip); | 2775 | snd_m3_free(chip); |
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c index ca05075c67c6..1d9232d2db34 100644 --- a/sound/pci/mixart/mixart_hwdep.c +++ b/sound/pci/mixart/mixart_hwdep.c | |||
@@ -565,6 +565,9 @@ int snd_mixart_setup_firmware(struct mixart_mgr *mgr) | |||
565 | return 0; | 565 | return 0; |
566 | } | 566 | } |
567 | 567 | ||
568 | MODULE_FIRMWARE("mixart/miXart8.xlx"); | ||
569 | MODULE_FIRMWARE("mixart/miXart8.elf"); | ||
570 | MODULE_FIRMWARE("mixart/miXart8AES.xlx"); | ||
568 | 571 | ||
569 | #else /* old style firmware loading */ | 572 | #else /* old style firmware loading */ |
570 | 573 | ||
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index d97413484ae9..f7f6a687f033 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c | |||
@@ -638,22 +638,22 @@ static void pcxhr_trigger_tasklet(unsigned long arg) | |||
638 | static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) | 638 | static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) |
639 | { | 639 | { |
640 | struct pcxhr_stream *stream; | 640 | struct pcxhr_stream *stream; |
641 | struct list_head *pos; | ||
642 | struct snd_pcm_substream *s; | 641 | struct snd_pcm_substream *s; |
643 | int i; | ||
644 | 642 | ||
645 | switch (cmd) { | 643 | switch (cmd) { |
646 | case SNDRV_PCM_TRIGGER_START: | 644 | case SNDRV_PCM_TRIGGER_START: |
647 | snd_printdd("SNDRV_PCM_TRIGGER_START\n"); | 645 | snd_printdd("SNDRV_PCM_TRIGGER_START\n"); |
648 | i = 0; | 646 | if (snd_pcm_stream_linked(subs)) { |
649 | snd_pcm_group_for_each(pos, subs) { | 647 | struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); |
650 | s = snd_pcm_group_substream_entry(pos); | 648 | snd_pcm_group_for_each_entry(s, subs) { |
651 | stream = s->runtime->private_data; | 649 | stream = s->runtime->private_data; |
652 | stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN; | 650 | stream->status = |
653 | snd_pcm_trigger_done(s, subs); | 651 | PCXHR_STREAM_STATUS_SCHEDULE_RUN; |
654 | i++; | 652 | snd_pcm_trigger_done(s, subs); |
655 | } | 653 | } |
656 | if (i==1) { | 654 | tasklet_hi_schedule(&chip->mgr->trigger_taskq); |
655 | } else { | ||
656 | stream = subs->runtime->private_data; | ||
657 | snd_printdd("Only one Substream %c %d\n", | 657 | snd_printdd("Only one Substream %c %d\n", |
658 | stream->pipe->is_capture ? 'C' : 'P', | 658 | stream->pipe->is_capture ? 'C' : 'P', |
659 | stream->pipe->first_audio); | 659 | stream->pipe->first_audio); |
@@ -665,15 +665,11 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) | |||
665 | if (pcxhr_set_stream_state(stream)) | 665 | if (pcxhr_set_stream_state(stream)) |
666 | return -EINVAL; | 666 | return -EINVAL; |
667 | stream->status = PCXHR_STREAM_STATUS_RUNNING; | 667 | stream->status = PCXHR_STREAM_STATUS_RUNNING; |
668 | } else { | ||
669 | struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); | ||
670 | tasklet_hi_schedule(&chip->mgr->trigger_taskq); | ||
671 | } | 668 | } |
672 | break; | 669 | break; |
673 | case SNDRV_PCM_TRIGGER_STOP: | 670 | case SNDRV_PCM_TRIGGER_STOP: |
674 | snd_printdd("SNDRV_PCM_TRIGGER_STOP\n"); | 671 | snd_printdd("SNDRV_PCM_TRIGGER_STOP\n"); |
675 | snd_pcm_group_for_each(pos, subs) { | 672 | snd_pcm_group_for_each_entry(s, subs) { |
676 | s = snd_pcm_group_substream_entry(pos); | ||
677 | stream = s->runtime->private_data; | 673 | stream = s->runtime->private_data; |
678 | stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP; | 674 | stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP; |
679 | if (pcxhr_set_stream_state(stream)) | 675 | if (pcxhr_set_stream_state(stream)) |
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c index 369c19fea985..d55d8bc90eee 100644 --- a/sound/pci/pcxhr/pcxhr_hwdep.c +++ b/sound/pci/pcxhr/pcxhr_hwdep.c | |||
@@ -356,6 +356,12 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) | |||
356 | return 0; | 356 | return 0; |
357 | } | 357 | } |
358 | 358 | ||
359 | MODULE_FIRMWARE("pcxhr/xi_1_882.dat"); | ||
360 | MODULE_FIRMWARE("pcxhr/xc_1_882.dat"); | ||
361 | MODULE_FIRMWARE("pcxhr/e321_512.e56"); | ||
362 | MODULE_FIRMWARE("pcxhr/b321_512.b56"); | ||
363 | MODULE_FIRMWARE("pcxhr/d321_512.d56"); | ||
364 | |||
359 | #else /* old style firmware loading */ | 365 | #else /* old style firmware loading */ |
360 | 366 | ||
361 | /* pcxhr hwdep interface id string */ | 367 | /* pcxhr hwdep interface id string */ |
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 952625dead58..8e5410483e67 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c | |||
@@ -117,6 +117,7 @@ MODULE_AUTHOR("Peter Gruber <nokos@gmx.net>"); | |||
117 | MODULE_DESCRIPTION("riptide"); | 117 | MODULE_DESCRIPTION("riptide"); |
118 | MODULE_LICENSE("GPL"); | 118 | MODULE_LICENSE("GPL"); |
119 | MODULE_SUPPORTED_DEVICE("{{Conexant,Riptide}}"); | 119 | MODULE_SUPPORTED_DEVICE("{{Conexant,Riptide}}"); |
120 | MODULE_FIRMWARE("riptide.hex"); | ||
120 | 121 | ||
121 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | 122 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; |
122 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | 123 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; |
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index 6bb7ac650ec4..618653e22561 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c | |||
@@ -1078,12 +1078,10 @@ static int | |||
1078 | snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | 1078 | snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd) |
1079 | { | 1079 | { |
1080 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); | 1080 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); |
1081 | struct list_head *pos; | ||
1082 | struct snd_pcm_substream *s; | 1081 | struct snd_pcm_substream *s; |
1083 | 1082 | ||
1084 | spin_lock(&rme32->lock); | 1083 | spin_lock(&rme32->lock); |
1085 | snd_pcm_group_for_each(pos, substream) { | 1084 | snd_pcm_group_for_each_entry(s, substream) { |
1086 | s = snd_pcm_group_substream_entry(pos); | ||
1087 | if (s != rme32->playback_substream && | 1085 | if (s != rme32->playback_substream && |
1088 | s != rme32->capture_substream) | 1086 | s != rme32->capture_substream) |
1089 | continue; | 1087 | continue; |
@@ -1110,8 +1108,7 @@ snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1110 | 1108 | ||
1111 | /* prefill playback buffer */ | 1109 | /* prefill playback buffer */ |
1112 | if (cmd == SNDRV_PCM_TRIGGER_START && rme32->fullduplex_mode) { | 1110 | if (cmd == SNDRV_PCM_TRIGGER_START && rme32->fullduplex_mode) { |
1113 | snd_pcm_group_for_each(pos, substream) { | 1111 | snd_pcm_group_for_each_entry(s, substream) { |
1114 | s = snd_pcm_group_substream_entry(pos); | ||
1115 | if (s == rme32->playback_substream) { | 1112 | if (s == rme32->playback_substream) { |
1116 | s->ops->ack(s); | 1113 | s->ops->ack(s); |
1117 | break; | 1114 | break; |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 89b3c7ff5037..3b3ef657f73e 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -60,6 +60,12 @@ MODULE_LICENSE("GPL"); | |||
60 | MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," | 60 | MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," |
61 | "{RME HDSP-9652}," | 61 | "{RME HDSP-9652}," |
62 | "{RME HDSP-9632}}"); | 62 | "{RME HDSP-9632}}"); |
63 | #ifdef HDSP_FW_LOADER | ||
64 | MODULE_FIRMWARE("multiface_firmware.bin"); | ||
65 | MODULE_FIRMWARE("multiface_firmware_rev11.bin"); | ||
66 | MODULE_FIRMWARE("digiface_firmware.bin"); | ||
67 | MODULE_FIRMWARE("digiface_firmware_rev11.bin"); | ||
68 | #endif | ||
63 | 69 | ||
64 | #define HDSP_MAX_CHANNELS 26 | 70 | #define HDSP_MAX_CHANNELS 26 |
65 | #define HDSP_MAX_DS_CHANNELS 14 | 71 | #define HDSP_MAX_DS_CHANNELS 14 |
@@ -275,6 +281,11 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," | |||
275 | #define HDSP_Frequency128KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0) | 281 | #define HDSP_Frequency128KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0) |
276 | #define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1) | 282 | #define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1) |
277 | #define HDSP_Frequency192KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0) | 283 | #define HDSP_Frequency192KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0) |
284 | /* RME says n = 104857600000000, but in the windows MADI driver, I see: | ||
285 | return 104857600000000 / rate; // 100 MHz | ||
286 | return 110100480000000 / rate; // 105 MHz | ||
287 | */ | ||
288 | #define DDS_NUMERATOR 104857600000000ULL; /* = 2^20 * 10^8 */ | ||
278 | 289 | ||
279 | #define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask) | 290 | #define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask) |
280 | #define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1) | 291 | #define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1) |
@@ -1001,11 +1012,7 @@ static void hdsp_set_dds_value(struct hdsp *hdsp, int rate) | |||
1001 | else if (rate >= 56000) | 1012 | else if (rate >= 56000) |
1002 | rate /= 2; | 1013 | rate /= 2; |
1003 | 1014 | ||
1004 | /* RME says n = 104857600000000, but in the windows MADI driver, I see: | 1015 | n = DDS_NUMERATOR; |
1005 | // return 104857600000000 / rate; // 100 MHz | ||
1006 | return 110100480000000 / rate; // 105 MHz | ||
1007 | */ | ||
1008 | n = 104857600000000ULL; /* = 2^20 * 10^8 */ | ||
1009 | div64_32(&n, rate, &r); | 1016 | div64_32(&n, rate, &r); |
1010 | /* n should be less than 2^32 for being written to FREQ register */ | 1017 | /* n should be less than 2^32 for being written to FREQ register */ |
1011 | snd_assert((n >> 32) == 0); | 1018 | snd_assert((n >> 32) == 0); |
@@ -3085,11 +3092,83 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn | |||
3085 | return 0; | 3092 | return 0; |
3086 | } | 3093 | } |
3087 | 3094 | ||
3095 | #define HDSP_DDS_OFFSET(xname, xindex) \ | ||
3096 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
3097 | .name = xname, \ | ||
3098 | .index = xindex, \ | ||
3099 | .info = snd_hdsp_info_dds_offset, \ | ||
3100 | .get = snd_hdsp_get_dds_offset, \ | ||
3101 | .put = snd_hdsp_put_dds_offset \ | ||
3102 | } | ||
3103 | |||
3104 | static int hdsp_dds_offset(struct hdsp *hdsp) | ||
3105 | { | ||
3106 | u64 n; | ||
3107 | u32 r; | ||
3108 | unsigned int dds_value = hdsp->dds_value; | ||
3109 | int system_sample_rate = hdsp->system_sample_rate; | ||
3110 | |||
3111 | n = DDS_NUMERATOR; | ||
3112 | /* | ||
3113 | * dds_value = n / rate | ||
3114 | * rate = n / dds_value | ||
3115 | */ | ||
3116 | div64_32(&n, dds_value, &r); | ||
3117 | if (system_sample_rate >= 112000) | ||
3118 | n *= 4; | ||
3119 | else if (system_sample_rate >= 56000) | ||
3120 | n *= 2; | ||
3121 | return ((int)n) - system_sample_rate; | ||
3122 | } | ||
3123 | |||
3124 | static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz) | ||
3125 | { | ||
3126 | int rate = hdsp->system_sample_rate + offset_hz; | ||
3127 | hdsp_set_dds_value(hdsp, rate); | ||
3128 | return 0; | ||
3129 | } | ||
3130 | |||
3131 | static int snd_hdsp_info_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | ||
3132 | { | ||
3133 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
3134 | uinfo->count = 1; | ||
3135 | uinfo->value.integer.min = -5000; | ||
3136 | uinfo->value.integer.max = 5000; | ||
3137 | return 0; | ||
3138 | } | ||
3139 | |||
3140 | static int snd_hdsp_get_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
3141 | { | ||
3142 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
3143 | |||
3144 | ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp); | ||
3145 | return 0; | ||
3146 | } | ||
3147 | |||
3148 | static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
3149 | { | ||
3150 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
3151 | int change; | ||
3152 | int val; | ||
3153 | |||
3154 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
3155 | return -EBUSY; | ||
3156 | val = ucontrol->value.enumerated.item[0]; | ||
3157 | spin_lock_irq(&hdsp->lock); | ||
3158 | if (val != hdsp_dds_offset(hdsp)) | ||
3159 | change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0; | ||
3160 | else | ||
3161 | change = 0; | ||
3162 | spin_unlock_irq(&hdsp->lock); | ||
3163 | return change; | ||
3164 | } | ||
3165 | |||
3088 | static struct snd_kcontrol_new snd_hdsp_9632_controls[] = { | 3166 | static struct snd_kcontrol_new snd_hdsp_9632_controls[] = { |
3089 | HDSP_DA_GAIN("DA Gain", 0), | 3167 | HDSP_DA_GAIN("DA Gain", 0), |
3090 | HDSP_AD_GAIN("AD Gain", 0), | 3168 | HDSP_AD_GAIN("AD Gain", 0), |
3091 | HDSP_PHONE_GAIN("Phones Gain", 0), | 3169 | HDSP_PHONE_GAIN("Phones Gain", 0), |
3092 | HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0) | 3170 | HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0), |
3171 | HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) | ||
3093 | }; | 3172 | }; |
3094 | 3173 | ||
3095 | static struct snd_kcontrol_new snd_hdsp_controls[] = { | 3174 | static struct snd_kcontrol_new snd_hdsp_controls[] = { |
@@ -3780,11 +3859,9 @@ static int snd_hdsp_reset(struct snd_pcm_substream *substream) | |||
3780 | else | 3859 | else |
3781 | runtime->status->hw_ptr = 0; | 3860 | runtime->status->hw_ptr = 0; |
3782 | if (other) { | 3861 | if (other) { |
3783 | struct list_head *pos; | ||
3784 | struct snd_pcm_substream *s; | 3862 | struct snd_pcm_substream *s; |
3785 | struct snd_pcm_runtime *oruntime = other->runtime; | 3863 | struct snd_pcm_runtime *oruntime = other->runtime; |
3786 | snd_pcm_group_for_each(pos, substream) { | 3864 | snd_pcm_group_for_each_entry(s, substream) { |
3787 | s = snd_pcm_group_substream_entry(pos); | ||
3788 | if (s == other) { | 3865 | if (s == other) { |
3789 | oruntime->status->hw_ptr = runtime->status->hw_ptr; | 3866 | oruntime->status->hw_ptr = runtime->status->hw_ptr; |
3790 | break; | 3867 | break; |
@@ -3933,10 +4010,8 @@ static int snd_hdsp_trigger(struct snd_pcm_substream *substream, int cmd) | |||
3933 | other = hdsp->playback_substream; | 4010 | other = hdsp->playback_substream; |
3934 | 4011 | ||
3935 | if (other) { | 4012 | if (other) { |
3936 | struct list_head *pos; | ||
3937 | struct snd_pcm_substream *s; | 4013 | struct snd_pcm_substream *s; |
3938 | snd_pcm_group_for_each(pos, substream) { | 4014 | snd_pcm_group_for_each_entry(s, substream) { |
3939 | s = snd_pcm_group_substream_entry(pos); | ||
3940 | if (s == other) { | 4015 | if (s == other) { |
3941 | snd_pcm_trigger_done(s, substream); | 4016 | snd_pcm_trigger_done(s, substream); |
3942 | if (cmd == SNDRV_PCM_TRIGGER_START) | 4017 | if (cmd == SNDRV_PCM_TRIGGER_START) |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 6e95857e4e67..143185e7e4dc 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -91,8 +91,10 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
91 | #define HDSPM_controlRegister 64 | 91 | #define HDSPM_controlRegister 64 |
92 | #define HDSPM_interruptConfirmation 96 | 92 | #define HDSPM_interruptConfirmation 96 |
93 | #define HDSPM_control2Reg 256 /* not in specs ???????? */ | 93 | #define HDSPM_control2Reg 256 /* not in specs ???????? */ |
94 | #define HDSPM_freqReg 256 /* for AES32 */ | ||
94 | #define HDSPM_midiDataOut0 352 /* just believe in old code */ | 95 | #define HDSPM_midiDataOut0 352 /* just believe in old code */ |
95 | #define HDSPM_midiDataOut1 356 | 96 | #define HDSPM_midiDataOut1 356 |
97 | #define HDSPM_eeprom_wr 384 /* for AES32 */ | ||
96 | 98 | ||
97 | /* DMA enable for 64 channels, only Bit 0 is relevant */ | 99 | /* DMA enable for 64 channels, only Bit 0 is relevant */ |
98 | #define HDSPM_outputEnableBase 512 /* 512-767 input DMA */ | 100 | #define HDSPM_outputEnableBase 512 /* 512-767 input DMA */ |
@@ -389,9 +391,8 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
389 | size is the same regardless of the number of channels, and | 391 | size is the same regardless of the number of channels, and |
390 | also the latency to use. | 392 | also the latency to use. |
391 | for one direction !!! | 393 | for one direction !!! |
392 | => need to mupltiply by 2!! | ||
393 | */ | 394 | */ |
394 | #define HDSPM_DMA_AREA_BYTES (2 * HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) | 395 | #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) |
395 | #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) | 396 | #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) |
396 | 397 | ||
397 | /* revisions >= 230 indicate AES32 card */ | 398 | /* revisions >= 230 indicate AES32 card */ |
@@ -484,28 +485,6 @@ static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = { | |||
484 | 56, 57, 58, 59, 60, 61, 62, 63 | 485 | 56, 57, 58, 59, 60, 61, 62, 63 |
485 | }; | 486 | }; |
486 | 487 | ||
487 | static char channel_map_madi_ds[HDSPM_MAX_CHANNELS] = { | ||
488 | 0, 2, 4, 6, 8, 10, 12, 14, | ||
489 | 16, 18, 20, 22, 24, 26, 28, 30, | ||
490 | 32, 34, 36, 38, 40, 42, 44, 46, | ||
491 | 48, 50, 52, 54, 56, 58, 60, 62, | ||
492 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
493 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
494 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
495 | -1, -1, -1, -1, -1, -1, -1, -1 | ||
496 | }; | ||
497 | |||
498 | static char channel_map_madi_qs[HDSPM_MAX_CHANNELS] = { | ||
499 | 0, 4, 8, 12, 16, 20, 24, 28, | ||
500 | 32, 36, 40, 44, 48, 52, 56, 60 | ||
501 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
502 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
503 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
504 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
505 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
506 | -1, -1, -1, -1, -1, -1, -1, -1 | ||
507 | }; | ||
508 | |||
509 | 488 | ||
510 | static struct pci_device_id snd_hdspm_ids[] __devinitdata = { | 489 | static struct pci_device_id snd_hdspm_ids[] __devinitdata = { |
511 | { | 490 | { |
@@ -818,6 +797,27 @@ static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames) | |||
818 | return 0; | 797 | return 0; |
819 | } | 798 | } |
820 | 799 | ||
800 | static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) | ||
801 | { | ||
802 | u64 n; | ||
803 | u32 r; | ||
804 | |||
805 | if (rate >= 112000) | ||
806 | rate /= 4; | ||
807 | else if (rate >= 56000) | ||
808 | rate /= 2; | ||
809 | |||
810 | /* RME says n = 104857600000000, but in the windows MADI driver, I see: | ||
811 | // return 104857600000000 / rate; // 100 MHz | ||
812 | return 110100480000000 / rate; // 105 MHz | ||
813 | */ | ||
814 | //n = 104857600000000ULL; /* = 2^20 * 10^8 */ | ||
815 | n = 110100480000000ULL; /* Value checked for AES32 and MADI */ | ||
816 | div64_32(&n, rate, &r); | ||
817 | /* n should be less than 2^32 for being written to FREQ register */ | ||
818 | snd_assert((n >> 32) == 0); | ||
819 | hdspm_write(hdspm, HDSPM_freqReg, (u32)n); | ||
820 | } | ||
821 | 821 | ||
822 | /* dummy set rate lets see what happens */ | 822 | /* dummy set rate lets see what happens */ |
823 | static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) | 823 | static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) |
@@ -943,12 +943,16 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) | |||
943 | hdspm->control_register |= rate_bits; | 943 | hdspm->control_register |= rate_bits; |
944 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); | 944 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); |
945 | 945 | ||
946 | if (rate > 96000 /* 64000*/) | 946 | /* For AES32, need to set DDS value in FREQ register |
947 | hdspm->channel_map = channel_map_madi_qs; | 947 | For MADI, also apparently */ |
948 | else if (rate > 48000) | 948 | hdspm_set_dds_value(hdspm, rate); |
949 | hdspm->channel_map = channel_map_madi_ds; | 949 | |
950 | else | 950 | if (hdspm->is_aes32 && rate != current_rate) |
951 | hdspm->channel_map = channel_map_madi_ss; | 951 | hdspm_write(hdspm, HDSPM_eeprom_wr, 0); |
952 | |||
953 | /* For AES32 and for MADI (at least rev 204), channel_map needs to | ||
954 | * always be channel_map_madi_ss, whatever the sample rate */ | ||
955 | hdspm->channel_map = channel_map_madi_ss; | ||
952 | 956 | ||
953 | hdspm->system_sample_rate = rate; | 957 | hdspm->system_sample_rate = rate; |
954 | 958 | ||
@@ -3184,8 +3188,8 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, | |||
3184 | hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, | 3188 | hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, |
3185 | hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); | 3189 | hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); |
3186 | snd_iprintf(buffer, | 3190 | snd_iprintf(buffer, |
3187 | "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n", | 3191 | "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n", |
3188 | hdspm->control_register, hdspm->control2_register, | 3192 | hdspm->control_register, |
3189 | status, status2, timecode); | 3193 | status, status2, timecode); |
3190 | 3194 | ||
3191 | snd_iprintf(buffer, "--- Settings ---\n"); | 3195 | snd_iprintf(buffer, "--- Settings ---\n"); |
@@ -3377,13 +3381,16 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm) | |||
3377 | 3381 | ||
3378 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); | 3382 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); |
3379 | 3383 | ||
3384 | if (!hdspm->is_aes32) { | ||
3385 | /* No control2 register for AES32 */ | ||
3380 | #ifdef SNDRV_BIG_ENDIAN | 3386 | #ifdef SNDRV_BIG_ENDIAN |
3381 | hdspm->control2_register = HDSPM_BIGENDIAN_MODE; | 3387 | hdspm->control2_register = HDSPM_BIGENDIAN_MODE; |
3382 | #else | 3388 | #else |
3383 | hdspm->control2_register = 0; | 3389 | hdspm->control2_register = 0; |
3384 | #endif | 3390 | #endif |
3385 | 3391 | ||
3386 | hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register); | 3392 | hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register); |
3393 | } | ||
3387 | hdspm_compute_period_size(hdspm); | 3394 | hdspm_compute_period_size(hdspm); |
3388 | 3395 | ||
3389 | /* silence everything */ | 3396 | /* silence everything */ |
@@ -3575,11 +3582,9 @@ static int snd_hdspm_reset(struct snd_pcm_substream *substream) | |||
3575 | else | 3582 | else |
3576 | runtime->status->hw_ptr = 0; | 3583 | runtime->status->hw_ptr = 0; |
3577 | if (other) { | 3584 | if (other) { |
3578 | struct list_head *pos; | ||
3579 | struct snd_pcm_substream *s; | 3585 | struct snd_pcm_substream *s; |
3580 | struct snd_pcm_runtime *oruntime = other->runtime; | 3586 | struct snd_pcm_runtime *oruntime = other->runtime; |
3581 | snd_pcm_group_for_each(pos, substream) { | 3587 | snd_pcm_group_for_each_entry(s, substream) { |
3582 | s = snd_pcm_group_substream_entry(pos); | ||
3583 | if (s == other) { | 3588 | if (s == other) { |
3584 | oruntime->status->hw_ptr = | 3589 | oruntime->status->hw_ptr = |
3585 | runtime->status->hw_ptr; | 3590 | runtime->status->hw_ptr; |
@@ -3658,11 +3663,10 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, | |||
3658 | 3663 | ||
3659 | /* Memory allocation, takashi's method, dont know if we should spinlock */ | 3664 | /* Memory allocation, takashi's method, dont know if we should spinlock */ |
3660 | /* malloc all buffer even if not enabled to get sure */ | 3665 | /* malloc all buffer even if not enabled to get sure */ |
3661 | /* malloc only needed bytes */ | 3666 | /* Update for MADI rev 204: we need to allocate for all channels, |
3667 | * otherwise it doesn't work at 96kHz */ | ||
3662 | err = | 3668 | err = |
3663 | snd_pcm_lib_malloc_pages(substream, | 3669 | snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES); |
3664 | HDSPM_CHANNEL_BUFFER_BYTES * | ||
3665 | params_channels(params)); | ||
3666 | if (err < 0) | 3670 | if (err < 0) |
3667 | return err; | 3671 | return err; |
3668 | 3672 | ||
@@ -3698,6 +3702,13 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, | |||
3698 | "playback" : "capture", | 3702 | "playback" : "capture", |
3699 | snd_pcm_sgbuf_get_addr(sgbuf, 0)); | 3703 | snd_pcm_sgbuf_get_addr(sgbuf, 0)); |
3700 | */ | 3704 | */ |
3705 | /* | ||
3706 | snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n", | ||
3707 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? | ||
3708 | "playback" : "capture", | ||
3709 | params_rate(params), params_channels(params), | ||
3710 | params_buffer_size(params)); | ||
3711 | */ | ||
3701 | return 0; | 3712 | return 0; |
3702 | } | 3713 | } |
3703 | 3714 | ||
@@ -3791,10 +3802,8 @@ static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
3791 | other = hdspm->playback_substream; | 3802 | other = hdspm->playback_substream; |
3792 | 3803 | ||
3793 | if (other) { | 3804 | if (other) { |
3794 | struct list_head *pos; | ||
3795 | struct snd_pcm_substream *s; | 3805 | struct snd_pcm_substream *s; |
3796 | snd_pcm_group_for_each(pos, substream) { | 3806 | snd_pcm_group_for_each_entry(s, substream) { |
3797 | s = snd_pcm_group_substream_entry(pos); | ||
3798 | if (s == other) { | 3807 | if (s == other) { |
3799 | snd_pcm_trigger_done(s, substream); | 3808 | snd_pcm_trigger_done(s, substream); |
3800 | if (cmd == SNDRV_PCM_TRIGGER_START) | 3809 | if (cmd == SNDRV_PCM_TRIGGER_START) |
@@ -3904,16 +3913,16 @@ static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params, | |||
3904 | struct snd_interval *r = | 3913 | struct snd_interval *r = |
3905 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 3914 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
3906 | 3915 | ||
3907 | if (r->min > 48000) { | 3916 | if (r->min > 48000 && r->max <= 96000) { |
3908 | struct snd_interval t = { | 3917 | struct snd_interval t = { |
3909 | .min = 1, | 3918 | .min = hdspm->ds_channels, |
3910 | .max = hdspm->ds_channels, | 3919 | .max = hdspm->ds_channels, |
3911 | .integer = 1, | 3920 | .integer = 1, |
3912 | }; | 3921 | }; |
3913 | return snd_interval_refine(c, &t); | 3922 | return snd_interval_refine(c, &t); |
3914 | } else if (r->max < 64000) { | 3923 | } else if (r->max < 64000) { |
3915 | struct snd_interval t = { | 3924 | struct snd_interval t = { |
3916 | .min = 1, | 3925 | .min = hdspm->ss_channels, |
3917 | .max = hdspm->ss_channels, | 3926 | .max = hdspm->ss_channels, |
3918 | .integer = 1, | 3927 | .integer = 1, |
3919 | }; | 3928 | }; |
@@ -3931,14 +3940,14 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, | |||
3931 | struct snd_interval *r = | 3940 | struct snd_interval *r = |
3932 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 3941 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
3933 | 3942 | ||
3934 | if (c->min <= hdspm->ss_channels) { | 3943 | if (c->min >= hdspm->ss_channels) { |
3935 | struct snd_interval t = { | 3944 | struct snd_interval t = { |
3936 | .min = 32000, | 3945 | .min = 32000, |
3937 | .max = 48000, | 3946 | .max = 48000, |
3938 | .integer = 1, | 3947 | .integer = 1, |
3939 | }; | 3948 | }; |
3940 | return snd_interval_refine(r, &t); | 3949 | return snd_interval_refine(r, &t); |
3941 | } else if (c->max > hdspm->ss_channels) { | 3950 | } else if (c->max <= hdspm->ds_channels) { |
3942 | struct snd_interval t = { | 3951 | struct snd_interval t = { |
3943 | .min = 64000, | 3952 | .min = 64000, |
3944 | .max = 96000, | 3953 | .max = 96000, |
@@ -3950,13 +3959,39 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, | |||
3950 | return 0; | 3959 | return 0; |
3951 | } | 3960 | } |
3952 | 3961 | ||
3962 | static int snd_hdspm_hw_rule_channels(struct snd_pcm_hw_params *params, | ||
3963 | struct snd_pcm_hw_rule *rule) | ||
3964 | { | ||
3965 | unsigned int list[3]; | ||
3966 | struct hdspm *hdspm = rule->private; | ||
3967 | struct snd_interval *c = hw_param_interval(params, | ||
3968 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
3969 | if (hdspm->is_aes32) { | ||
3970 | list[0] = hdspm->qs_channels; | ||
3971 | list[1] = hdspm->ds_channels; | ||
3972 | list[2] = hdspm->ss_channels; | ||
3973 | return snd_interval_list(c, 3, list, 0); | ||
3974 | } else { | ||
3975 | list[0] = hdspm->ds_channels; | ||
3976 | list[1] = hdspm->ss_channels; | ||
3977 | return snd_interval_list(c, 2, list, 0); | ||
3978 | } | ||
3979 | } | ||
3980 | |||
3981 | |||
3982 | static unsigned int hdspm_aes32_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 }; | ||
3983 | |||
3984 | static struct snd_pcm_hw_constraint_list hdspm_hw_constraints_aes32_sample_rates = { | ||
3985 | .count = ARRAY_SIZE(hdspm_aes32_sample_rates), | ||
3986 | .list = hdspm_aes32_sample_rates, | ||
3987 | .mask = 0 | ||
3988 | }; | ||
3989 | |||
3953 | static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) | 3990 | static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) |
3954 | { | 3991 | { |
3955 | struct hdspm *hdspm = snd_pcm_substream_chip(substream); | 3992 | struct hdspm *hdspm = snd_pcm_substream_chip(substream); |
3956 | struct snd_pcm_runtime *runtime = substream->runtime; | 3993 | struct snd_pcm_runtime *runtime = substream->runtime; |
3957 | 3994 | ||
3958 | snd_printdd("Open device substream %d\n", substream->stream); | ||
3959 | |||
3960 | spin_lock_irq(&hdspm->lock); | 3995 | spin_lock_irq(&hdspm->lock); |
3961 | 3996 | ||
3962 | snd_pcm_set_sync(substream); | 3997 | snd_pcm_set_sync(substream); |
@@ -3977,14 +4012,21 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) | |||
3977 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 4012 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
3978 | &hw_constraints_period_sizes); | 4013 | &hw_constraints_period_sizes); |
3979 | 4014 | ||
3980 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 4015 | if (hdspm->is_aes32) { |
3981 | snd_hdspm_hw_rule_channels_rate, hdspm, | 4016 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
3982 | SNDRV_PCM_HW_PARAM_RATE, -1); | 4017 | &hdspm_hw_constraints_aes32_sample_rates); |
3983 | 4018 | } else { | |
3984 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 4019 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
3985 | snd_hdspm_hw_rule_rate_channels, hdspm, | 4020 | snd_hdspm_hw_rule_channels, hdspm, |
3986 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | 4021 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); |
3987 | 4022 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | |
4023 | snd_hdspm_hw_rule_channels_rate, hdspm, | ||
4024 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
4025 | |||
4026 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
4027 | snd_hdspm_hw_rule_rate_channels, hdspm, | ||
4028 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
4029 | } | ||
3988 | return 0; | 4030 | return 0; |
3989 | } | 4031 | } |
3990 | 4032 | ||
@@ -4024,14 +4066,21 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream) | |||
4024 | snd_pcm_hw_constraint_list(runtime, 0, | 4066 | snd_pcm_hw_constraint_list(runtime, 0, |
4025 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 4067 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
4026 | &hw_constraints_period_sizes); | 4068 | &hw_constraints_period_sizes); |
4027 | 4069 | if (hdspm->is_aes32) { | |
4028 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 4070 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
4029 | snd_hdspm_hw_rule_channels_rate, hdspm, | 4071 | &hdspm_hw_constraints_aes32_sample_rates); |
4030 | SNDRV_PCM_HW_PARAM_RATE, -1); | 4072 | } else { |
4031 | 4073 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | |
4032 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 4074 | snd_hdspm_hw_rule_channels, hdspm, |
4033 | snd_hdspm_hw_rule_rate_channels, hdspm, | 4075 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); |
4034 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | 4076 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
4077 | snd_hdspm_hw_rule_channels_rate, hdspm, | ||
4078 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
4079 | |||
4080 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
4081 | snd_hdspm_hw_rule_rate_channels, hdspm, | ||
4082 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
4083 | } | ||
4035 | return 0; | 4084 | return 0; |
4036 | } | 4085 | } |
4037 | 4086 | ||
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index cc3bdececce7..bd7dbd267ed1 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c | |||
@@ -1992,11 +1992,9 @@ static int snd_rme9652_reset(struct snd_pcm_substream *substream) | |||
1992 | else | 1992 | else |
1993 | runtime->status->hw_ptr = 0; | 1993 | runtime->status->hw_ptr = 0; |
1994 | if (other) { | 1994 | if (other) { |
1995 | struct list_head *pos; | ||
1996 | struct snd_pcm_substream *s; | 1995 | struct snd_pcm_substream *s; |
1997 | struct snd_pcm_runtime *oruntime = other->runtime; | 1996 | struct snd_pcm_runtime *oruntime = other->runtime; |
1998 | snd_pcm_group_for_each(pos, substream) { | 1997 | snd_pcm_group_for_each_entry(s, substream) { |
1999 | s = snd_pcm_group_substream_entry(pos); | ||
2000 | if (s == other) { | 1998 | if (s == other) { |
2001 | oruntime->status->hw_ptr = runtime->status->hw_ptr; | 1999 | oruntime->status->hw_ptr = runtime->status->hw_ptr; |
2002 | break; | 2000 | break; |
@@ -2140,10 +2138,8 @@ static int snd_rme9652_trigger(struct snd_pcm_substream *substream, | |||
2140 | other = rme9652->playback_substream; | 2138 | other = rme9652->playback_substream; |
2141 | 2139 | ||
2142 | if (other) { | 2140 | if (other) { |
2143 | struct list_head *pos; | ||
2144 | struct snd_pcm_substream *s; | 2141 | struct snd_pcm_substream *s; |
2145 | snd_pcm_group_for_each(pos, substream) { | 2142 | snd_pcm_group_for_each_entry(s, substream) { |
2146 | s = snd_pcm_group_substream_entry(pos); | ||
2147 | if (s == other) { | 2143 | if (s == other) { |
2148 | snd_pcm_trigger_done(s, substream); | 2144 | snd_pcm_trigger_done(s, substream); |
2149 | if (cmd == SNDRV_PCM_TRIGGER_START) | 2145 | if (cmd == SNDRV_PCM_TRIGGER_START) |
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 3bff32167f66..7ca606272460 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c | |||
@@ -1540,7 +1540,6 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream, | |||
1540 | 1540 | ||
1541 | { | 1541 | { |
1542 | struct snd_trident *trident = snd_pcm_substream_chip(substream); | 1542 | struct snd_trident *trident = snd_pcm_substream_chip(substream); |
1543 | struct list_head *pos; | ||
1544 | struct snd_pcm_substream *s; | 1543 | struct snd_pcm_substream *s; |
1545 | unsigned int what, whati, capture_flag, spdif_flag; | 1544 | unsigned int what, whati, capture_flag, spdif_flag; |
1546 | struct snd_trident_voice *voice, *evoice; | 1545 | struct snd_trident_voice *voice, *evoice; |
@@ -1563,8 +1562,7 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream, | |||
1563 | what = whati = capture_flag = spdif_flag = 0; | 1562 | what = whati = capture_flag = spdif_flag = 0; |
1564 | spin_lock(&trident->reg_lock); | 1563 | spin_lock(&trident->reg_lock); |
1565 | val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff; | 1564 | val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff; |
1566 | snd_pcm_group_for_each(pos, substream) { | 1565 | snd_pcm_group_for_each_entry(s, substream) { |
1567 | s = snd_pcm_group_substream_entry(pos); | ||
1568 | if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) { | 1566 | if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) { |
1569 | voice = s->runtime->private_data; | 1567 | voice = s->runtime->private_data; |
1570 | evoice = voice->extra; | 1568 | evoice = voice->extra; |
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index fd12674d0394..ea861bceaddf 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c | |||
@@ -1998,9 +1998,7 @@ static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip) | |||
1998 | } | 1998 | } |
1999 | } | 1999 | } |
2000 | 2000 | ||
2001 | #define FIRMWARE_IN_THE_KERNEL | 2001 | #ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL |
2002 | |||
2003 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
2004 | 2002 | ||
2005 | #include "ymfpci_image.h" | 2003 | #include "ymfpci_image.h" |
2006 | 2004 | ||
@@ -2018,6 +2016,24 @@ static struct firmware snd_ymfpci_controller_1e_microcode = { | |||
2018 | }; | 2016 | }; |
2019 | #endif | 2017 | #endif |
2020 | 2018 | ||
2019 | #ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL | ||
2020 | static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) | ||
2021 | { | ||
2022 | chip->dsp_microcode = &snd_ymfpci_dsp_microcode; | ||
2023 | if (chip->device_id == PCI_DEVICE_ID_YAMAHA_724F || | ||
2024 | chip->device_id == PCI_DEVICE_ID_YAMAHA_740C || | ||
2025 | chip->device_id == PCI_DEVICE_ID_YAMAHA_744 || | ||
2026 | chip->device_id == PCI_DEVICE_ID_YAMAHA_754) | ||
2027 | chip->controller_microcode = | ||
2028 | &snd_ymfpci_controller_1e_microcode; | ||
2029 | else | ||
2030 | chip->controller_microcode = | ||
2031 | &snd_ymfpci_controller_microcode; | ||
2032 | return 0; | ||
2033 | } | ||
2034 | |||
2035 | #else /* use fw_loader */ | ||
2036 | |||
2021 | #ifdef __LITTLE_ENDIAN | 2037 | #ifdef __LITTLE_ENDIAN |
2022 | static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { } | 2038 | static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { } |
2023 | #else | 2039 | #else |
@@ -2046,13 +2062,8 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) | |||
2046 | err = -EINVAL; | 2062 | err = -EINVAL; |
2047 | } | 2063 | } |
2048 | } | 2064 | } |
2049 | if (err < 0) { | 2065 | if (err < 0) |
2050 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
2051 | chip->dsp_microcode = &snd_ymfpci_dsp_microcode; | ||
2052 | #else | ||
2053 | return err; | 2066 | return err; |
2054 | #endif | ||
2055 | } | ||
2056 | is_1e = chip->device_id == PCI_DEVICE_ID_YAMAHA_724F || | 2067 | is_1e = chip->device_id == PCI_DEVICE_ID_YAMAHA_724F || |
2057 | chip->device_id == PCI_DEVICE_ID_YAMAHA_740C || | 2068 | chip->device_id == PCI_DEVICE_ID_YAMAHA_740C || |
2058 | chip->device_id == PCI_DEVICE_ID_YAMAHA_744 || | 2069 | chip->device_id == PCI_DEVICE_ID_YAMAHA_744 || |
@@ -2069,18 +2080,17 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) | |||
2069 | err = -EINVAL; | 2080 | err = -EINVAL; |
2070 | } | 2081 | } |
2071 | } | 2082 | } |
2072 | if (err < 0) { | 2083 | if (err < 0) |
2073 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
2074 | chip->controller_microcode = | ||
2075 | is_1e ? &snd_ymfpci_controller_1e_microcode | ||
2076 | : &snd_ymfpci_controller_microcode; | ||
2077 | #else | ||
2078 | return err; | 2084 | return err; |
2079 | #endif | ||
2080 | } | ||
2081 | return 0; | 2085 | return 0; |
2082 | } | 2086 | } |
2083 | 2087 | ||
2088 | MODULE_FIRMWARE("yamaha/ds1_dsp.fw"); | ||
2089 | MODULE_FIRMWARE("yamaha/ds1_ctrl.fw"); | ||
2090 | MODULE_FIRMWARE("yamaha/ds1e_ctrl.fw"); | ||
2091 | |||
2092 | #endif | ||
2093 | |||
2084 | static void snd_ymfpci_download_image(struct snd_ymfpci *chip) | 2094 | static void snd_ymfpci_download_image(struct snd_ymfpci *chip) |
2085 | { | 2095 | { |
2086 | int i; | 2096 | int i; |
@@ -2259,15 +2269,10 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip) | |||
2259 | pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl); | 2269 | pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl); |
2260 | 2270 | ||
2261 | pci_disable_device(chip->pci); | 2271 | pci_disable_device(chip->pci); |
2262 | #ifdef FIRMWARE_IN_THE_KERNEL | 2272 | #ifndef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL |
2263 | if (chip->dsp_microcode != &snd_ymfpci_dsp_microcode) | 2273 | release_firmware(chip->dsp_microcode); |
2264 | #endif | 2274 | release_firmware(chip->controller_microcode); |
2265 | release_firmware(chip->dsp_microcode); | ||
2266 | #ifdef FIRMWARE_IN_THE_KERNEL | ||
2267 | if (chip->controller_microcode != &snd_ymfpci_controller_microcode && | ||
2268 | chip->controller_microcode != &snd_ymfpci_controller_1e_microcode) | ||
2269 | #endif | 2275 | #endif |
2270 | release_firmware(chip->controller_microcode); | ||
2271 | kfree(chip); | 2276 | kfree(chip); |
2272 | return 0; | 2277 | return 0; |
2273 | } | 2278 | } |
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 363bcb5f08e6..c57e127d9ccb 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c | |||
@@ -297,7 +297,7 @@ static int vxpocket_probe(struct pcmcia_device *p_dev) | |||
297 | 297 | ||
298 | /* find an empty slot from the card list */ | 298 | /* find an empty slot from the card list */ |
299 | for (i = 0; i < SNDRV_CARDS; i++) { | 299 | for (i = 0; i < SNDRV_CARDS; i++) { |
300 | if (! card_alloc & (1 << i)) | 300 | if (!(card_alloc & (1 << i))) |
301 | break; | 301 | break; |
302 | } | 302 | } |
303 | if (i >= SNDRV_CARDS) { | 303 | if (i >= SNDRV_CARDS) { |
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index dccaa4be679e..10cffc087181 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig | |||
@@ -2,31 +2,31 @@ | |||
2 | # SoC audio configuration | 2 | # SoC audio configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "SoC audio support" | 5 | menu "System on Chip audio support" |
6 | depends on SND!=n | 6 | depends on SND!=n |
7 | 7 | ||
8 | config SND_SOC_AC97_BUS | 8 | config SND_SOC_AC97_BUS |
9 | bool | 9 | bool |
10 | 10 | ||
11 | config SND_SOC | 11 | config SND_SOC |
12 | tristate "SoC audio support" | 12 | tristate "ALSA for SoC audio support" |
13 | depends on SND | 13 | depends on SND |
14 | select SND_PCM | 14 | select SND_PCM |
15 | ---help--- | 15 | ---help--- |
16 | 16 | ||
17 | If you want SoC support, you should say Y here and also to the | 17 | If you want ASoC support, you should say Y here and also to the |
18 | specific driver for your SoC below. You will also need to select the | 18 | specific driver for your SoC platform below. |
19 | specific codec(s) attached to the SoC | 19 | |
20 | ASoC provides power efficient ALSA support for embedded battery powered | ||
21 | SoC based systems like PDA's, Phones and Personal Media Players. | ||
20 | 22 | ||
21 | This SoC audio support can also be built as a module. If so, the module | 23 | This ASoC audio support can also be built as a module. If so, the module |
22 | will be called snd-soc-core. | 24 | will be called snd-soc-core. |
23 | 25 | ||
24 | # All the supported Soc's | 26 | # All the supported Soc's |
25 | menu "SoC Platforms" | ||
26 | depends on SND_SOC | ||
27 | source "sound/soc/at91/Kconfig" | 27 | source "sound/soc/at91/Kconfig" |
28 | source "sound/soc/pxa/Kconfig" | 28 | source "sound/soc/pxa/Kconfig" |
29 | endmenu | 29 | source "sound/soc/s3c24xx/Kconfig" |
30 | 30 | ||
31 | # Supported codecs | 31 | # Supported codecs |
32 | source "sound/soc/codecs/Kconfig" | 32 | source "sound/soc/codecs/Kconfig" |
diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 98e6f49dafc2..0ae2e49036f9 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | snd-soc-core-objs := soc-core.o soc-dapm.o | 1 | snd-soc-core-objs := soc-core.o soc-dapm.o |
2 | 2 | ||
3 | obj-$(CONFIG_SND_SOC) += snd-soc-core.o | 3 | obj-$(CONFIG_SND_SOC) += snd-soc-core.o |
4 | obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ | 4 | obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/ |
diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig index a5b2558916c1..5cb93fd3a407 100644 --- a/sound/soc/at91/Kconfig +++ b/sound/soc/at91/Kconfig | |||
@@ -1,5 +1,3 @@ | |||
1 | menu "SoC Audio for the Atmel AT91" | ||
2 | |||
3 | config SND_AT91_SOC | 1 | config SND_AT91_SOC |
4 | tristate "SoC Audio for the Atmel AT91 System-on-Chip" | 2 | tristate "SoC Audio for the Atmel AT91 System-on-Chip" |
5 | depends on ARCH_AT91 && SND_SOC | 3 | depends on ARCH_AT91 && SND_SOC |
@@ -8,13 +6,13 @@ config SND_AT91_SOC | |||
8 | the AT91 SSC interface. You will also need | 6 | the AT91 SSC interface. You will also need |
9 | to select the audio interfaces to support below. | 7 | to select the audio interfaces to support below. |
10 | 8 | ||
11 | config SND_AT91_SOC_I2S | 9 | config SND_AT91_SOC_SSC |
12 | tristate | 10 | tristate |
13 | 11 | ||
14 | config SND_AT91_SOC_ETI_B1_WM8731 | 12 | config SND_AT91_SOC_ETI_B1_WM8731 |
15 | tristate "SoC I2S Audio support for WM8731-based Endrelia ETI-B1 boards" | 13 | tristate "SoC Audio support for WM8731-based Endrelia ETI-B1 boards" |
16 | depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1) | 14 | depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1) |
17 | select SND_AT91_SOC_I2S | 15 | select SND_AT91_SOC_SSC |
18 | select SND_SOC_WM8731 | 16 | select SND_SOC_WM8731 |
19 | help | 17 | help |
20 | Say Y if you want to add support for SoC audio on WM8731-based | 18 | Say Y if you want to add support for SoC audio on WM8731-based |
@@ -27,5 +25,3 @@ config SND_AT91_SOC_ETI_SLAVE | |||
27 | help | 25 | help |
28 | Say Y if you want to run with the AT91 SSC generating the BCLK | 26 | Say Y if you want to run with the AT91 SSC generating the BCLK |
29 | and LRC signals on Endrelia boards. | 27 | and LRC signals on Endrelia boards. |
30 | |||
31 | endmenu | ||
diff --git a/sound/soc/at91/Makefile b/sound/soc/at91/Makefile index b77b01ab2028..f23da17cc328 100644 --- a/sound/soc/at91/Makefile +++ b/sound/soc/at91/Makefile | |||
@@ -1,9 +1,9 @@ | |||
1 | # AT91 Platform Support | 1 | # AT91 Platform Support |
2 | snd-soc-at91-objs := at91-pcm.o | 2 | snd-soc-at91-objs := at91-pcm.o |
3 | snd-soc-at91-i2s-objs := at91-i2s.o | 3 | snd-soc-at91-ssc-objs := at91-ssc.o |
4 | 4 | ||
5 | obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o | 5 | obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o |
6 | obj-$(CONFIG_SND_AT91_SOC_I2S) += snd-soc-at91-i2s.o | 6 | obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o |
7 | 7 | ||
8 | # AT91 Machine Support | 8 | # AT91 Machine Support |
9 | snd-soc-eti-b1-wm8731-objs := eti_b1_wm8731.o | 9 | snd-soc-eti-b1-wm8731-objs := eti_b1_wm8731.o |
diff --git a/sound/soc/at91/at91-i2s.c b/sound/soc/at91/at91-ssc.c index 9fc0c0388881..3d4e32cff75e 100644 --- a/sound/soc/at91/at91-i2s.c +++ b/sound/soc/at91/at91-ssc.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * at91-i2s.c -- ALSA SoC I2S Audio Layer Platform driver | 2 | * at91-ssc.c -- ALSA SoC AT91 SSC Audio Layer Platform driver |
3 | * | 3 | * |
4 | * Author: Frank Mandarino <fmandarino@endrelia.com> | 4 | * Author: Frank Mandarino <fmandarino@endrelia.com> |
5 | * Endrelia Technologies Inc. | 5 | * Endrelia Technologies Inc. |
@@ -25,6 +25,7 @@ | |||
25 | #include <sound/driver.h> | 25 | #include <sound/driver.h> |
26 | #include <sound/core.h> | 26 | #include <sound/core.h> |
27 | #include <sound/pcm.h> | 27 | #include <sound/pcm.h> |
28 | #include <sound/pcm_params.h> | ||
28 | #include <sound/initval.h> | 29 | #include <sound/initval.h> |
29 | #include <sound/soc.h> | 30 | #include <sound/soc.h> |
30 | 31 | ||
@@ -33,10 +34,10 @@ | |||
33 | #include <asm/arch/at91_ssc.h> | 34 | #include <asm/arch/at91_ssc.h> |
34 | 35 | ||
35 | #include "at91-pcm.h" | 36 | #include "at91-pcm.h" |
36 | #include "at91-i2s.h" | 37 | #include "at91-ssc.h" |
37 | 38 | ||
38 | #if 0 | 39 | #if 0 |
39 | #define DBG(x...) printk(KERN_DEBUG "at91-i2s:" x) | 40 | #define DBG(x...) printk(KERN_DEBUG "at91-ssc:" x) |
40 | #else | 41 | #else |
41 | #define DBG(x...) | 42 | #define DBG(x...) |
42 | #endif | 43 | #endif |
@@ -92,33 +93,33 @@ static struct at91_ssc_mask ssc_rx_mask = { | |||
92 | */ | 93 | */ |
93 | static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = { | 94 | static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = { |
94 | {{ | 95 | {{ |
95 | .name = "SSC0/I2S PCM Stereo out", | 96 | .name = "SSC0 PCM out", |
96 | .pdc = &pdc_tx_reg, | 97 | .pdc = &pdc_tx_reg, |
97 | .mask = &ssc_tx_mask, | 98 | .mask = &ssc_tx_mask, |
98 | }, | 99 | }, |
99 | { | 100 | { |
100 | .name = "SSC0/I2S PCM Stereo in", | 101 | .name = "SSC0 PCM in", |
101 | .pdc = &pdc_rx_reg, | 102 | .pdc = &pdc_rx_reg, |
102 | .mask = &ssc_rx_mask, | 103 | .mask = &ssc_rx_mask, |
103 | }}, | 104 | }}, |
104 | #if NUM_SSC_DEVICES == 3 | 105 | #if NUM_SSC_DEVICES == 3 |
105 | {{ | 106 | {{ |
106 | .name = "SSC1/I2S PCM Stereo out", | 107 | .name = "SSC1 PCM out", |
107 | .pdc = &pdc_tx_reg, | 108 | .pdc = &pdc_tx_reg, |
108 | .mask = &ssc_tx_mask, | 109 | .mask = &ssc_tx_mask, |
109 | }, | 110 | }, |
110 | { | 111 | { |
111 | .name = "SSC1/I2S PCM Stereo in", | 112 | .name = "SSC1 PCM in", |
112 | .pdc = &pdc_rx_reg, | 113 | .pdc = &pdc_rx_reg, |
113 | .mask = &ssc_rx_mask, | 114 | .mask = &ssc_rx_mask, |
114 | }}, | 115 | }}, |
115 | {{ | 116 | {{ |
116 | .name = "SSC2/I2S PCM Stereo out", | 117 | .name = "SSC2 PCM out", |
117 | .pdc = &pdc_tx_reg, | 118 | .pdc = &pdc_tx_reg, |
118 | .mask = &ssc_tx_mask, | 119 | .mask = &ssc_tx_mask, |
119 | }, | 120 | }, |
120 | { | 121 | { |
121 | .name = "SSC1/I2S PCM Stereo in", | 122 | .name = "SSC2 PCM in", |
122 | .pdc = &pdc_rx_reg, | 123 | .pdc = &pdc_rx_reg, |
123 | .mask = &ssc_rx_mask, | 124 | .mask = &ssc_rx_mask, |
124 | }}, | 125 | }}, |
@@ -151,33 +152,33 @@ static struct at91_ssc_info { | |||
151 | } ssc_info[NUM_SSC_DEVICES] = { | 152 | } ssc_info[NUM_SSC_DEVICES] = { |
152 | { | 153 | { |
153 | .name = "ssc0", | 154 | .name = "ssc0", |
154 | .lock = SPIN_LOCK_UNLOCKED, | 155 | .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock), |
155 | .dir_mask = 0, | 156 | .dir_mask = 0, |
156 | .initialized = 0, | 157 | .initialized = 0, |
157 | }, | 158 | }, |
158 | #if NUM_SSC_DEVICES == 3 | 159 | #if NUM_SSC_DEVICES == 3 |
159 | { | 160 | { |
160 | .name = "ssc1", | 161 | .name = "ssc1", |
161 | .lock = SPIN_LOCK_UNLOCKED, | 162 | .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock), |
162 | .dir_mask = 0, | 163 | .dir_mask = 0, |
163 | .initialized = 0, | 164 | .initialized = 0, |
164 | }, | 165 | }, |
165 | { | 166 | { |
166 | .name = "ssc2", | 167 | .name = "ssc2", |
167 | .lock = SPIN_LOCK_UNLOCKED, | 168 | .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock), |
168 | .dir_mask = 0, | 169 | .dir_mask = 0, |
169 | .initialized = 0, | 170 | .initialized = 0, |
170 | }, | 171 | }, |
171 | #endif | 172 | #endif |
172 | }; | 173 | }; |
173 | 174 | ||
174 | static unsigned int at91_i2s_sysclk; | 175 | static unsigned int at91_ssc_sysclk; |
175 | 176 | ||
176 | /* | 177 | /* |
177 | * SSC interrupt handler. Passes PDC interrupts to the DMA | 178 | * SSC interrupt handler. Passes PDC interrupts to the DMA |
178 | * interrupt handler in the PCM driver. | 179 | * interrupt handler in the PCM driver. |
179 | */ | 180 | */ |
180 | static irqreturn_t at91_i2s_interrupt(int irq, void *dev_id) | 181 | static irqreturn_t at91_ssc_interrupt(int irq, void *dev_id) |
181 | { | 182 | { |
182 | struct at91_ssc_info *ssc_p = dev_id; | 183 | struct at91_ssc_info *ssc_p = dev_id; |
183 | struct at91_pcm_dma_params *dma_params; | 184 | struct at91_pcm_dma_params *dma_params; |
@@ -209,13 +210,13 @@ static irqreturn_t at91_i2s_interrupt(int irq, void *dev_id) | |||
209 | /* | 210 | /* |
210 | * Startup. Only that one substream allowed in each direction. | 211 | * Startup. Only that one substream allowed in each direction. |
211 | */ | 212 | */ |
212 | static int at91_i2s_startup(struct snd_pcm_substream *substream) | 213 | static int at91_ssc_startup(struct snd_pcm_substream *substream) |
213 | { | 214 | { |
214 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 215 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
215 | struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; | 216 | struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; |
216 | int dir_mask; | 217 | int dir_mask; |
217 | 218 | ||
218 | DBG("i2s_startup: SSC_SR=0x%08lx\n", | 219 | DBG("ssc_startup: SSC_SR=0x%08lx\n", |
219 | at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)); | 220 | at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)); |
220 | dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2; | 221 | dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2; |
221 | 222 | ||
@@ -234,7 +235,7 @@ static int at91_i2s_startup(struct snd_pcm_substream *substream) | |||
234 | * Shutdown. Clear DMA parameters and shutdown the SSC if there | 235 | * Shutdown. Clear DMA parameters and shutdown the SSC if there |
235 | * are no other substreams open. | 236 | * are no other substreams open. |
236 | */ | 237 | */ |
237 | static void at91_i2s_shutdown(struct snd_pcm_substream *substream) | 238 | static void at91_ssc_shutdown(struct snd_pcm_substream *substream) |
238 | { | 239 | { |
239 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 240 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
240 | struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; | 241 | struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; |
@@ -281,7 +282,7 @@ static void at91_i2s_shutdown(struct snd_pcm_substream *substream) | |||
281 | /* | 282 | /* |
282 | * Record the SSC system clock rate. | 283 | * Record the SSC system clock rate. |
283 | */ | 284 | */ |
284 | static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, | 285 | static int at91_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, |
285 | int clk_id, unsigned int freq, int dir) | 286 | int clk_id, unsigned int freq, int dir) |
286 | { | 287 | { |
287 | /* | 288 | /* |
@@ -291,7 +292,7 @@ static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, | |||
291 | */ | 292 | */ |
292 | switch (clk_id) { | 293 | switch (clk_id) { |
293 | case AT91_SYSCLK_MCK: | 294 | case AT91_SYSCLK_MCK: |
294 | at91_i2s_sysclk = freq; | 295 | at91_ssc_sysclk = freq; |
295 | break; | 296 | break; |
296 | default: | 297 | default: |
297 | return -EINVAL; | 298 | return -EINVAL; |
@@ -303,14 +304,11 @@ static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, | |||
303 | /* | 304 | /* |
304 | * Record the DAI format for use in hw_params(). | 305 | * Record the DAI format for use in hw_params(). |
305 | */ | 306 | */ |
306 | static int at91_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, | 307 | static int at91_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, |
307 | unsigned int fmt) | 308 | unsigned int fmt) |
308 | { | 309 | { |
309 | struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; | 310 | struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; |
310 | 311 | ||
311 | if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) | ||
312 | return -EINVAL; | ||
313 | |||
314 | ssc_p->daifmt = fmt; | 312 | ssc_p->daifmt = fmt; |
315 | return 0; | 313 | return 0; |
316 | } | 314 | } |
@@ -318,7 +316,7 @@ static int at91_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, | |||
318 | /* | 316 | /* |
319 | * Record SSC clock dividers for use in hw_params(). | 317 | * Record SSC clock dividers for use in hw_params(). |
320 | */ | 318 | */ |
321 | static int at91_i2s_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai, | 319 | static int at91_ssc_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai, |
322 | int div_id, int div) | 320 | int div_id, int div) |
323 | { | 321 | { |
324 | struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; | 322 | struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; |
@@ -355,7 +353,7 @@ static int at91_i2s_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai, | |||
355 | /* | 353 | /* |
356 | * Configure the SSC. | 354 | * Configure the SSC. |
357 | */ | 355 | */ |
358 | static int at91_i2s_hw_params(struct snd_pcm_substream *substream, | 356 | static int at91_ssc_hw_params(struct snd_pcm_substream *substream, |
359 | struct snd_pcm_hw_params *params) | 357 | struct snd_pcm_hw_params *params) |
360 | { | 358 | { |
361 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 359 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
@@ -391,20 +389,50 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream, | |||
391 | channels = params_channels(params); | 389 | channels = params_channels(params); |
392 | 390 | ||
393 | /* | 391 | /* |
392 | * Determine sample size in bits and the PDC increment. | ||
393 | */ | ||
394 | switch(params_format(params)) { | ||
395 | case SNDRV_PCM_FORMAT_S8: | ||
396 | bits = 8; | ||
397 | dma_params->pdc_xfer_size = 1; | ||
398 | break; | ||
399 | case SNDRV_PCM_FORMAT_S16_LE: | ||
400 | bits = 16; | ||
401 | dma_params->pdc_xfer_size = 2; | ||
402 | break; | ||
403 | case SNDRV_PCM_FORMAT_S24_LE: | ||
404 | bits = 24; | ||
405 | dma_params->pdc_xfer_size = 4; | ||
406 | break; | ||
407 | case SNDRV_PCM_FORMAT_S32_LE: | ||
408 | bits = 32; | ||
409 | dma_params->pdc_xfer_size = 4; | ||
410 | break; | ||
411 | default: | ||
412 | printk(KERN_WARNING "at91-ssc: unsupported PCM format"); | ||
413 | return -EINVAL; | ||
414 | } | ||
415 | |||
416 | /* | ||
394 | * The SSC only supports up to 16-bit samples in I2S format, due | 417 | * The SSC only supports up to 16-bit samples in I2S format, due |
395 | * to the size of the Frame Mode Register FSLEN field. Also, I2S | 418 | * to the size of the Frame Mode Register FSLEN field. |
396 | * implies signed data. | ||
397 | */ | 419 | */ |
398 | bits = 16; | 420 | if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S |
399 | dma_params->pdc_xfer_size = 2; | 421 | && bits > 16) { |
422 | printk(KERN_WARNING | ||
423 | "at91-ssc: sample size %d is too large for I2S\n", bits); | ||
424 | return -EINVAL; | ||
425 | } | ||
400 | 426 | ||
401 | /* | 427 | /* |
402 | * Compute SSC register settings. | 428 | * Compute SSC register settings. |
403 | */ | 429 | */ |
404 | switch (ssc_p->daifmt) { | 430 | switch (ssc_p->daifmt |
405 | case SND_SOC_DAIFMT_CBS_CFS: | 431 | & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) { |
432 | |||
433 | case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS: | ||
406 | /* | 434 | /* |
407 | * SSC provides BCLK and LRC clocks. | 435 | * I2S format, SSC provides BCLK and LRC clocks. |
408 | * | 436 | * |
409 | * The SSC transmit and receive clocks are generated from the | 437 | * The SSC transmit and receive clocks are generated from the |
410 | * MCK divider, and the BCLK signal is output on the SSC TK line. | 438 | * MCK divider, and the BCLK signal is output on the SSC TK line. |
@@ -441,10 +469,9 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream, | |||
441 | | (((bits - 1) << 0) & AT91_SSC_DATALEN); | 469 | | (((bits - 1) << 0) & AT91_SSC_DATALEN); |
442 | break; | 470 | break; |
443 | 471 | ||
444 | case SND_SOC_DAIFMT_CBM_CFM: | 472 | case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM: |
445 | |||
446 | /* | 473 | /* |
447 | * CODEC supplies BCLK and LRC clocks. | 474 | * I2S format, CODEC supplies BCLK and LRC clocks. |
448 | * | 475 | * |
449 | * The SSC transmit clock is obtained from the BCLK signal on | 476 | * The SSC transmit clock is obtained from the BCLK signal on |
450 | * on the TK line, and the SSC receive clock is generated from the | 477 | * on the TK line, and the SSC receive clock is generated from the |
@@ -490,10 +517,51 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream, | |||
490 | | (((bits - 1) << 0) & AT91_SSC_DATALEN); | 517 | | (((bits - 1) << 0) & AT91_SSC_DATALEN); |
491 | break; | 518 | break; |
492 | 519 | ||
493 | case SND_SOC_DAIFMT_CBS_CFM: | 520 | case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS: |
494 | case SND_SOC_DAIFMT_CBM_CFS: | 521 | /* |
522 | * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks. | ||
523 | * | ||
524 | * The SSC transmit and receive clocks are generated from the | ||
525 | * MCK divider, and the BCLK signal is output on the SSC TK line. | ||
526 | */ | ||
527 | rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD) | ||
528 | | (( 1 << 16) & AT91_SSC_STTDLY) | ||
529 | | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START) | ||
530 | | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI) | ||
531 | | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO) | ||
532 | | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS); | ||
533 | |||
534 | rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) | ||
535 | | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS) | ||
536 | | (( 0 << 16) & AT91_SSC_FSLEN) | ||
537 | | (((channels - 1) << 8) & AT91_SSC_DATNB) | ||
538 | | (( 1 << 7) & AT91_SSC_MSBF) | ||
539 | | (( 0 << 5) & AT91_SSC_LOOP) | ||
540 | | (((bits - 1) << 0) & AT91_SSC_DATALEN); | ||
541 | |||
542 | tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD) | ||
543 | | (( 1 << 16) & AT91_SSC_STTDLY) | ||
544 | | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START) | ||
545 | | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI) | ||
546 | | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO) | ||
547 | | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS); | ||
548 | |||
549 | tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) | ||
550 | | (( 0 << 23) & AT91_SSC_FSDEN) | ||
551 | | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS) | ||
552 | | (( 0 << 16) & AT91_SSC_FSLEN) | ||
553 | | (((channels - 1) << 8) & AT91_SSC_DATNB) | ||
554 | | (( 1 << 7) & AT91_SSC_MSBF) | ||
555 | | (( 0 << 5) & AT91_SSC_DATDEF) | ||
556 | | (((bits - 1) << 0) & AT91_SSC_DATALEN); | ||
557 | |||
558 | |||
559 | |||
560 | break; | ||
561 | |||
562 | case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM: | ||
495 | default: | 563 | default: |
496 | printk(KERN_WARNING "at91-i2s: unsupported DAI format 0x%x.\n", | 564 | printk(KERN_WARNING "at91-ssc: unsupported DAI format 0x%x.\n", |
497 | ssc_p->daifmt); | 565 | ssc_p->daifmt); |
498 | return -EINVAL; | 566 | return -EINVAL; |
499 | break; | 567 | break; |
@@ -518,9 +586,9 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream, | |||
518 | at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0); | 586 | at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0); |
519 | at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0); | 587 | at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0); |
520 | 588 | ||
521 | if ((ret = request_irq(ssc_p->ssc.pid, at91_i2s_interrupt, | 589 | if ((ret = request_irq(ssc_p->ssc.pid, at91_ssc_interrupt, |
522 | 0, ssc_p->name, ssc_p)) < 0) { | 590 | 0, ssc_p->name, ssc_p)) < 0) { |
523 | printk(KERN_WARNING "at91-i2s: request_irq failure\n"); | 591 | printk(KERN_WARNING "at91-ssc: request_irq failure\n"); |
524 | 592 | ||
525 | DBG("Stopping pid %d clock\n", ssc_p->ssc.pid); | 593 | DBG("Stopping pid %d clock\n", ssc_p->ssc.pid); |
526 | at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid); | 594 | at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid); |
@@ -546,7 +614,7 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream, | |||
546 | } | 614 | } |
547 | 615 | ||
548 | 616 | ||
549 | static int at91_i2s_prepare(struct snd_pcm_substream *substream) | 617 | static int at91_ssc_prepare(struct snd_pcm_substream *substream) |
550 | { | 618 | { |
551 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 619 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
552 | struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; | 620 | struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; |
@@ -566,7 +634,7 @@ static int at91_i2s_prepare(struct snd_pcm_substream *substream) | |||
566 | 634 | ||
567 | 635 | ||
568 | #ifdef CONFIG_PM | 636 | #ifdef CONFIG_PM |
569 | static int at91_i2s_suspend(struct platform_device *pdev, | 637 | static int at91_ssc_suspend(struct platform_device *pdev, |
570 | struct snd_soc_cpu_dai *cpu_dai) | 638 | struct snd_soc_cpu_dai *cpu_dai) |
571 | { | 639 | { |
572 | struct at91_ssc_info *ssc_p; | 640 | struct at91_ssc_info *ssc_p; |
@@ -594,7 +662,7 @@ static int at91_i2s_suspend(struct platform_device *pdev, | |||
594 | return 0; | 662 | return 0; |
595 | } | 663 | } |
596 | 664 | ||
597 | static int at91_i2s_resume(struct platform_device *pdev, | 665 | static int at91_ssc_resume(struct platform_device *pdev, |
598 | struct snd_soc_cpu_dai *cpu_dai) | 666 | struct snd_soc_cpu_dai *cpu_dai) |
599 | { | 667 | { |
600 | struct at91_ssc_info *ssc_p; | 668 | struct at91_ssc_info *ssc_p; |
@@ -620,102 +688,105 @@ static int at91_i2s_resume(struct platform_device *pdev, | |||
620 | } | 688 | } |
621 | 689 | ||
622 | #else | 690 | #else |
623 | #define at91_i2s_suspend NULL | 691 | #define at91_ssc_suspend NULL |
624 | #define at91_i2s_resume NULL | 692 | #define at91_ssc_resume NULL |
625 | #endif | 693 | #endif |
626 | 694 | ||
627 | #define AT91_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ | 695 | #define AT91_SSC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ |
628 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ | 696 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ |
629 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ | 697 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ |
630 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ | 698 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ |
631 | SNDRV_PCM_RATE_96000) | 699 | SNDRV_PCM_RATE_96000) |
632 | 700 | ||
633 | struct snd_soc_cpu_dai at91_i2s_dai[NUM_SSC_DEVICES] = { | 701 | #define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ |
634 | { .name = "at91_ssc0/i2s", | 702 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) |
703 | |||
704 | struct snd_soc_cpu_dai at91_ssc_dai[NUM_SSC_DEVICES] = { | ||
705 | { .name = "at91-ssc0", | ||
635 | .id = 0, | 706 | .id = 0, |
636 | .type = SND_SOC_DAI_I2S, | 707 | .type = SND_SOC_DAI_PCM, |
637 | .suspend = at91_i2s_suspend, | 708 | .suspend = at91_ssc_suspend, |
638 | .resume = at91_i2s_resume, | 709 | .resume = at91_ssc_resume, |
639 | .playback = { | 710 | .playback = { |
640 | .channels_min = 1, | 711 | .channels_min = 1, |
641 | .channels_max = 2, | 712 | .channels_max = 2, |
642 | .rates = AT91_I2S_RATES, | 713 | .rates = AT91_SSC_RATES, |
643 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 714 | .formats = AT91_SSC_FORMATS,}, |
644 | .capture = { | 715 | .capture = { |
645 | .channels_min = 1, | 716 | .channels_min = 1, |
646 | .channels_max = 2, | 717 | .channels_max = 2, |
647 | .rates = AT91_I2S_RATES, | 718 | .rates = AT91_SSC_RATES, |
648 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 719 | .formats = AT91_SSC_FORMATS,}, |
649 | .ops = { | 720 | .ops = { |
650 | .startup = at91_i2s_startup, | 721 | .startup = at91_ssc_startup, |
651 | .shutdown = at91_i2s_shutdown, | 722 | .shutdown = at91_ssc_shutdown, |
652 | .prepare = at91_i2s_prepare, | 723 | .prepare = at91_ssc_prepare, |
653 | .hw_params = at91_i2s_hw_params,}, | 724 | .hw_params = at91_ssc_hw_params,}, |
654 | .dai_ops = { | 725 | .dai_ops = { |
655 | .set_sysclk = at91_i2s_set_dai_sysclk, | 726 | .set_sysclk = at91_ssc_set_dai_sysclk, |
656 | .set_fmt = at91_i2s_set_dai_fmt, | 727 | .set_fmt = at91_ssc_set_dai_fmt, |
657 | .set_clkdiv = at91_i2s_set_dai_clkdiv,}, | 728 | .set_clkdiv = at91_ssc_set_dai_clkdiv,}, |
658 | .private_data = &ssc_info[0].ssc, | 729 | .private_data = &ssc_info[0].ssc, |
659 | }, | 730 | }, |
660 | #if NUM_SSC_DEVICES == 3 | 731 | #if NUM_SSC_DEVICES == 3 |
661 | { .name = "at91_ssc1/i2s", | 732 | { .name = "at91-ssc1", |
662 | .id = 1, | 733 | .id = 1, |
663 | .type = SND_SOC_DAI_I2S, | 734 | .type = SND_SOC_DAI_PCM, |
664 | .suspend = at91_i2s_suspend, | 735 | .suspend = at91_ssc_suspend, |
665 | .resume = at91_i2s_resume, | 736 | .resume = at91_ssc_resume, |
666 | .playback = { | 737 | .playback = { |
667 | .channels_min = 1, | 738 | .channels_min = 1, |
668 | .channels_max = 2, | 739 | .channels_max = 2, |
669 | .rates = AT91_I2S_RATES, | 740 | .rates = AT91_SSC_RATES, |
670 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 741 | .formats = AT91_SSC_FORMATS,}, |
671 | .capture = { | 742 | .capture = { |
672 | .channels_min = 1, | 743 | .channels_min = 1, |
673 | .channels_max = 2, | 744 | .channels_max = 2, |
674 | .rates = AT91_I2S_RATES, | 745 | .rates = AT91_SSC_RATES, |
675 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 746 | .formats = AT91_SSC_FORMATS,}, |
676 | .ops = { | 747 | .ops = { |
677 | .startup = at91_i2s_startup, | 748 | .startup = at91_ssc_startup, |
678 | .shutdown = at91_i2s_shutdown, | 749 | .shutdown = at91_ssc_shutdown, |
679 | .prepare = at91_i2s_prepare, | 750 | .prepare = at91_ssc_prepare, |
680 | .hw_params = at91_i2s_hw_params,}, | 751 | .hw_params = at91_ssc_hw_params,}, |
681 | .dai_ops = { | 752 | .dai_ops = { |
682 | .set_sysclk = at91_i2s_set_dai_sysclk, | 753 | .set_sysclk = at91_ssc_set_dai_sysclk, |
683 | .set_fmt = at91_i2s_set_dai_fmt, | 754 | .set_fmt = at91_ssc_set_dai_fmt, |
684 | .set_clkdiv = at91_i2s_set_dai_clkdiv,}, | 755 | .set_clkdiv = at91_ssc_set_dai_clkdiv,}, |
685 | .private_data = &ssc_info[1].ssc, | 756 | .private_data = &ssc_info[1].ssc, |
686 | }, | 757 | }, |
687 | { .name = "at91_ssc2/i2s", | 758 | { .name = "at91-ssc2", |
688 | .id = 2, | 759 | .id = 2, |
689 | .type = SND_SOC_DAI_I2S, | 760 | .type = SND_SOC_DAI_PCM, |
690 | .suspend = at91_i2s_suspend, | 761 | .suspend = at91_ssc_suspend, |
691 | .resume = at91_i2s_resume, | 762 | .resume = at91_ssc_resume, |
692 | .playback = { | 763 | .playback = { |
693 | .channels_min = 1, | 764 | .channels_min = 1, |
694 | .channels_max = 2, | 765 | .channels_max = 2, |
695 | .rates = AT91_I2S_RATES, | 766 | .rates = AT91_SSC_RATES, |
696 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 767 | .formats = AT91_SSC_FORMATS,}, |
697 | .capture = { | 768 | .capture = { |
698 | .channels_min = 1, | 769 | .channels_min = 1, |
699 | .channels_max = 2, | 770 | .channels_max = 2, |
700 | .rates = AT91_I2S_RATES, | 771 | .rates = AT91_SSC_RATES, |
701 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 772 | .formats = AT91_SSC_FORMATS,}, |
702 | .ops = { | 773 | .ops = { |
703 | .startup = at91_i2s_startup, | 774 | .startup = at91_ssc_startup, |
704 | .shutdown = at91_i2s_shutdown, | 775 | .shutdown = at91_ssc_shutdown, |
705 | .prepare = at91_i2s_prepare, | 776 | .prepare = at91_ssc_prepare, |
706 | .hw_params = at91_i2s_hw_params,}, | 777 | .hw_params = at91_ssc_hw_params,}, |
707 | .dai_ops = { | 778 | .dai_ops = { |
708 | .set_sysclk = at91_i2s_set_dai_sysclk, | 779 | .set_sysclk = at91_ssc_set_dai_sysclk, |
709 | .set_fmt = at91_i2s_set_dai_fmt, | 780 | .set_fmt = at91_ssc_set_dai_fmt, |
710 | .set_clkdiv = at91_i2s_set_dai_clkdiv,}, | 781 | .set_clkdiv = at91_ssc_set_dai_clkdiv,}, |
711 | .private_data = &ssc_info[2].ssc, | 782 | .private_data = &ssc_info[2].ssc, |
712 | }, | 783 | }, |
713 | #endif | 784 | #endif |
714 | }; | 785 | }; |
715 | 786 | ||
716 | EXPORT_SYMBOL_GPL(at91_i2s_dai); | 787 | EXPORT_SYMBOL_GPL(at91_ssc_dai); |
717 | 788 | ||
718 | /* Module information */ | 789 | /* Module information */ |
719 | MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com"); | 790 | MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com"); |
720 | MODULE_DESCRIPTION("AT91 I2S ASoC Interface"); | 791 | MODULE_DESCRIPTION("AT91 SSC ASoC Interface"); |
721 | MODULE_LICENSE("GPL"); | 792 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/at91/at91-i2s.h b/sound/soc/at91/at91-ssc.h index f8a875ba0ccc..b188f973df9f 100644 --- a/sound/soc/at91/at91-i2s.h +++ b/sound/soc/at91/at91-ssc.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * at91-i2s.h - ALSA I2S interface for the Atmel AT91 SoC | 2 | * at91-ssc.h - ALSA SSC interface for the Atmel AT91 SoC |
3 | * | 3 | * |
4 | * Author: Frank Mandarino <fmandarino@endrelia.com> | 4 | * Author: Frank Mandarino <fmandarino@endrelia.com> |
5 | * Endrelia Technologies Inc. | 5 | * Endrelia Technologies Inc. |
@@ -10,18 +10,18 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifndef _AT91_I2S_H | 13 | #ifndef _AT91_SSC_H |
14 | #define _AT91_I2S_H | 14 | #define _AT91_SSC_H |
15 | 15 | ||
16 | /* I2S system clock ids */ | 16 | /* SSC system clock ids */ |
17 | #define AT91_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */ | 17 | #define AT91_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */ |
18 | 18 | ||
19 | /* I2S divider ids */ | 19 | /* SSC divider ids */ |
20 | #define AT91SSC_CMR_DIV 0 /* MCK divider for BCLK */ | 20 | #define AT91SSC_CMR_DIV 0 /* MCK divider for BCLK */ |
21 | #define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */ | 21 | #define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */ |
22 | #define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */ | 22 | #define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */ |
23 | 23 | ||
24 | extern struct snd_soc_cpu_dai at91_i2s_dai[]; | 24 | extern struct snd_soc_cpu_dai at91_ssc_dai[]; |
25 | 25 | ||
26 | #endif /* _AT91_I2S_H */ | 26 | #endif /* _AT91_SSC_H */ |
27 | 27 | ||
diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c index 8179df3bb2f3..820a676c56bf 100644 --- a/sound/soc/at91/eti_b1_wm8731.c +++ b/sound/soc/at91/eti_b1_wm8731.c | |||
@@ -40,7 +40,7 @@ | |||
40 | 40 | ||
41 | #include "../codecs/wm8731.h" | 41 | #include "../codecs/wm8731.h" |
42 | #include "at91-pcm.h" | 42 | #include "at91-pcm.h" |
43 | #include "at91-i2s.h" | 43 | #include "at91-ssc.h" |
44 | 44 | ||
45 | #if 0 | 45 | #if 0 |
46 | #define DBG(x...) printk(KERN_INFO "eti_b1_wm8731: " x) | 46 | #define DBG(x...) printk(KERN_INFO "eti_b1_wm8731: " x) |
@@ -248,15 +248,15 @@ static int eti_b1_wm8731_init(struct snd_soc_codec *codec) | |||
248 | 248 | ||
249 | static struct snd_soc_dai_link eti_b1_dai = { | 249 | static struct snd_soc_dai_link eti_b1_dai = { |
250 | .name = "WM8731", | 250 | .name = "WM8731", |
251 | .stream_name = "WM8731", | 251 | .stream_name = "WM8731 PCM", |
252 | .cpu_dai = &at91_i2s_dai[1], | 252 | .cpu_dai = &at91_ssc_dai[1], |
253 | .codec_dai = &wm8731_dai, | 253 | .codec_dai = &wm8731_dai, |
254 | .init = eti_b1_wm8731_init, | 254 | .init = eti_b1_wm8731_init, |
255 | .ops = &eti_b1_ops, | 255 | .ops = &eti_b1_ops, |
256 | }; | 256 | }; |
257 | 257 | ||
258 | static struct snd_soc_machine snd_soc_machine_eti_b1 = { | 258 | static struct snd_soc_machine snd_soc_machine_eti_b1 = { |
259 | .name = "ETI_B1", | 259 | .name = "ETI_B1_WM8731", |
260 | .dai_link = &eti_b1_dai, | 260 | .dai_link = &eti_b1_dai, |
261 | .num_links = 1, | 261 | .num_links = 1, |
262 | }; | 262 | }; |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index ec2a2787957a..e5fb437b86e8 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -10,6 +10,10 @@ config SND_SOC_WM8750 | |||
10 | tristate | 10 | tristate |
11 | depends on SND_SOC | 11 | depends on SND_SOC |
12 | 12 | ||
13 | config SND_SOC_WM8753 | ||
14 | tristate | ||
15 | depends on SND_SOC | ||
16 | |||
13 | config SND_SOC_WM9712 | 17 | config SND_SOC_WM9712 |
14 | tristate | 18 | tristate |
15 | depends on SND_SOC | 19 | depends on SND_SOC |
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3249a6e4f1d0..e39a747a17cf 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -1,9 +1,11 @@ | |||
1 | snd-soc-ac97-objs := ac97.o | 1 | snd-soc-ac97-objs := ac97.o |
2 | snd-soc-wm8731-objs := wm8731.o | 2 | snd-soc-wm8731-objs := wm8731.o |
3 | snd-soc-wm8750-objs := wm8750.o | 3 | snd-soc-wm8750-objs := wm8750.o |
4 | snd-soc-wm8753-objs := wm8753.o | ||
4 | snd-soc-wm9712-objs := wm9712.o | 5 | snd-soc-wm9712-objs := wm9712.o |
5 | 6 | ||
6 | obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o | 7 | obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o |
7 | obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o | 8 | obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o |
8 | obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o | 9 | obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o |
10 | obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o | ||
9 | obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o | 11 | obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o |
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 55bc55eb6e24..0cdef971cbd3 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c | |||
@@ -60,6 +60,7 @@ static struct snd_soc_codec_dai ac97_dai = { | |||
60 | .ops = { | 60 | .ops = { |
61 | .prepare = ac97_prepare,}, | 61 | .prepare = ac97_prepare,}, |
62 | }; | 62 | }; |
63 | EXPORT_SYMBOL_GPL(ac97_dai); | ||
63 | 64 | ||
64 | static unsigned int ac97_read(struct snd_soc_codec *codec, | 65 | static unsigned int ac97_read(struct snd_soc_codec *codec, |
65 | unsigned int reg) | 66 | unsigned int reg) |
diff --git a/sound/soc/codecs/ac97.h b/sound/soc/codecs/ac97.h index 930ddfc2321a..2bf6d69fd069 100644 --- a/sound/soc/codecs/ac97.h +++ b/sound/soc/codecs/ac97.h | |||
@@ -14,5 +14,6 @@ | |||
14 | #define __LINUX_SND_SOC_AC97_H | 14 | #define __LINUX_SND_SOC_AC97_H |
15 | 15 | ||
16 | extern struct snd_soc_codec_device soc_codec_dev_ac97; | 16 | extern struct snd_soc_codec_device soc_codec_dev_ac97; |
17 | extern struct snd_soc_codec_dai ac97_dai; | ||
17 | 18 | ||
18 | #endif | 19 | #endif |
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 7073e8e294fc..28684eeda738 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
@@ -808,7 +808,7 @@ static int wm8750_init(struct snd_soc_device *socdev) | |||
808 | codec->dai = &wm8750_dai; | 808 | codec->dai = &wm8750_dai; |
809 | codec->num_dai = 1; | 809 | codec->num_dai = 1; |
810 | codec->reg_cache_size = sizeof(wm8750_reg); | 810 | codec->reg_cache_size = sizeof(wm8750_reg); |
811 | codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KRENEL); | 811 | codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL); |
812 | if (codec->reg_cache == NULL) | 812 | if (codec->reg_cache == NULL) |
813 | return -ENOMEM; | 813 | return -ENOMEM; |
814 | 814 | ||
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c new file mode 100644 index 000000000000..efced934566d --- /dev/null +++ b/sound/soc/codecs/wm8753.c | |||
@@ -0,0 +1,1811 @@ | |||
1 | /* | ||
2 | * wm8753.c -- WM8753 ALSA Soc Audio driver | ||
3 | * | ||
4 | * Copyright 2003 Wolfson Microelectronics PLC. | ||
5 | * Author: Liam Girdwood | ||
6 | * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * Notes: | ||
14 | * The WM8753 is a low power, high quality stereo codec with integrated PCM | ||
15 | * codec designed for portable digital telephony applications. | ||
16 | * | ||
17 | * Dual DAI:- | ||
18 | * | ||
19 | * This driver support 2 DAI PCM's. This makes the default PCM available for | ||
20 | * HiFi audio (e.g. MP3, ogg) playback/capture and the other PCM available for | ||
21 | * voice. | ||
22 | * | ||
23 | * Please note that the voice PCM can be connected directly to a Bluetooth | ||
24 | * codec or GSM modem and thus cannot be read or written to, although it is | ||
25 | * available to be configured with snd_hw_params(), etc and kcontrols in the | ||
26 | * normal alsa manner. | ||
27 | * | ||
28 | * Fast DAI switching:- | ||
29 | * | ||
30 | * The driver can now fast switch between the DAI configurations via a | ||
31 | * an alsa kcontrol. This allows the PCM to remain open. | ||
32 | * | ||
33 | */ | ||
34 | |||
35 | #include <linux/module.h> | ||
36 | #include <linux/moduleparam.h> | ||
37 | #include <linux/version.h> | ||
38 | #include <linux/kernel.h> | ||
39 | #include <linux/init.h> | ||
40 | #include <linux/delay.h> | ||
41 | #include <linux/pm.h> | ||
42 | #include <linux/i2c.h> | ||
43 | #include <linux/platform_device.h> | ||
44 | #include <sound/driver.h> | ||
45 | #include <sound/core.h> | ||
46 | #include <sound/pcm.h> | ||
47 | #include <sound/pcm_params.h> | ||
48 | #include <sound/soc.h> | ||
49 | #include <sound/soc-dapm.h> | ||
50 | #include <sound/initval.h> | ||
51 | #include <asm/div64.h> | ||
52 | |||
53 | #include "wm8753.h" | ||
54 | |||
55 | #define AUDIO_NAME "wm8753" | ||
56 | #define WM8753_VERSION "0.16" | ||
57 | |||
58 | /* | ||
59 | * Debug | ||
60 | */ | ||
61 | |||
62 | #define WM8753_DEBUG 0 | ||
63 | |||
64 | #ifdef WM8753_DEBUG | ||
65 | #define dbg(format, arg...) \ | ||
66 | printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg) | ||
67 | #else | ||
68 | #define dbg(format, arg...) do {} while (0) | ||
69 | #endif | ||
70 | #define err(format, arg...) \ | ||
71 | printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg) | ||
72 | #define info(format, arg...) \ | ||
73 | printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) | ||
74 | #define warn(format, arg...) \ | ||
75 | printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg) | ||
76 | |||
77 | static int caps_charge = 2000; | ||
78 | module_param(caps_charge, int, 0); | ||
79 | MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); | ||
80 | |||
81 | static void wm8753_set_dai_mode(struct snd_soc_codec *codec, | ||
82 | unsigned int mode); | ||
83 | |||
84 | /* codec private data */ | ||
85 | struct wm8753_priv { | ||
86 | unsigned int sysclk; | ||
87 | unsigned int pcmclk; | ||
88 | }; | ||
89 | |||
90 | /* | ||
91 | * wm8753 register cache | ||
92 | * We can't read the WM8753 register space when we | ||
93 | * are using 2 wire for device control, so we cache them instead. | ||
94 | */ | ||
95 | static const u16 wm8753_reg[] = { | ||
96 | 0x0008, 0x0000, 0x000a, 0x000a, | ||
97 | 0x0033, 0x0000, 0x0007, 0x00ff, | ||
98 | 0x00ff, 0x000f, 0x000f, 0x007b, | ||
99 | 0x0000, 0x0032, 0x0000, 0x00c3, | ||
100 | 0x00c3, 0x00c0, 0x0000, 0x0000, | ||
101 | 0x0000, 0x0000, 0x0000, 0x0000, | ||
102 | 0x0000, 0x0000, 0x0000, 0x0000, | ||
103 | 0x0000, 0x0000, 0x0000, 0x0055, | ||
104 | 0x0005, 0x0050, 0x0055, 0x0050, | ||
105 | 0x0055, 0x0050, 0x0055, 0x0079, | ||
106 | 0x0079, 0x0079, 0x0079, 0x0079, | ||
107 | 0x0000, 0x0000, 0x0000, 0x0000, | ||
108 | 0x0097, 0x0097, 0x0000, 0x0004, | ||
109 | 0x0000, 0x0083, 0x0024, 0x01ba, | ||
110 | 0x0000, 0x0083, 0x0024, 0x01ba, | ||
111 | 0x0000, 0x0000 | ||
112 | }; | ||
113 | |||
114 | /* | ||
115 | * read wm8753 register cache | ||
116 | */ | ||
117 | static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec, | ||
118 | unsigned int reg) | ||
119 | { | ||
120 | u16 *cache = codec->reg_cache; | ||
121 | if (reg < 1 || reg > (ARRAY_SIZE(wm8753_reg) + 1)) | ||
122 | return -1; | ||
123 | return cache[reg - 1]; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * write wm8753 register cache | ||
128 | */ | ||
129 | static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec, | ||
130 | unsigned int reg, unsigned int value) | ||
131 | { | ||
132 | u16 *cache = codec->reg_cache; | ||
133 | if (reg < 1 || reg > 0x3f) | ||
134 | return; | ||
135 | cache[reg - 1] = value; | ||
136 | } | ||
137 | |||
138 | /* | ||
139 | * write to the WM8753 register space | ||
140 | */ | ||
141 | static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg, | ||
142 | unsigned int value) | ||
143 | { | ||
144 | u8 data[2]; | ||
145 | |||
146 | /* data is | ||
147 | * D15..D9 WM8753 register offset | ||
148 | * D8...D0 register data | ||
149 | */ | ||
150 | data[0] = (reg << 1) | ((value >> 8) & 0x0001); | ||
151 | data[1] = value & 0x00ff; | ||
152 | |||
153 | wm8753_write_reg_cache (codec, reg, value); | ||
154 | if (codec->hw_write(codec->control_data, data, 2) == 2) | ||
155 | return 0; | ||
156 | else | ||
157 | return -EIO; | ||
158 | } | ||
159 | |||
160 | #define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0) | ||
161 | |||
162 | /* | ||
163 | * WM8753 Controls | ||
164 | */ | ||
165 | static const char *wm8753_base[] = {"Linear Control", "Adaptive Boost"}; | ||
166 | static const char *wm8753_base_filter[] = | ||
167 | {"130Hz @ 48kHz", "200Hz @ 48kHz", "100Hz @ 16kHz", "400Hz @ 48kHz", | ||
168 | "100Hz @ 8kHz", "200Hz @ 8kHz"}; | ||
169 | static const char *wm8753_treble[] = {"8kHz", "4kHz"}; | ||
170 | static const char *wm8753_alc_func[] = {"Off", "Right", "Left", "Stereo"}; | ||
171 | static const char *wm8753_ng_type[] = {"Constant PGA Gain", "Mute ADC Output"}; | ||
172 | static const char *wm8753_3d_func[] = {"Capture", "Playback"}; | ||
173 | static const char *wm8753_3d_uc[] = {"2.2kHz", "1.5kHz"}; | ||
174 | static const char *wm8753_3d_lc[] = {"200Hz", "500Hz"}; | ||
175 | static const char *wm8753_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz"}; | ||
176 | static const char *wm8753_mono_mix[] = {"Stereo", "Left", "Right", "Mono"}; | ||
177 | static const char *wm8753_dac_phase[] = {"Non Inverted", "Inverted"}; | ||
178 | static const char *wm8753_line_mix[] = {"Line 1 + 2", "Line 1 - 2", | ||
179 | "Line 1", "Line 2"}; | ||
180 | static const char *wm8753_mono_mux[] = {"Line Mix", "Rx Mix"}; | ||
181 | static const char *wm8753_right_mux[] = {"Line 2", "Rx Mix"}; | ||
182 | static const char *wm8753_left_mux[] = {"Line 1", "Rx Mix"}; | ||
183 | static const char *wm8753_rxmsel[] = {"RXP - RXN", "RXP + RXN", "RXP", "RXN"}; | ||
184 | static const char *wm8753_sidetone_mux[] = {"Left PGA", "Mic 1", "Mic 2", | ||
185 | "Right PGA"}; | ||
186 | static const char *wm8753_mono2_src[] = {"Inverted Mono 1", "Left", "Right", | ||
187 | "Left + Right"}; | ||
188 | static const char *wm8753_out3[] = {"VREF", "ROUT2", "Left + Right"}; | ||
189 | static const char *wm8753_out4[] = {"VREF", "Capture ST", "LOUT2"}; | ||
190 | static const char *wm8753_radcsel[] = {"PGA", "Line or RXP-RXN", "Sidetone"}; | ||
191 | static const char *wm8753_ladcsel[] = {"PGA", "Line or RXP-RXN", "Line"}; | ||
192 | static const char *wm8753_mono_adc[] = {"Stereo", "Analogue Mix Left", | ||
193 | "Analogue Mix Right", "Digital Mono Mix"}; | ||
194 | static const char *wm8753_adc_hp[] = {"3.4Hz @ 48kHz", "82Hz @ 16k", | ||
195 | "82Hz @ 8kHz", "170Hz @ 8kHz"}; | ||
196 | static const char *wm8753_adc_filter[] = {"HiFi", "Voice"}; | ||
197 | static const char *wm8753_mic_sel[] = {"Mic 1", "Mic 2", "Mic 3"}; | ||
198 | static const char *wm8753_dai_mode[] = {"DAI 0", "DAI 1", "DAI 2", "DAI 3"}; | ||
199 | static const char *wm8753_dat_sel[] = {"Stereo", "Left ADC", "Right ADC", | ||
200 | "Channel Swap"}; | ||
201 | |||
202 | static const struct soc_enum wm8753_enum[] = { | ||
203 | SOC_ENUM_SINGLE(WM8753_BASS, 7, 2, wm8753_base), | ||
204 | SOC_ENUM_SINGLE(WM8753_BASS, 4, 6, wm8753_base_filter), | ||
205 | SOC_ENUM_SINGLE(WM8753_TREBLE, 6, 2, wm8753_treble), | ||
206 | SOC_ENUM_SINGLE(WM8753_ALC1, 7, 4, wm8753_alc_func), | ||
207 | SOC_ENUM_SINGLE(WM8753_NGATE, 1, 2, wm8753_ng_type), | ||
208 | SOC_ENUM_SINGLE(WM8753_3D, 7, 2, wm8753_3d_func), | ||
209 | SOC_ENUM_SINGLE(WM8753_3D, 6, 2, wm8753_3d_uc), | ||
210 | SOC_ENUM_SINGLE(WM8753_3D, 5, 2, wm8753_3d_lc), | ||
211 | SOC_ENUM_SINGLE(WM8753_DAC, 1, 4, wm8753_deemp), | ||
212 | SOC_ENUM_SINGLE(WM8753_DAC, 4, 4, wm8753_mono_mix), | ||
213 | SOC_ENUM_SINGLE(WM8753_DAC, 6, 2, wm8753_dac_phase), | ||
214 | SOC_ENUM_SINGLE(WM8753_INCTL1, 3, 4, wm8753_line_mix), | ||
215 | SOC_ENUM_SINGLE(WM8753_INCTL1, 2, 2, wm8753_mono_mux), | ||
216 | SOC_ENUM_SINGLE(WM8753_INCTL1, 1, 2, wm8753_right_mux), | ||
217 | SOC_ENUM_SINGLE(WM8753_INCTL1, 0, 2, wm8753_left_mux), | ||
218 | SOC_ENUM_SINGLE(WM8753_INCTL2, 6, 4, wm8753_rxmsel), | ||
219 | SOC_ENUM_SINGLE(WM8753_INCTL2, 4, 4, wm8753_sidetone_mux), | ||
220 | SOC_ENUM_SINGLE(WM8753_OUTCTL, 7, 4, wm8753_mono2_src), | ||
221 | SOC_ENUM_SINGLE(WM8753_OUTCTL, 0, 3, wm8753_out3), | ||
222 | SOC_ENUM_SINGLE(WM8753_ADCTL2, 7, 3, wm8753_out4), | ||
223 | SOC_ENUM_SINGLE(WM8753_ADCIN, 2, 3, wm8753_radcsel), | ||
224 | SOC_ENUM_SINGLE(WM8753_ADCIN, 0, 3, wm8753_ladcsel), | ||
225 | SOC_ENUM_SINGLE(WM8753_ADCIN, 4, 4, wm8753_mono_adc), | ||
226 | SOC_ENUM_SINGLE(WM8753_ADC, 2, 4, wm8753_adc_hp), | ||
227 | SOC_ENUM_SINGLE(WM8753_ADC, 4, 2, wm8753_adc_filter), | ||
228 | SOC_ENUM_SINGLE(WM8753_MICBIAS, 6, 3, wm8753_mic_sel), | ||
229 | SOC_ENUM_SINGLE(WM8753_IOCTL, 2, 4, wm8753_dai_mode), | ||
230 | SOC_ENUM_SINGLE(WM8753_ADC, 7, 4, wm8753_dat_sel), | ||
231 | }; | ||
232 | |||
233 | |||
234 | static int wm8753_get_dai(struct snd_kcontrol *kcontrol, | ||
235 | struct snd_ctl_elem_value *ucontrol) | ||
236 | { | ||
237 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
238 | int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); | ||
239 | |||
240 | ucontrol->value.integer.value[0] = (mode & 0xc) >> 2; | ||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static int wm8753_set_dai(struct snd_kcontrol *kcontrol, | ||
245 | struct snd_ctl_elem_value *ucontrol) | ||
246 | { | ||
247 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
248 | int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); | ||
249 | |||
250 | if (((mode &0xc) >> 2) == ucontrol->value.integer.value[0]) | ||
251 | return 0; | ||
252 | |||
253 | mode &= 0xfff3; | ||
254 | mode |= (ucontrol->value.integer.value[0] << 2); | ||
255 | |||
256 | wm8753_write(codec, WM8753_IOCTL, mode); | ||
257 | wm8753_set_dai_mode(codec, ucontrol->value.integer.value[0]); | ||
258 | return 1; | ||
259 | } | ||
260 | |||
261 | static const struct snd_kcontrol_new wm8753_snd_controls[] = { | ||
262 | SOC_DOUBLE_R("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0), | ||
263 | |||
264 | SOC_DOUBLE_R("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0), | ||
265 | |||
266 | SOC_DOUBLE_R("Headphone Playback Volume", WM8753_LOUT1V, WM8753_ROUT1V, 0, 127, 0), | ||
267 | SOC_DOUBLE_R("Speaker Playback Volume", WM8753_LOUT2V, WM8753_ROUT2V, 0, 127, 0), | ||
268 | |||
269 | SOC_SINGLE("Mono Playback Volume", WM8753_MOUTV, 0, 127, 0), | ||
270 | |||
271 | SOC_DOUBLE_R("Bypass Playback Volume", WM8753_LOUTM1, WM8753_ROUTM1, 4, 7, 1), | ||
272 | SOC_DOUBLE_R("Sidetone Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 4, 7, 1), | ||
273 | SOC_DOUBLE_R("Voice Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 0, 7, 1), | ||
274 | |||
275 | SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V, WM8753_ROUT1V, 7, 1, 0), | ||
276 | SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V, WM8753_ROUT2V, 7, 1, 0), | ||
277 | |||
278 | SOC_SINGLE("Mono Bypass Playback Volume", WM8753_MOUTM1, 4, 7, 1), | ||
279 | SOC_SINGLE("Mono Sidetone Playback Volume", WM8753_MOUTM2, 4, 7, 1), | ||
280 | SOC_SINGLE("Mono Voice Playback Volume", WM8753_MOUTM2, 4, 7, 1), | ||
281 | SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV, 7, 1, 0), | ||
282 | |||
283 | SOC_ENUM("Bass Boost", wm8753_enum[0]), | ||
284 | SOC_ENUM("Bass Filter", wm8753_enum[1]), | ||
285 | SOC_SINGLE("Bass Volume", WM8753_BASS, 0, 15, 1), | ||
286 | |||
287 | SOC_SINGLE("Treble Volume", WM8753_TREBLE, 0, 15, 1), | ||
288 | SOC_ENUM("Treble Cut-off", wm8753_enum[2]), | ||
289 | |||
290 | SOC_DOUBLE("Sidetone Capture Volume", WM8753_RECMIX1, 0, 4, 7, 1), | ||
291 | SOC_SINGLE("Voice Sidetone Capture Volume", WM8753_RECMIX2, 0, 7, 1), | ||
292 | |||
293 | SOC_DOUBLE_R("Capture Volume", WM8753_LINVOL, WM8753_RINVOL, 0, 63, 0), | ||
294 | SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL, WM8753_RINVOL, 6, 1, 0), | ||
295 | SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL, WM8753_RINVOL, 7, 1, 1), | ||
296 | |||
297 | SOC_ENUM("Capture Filter Select", wm8753_enum[23]), | ||
298 | SOC_ENUM("Capture Filter Cut-off", wm8753_enum[24]), | ||
299 | SOC_SINGLE("Capture Filter Switch", WM8753_ADC, 0, 1, 1), | ||
300 | |||
301 | SOC_SINGLE("ALC Capture Target Volume", WM8753_ALC1, 0, 7, 0), | ||
302 | SOC_SINGLE("ALC Capture Max Volume", WM8753_ALC1, 4, 7, 0), | ||
303 | SOC_ENUM("ALC Capture Function", wm8753_enum[3]), | ||
304 | SOC_SINGLE("ALC Capture ZC Switch", WM8753_ALC2, 8, 1, 0), | ||
305 | SOC_SINGLE("ALC Capture Hold Time", WM8753_ALC2, 0, 15, 1), | ||
306 | SOC_SINGLE("ALC Capture Decay Time", WM8753_ALC3, 4, 15, 1), | ||
307 | SOC_SINGLE("ALC Capture Attack Time", WM8753_ALC3, 0, 15, 0), | ||
308 | SOC_SINGLE("ALC Capture NG Threshold", WM8753_NGATE, 3, 31, 0), | ||
309 | SOC_ENUM("ALC Capture NG Type", wm8753_enum[4]), | ||
310 | SOC_SINGLE("ALC Capture NG Switch", WM8753_NGATE, 0, 1, 0), | ||
311 | |||
312 | SOC_ENUM("3D Function", wm8753_enum[5]), | ||
313 | SOC_ENUM("3D Upper Cut-off", wm8753_enum[6]), | ||
314 | SOC_ENUM("3D Lower Cut-off", wm8753_enum[7]), | ||
315 | SOC_SINGLE("3D Volume", WM8753_3D, 1, 15, 0), | ||
316 | SOC_SINGLE("3D Switch", WM8753_3D, 0, 1, 0), | ||
317 | |||
318 | SOC_SINGLE("Capture 6dB Attenuate", WM8753_ADCTL1, 2, 1, 0), | ||
319 | SOC_SINGLE("Playback 6dB Attenuate", WM8753_ADCTL1, 1, 1, 0), | ||
320 | |||
321 | SOC_ENUM("De-emphasis", wm8753_enum[8]), | ||
322 | SOC_ENUM("Playback Mono Mix", wm8753_enum[9]), | ||
323 | SOC_ENUM("Playback Phase", wm8753_enum[10]), | ||
324 | |||
325 | SOC_SINGLE("Mic2 Capture Volume", WM8753_INCTL1, 7, 3, 0), | ||
326 | SOC_SINGLE("Mic1 Capture Volume", WM8753_INCTL1, 5, 3, 0), | ||
327 | |||
328 | SOC_ENUM_EXT("DAI Mode", wm8753_enum[26], wm8753_get_dai, wm8753_set_dai), | ||
329 | |||
330 | SOC_ENUM("ADC Data Select", wm8753_enum[27]), | ||
331 | }; | ||
332 | |||
333 | /* add non dapm controls */ | ||
334 | static int wm8753_add_controls(struct snd_soc_codec *codec) | ||
335 | { | ||
336 | int err, i; | ||
337 | |||
338 | for (i = 0; i < ARRAY_SIZE(wm8753_snd_controls); i++) { | ||
339 | err = snd_ctl_add(codec->card, | ||
340 | snd_soc_cnew(&wm8753_snd_controls[i],codec, NULL)); | ||
341 | if (err < 0) | ||
342 | return err; | ||
343 | } | ||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | /* | ||
348 | * _DAPM_ Controls | ||
349 | */ | ||
350 | |||
351 | /* Left Mixer */ | ||
352 | static const struct snd_kcontrol_new wm8753_left_mixer_controls[] = { | ||
353 | SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_LOUTM2, 8, 1, 0), | ||
354 | SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_LOUTM2, 7, 1, 0), | ||
355 | SOC_DAPM_SINGLE("Left Playback Switch", WM8753_LOUTM1, 8, 1, 0), | ||
356 | SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_LOUTM1, 7, 1, 0), | ||
357 | }; | ||
358 | |||
359 | /* Right mixer */ | ||
360 | static const struct snd_kcontrol_new wm8753_right_mixer_controls[] = { | ||
361 | SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_ROUTM2, 8, 1, 0), | ||
362 | SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_ROUTM2, 7, 1, 0), | ||
363 | SOC_DAPM_SINGLE("Right Playback Switch", WM8753_ROUTM1, 8, 1, 0), | ||
364 | SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_ROUTM1, 7, 1, 0), | ||
365 | }; | ||
366 | |||
367 | /* Mono mixer */ | ||
368 | static const struct snd_kcontrol_new wm8753_mono_mixer_controls[] = { | ||
369 | SOC_DAPM_SINGLE("Left Playback Switch", WM8753_MOUTM1, 8, 1, 0), | ||
370 | SOC_DAPM_SINGLE("Right Playback Switch", WM8753_MOUTM2, 8, 1, 0), | ||
371 | SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_MOUTM2, 3, 1, 0), | ||
372 | SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_MOUTM2, 7, 1, 0), | ||
373 | SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_MOUTM1, 7, 1, 0), | ||
374 | }; | ||
375 | |||
376 | /* Mono 2 Mux */ | ||
377 | static const struct snd_kcontrol_new wm8753_mono2_controls = | ||
378 | SOC_DAPM_ENUM("Route", wm8753_enum[17]); | ||
379 | |||
380 | /* Out 3 Mux */ | ||
381 | static const struct snd_kcontrol_new wm8753_out3_controls = | ||
382 | SOC_DAPM_ENUM("Route", wm8753_enum[18]); | ||
383 | |||
384 | /* Out 4 Mux */ | ||
385 | static const struct snd_kcontrol_new wm8753_out4_controls = | ||
386 | SOC_DAPM_ENUM("Route", wm8753_enum[19]); | ||
387 | |||
388 | /* ADC Mono Mix */ | ||
389 | static const struct snd_kcontrol_new wm8753_adc_mono_controls = | ||
390 | SOC_DAPM_ENUM("Route", wm8753_enum[22]); | ||
391 | |||
392 | /* Record mixer */ | ||
393 | static const struct snd_kcontrol_new wm8753_record_mixer_controls[] = { | ||
394 | SOC_DAPM_SINGLE("Voice Capture Switch", WM8753_RECMIX2, 3, 1, 0), | ||
395 | SOC_DAPM_SINGLE("Left Capture Switch", WM8753_RECMIX1, 3, 1, 0), | ||
396 | SOC_DAPM_SINGLE("Right Capture Switch", WM8753_RECMIX1, 7, 1, 0), | ||
397 | }; | ||
398 | |||
399 | /* Left ADC mux */ | ||
400 | static const struct snd_kcontrol_new wm8753_adc_left_controls = | ||
401 | SOC_DAPM_ENUM("Route", wm8753_enum[21]); | ||
402 | |||
403 | /* Right ADC mux */ | ||
404 | static const struct snd_kcontrol_new wm8753_adc_right_controls = | ||
405 | SOC_DAPM_ENUM("Route", wm8753_enum[20]); | ||
406 | |||
407 | /* MIC mux */ | ||
408 | static const struct snd_kcontrol_new wm8753_mic_mux_controls = | ||
409 | SOC_DAPM_ENUM("Route", wm8753_enum[16]); | ||
410 | |||
411 | /* ALC mixer */ | ||
412 | static const struct snd_kcontrol_new wm8753_alc_mixer_controls[] = { | ||
413 | SOC_DAPM_SINGLE("Line Capture Switch", WM8753_INCTL2, 3, 1, 0), | ||
414 | SOC_DAPM_SINGLE("Mic2 Capture Switch", WM8753_INCTL2, 2, 1, 0), | ||
415 | SOC_DAPM_SINGLE("Mic1 Capture Switch", WM8753_INCTL2, 1, 1, 0), | ||
416 | SOC_DAPM_SINGLE("Rx Capture Switch", WM8753_INCTL2, 0, 1, 0), | ||
417 | }; | ||
418 | |||
419 | /* Left Line mux */ | ||
420 | static const struct snd_kcontrol_new wm8753_line_left_controls = | ||
421 | SOC_DAPM_ENUM("Route", wm8753_enum[14]); | ||
422 | |||
423 | /* Right Line mux */ | ||
424 | static const struct snd_kcontrol_new wm8753_line_right_controls = | ||
425 | SOC_DAPM_ENUM("Route", wm8753_enum[13]); | ||
426 | |||
427 | /* Mono Line mux */ | ||
428 | static const struct snd_kcontrol_new wm8753_line_mono_controls = | ||
429 | SOC_DAPM_ENUM("Route", wm8753_enum[12]); | ||
430 | |||
431 | /* Line mux and mixer */ | ||
432 | static const struct snd_kcontrol_new wm8753_line_mux_mix_controls = | ||
433 | SOC_DAPM_ENUM("Route", wm8753_enum[11]); | ||
434 | |||
435 | /* Rx mux and mixer */ | ||
436 | static const struct snd_kcontrol_new wm8753_rx_mux_mix_controls = | ||
437 | SOC_DAPM_ENUM("Route", wm8753_enum[15]); | ||
438 | |||
439 | /* Mic Selector Mux */ | ||
440 | static const struct snd_kcontrol_new wm8753_mic_sel_mux_controls = | ||
441 | SOC_DAPM_ENUM("Route", wm8753_enum[25]); | ||
442 | |||
443 | static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { | ||
444 | SND_SOC_DAPM_MICBIAS("Mic Bias", WM8753_PWR1, 5, 0), | ||
445 | SND_SOC_DAPM_MIXER("Left Mixer", WM8753_PWR4, 0, 0, | ||
446 | &wm8753_left_mixer_controls[0], ARRAY_SIZE(wm8753_left_mixer_controls)), | ||
447 | SND_SOC_DAPM_PGA("Left Out 1", WM8753_PWR3, 8, 0, NULL, 0), | ||
448 | SND_SOC_DAPM_PGA("Left Out 2", WM8753_PWR3, 6, 0, NULL, 0), | ||
449 | SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", WM8753_PWR1, 3, 0), | ||
450 | SND_SOC_DAPM_OUTPUT("LOUT1"), | ||
451 | SND_SOC_DAPM_OUTPUT("LOUT2"), | ||
452 | SND_SOC_DAPM_MIXER("Right Mixer", WM8753_PWR4, 1, 0, | ||
453 | &wm8753_right_mixer_controls[0], ARRAY_SIZE(wm8753_right_mixer_controls)), | ||
454 | SND_SOC_DAPM_PGA("Right Out 1", WM8753_PWR3, 7, 0, NULL, 0), | ||
455 | SND_SOC_DAPM_PGA("Right Out 2", WM8753_PWR3, 5, 0, NULL, 0), | ||
456 | SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", WM8753_PWR1, 2, 0), | ||
457 | SND_SOC_DAPM_OUTPUT("ROUT1"), | ||
458 | SND_SOC_DAPM_OUTPUT("ROUT2"), | ||
459 | SND_SOC_DAPM_MIXER("Mono Mixer", WM8753_PWR4, 2, 0, | ||
460 | &wm8753_mono_mixer_controls[0], ARRAY_SIZE(wm8753_mono_mixer_controls)), | ||
461 | SND_SOC_DAPM_PGA("Mono Out 1", WM8753_PWR3, 2, 0, NULL, 0), | ||
462 | SND_SOC_DAPM_PGA("Mono Out 2", WM8753_PWR3, 1, 0, NULL, 0), | ||
463 | SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", WM8753_PWR1, 4, 0), | ||
464 | SND_SOC_DAPM_OUTPUT("MONO1"), | ||
465 | SND_SOC_DAPM_MUX("Mono 2 Mux", SND_SOC_NOPM, 0, 0, &wm8753_mono2_controls), | ||
466 | SND_SOC_DAPM_OUTPUT("MONO2"), | ||
467 | SND_SOC_DAPM_MIXER("Out3 Left + Right", -1, 0, 0, NULL, 0), | ||
468 | SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out3_controls), | ||
469 | SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3, 4, 0, NULL, 0), | ||
470 | SND_SOC_DAPM_OUTPUT("OUT3"), | ||
471 | SND_SOC_DAPM_MUX("Out4 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out4_controls), | ||
472 | SND_SOC_DAPM_PGA("Out 4", WM8753_PWR3, 3, 0, NULL, 0), | ||
473 | SND_SOC_DAPM_OUTPUT("OUT4"), | ||
474 | SND_SOC_DAPM_MIXER("Playback Mixer", WM8753_PWR4, 3, 0, | ||
475 | &wm8753_record_mixer_controls[0], | ||
476 | ARRAY_SIZE(wm8753_record_mixer_controls)), | ||
477 | SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8753_PWR2, 3, 0), | ||
478 | SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8753_PWR2, 2, 0), | ||
479 | SND_SOC_DAPM_MUX("Capture Left Mixer", SND_SOC_NOPM, 0, 0, | ||
480 | &wm8753_adc_mono_controls), | ||
481 | SND_SOC_DAPM_MUX("Capture Right Mixer", SND_SOC_NOPM, 0, 0, | ||
482 | &wm8753_adc_mono_controls), | ||
483 | SND_SOC_DAPM_MUX("Capture Left Mux", SND_SOC_NOPM, 0, 0, | ||
484 | &wm8753_adc_left_controls), | ||
485 | SND_SOC_DAPM_MUX("Capture Right Mux", SND_SOC_NOPM, 0, 0, | ||
486 | &wm8753_adc_right_controls), | ||
487 | SND_SOC_DAPM_MUX("Mic Sidetone Mux", SND_SOC_NOPM, 0, 0, | ||
488 | &wm8753_mic_mux_controls), | ||
489 | SND_SOC_DAPM_PGA("Left Capture Volume", WM8753_PWR2, 5, 0, NULL, 0), | ||
490 | SND_SOC_DAPM_PGA("Right Capture Volume", WM8753_PWR2, 4, 0, NULL, 0), | ||
491 | SND_SOC_DAPM_MIXER("ALC Mixer", WM8753_PWR2, 6, 0, | ||
492 | &wm8753_alc_mixer_controls[0], ARRAY_SIZE(wm8753_alc_mixer_controls)), | ||
493 | SND_SOC_DAPM_MUX("Line Left Mux", SND_SOC_NOPM, 0, 0, | ||
494 | &wm8753_line_left_controls), | ||
495 | SND_SOC_DAPM_MUX("Line Right Mux", SND_SOC_NOPM, 0, 0, | ||
496 | &wm8753_line_right_controls), | ||
497 | SND_SOC_DAPM_MUX("Line Mono Mux", SND_SOC_NOPM, 0, 0, | ||
498 | &wm8753_line_mono_controls), | ||
499 | SND_SOC_DAPM_MUX("Line Mixer", WM8753_PWR2, 0, 0, | ||
500 | &wm8753_line_mux_mix_controls), | ||
501 | SND_SOC_DAPM_MUX("Rx Mixer", WM8753_PWR2, 1, 0, | ||
502 | &wm8753_rx_mux_mix_controls), | ||
503 | SND_SOC_DAPM_PGA("Mic 1 Volume", WM8753_PWR2, 8, 0, NULL, 0), | ||
504 | SND_SOC_DAPM_PGA("Mic 2 Volume", WM8753_PWR2, 7, 0, NULL, 0), | ||
505 | SND_SOC_DAPM_MUX("Mic Selection Mux", SND_SOC_NOPM, 0, 0, | ||
506 | &wm8753_mic_sel_mux_controls), | ||
507 | SND_SOC_DAPM_INPUT("LINE1"), | ||
508 | SND_SOC_DAPM_INPUT("LINE2"), | ||
509 | SND_SOC_DAPM_INPUT("RXP"), | ||
510 | SND_SOC_DAPM_INPUT("RXN"), | ||
511 | SND_SOC_DAPM_INPUT("ACIN"), | ||
512 | SND_SOC_DAPM_OUTPUT("ACOP"), | ||
513 | SND_SOC_DAPM_INPUT("MIC1N"), | ||
514 | SND_SOC_DAPM_INPUT("MIC1"), | ||
515 | SND_SOC_DAPM_INPUT("MIC2N"), | ||
516 | SND_SOC_DAPM_INPUT("MIC2"), | ||
517 | SND_SOC_DAPM_VMID("VREF"), | ||
518 | }; | ||
519 | |||
520 | static const char *audio_map[][3] = { | ||
521 | /* left mixer */ | ||
522 | {"Left Mixer", "Left Playback Switch", "Left DAC"}, | ||
523 | {"Left Mixer", "Voice Playback Switch", "Voice DAC"}, | ||
524 | {"Left Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"}, | ||
525 | {"Left Mixer", "Bypass Playback Switch", "Line Left Mux"}, | ||
526 | |||
527 | /* right mixer */ | ||
528 | {"Right Mixer", "Right Playback Switch", "Right DAC"}, | ||
529 | {"Right Mixer", "Voice Playback Switch", "Voice DAC"}, | ||
530 | {"Right Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"}, | ||
531 | {"Right Mixer", "Bypass Playback Switch", "Line Right Mux"}, | ||
532 | |||
533 | /* mono mixer */ | ||
534 | {"Mono Mixer", "Voice Playback Switch", "Voice DAC"}, | ||
535 | {"Mono Mixer", "Left Playback Switch", "Left DAC"}, | ||
536 | {"Mono Mixer", "Right Playback Switch", "Right DAC"}, | ||
537 | {"Mono Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"}, | ||
538 | {"Mono Mixer", "Bypass Playback Switch", "Line Mono Mux"}, | ||
539 | |||
540 | /* left out */ | ||
541 | {"Left Out 1", NULL, "Left Mixer"}, | ||
542 | {"Left Out 2", NULL, "Left Mixer"}, | ||
543 | {"LOUT1", NULL, "Left Out 1"}, | ||
544 | {"LOUT2", NULL, "Left Out 2"}, | ||
545 | |||
546 | /* right out */ | ||
547 | {"Right Out 1", NULL, "Right Mixer"}, | ||
548 | {"Right Out 2", NULL, "Right Mixer"}, | ||
549 | {"ROUT1", NULL, "Right Out 1"}, | ||
550 | {"ROUT2", NULL, "Right Out 2"}, | ||
551 | |||
552 | /* mono 1 out */ | ||
553 | {"Mono Out 1", NULL, "Mono Mixer"}, | ||
554 | {"MONO1", NULL, "Mono Out 1"}, | ||
555 | |||
556 | /* mono 2 out */ | ||
557 | {"Mono 2 Mux", "Left + Right", "Out3 Left + Right"}, | ||
558 | {"Mono 2 Mux", "Inverted Mono 1", "MONO1"}, | ||
559 | {"Mono 2 Mux", "Left", "Left Mixer"}, | ||
560 | {"Mono 2 Mux", "Right", "Right Mixer"}, | ||
561 | {"Mono Out 2", NULL, "Mono 2 Mux"}, | ||
562 | {"MONO2", NULL, "Mono Out 2"}, | ||
563 | |||
564 | /* out 3 */ | ||
565 | {"Out3 Left + Right", NULL, "Left Mixer"}, | ||
566 | {"Out3 Left + Right", NULL, "Right Mixer"}, | ||
567 | {"Out3 Mux", "VREF", "VREF"}, | ||
568 | {"Out3 Mux", "Left + Right", "Out3 Left + Right"}, | ||
569 | {"Out3 Mux", "ROUT2", "ROUT2"}, | ||
570 | {"Out 3", NULL, "Out3 Mux"}, | ||
571 | {"OUT3", NULL, "Out 3"}, | ||
572 | |||
573 | /* out 4 */ | ||
574 | {"Out4 Mux", "VREF", "VREF"}, | ||
575 | {"Out4 Mux", "Capture ST", "Capture ST Mixer"}, | ||
576 | {"Out4 Mux", "LOUT2", "LOUT2"}, | ||
577 | {"Out 4", NULL, "Out4 Mux"}, | ||
578 | {"OUT4", NULL, "Out 4"}, | ||
579 | |||
580 | /* record mixer */ | ||
581 | {"Playback Mixer", "Left Capture Switch", "Left Mixer"}, | ||
582 | {"Playback Mixer", "Voice Capture Switch", "Mono Mixer"}, | ||
583 | {"Playback Mixer", "Right Capture Switch", "Right Mixer"}, | ||
584 | |||
585 | /* Mic/SideTone Mux */ | ||
586 | {"Mic Sidetone Mux", "Left PGA", "Left Capture Volume"}, | ||
587 | {"Mic Sidetone Mux", "Right PGA", "Right Capture Volume"}, | ||
588 | {"Mic Sidetone Mux", "Mic 1", "Mic 1 Volume"}, | ||
589 | {"Mic Sidetone Mux", "Mic 2", "Mic 2 Volume"}, | ||
590 | |||
591 | /* Capture Left Mux */ | ||
592 | {"Capture Left Mux", "PGA", "Left Capture Volume"}, | ||
593 | {"Capture Left Mux", "Line or RXP-RXN", "Line Left Mux"}, | ||
594 | {"Capture Left Mux", "Line", "LINE1"}, | ||
595 | |||
596 | /* Capture Right Mux */ | ||
597 | {"Capture Right Mux", "PGA", "Right Capture Volume"}, | ||
598 | {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"}, | ||
599 | {"Capture Right Mux", "Sidetone", "Capture ST Mixer"}, | ||
600 | |||
601 | /* Mono Capture mixer-mux */ | ||
602 | {"Capture Right Mixer", "Stereo", "Capture Right Mux"}, | ||
603 | {"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"}, | ||
604 | {"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"}, | ||
605 | {"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"}, | ||
606 | {"Capture Right Mixer", "Analogue Mix Right", "Capture Right Mux"}, | ||
607 | {"Capture Left Mixer", "Digital Mono Mix", "Capture Left Mux"}, | ||
608 | {"Capture Left Mixer", "Digital Mono Mix", "Capture Right Mux"}, | ||
609 | {"Capture Right Mixer", "Digital Mono Mix", "Capture Left Mux"}, | ||
610 | {"Capture Right Mixer", "Digital Mono Mix", "Capture Right Mux"}, | ||
611 | |||
612 | /* ADC */ | ||
613 | {"Left ADC", NULL, "Capture Left Mixer"}, | ||
614 | {"Right ADC", NULL, "Capture Right Mixer"}, | ||
615 | |||
616 | /* Left Capture Volume */ | ||
617 | {"Left Capture Volume", NULL, "ACIN"}, | ||
618 | |||
619 | /* Right Capture Volume */ | ||
620 | {"Right Capture Volume", NULL, "Mic 2 Volume"}, | ||
621 | |||
622 | /* ALC Mixer */ | ||
623 | {"ALC Mixer", "Line Capture Switch", "Line Mixer"}, | ||
624 | {"ALC Mixer", "Mic2 Capture Switch", "Mic 2 Volume"}, | ||
625 | {"ALC Mixer", "Mic1 Capture Switch", "Mic 1 Volume"}, | ||
626 | {"ALC Mixer", "Rx Capture Switch", "Rx Mixer"}, | ||
627 | |||
628 | /* Line Left Mux */ | ||
629 | {"Line Left Mux", "Line 1", "LINE1"}, | ||
630 | {"Line Left Mux", "Rx Mix", "Rx Mixer"}, | ||
631 | |||
632 | /* Line Right Mux */ | ||
633 | {"Line Right Mux", "Line 2", "LINE2"}, | ||
634 | {"Line Right Mux", "Rx Mix", "Rx Mixer"}, | ||
635 | |||
636 | /* Line Mono Mux */ | ||
637 | {"Line Mono Mux", "Line Mix", "Line Mixer"}, | ||
638 | {"Line Mono Mux", "Rx Mix", "Rx Mixer"}, | ||
639 | |||
640 | /* Line Mixer/Mux */ | ||
641 | {"Line Mixer", "Line 1 + 2", "LINE1"}, | ||
642 | {"Line Mixer", "Line 1 - 2", "LINE1"}, | ||
643 | {"Line Mixer", "Line 1 + 2", "LINE2"}, | ||
644 | {"Line Mixer", "Line 1 - 2", "LINE2"}, | ||
645 | {"Line Mixer", "Line 1", "LINE1"}, | ||
646 | {"Line Mixer", "Line 2", "LINE2"}, | ||
647 | |||
648 | /* Rx Mixer/Mux */ | ||
649 | {"Rx Mixer", "RXP - RXN", "RXP"}, | ||
650 | {"Rx Mixer", "RXP + RXN", "RXP"}, | ||
651 | {"Rx Mixer", "RXP - RXN", "RXN"}, | ||
652 | {"Rx Mixer", "RXP + RXN", "RXN"}, | ||
653 | {"Rx Mixer", "RXP", "RXP"}, | ||
654 | {"Rx Mixer", "RXN", "RXN"}, | ||
655 | |||
656 | /* Mic 1 Volume */ | ||
657 | {"Mic 1 Volume", NULL, "MIC1N"}, | ||
658 | {"Mic 1 Volume", NULL, "Mic Selection Mux"}, | ||
659 | |||
660 | /* Mic 2 Volume */ | ||
661 | {"Mic 2 Volume", NULL, "MIC2N"}, | ||
662 | {"Mic 2 Volume", NULL, "MIC2"}, | ||
663 | |||
664 | /* Mic Selector Mux */ | ||
665 | {"Mic Selection Mux", "Mic 1", "MIC1"}, | ||
666 | {"Mic Selection Mux", "Mic 2", "MIC2N"}, | ||
667 | {"Mic Selection Mux", "Mic 3", "MIC2"}, | ||
668 | |||
669 | /* ACOP */ | ||
670 | {"ACOP", NULL, "ALC Mixer"}, | ||
671 | |||
672 | /* terminator */ | ||
673 | {NULL, NULL, NULL}, | ||
674 | }; | ||
675 | |||
676 | static int wm8753_add_widgets(struct snd_soc_codec *codec) | ||
677 | { | ||
678 | int i; | ||
679 | |||
680 | for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++) | ||
681 | snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]); | ||
682 | |||
683 | /* set up the WM8753 audio map */ | ||
684 | for (i = 0; audio_map[i][0] != NULL; i++) { | ||
685 | snd_soc_dapm_connect_input(codec, audio_map[i][0], | ||
686 | audio_map[i][1], audio_map[i][2]); | ||
687 | } | ||
688 | |||
689 | snd_soc_dapm_new_widgets(codec); | ||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | /* PLL divisors */ | ||
694 | struct _pll_div { | ||
695 | u32 div2:1; | ||
696 | u32 n:4; | ||
697 | u32 k:24; | ||
698 | }; | ||
699 | |||
700 | /* The size in bits of the pll divide multiplied by 10 | ||
701 | * to allow rounding later */ | ||
702 | #define FIXED_PLL_SIZE ((1 << 22) * 10) | ||
703 | |||
704 | static void pll_factors(struct _pll_div *pll_div, unsigned int target, | ||
705 | unsigned int source) | ||
706 | { | ||
707 | u64 Kpart; | ||
708 | unsigned int K, Ndiv, Nmod; | ||
709 | |||
710 | Ndiv = target / source; | ||
711 | if (Ndiv < 6) { | ||
712 | source >>= 1; | ||
713 | pll_div->div2 = 1; | ||
714 | Ndiv = target / source; | ||
715 | } else | ||
716 | pll_div->div2 = 0; | ||
717 | |||
718 | if ((Ndiv < 6) || (Ndiv > 12)) | ||
719 | printk(KERN_WARNING | ||
720 | "WM8753 N value outwith recommended range! N = %d\n",Ndiv); | ||
721 | |||
722 | pll_div->n = Ndiv; | ||
723 | Nmod = target % source; | ||
724 | Kpart = FIXED_PLL_SIZE * (long long)Nmod; | ||
725 | |||
726 | do_div(Kpart, source); | ||
727 | |||
728 | K = Kpart & 0xFFFFFFFF; | ||
729 | |||
730 | /* Check if we need to round */ | ||
731 | if ((K % 10) >= 5) | ||
732 | K += 5; | ||
733 | |||
734 | /* Move down to proper range now rounding is done */ | ||
735 | K /= 10; | ||
736 | |||
737 | pll_div->k = K; | ||
738 | } | ||
739 | |||
740 | static int wm8753_set_dai_pll(struct snd_soc_codec_dai *codec_dai, | ||
741 | int pll_id, unsigned int freq_in, unsigned int freq_out) | ||
742 | { | ||
743 | u16 reg, enable; | ||
744 | int offset; | ||
745 | struct snd_soc_codec *codec = codec_dai->codec; | ||
746 | |||
747 | if (pll_id < WM8753_PLL1 || pll_id > WM8753_PLL2) | ||
748 | return -ENODEV; | ||
749 | |||
750 | if (pll_id == WM8753_PLL1) { | ||
751 | offset = 0; | ||
752 | enable = 0x10; | ||
753 | reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef; | ||
754 | } else { | ||
755 | offset = 4; | ||
756 | enable = 0x8; | ||
757 | reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7; | ||
758 | } | ||
759 | |||
760 | if (!freq_in || !freq_out) { | ||
761 | /* disable PLL */ | ||
762 | wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026); | ||
763 | wm8753_write(codec, WM8753_CLOCK, reg); | ||
764 | return 0; | ||
765 | } else { | ||
766 | u16 value = 0; | ||
767 | struct _pll_div pll_div; | ||
768 | |||
769 | pll_factors(&pll_div, freq_out * 8, freq_in); | ||
770 | |||
771 | /* set up N and K PLL divisor ratios */ | ||
772 | /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */ | ||
773 | value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18); | ||
774 | wm8753_write(codec, WM8753_PLL1CTL2 + offset, value); | ||
775 | |||
776 | /* bits 8:0 = PLL_K[17:9] */ | ||
777 | value = (pll_div.k & 0x03fe00) >> 9; | ||
778 | wm8753_write(codec, WM8753_PLL1CTL3 + offset, value); | ||
779 | |||
780 | /* bits 8:0 = PLL_K[8:0] */ | ||
781 | value = pll_div.k & 0x0001ff; | ||
782 | wm8753_write(codec, WM8753_PLL1CTL4 + offset, value); | ||
783 | |||
784 | /* set PLL as input and enable */ | ||
785 | wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 | | ||
786 | (pll_div.div2 << 3)); | ||
787 | wm8753_write(codec, WM8753_CLOCK, reg | enable); | ||
788 | } | ||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | struct _coeff_div { | ||
793 | u32 mclk; | ||
794 | u32 rate; | ||
795 | u8 sr:5; | ||
796 | u8 usb:1; | ||
797 | }; | ||
798 | |||
799 | /* codec hifi mclk (after PLL) clock divider coefficients */ | ||
800 | static const struct _coeff_div coeff_div[] = { | ||
801 | /* 8k */ | ||
802 | {12288000, 8000, 0x6, 0x0}, | ||
803 | {11289600, 8000, 0x16, 0x0}, | ||
804 | {18432000, 8000, 0x7, 0x0}, | ||
805 | {16934400, 8000, 0x17, 0x0}, | ||
806 | {12000000, 8000, 0x6, 0x1}, | ||
807 | |||
808 | /* 11.025k */ | ||
809 | {11289600, 11025, 0x18, 0x0}, | ||
810 | {16934400, 11025, 0x19, 0x0}, | ||
811 | {12000000, 11025, 0x19, 0x1}, | ||
812 | |||
813 | /* 16k */ | ||
814 | {12288000, 16000, 0xa, 0x0}, | ||
815 | {18432000, 16000, 0xb, 0x0}, | ||
816 | {12000000, 16000, 0xa, 0x1}, | ||
817 | |||
818 | /* 22.05k */ | ||
819 | {11289600, 22050, 0x1a, 0x0}, | ||
820 | {16934400, 22050, 0x1b, 0x0}, | ||
821 | {12000000, 22050, 0x1b, 0x1}, | ||
822 | |||
823 | /* 32k */ | ||
824 | {12288000, 32000, 0xc, 0x0}, | ||
825 | {18432000, 32000, 0xd, 0x0}, | ||
826 | {12000000, 32000, 0xa, 0x1}, | ||
827 | |||
828 | /* 44.1k */ | ||
829 | {11289600, 44100, 0x10, 0x0}, | ||
830 | {16934400, 44100, 0x11, 0x0}, | ||
831 | {12000000, 44100, 0x11, 0x1}, | ||
832 | |||
833 | /* 48k */ | ||
834 | {12288000, 48000, 0x0, 0x0}, | ||
835 | {18432000, 48000, 0x1, 0x0}, | ||
836 | {12000000, 48000, 0x0, 0x1}, | ||
837 | |||
838 | /* 88.2k */ | ||
839 | {11289600, 88200, 0x1e, 0x0}, | ||
840 | {16934400, 88200, 0x1f, 0x0}, | ||
841 | {12000000, 88200, 0x1f, 0x1}, | ||
842 | |||
843 | /* 96k */ | ||
844 | {12288000, 96000, 0xe, 0x0}, | ||
845 | {18432000, 96000, 0xf, 0x0}, | ||
846 | {12000000, 96000, 0xe, 0x1}, | ||
847 | }; | ||
848 | |||
849 | static int get_coeff(int mclk, int rate) | ||
850 | { | ||
851 | int i; | ||
852 | |||
853 | for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { | ||
854 | if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) | ||
855 | return i; | ||
856 | } | ||
857 | return -EINVAL; | ||
858 | } | ||
859 | |||
860 | /* | ||
861 | * Clock after PLL and dividers | ||
862 | */ | ||
863 | static int wm8753_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, | ||
864 | int clk_id, unsigned int freq, int dir) | ||
865 | { | ||
866 | struct snd_soc_codec *codec = codec_dai->codec; | ||
867 | struct wm8753_priv *wm8753 = codec->private_data; | ||
868 | |||
869 | switch (freq) { | ||
870 | case 11289600: | ||
871 | case 12000000: | ||
872 | case 12288000: | ||
873 | case 16934400: | ||
874 | case 18432000: | ||
875 | if (clk_id == WM8753_MCLK) { | ||
876 | wm8753->sysclk = freq; | ||
877 | return 0; | ||
878 | } else if (clk_id == WM8753_PCMCLK) { | ||
879 | wm8753->pcmclk = freq; | ||
880 | return 0; | ||
881 | } | ||
882 | break; | ||
883 | } | ||
884 | return -EINVAL; | ||
885 | } | ||
886 | |||
887 | /* | ||
888 | * Set's ADC and Voice DAC format. | ||
889 | */ | ||
890 | static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, | ||
891 | unsigned int fmt) | ||
892 | { | ||
893 | struct snd_soc_codec *codec = codec_dai->codec; | ||
894 | u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec; | ||
895 | |||
896 | /* interface format */ | ||
897 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
898 | case SND_SOC_DAIFMT_I2S: | ||
899 | voice |= 0x0002; | ||
900 | break; | ||
901 | case SND_SOC_DAIFMT_RIGHT_J: | ||
902 | break; | ||
903 | case SND_SOC_DAIFMT_LEFT_J: | ||
904 | voice |= 0x0001; | ||
905 | break; | ||
906 | case SND_SOC_DAIFMT_DSP_A: | ||
907 | voice |= 0x0003; | ||
908 | break; | ||
909 | case SND_SOC_DAIFMT_DSP_B: | ||
910 | voice |= 0x0013; | ||
911 | break; | ||
912 | default: | ||
913 | return -EINVAL; | ||
914 | } | ||
915 | |||
916 | wm8753_write(codec, WM8753_PCM, voice); | ||
917 | return 0; | ||
918 | } | ||
919 | |||
920 | /* | ||
921 | * Set PCM DAI bit size and sample rate. | ||
922 | */ | ||
923 | static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, | ||
924 | struct snd_pcm_hw_params *params) | ||
925 | { | ||
926 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
927 | struct snd_soc_device *socdev = rtd->socdev; | ||
928 | struct snd_soc_codec *codec = socdev->codec; | ||
929 | struct wm8753_priv *wm8753 = codec->private_data; | ||
930 | u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; | ||
931 | u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; | ||
932 | |||
933 | /* bit size */ | ||
934 | switch (params_format(params)) { | ||
935 | case SNDRV_PCM_FORMAT_S16_LE: | ||
936 | break; | ||
937 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
938 | voice |= 0x0004; | ||
939 | break; | ||
940 | case SNDRV_PCM_FORMAT_S24_LE: | ||
941 | voice |= 0x0008; | ||
942 | break; | ||
943 | case SNDRV_PCM_FORMAT_S32_LE: | ||
944 | voice |= 0x000c; | ||
945 | break; | ||
946 | } | ||
947 | |||
948 | /* sample rate */ | ||
949 | if (params_rate(params) * 384 == wm8753->pcmclk) | ||
950 | srate |= 0x80; | ||
951 | wm8753_write(codec, WM8753_SRATE1, srate); | ||
952 | |||
953 | wm8753_write(codec, WM8753_PCM, voice); | ||
954 | return 0; | ||
955 | } | ||
956 | |||
957 | /* | ||
958 | * Set's PCM dai fmt and BCLK. | ||
959 | */ | ||
960 | static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, | ||
961 | unsigned int fmt) | ||
962 | { | ||
963 | struct snd_soc_codec *codec = codec_dai->codec; | ||
964 | u16 voice, ioctl; | ||
965 | |||
966 | voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f; | ||
967 | ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d; | ||
968 | |||
969 | /* set master/slave audio interface */ | ||
970 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
971 | case SND_SOC_DAIFMT_CBS_CFS: | ||
972 | break; | ||
973 | case SND_SOC_DAIFMT_CBM_CFM: | ||
974 | ioctl |= 0x2; | ||
975 | case SND_SOC_DAIFMT_CBM_CFS: | ||
976 | voice |= 0x0040; | ||
977 | break; | ||
978 | default: | ||
979 | return -EINVAL; | ||
980 | } | ||
981 | |||
982 | /* clock inversion */ | ||
983 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
984 | case SND_SOC_DAIFMT_DSP_A: | ||
985 | case SND_SOC_DAIFMT_DSP_B: | ||
986 | /* frame inversion not valid for DSP modes */ | ||
987 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
988 | case SND_SOC_DAIFMT_NB_NF: | ||
989 | break; | ||
990 | case SND_SOC_DAIFMT_IB_NF: | ||
991 | voice |= 0x0080; | ||
992 | break; | ||
993 | default: | ||
994 | return -EINVAL; | ||
995 | } | ||
996 | break; | ||
997 | case SND_SOC_DAIFMT_I2S: | ||
998 | case SND_SOC_DAIFMT_RIGHT_J: | ||
999 | case SND_SOC_DAIFMT_LEFT_J: | ||
1000 | voice &= ~0x0010; | ||
1001 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
1002 | case SND_SOC_DAIFMT_NB_NF: | ||
1003 | break; | ||
1004 | case SND_SOC_DAIFMT_IB_IF: | ||
1005 | voice |= 0x0090; | ||
1006 | break; | ||
1007 | case SND_SOC_DAIFMT_IB_NF: | ||
1008 | voice |= 0x0080; | ||
1009 | break; | ||
1010 | case SND_SOC_DAIFMT_NB_IF: | ||
1011 | voice |= 0x0010; | ||
1012 | break; | ||
1013 | default: | ||
1014 | return -EINVAL; | ||
1015 | } | ||
1016 | break; | ||
1017 | default: | ||
1018 | return -EINVAL; | ||
1019 | } | ||
1020 | |||
1021 | wm8753_write(codec, WM8753_PCM, voice); | ||
1022 | wm8753_write(codec, WM8753_IOCTL, ioctl); | ||
1023 | return 0; | ||
1024 | } | ||
1025 | |||
1026 | static int wm8753_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai, | ||
1027 | int div_id, int div) | ||
1028 | { | ||
1029 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1030 | u16 reg; | ||
1031 | |||
1032 | switch (div_id) { | ||
1033 | case WM8753_PCMDIV: | ||
1034 | reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f; | ||
1035 | wm8753_write(codec, WM8753_CLOCK, reg | div); | ||
1036 | break; | ||
1037 | case WM8753_BCLKDIV: | ||
1038 | reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7; | ||
1039 | wm8753_write(codec, WM8753_SRATE2, reg | div); | ||
1040 | break; | ||
1041 | case WM8753_VXCLKDIV: | ||
1042 | reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f; | ||
1043 | wm8753_write(codec, WM8753_SRATE2, reg | div); | ||
1044 | break; | ||
1045 | default: | ||
1046 | return -EINVAL; | ||
1047 | } | ||
1048 | return 0; | ||
1049 | } | ||
1050 | |||
1051 | /* | ||
1052 | * Set's HiFi DAC format. | ||
1053 | */ | ||
1054 | static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, | ||
1055 | unsigned int fmt) | ||
1056 | { | ||
1057 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1058 | u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0; | ||
1059 | |||
1060 | /* interface format */ | ||
1061 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
1062 | case SND_SOC_DAIFMT_I2S: | ||
1063 | hifi |= 0x0002; | ||
1064 | break; | ||
1065 | case SND_SOC_DAIFMT_RIGHT_J: | ||
1066 | break; | ||
1067 | case SND_SOC_DAIFMT_LEFT_J: | ||
1068 | hifi |= 0x0001; | ||
1069 | break; | ||
1070 | case SND_SOC_DAIFMT_DSP_A: | ||
1071 | hifi |= 0x0003; | ||
1072 | break; | ||
1073 | case SND_SOC_DAIFMT_DSP_B: | ||
1074 | hifi |= 0x0013; | ||
1075 | break; | ||
1076 | default: | ||
1077 | return -EINVAL; | ||
1078 | } | ||
1079 | |||
1080 | wm8753_write(codec, WM8753_HIFI, hifi); | ||
1081 | return 0; | ||
1082 | } | ||
1083 | |||
1084 | /* | ||
1085 | * Set's I2S DAI format. | ||
1086 | */ | ||
1087 | static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, | ||
1088 | unsigned int fmt) | ||
1089 | { | ||
1090 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1091 | u16 ioctl, hifi; | ||
1092 | |||
1093 | hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f; | ||
1094 | ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae; | ||
1095 | |||
1096 | /* set master/slave audio interface */ | ||
1097 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1098 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1099 | break; | ||
1100 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1101 | ioctl |= 0x1; | ||
1102 | case SND_SOC_DAIFMT_CBM_CFS: | ||
1103 | hifi |= 0x0040; | ||
1104 | break; | ||
1105 | default: | ||
1106 | return -EINVAL; | ||
1107 | } | ||
1108 | |||
1109 | /* clock inversion */ | ||
1110 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
1111 | case SND_SOC_DAIFMT_DSP_A: | ||
1112 | case SND_SOC_DAIFMT_DSP_B: | ||
1113 | /* frame inversion not valid for DSP modes */ | ||
1114 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
1115 | case SND_SOC_DAIFMT_NB_NF: | ||
1116 | break; | ||
1117 | case SND_SOC_DAIFMT_IB_NF: | ||
1118 | hifi |= 0x0080; | ||
1119 | break; | ||
1120 | default: | ||
1121 | return -EINVAL; | ||
1122 | } | ||
1123 | break; | ||
1124 | case SND_SOC_DAIFMT_I2S: | ||
1125 | case SND_SOC_DAIFMT_RIGHT_J: | ||
1126 | case SND_SOC_DAIFMT_LEFT_J: | ||
1127 | hifi &= ~0x0010; | ||
1128 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
1129 | case SND_SOC_DAIFMT_NB_NF: | ||
1130 | break; | ||
1131 | case SND_SOC_DAIFMT_IB_IF: | ||
1132 | hifi |= 0x0090; | ||
1133 | break; | ||
1134 | case SND_SOC_DAIFMT_IB_NF: | ||
1135 | hifi |= 0x0080; | ||
1136 | break; | ||
1137 | case SND_SOC_DAIFMT_NB_IF: | ||
1138 | hifi |= 0x0010; | ||
1139 | break; | ||
1140 | default: | ||
1141 | return -EINVAL; | ||
1142 | } | ||
1143 | break; | ||
1144 | default: | ||
1145 | return -EINVAL; | ||
1146 | } | ||
1147 | |||
1148 | wm8753_write(codec, WM8753_HIFI, hifi); | ||
1149 | wm8753_write(codec, WM8753_IOCTL, ioctl); | ||
1150 | return 0; | ||
1151 | } | ||
1152 | |||
1153 | /* | ||
1154 | * Set PCM DAI bit size and sample rate. | ||
1155 | */ | ||
1156 | static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, | ||
1157 | struct snd_pcm_hw_params *params) | ||
1158 | { | ||
1159 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
1160 | struct snd_soc_device *socdev = rtd->socdev; | ||
1161 | struct snd_soc_codec *codec = socdev->codec; | ||
1162 | struct wm8753_priv *wm8753 = codec->private_data; | ||
1163 | u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; | ||
1164 | u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; | ||
1165 | int coeff; | ||
1166 | |||
1167 | /* is digital filter coefficient valid ? */ | ||
1168 | coeff = get_coeff(wm8753->sysclk, params_rate(params)); | ||
1169 | if (coeff < 0) { | ||
1170 | printk(KERN_ERR "wm8753 invalid MCLK or rate\n"); | ||
1171 | return coeff; | ||
1172 | } | ||
1173 | wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) | | ||
1174 | coeff_div[coeff].usb); | ||
1175 | |||
1176 | /* bit size */ | ||
1177 | switch (params_format(params)) { | ||
1178 | case SNDRV_PCM_FORMAT_S16_LE: | ||
1179 | break; | ||
1180 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
1181 | hifi |= 0x0004; | ||
1182 | break; | ||
1183 | case SNDRV_PCM_FORMAT_S24_LE: | ||
1184 | hifi |= 0x0008; | ||
1185 | break; | ||
1186 | case SNDRV_PCM_FORMAT_S32_LE: | ||
1187 | hifi |= 0x000c; | ||
1188 | break; | ||
1189 | } | ||
1190 | |||
1191 | wm8753_write(codec, WM8753_HIFI, hifi); | ||
1192 | return 0; | ||
1193 | } | ||
1194 | |||
1195 | static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, | ||
1196 | unsigned int fmt) | ||
1197 | { | ||
1198 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1199 | u16 clock; | ||
1200 | |||
1201 | /* set clk source as pcmclk */ | ||
1202 | clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; | ||
1203 | wm8753_write(codec, WM8753_CLOCK, clock); | ||
1204 | |||
1205 | if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) | ||
1206 | return -EINVAL; | ||
1207 | return wm8753_pcm_set_dai_fmt(codec_dai, fmt); | ||
1208 | } | ||
1209 | |||
1210 | static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, | ||
1211 | unsigned int fmt) | ||
1212 | { | ||
1213 | if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) | ||
1214 | return -EINVAL; | ||
1215 | return wm8753_i2s_set_dai_fmt(codec_dai, fmt); | ||
1216 | } | ||
1217 | |||
1218 | static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, | ||
1219 | unsigned int fmt) | ||
1220 | { | ||
1221 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1222 | u16 clock; | ||
1223 | |||
1224 | /* set clk source as pcmclk */ | ||
1225 | clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; | ||
1226 | wm8753_write(codec, WM8753_CLOCK, clock); | ||
1227 | |||
1228 | if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) | ||
1229 | return -EINVAL; | ||
1230 | return wm8753_i2s_set_dai_fmt(codec_dai, fmt); | ||
1231 | } | ||
1232 | |||
1233 | static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, | ||
1234 | unsigned int fmt) | ||
1235 | { | ||
1236 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1237 | u16 clock; | ||
1238 | |||
1239 | /* set clk source as mclk */ | ||
1240 | clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; | ||
1241 | wm8753_write(codec, WM8753_CLOCK, clock | 0x4); | ||
1242 | |||
1243 | if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) | ||
1244 | return -EINVAL; | ||
1245 | if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) | ||
1246 | return -EINVAL; | ||
1247 | return wm8753_i2s_set_dai_fmt(codec_dai, fmt); | ||
1248 | } | ||
1249 | |||
1250 | static int wm8753_mute(struct snd_soc_codec_dai *dai, int mute) | ||
1251 | { | ||
1252 | struct snd_soc_codec *codec = dai->codec; | ||
1253 | u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7; | ||
1254 | |||
1255 | /* the digital mute covers the HiFi and Voice DAC's on the WM8753. | ||
1256 | * make sure we check if they are not both active when we mute */ | ||
1257 | if (mute && dai->id == 1) { | ||
1258 | if (!wm8753_dai[WM8753_DAI_VOICE].playback.active || | ||
1259 | !wm8753_dai[WM8753_DAI_HIFI].playback.active) | ||
1260 | wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); | ||
1261 | } else { | ||
1262 | if (mute) | ||
1263 | wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); | ||
1264 | else | ||
1265 | wm8753_write(codec, WM8753_DAC, mute_reg); | ||
1266 | } | ||
1267 | |||
1268 | return 0; | ||
1269 | } | ||
1270 | |||
1271 | static int wm8753_dapm_event(struct snd_soc_codec *codec, int event) | ||
1272 | { | ||
1273 | u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e; | ||
1274 | |||
1275 | switch (event) { | ||
1276 | case SNDRV_CTL_POWER_D0: /* full On */ | ||
1277 | /* set vmid to 50k and unmute dac */ | ||
1278 | wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); | ||
1279 | break; | ||
1280 | case SNDRV_CTL_POWER_D1: /* partial On */ | ||
1281 | case SNDRV_CTL_POWER_D2: /* partial On */ | ||
1282 | /* set vmid to 5k for quick power up */ | ||
1283 | wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); | ||
1284 | break; | ||
1285 | case SNDRV_CTL_POWER_D3hot: /* Off, with power */ | ||
1286 | /* mute dac and set vmid to 500k, enable VREF */ | ||
1287 | wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141); | ||
1288 | break; | ||
1289 | case SNDRV_CTL_POWER_D3cold: /* Off, without power */ | ||
1290 | wm8753_write(codec, WM8753_PWR1, 0x0001); | ||
1291 | break; | ||
1292 | } | ||
1293 | codec->dapm_state = event; | ||
1294 | return 0; | ||
1295 | } | ||
1296 | |||
1297 | #define WM8753_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ | ||
1298 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ | ||
1299 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) | ||
1300 | |||
1301 | #define WM8753_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | ||
1302 | SNDRV_PCM_FMTBIT_S24_LE) | ||
1303 | |||
1304 | /* | ||
1305 | * The WM8753 supports upto 4 different and mutually exclusive DAI | ||
1306 | * configurations. This gives 2 PCM's available for use, hifi and voice. | ||
1307 | * NOTE: The Voice PCM cannot play or capture audio to the CPU as it's DAI | ||
1308 | * is connected between the wm8753 and a BT codec or GSM modem. | ||
1309 | * | ||
1310 | * 1. Voice over PCM DAI - HIFI DAC over HIFI DAI | ||
1311 | * 2. Voice over HIFI DAI - HIFI disabled | ||
1312 | * 3. Voice disabled - HIFI over HIFI | ||
1313 | * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture | ||
1314 | */ | ||
1315 | static const struct snd_soc_codec_dai wm8753_all_dai[] = { | ||
1316 | /* DAI HiFi mode 1 */ | ||
1317 | { .name = "WM8753 HiFi", | ||
1318 | .id = 1, | ||
1319 | .playback = { | ||
1320 | .stream_name = "HiFi Playback", | ||
1321 | .channels_min = 1, | ||
1322 | .channels_max = 2, | ||
1323 | .rates = WM8753_RATES, | ||
1324 | .formats = WM8753_FORMATS,}, | ||
1325 | .capture = { /* dummy for fast DAI switching */ | ||
1326 | .stream_name = "Capture", | ||
1327 | .channels_min = 1, | ||
1328 | .channels_max = 2, | ||
1329 | .rates = WM8753_RATES, | ||
1330 | .formats = WM8753_FORMATS,}, | ||
1331 | .ops = { | ||
1332 | .hw_params = wm8753_i2s_hw_params,}, | ||
1333 | .dai_ops = { | ||
1334 | .digital_mute = wm8753_mute, | ||
1335 | .set_fmt = wm8753_mode1h_set_dai_fmt, | ||
1336 | .set_clkdiv = wm8753_set_dai_clkdiv, | ||
1337 | .set_pll = wm8753_set_dai_pll, | ||
1338 | .set_sysclk = wm8753_set_dai_sysclk, | ||
1339 | }, | ||
1340 | }, | ||
1341 | /* DAI Voice mode 1 */ | ||
1342 | { .name = "WM8753 Voice", | ||
1343 | .id = 1, | ||
1344 | .playback = { | ||
1345 | .stream_name = "Voice Playback", | ||
1346 | .channels_min = 1, | ||
1347 | .channels_max = 1, | ||
1348 | .rates = WM8753_RATES, | ||
1349 | .formats = WM8753_FORMATS,}, | ||
1350 | .capture = { | ||
1351 | .stream_name = "Capture", | ||
1352 | .channels_min = 1, | ||
1353 | .channels_max = 2, | ||
1354 | .rates = WM8753_RATES, | ||
1355 | .formats = WM8753_FORMATS,}, | ||
1356 | .ops = { | ||
1357 | .hw_params = wm8753_pcm_hw_params,}, | ||
1358 | .dai_ops = { | ||
1359 | .digital_mute = wm8753_mute, | ||
1360 | .set_fmt = wm8753_mode1v_set_dai_fmt, | ||
1361 | .set_clkdiv = wm8753_set_dai_clkdiv, | ||
1362 | .set_pll = wm8753_set_dai_pll, | ||
1363 | .set_sysclk = wm8753_set_dai_sysclk, | ||
1364 | }, | ||
1365 | }, | ||
1366 | /* DAI HiFi mode 2 - dummy */ | ||
1367 | { .name = "WM8753 HiFi", | ||
1368 | .id = 2, | ||
1369 | }, | ||
1370 | /* DAI Voice mode 2 */ | ||
1371 | { .name = "WM8753 Voice", | ||
1372 | .id = 2, | ||
1373 | .playback = { | ||
1374 | .stream_name = "Voice Playback", | ||
1375 | .channels_min = 1, | ||
1376 | .channels_max = 1, | ||
1377 | .rates = WM8753_RATES, | ||
1378 | .formats = WM8753_FORMATS,}, | ||
1379 | .capture = { | ||
1380 | .stream_name = "Capture", | ||
1381 | .channels_min = 1, | ||
1382 | .channels_max = 2, | ||
1383 | .rates = WM8753_RATES, | ||
1384 | .formats = WM8753_FORMATS,}, | ||
1385 | .ops = { | ||
1386 | .hw_params = wm8753_pcm_hw_params,}, | ||
1387 | .dai_ops = { | ||
1388 | .digital_mute = wm8753_mute, | ||
1389 | .set_fmt = wm8753_mode2_set_dai_fmt, | ||
1390 | .set_clkdiv = wm8753_set_dai_clkdiv, | ||
1391 | .set_pll = wm8753_set_dai_pll, | ||
1392 | .set_sysclk = wm8753_set_dai_sysclk, | ||
1393 | }, | ||
1394 | }, | ||
1395 | /* DAI HiFi mode 3 */ | ||
1396 | { .name = "WM8753 HiFi", | ||
1397 | .id = 3, | ||
1398 | .playback = { | ||
1399 | .stream_name = "HiFi Playback", | ||
1400 | .channels_min = 1, | ||
1401 | .channels_max = 2, | ||
1402 | .rates = WM8753_RATES, | ||
1403 | .formats = WM8753_FORMATS,}, | ||
1404 | .capture = { | ||
1405 | .stream_name = "Capture", | ||
1406 | .channels_min = 1, | ||
1407 | .channels_max = 2, | ||
1408 | .rates = WM8753_RATES, | ||
1409 | .formats = WM8753_FORMATS,}, | ||
1410 | .ops = { | ||
1411 | .hw_params = wm8753_i2s_hw_params,}, | ||
1412 | .dai_ops = { | ||
1413 | .digital_mute = wm8753_mute, | ||
1414 | .set_fmt = wm8753_mode3_4_set_dai_fmt, | ||
1415 | .set_clkdiv = wm8753_set_dai_clkdiv, | ||
1416 | .set_pll = wm8753_set_dai_pll, | ||
1417 | .set_sysclk = wm8753_set_dai_sysclk, | ||
1418 | }, | ||
1419 | }, | ||
1420 | /* DAI Voice mode 3 - dummy */ | ||
1421 | { .name = "WM8753 Voice", | ||
1422 | .id = 3, | ||
1423 | }, | ||
1424 | /* DAI HiFi mode 4 */ | ||
1425 | { .name = "WM8753 HiFi", | ||
1426 | .id = 4, | ||
1427 | .playback = { | ||
1428 | .stream_name = "HiFi Playback", | ||
1429 | .channels_min = 1, | ||
1430 | .channels_max = 2, | ||
1431 | .rates = WM8753_RATES, | ||
1432 | .formats = WM8753_FORMATS,}, | ||
1433 | .capture = { | ||
1434 | .stream_name = "Capture", | ||
1435 | .channels_min = 1, | ||
1436 | .channels_max = 2, | ||
1437 | .rates = WM8753_RATES, | ||
1438 | .formats = WM8753_FORMATS,}, | ||
1439 | .ops = { | ||
1440 | .hw_params = wm8753_i2s_hw_params,}, | ||
1441 | .dai_ops = { | ||
1442 | .digital_mute = wm8753_mute, | ||
1443 | .set_fmt = wm8753_mode3_4_set_dai_fmt, | ||
1444 | .set_clkdiv = wm8753_set_dai_clkdiv, | ||
1445 | .set_pll = wm8753_set_dai_pll, | ||
1446 | .set_sysclk = wm8753_set_dai_sysclk, | ||
1447 | }, | ||
1448 | }, | ||
1449 | /* DAI Voice mode 4 - dummy */ | ||
1450 | { .name = "WM8753 Voice", | ||
1451 | .id = 4, | ||
1452 | }, | ||
1453 | }; | ||
1454 | |||
1455 | struct snd_soc_codec_dai wm8753_dai[2]; | ||
1456 | EXPORT_SYMBOL_GPL(wm8753_dai); | ||
1457 | |||
1458 | static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode) | ||
1459 | { | ||
1460 | if (mode < 4) { | ||
1461 | int playback_active, capture_active, codec_active, pop_wait; | ||
1462 | void *private_data; | ||
1463 | |||
1464 | playback_active = wm8753_dai[0].playback.active; | ||
1465 | capture_active = wm8753_dai[0].capture.active; | ||
1466 | codec_active = wm8753_dai[0].active; | ||
1467 | private_data = wm8753_dai[0].private_data; | ||
1468 | pop_wait = wm8753_dai[0].pop_wait; | ||
1469 | wm8753_dai[0] = wm8753_all_dai[mode << 1]; | ||
1470 | wm8753_dai[0].playback.active = playback_active; | ||
1471 | wm8753_dai[0].capture.active = capture_active; | ||
1472 | wm8753_dai[0].active = codec_active; | ||
1473 | wm8753_dai[0].private_data = private_data; | ||
1474 | wm8753_dai[0].pop_wait = pop_wait; | ||
1475 | |||
1476 | playback_active = wm8753_dai[1].playback.active; | ||
1477 | capture_active = wm8753_dai[1].capture.active; | ||
1478 | codec_active = wm8753_dai[1].active; | ||
1479 | private_data = wm8753_dai[1].private_data; | ||
1480 | pop_wait = wm8753_dai[1].pop_wait; | ||
1481 | wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1]; | ||
1482 | wm8753_dai[1].playback.active = playback_active; | ||
1483 | wm8753_dai[1].capture.active = capture_active; | ||
1484 | wm8753_dai[1].active = codec_active; | ||
1485 | wm8753_dai[1].private_data = private_data; | ||
1486 | wm8753_dai[1].pop_wait = pop_wait; | ||
1487 | } | ||
1488 | wm8753_dai[0].codec = codec; | ||
1489 | wm8753_dai[1].codec = codec; | ||
1490 | } | ||
1491 | |||
1492 | static void wm8753_work(struct work_struct *work) | ||
1493 | { | ||
1494 | struct snd_soc_codec *codec = | ||
1495 | container_of(work, struct snd_soc_codec, delayed_work.work); | ||
1496 | wm8753_dapm_event(codec, codec->dapm_state); | ||
1497 | } | ||
1498 | |||
1499 | static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) | ||
1500 | { | ||
1501 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1502 | struct snd_soc_codec *codec = socdev->codec; | ||
1503 | |||
1504 | /* we only need to suspend if we are a valid card */ | ||
1505 | if(!codec->card) | ||
1506 | return 0; | ||
1507 | |||
1508 | wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold); | ||
1509 | return 0; | ||
1510 | } | ||
1511 | |||
1512 | static int wm8753_resume(struct platform_device *pdev) | ||
1513 | { | ||
1514 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1515 | struct snd_soc_codec *codec = socdev->codec; | ||
1516 | int i; | ||
1517 | u8 data[2]; | ||
1518 | u16 *cache = codec->reg_cache; | ||
1519 | |||
1520 | /* we only need to resume if we are a valid card */ | ||
1521 | if(!codec->card) | ||
1522 | return 0; | ||
1523 | |||
1524 | /* Sync reg_cache with the hardware */ | ||
1525 | for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { | ||
1526 | if (i + 1 == WM8753_RESET) | ||
1527 | continue; | ||
1528 | data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001); | ||
1529 | data[1] = cache[i] & 0x00ff; | ||
1530 | codec->hw_write(codec->control_data, data, 2); | ||
1531 | } | ||
1532 | |||
1533 | wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3hot); | ||
1534 | |||
1535 | /* charge wm8753 caps */ | ||
1536 | if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) { | ||
1537 | wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2); | ||
1538 | codec->dapm_state = SNDRV_CTL_POWER_D0; | ||
1539 | schedule_delayed_work(&codec->delayed_work, | ||
1540 | msecs_to_jiffies(caps_charge)); | ||
1541 | } | ||
1542 | |||
1543 | return 0; | ||
1544 | } | ||
1545 | |||
1546 | /* | ||
1547 | * initialise the WM8753 driver | ||
1548 | * register the mixer and dsp interfaces with the kernel | ||
1549 | */ | ||
1550 | static int wm8753_init(struct snd_soc_device *socdev) | ||
1551 | { | ||
1552 | struct snd_soc_codec *codec = socdev->codec; | ||
1553 | int reg, ret = 0; | ||
1554 | |||
1555 | codec->name = "WM8753"; | ||
1556 | codec->owner = THIS_MODULE; | ||
1557 | codec->read = wm8753_read_reg_cache; | ||
1558 | codec->write = wm8753_write; | ||
1559 | codec->dapm_event = wm8753_dapm_event; | ||
1560 | codec->dai = wm8753_dai; | ||
1561 | codec->num_dai = 2; | ||
1562 | codec->reg_cache_size = sizeof(wm8753_reg); | ||
1563 | codec->reg_cache = kmemdup(wm8753_reg, sizeof(wm8753_reg), GFP_KERNEL); | ||
1564 | |||
1565 | if (codec->reg_cache == NULL) | ||
1566 | return -ENOMEM; | ||
1567 | |||
1568 | wm8753_set_dai_mode(codec, 0); | ||
1569 | |||
1570 | wm8753_reset(codec); | ||
1571 | |||
1572 | /* register pcms */ | ||
1573 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
1574 | if (ret < 0) { | ||
1575 | printk(KERN_ERR "wm8753: failed to create pcms\n"); | ||
1576 | goto pcm_err; | ||
1577 | } | ||
1578 | |||
1579 | /* charge output caps */ | ||
1580 | wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2); | ||
1581 | codec->dapm_state = SNDRV_CTL_POWER_D3hot; | ||
1582 | schedule_delayed_work(&codec->delayed_work, | ||
1583 | msecs_to_jiffies(caps_charge)); | ||
1584 | |||
1585 | /* set the update bits */ | ||
1586 | reg = wm8753_read_reg_cache(codec, WM8753_LDAC); | ||
1587 | wm8753_write(codec, WM8753_LDAC, reg | 0x0100); | ||
1588 | reg = wm8753_read_reg_cache(codec, WM8753_RDAC); | ||
1589 | wm8753_write(codec, WM8753_RDAC, reg | 0x0100); | ||
1590 | reg = wm8753_read_reg_cache(codec, WM8753_LADC); | ||
1591 | wm8753_write(codec, WM8753_LADC, reg | 0x0100); | ||
1592 | reg = wm8753_read_reg_cache(codec, WM8753_RADC); | ||
1593 | wm8753_write(codec, WM8753_RADC, reg | 0x0100); | ||
1594 | reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V); | ||
1595 | wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100); | ||
1596 | reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V); | ||
1597 | wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100); | ||
1598 | reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V); | ||
1599 | wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100); | ||
1600 | reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V); | ||
1601 | wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100); | ||
1602 | reg = wm8753_read_reg_cache(codec, WM8753_LINVOL); | ||
1603 | wm8753_write(codec, WM8753_LINVOL, reg | 0x0100); | ||
1604 | reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); | ||
1605 | wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); | ||
1606 | |||
1607 | wm8753_add_controls(codec); | ||
1608 | wm8753_add_widgets(codec); | ||
1609 | ret = snd_soc_register_card(socdev); | ||
1610 | if (ret < 0) { | ||
1611 | printk(KERN_ERR "wm8753: failed to register card\n"); | ||
1612 | goto card_err; | ||
1613 | } | ||
1614 | return ret; | ||
1615 | |||
1616 | card_err: | ||
1617 | snd_soc_free_pcms(socdev); | ||
1618 | snd_soc_dapm_free(socdev); | ||
1619 | pcm_err: | ||
1620 | kfree(codec->reg_cache); | ||
1621 | return ret; | ||
1622 | } | ||
1623 | |||
1624 | /* If the i2c layer weren't so broken, we could pass this kind of data | ||
1625 | around */ | ||
1626 | static struct snd_soc_device *wm8753_socdev; | ||
1627 | |||
1628 | #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) | ||
1629 | |||
1630 | /* | ||
1631 | * WM8753 2 wire address is determined by GPIO5 | ||
1632 | * state during powerup. | ||
1633 | * low = 0x1a | ||
1634 | * high = 0x1b | ||
1635 | */ | ||
1636 | static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; | ||
1637 | |||
1638 | /* Magic definition of all other variables and things */ | ||
1639 | I2C_CLIENT_INSMOD; | ||
1640 | |||
1641 | static struct i2c_driver wm8753_i2c_driver; | ||
1642 | static struct i2c_client client_template; | ||
1643 | |||
1644 | static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind) | ||
1645 | { | ||
1646 | struct snd_soc_device *socdev = wm8753_socdev; | ||
1647 | struct wm8753_setup_data *setup = socdev->codec_data; | ||
1648 | struct snd_soc_codec *codec = socdev->codec; | ||
1649 | struct i2c_client *i2c; | ||
1650 | int ret; | ||
1651 | |||
1652 | if (addr != setup->i2c_address) | ||
1653 | return -ENODEV; | ||
1654 | |||
1655 | client_template.adapter = adap; | ||
1656 | client_template.addr = addr; | ||
1657 | |||
1658 | i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); | ||
1659 | if (i2c == NULL){ | ||
1660 | kfree(codec); | ||
1661 | return -ENOMEM; | ||
1662 | } | ||
1663 | i2c_set_clientdata(i2c, codec); | ||
1664 | codec->control_data = i2c; | ||
1665 | |||
1666 | ret = i2c_attach_client(i2c); | ||
1667 | if (ret < 0) { | ||
1668 | err("failed to attach codec at addr %x\n", addr); | ||
1669 | goto err; | ||
1670 | } | ||
1671 | |||
1672 | ret = wm8753_init(socdev); | ||
1673 | if (ret < 0) { | ||
1674 | err("failed to initialise WM8753\n"); | ||
1675 | goto err; | ||
1676 | } | ||
1677 | |||
1678 | return ret; | ||
1679 | |||
1680 | err: | ||
1681 | kfree(codec); | ||
1682 | kfree(i2c); | ||
1683 | return ret; | ||
1684 | } | ||
1685 | |||
1686 | static int wm8753_i2c_detach(struct i2c_client *client) | ||
1687 | { | ||
1688 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | ||
1689 | i2c_detach_client(client); | ||
1690 | kfree(codec->reg_cache); | ||
1691 | kfree(client); | ||
1692 | return 0; | ||
1693 | } | ||
1694 | |||
1695 | static int wm8753_i2c_attach(struct i2c_adapter *adap) | ||
1696 | { | ||
1697 | return i2c_probe(adap, &addr_data, wm8753_codec_probe); | ||
1698 | } | ||
1699 | |||
1700 | /* corgi i2c codec control layer */ | ||
1701 | static struct i2c_driver wm8753_i2c_driver = { | ||
1702 | .driver = { | ||
1703 | .name = "WM8753 I2C Codec", | ||
1704 | .owner = THIS_MODULE, | ||
1705 | }, | ||
1706 | .id = I2C_DRIVERID_WM8753, | ||
1707 | .attach_adapter = wm8753_i2c_attach, | ||
1708 | .detach_client = wm8753_i2c_detach, | ||
1709 | .command = NULL, | ||
1710 | }; | ||
1711 | |||
1712 | static struct i2c_client client_template = { | ||
1713 | .name = "WM8753", | ||
1714 | .driver = &wm8753_i2c_driver, | ||
1715 | }; | ||
1716 | #endif | ||
1717 | |||
1718 | static int wm8753_probe(struct platform_device *pdev) | ||
1719 | { | ||
1720 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1721 | struct wm8753_setup_data *setup; | ||
1722 | struct snd_soc_codec *codec; | ||
1723 | struct wm8753_priv *wm8753; | ||
1724 | int ret = 0; | ||
1725 | |||
1726 | info("WM8753 Audio Codec %s", WM8753_VERSION); | ||
1727 | |||
1728 | setup = socdev->codec_data; | ||
1729 | codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | ||
1730 | if (codec == NULL) | ||
1731 | return -ENOMEM; | ||
1732 | |||
1733 | wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); | ||
1734 | if (wm8753 == NULL) { | ||
1735 | kfree(codec); | ||
1736 | return -ENOMEM; | ||
1737 | } | ||
1738 | |||
1739 | codec->private_data = wm8753; | ||
1740 | socdev->codec = codec; | ||
1741 | mutex_init(&codec->mutex); | ||
1742 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
1743 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
1744 | wm8753_socdev = socdev; | ||
1745 | INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); | ||
1746 | |||
1747 | #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) | ||
1748 | if (setup->i2c_address) { | ||
1749 | normal_i2c[0] = setup->i2c_address; | ||
1750 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
1751 | ret = i2c_add_driver(&wm8753_i2c_driver); | ||
1752 | if (ret != 0) | ||
1753 | printk(KERN_ERR "can't add i2c driver"); | ||
1754 | } | ||
1755 | #else | ||
1756 | /* Add other interfaces here */ | ||
1757 | #endif | ||
1758 | return ret; | ||
1759 | } | ||
1760 | |||
1761 | /* | ||
1762 | * This function forces any delayed work to be queued and run. | ||
1763 | */ | ||
1764 | static int run_delayed_work(struct delayed_work *dwork) | ||
1765 | { | ||
1766 | int ret; | ||
1767 | |||
1768 | /* cancel any work waiting to be queued. */ | ||
1769 | ret = cancel_delayed_work(dwork); | ||
1770 | |||
1771 | /* if there was any work waiting then we run it now and | ||
1772 | * wait for it's completion */ | ||
1773 | if (ret) { | ||
1774 | schedule_delayed_work(dwork, 0); | ||
1775 | flush_scheduled_work(); | ||
1776 | } | ||
1777 | return ret; | ||
1778 | } | ||
1779 | |||
1780 | /* power down chip */ | ||
1781 | static int wm8753_remove(struct platform_device *pdev) | ||
1782 | { | ||
1783 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1784 | struct snd_soc_codec *codec = socdev->codec; | ||
1785 | |||
1786 | if (codec->control_data) | ||
1787 | wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold); | ||
1788 | run_delayed_work(&codec->delayed_work); | ||
1789 | snd_soc_free_pcms(socdev); | ||
1790 | snd_soc_dapm_free(socdev); | ||
1791 | #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) | ||
1792 | i2c_del_driver(&wm8753_i2c_driver); | ||
1793 | #endif | ||
1794 | kfree(codec->private_data); | ||
1795 | kfree(codec); | ||
1796 | |||
1797 | return 0; | ||
1798 | } | ||
1799 | |||
1800 | struct snd_soc_codec_device soc_codec_dev_wm8753 = { | ||
1801 | .probe = wm8753_probe, | ||
1802 | .remove = wm8753_remove, | ||
1803 | .suspend = wm8753_suspend, | ||
1804 | .resume = wm8753_resume, | ||
1805 | }; | ||
1806 | |||
1807 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753); | ||
1808 | |||
1809 | MODULE_DESCRIPTION("ASoC WM8753 driver"); | ||
1810 | MODULE_AUTHOR("Liam Girdwood"); | ||
1811 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h new file mode 100644 index 000000000000..95e2a1f53169 --- /dev/null +++ b/sound/soc/codecs/wm8753.h | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * wm8753.h -- audio driver for WM8753 | ||
3 | * | ||
4 | * Copyright 2003 Wolfson Microelectronics PLC. | ||
5 | * Author: Liam Girdwood | ||
6 | * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #ifndef _WM8753_H | ||
16 | #define _WM8753_H | ||
17 | |||
18 | /* WM8753 register space */ | ||
19 | |||
20 | #define WM8753_DAC 0x01 | ||
21 | #define WM8753_ADC 0x02 | ||
22 | #define WM8753_PCM 0x03 | ||
23 | #define WM8753_HIFI 0x04 | ||
24 | #define WM8753_IOCTL 0x05 | ||
25 | #define WM8753_SRATE1 0x06 | ||
26 | #define WM8753_SRATE2 0x07 | ||
27 | #define WM8753_LDAC 0x08 | ||
28 | #define WM8753_RDAC 0x09 | ||
29 | #define WM8753_BASS 0x0a | ||
30 | #define WM8753_TREBLE 0x0b | ||
31 | #define WM8753_ALC1 0x0c | ||
32 | #define WM8753_ALC2 0x0d | ||
33 | #define WM8753_ALC3 0x0e | ||
34 | #define WM8753_NGATE 0x0f | ||
35 | #define WM8753_LADC 0x10 | ||
36 | #define WM8753_RADC 0x11 | ||
37 | #define WM8753_ADCTL1 0x12 | ||
38 | #define WM8753_3D 0x13 | ||
39 | #define WM8753_PWR1 0x14 | ||
40 | #define WM8753_PWR2 0x15 | ||
41 | #define WM8753_PWR3 0x16 | ||
42 | #define WM8753_PWR4 0x17 | ||
43 | #define WM8753_ID 0x18 | ||
44 | #define WM8753_INTPOL 0x19 | ||
45 | #define WM8753_INTEN 0x1a | ||
46 | #define WM8753_GPIO1 0x1b | ||
47 | #define WM8753_GPIO2 0x1c | ||
48 | #define WM8753_RESET 0x1f | ||
49 | #define WM8753_RECMIX1 0x20 | ||
50 | #define WM8753_RECMIX2 0x21 | ||
51 | #define WM8753_LOUTM1 0x22 | ||
52 | #define WM8753_LOUTM2 0x23 | ||
53 | #define WM8753_ROUTM1 0x24 | ||
54 | #define WM8753_ROUTM2 0x25 | ||
55 | #define WM8753_MOUTM1 0x26 | ||
56 | #define WM8753_MOUTM2 0x27 | ||
57 | #define WM8753_LOUT1V 0x28 | ||
58 | #define WM8753_ROUT1V 0x29 | ||
59 | #define WM8753_LOUT2V 0x2a | ||
60 | #define WM8753_ROUT2V 0x2b | ||
61 | #define WM8753_MOUTV 0x2c | ||
62 | #define WM8753_OUTCTL 0x2d | ||
63 | #define WM8753_ADCIN 0x2e | ||
64 | #define WM8753_INCTL1 0x2f | ||
65 | #define WM8753_INCTL2 0x30 | ||
66 | #define WM8753_LINVOL 0x31 | ||
67 | #define WM8753_RINVOL 0x32 | ||
68 | #define WM8753_MICBIAS 0x33 | ||
69 | #define WM8753_CLOCK 0x34 | ||
70 | #define WM8753_PLL1CTL1 0x35 | ||
71 | #define WM8753_PLL1CTL2 0x36 | ||
72 | #define WM8753_PLL1CTL3 0x37 | ||
73 | #define WM8753_PLL1CTL4 0x38 | ||
74 | #define WM8753_PLL2CTL1 0x39 | ||
75 | #define WM8753_PLL2CTL2 0x3a | ||
76 | #define WM8753_PLL2CTL3 0x3b | ||
77 | #define WM8753_PLL2CTL4 0x3c | ||
78 | #define WM8753_BIASCTL 0x3d | ||
79 | #define WM8753_ADCTL2 0x3f | ||
80 | |||
81 | struct wm8753_setup_data { | ||
82 | unsigned short i2c_address; | ||
83 | }; | ||
84 | |||
85 | #define WM8753_PLL1 0 | ||
86 | #define WM8753_PLL2 1 | ||
87 | |||
88 | /* clock inputs */ | ||
89 | #define WM8753_MCLK 0 | ||
90 | #define WM8753_PCMCLK 1 | ||
91 | |||
92 | /* clock divider id's */ | ||
93 | #define WM8753_PCMDIV 0 | ||
94 | #define WM8753_BCLKDIV 1 | ||
95 | #define WM8753_VXCLKDIV 2 | ||
96 | |||
97 | /* PCM clock dividers */ | ||
98 | #define WM8753_PCM_DIV_1 (0 << 6) | ||
99 | #define WM8753_PCM_DIV_3 (2 << 6) | ||
100 | #define WM8753_PCM_DIV_5_5 (3 << 6) | ||
101 | #define WM8753_PCM_DIV_2 (4 << 6) | ||
102 | #define WM8753_PCM_DIV_4 (5 << 6) | ||
103 | #define WM8753_PCM_DIV_6 (6 << 6) | ||
104 | #define WM8753_PCM_DIV_8 (7 << 6) | ||
105 | |||
106 | /* BCLK clock dividers */ | ||
107 | #define WM8753_BCLK_DIV_1 (0 << 3) | ||
108 | #define WM8753_BCLK_DIV_2 (1 << 3) | ||
109 | #define WM8753_BCLK_DIV_4 (2 << 3) | ||
110 | #define WM8753_BCLK_DIV_8 (3 << 3) | ||
111 | #define WM8753_BCLK_DIV_16 (4 << 3) | ||
112 | |||
113 | /* VXCLK clock dividers */ | ||
114 | #define WM8753_VXCLK_DIV_1 (0 << 6) | ||
115 | #define WM8753_VXCLK_DIV_2 (1 << 6) | ||
116 | #define WM8753_VXCLK_DIV_4 (2 << 6) | ||
117 | #define WM8753_VXCLK_DIV_8 (3 << 6) | ||
118 | #define WM8753_VXCLK_DIV_16 (4 << 6) | ||
119 | |||
120 | #define WM8753_DAI_HIFI 0 | ||
121 | #define WM8753_DAI_VOICE 1 | ||
122 | |||
123 | extern struct snd_soc_codec_dai wm8753_dai[2]; | ||
124 | extern struct snd_soc_codec_device soc_codec_dev_wm8753; | ||
125 | |||
126 | #endif | ||
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index ee7a691a9ba1..264413a00cac 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
@@ -676,14 +676,13 @@ static int wm9712_soc_probe(struct platform_device *pdev) | |||
676 | codec = socdev->codec; | 676 | codec = socdev->codec; |
677 | mutex_init(&codec->mutex); | 677 | mutex_init(&codec->mutex); |
678 | 678 | ||
679 | codec->reg_cache = | 679 | codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL); |
680 | kzalloc(sizeof(u16) * ARRAY_SIZE(wm9712_reg), GFP_KERNEL); | 680 | |
681 | if (codec->reg_cache == NULL) { | 681 | if (codec->reg_cache == NULL) { |
682 | ret = -ENOMEM; | 682 | ret = -ENOMEM; |
683 | goto cache_err; | 683 | goto cache_err; |
684 | } | 684 | } |
685 | memcpy(codec->reg_cache, wm9712_reg, sizeof(u16) * ARRAY_SIZE(wm9712_reg)); | 685 | codec->reg_cache_size = sizeof(wm9712_reg); |
686 | codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(wm9712_reg); | ||
687 | codec->reg_cache_step = 2; | 686 | codec->reg_cache_step = 2; |
688 | 687 | ||
689 | codec->name = "WM9712"; | 688 | codec->name = "WM9712"; |
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index b9ab3b8e1d3e..a83e22937c27 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig | |||
@@ -1,5 +1,3 @@ | |||
1 | menu "SoC Audio for the Intel PXA2xx" | ||
2 | |||
3 | config SND_PXA2XX_SOC | 1 | config SND_PXA2XX_SOC |
4 | tristate "SoC Audio for the Intel PXA2xx chip" | 2 | tristate "SoC Audio for the Intel PXA2xx chip" |
5 | depends on ARCH_PXA && SND_SOC | 3 | depends on ARCH_PXA && SND_SOC |
@@ -55,5 +53,3 @@ config SND_PXA2XX_SOC_TOSA | |||
55 | help | 53 | help |
56 | Say Y if you want to add support for SoC audio on Sharp | 54 | Say Y if you want to add support for SoC audio on Sharp |
57 | Zaurus SL-C6000x models (Tosa). | 55 | Zaurus SL-C6000x models (Tosa). |
58 | |||
59 | endmenu | ||
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig new file mode 100644 index 000000000000..044a3712077a --- /dev/null +++ b/sound/soc/s3c24xx/Kconfig | |||
@@ -0,0 +1,10 @@ | |||
1 | config SND_S3C24XX_SOC | ||
2 | tristate "SoC Audio for the Samsung S3C24XX chips" | ||
3 | depends on ARCH_S3C2410 && SND_SOC | ||
4 | help | ||
5 | Say Y or M if you want to add support for codecs attached to | ||
6 | the S3C24XX AC97, I2S or SSP interface. You will also need | ||
7 | to select the audio interfaces to support below. | ||
8 | |||
9 | config SND_S3C24XX_SOC_I2S | ||
10 | tristate | ||
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile new file mode 100644 index 000000000000..6f0fffcb30f5 --- /dev/null +++ b/sound/soc/s3c24xx/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | # S3c24XX Platform Support | ||
2 | snd-soc-s3c24xx-objs := s3c24xx-pcm.o | ||
3 | snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o | ||
4 | |||
5 | obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o | ||
6 | obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o | ||
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c new file mode 100644 index 000000000000..8ca314dc8891 --- /dev/null +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c | |||
@@ -0,0 +1,441 @@ | |||
1 | /* | ||
2 | * s3c24xx-i2s.c -- ALSA Soc Audio Layer | ||
3 | * | ||
4 | * (c) 2006 Wolfson Microelectronics PLC. | ||
5 | * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com | ||
6 | * | ||
7 | * (c) 2004-2005 Simtec Electronics | ||
8 | * http://armlinux.simtec.co.uk/ | ||
9 | * Ben Dooks <ben@simtec.co.uk> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | * | ||
16 | * | ||
17 | * Revision history | ||
18 | * 11th Dec 2006 Merged with Simtec driver | ||
19 | * 10th Nov 2006 Initial version. | ||
20 | */ | ||
21 | |||
22 | #include <linux/init.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/clk.h> | ||
27 | #include <sound/driver.h> | ||
28 | #include <sound/core.h> | ||
29 | #include <sound/pcm.h> | ||
30 | #include <sound/pcm_params.h> | ||
31 | #include <sound/initval.h> | ||
32 | #include <sound/soc.h> | ||
33 | |||
34 | #include <asm/hardware.h> | ||
35 | #include <asm/io.h> | ||
36 | #include <asm/arch/regs-iis.h> | ||
37 | #include <asm/arch/regs-gpio.h> | ||
38 | #include <asm/arch/regs-clock.h> | ||
39 | #include <asm/arch/audio.h> | ||
40 | #include <asm/dma.h> | ||
41 | #include <asm/arch/dma.h> | ||
42 | |||
43 | #include "s3c24xx-pcm.h" | ||
44 | #include "s3c24xx-i2s.h" | ||
45 | |||
46 | #define S3C24XX_I2S_DEBUG 0 | ||
47 | #if S3C24XX_I2S_DEBUG | ||
48 | #define DBG(x...) printk(KERN_DEBUG x) | ||
49 | #else | ||
50 | #define DBG(x...) | ||
51 | #endif | ||
52 | |||
53 | static struct s3c2410_dma_client s3c24xx_dma_client_out = { | ||
54 | .name = "I2S PCM Stereo out" | ||
55 | }; | ||
56 | |||
57 | static struct s3c2410_dma_client s3c24xx_dma_client_in = { | ||
58 | .name = "I2S PCM Stereo in" | ||
59 | }; | ||
60 | |||
61 | static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_out = { | ||
62 | .client = &s3c24xx_dma_client_out, | ||
63 | .channel = DMACH_I2S_OUT, | ||
64 | .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, | ||
65 | .dma_size = 2, | ||
66 | }; | ||
67 | |||
68 | static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_in = { | ||
69 | .client = &s3c24xx_dma_client_in, | ||
70 | .channel = DMACH_I2S_IN, | ||
71 | .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, | ||
72 | .dma_size = 2, | ||
73 | }; | ||
74 | |||
75 | struct s3c24xx_i2s_info { | ||
76 | void __iomem *regs; | ||
77 | struct clk *iis_clk; | ||
78 | }; | ||
79 | static struct s3c24xx_i2s_info s3c24xx_i2s; | ||
80 | |||
81 | static void s3c24xx_snd_txctrl(int on) | ||
82 | { | ||
83 | u32 iisfcon; | ||
84 | u32 iiscon; | ||
85 | u32 iismod; | ||
86 | |||
87 | DBG("Entered %s\n", __FUNCTION__); | ||
88 | |||
89 | iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); | ||
90 | iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); | ||
91 | iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
92 | |||
93 | DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); | ||
94 | |||
95 | if (on) { | ||
96 | iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE; | ||
97 | iiscon |= S3C2410_IISCON_TXDMAEN | S3C2410_IISCON_IISEN; | ||
98 | iiscon &= ~S3C2410_IISCON_TXIDLE; | ||
99 | iismod |= S3C2410_IISMOD_TXMODE; | ||
100 | |||
101 | writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
102 | writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); | ||
103 | writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); | ||
104 | } else { | ||
105 | /* note, we have to disable the FIFOs otherwise bad things | ||
106 | * seem to happen when the DMA stops. According to the | ||
107 | * Samsung supplied kernel, this should allow the DMA | ||
108 | * engine and FIFOs to reset. If this isn't allowed, the | ||
109 | * DMA engine will simply freeze randomly. | ||
110 | */ | ||
111 | |||
112 | iisfcon &= ~S3C2410_IISFCON_TXENABLE; | ||
113 | iisfcon &= ~S3C2410_IISFCON_TXDMA; | ||
114 | iiscon |= S3C2410_IISCON_TXIDLE; | ||
115 | iiscon &= ~S3C2410_IISCON_TXDMAEN; | ||
116 | iismod &= ~S3C2410_IISMOD_TXMODE; | ||
117 | |||
118 | writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); | ||
119 | writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); | ||
120 | writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
121 | } | ||
122 | |||
123 | DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); | ||
124 | } | ||
125 | |||
126 | static void s3c24xx_snd_rxctrl(int on) | ||
127 | { | ||
128 | u32 iisfcon; | ||
129 | u32 iiscon; | ||
130 | u32 iismod; | ||
131 | |||
132 | DBG("Entered %s\n", __FUNCTION__); | ||
133 | |||
134 | iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); | ||
135 | iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); | ||
136 | iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
137 | |||
138 | DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); | ||
139 | |||
140 | if (on) { | ||
141 | iisfcon |= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE; | ||
142 | iiscon |= S3C2410_IISCON_RXDMAEN | S3C2410_IISCON_IISEN; | ||
143 | iiscon &= ~S3C2410_IISCON_RXIDLE; | ||
144 | iismod |= S3C2410_IISMOD_RXMODE; | ||
145 | |||
146 | writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
147 | writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); | ||
148 | writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); | ||
149 | } else { | ||
150 | /* note, we have to disable the FIFOs otherwise bad things | ||
151 | * seem to happen when the DMA stops. According to the | ||
152 | * Samsung supplied kernel, this should allow the DMA | ||
153 | * engine and FIFOs to reset. If this isn't allowed, the | ||
154 | * DMA engine will simply freeze randomly. | ||
155 | */ | ||
156 | |||
157 | iisfcon &= ~S3C2410_IISFCON_RXENABLE; | ||
158 | iisfcon &= ~S3C2410_IISFCON_RXDMA; | ||
159 | iiscon |= S3C2410_IISCON_RXIDLE; | ||
160 | iiscon &= ~S3C2410_IISCON_RXDMAEN; | ||
161 | iismod &= ~S3C2410_IISMOD_RXMODE; | ||
162 | |||
163 | writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); | ||
164 | writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); | ||
165 | writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
166 | } | ||
167 | |||
168 | DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); | ||
169 | } | ||
170 | |||
171 | /* | ||
172 | * Wait for the LR signal to allow synchronisation to the L/R clock | ||
173 | * from the codec. May only be needed for slave mode. | ||
174 | */ | ||
175 | static int s3c24xx_snd_lrsync(void) | ||
176 | { | ||
177 | u32 iiscon; | ||
178 | unsigned long timeout = jiffies + msecs_to_jiffies(5); | ||
179 | |||
180 | DBG("Entered %s\n", __FUNCTION__); | ||
181 | |||
182 | while (1) { | ||
183 | iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); | ||
184 | if (iiscon & S3C2410_IISCON_LRINDEX) | ||
185 | break; | ||
186 | |||
187 | if (timeout < jiffies) | ||
188 | return -ETIMEDOUT; | ||
189 | } | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * Check whether CPU is the master or slave | ||
196 | */ | ||
197 | static inline int s3c24xx_snd_is_clkmaster(void) | ||
198 | { | ||
199 | DBG("Entered %s\n", __FUNCTION__); | ||
200 | |||
201 | return (readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & S3C2410_IISMOD_SLAVE) ? 0:1; | ||
202 | } | ||
203 | |||
204 | /* | ||
205 | * Set S3C24xx I2S DAI format | ||
206 | */ | ||
207 | static int s3c24xx_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai, | ||
208 | unsigned int fmt) | ||
209 | { | ||
210 | u32 iismod; | ||
211 | |||
212 | DBG("Entered %s\n", __FUNCTION__); | ||
213 | |||
214 | iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
215 | DBG("hw_params r: IISMOD: %lx \n", iismod); | ||
216 | |||
217 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
218 | case SND_SOC_DAIFMT_CBM_CFM: | ||
219 | iismod |= S3C2410_IISMOD_SLAVE; | ||
220 | break; | ||
221 | case SND_SOC_DAIFMT_CBS_CFS: | ||
222 | break; | ||
223 | default: | ||
224 | return -EINVAL; | ||
225 | } | ||
226 | |||
227 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
228 | case SND_SOC_DAIFMT_LEFT_J: | ||
229 | iismod |= S3C2410_IISMOD_MSB; | ||
230 | break; | ||
231 | case SND_SOC_DAIFMT_I2S: | ||
232 | break; | ||
233 | default: | ||
234 | return -EINVAL; | ||
235 | } | ||
236 | |||
237 | writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
238 | DBG("hw_params w: IISMOD: %lx \n", iismod); | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, | ||
243 | struct snd_pcm_hw_params *params) | ||
244 | { | ||
245 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
246 | u32 iismod; | ||
247 | |||
248 | DBG("Entered %s\n", __FUNCTION__); | ||
249 | |||
250 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
251 | rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out; | ||
252 | else | ||
253 | rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in; | ||
254 | |||
255 | /* Working copies of register */ | ||
256 | iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
257 | DBG("hw_params r: IISMOD: %lx\n", iismod); | ||
258 | |||
259 | switch (params_format(params)) { | ||
260 | case SNDRV_PCM_FORMAT_S8: | ||
261 | break; | ||
262 | case SNDRV_PCM_FORMAT_S16_LE: | ||
263 | iismod |= S3C2410_IISMOD_16BIT; | ||
264 | break; | ||
265 | } | ||
266 | |||
267 | writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
268 | DBG("hw_params w: IISMOD: %lx\n", iismod); | ||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd) | ||
273 | { | ||
274 | int ret = 0; | ||
275 | |||
276 | DBG("Entered %s\n", __FUNCTION__); | ||
277 | |||
278 | switch (cmd) { | ||
279 | case SNDRV_PCM_TRIGGER_START: | ||
280 | case SNDRV_PCM_TRIGGER_RESUME: | ||
281 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
282 | if (!s3c24xx_snd_is_clkmaster()) { | ||
283 | ret = s3c24xx_snd_lrsync(); | ||
284 | if (ret) | ||
285 | goto exit_err; | ||
286 | } | ||
287 | |||
288 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | ||
289 | s3c24xx_snd_rxctrl(1); | ||
290 | else | ||
291 | s3c24xx_snd_txctrl(1); | ||
292 | break; | ||
293 | case SNDRV_PCM_TRIGGER_STOP: | ||
294 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
295 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
296 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | ||
297 | s3c24xx_snd_rxctrl(0); | ||
298 | else | ||
299 | s3c24xx_snd_txctrl(0); | ||
300 | break; | ||
301 | default: | ||
302 | ret = -EINVAL; | ||
303 | break; | ||
304 | } | ||
305 | |||
306 | exit_err: | ||
307 | return ret; | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * Set S3C24xx Clock source | ||
312 | */ | ||
313 | static int s3c24xx_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, | ||
314 | int clk_id, unsigned int freq, int dir) | ||
315 | { | ||
316 | u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
317 | |||
318 | DBG("Entered %s\n", __FUNCTION__); | ||
319 | |||
320 | iismod &= ~S3C2440_IISMOD_MPLL; | ||
321 | |||
322 | switch (clk_id) { | ||
323 | case S3C24XX_CLKSRC_PCLK: | ||
324 | break; | ||
325 | case S3C24XX_CLKSRC_MPLL: | ||
326 | iismod |= S3C2440_IISMOD_MPLL; | ||
327 | break; | ||
328 | default: | ||
329 | return -EINVAL; | ||
330 | } | ||
331 | |||
332 | writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | /* | ||
337 | * Set S3C24xx Clock dividers | ||
338 | */ | ||
339 | static int s3c24xx_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai, | ||
340 | int div_id, int div) | ||
341 | { | ||
342 | u32 reg; | ||
343 | |||
344 | DBG("Entered %s\n", __FUNCTION__); | ||
345 | |||
346 | switch (div_id) { | ||
347 | case S3C24XX_DIV_MCLK: | ||
348 | reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK; | ||
349 | writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
350 | break; | ||
351 | case S3C24XX_DIV_BCLK: | ||
352 | reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS); | ||
353 | writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); | ||
354 | break; | ||
355 | case S3C24XX_DIV_PRESCALER: | ||
356 | writel(div, s3c24xx_i2s.regs + S3C2410_IISPSR); | ||
357 | reg = readl(s3c24xx_i2s.regs + S3C2410_IISCON); | ||
358 | writel(reg | S3C2410_IISCON_PSCEN, s3c24xx_i2s.regs + S3C2410_IISCON); | ||
359 | break; | ||
360 | default: | ||
361 | return -EINVAL; | ||
362 | } | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * To avoid duplicating clock code, allow machine driver to | ||
369 | * get the clockrate from here. | ||
370 | */ | ||
371 | u32 s3c24xx_i2s_get_clockrate(void) | ||
372 | { | ||
373 | return clk_get_rate(s3c24xx_i2s.iis_clk); | ||
374 | } | ||
375 | EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); | ||
376 | |||
377 | static int s3c24xx_i2s_probe(struct platform_device *pdev) | ||
378 | { | ||
379 | DBG("Entered %s\n", __FUNCTION__); | ||
380 | |||
381 | s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); | ||
382 | if (s3c24xx_i2s.regs == NULL) | ||
383 | return -ENXIO; | ||
384 | |||
385 | s3c24xx_i2s.iis_clk=clk_get(&pdev->dev, "iis"); | ||
386 | if (s3c24xx_i2s.iis_clk == NULL) { | ||
387 | DBG("failed to get iis_clock\n"); | ||
388 | return -ENODEV; | ||
389 | } | ||
390 | clk_enable(s3c24xx_i2s.iis_clk); | ||
391 | |||
392 | /* Configure the I2S pins in correct mode */ | ||
393 | s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); | ||
394 | s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK); | ||
395 | s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK); | ||
396 | s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI); | ||
397 | s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO); | ||
398 | |||
399 | writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON); | ||
400 | |||
401 | s3c24xx_snd_txctrl(0); | ||
402 | s3c24xx_snd_rxctrl(0); | ||
403 | |||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | #define S3C24XX_I2S_RATES \ | ||
408 | (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ | ||
409 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ | ||
410 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) | ||
411 | |||
412 | struct snd_soc_cpu_dai s3c24xx_i2s_dai = { | ||
413 | .name = "s3c24xx-i2s", | ||
414 | .id = 0, | ||
415 | .type = SND_SOC_DAI_I2S, | ||
416 | .probe = s3c24xx_i2s_probe, | ||
417 | .playback = { | ||
418 | .channels_min = 2, | ||
419 | .channels_max = 2, | ||
420 | .rates = S3C24XX_I2S_RATES, | ||
421 | .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, | ||
422 | .capture = { | ||
423 | .channels_min = 2, | ||
424 | .channels_max = 2, | ||
425 | .rates = S3C24XX_I2S_RATES, | ||
426 | .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, | ||
427 | .ops = { | ||
428 | .trigger = s3c24xx_i2s_trigger, | ||
429 | .hw_params = s3c24xx_i2s_hw_params,}, | ||
430 | .dai_ops = { | ||
431 | .set_fmt = s3c24xx_i2s_set_fmt, | ||
432 | .set_clkdiv = s3c24xx_i2s_set_clkdiv, | ||
433 | .set_sysclk = s3c24xx_i2s_set_sysclk, | ||
434 | }, | ||
435 | }; | ||
436 | EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai); | ||
437 | |||
438 | /* Module information */ | ||
439 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); | ||
440 | MODULE_DESCRIPTION("s3c24xx I2S SoC Interface"); | ||
441 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/s3c24xx/s3c24xx-i2s.h new file mode 100644 index 000000000000..537b4ecce8a3 --- /dev/null +++ b/sound/soc/s3c24xx/s3c24xx-i2s.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * s3c24xx-i2s.c -- ALSA Soc Audio Layer | ||
3 | * | ||
4 | * Copyright 2005 Wolfson Microelectronics PLC. | ||
5 | * Author: Graeme Gregory | ||
6 | * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * Revision history | ||
14 | * 10th Nov 2006 Initial version. | ||
15 | */ | ||
16 | |||
17 | #ifndef S3C24XXI2S_H_ | ||
18 | #define S3C24XXI2S_H_ | ||
19 | |||
20 | /* clock sources */ | ||
21 | #define S3C24XX_CLKSRC_PCLK 0 | ||
22 | #define S3C24XX_CLKSRC_MPLL 1 | ||
23 | |||
24 | /* Clock dividers */ | ||
25 | #define S3C24XX_DIV_MCLK 0 | ||
26 | #define S3C24XX_DIV_BCLK 1 | ||
27 | #define S3C24XX_DIV_PRESCALER 2 | ||
28 | |||
29 | /* prescaler */ | ||
30 | #define S3C24XX_PRESCALE(a,b) \ | ||
31 | (((a - 1) << S3C2410_IISPSR_INTSHIFT) | ((b - 1) << S3C2410_IISPSR_EXTSHFIT)) | ||
32 | |||
33 | u32 s3c24xx_i2s_get_clockrate(void); | ||
34 | |||
35 | extern struct snd_soc_cpu_dai s3c24xx_i2s_dai; | ||
36 | |||
37 | #endif /*S3C24XXI2S_H_*/ | ||
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c new file mode 100644 index 000000000000..21dc6974d6a3 --- /dev/null +++ b/sound/soc/s3c24xx/s3c24xx-pcm.c | |||
@@ -0,0 +1,468 @@ | |||
1 | /* | ||
2 | * s3c24xx-pcm.c -- ALSA Soc Audio Layer | ||
3 | * | ||
4 | * (c) 2006 Wolfson Microelectronics PLC. | ||
5 | * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com | ||
6 | * | ||
7 | * (c) 2004-2005 Simtec Electronics | ||
8 | * http://armlinux.simtec.co.uk/ | ||
9 | * Ben Dooks <ben@simtec.co.uk> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | * | ||
16 | * Revision history | ||
17 | * 11th Dec 2006 Merged with Simtec driver | ||
18 | * 10th Nov 2006 Initial version. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/dma-mapping.h> | ||
26 | |||
27 | #include <sound/driver.h> | ||
28 | #include <sound/core.h> | ||
29 | #include <sound/pcm.h> | ||
30 | #include <sound/pcm_params.h> | ||
31 | #include <sound/soc.h> | ||
32 | |||
33 | #include <asm/dma.h> | ||
34 | #include <asm/io.h> | ||
35 | #include <asm/hardware.h> | ||
36 | #include <asm/arch/dma.h> | ||
37 | #include <asm/arch/audio.h> | ||
38 | |||
39 | #include "s3c24xx-pcm.h" | ||
40 | |||
41 | #define S3C24XX_PCM_DEBUG 0 | ||
42 | #if S3C24XX_PCM_DEBUG | ||
43 | #define DBG(x...) printk(KERN_DEBUG x) | ||
44 | #else | ||
45 | #define DBG(x...) | ||
46 | #endif | ||
47 | |||
48 | static const struct snd_pcm_hardware s3c24xx_pcm_hardware = { | ||
49 | .info = SNDRV_PCM_INFO_INTERLEAVED | | ||
50 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
51 | SNDRV_PCM_INFO_MMAP | | ||
52 | SNDRV_PCM_INFO_MMAP_VALID, | ||
53 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | ||
54 | SNDRV_PCM_FMTBIT_U16_LE | | ||
55 | SNDRV_PCM_FMTBIT_U8 | | ||
56 | SNDRV_PCM_FMTBIT_S8, | ||
57 | .channels_min = 2, | ||
58 | .channels_max = 2, | ||
59 | .buffer_bytes_max = 128*1024, | ||
60 | .period_bytes_min = PAGE_SIZE, | ||
61 | .period_bytes_max = PAGE_SIZE*2, | ||
62 | .periods_min = 2, | ||
63 | .periods_max = 128, | ||
64 | .fifo_size = 32, | ||
65 | }; | ||
66 | |||
67 | struct s3c24xx_runtime_data { | ||
68 | spinlock_t lock; | ||
69 | int state; | ||
70 | unsigned int dma_loaded; | ||
71 | unsigned int dma_limit; | ||
72 | unsigned int dma_period; | ||
73 | dma_addr_t dma_start; | ||
74 | dma_addr_t dma_pos; | ||
75 | dma_addr_t dma_end; | ||
76 | struct s3c24xx_pcm_dma_params *params; | ||
77 | }; | ||
78 | |||
79 | /* s3c24xx_pcm_enqueue | ||
80 | * | ||
81 | * place a dma buffer onto the queue for the dma system | ||
82 | * to handle. | ||
83 | */ | ||
84 | static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream) | ||
85 | { | ||
86 | struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; | ||
87 | dma_addr_t pos = prtd->dma_pos; | ||
88 | int ret; | ||
89 | |||
90 | DBG("Entered %s\n", __FUNCTION__); | ||
91 | |||
92 | while (prtd->dma_loaded < prtd->dma_limit) { | ||
93 | unsigned long len = prtd->dma_period; | ||
94 | |||
95 | DBG("dma_loaded: %d\n",prtd->dma_loaded); | ||
96 | |||
97 | if ((pos + len) > prtd->dma_end) { | ||
98 | len = prtd->dma_end - pos; | ||
99 | DBG(KERN_DEBUG "%s: corrected dma len %ld\n", | ||
100 | __FUNCTION__, len); | ||
101 | } | ||
102 | |||
103 | ret = s3c2410_dma_enqueue(prtd->params->channel, | ||
104 | substream, pos, len); | ||
105 | |||
106 | if (ret == 0) { | ||
107 | prtd->dma_loaded++; | ||
108 | pos += prtd->dma_period; | ||
109 | if (pos >= prtd->dma_end) | ||
110 | pos = prtd->dma_start; | ||
111 | } else | ||
112 | break; | ||
113 | } | ||
114 | |||
115 | prtd->dma_pos = pos; | ||
116 | } | ||
117 | |||
118 | static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, | ||
119 | void *dev_id, int size, | ||
120 | enum s3c2410_dma_buffresult result) | ||
121 | { | ||
122 | struct snd_pcm_substream *substream = dev_id; | ||
123 | struct s3c24xx_runtime_data *prtd; | ||
124 | |||
125 | DBG("Entered %s\n", __FUNCTION__); | ||
126 | |||
127 | if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) | ||
128 | return; | ||
129 | |||
130 | prtd = substream->runtime->private_data; | ||
131 | |||
132 | if (substream) | ||
133 | snd_pcm_period_elapsed(substream); | ||
134 | |||
135 | spin_lock(&prtd->lock); | ||
136 | if (prtd->state & ST_RUNNING) { | ||
137 | prtd->dma_loaded--; | ||
138 | s3c24xx_pcm_enqueue(substream); | ||
139 | } | ||
140 | |||
141 | spin_unlock(&prtd->lock); | ||
142 | } | ||
143 | |||
144 | static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream, | ||
145 | struct snd_pcm_hw_params *params) | ||
146 | { | ||
147 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
148 | struct s3c24xx_runtime_data *prtd = runtime->private_data; | ||
149 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
150 | struct s3c24xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; | ||
151 | unsigned long totbytes = params_buffer_bytes(params); | ||
152 | int ret=0; | ||
153 | |||
154 | DBG("Entered %s\n", __FUNCTION__); | ||
155 | |||
156 | /* return if this is a bufferless transfer e.g. | ||
157 | * codec <--> BT codec or GSM modem -- lg FIXME */ | ||
158 | if (!dma) | ||
159 | return 0; | ||
160 | |||
161 | /* prepare DMA */ | ||
162 | prtd->params = dma; | ||
163 | |||
164 | DBG("params %p, client %p, channel %d\n", prtd->params, | ||
165 | prtd->params->client, prtd->params->channel); | ||
166 | |||
167 | ret = s3c2410_dma_request(prtd->params->channel, | ||
168 | prtd->params->client, NULL); | ||
169 | |||
170 | if (ret) { | ||
171 | DBG(KERN_ERR "failed to get dma channel\n"); | ||
172 | return ret; | ||
173 | } | ||
174 | |||
175 | /* channel needs configuring for mem=>device, increment memory addr, | ||
176 | * sync to pclk, half-word transfers to the IIS-FIFO. */ | ||
177 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
178 | s3c2410_dma_devconfig(prtd->params->channel, | ||
179 | S3C2410_DMASRC_MEM, S3C2410_DISRCC_INC | | ||
180 | S3C2410_DISRCC_APB, prtd->params->dma_addr); | ||
181 | |||
182 | s3c2410_dma_config(prtd->params->channel, | ||
183 | prtd->params->dma_size, | ||
184 | S3C2410_DCON_SYNC_PCLK | | ||
185 | S3C2410_DCON_HANDSHAKE); | ||
186 | } else { | ||
187 | s3c2410_dma_config(prtd->params->channel, | ||
188 | prtd->params->dma_size, | ||
189 | S3C2410_DCON_HANDSHAKE | | ||
190 | S3C2410_DCON_SYNC_PCLK); | ||
191 | |||
192 | s3c2410_dma_devconfig(prtd->params->channel, | ||
193 | S3C2410_DMASRC_HW, 0x3, | ||
194 | prtd->params->dma_addr); | ||
195 | } | ||
196 | |||
197 | s3c2410_dma_set_buffdone_fn(prtd->params->channel, | ||
198 | s3c24xx_audio_buffdone); | ||
199 | |||
200 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
201 | |||
202 | runtime->dma_bytes = totbytes; | ||
203 | |||
204 | spin_lock_irq(&prtd->lock); | ||
205 | prtd->dma_loaded = 0; | ||
206 | prtd->dma_limit = runtime->hw.periods_min; | ||
207 | prtd->dma_period = params_period_bytes(params); | ||
208 | prtd->dma_start = runtime->dma_addr; | ||
209 | prtd->dma_pos = prtd->dma_start; | ||
210 | prtd->dma_end = prtd->dma_start + totbytes; | ||
211 | spin_unlock_irq(&prtd->lock); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream) | ||
217 | { | ||
218 | struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; | ||
219 | |||
220 | DBG("Entered %s\n", __FUNCTION__); | ||
221 | |||
222 | /* TODO - do we need to ensure DMA flushed */ | ||
223 | snd_pcm_set_runtime_buffer(substream, NULL); | ||
224 | |||
225 | if (prtd->params) { | ||
226 | s3c2410_dma_free(prtd->params->channel, prtd->params->client); | ||
227 | prtd->params = NULL; | ||
228 | } | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream) | ||
234 | { | ||
235 | struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; | ||
236 | int ret = 0; | ||
237 | |||
238 | DBG("Entered %s\n", __FUNCTION__); | ||
239 | |||
240 | /* return if this is a bufferless transfer e.g. | ||
241 | * codec <--> BT codec or GSM modem -- lg FIXME */ | ||
242 | if (!prtd->params) | ||
243 | return 0; | ||
244 | |||
245 | /* flush the DMA channel */ | ||
246 | s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); | ||
247 | prtd->dma_loaded = 0; | ||
248 | prtd->dma_pos = prtd->dma_start; | ||
249 | |||
250 | /* enqueue dma buffers */ | ||
251 | s3c24xx_pcm_enqueue(substream); | ||
252 | |||
253 | return ret; | ||
254 | } | ||
255 | |||
256 | static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
257 | { | ||
258 | struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; | ||
259 | int ret = 0; | ||
260 | |||
261 | DBG("Entered %s\n", __FUNCTION__); | ||
262 | |||
263 | spin_lock(&prtd->lock); | ||
264 | |||
265 | switch (cmd) { | ||
266 | case SNDRV_PCM_TRIGGER_START: | ||
267 | case SNDRV_PCM_TRIGGER_RESUME: | ||
268 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
269 | prtd->state |= ST_RUNNING; | ||
270 | s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START); | ||
271 | s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STARTED); | ||
272 | break; | ||
273 | |||
274 | case SNDRV_PCM_TRIGGER_STOP: | ||
275 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
276 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
277 | prtd->state &= ~ST_RUNNING; | ||
278 | s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP); | ||
279 | break; | ||
280 | |||
281 | default: | ||
282 | ret = -EINVAL; | ||
283 | break; | ||
284 | } | ||
285 | |||
286 | spin_unlock(&prtd->lock); | ||
287 | |||
288 | return ret; | ||
289 | } | ||
290 | |||
291 | static snd_pcm_uframes_t | ||
292 | s3c24xx_pcm_pointer(struct snd_pcm_substream *substream) | ||
293 | { | ||
294 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
295 | struct s3c24xx_runtime_data *prtd = runtime->private_data; | ||
296 | unsigned long res; | ||
297 | dma_addr_t src, dst; | ||
298 | |||
299 | DBG("Entered %s\n", __FUNCTION__); | ||
300 | |||
301 | spin_lock(&prtd->lock); | ||
302 | s3c2410_dma_getposition(prtd->params->channel, &src, &dst); | ||
303 | |||
304 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | ||
305 | res = dst - prtd->dma_start; | ||
306 | else | ||
307 | res = src - prtd->dma_start; | ||
308 | |||
309 | spin_unlock(&prtd->lock); | ||
310 | |||
311 | DBG("Pointer %x %x\n",src,dst); | ||
312 | |||
313 | /* we seem to be getting the odd error from the pcm library due | ||
314 | * to out-of-bounds pointers. this is maybe due to the dma engine | ||
315 | * not having loaded the new values for the channel before being | ||
316 | * callled... (todo - fix ) | ||
317 | */ | ||
318 | |||
319 | if (res >= snd_pcm_lib_buffer_bytes(substream)) { | ||
320 | if (res == snd_pcm_lib_buffer_bytes(substream)) | ||
321 | res = 0; | ||
322 | } | ||
323 | |||
324 | return bytes_to_frames(substream->runtime, res); | ||
325 | } | ||
326 | |||
327 | static int s3c24xx_pcm_open(struct snd_pcm_substream *substream) | ||
328 | { | ||
329 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
330 | struct s3c24xx_runtime_data *prtd; | ||
331 | |||
332 | DBG("Entered %s\n", __FUNCTION__); | ||
333 | |||
334 | snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware); | ||
335 | |||
336 | prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL); | ||
337 | if (prtd == NULL) | ||
338 | return -ENOMEM; | ||
339 | |||
340 | runtime->private_data = prtd; | ||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static int s3c24xx_pcm_close(struct snd_pcm_substream *substream) | ||
345 | { | ||
346 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
347 | struct s3c24xx_runtime_data *prtd = runtime->private_data; | ||
348 | |||
349 | DBG("Entered %s\n", __FUNCTION__); | ||
350 | |||
351 | if (prtd) | ||
352 | kfree(prtd); | ||
353 | else | ||
354 | DBG("s3c24xx_pcm_close called with prtd == NULL\n"); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static int s3c24xx_pcm_mmap(struct snd_pcm_substream *substream, | ||
360 | struct vm_area_struct *vma) | ||
361 | { | ||
362 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
363 | |||
364 | DBG("Entered %s\n", __FUNCTION__); | ||
365 | |||
366 | return dma_mmap_writecombine(substream->pcm->card->dev, vma, | ||
367 | runtime->dma_area, | ||
368 | runtime->dma_addr, | ||
369 | runtime->dma_bytes); | ||
370 | } | ||
371 | |||
372 | static struct snd_pcm_ops s3c24xx_pcm_ops = { | ||
373 | .open = s3c24xx_pcm_open, | ||
374 | .close = s3c24xx_pcm_close, | ||
375 | .ioctl = snd_pcm_lib_ioctl, | ||
376 | .hw_params = s3c24xx_pcm_hw_params, | ||
377 | .hw_free = s3c24xx_pcm_hw_free, | ||
378 | .prepare = s3c24xx_pcm_prepare, | ||
379 | .trigger = s3c24xx_pcm_trigger, | ||
380 | .pointer = s3c24xx_pcm_pointer, | ||
381 | .mmap = s3c24xx_pcm_mmap, | ||
382 | }; | ||
383 | |||
384 | static int s3c24xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
385 | { | ||
386 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
387 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
388 | size_t size = s3c24xx_pcm_hardware.buffer_bytes_max; | ||
389 | |||
390 | DBG("Entered %s\n", __FUNCTION__); | ||
391 | |||
392 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
393 | buf->dev.dev = pcm->card->dev; | ||
394 | buf->private_data = NULL; | ||
395 | buf->area = dma_alloc_writecombine(pcm->card->dev, size, | ||
396 | &buf->addr, GFP_KERNEL); | ||
397 | if (!buf->area) | ||
398 | return -ENOMEM; | ||
399 | buf->bytes = size; | ||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm) | ||
404 | { | ||
405 | struct snd_pcm_substream *substream; | ||
406 | struct snd_dma_buffer *buf; | ||
407 | int stream; | ||
408 | |||
409 | DBG("Entered %s\n", __FUNCTION__); | ||
410 | |||
411 | for (stream = 0; stream < 2; stream++) { | ||
412 | substream = pcm->streams[stream].substream; | ||
413 | if (!substream) | ||
414 | continue; | ||
415 | |||
416 | buf = &substream->dma_buffer; | ||
417 | if (!buf->area) | ||
418 | continue; | ||
419 | |||
420 | dma_free_writecombine(pcm->card->dev, buf->bytes, | ||
421 | buf->area, buf->addr); | ||
422 | buf->area = NULL; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | static u64 s3c24xx_pcm_dmamask = DMA_32BIT_MASK; | ||
427 | |||
428 | static int s3c24xx_pcm_new(struct snd_card *card, | ||
429 | struct snd_soc_codec_dai *dai, struct snd_pcm *pcm) | ||
430 | { | ||
431 | int ret = 0; | ||
432 | |||
433 | DBG("Entered %s\n", __FUNCTION__); | ||
434 | |||
435 | if (!card->dev->dma_mask) | ||
436 | card->dev->dma_mask = &s3c24xx_pcm_dmamask; | ||
437 | if (!card->dev->coherent_dma_mask) | ||
438 | card->dev->coherent_dma_mask = 0xffffffff; | ||
439 | |||
440 | if (dai->playback.channels_min) { | ||
441 | ret = s3c24xx_pcm_preallocate_dma_buffer(pcm, | ||
442 | SNDRV_PCM_STREAM_PLAYBACK); | ||
443 | if (ret) | ||
444 | goto out; | ||
445 | } | ||
446 | |||
447 | if (dai->capture.channels_min) { | ||
448 | ret = s3c24xx_pcm_preallocate_dma_buffer(pcm, | ||
449 | SNDRV_PCM_STREAM_CAPTURE); | ||
450 | if (ret) | ||
451 | goto out; | ||
452 | } | ||
453 | out: | ||
454 | return ret; | ||
455 | } | ||
456 | |||
457 | struct snd_soc_platform s3c24xx_soc_platform = { | ||
458 | .name = "s3c24xx-audio", | ||
459 | .pcm_ops = &s3c24xx_pcm_ops, | ||
460 | .pcm_new = s3c24xx_pcm_new, | ||
461 | .pcm_free = s3c24xx_pcm_free_dma_buffers, | ||
462 | }; | ||
463 | |||
464 | EXPORT_SYMBOL_GPL(s3c24xx_soc_platform); | ||
465 | |||
466 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); | ||
467 | MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module"); | ||
468 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.h b/sound/soc/s3c24xx/s3c24xx-pcm.h new file mode 100644 index 000000000000..0088c79822ea --- /dev/null +++ b/sound/soc/s3c24xx/s3c24xx-pcm.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * s3c24xx-pcm.h -- | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | * | ||
9 | * ALSA PCM interface for the Samsung S3C24xx CPU | ||
10 | */ | ||
11 | |||
12 | #ifndef _S3C24XX_PCM_H | ||
13 | #define _S3C24XX_PCM_H | ||
14 | |||
15 | #define ST_RUNNING (1<<0) | ||
16 | #define ST_OPENED (1<<1) | ||
17 | |||
18 | struct s3c24xx_pcm_dma_params { | ||
19 | struct s3c2410_dma_client *client; /* stream identifier */ | ||
20 | int channel; /* Channel ID */ | ||
21 | dma_addr_t dma_addr; | ||
22 | int dma_size; /* Size of the DMA transfer */ | ||
23 | }; | ||
24 | |||
25 | #define S3C24XX_DAI_I2S 0 | ||
26 | |||
27 | /* platform data */ | ||
28 | extern struct snd_soc_platform s3c24xx_soc_platform; | ||
29 | extern struct snd_ac97_bus_ops s3c24xx_ac97_ops; | ||
30 | |||
31 | #endif | ||
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 7caf8c7b0ac5..96bce55572a0 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -882,13 +882,15 @@ int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink, | |||
882 | if (wsink->id == snd_soc_dapm_input) { | 882 | if (wsink->id == snd_soc_dapm_input) { |
883 | if (wsource->id == snd_soc_dapm_micbias || | 883 | if (wsource->id == snd_soc_dapm_micbias || |
884 | wsource->id == snd_soc_dapm_mic || | 884 | wsource->id == snd_soc_dapm_mic || |
885 | wsink->id == snd_soc_dapm_line) | 885 | wsink->id == snd_soc_dapm_line || |
886 | wsink->id == snd_soc_dapm_output) | ||
886 | wsink->ext = 1; | 887 | wsink->ext = 1; |
887 | } | 888 | } |
888 | if (wsource->id == snd_soc_dapm_output) { | 889 | if (wsource->id == snd_soc_dapm_output) { |
889 | if (wsink->id == snd_soc_dapm_spk || | 890 | if (wsink->id == snd_soc_dapm_spk || |
890 | wsink->id == snd_soc_dapm_hp || | 891 | wsink->id == snd_soc_dapm_hp || |
891 | wsink->id == snd_soc_dapm_line) | 892 | wsink->id == snd_soc_dapm_line || |
893 | wsink->id == snd_soc_dapm_input) | ||
892 | wsource->ext = 1; | 894 | wsource->ext = 1; |
893 | } | 895 | } |
894 | 896 | ||
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 900a00de35fd..dca0344cc1bc 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c | |||
@@ -661,11 +661,9 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, int cmd) | |||
661 | { | 661 | { |
662 | unsigned int what = 0; | 662 | unsigned int what = 0; |
663 | struct snd_pcm_substream *s; | 663 | struct snd_pcm_substream *s; |
664 | struct list_head *pos; | ||
665 | unsigned long flags; | 664 | unsigned long flags; |
666 | 665 | ||
667 | snd_pcm_group_for_each(pos, substream) { | 666 | snd_pcm_group_for_each_entry(s, substream) { |
668 | s = snd_pcm_group_substream_entry(pos); | ||
669 | if (s == chip->playback_substream) { | 667 | if (s == chip->playback_substream) { |
670 | what |= CS4231_PLAYBACK_ENABLE; | 668 | what |= CS4231_PLAYBACK_ENABLE; |
671 | snd_pcm_trigger_done(s, substream); | 669 | snd_pcm_trigger_done(s, substream); |
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index f05d02f5b69f..315360f31278 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
@@ -29,5 +29,33 @@ config SND_USB_USX2Y | |||
29 | To compile this driver as a module, choose M here: the module | 29 | To compile this driver as a module, choose M here: the module |
30 | will be called snd-usb-usx2y. | 30 | will be called snd-usb-usx2y. |
31 | 31 | ||
32 | config SND_USB_CAIAQ | ||
33 | tristate "Native Instruments USB audio devices" | ||
34 | depends on SND && USB | ||
35 | select SND_HWDEP | ||
36 | select SND_RAWMIDI | ||
37 | select SND_PCM | ||
38 | help | ||
39 | Say Y here to include support for caiaq USB audio interfaces, | ||
40 | namely: | ||
41 | |||
42 | * Native Instruments RigKontrol2 | ||
43 | * Native Instruments Kore Controller | ||
44 | * Native Instruments Audio Kontrol 1 | ||
45 | * Native Instruments Audio 8 DJ | ||
46 | |||
47 | To compile this driver as a module, choose M here: the module | ||
48 | will be called snd-usb-caiaq. | ||
49 | |||
50 | config SND_USB_CAIAQ_INPUT | ||
51 | bool "enable input device for controllers" | ||
52 | depends on SND_USB_CAIAQ | ||
53 | help | ||
54 | Say Y here to support input controllers like buttons, knobs, | ||
55 | alpha dials and analog pedals on the following products: | ||
56 | |||
57 | * Native Instruments RigKontrol2 | ||
58 | * Native Instruments Audio Kontrol 1 | ||
59 | |||
32 | endmenu | 60 | endmenu |
33 | 61 | ||
diff --git a/sound/usb/Makefile b/sound/usb/Makefile index 2c1dc11a72e2..aa252ef2ebfb 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile | |||
@@ -9,4 +9,4 @@ snd-usb-lib-objs := usbmidi.o | |||
9 | obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o | 9 | obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o |
10 | obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o | 10 | obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o |
11 | 11 | ||
12 | obj-$(CONFIG_SND) += usx2y/ | 12 | obj-$(CONFIG_SND) += usx2y/ caiaq/ |
diff --git a/sound/usb/caiaq/Makefile b/sound/usb/caiaq/Makefile new file mode 100644 index 000000000000..455c8c58a1bd --- /dev/null +++ b/sound/usb/caiaq/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | snd-usb-caiaq-objs := caiaq-device.o caiaq-audio.o caiaq-midi.o caiaq-input.o | ||
2 | |||
3 | obj-$(CONFIG_SND_USB_CAIAQ) += snd-usb-caiaq.o | ||
diff --git a/sound/usb/caiaq/caiaq-audio.c b/sound/usb/caiaq/caiaq-audio.c new file mode 100644 index 000000000000..0414d766ba07 --- /dev/null +++ b/sound/usb/caiaq/caiaq-audio.c | |||
@@ -0,0 +1,707 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2006,2007 Daniel Mack, Karsten Wiese | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program 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 program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | #include <sound/driver.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/moduleparam.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/usb.h> | ||
25 | #include <linux/spinlock.h> | ||
26 | #include <sound/core.h> | ||
27 | #include <sound/initval.h> | ||
28 | #include <sound/pcm.h> | ||
29 | #include <sound/rawmidi.h> | ||
30 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | ||
31 | #include <linux/input.h> | ||
32 | #endif | ||
33 | |||
34 | #include "caiaq-device.h" | ||
35 | #include "caiaq-audio.h" | ||
36 | |||
37 | #define N_URBS 32 | ||
38 | #define CLOCK_DRIFT_TOLERANCE 5 | ||
39 | #define FRAMES_PER_URB 8 | ||
40 | #define BYTES_PER_FRAME 512 | ||
41 | #define CHANNELS_PER_STREAM 2 | ||
42 | #define BYTES_PER_SAMPLE 3 | ||
43 | #define BYTES_PER_SAMPLE_USB 4 | ||
44 | #define MAX_BUFFER_SIZE (128*1024) | ||
45 | |||
46 | #define ENDPOINT_CAPTURE 2 | ||
47 | #define ENDPOINT_PLAYBACK 6 | ||
48 | |||
49 | #define MAKE_CHECKBYTE(dev,stream,i) \ | ||
50 | (stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1) | ||
51 | |||
52 | static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = { | ||
53 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | ||
54 | SNDRV_PCM_INFO_BLOCK_TRANSFER), | ||
55 | .formats = SNDRV_PCM_FMTBIT_S24_3BE, | ||
56 | .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | | ||
57 | SNDRV_PCM_RATE_96000), | ||
58 | .rate_min = 44100, | ||
59 | .rate_max = 0, /* will overwrite later */ | ||
60 | .channels_min = CHANNELS_PER_STREAM, | ||
61 | .channels_max = CHANNELS_PER_STREAM, | ||
62 | .buffer_bytes_max = MAX_BUFFER_SIZE, | ||
63 | .period_bytes_min = 4096, | ||
64 | .period_bytes_max = MAX_BUFFER_SIZE, | ||
65 | .periods_min = 1, | ||
66 | .periods_max = 1024, | ||
67 | }; | ||
68 | |||
69 | static void | ||
70 | activate_substream(struct snd_usb_caiaqdev *dev, | ||
71 | struct snd_pcm_substream *sub) | ||
72 | { | ||
73 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
74 | dev->sub_playback[sub->number] = sub; | ||
75 | else | ||
76 | dev->sub_capture[sub->number] = sub; | ||
77 | } | ||
78 | |||
79 | static void | ||
80 | deactivate_substream(struct snd_usb_caiaqdev *dev, | ||
81 | struct snd_pcm_substream *sub) | ||
82 | { | ||
83 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
84 | dev->sub_playback[sub->number] = NULL; | ||
85 | else | ||
86 | dev->sub_capture[sub->number] = NULL; | ||
87 | } | ||
88 | |||
89 | static int | ||
90 | all_substreams_zero(struct snd_pcm_substream **subs) | ||
91 | { | ||
92 | int i; | ||
93 | for (i = 0; i < MAX_STREAMS; i++) | ||
94 | if (subs[i] != NULL) | ||
95 | return 0; | ||
96 | return 1; | ||
97 | } | ||
98 | |||
99 | static int stream_start(struct snd_usb_caiaqdev *dev) | ||
100 | { | ||
101 | int i, ret; | ||
102 | |||
103 | debug("stream_start(%p)\n", dev); | ||
104 | spin_lock_irq(&dev->spinlock); | ||
105 | if (dev->streaming) { | ||
106 | spin_unlock_irq(&dev->spinlock); | ||
107 | return -EINVAL; | ||
108 | } | ||
109 | |||
110 | dev->input_panic = 0; | ||
111 | dev->output_panic = 0; | ||
112 | dev->first_packet = 1; | ||
113 | dev->streaming = 1; | ||
114 | |||
115 | for (i = 0; i < N_URBS; i++) { | ||
116 | ret = usb_submit_urb(dev->data_urbs_in[i], GFP_ATOMIC); | ||
117 | if (ret) { | ||
118 | log("unable to trigger initial read #%d! (ret = %d)\n", | ||
119 | i, ret); | ||
120 | dev->streaming = 0; | ||
121 | spin_unlock_irq(&dev->spinlock); | ||
122 | return -EPIPE; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | spin_unlock_irq(&dev->spinlock); | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static void stream_stop(struct snd_usb_caiaqdev *dev) | ||
131 | { | ||
132 | int i; | ||
133 | |||
134 | debug("stream_stop(%p)\n", dev); | ||
135 | if (!dev->streaming) | ||
136 | return; | ||
137 | |||
138 | dev->streaming = 0; | ||
139 | for (i = 0; i < N_URBS; i++) { | ||
140 | usb_unlink_urb(dev->data_urbs_in[i]); | ||
141 | usb_unlink_urb(dev->data_urbs_out[i]); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream) | ||
146 | { | ||
147 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); | ||
148 | debug("snd_usb_caiaq_substream_open(%p)\n", substream); | ||
149 | substream->runtime->hw = dev->pcm_info; | ||
150 | snd_pcm_limit_hw_rates(substream->runtime); | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream) | ||
155 | { | ||
156 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); | ||
157 | |||
158 | debug("snd_usb_caiaq_substream_close(%p)\n", substream); | ||
159 | if (all_substreams_zero(dev->sub_playback) && | ||
160 | all_substreams_zero(dev->sub_capture)) { | ||
161 | /* when the last client has stopped streaming, | ||
162 | * all sample rates are allowed again */ | ||
163 | stream_stop(dev); | ||
164 | dev->pcm_info.rates = dev->samplerates; | ||
165 | } | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub, | ||
171 | struct snd_pcm_hw_params *hw_params) | ||
172 | { | ||
173 | debug("snd_usb_caiaq_pcm_hw_params(%p)\n", sub); | ||
174 | return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params)); | ||
175 | } | ||
176 | |||
177 | static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub) | ||
178 | { | ||
179 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); | ||
180 | debug("snd_usb_caiaq_pcm_hw_free(%p)\n", sub); | ||
181 | spin_lock_irq(&dev->spinlock); | ||
182 | deactivate_substream(dev, sub); | ||
183 | spin_unlock_irq(&dev->spinlock); | ||
184 | return snd_pcm_lib_free_pages(sub); | ||
185 | } | ||
186 | |||
187 | /* this should probably go upstream */ | ||
188 | #if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12 | ||
189 | #error "Change this table" | ||
190 | #endif | ||
191 | |||
192 | static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, | ||
193 | 48000, 64000, 88200, 96000, 176400, 192000 }; | ||
194 | |||
195 | static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) | ||
196 | { | ||
197 | int bytes_per_sample, bpp, ret, i; | ||
198 | int index = substream->number; | ||
199 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); | ||
200 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
201 | |||
202 | debug("snd_usb_caiaq_pcm_prepare(%p)\n", substream); | ||
203 | |||
204 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
205 | dev->audio_out_buf_pos[index] = BYTES_PER_SAMPLE + 1; | ||
206 | else | ||
207 | dev->audio_in_buf_pos[index] = 0; | ||
208 | |||
209 | if (dev->streaming) | ||
210 | return 0; | ||
211 | |||
212 | /* the first client that opens a stream defines the sample rate | ||
213 | * setting for all subsequent calls, until the last client closed. */ | ||
214 | for (i=0; i < ARRAY_SIZE(rates); i++) | ||
215 | if (runtime->rate == rates[i]) | ||
216 | dev->pcm_info.rates = 1 << i; | ||
217 | |||
218 | snd_pcm_limit_hw_rates(runtime); | ||
219 | |||
220 | bytes_per_sample = BYTES_PER_SAMPLE; | ||
221 | if (dev->spec.data_alignment == 2) | ||
222 | bytes_per_sample++; | ||
223 | |||
224 | bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) | ||
225 | * bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams; | ||
226 | |||
227 | ret = snd_usb_caiaq_set_audio_params(dev, runtime->rate, | ||
228 | runtime->sample_bits, bpp); | ||
229 | if (ret) | ||
230 | return ret; | ||
231 | |||
232 | ret = stream_start(dev); | ||
233 | if (ret) | ||
234 | return ret; | ||
235 | |||
236 | dev->output_running = 0; | ||
237 | wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ); | ||
238 | if (!dev->output_running) { | ||
239 | stream_stop(dev); | ||
240 | return -EPIPE; | ||
241 | } | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd) | ||
247 | { | ||
248 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); | ||
249 | |||
250 | switch (cmd) { | ||
251 | case SNDRV_PCM_TRIGGER_START: | ||
252 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
253 | spin_lock(&dev->spinlock); | ||
254 | activate_substream(dev, sub); | ||
255 | spin_unlock(&dev->spinlock); | ||
256 | break; | ||
257 | case SNDRV_PCM_TRIGGER_STOP: | ||
258 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
259 | spin_lock(&dev->spinlock); | ||
260 | deactivate_substream(dev, sub); | ||
261 | spin_unlock(&dev->spinlock); | ||
262 | break; | ||
263 | default: | ||
264 | return -EINVAL; | ||
265 | } | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static snd_pcm_uframes_t | ||
271 | snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) | ||
272 | { | ||
273 | int index = sub->number; | ||
274 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); | ||
275 | |||
276 | if (dev->input_panic || dev->output_panic) | ||
277 | return SNDRV_PCM_POS_XRUN; | ||
278 | |||
279 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
280 | return bytes_to_frames(sub->runtime, | ||
281 | dev->audio_out_buf_pos[index]); | ||
282 | else | ||
283 | return bytes_to_frames(sub->runtime, | ||
284 | dev->audio_in_buf_pos[index]); | ||
285 | } | ||
286 | |||
287 | /* operators for both playback and capture */ | ||
288 | static struct snd_pcm_ops snd_usb_caiaq_ops = { | ||
289 | .open = snd_usb_caiaq_substream_open, | ||
290 | .close = snd_usb_caiaq_substream_close, | ||
291 | .ioctl = snd_pcm_lib_ioctl, | ||
292 | .hw_params = snd_usb_caiaq_pcm_hw_params, | ||
293 | .hw_free = snd_usb_caiaq_pcm_hw_free, | ||
294 | .prepare = snd_usb_caiaq_pcm_prepare, | ||
295 | .trigger = snd_usb_caiaq_pcm_trigger, | ||
296 | .pointer = snd_usb_caiaq_pcm_pointer | ||
297 | }; | ||
298 | |||
299 | static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev, | ||
300 | struct snd_pcm_substream **subs) | ||
301 | { | ||
302 | int stream, pb, *cnt; | ||
303 | struct snd_pcm_substream *sub; | ||
304 | |||
305 | for (stream = 0; stream < dev->n_streams; stream++) { | ||
306 | sub = subs[stream]; | ||
307 | if (!sub) | ||
308 | continue; | ||
309 | |||
310 | pb = frames_to_bytes(sub->runtime, | ||
311 | sub->runtime->period_size); | ||
312 | cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
313 | &dev->period_out_count[stream] : | ||
314 | &dev->period_in_count[stream]; | ||
315 | |||
316 | if (*cnt >= pb) { | ||
317 | snd_pcm_period_elapsed(sub); | ||
318 | *cnt %= pb; | ||
319 | } | ||
320 | } | ||
321 | } | ||
322 | |||
323 | static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev, | ||
324 | const struct urb *urb, | ||
325 | const struct usb_iso_packet_descriptor *iso) | ||
326 | { | ||
327 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; | ||
328 | struct snd_pcm_substream *sub; | ||
329 | int stream, i; | ||
330 | |||
331 | if (all_substreams_zero(dev->sub_capture)) | ||
332 | return; | ||
333 | |||
334 | spin_lock(&dev->spinlock); | ||
335 | |||
336 | for (i = 0; i < iso->actual_length;) { | ||
337 | for (stream = 0; stream < dev->n_streams; stream++, i++) { | ||
338 | sub = dev->sub_capture[stream]; | ||
339 | if (sub) { | ||
340 | struct snd_pcm_runtime *rt = sub->runtime; | ||
341 | char *audio_buf = rt->dma_area; | ||
342 | int sz = frames_to_bytes(rt, rt->buffer_size); | ||
343 | audio_buf[dev->audio_in_buf_pos[stream]++] | ||
344 | = usb_buf[i]; | ||
345 | dev->period_in_count[stream]++; | ||
346 | if (dev->audio_in_buf_pos[stream] == sz) | ||
347 | dev->audio_in_buf_pos[stream] = 0; | ||
348 | } | ||
349 | } | ||
350 | } | ||
351 | |||
352 | spin_unlock(&dev->spinlock); | ||
353 | } | ||
354 | |||
355 | static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev, | ||
356 | const struct urb *urb, | ||
357 | const struct usb_iso_packet_descriptor *iso) | ||
358 | { | ||
359 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; | ||
360 | unsigned char check_byte; | ||
361 | struct snd_pcm_substream *sub; | ||
362 | int stream, i; | ||
363 | |||
364 | spin_lock(&dev->spinlock); | ||
365 | |||
366 | for (i = 0; i < iso->actual_length;) { | ||
367 | if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) { | ||
368 | for (stream = 0; | ||
369 | stream < dev->n_streams; | ||
370 | stream++, i++) { | ||
371 | if (dev->first_packet) | ||
372 | continue; | ||
373 | |||
374 | check_byte = MAKE_CHECKBYTE(dev, stream, i); | ||
375 | |||
376 | if ((usb_buf[i] & 0x3f) != check_byte) | ||
377 | dev->input_panic = 1; | ||
378 | |||
379 | if (usb_buf[i] & 0x80) | ||
380 | dev->output_panic = 1; | ||
381 | } | ||
382 | } | ||
383 | dev->first_packet = 0; | ||
384 | |||
385 | for (stream = 0; stream < dev->n_streams; stream++, i++) { | ||
386 | sub = dev->sub_capture[stream]; | ||
387 | if (sub) { | ||
388 | struct snd_pcm_runtime *rt = sub->runtime; | ||
389 | char *audio_buf = rt->dma_area; | ||
390 | int sz = frames_to_bytes(rt, rt->buffer_size); | ||
391 | audio_buf[dev->audio_in_buf_pos[stream]++] = | ||
392 | usb_buf[i]; | ||
393 | dev->period_in_count[stream]++; | ||
394 | if (dev->audio_in_buf_pos[stream] == sz) | ||
395 | dev->audio_in_buf_pos[stream] = 0; | ||
396 | } | ||
397 | } | ||
398 | } | ||
399 | |||
400 | spin_unlock(&dev->spinlock); | ||
401 | } | ||
402 | |||
403 | static void read_in_urb(struct snd_usb_caiaqdev *dev, | ||
404 | const struct urb *urb, | ||
405 | const struct usb_iso_packet_descriptor *iso) | ||
406 | { | ||
407 | if (!dev->streaming) | ||
408 | return; | ||
409 | |||
410 | switch (dev->spec.data_alignment) { | ||
411 | case 0: | ||
412 | read_in_urb_mode0(dev, urb, iso); | ||
413 | break; | ||
414 | case 2: | ||
415 | read_in_urb_mode2(dev, urb, iso); | ||
416 | break; | ||
417 | } | ||
418 | |||
419 | if (dev->input_panic || dev->output_panic) { | ||
420 | debug("streaming error detected %s %s\n", | ||
421 | dev->input_panic ? "(input)" : "", | ||
422 | dev->output_panic ? "(output)" : ""); | ||
423 | } | ||
424 | |||
425 | check_for_elapsed_periods(dev, dev->sub_capture); | ||
426 | } | ||
427 | |||
428 | static void fill_out_urb(struct snd_usb_caiaqdev *dev, | ||
429 | struct urb *urb, | ||
430 | const struct usb_iso_packet_descriptor *iso) | ||
431 | { | ||
432 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; | ||
433 | struct snd_pcm_substream *sub; | ||
434 | int stream, i; | ||
435 | |||
436 | spin_lock(&dev->spinlock); | ||
437 | |||
438 | for (i = 0; i < iso->length;) { | ||
439 | for (stream = 0; stream < dev->n_streams; stream++, i++) { | ||
440 | sub = dev->sub_playback[stream]; | ||
441 | if (sub) { | ||
442 | struct snd_pcm_runtime *rt = sub->runtime; | ||
443 | char *audio_buf = rt->dma_area; | ||
444 | int sz = frames_to_bytes(rt, rt->buffer_size); | ||
445 | usb_buf[i] = | ||
446 | audio_buf[dev->audio_out_buf_pos[stream]]; | ||
447 | dev->period_out_count[stream]++; | ||
448 | dev->audio_out_buf_pos[stream]++; | ||
449 | if (dev->audio_out_buf_pos[stream] == sz) | ||
450 | dev->audio_out_buf_pos[stream] = 0; | ||
451 | } else | ||
452 | usb_buf[i] = 0; | ||
453 | } | ||
454 | |||
455 | /* fill in the check bytes */ | ||
456 | if (dev->spec.data_alignment == 2 && | ||
457 | i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == | ||
458 | (dev->n_streams * CHANNELS_PER_STREAM)) | ||
459 | for (stream = 0; stream < dev->n_streams; stream++, i++) | ||
460 | usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i); | ||
461 | } | ||
462 | |||
463 | spin_unlock(&dev->spinlock); | ||
464 | check_for_elapsed_periods(dev, dev->sub_playback); | ||
465 | } | ||
466 | |||
467 | static void read_completed(struct urb *urb) | ||
468 | { | ||
469 | struct snd_usb_caiaq_cb_info *info = urb->context; | ||
470 | struct snd_usb_caiaqdev *dev; | ||
471 | struct urb *out; | ||
472 | int frame, len, send_it = 0, outframe = 0; | ||
473 | |||
474 | if (urb->status || !info) | ||
475 | return; | ||
476 | |||
477 | dev = info->dev; | ||
478 | if (!dev->streaming) | ||
479 | return; | ||
480 | |||
481 | out = dev->data_urbs_out[info->index]; | ||
482 | |||
483 | /* read the recently received packet and send back one which has | ||
484 | * the same layout */ | ||
485 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { | ||
486 | if (urb->iso_frame_desc[frame].status) | ||
487 | continue; | ||
488 | |||
489 | len = urb->iso_frame_desc[outframe].actual_length; | ||
490 | out->iso_frame_desc[outframe].length = len; | ||
491 | out->iso_frame_desc[outframe].actual_length = 0; | ||
492 | out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame; | ||
493 | |||
494 | if (len > 0) { | ||
495 | fill_out_urb(dev, out, &out->iso_frame_desc[outframe]); | ||
496 | read_in_urb(dev, urb, &urb->iso_frame_desc[frame]); | ||
497 | send_it = 1; | ||
498 | } | ||
499 | |||
500 | outframe++; | ||
501 | } | ||
502 | |||
503 | if (send_it) { | ||
504 | out->number_of_packets = FRAMES_PER_URB; | ||
505 | out->transfer_flags = URB_ISO_ASAP; | ||
506 | usb_submit_urb(out, GFP_ATOMIC); | ||
507 | } | ||
508 | |||
509 | /* re-submit inbound urb */ | ||
510 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { | ||
511 | urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; | ||
512 | urb->iso_frame_desc[frame].length = BYTES_PER_FRAME; | ||
513 | urb->iso_frame_desc[frame].actual_length = 0; | ||
514 | } | ||
515 | |||
516 | urb->number_of_packets = FRAMES_PER_URB; | ||
517 | urb->transfer_flags = URB_ISO_ASAP; | ||
518 | usb_submit_urb(urb, GFP_ATOMIC); | ||
519 | } | ||
520 | |||
521 | static void write_completed(struct urb *urb) | ||
522 | { | ||
523 | struct snd_usb_caiaq_cb_info *info = urb->context; | ||
524 | struct snd_usb_caiaqdev *dev = info->dev; | ||
525 | |||
526 | if (!dev->output_running) { | ||
527 | dev->output_running = 1; | ||
528 | wake_up(&dev->prepare_wait_queue); | ||
529 | } | ||
530 | } | ||
531 | |||
532 | static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) | ||
533 | { | ||
534 | int i, frame; | ||
535 | struct urb **urbs; | ||
536 | struct usb_device *usb_dev = dev->chip.dev; | ||
537 | unsigned int pipe; | ||
538 | |||
539 | pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
540 | usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) : | ||
541 | usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE); | ||
542 | |||
543 | urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL); | ||
544 | if (!urbs) { | ||
545 | log("unable to kmalloc() urbs, OOM!?\n"); | ||
546 | *ret = -ENOMEM; | ||
547 | return NULL; | ||
548 | } | ||
549 | |||
550 | for (i = 0; i < N_URBS; i++) { | ||
551 | urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL); | ||
552 | if (!urbs[i]) { | ||
553 | log("unable to usb_alloc_urb(), OOM!?\n"); | ||
554 | *ret = -ENOMEM; | ||
555 | return urbs; | ||
556 | } | ||
557 | |||
558 | urbs[i]->transfer_buffer = | ||
559 | kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL); | ||
560 | if (!urbs[i]->transfer_buffer) { | ||
561 | log("unable to kmalloc() transfer buffer, OOM!?\n"); | ||
562 | *ret = -ENOMEM; | ||
563 | return urbs; | ||
564 | } | ||
565 | |||
566 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { | ||
567 | struct usb_iso_packet_descriptor *iso = | ||
568 | &urbs[i]->iso_frame_desc[frame]; | ||
569 | |||
570 | iso->offset = BYTES_PER_FRAME * frame; | ||
571 | iso->length = BYTES_PER_FRAME; | ||
572 | } | ||
573 | |||
574 | urbs[i]->dev = usb_dev; | ||
575 | urbs[i]->pipe = pipe; | ||
576 | urbs[i]->transfer_buffer_length = FRAMES_PER_URB | ||
577 | * BYTES_PER_FRAME; | ||
578 | urbs[i]->context = &dev->data_cb_info[i]; | ||
579 | urbs[i]->interval = 1; | ||
580 | urbs[i]->transfer_flags = URB_ISO_ASAP; | ||
581 | urbs[i]->number_of_packets = FRAMES_PER_URB; | ||
582 | urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ? | ||
583 | read_completed : write_completed; | ||
584 | } | ||
585 | |||
586 | *ret = 0; | ||
587 | return urbs; | ||
588 | } | ||
589 | |||
590 | static void free_urbs(struct urb **urbs) | ||
591 | { | ||
592 | int i; | ||
593 | |||
594 | if (!urbs) | ||
595 | return; | ||
596 | |||
597 | for (i = 0; i < N_URBS; i++) { | ||
598 | if (!urbs[i]) | ||
599 | continue; | ||
600 | |||
601 | usb_kill_urb(urbs[i]); | ||
602 | kfree(urbs[i]->transfer_buffer); | ||
603 | usb_free_urb(urbs[i]); | ||
604 | } | ||
605 | |||
606 | kfree(urbs); | ||
607 | } | ||
608 | |||
609 | int __devinit snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) | ||
610 | { | ||
611 | int i, ret; | ||
612 | |||
613 | dev->n_audio_in = max(dev->spec.num_analog_audio_in, | ||
614 | dev->spec.num_digital_audio_in) / | ||
615 | CHANNELS_PER_STREAM; | ||
616 | dev->n_audio_out = max(dev->spec.num_analog_audio_out, | ||
617 | dev->spec.num_digital_audio_out) / | ||
618 | CHANNELS_PER_STREAM; | ||
619 | dev->n_streams = max(dev->n_audio_in, dev->n_audio_out); | ||
620 | |||
621 | debug("dev->n_audio_in = %d\n", dev->n_audio_in); | ||
622 | debug("dev->n_audio_out = %d\n", dev->n_audio_out); | ||
623 | debug("dev->n_streams = %d\n", dev->n_streams); | ||
624 | |||
625 | if (dev->n_streams > MAX_STREAMS) { | ||
626 | log("unable to initialize device, too many streams.\n"); | ||
627 | return -EINVAL; | ||
628 | } | ||
629 | |||
630 | ret = snd_pcm_new(dev->chip.card, dev->product_name, 0, | ||
631 | dev->n_audio_out, dev->n_audio_in, &dev->pcm); | ||
632 | |||
633 | if (ret < 0) { | ||
634 | log("snd_pcm_new() returned %d\n", ret); | ||
635 | return ret; | ||
636 | } | ||
637 | |||
638 | dev->pcm->private_data = dev; | ||
639 | strcpy(dev->pcm->name, dev->product_name); | ||
640 | |||
641 | memset(dev->sub_playback, 0, sizeof(dev->sub_playback)); | ||
642 | memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); | ||
643 | |||
644 | memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware, | ||
645 | sizeof(snd_usb_caiaq_pcm_hardware)); | ||
646 | |||
647 | /* setup samplerates */ | ||
648 | dev->samplerates = dev->pcm_info.rates; | ||
649 | switch (dev->chip.usb_id) { | ||
650 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): | ||
651 | dev->samplerates |= SNDRV_PCM_RATE_88200; | ||
652 | dev->samplerates |= SNDRV_PCM_RATE_192000; | ||
653 | break; | ||
654 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): | ||
655 | dev->samplerates |= SNDRV_PCM_RATE_88200; | ||
656 | break; | ||
657 | } | ||
658 | |||
659 | snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, | ||
660 | &snd_usb_caiaq_ops); | ||
661 | snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, | ||
662 | &snd_usb_caiaq_ops); | ||
663 | |||
664 | snd_pcm_lib_preallocate_pages_for_all(dev->pcm, | ||
665 | SNDRV_DMA_TYPE_CONTINUOUS, | ||
666 | snd_dma_continuous_data(GFP_KERNEL), | ||
667 | MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); | ||
668 | |||
669 | dev->data_cb_info = | ||
670 | kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS, | ||
671 | GFP_KERNEL); | ||
672 | |||
673 | if (!dev->data_cb_info) | ||
674 | return -ENOMEM; | ||
675 | |||
676 | for (i = 0; i < N_URBS; i++) { | ||
677 | dev->data_cb_info[i].dev = dev; | ||
678 | dev->data_cb_info[i].index = i; | ||
679 | } | ||
680 | |||
681 | dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret); | ||
682 | if (ret < 0) { | ||
683 | kfree(dev->data_cb_info); | ||
684 | free_urbs(dev->data_urbs_in); | ||
685 | return ret; | ||
686 | } | ||
687 | |||
688 | dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret); | ||
689 | if (ret < 0) { | ||
690 | kfree(dev->data_cb_info); | ||
691 | free_urbs(dev->data_urbs_in); | ||
692 | free_urbs(dev->data_urbs_out); | ||
693 | return ret; | ||
694 | } | ||
695 | |||
696 | return 0; | ||
697 | } | ||
698 | |||
699 | void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev) | ||
700 | { | ||
701 | debug("snd_usb_caiaq_audio_free (%p)\n", dev); | ||
702 | stream_stop(dev); | ||
703 | free_urbs(dev->data_urbs_in); | ||
704 | free_urbs(dev->data_urbs_out); | ||
705 | kfree(dev->data_cb_info); | ||
706 | } | ||
707 | |||
diff --git a/sound/usb/caiaq/caiaq-audio.h b/sound/usb/caiaq/caiaq-audio.h new file mode 100644 index 000000000000..8ab1f8d9529e --- /dev/null +++ b/sound/usb/caiaq/caiaq-audio.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef CAIAQ_AUDIO_H | ||
2 | #define CAIAQ_AUDIO_H | ||
3 | |||
4 | int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev); | ||
5 | void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev); | ||
6 | |||
7 | #endif /* CAIAQ_AUDIO_H */ | ||
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c new file mode 100644 index 000000000000..4709347326f9 --- /dev/null +++ b/sound/usb/caiaq/caiaq-device.c | |||
@@ -0,0 +1,436 @@ | |||
1 | /* | ||
2 | * caiaq.c: ALSA driver for caiaq/NativeInstruments devices | ||
3 | * | ||
4 | * Copyright (c) 2007 Daniel Mack <daniel@caiaq.de> | ||
5 | * Karsten Wiese <fzu@wemgehoertderstaat.de> | ||
6 | * | ||
7 | * 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 | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
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 | |||
22 | #include <linux/init.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/moduleparam.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/usb.h> | ||
27 | #include <linux/input.h> | ||
28 | #include <linux/spinlock.h> | ||
29 | #include <sound/driver.h> | ||
30 | #include <sound/core.h> | ||
31 | #include <sound/initval.h> | ||
32 | #include <sound/pcm.h> | ||
33 | #include <sound/rawmidi.h> | ||
34 | |||
35 | #include "caiaq-device.h" | ||
36 | #include "caiaq-audio.h" | ||
37 | #include "caiaq-midi.h" | ||
38 | |||
39 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | ||
40 | #include "caiaq-input.h" | ||
41 | #endif | ||
42 | |||
43 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | ||
44 | MODULE_DESCRIPTION("caiaq USB audio, version 1.1.0"); | ||
45 | MODULE_LICENSE("GPL"); | ||
46 | MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," | ||
47 | "{Native Instruments, Kore Controller}," | ||
48 | "{Native Instruments, Audio Kontrol 1}" | ||
49 | "{Native Instruments, Audio 8 DJ}}"); | ||
50 | |||
51 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | ||
52 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ | ||
53 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ | ||
54 | static int snd_card_used[SNDRV_CARDS]; | ||
55 | |||
56 | module_param_array(index, int, NULL, 0444); | ||
57 | MODULE_PARM_DESC(index, "Index value for the caiaq sound device"); | ||
58 | module_param_array(id, charp, NULL, 0444); | ||
59 | MODULE_PARM_DESC(id, "ID string for the caiaq soundcard."); | ||
60 | module_param_array(enable, bool, NULL, 0444); | ||
61 | MODULE_PARM_DESC(enable, "Enable the caiaq soundcard."); | ||
62 | |||
63 | enum { | ||
64 | SAMPLERATE_44100 = 0, | ||
65 | SAMPLERATE_48000 = 1, | ||
66 | SAMPLERATE_96000 = 2, | ||
67 | SAMPLERATE_192000 = 3, | ||
68 | SAMPLERATE_88200 = 4, | ||
69 | SAMPLERATE_INVALID = 0xff | ||
70 | }; | ||
71 | |||
72 | enum { | ||
73 | DEPTH_NONE = 0, | ||
74 | DEPTH_16 = 1, | ||
75 | DEPTH_24 = 2, | ||
76 | DEPTH_32 = 3 | ||
77 | }; | ||
78 | |||
79 | static struct usb_device_id snd_usb_id_table[] = { | ||
80 | { | ||
81 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
82 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | ||
83 | .idProduct = USB_PID_RIGKONTROL2 | ||
84 | }, | ||
85 | { | ||
86 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
87 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | ||
88 | .idProduct = USB_PID_KORECONTROLLER | ||
89 | }, | ||
90 | { | ||
91 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
92 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | ||
93 | .idProduct = USB_PID_AK1 | ||
94 | }, | ||
95 | { | ||
96 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
97 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | ||
98 | .idProduct = USB_PID_AUDIO8DJ | ||
99 | }, | ||
100 | { /* terminator */ } | ||
101 | }; | ||
102 | |||
103 | static void usb_ep1_command_reply_dispatch (struct urb* urb) | ||
104 | { | ||
105 | int ret; | ||
106 | struct snd_usb_caiaqdev *dev = urb->context; | ||
107 | unsigned char *buf = urb->transfer_buffer; | ||
108 | |||
109 | if (urb->status || !dev) { | ||
110 | log("received EP1 urb->status = %i\n", urb->status); | ||
111 | return; | ||
112 | } | ||
113 | |||
114 | switch(buf[0]) { | ||
115 | case EP1_CMD_GET_DEVICE_INFO: | ||
116 | memcpy(&dev->spec, buf+1, sizeof(struct caiaq_device_spec)); | ||
117 | dev->spec.fw_version = le16_to_cpu(dev->spec.fw_version); | ||
118 | debug("device spec (firmware %d): audio: %d in, %d out, " | ||
119 | "MIDI: %d in, %d out, data alignment %d\n", | ||
120 | dev->spec.fw_version, | ||
121 | dev->spec.num_analog_audio_in, | ||
122 | dev->spec.num_analog_audio_out, | ||
123 | dev->spec.num_midi_in, | ||
124 | dev->spec.num_midi_out, | ||
125 | dev->spec.data_alignment); | ||
126 | |||
127 | dev->spec_received++; | ||
128 | wake_up(&dev->ep1_wait_queue); | ||
129 | break; | ||
130 | case EP1_CMD_AUDIO_PARAMS: | ||
131 | dev->audio_parm_answer = buf[1]; | ||
132 | wake_up(&dev->ep1_wait_queue); | ||
133 | break; | ||
134 | case EP1_CMD_MIDI_READ: | ||
135 | snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]); | ||
136 | break; | ||
137 | |||
138 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | ||
139 | case EP1_CMD_READ_ERP: | ||
140 | case EP1_CMD_READ_ANALOG: | ||
141 | case EP1_CMD_READ_IO: | ||
142 | snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length); | ||
143 | break; | ||
144 | #endif | ||
145 | } | ||
146 | |||
147 | dev->ep1_in_urb.actual_length = 0; | ||
148 | ret = usb_submit_urb(&dev->ep1_in_urb, GFP_ATOMIC); | ||
149 | if (ret < 0) | ||
150 | log("unable to submit urb. OOM!?\n"); | ||
151 | } | ||
152 | |||
153 | static int send_command (struct snd_usb_caiaqdev *dev, | ||
154 | unsigned char command, | ||
155 | const unsigned char *buffer, | ||
156 | int len) | ||
157 | { | ||
158 | int actual_len; | ||
159 | struct usb_device *usb_dev = dev->chip.dev; | ||
160 | |||
161 | if (!usb_dev) | ||
162 | return -EIO; | ||
163 | |||
164 | if (len > EP1_BUFSIZE - 1) | ||
165 | len = EP1_BUFSIZE - 1; | ||
166 | |||
167 | if (buffer && len > 0) | ||
168 | memcpy(dev->ep1_out_buf+1, buffer, len); | ||
169 | |||
170 | dev->ep1_out_buf[0] = command; | ||
171 | return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1), | ||
172 | dev->ep1_out_buf, len+1, &actual_len, 200); | ||
173 | } | ||
174 | |||
175 | int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, | ||
176 | int rate, int depth, int bpp) | ||
177 | { | ||
178 | int ret; | ||
179 | char tmp[5]; | ||
180 | |||
181 | switch (rate) { | ||
182 | case 44100: tmp[0] = SAMPLERATE_44100; break; | ||
183 | case 48000: tmp[0] = SAMPLERATE_48000; break; | ||
184 | case 88200: tmp[0] = SAMPLERATE_88200; break; | ||
185 | case 96000: tmp[0] = SAMPLERATE_96000; break; | ||
186 | case 192000: tmp[0] = SAMPLERATE_192000; break; | ||
187 | default: return -EINVAL; | ||
188 | } | ||
189 | |||
190 | switch (depth) { | ||
191 | case 16: tmp[1] = DEPTH_16; break; | ||
192 | case 24: tmp[1] = DEPTH_24; break; | ||
193 | default: return -EINVAL; | ||
194 | } | ||
195 | |||
196 | tmp[2] = bpp & 0xff; | ||
197 | tmp[3] = bpp >> 8; | ||
198 | tmp[4] = 1; /* packets per microframe */ | ||
199 | |||
200 | debug("setting audio params: %d Hz, %d bits, %d bpp\n", | ||
201 | rate, depth, bpp); | ||
202 | |||
203 | dev->audio_parm_answer = -1; | ||
204 | ret = send_command(dev, EP1_CMD_AUDIO_PARAMS, tmp, sizeof(tmp)); | ||
205 | |||
206 | if (ret) | ||
207 | return ret; | ||
208 | |||
209 | if (!wait_event_timeout(dev->ep1_wait_queue, | ||
210 | dev->audio_parm_answer >= 0, HZ)) | ||
211 | return -EPIPE; | ||
212 | |||
213 | if (dev->audio_parm_answer != 1) | ||
214 | debug("unable to set the device's audio params\n"); | ||
215 | |||
216 | return dev->audio_parm_answer == 1 ? 0 : -EINVAL; | ||
217 | } | ||
218 | |||
219 | int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, | ||
220 | int digital, int analog, int erp) | ||
221 | { | ||
222 | char tmp[3] = { digital, analog, erp }; | ||
223 | return send_command(dev, EP1_CMD_AUTO_MSG, tmp, sizeof(tmp)); | ||
224 | } | ||
225 | |||
226 | static void setup_card(struct snd_usb_caiaqdev *dev) | ||
227 | { | ||
228 | int ret; | ||
229 | char val[3]; | ||
230 | |||
231 | /* device-specific startup specials */ | ||
232 | switch (dev->chip.usb_id) { | ||
233 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): | ||
234 | /* RigKontrol2 - display centered dash ('-') */ | ||
235 | val[0] = 0x00; | ||
236 | val[1] = 0x00; | ||
237 | val[2] = 0x01; | ||
238 | send_command(dev, EP1_CMD_WRITE_IO, val, 3); | ||
239 | break; | ||
240 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): | ||
241 | /* Audio Kontrol 1 - make USB-LED stop blinking */ | ||
242 | val[0] = 0x00; | ||
243 | send_command(dev, EP1_CMD_WRITE_IO, val, 1); | ||
244 | break; | ||
245 | } | ||
246 | |||
247 | ret = snd_usb_caiaq_audio_init(dev); | ||
248 | if (ret < 0) | ||
249 | log("Unable to set up audio system (ret=%d)\n", ret); | ||
250 | |||
251 | ret = snd_usb_caiaq_midi_init(dev); | ||
252 | if (ret < 0) | ||
253 | log("Unable to set up MIDI system (ret=%d)\n", ret); | ||
254 | |||
255 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | ||
256 | ret = snd_usb_caiaq_input_init(dev); | ||
257 | if (ret < 0) | ||
258 | log("Unable to set up input system (ret=%d)\n", ret); | ||
259 | #endif | ||
260 | |||
261 | /* finally, register the card and all its sub-instances */ | ||
262 | ret = snd_card_register(dev->chip.card); | ||
263 | if (ret < 0) { | ||
264 | log("snd_card_register() returned %d\n", ret); | ||
265 | snd_card_free(dev->chip.card); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | static struct snd_card* create_card(struct usb_device* usb_dev) | ||
270 | { | ||
271 | int devnum; | ||
272 | struct snd_card *card; | ||
273 | struct snd_usb_caiaqdev *dev; | ||
274 | |||
275 | for (devnum = 0; devnum < SNDRV_CARDS; devnum++) | ||
276 | if (enable[devnum] && !snd_card_used[devnum]) | ||
277 | break; | ||
278 | |||
279 | if (devnum >= SNDRV_CARDS) | ||
280 | return NULL; | ||
281 | |||
282 | card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, | ||
283 | sizeof(struct snd_usb_caiaqdev)); | ||
284 | if (!card) | ||
285 | return NULL; | ||
286 | |||
287 | dev = caiaqdev(card); | ||
288 | dev->chip.dev = usb_dev; | ||
289 | dev->chip.card = card; | ||
290 | dev->chip.usb_id = USB_ID(usb_dev->descriptor.idVendor, | ||
291 | usb_dev->descriptor.idProduct); | ||
292 | spin_lock_init(&dev->spinlock); | ||
293 | snd_card_set_dev(card, &usb_dev->dev); | ||
294 | |||
295 | return card; | ||
296 | } | ||
297 | |||
298 | static int init_card(struct snd_usb_caiaqdev *dev) | ||
299 | { | ||
300 | char *c; | ||
301 | struct usb_device *usb_dev = dev->chip.dev; | ||
302 | struct snd_card *card = dev->chip.card; | ||
303 | int err, len; | ||
304 | |||
305 | if (usb_set_interface(usb_dev, 0, 1) != 0) { | ||
306 | log("can't set alt interface.\n"); | ||
307 | return -EIO; | ||
308 | } | ||
309 | |||
310 | usb_init_urb(&dev->ep1_in_urb); | ||
311 | usb_init_urb(&dev->midi_out_urb); | ||
312 | |||
313 | usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev, | ||
314 | usb_rcvbulkpipe(usb_dev, 0x1), | ||
315 | dev->ep1_in_buf, EP1_BUFSIZE, | ||
316 | usb_ep1_command_reply_dispatch, dev); | ||
317 | |||
318 | usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev, | ||
319 | usb_sndbulkpipe(usb_dev, 0x1), | ||
320 | dev->midi_out_buf, EP1_BUFSIZE, | ||
321 | snd_usb_caiaq_midi_output_done, dev); | ||
322 | |||
323 | init_waitqueue_head(&dev->ep1_wait_queue); | ||
324 | init_waitqueue_head(&dev->prepare_wait_queue); | ||
325 | |||
326 | if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0) | ||
327 | return -EIO; | ||
328 | |||
329 | err = send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); | ||
330 | if (err) | ||
331 | return err; | ||
332 | |||
333 | if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ)) | ||
334 | return -ENODEV; | ||
335 | |||
336 | usb_string(usb_dev, usb_dev->descriptor.iManufacturer, | ||
337 | dev->vendor_name, CAIAQ_USB_STR_LEN); | ||
338 | |||
339 | usb_string(usb_dev, usb_dev->descriptor.iProduct, | ||
340 | dev->product_name, CAIAQ_USB_STR_LEN); | ||
341 | |||
342 | usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, | ||
343 | dev->serial, CAIAQ_USB_STR_LEN); | ||
344 | |||
345 | /* terminate serial string at first white space occurence */ | ||
346 | c = strchr(dev->serial, ' '); | ||
347 | if (c) | ||
348 | *c = '\0'; | ||
349 | |||
350 | strcpy(card->driver, MODNAME); | ||
351 | strcpy(card->shortname, dev->product_name); | ||
352 | |||
353 | len = snprintf(card->longname, sizeof(card->longname), | ||
354 | "%s %s (serial %s, ", | ||
355 | dev->vendor_name, dev->product_name, dev->serial); | ||
356 | |||
357 | if (len < sizeof(card->longname) - 2) | ||
358 | len += usb_make_path(usb_dev, card->longname + len, | ||
359 | sizeof(card->longname) - len); | ||
360 | |||
361 | card->longname[len++] = ')'; | ||
362 | card->longname[len] = '\0'; | ||
363 | setup_card(dev); | ||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static int snd_probe(struct usb_interface *intf, | ||
368 | const struct usb_device_id *id) | ||
369 | { | ||
370 | int ret; | ||
371 | struct snd_card *card; | ||
372 | struct usb_device *device = interface_to_usbdev(intf); | ||
373 | |||
374 | card = create_card(device); | ||
375 | |||
376 | if (!card) | ||
377 | return -ENOMEM; | ||
378 | |||
379 | dev_set_drvdata(&intf->dev, card); | ||
380 | ret = init_card(caiaqdev(card)); | ||
381 | if (ret < 0) { | ||
382 | log("unable to init card! (ret=%d)\n", ret); | ||
383 | snd_card_free(card); | ||
384 | return ret; | ||
385 | } | ||
386 | |||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | static void snd_disconnect(struct usb_interface *intf) | ||
391 | { | ||
392 | struct snd_usb_caiaqdev *dev; | ||
393 | struct snd_card *card = dev_get_drvdata(&intf->dev); | ||
394 | |||
395 | debug("snd_disconnect(%p)\n", intf); | ||
396 | |||
397 | if (!card) | ||
398 | return; | ||
399 | |||
400 | dev = caiaqdev(card); | ||
401 | snd_card_disconnect(card); | ||
402 | |||
403 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | ||
404 | snd_usb_caiaq_input_free(dev); | ||
405 | #endif | ||
406 | snd_usb_caiaq_audio_free(dev); | ||
407 | |||
408 | usb_kill_urb(&dev->ep1_in_urb); | ||
409 | usb_kill_urb(&dev->midi_out_urb); | ||
410 | |||
411 | snd_card_free(card); | ||
412 | usb_reset_device(interface_to_usbdev(intf)); | ||
413 | } | ||
414 | |||
415 | |||
416 | MODULE_DEVICE_TABLE(usb, snd_usb_id_table); | ||
417 | static struct usb_driver snd_usb_driver = { | ||
418 | .name = MODNAME, | ||
419 | .probe = snd_probe, | ||
420 | .disconnect = snd_disconnect, | ||
421 | .id_table = snd_usb_id_table, | ||
422 | }; | ||
423 | |||
424 | static int __init snd_module_init(void) | ||
425 | { | ||
426 | return usb_register(&snd_usb_driver); | ||
427 | } | ||
428 | |||
429 | static void __exit snd_module_exit(void) | ||
430 | { | ||
431 | usb_deregister(&snd_usb_driver); | ||
432 | } | ||
433 | |||
434 | module_init(snd_module_init) | ||
435 | module_exit(snd_module_exit) | ||
436 | |||
diff --git a/sound/usb/caiaq/caiaq-device.h b/sound/usb/caiaq/caiaq-device.h new file mode 100644 index 000000000000..088d5ec241f3 --- /dev/null +++ b/sound/usb/caiaq/caiaq-device.h | |||
@@ -0,0 +1,116 @@ | |||
1 | #ifndef CAIAQ_DEVICE_H | ||
2 | #define CAIAQ_DEVICE_H | ||
3 | |||
4 | #include "../usbaudio.h" | ||
5 | |||
6 | #define USB_VID_NATIVEINSTRUMENTS 0x17cc | ||
7 | |||
8 | #define USB_PID_RIGKONTROL2 0x1969 | ||
9 | #define USB_PID_KORECONTROLLER 0x4711 | ||
10 | #define USB_PID_AK1 0x0815 | ||
11 | #define USB_PID_AUDIO8DJ 0x1978 | ||
12 | |||
13 | #define EP1_BUFSIZE 64 | ||
14 | #define CAIAQ_USB_STR_LEN 0xff | ||
15 | #define MAX_STREAMS 32 | ||
16 | |||
17 | //#define SND_USB_CAIAQ_DEBUG | ||
18 | |||
19 | #define MODNAME "snd-usb-caiaq" | ||
20 | #define log(x...) snd_printk(KERN_WARNING MODNAME" log: " x) | ||
21 | |||
22 | #ifdef SND_USB_CAIAQ_DEBUG | ||
23 | #define debug(x...) snd_printk(KERN_WARNING MODNAME " debug: " x) | ||
24 | #else | ||
25 | #define debug(x...) do { } while(0) | ||
26 | #endif | ||
27 | |||
28 | #define EP1_CMD_GET_DEVICE_INFO 0x1 | ||
29 | #define EP1_CMD_READ_ERP 0x2 | ||
30 | #define EP1_CMD_READ_ANALOG 0x3 | ||
31 | #define EP1_CMD_READ_IO 0x4 | ||
32 | #define EP1_CMD_WRITE_IO 0x5 | ||
33 | #define EP1_CMD_MIDI_READ 0x6 | ||
34 | #define EP1_CMD_MIDI_WRITE 0x7 | ||
35 | #define EP1_CMD_AUDIO_PARAMS 0x9 | ||
36 | #define EP1_CMD_AUTO_MSG 0xb | ||
37 | |||
38 | struct caiaq_device_spec { | ||
39 | unsigned short fw_version; | ||
40 | unsigned char hw_subtype; | ||
41 | unsigned char num_erp; | ||
42 | unsigned char num_analog_in; | ||
43 | unsigned char num_digital_in; | ||
44 | unsigned char num_digital_out; | ||
45 | unsigned char num_analog_audio_out; | ||
46 | unsigned char num_analog_audio_in; | ||
47 | unsigned char num_digital_audio_out; | ||
48 | unsigned char num_digital_audio_in; | ||
49 | unsigned char num_midi_out; | ||
50 | unsigned char num_midi_in; | ||
51 | unsigned char data_alignment; | ||
52 | } __attribute__ ((packed)); | ||
53 | |||
54 | struct snd_usb_caiaq_cb_info; | ||
55 | |||
56 | struct snd_usb_caiaqdev { | ||
57 | struct snd_usb_audio chip; | ||
58 | |||
59 | struct urb ep1_in_urb; | ||
60 | struct urb midi_out_urb; | ||
61 | struct urb **data_urbs_in; | ||
62 | struct urb **data_urbs_out; | ||
63 | struct snd_usb_caiaq_cb_info *data_cb_info; | ||
64 | |||
65 | unsigned char ep1_in_buf[EP1_BUFSIZE]; | ||
66 | unsigned char ep1_out_buf[EP1_BUFSIZE]; | ||
67 | unsigned char midi_out_buf[EP1_BUFSIZE]; | ||
68 | |||
69 | struct caiaq_device_spec spec; | ||
70 | spinlock_t spinlock; | ||
71 | wait_queue_head_t ep1_wait_queue; | ||
72 | wait_queue_head_t prepare_wait_queue; | ||
73 | int spec_received, audio_parm_answer; | ||
74 | |||
75 | char vendor_name[CAIAQ_USB_STR_LEN]; | ||
76 | char product_name[CAIAQ_USB_STR_LEN]; | ||
77 | char serial[CAIAQ_USB_STR_LEN]; | ||
78 | |||
79 | int n_streams, n_audio_in, n_audio_out; | ||
80 | int streaming, first_packet, output_running; | ||
81 | int audio_in_buf_pos[MAX_STREAMS]; | ||
82 | int audio_out_buf_pos[MAX_STREAMS]; | ||
83 | int period_in_count[MAX_STREAMS]; | ||
84 | int period_out_count[MAX_STREAMS]; | ||
85 | int input_panic, output_panic; | ||
86 | char *audio_in_buf, *audio_out_buf; | ||
87 | unsigned int samplerates; | ||
88 | |||
89 | struct snd_pcm_substream *sub_playback[MAX_STREAMS]; | ||
90 | struct snd_pcm_substream *sub_capture[MAX_STREAMS]; | ||
91 | |||
92 | /* Linux input */ | ||
93 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | ||
94 | struct input_dev *input_dev; | ||
95 | #endif | ||
96 | |||
97 | /* ALSA */ | ||
98 | struct snd_pcm *pcm; | ||
99 | struct snd_pcm_hardware pcm_info; | ||
100 | struct snd_rawmidi *rmidi; | ||
101 | struct snd_rawmidi_substream *midi_receive_substream; | ||
102 | struct snd_rawmidi_substream *midi_out_substream; | ||
103 | }; | ||
104 | |||
105 | struct snd_usb_caiaq_cb_info { | ||
106 | struct snd_usb_caiaqdev *dev; | ||
107 | int index; | ||
108 | }; | ||
109 | |||
110 | #define caiaqdev(c) ((struct snd_usb_caiaqdev*)(c)->private_data) | ||
111 | |||
112 | int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, int rate, int depth, int bbp); | ||
113 | int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, int digital, int analog, int erp); | ||
114 | |||
115 | |||
116 | #endif /* CAIAQ_DEVICE_H */ | ||
diff --git a/sound/usb/caiaq/caiaq-input.c b/sound/usb/caiaq/caiaq-input.c new file mode 100644 index 000000000000..3acd12db6952 --- /dev/null +++ b/sound/usb/caiaq/caiaq-input.c | |||
@@ -0,0 +1,246 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2006,2007 Daniel Mack, Tim Ruetz | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program 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 program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | #include <linux/init.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/moduleparam.h> | ||
22 | #include <linux/input.h> | ||
23 | #include <linux/usb.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <sound/driver.h> | ||
26 | #include <sound/core.h> | ||
27 | #include <sound/rawmidi.h> | ||
28 | #include <sound/pcm.h> | ||
29 | #include "caiaq-device.h" | ||
30 | #include "caiaq-input.h" | ||
31 | |||
32 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | ||
33 | |||
34 | static unsigned char keycode_ak1[] = { KEY_C, KEY_B, KEY_A }; | ||
35 | static unsigned char keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4, | ||
36 | KEY_5, KEY_6, KEY_7 }; | ||
37 | |||
38 | #define DEG90 (range/2) | ||
39 | #define DEG180 (range) | ||
40 | #define DEG270 (DEG90 + DEG180) | ||
41 | #define DEG360 (DEG180 * 2) | ||
42 | #define HIGH_PEAK (268) | ||
43 | #define LOW_PEAK (-7) | ||
44 | |||
45 | /* some of these devices have endless rotation potentiometers | ||
46 | * built in which use two tapers, 90 degrees phase shifted. | ||
47 | * this algorithm decodes them to one single value, ranging | ||
48 | * from 0 to 999 */ | ||
49 | static unsigned int decode_erp(unsigned char a, unsigned char b) | ||
50 | { | ||
51 | int weight_a, weight_b; | ||
52 | int pos_a, pos_b; | ||
53 | int ret; | ||
54 | int range = HIGH_PEAK - LOW_PEAK; | ||
55 | int mid_value = (HIGH_PEAK + LOW_PEAK) / 2; | ||
56 | |||
57 | weight_b = abs(mid_value-a) - (range/2 - 100)/2; | ||
58 | |||
59 | if (weight_b < 0) | ||
60 | weight_b = 0; | ||
61 | |||
62 | if (weight_b > 100) | ||
63 | weight_b = 100; | ||
64 | |||
65 | weight_a = 100 - weight_b; | ||
66 | |||
67 | if (a < mid_value) { | ||
68 | /* 0..90 and 270..360 degrees */ | ||
69 | pos_b = b - LOW_PEAK + DEG270; | ||
70 | if (pos_b >= DEG360) | ||
71 | pos_b -= DEG360; | ||
72 | } else | ||
73 | /* 90..270 degrees */ | ||
74 | pos_b = HIGH_PEAK - b + DEG90; | ||
75 | |||
76 | |||
77 | if (b > mid_value) | ||
78 | /* 0..180 degrees */ | ||
79 | pos_a = a - LOW_PEAK; | ||
80 | else | ||
81 | /* 180..360 degrees */ | ||
82 | pos_a = HIGH_PEAK - a + DEG180; | ||
83 | |||
84 | /* interpolate both slider values, depending on weight factors */ | ||
85 | /* 0..99 x DEG360 */ | ||
86 | ret = pos_a * weight_a + pos_b * weight_b; | ||
87 | |||
88 | /* normalize to 0..999 */ | ||
89 | ret *= 10; | ||
90 | ret /= DEG360; | ||
91 | |||
92 | if (ret < 0) | ||
93 | ret += 1000; | ||
94 | |||
95 | if (ret >= 1000) | ||
96 | ret -= 1000; | ||
97 | |||
98 | return ret; | ||
99 | } | ||
100 | |||
101 | #undef DEG90 | ||
102 | #undef DEG180 | ||
103 | #undef DEG270 | ||
104 | #undef DEG360 | ||
105 | #undef HIGH_PEAK | ||
106 | #undef LOW_PEAK | ||
107 | |||
108 | |||
109 | static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, | ||
110 | const char *buf, unsigned int len) | ||
111 | { | ||
112 | switch(dev->input_dev->id.product) { | ||
113 | case USB_PID_RIGKONTROL2: | ||
114 | input_report_abs(dev->input_dev, ABS_X, (buf[4] << 8) |buf[5]); | ||
115 | input_report_abs(dev->input_dev, ABS_Y, (buf[0] << 8) |buf[1]); | ||
116 | input_report_abs(dev->input_dev, ABS_Z, (buf[2] << 8) |buf[3]); | ||
117 | input_sync(dev->input_dev); | ||
118 | break; | ||
119 | } | ||
120 | } | ||
121 | |||
122 | static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, | ||
123 | const char *buf, unsigned int len) | ||
124 | { | ||
125 | int i; | ||
126 | |||
127 | switch(dev->input_dev->id.product) { | ||
128 | case USB_PID_AK1: | ||
129 | i = decode_erp(buf[0], buf[1]); | ||
130 | input_report_abs(dev->input_dev, ABS_X, i); | ||
131 | input_sync(dev->input_dev); | ||
132 | break; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, | ||
137 | char *buf, unsigned int len) | ||
138 | { | ||
139 | int i; | ||
140 | unsigned char *keycode = dev->input_dev->keycode; | ||
141 | |||
142 | if (!keycode) | ||
143 | return; | ||
144 | |||
145 | if (dev->input_dev->id.product == USB_PID_RIGKONTROL2) | ||
146 | for (i=0; i<len; i++) | ||
147 | buf[i] = ~buf[i]; | ||
148 | |||
149 | for (i=0; (i<dev->input_dev->keycodemax) && (i < len); i++) | ||
150 | input_report_key(dev->input_dev, keycode[i], | ||
151 | buf[i/8] & (1 << (i%8))); | ||
152 | |||
153 | input_sync(dev->input_dev); | ||
154 | } | ||
155 | |||
156 | void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, | ||
157 | char *buf, | ||
158 | unsigned int len) | ||
159 | { | ||
160 | if (!dev->input_dev || (len < 1)) | ||
161 | return; | ||
162 | |||
163 | switch (buf[0]) { | ||
164 | case EP1_CMD_READ_ANALOG: | ||
165 | snd_caiaq_input_read_analog(dev, buf+1, len-1); | ||
166 | break; | ||
167 | case EP1_CMD_READ_ERP: | ||
168 | snd_caiaq_input_read_erp(dev, buf+1, len-1); | ||
169 | break; | ||
170 | case EP1_CMD_READ_IO: | ||
171 | snd_caiaq_input_read_io(dev, buf+1, len-1); | ||
172 | break; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | ||
177 | { | ||
178 | struct usb_device *usb_dev = dev->chip.dev; | ||
179 | struct input_dev *input; | ||
180 | int i, ret; | ||
181 | |||
182 | input = input_allocate_device(); | ||
183 | if (!input) | ||
184 | return -ENOMEM; | ||
185 | |||
186 | input->name = dev->product_name; | ||
187 | input->id.bustype = BUS_USB; | ||
188 | input->id.vendor = usb_dev->descriptor.idVendor; | ||
189 | input->id.product = usb_dev->descriptor.idProduct; | ||
190 | input->id.version = usb_dev->descriptor.bcdDevice; | ||
191 | |||
192 | switch (dev->chip.usb_id) { | ||
193 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): | ||
194 | input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
195 | input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z); | ||
196 | input->keycode = keycode_rk2; | ||
197 | input->keycodesize = sizeof(char); | ||
198 | input->keycodemax = ARRAY_SIZE(keycode_rk2); | ||
199 | for (i=0; i<ARRAY_SIZE(keycode_rk2); i++) | ||
200 | set_bit(keycode_rk2[i], input->keybit); | ||
201 | |||
202 | input_set_abs_params(input, ABS_X, 0, 4096, 0, 10); | ||
203 | input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10); | ||
204 | input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); | ||
205 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0); | ||
206 | break; | ||
207 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): | ||
208 | input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
209 | input->absbit[0] = BIT(ABS_X); | ||
210 | input->keycode = keycode_ak1; | ||
211 | input->keycodesize = sizeof(char); | ||
212 | input->keycodemax = ARRAY_SIZE(keycode_ak1); | ||
213 | for (i=0; i<ARRAY_SIZE(keycode_ak1); i++) | ||
214 | set_bit(keycode_ak1[i], input->keybit); | ||
215 | |||
216 | input_set_abs_params(input, ABS_X, 0, 999, 0, 10); | ||
217 | snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5); | ||
218 | break; | ||
219 | default: | ||
220 | /* no input methods supported on this device */ | ||
221 | input_free_device(input); | ||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | ret = input_register_device(input); | ||
226 | if (ret < 0) { | ||
227 | input_free_device(input); | ||
228 | return ret; | ||
229 | } | ||
230 | |||
231 | dev->input_dev = input; | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) | ||
236 | { | ||
237 | if (!dev || !dev->input_dev) | ||
238 | return; | ||
239 | |||
240 | input_unregister_device(dev->input_dev); | ||
241 | input_free_device(dev->input_dev); | ||
242 | dev->input_dev = NULL; | ||
243 | } | ||
244 | |||
245 | #endif /* CONFIG_SND_USB_CAIAQ_INPUT */ | ||
246 | |||
diff --git a/sound/usb/caiaq/caiaq-input.h b/sound/usb/caiaq/caiaq-input.h new file mode 100644 index 000000000000..ced535577864 --- /dev/null +++ b/sound/usb/caiaq/caiaq-input.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef CAIAQ_INPUT_H | ||
2 | #define CAIAQ_INPUT_H | ||
3 | |||
4 | void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, char *buf, unsigned int len); | ||
5 | int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev); | ||
6 | void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev); | ||
7 | |||
8 | #endif | ||
diff --git a/sound/usb/caiaq/caiaq-midi.c b/sound/usb/caiaq/caiaq-midi.c new file mode 100644 index 000000000000..793ca20ce349 --- /dev/null +++ b/sound/usb/caiaq/caiaq-midi.c | |||
@@ -0,0 +1,177 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2006,2007 Daniel Mack | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program 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 program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | #include <linux/init.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/moduleparam.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/usb.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <linux/spinlock.h> | ||
26 | #include <sound/driver.h> | ||
27 | #include <sound/core.h> | ||
28 | #include <sound/rawmidi.h> | ||
29 | #include <sound/pcm.h> | ||
30 | |||
31 | #include "caiaq-device.h" | ||
32 | #include "caiaq-midi.h" | ||
33 | |||
34 | |||
35 | static int snd_usb_caiaq_midi_input_open(struct snd_rawmidi_substream *substream) | ||
36 | { | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static int snd_usb_caiaq_midi_input_close(struct snd_rawmidi_substream *substream) | ||
41 | { | ||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) | ||
46 | { | ||
47 | struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; | ||
48 | |||
49 | if (!dev) | ||
50 | return; | ||
51 | |||
52 | dev->midi_receive_substream = up ? substream : NULL; | ||
53 | } | ||
54 | |||
55 | |||
56 | static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substream) | ||
57 | { | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream) | ||
62 | { | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev, | ||
67 | struct snd_rawmidi_substream *substream) | ||
68 | { | ||
69 | int len, ret; | ||
70 | |||
71 | dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE; | ||
72 | dev->midi_out_buf[1] = 0; /* port */ | ||
73 | len = snd_rawmidi_transmit_peek(substream, dev->midi_out_buf+3, EP1_BUFSIZE-3); | ||
74 | |||
75 | if (len <= 0) | ||
76 | return; | ||
77 | |||
78 | dev->midi_out_buf[2] = len; | ||
79 | dev->midi_out_urb.transfer_buffer_length = len+3; | ||
80 | |||
81 | ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC); | ||
82 | if (ret < 0) | ||
83 | log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed, %d\n", | ||
84 | substream, ret); | ||
85 | } | ||
86 | |||
87 | static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) | ||
88 | { | ||
89 | struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; | ||
90 | |||
91 | if (dev->midi_out_substream != NULL) | ||
92 | return; | ||
93 | |||
94 | if (!up) { | ||
95 | dev->midi_out_substream = NULL; | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | dev->midi_out_substream = substream; | ||
100 | snd_usb_caiaq_midi_send(dev, substream); | ||
101 | } | ||
102 | |||
103 | |||
104 | static struct snd_rawmidi_ops snd_usb_caiaq_midi_output = | ||
105 | { | ||
106 | .open = snd_usb_caiaq_midi_output_open, | ||
107 | .close = snd_usb_caiaq_midi_output_close, | ||
108 | .trigger = snd_usb_caiaq_midi_output_trigger, | ||
109 | }; | ||
110 | |||
111 | static struct snd_rawmidi_ops snd_usb_caiaq_midi_input = | ||
112 | { | ||
113 | .open = snd_usb_caiaq_midi_input_open, | ||
114 | .close = snd_usb_caiaq_midi_input_close, | ||
115 | .trigger = snd_usb_caiaq_midi_input_trigger, | ||
116 | }; | ||
117 | |||
118 | void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, | ||
119 | int port, const char *buf, int len) | ||
120 | { | ||
121 | if (!dev->midi_receive_substream) | ||
122 | return; | ||
123 | |||
124 | snd_rawmidi_receive(dev->midi_receive_substream, buf, len); | ||
125 | } | ||
126 | |||
127 | int __devinit snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device) | ||
128 | { | ||
129 | int ret; | ||
130 | struct snd_rawmidi *rmidi; | ||
131 | |||
132 | ret = snd_rawmidi_new(device->chip.card, device->product_name, 0, | ||
133 | device->spec.num_midi_out, | ||
134 | device->spec.num_midi_in, | ||
135 | &rmidi); | ||
136 | |||
137 | if (ret < 0) | ||
138 | return ret; | ||
139 | |||
140 | strcpy(rmidi->name, device->product_name); | ||
141 | |||
142 | rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX; | ||
143 | rmidi->private_data = device; | ||
144 | |||
145 | if (device->spec.num_midi_out > 0) { | ||
146 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; | ||
147 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, | ||
148 | &snd_usb_caiaq_midi_output); | ||
149 | } | ||
150 | |||
151 | if (device->spec.num_midi_in > 0) { | ||
152 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; | ||
153 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, | ||
154 | &snd_usb_caiaq_midi_input); | ||
155 | } | ||
156 | |||
157 | device->rmidi = rmidi; | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | void snd_usb_caiaq_midi_output_done(struct urb* urb) | ||
163 | { | ||
164 | struct snd_usb_caiaqdev *dev = urb->context; | ||
165 | char *buf = urb->transfer_buffer; | ||
166 | |||
167 | if (urb->status != 0) | ||
168 | return; | ||
169 | |||
170 | if (!dev->midi_out_substream) | ||
171 | return; | ||
172 | |||
173 | snd_rawmidi_transmit_ack(dev->midi_out_substream, buf[2]); | ||
174 | dev->midi_out_substream = NULL; | ||
175 | snd_usb_caiaq_midi_send(dev, dev->midi_out_substream); | ||
176 | } | ||
177 | |||
diff --git a/sound/usb/caiaq/caiaq-midi.h b/sound/usb/caiaq/caiaq-midi.h new file mode 100644 index 000000000000..9d16db027fc3 --- /dev/null +++ b/sound/usb/caiaq/caiaq-midi.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef CAIAQ_MIDI_H | ||
2 | #define CAIAQ_MIDI_H | ||
3 | |||
4 | int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev); | ||
5 | void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len); | ||
6 | void snd_usb_caiaq_midi_output_done(struct urb* urb); | ||
7 | |||
8 | #endif /* CAIAQ_MIDI_H */ | ||
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index b6d886373bb0..8ebc1adb5ed9 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -1878,6 +1878,9 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre | |||
1878 | } | 1878 | } |
1879 | 1879 | ||
1880 | /* set the period time minimum 1ms */ | 1880 | /* set the period time minimum 1ms */ |
1881 | /* FIXME: high-speed mode allows 125us minimum period, but many parts | ||
1882 | * in the current code assume the 1ms period. | ||
1883 | */ | ||
1881 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, | 1884 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, |
1882 | 1000 * MIN_PACKS_URB, | 1885 | 1000 * MIN_PACKS_URB, |
1883 | /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX); | 1886 | /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX); |
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 24f5a26c5f0c..99295f9b7691 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * usbmidi.c - ALSA USB MIDI driver | 2 | * usbmidi.c - ALSA USB MIDI driver |
3 | * | 3 | * |
4 | * Copyright (c) 2002-2005 Clemens Ladisch | 4 | * Copyright (c) 2002-2007 Clemens Ladisch |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * Based on the OSS usb-midi driver by NAGANO Daisuke, | 7 | * Based on the OSS usb-midi driver by NAGANO Daisuke, |
@@ -145,6 +145,7 @@ struct snd_usb_midi_in_endpoint { | |||
145 | struct urb* urb; | 145 | struct urb* urb; |
146 | struct usbmidi_in_port { | 146 | struct usbmidi_in_port { |
147 | struct snd_rawmidi_substream *substream; | 147 | struct snd_rawmidi_substream *substream; |
148 | u8 running_status_length; | ||
148 | } ports[0x10]; | 149 | } ports[0x10]; |
149 | u8 seen_f5; | 150 | u8 seen_f5; |
150 | u8 error_resubmit; | 151 | u8 error_resubmit; |
@@ -366,6 +367,46 @@ static void snd_usbmidi_midiman_input(struct snd_usb_midi_in_endpoint* ep, | |||
366 | } | 367 | } |
367 | 368 | ||
368 | /* | 369 | /* |
370 | * Buggy M-Audio device: running status on input results in a packet that has | ||
371 | * the data bytes but not the status byte and that is marked with CIN 4. | ||
372 | */ | ||
373 | static void snd_usbmidi_maudio_broken_running_status_input( | ||
374 | struct snd_usb_midi_in_endpoint* ep, | ||
375 | uint8_t* buffer, int buffer_length) | ||
376 | { | ||
377 | int i; | ||
378 | |||
379 | for (i = 0; i + 3 < buffer_length; i += 4) | ||
380 | if (buffer[i] != 0) { | ||
381 | int cable = buffer[i] >> 4; | ||
382 | u8 cin = buffer[i] & 0x0f; | ||
383 | struct usbmidi_in_port *port = &ep->ports[cable]; | ||
384 | int length; | ||
385 | |||
386 | length = snd_usbmidi_cin_length[cin]; | ||
387 | if (cin == 0xf && buffer[i + 1] >= 0xf8) | ||
388 | ; /* realtime msg: no running status change */ | ||
389 | else if (cin >= 0x8 && cin <= 0xe) | ||
390 | /* channel msg */ | ||
391 | port->running_status_length = length - 1; | ||
392 | else if (cin == 0x4 && | ||
393 | port->running_status_length != 0 && | ||
394 | buffer[i + 1] < 0x80) | ||
395 | /* CIN 4 that is not a SysEx */ | ||
396 | length = port->running_status_length; | ||
397 | else | ||
398 | /* | ||
399 | * All other msgs cannot begin running status. | ||
400 | * (A channel msg sent as two or three CIN 0xF | ||
401 | * packets could in theory, but this device | ||
402 | * doesn't use this format.) | ||
403 | */ | ||
404 | port->running_status_length = 0; | ||
405 | snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | /* | ||
369 | * Adds one USB MIDI packet to the output buffer. | 410 | * Adds one USB MIDI packet to the output buffer. |
370 | */ | 411 | */ |
371 | static void snd_usbmidi_output_standard_packet(struct urb* urb, uint8_t p0, | 412 | static void snd_usbmidi_output_standard_packet(struct urb* urb, uint8_t p0, |
@@ -525,6 +566,12 @@ static struct usb_protocol_ops snd_usbmidi_midiman_ops = { | |||
525 | .output_packet = snd_usbmidi_output_midiman_packet, | 566 | .output_packet = snd_usbmidi_output_midiman_packet, |
526 | }; | 567 | }; |
527 | 568 | ||
569 | static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = { | ||
570 | .input = snd_usbmidi_maudio_broken_running_status_input, | ||
571 | .output = snd_usbmidi_standard_output, | ||
572 | .output_packet = snd_usbmidi_output_standard_packet, | ||
573 | }; | ||
574 | |||
528 | /* | 575 | /* |
529 | * Novation USB MIDI protocol: number of data bytes is in the first byte | 576 | * Novation USB MIDI protocol: number of data bytes is in the first byte |
530 | * (when receiving) (+1!) or in the second byte (when sending); data begins | 577 | * (when receiving) (+1!) or in the second byte (when sending); data begins |
@@ -918,7 +965,11 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi, | |||
918 | } | 965 | } |
919 | /* we never use interrupt output pipes */ | 966 | /* we never use interrupt output pipes */ |
920 | pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); | 967 | pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); |
921 | ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); | 968 | if (umidi->chip->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */ |
969 | /* FIXME: we need more URBs to get reasonable bandwidth here: */ | ||
970 | ep->max_transfer = 4; | ||
971 | else | ||
972 | ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); | ||
922 | buffer = usb_buffer_alloc(umidi->chip->dev, ep->max_transfer, | 973 | buffer = usb_buffer_alloc(umidi->chip->dev, ep->max_transfer, |
923 | GFP_KERNEL, &ep->urb->transfer_dma); | 974 | GFP_KERNEL, &ep->urb->transfer_dma); |
924 | if (!buffer) { | 975 | if (!buffer) { |
@@ -1606,6 +1657,9 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | |||
1606 | switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) { | 1657 | switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) { |
1607 | case QUIRK_MIDI_STANDARD_INTERFACE: | 1658 | case QUIRK_MIDI_STANDARD_INTERFACE: |
1608 | err = snd_usbmidi_get_ms_info(umidi, endpoints); | 1659 | err = snd_usbmidi_get_ms_info(umidi, endpoints); |
1660 | if (chip->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */ | ||
1661 | umidi->usb_protocol_ops = | ||
1662 | &snd_usbmidi_maudio_broken_running_status_ops; | ||
1609 | break; | 1663 | break; |
1610 | case QUIRK_MIDI_FIXED_ENDPOINT: | 1664 | case QUIRK_MIDI_FIXED_ENDPOINT: |
1611 | memcpy(&endpoints[0], quirk->data, | 1665 | memcpy(&endpoints[0], quirk->data, |
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 858262068f4f..8fcbe93b2589 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h | |||
@@ -40,6 +40,29 @@ | |||
40 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC | 40 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface | ||
44 | * class matches do not take effect without an explicit ID match. | ||
45 | */ | ||
46 | { | ||
47 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | | ||
48 | USB_DEVICE_ID_MATCH_INT_CLASS | | ||
49 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | ||
50 | .idVendor = 0x046d, | ||
51 | .idProduct = 0x08f0, | ||
52 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
53 | .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL | ||
54 | }, | ||
55 | { | ||
56 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | | ||
57 | USB_DEVICE_ID_MATCH_INT_CLASS | | ||
58 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | ||
59 | .idVendor = 0x046d, | ||
60 | .idProduct = 0x08f6, | ||
61 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
62 | .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL | ||
63 | }, | ||
64 | |||
65 | /* | ||
43 | * Yamaha devices | 66 | * Yamaha devices |
44 | */ | 67 | */ |
45 | 68 | ||