]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - sound/isa/opti9xx/opti92x-ad1848.c
Merge git://git.infradead.org/~dedekind/ubi-2.6
[linux-2.6-omap-h63xx.git] / sound / isa / opti9xx / opti92x-ad1848.c
index df227377c3331d8d46030c3d37bb6bb8d298df65..fe1afc13a01d4bdf6a373a40611f24e734788dcf 100644 (file)
 */
 
 
-#include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
@@ -259,7 +258,6 @@ struct snd_opti9xx {
 };
 
 static int snd_opti9xx_pnp_is_probed;
-static struct platform_device *snd_opti9xx_platform_device;
 
 #ifdef CONFIG_PNP
 
@@ -281,10 +279,10 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids);
 #endif /* CONFIG_PNP */
 
 #ifdef OPTi93X
-#define DRIVER_NAME    "snd-card-opti93x"
+#define DEV_NAME "opti93x"
 #else
-#define DRIVER_NAME    "snd-card-opti92x"
-#endif /* OPTi93X */
+#define DEV_NAME "opti92x"
+#endif
 
 static char * snd_opti9xx_names[] = {
        "unkown",
@@ -294,7 +292,7 @@ static char * snd_opti9xx_names[] = {
 };
 
 
-static long __init snd_legacy_find_free_ioport(long *port_table, long size)
+static long __devinit snd_legacy_find_free_ioport(long *port_table, long size)
 {
        while (*port_table != -1) {
                if (request_region(*port_table, size, "ALSA test")) {
@@ -306,7 +304,8 @@ static long __init snd_legacy_find_free_ioport(long *port_table, long size)
        return -1;
 }
 
-static int __init snd_opti9xx_init(struct snd_opti9xx *chip, unsigned short hardware)
+static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
+                                     unsigned short hardware)
 {
        static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
 
@@ -451,7 +450,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
                (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
 
 
-static int __init snd_opti9xx_configure(struct snd_opti9xx *chip)
+static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
 {
        unsigned char wss_base_bits;
        unsigned char irq_bits;
@@ -501,6 +500,16 @@ static int __init snd_opti9xx_configure(struct snd_opti9xx *chip)
                        (chip->hardware == OPTi9XX_HW_82C930 ? 0x00 : 0x04),
                        0x34);
                snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x20, 0xbf);
+               /* 
+                * The BTC 1817DW has QS1000 wavetable which is connected
+                * to the serial digital input of the OPTI931.
+                */
+               snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(21), 0x82, 0xff);
+               /* 
+                * This bit sets OPTI931 to automaticaly select FM
+                * or digital input signal.
+                */
+               snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(26), 0x01, 0x01);
                break;
 #endif /* OPTi93X */
 
@@ -934,10 +943,8 @@ static int snd_opti93x_trigger(struct snd_pcm_substream *substream,
        case SNDRV_PCM_TRIGGER_STOP:
        {
                unsigned int what = 0;
-               struct list_head *pos;
                struct snd_pcm_substream *s;
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == chip->playback_substream) {
                                what |= OPTi93X_PLAYBACK_ENABLE;
                                snd_pcm_trigger_done(s, substream);
@@ -1291,7 +1298,7 @@ static int snd_opti93x_create(struct snd_card *card, struct snd_opti9xx *chip,
        }
        codec->dma2 = chip->dma2;
 
-       if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DRIVER_NAME" - WSS", codec)) {
+       if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DEV_NAME" - WSS", codec)) {
                snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq);
                snd_opti93x_free(codec);
                return -EBUSY;
@@ -1561,7 +1568,7 @@ static int snd_opti93x_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
        return change;
 }
 
-static struct snd_kcontrol_new snd_opti93x_controls[] = {
+static struct snd_kcontrol_new snd_opti93x_controls[] __devinitdata = {
 OPTi93X_DOUBLE("Master Playback Switch", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
 OPTi93X_DOUBLE("Master Playback Volume", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), 
 OPTi93X_DOUBLE("PCM Playback Switch", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 7, 7, 1, 1),
@@ -1587,7 +1594,7 @@ OPTi93X_DOUBLE("Capture Volume", 0, OPTi93X_MIXOUT_LEFT, OPTi93X_MIXOUT_RIGHT, 0
 }
 };
                                         
-static int snd_opti93x_mixer(struct snd_opti93x *chip)
+static int __devinit snd_opti93x_mixer(struct snd_opti93x *chip)
 {
        struct snd_card *card;
        struct snd_kcontrol_new knew;
@@ -1622,7 +1629,8 @@ static int snd_opti93x_mixer(struct snd_opti93x *chip)
 
 #endif /* OPTi93X */
 
-static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti9xx *chip)
+static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
+                                            struct snd_opti9xx *chip)
 {
        int i, err;
 
@@ -1676,67 +1684,34 @@ static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti
 }
 
 #ifdef CONFIG_PNP
-static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card_link *card,
-                                      const struct pnp_card_device_id *pid)
+static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
+                                         struct pnp_card_link *card,
+                                         const struct pnp_card_device_id *pid)
 {
        struct pnp_dev *pdev;
-       struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
        int err;
 
-       if (!cfg)
-               return -ENOMEM;
        chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL);
-       if (chip->dev == NULL) {
-               kfree(cfg);
+       if (chip->dev == NULL)
                return -EBUSY;
-       }
+
        chip->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
 
        pdev = chip->dev;
-       pnp_init_resource_table(cfg);
 
-#ifdef OPTi93X
-       if (port != SNDRV_AUTO_PORT)
-               pnp_resource_change(&cfg->port_resource[0], port + 4, 4);
-#else
-       if (pid->driver_data != 0x0924 && port != SNDRV_AUTO_PORT)
-               pnp_resource_change(&cfg->port_resource[1], port, 4);
-#endif /* OPTi93X */
-       if (irq != SNDRV_AUTO_IRQ)
-               pnp_resource_change(&cfg->irq_resource[0], irq, 1);
-       if (dma1 != SNDRV_AUTO_DMA)
-               pnp_resource_change(&cfg->dma_resource[0], dma1, 1);
-#if defined(CS4231) || defined(OPTi93X)
-       if (dma2 != SNDRV_AUTO_DMA)
-               pnp_resource_change(&cfg->dma_resource[1], dma2, 1);
-#else
-#ifdef snd_opti9xx_fixup_dma2
-       snd_opti9xx_fixup_dma2(pdev);
-#endif
-#endif /* CS4231 || OPTi93X */
-#ifdef OPTi93X
-       if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT)
-               pnp_resource_change(&cfg->port_resource[1], fm_port, 4);
-#else
-       if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT)
-               pnp_resource_change(&cfg->port_resource[2], fm_port, 4);
-#endif
-       if (pnp_manual_config_dev(pdev, cfg, 0) < 0)
-               snd_printk(KERN_ERR "AUDIO the requested resources are invalid, using auto config\n");
        err = pnp_activate_dev(pdev);
        if (err < 0) {
                snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
-               kfree(cfg);
                return err;
        }
 
 #ifdef OPTi93X
        port = pnp_port_start(pdev, 0) - 4;
-       fm_port = pnp_port_start(pdev, 1);
+       fm_port = pnp_port_start(pdev, 1) + 8;
 #else
        if (pid->driver_data != 0x0924)
                port = pnp_port_start(pdev, 1);
-       fm_port = pnp_port_start(pdev, 2);
+       fm_port = pnp_port_start(pdev, 2) + 8;
 #endif /* OPTi93X */
        irq = pnp_irq(pdev, 0);
        dma1 = pnp_dma(pdev, 0);
@@ -1746,15 +1721,6 @@ static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card
 
        pdev = chip->devmpu;
        if (pdev && mpu_port > 0) {
-               pnp_init_resource_table(cfg);
-
-               if (mpu_port != SNDRV_AUTO_PORT)
-                       pnp_resource_change(&cfg->port_resource[0], mpu_port, 2);
-               if (mpu_irq != SNDRV_AUTO_IRQ)
-                       pnp_resource_change(&cfg->irq_resource[0], mpu_irq, 1);
-
-               if (pnp_manual_config_dev(pdev, cfg, 0) < 0)
-                       snd_printk(KERN_ERR "AUDIO the requested resources are invalid, using auto config\n");
                err = pnp_activate_dev(pdev);
                if (err < 0) {
                        snd_printk(KERN_ERR "AUDIO pnp configure failure\n");
@@ -1765,7 +1731,6 @@ static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card
                        mpu_irq = pnp_irq(pdev, 0);
                }
        }
-       kfree(cfg);
        return pid->driver_data;
 }
 #endif /* CONFIG_PNP */
@@ -1778,7 +1743,7 @@ static void snd_card_opti9xx_free(struct snd_card *card)
                release_and_free_resource(chip->res_mc_base);
 }
 
-static int __init snd_opti9xx_probe(struct snd_card *card)
+static int __devinit snd_opti9xx_probe(struct snd_card *card)
 {
        static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
        int error;
@@ -1924,7 +1889,20 @@ static struct snd_card *snd_opti9xx_card_new(void)
        return card;
 }
 
-static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
+static int __devinit snd_opti9xx_isa_match(struct device *devptr,
+                                          unsigned int dev)
+{
+#ifdef CONFIG_PNP
+       if (snd_opti9xx_pnp_is_probed)
+               return 0;
+       if (isapnp)
+               return 0;
+#endif
+       return 1;
+}
+
+static int __devinit snd_opti9xx_isa_probe(struct device *devptr,
+                                          unsigned int dev)
 {
        struct snd_card *card;
        int error;
@@ -1940,9 +1918,6 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
        static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
 #endif /* CS4231 || OPTi93X */
 
-       if (snd_opti9xx_pnp_is_probed)
-               return -EBUSY;
-
        if (mpu_port == SNDRV_AUTO_PORT) {
                if ((mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
                        snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
@@ -1984,34 +1959,36 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
                snd_card_free(card);
                return error;
        }
-       snd_card_set_dev(card, &devptr->dev);
+       snd_card_set_dev(card, devptr);
        if ((error = snd_opti9xx_probe(card)) < 0) {
                snd_card_free(card);
                return error;
        }
-       platform_set_drvdata(devptr, card);
+       dev_set_drvdata(devptr, card);
        return 0;
 }
 
-static int __devexit snd_opti9xx_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_opti9xx_isa_remove(struct device *devptr,
+                                           unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(devptr));
+       dev_set_drvdata(devptr, NULL);
        return 0;
 }
 
-static struct platform_driver snd_opti9xx_driver = {
-       .probe          = snd_opti9xx_nonpnp_probe,
-       .remove         = __devexit_p(snd_opti9xx_nonpnp_remove),
+static struct isa_driver snd_opti9xx_driver = {
+       .match          = snd_opti9xx_isa_match,
+       .probe          = snd_opti9xx_isa_probe,
+       .remove         = __devexit_p(snd_opti9xx_isa_remove),
        /* FIXME: suspend/resume */
        .driver         = {
-               .name   = DRIVER_NAME
+               .name   = DEV_NAME
        },
 };
 
 #ifdef CONFIG_PNP
-static int __init snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
-                                       const struct pnp_card_device_id *pid)
+static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
+                                          const struct pnp_card_device_id *pid)
 {
        struct snd_card *card;
        int error, hw;
@@ -2074,11 +2051,6 @@ static struct pnp_card_driver opti9xx_pnpc_driver = {
 };
 #endif
 
-#ifdef CONFIG_PNP
-#define is_isapnp_selected()   isapnp
-#else
-#define is_isapnp_selected()   0
-#endif
 #ifdef OPTi93X
 #define CHIP_NAME      "82C93x"
 #else
@@ -2087,42 +2059,20 @@ static struct pnp_card_driver opti9xx_pnpc_driver = {
 
 static int __init alsa_card_opti9xx_init(void)
 {
-       int error;
-       struct platform_device *device;
-
 #ifdef CONFIG_PNP
        pnp_register_card_driver(&opti9xx_pnpc_driver);
        if (snd_opti9xx_pnp_is_probed)
                return 0;
-#endif
-       if (! is_isapnp_selected()) {
-               error = platform_driver_register(&snd_opti9xx_driver);
-               if (error < 0)
-                       return error;
-               device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
-               if (!IS_ERR(device)) {
-                       if (platform_get_drvdata(device)) {
-                               snd_opti9xx_platform_device = device;
-                               return 0;
-                       }
-                       platform_device_unregister(device);
-               }
-               platform_driver_unregister(&snd_opti9xx_driver);
-       }
-#ifdef CONFIG_PNP
        pnp_unregister_card_driver(&opti9xx_pnpc_driver);
 #endif
-#ifdef MODULE
-       printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n");
-#endif
-       return -ENODEV;
+       return isa_register_driver(&snd_opti9xx_driver, 1);
 }
 
 static void __exit alsa_card_opti9xx_exit(void)
 {
        if (!snd_opti9xx_pnp_is_probed) {
-               platform_device_unregister(snd_opti9xx_platform_device);
-               platform_driver_unregister(&snd_opti9xx_driver);
+               isa_unregister_driver(&snd_opti9xx_driver);
+               return;
        }
 #ifdef CONFIG_PNP
        pnp_unregister_card_driver(&opti9xx_pnpc_driver);