Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
[pandora-kernel.git] / sound / pci / rme9652 / hdspm.c
index 493e394..15a6c3b 100644 (file)
@@ -520,16 +520,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
 #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
 #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
 
-/* revisions >= 230 indicate AES32 card */
-#define HDSPM_MADI_ANCIENT_REV 204
-#define HDSPM_MADI_OLD_REV     207
-#define HDSPM_MADI_REV         210
 #define HDSPM_RAYDAT_REV       211
 #define HDSPM_AIO_REV          212
 #define HDSPM_MADIFACE_REV     213
-#define HDSPM_AES_REV          240
-#define HDSPM_AES32_REV                234
-#define HDSPM_AES32_OLD_REV    233
 
 /* speed factor modes */
 #define HDSPM_SPEED_SINGLE 0
@@ -1241,10 +1234,30 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
        return rate;
 }
 
+/* return latency in samples per period */
+static int hdspm_get_latency(struct hdspm *hdspm)
+{
+       int n;
+
+       n = hdspm_decode_latency(hdspm->control_register);
+
+       /* Special case for new RME cards with 32 samples period size.
+        * The three latency bits in the control register
+        * (HDSP_LatencyMask) encode latency values of 64 samples as
+        * 0, 128 samples as 1 ... 4096 samples as 6. For old cards, 7
+        * denotes 8192 samples, but on new cards like RayDAT or AIO,
+        * it corresponds to 32 samples.
+        */
+       if ((7 == n) && (RayDAT == hdspm->io_type || AIO == hdspm->io_type))
+               n = -1;
+
+       return 1 << (n + 6);
+}
+
 /* Latency function */
 static inline void hdspm_compute_period_size(struct hdspm *hdspm)
 {
-       hdspm->period_bytes = 1 << ((hdspm_decode_latency(hdspm->control_register) + 8));
+       hdspm->period_bytes = 4 * hdspm_get_latency(hdspm);
 }
 
 
@@ -1303,12 +1316,27 @@ static int hdspm_set_interrupt_interval(struct hdspm *s, unsigned int frames)
 
        spin_lock_irq(&s->lock);
 
-       frames >>= 7;
-       n = 0;
-       while (frames) {
-               n++;
-               frames >>= 1;
+       if (32 == frames) {
+               /* Special case for new RME cards like RayDAT/AIO which
+                * support period sizes of 32 samples. Since latency is
+                * encoded in the three bits of HDSP_LatencyMask, we can only
+                * have values from 0 .. 7. While 0 still means 64 samples and
+                * 6 represents 4096 samples on all cards, 7 represents 8192
+                * on older cards and 32 samples on new cards.
+                *
+                * In other words, period size in samples is calculated by
+                * 2^(n+6) with n ranging from 0 .. 7.
+                */
+               n = 7;
+       } else {
+               frames >>= 7;
+               n = 0;
+               while (frames) {
+                       n++;
+                       frames >>= 1;
+               }
        }
+
        s->control_register &= ~HDSPM_LatencyMask;
        s->control_register |= hdspm_encode_latency(n);
 
@@ -4801,8 +4829,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
 
        snd_iprintf(buffer, "--- Settings ---\n");
 
-       x = 1 << (6 + hdspm_decode_latency(hdspm->control_register &
-                                                       HDSPM_LatencyMask));
+       x = hdspm_get_latency(hdspm);
 
        snd_iprintf(buffer,
                "Size (Latency): %d samples (2 periods of %lu bytes)\n",
@@ -4965,8 +4992,7 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
 
        snd_iprintf(buffer, "--- Settings ---\n");
 
-       x = 1 << (6 + hdspm_decode_latency(hdspm->control_register &
-                               HDSPM_LatencyMask));
+       x = hdspm_get_latency(hdspm);
 
        snd_iprintf(buffer,
                    "Size (Latency): %d samples (2 periods of %lu bytes)\n",
@@ -5672,19 +5698,6 @@ static int snd_hdspm_prepare(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static unsigned int period_sizes_old[] = {
-       64, 128, 256, 512, 1024, 2048, 4096
-};
-
-static unsigned int period_sizes_new[] = {
-       32, 64, 128, 256, 512, 1024, 2048, 4096
-};
-
-/* RayDAT and AIO always have a buffer of 16384 samples per channel */
-static unsigned int raydat_aio_buffer_sizes[] = {
-       16384
-};
-
 static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
        .info = (SNDRV_PCM_INFO_MMAP |
                 SNDRV_PCM_INFO_MMAP_VALID |
@@ -5703,8 +5716,8 @@ static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
        .channels_max = HDSPM_MAX_CHANNELS,
        .buffer_bytes_max =
            HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
-       .period_bytes_min = (64 * 4),
-       .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS,
+       .period_bytes_min = (32 * 4),
+       .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
        .periods_min = 2,
        .periods_max = 512,
        .fifo_size = 0
@@ -5728,31 +5741,13 @@ static struct snd_pcm_hardware snd_hdspm_capture_subinfo = {
        .channels_max = HDSPM_MAX_CHANNELS,
        .buffer_bytes_max =
            HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
-       .period_bytes_min = (64 * 4),
-       .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS,
+       .period_bytes_min = (32 * 4),
+       .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
        .periods_min = 2,
        .periods_max = 512,
        .fifo_size = 0
 };
 
-static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_old = {
-       .count = ARRAY_SIZE(period_sizes_old),
-       .list = period_sizes_old,
-       .mask = 0
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_new = {
-       .count = ARRAY_SIZE(period_sizes_new),
-       .list = period_sizes_new,
-       .mask = 0
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_raydat_io_buffer = {
-       .count = ARRAY_SIZE(raydat_aio_buffer_sizes),
-       .list = raydat_aio_buffer_sizes,
-       .mask = 0
-};
-
 static int snd_hdspm_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params,
                                           struct snd_pcm_hw_rule *rule)
 {
@@ -5953,26 +5948,29 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
        spin_unlock_irq(&hdspm->lock);
 
        snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+       snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
 
        switch (hdspm->io_type) {
        case AIO:
        case RayDAT:
-               snd_pcm_hw_constraint_list(runtime, 0,
-                               SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
-                               &hw_constraints_period_sizes_new);
-               snd_pcm_hw_constraint_list(runtime, 0,
-                               SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
-                               &hw_constraints_raydat_io_buffer);
-
+               snd_pcm_hw_constraint_minmax(runtime,
+                                            SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+                                            32, 4096);
+               /* RayDAT & AIO have a fixed buffer of 16384 samples per channel */
+               snd_pcm_hw_constraint_minmax(runtime,
+                                            SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+                                            16384, 16384);
                break;
 
        default:
-               snd_pcm_hw_constraint_list(runtime, 0,
-                               SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
-                               &hw_constraints_period_sizes_old);
+               snd_pcm_hw_constraint_minmax(runtime,
+                                            SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+                                            64, 8192);
+               break;
        }
 
        if (AES32 == hdspm->io_type) {
+               runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
                snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
                                &hdspm_hw_constraints_aes32_sample_rates);
        } else {
@@ -6025,24 +6023,28 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream)
        spin_unlock_irq(&hdspm->lock);
 
        snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+       snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
+
        switch (hdspm->io_type) {
        case AIO:
        case RayDAT:
-         snd_pcm_hw_constraint_list(runtime, 0,
-                                    SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
-                                    &hw_constraints_period_sizes_new);
-         snd_pcm_hw_constraint_list(runtime, 0,
-                                    SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
-                                    &hw_constraints_raydat_io_buffer);
-         break;
+               snd_pcm_hw_constraint_minmax(runtime,
+                                            SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+                                            32, 4096);
+               snd_pcm_hw_constraint_minmax(runtime,
+                                            SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+                                            16384, 16384);
+               break;
 
        default:
-         snd_pcm_hw_constraint_list(runtime, 0,
-                                    SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
-                                    &hw_constraints_period_sizes_old);
+               snd_pcm_hw_constraint_minmax(runtime,
+                                            SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+                                            64, 8192);
+               break;
        }
 
        if (AES32 == hdspm->io_type) {
+               runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
                snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
                                &hdspm_hw_constraints_aes32_sample_rates);
        } else {
@@ -6088,7 +6090,7 @@ static inline int copy_u32_le(void __user *dest, void __iomem *src)
 }
 
 static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
-               unsigned int cmd, unsigned long __user arg)
+               unsigned int cmd, unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
        struct hdspm *hdspm = hw->private_data;
@@ -6213,11 +6215,13 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
                info.line_out = hdspm_line_out(hdspm);
                info.passthru = 0;
                spin_unlock_irq(&hdspm->lock);
-               if (copy_to_user((void __user *) arg, &info, sizeof(info)))
+               if (copy_to_user(argp, &info, sizeof(info)))
                        return -EFAULT;
                break;
 
        case SNDRV_HDSPM_IOCTL_GET_STATUS:
+               memset(&status, 0, sizeof(status));
+
                status.card_type = hdspm->io_type;
 
                status.autosync_source = hdspm_autosync_ref(hdspm);
@@ -6242,7 +6246,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
                        status.card_specific.madi.madi_input =
                                (statusregister & HDSPM_AB_int) ? 1 : 0;
                        status.card_specific.madi.channel_format =
-                               (statusregister & HDSPM_TX_64ch) ? 1 : 0;
+                               (statusregister & HDSPM_RX_64ch) ? 1 : 0;
                        /* TODO: Mac driver sets it when f_s>48kHz */
                        status.card_specific.madi.frame_format = 0;
 
@@ -6250,13 +6254,15 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
                        break;
                }
 
-               if (copy_to_user((void __user *) arg, &status, sizeof(status)))
+               if (copy_to_user(argp, &status, sizeof(status)))
                        return -EFAULT;
 
 
                break;
 
        case SNDRV_HDSPM_IOCTL_GET_VERSION:
+               memset(&hdspm_version, 0, sizeof(hdspm_version));
+
                hdspm_version.card_type = hdspm->io_type;
                strncpy(hdspm_version.cardname, hdspm->card_name,
                                sizeof(hdspm_version.cardname));
@@ -6267,13 +6273,13 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
                if (hdspm->tco)
                        hdspm_version.addons |= HDSPM_ADDON_TCO;
 
-               if (copy_to_user((void __user *) arg, &hdspm_version,
+               if (copy_to_user(argp, &hdspm_version,
                                        sizeof(hdspm_version)))
                        return -EFAULT;
                break;
 
        case SNDRV_HDSPM_IOCTL_GET_MIXER:
-               if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer)))
+               if (copy_from_user(&mixer, argp, sizeof(mixer)))
                        return -EFAULT;
                if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer,
                                        sizeof(struct hdspm_mixer)))
@@ -6490,13 +6496,6 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
        strcpy(card->driver, "HDSPM");
 
        switch (hdspm->firmware_rev) {
-       case HDSPM_MADI_REV:
-       case HDSPM_MADI_OLD_REV:
-       case HDSPM_MADI_ANCIENT_REV:
-               hdspm->io_type = MADI;
-               hdspm->card_name = "RME MADI";
-               hdspm->midiPorts = 3;
-               break;
        case HDSPM_RAYDAT_REV:
                hdspm->io_type = RayDAT;
                hdspm->card_name = "RME RayDAT";
@@ -6512,17 +6511,25 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
                hdspm->card_name = "RME MADIface";
                hdspm->midiPorts = 1;
                break;
-       case HDSPM_AES_REV:
-       case HDSPM_AES32_REV:
-       case HDSPM_AES32_OLD_REV:
-               hdspm->io_type = AES32;
-               hdspm->card_name = "RME AES32";
-               hdspm->midiPorts = 2;
-               break;
        default:
-               snd_printk(KERN_ERR "HDSPM: unknown firmware revision %x\n",
+               if ((hdspm->firmware_rev == 0xf0) ||
+                       ((hdspm->firmware_rev >= 0xe6) &&
+                                       (hdspm->firmware_rev <= 0xea))) {
+                       hdspm->io_type = AES32;
+                       hdspm->card_name = "RME AES32";
+                       hdspm->midiPorts = 2;
+               } else if ((hdspm->firmware_rev == 0xd5) ||
+                       ((hdspm->firmware_rev >= 0xc8)  &&
+                               (hdspm->firmware_rev <= 0xcf))) {
+                       hdspm->io_type = MADI;
+                       hdspm->card_name = "RME MADI";
+                       hdspm->midiPorts = 3;
+               } else {
+                       snd_printk(KERN_ERR
+                               "HDSPM: unknown firmware revision %x\n",
                                hdspm->firmware_rev);
-               return -ENODEV;
+                       return -ENODEV;
+               }
        }
 
        err = pci_enable_device(pci);