]> err.no Git - linux-2.6/blobdiff - sound/isa/es18xx.c
Manual merge with Linus.
[linux-2.6] / sound / isa / es18xx.c
index 93335000c51e6a04ed96bc81ef7230308f77b3a9..9fbc185b4cc24a734a1a19599eeed5d3738eb27f 100644 (file)
  * - contrarily to some pages in DS_1869.PDF the rates can be set
  *   independently.
  *
+ * - Zoom Video is implemented by sharing the FM DAC, thus the user can
+ *   have either FM playback or Video playback but not both simultaneously.
+ *   The Video Playback Switch mixer control toggles this choice.
+ *
  * BUGS:
  *
  * - There is a major trouble I noted:
  *
  */
 
-
+/*
+ * ES1879 NOTES:
+ * - When Zoom Video is enabled (reg 0x71 bit 6 toggled on) the PCM playback
+ *   seems to be effected (speaker_test plays a lower frequency). Can't find
+ *   anything in the datasheet to account for this, so a Video Playback Switch
+ *   control has been included to allow ZV to be enabled only when necessary.
+ *   Then again on at least one test system the 0x71 bit 6 enable bit is not 
+ *   needed for ZV, so maybe the datasheet is entirely wrong here.
+ */
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
@@ -1317,10 +1330,20 @@ static struct snd_kcontrol_new snd_es18xx_opt_speaker =
 
 static struct snd_kcontrol_new snd_es18xx_opt_1869[] = {
 ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
+ES18XX_SINGLE("Video Playback Switch", 0, 0x7f, 0, 1, 0),
 ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
 ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0)
 };
 
+static struct snd_kcontrol_new snd_es18xx_opt_1878 =
+       ES18XX_DOUBLE("Video Playback Volume", 0, 0x68, 0x68, 4, 0, 15, 0);
+
+static struct snd_kcontrol_new snd_es18xx_opt_1879[] = {
+ES18XX_SINGLE("Video Playback Switch", 0, 0x71, 6, 1, 0),
+ES18XX_DOUBLE("Video Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
+ES18XX_DOUBLE("Video Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0)
+};
+
 static struct snd_kcontrol_new snd_es18xx_pcm1_controls[] = {
 ES18XX_DOUBLE("PCM Playback Volume", 0, 0x14, 0x14, 4, 0, 15, 0),
 };
@@ -1365,7 +1388,6 @@ static struct snd_kcontrol_new snd_es18xx_hw_volume_controls[] = {
 ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0),
 };
 
-#if 0
 static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg)
 {
        int data;
@@ -1376,7 +1398,6 @@ static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned ch
         spin_unlock_irqrestore(&chip->ctrl_lock, flags);
        return data;
 }
-#endif
 
 static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip, 
                                              unsigned char reg, unsigned char data)
@@ -1522,6 +1543,17 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
                snd_es18xx_mixer_write(chip, 0x58, 0x94);
                snd_es18xx_mixer_write(chip, 0x5a, 0x80);
        }
+       /* Flip the "enable I2S" bits for those chipsets that need it */
+       switch (chip->version) {
+       case 0x1879:
+               //Leaving I2S enabled on the 1879 screws up the PCM playback (rate effected somehow)
+               //so a Switch control has been added to toggle this 0x71 bit on/off:
+               //snd_es18xx_mixer_bits(chip, 0x71, 0x40, 0x40);
+               /* Note: we fall through on purpose here. */
+       case 0x1878:
+               snd_es18xx_config_write(chip, 0x29, snd_es18xx_config_read(chip, 0x29) | 0x40);
+               break;
+       }
        /* Mute input source */
        if (chip->caps & ES18XX_MUTEREC)
                mask = 0x10;
@@ -1929,6 +1961,19 @@ static int __devinit snd_es18xx_mixer(struct snd_es18xx *chip)
                        if (err < 0)
                                return err;
                }
+       } else if (chip->version == 0x1878) {
+               err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_1878,
+                                                    chip));
+               if (err < 0)
+                       return err;
+       } else if (chip->version == 0x1879) {
+               for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1879); idx++) {
+                       err = snd_ctl_add(card,
+                                         snd_ctl_new1(&snd_es18xx_opt_1879[idx],
+                                                      chip));
+                       if (err < 0)
+                               return err;
+               }
        }
        return 0;
 }
@@ -2038,6 +2083,7 @@ static int __devinit snd_audiodrive_pnp(int dev, struct snd_audiodrive *acard,
        err = pnp_activate_dev(acard->devc);
        if (err < 0) {
                snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n");
+               kfree(cfg);
                return -EAGAIN;
        }
        snd_printdd("pnp: port=0x%lx\n", pnp_port_start(acard->devc, 0));
@@ -2158,7 +2204,7 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
        return snd_card_register(card);
 }
 
-static int __init snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr)
+static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr)
 {
        struct snd_card *card;
        int err;
@@ -2175,7 +2221,7 @@ static int __init snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devp
        return 0;
 }
 
-static int __init snd_es18xx_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
 {
        int dev = pdev->id;
        int err;
@@ -2251,6 +2297,8 @@ static struct platform_driver snd_es18xx_nonpnp_driver = {
 
 
 #ifdef CONFIG_PNP
+static unsigned int __devinitdata es18xx_pnp_devices;
+
 static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *pcard,
                                               const struct pnp_card_device_id *pid)
 {
@@ -2281,6 +2329,7 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *pcard,
 
        pnp_set_card_drvdata(pcard, card);
        dev++;
+       es18xx_pnp_devices++;
        return 0;
 }
 
@@ -2336,9 +2385,9 @@ static int __init alsa_card_es18xx_init(void)
        if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0)
                return err;
 
-       for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+       for (i = 0; i < SNDRV_CARDS; i++) {
                struct platform_device *device;
-               if (is_isapnp_selected(i))
+               if (! enable[i] || is_isapnp_selected(i))
                        continue;
                device = platform_device_register_simple(ES18XX_DRIVER,
                                                         i, NULL, 0);
@@ -2351,10 +2400,10 @@ static int __init alsa_card_es18xx_init(void)
        }
 
 #ifdef CONFIG_PNP
-       i = pnp_register_card_driver(&es18xx_pnpc_driver);
-       if (i >= 0) {
+       err = pnp_register_card_driver(&es18xx_pnpc_driver);
+       if (!err) {
                pnp_registered = 1;
-               cards += i;
+               cards += es18xx_pnp_devices;
        }
 #endif