Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[pandora-kernel.git] / sound / pci / asihpi / asihpi.c
index e3569bd..eae62eb 100644 (file)
 #include <sound/tlv.h>
 #include <sound/hwdep.h>
 
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
 MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
 
-#if defined CONFIG_SND_DEBUG
-/* copied from pcm_lib.c, hope later patch will make that version public
-and this copy can be removed */
-static void pcm_debug_name(struct snd_pcm_substream *substream,
-                          char *name, size_t len)
-{
-       snprintf(name, len, "pcmC%dD%d%c:%d",
-                substream->pcm->card->number,
-                substream->pcm->device,
-                substream->stream ? 'c' : 'p',
-                substream->number);
-}
-#define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name))
-#else
-#define pcm_debug_name(s, n, l) do { } while (0)
-#define DEBUG_NAME(name, substream) do { } while (0)
-#endif
-
 #if defined CONFIG_SND_DEBUG_VERBOSE
 /**
  * snd_printddd - very verbose debug printk
@@ -304,7 +285,8 @@ static u16 handle_error(u16 err, int line, char *filename)
 static void print_hwparams(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *p)
 {
-       DEBUG_NAME(substream, name);
+       char name[16];
+       snd_pcm_debug_name(substream, name, sizeof(name));
        snd_printd("%s HWPARAMS\n", name);
        snd_printd(" samplerate %d Hz\n", params_rate(p));
        snd_printd(" channels %d\n", params_channels(p));
@@ -576,8 +558,9 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
        struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
        struct snd_pcm_substream *s;
        u16 e;
-       DEBUG_NAME(substream, name);
+       char name[16];
 
+       snd_pcm_debug_name(substream, name, sizeof(name));
        snd_printdd("%s trigger\n", name);
 
        switch (cmd) {
@@ -741,7 +724,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
        int loops = 0;
        u16 state;
        u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
-       DEBUG_NAME(substream, name);
+       char name[16];
+
+       snd_pcm_debug_name(substream, name, sizeof(name));
 
        snd_printdd("%s snd_card_asihpi_timer_function\n", name);
 
@@ -1323,10 +1308,12 @@ static const char * const asihpi_src_names[] = {
        "RF",
        "Clock",
        "Bitstream",
-       "Microphone",
-       "Cobranet",
+       "Mic",
+       "Net",
        "Analog",
        "Adapter",
+       "RTP",
+       "GPI",
 };
 
 compile_time_assert(
@@ -1341,8 +1328,10 @@ static const char * const asihpi_dst_names[] = {
        "Digital",
        "RF",
        "Speaker",
-       "Cobranet Out",
-       "Analog"
+       "Net",
+       "Analog",
+       "RTP",
+       "GPO",
 };
 
 compile_time_assert(
@@ -1476,11 +1465,40 @@ static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
 
 static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
 
+#define snd_asihpi_volume_mute_info    snd_ctl_boolean_mono_info
+
+static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
+{
+       u32 h_control = kcontrol->private_value;
+       u32 mute;
+
+       hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
+       ucontrol->value.integer.value[0] = mute ? 0 : 1;
+
+       return 0;
+}
+
+static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
+{
+       u32 h_control = kcontrol->private_value;
+       int change = 1;
+       /* HPI currently only supports all or none muting of multichannel volume
+       ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
+       */
+       int mute =  ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS;
+       hpi_handle_error(hpi_volume_set_mute(h_control, mute));
+       return change;
+}
+
 static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
                                        struct hpi_control *hpi_ctl)
 {
        struct snd_card *card = asihpi->card;
        struct snd_kcontrol_new snd_control;
+       int err;
+       u32 mute;
 
        asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
        snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1490,7 +1508,19 @@ static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
        snd_control.put = snd_asihpi_volume_put;
        snd_control.tlv.p = db_scale_100;
 
-       return ctl_add(card, &snd_control, asihpi);
+       err = ctl_add(card, &snd_control, asihpi);
+       if (err)
+               return err;
+
+       if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) {
+               asihpi_ctl_init(&snd_control, hpi_ctl, "Switch");
+               snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
+               snd_control.info = snd_asihpi_volume_mute_info;
+               snd_control.get = snd_asihpi_volume_mute_get;
+               snd_control.put = snd_asihpi_volume_mute_put;
+               err = ctl_add(card, &snd_control, asihpi);
+       }
+       return err;
 }
 
 /*------------------------------------------------------------
@@ -2923,7 +2953,7 @@ static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
 MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
 
 static struct pci_driver driver = {
-       .name = "asihpi",
+       .name = KBUILD_MODNAME,
        .id_table = asihpi_pci_tbl,
        .probe = snd_asihpi_probe,
        .remove = __devexit_p(snd_asihpi_remove),