linux/drivers/staging/line6/podhd.c
<<
>>
Prefs
   1/*
   2 * Line6 Pod HD
   3 *
   4 * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com>
   5 *
   6 *      This program is free software; you can redistribute it and/or
   7 *      modify it under the terms of the GNU General Public License as
   8 *      published by the Free Software Foundation, version 2.
   9 *
  10 */
  11
  12#include <sound/core.h>
  13#include <sound/pcm.h>
  14
  15#include "audio.h"
  16#include "driver.h"
  17#include "pcm.h"
  18#include "podhd.h"
  19
  20#define PODHD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
  21
  22static struct snd_ratden podhd_ratden = {
  23        .num_min = 48000,
  24        .num_max = 48000,
  25        .num_step = 1,
  26        .den = 1,
  27};
  28
  29static struct line6_pcm_properties podhd_pcm_properties = {
  30        .snd_line6_playback_hw = {
  31                                  .info = (SNDRV_PCM_INFO_MMAP |
  32                                           SNDRV_PCM_INFO_INTERLEAVED |
  33                                           SNDRV_PCM_INFO_BLOCK_TRANSFER |
  34                                           SNDRV_PCM_INFO_MMAP_VALID |
  35                                           SNDRV_PCM_INFO_PAUSE |
  36#ifdef CONFIG_PM
  37                                           SNDRV_PCM_INFO_RESUME |
  38#endif
  39                                           SNDRV_PCM_INFO_SYNC_START),
  40                                  .formats = SNDRV_PCM_FMTBIT_S24_3LE,
  41                                  .rates = SNDRV_PCM_RATE_48000,
  42                                  .rate_min = 48000,
  43                                  .rate_max = 48000,
  44                                  .channels_min = 2,
  45                                  .channels_max = 2,
  46                                  .buffer_bytes_max = 60000,
  47                                  .period_bytes_min = 64,
  48                                  .period_bytes_max = 8192,
  49                                  .periods_min = 1,
  50                                  .periods_max = 1024},
  51        .snd_line6_capture_hw = {
  52                                 .info = (SNDRV_PCM_INFO_MMAP |
  53                                          SNDRV_PCM_INFO_INTERLEAVED |
  54                                          SNDRV_PCM_INFO_BLOCK_TRANSFER |
  55                                          SNDRV_PCM_INFO_MMAP_VALID |
  56#ifdef CONFIG_PM
  57                                          SNDRV_PCM_INFO_RESUME |
  58#endif
  59                                          SNDRV_PCM_INFO_SYNC_START),
  60                                 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
  61                                 .rates = SNDRV_PCM_RATE_48000,
  62                                 .rate_min = 48000,
  63                                 .rate_max = 48000,
  64                                 .channels_min = 2,
  65                                 .channels_max = 2,
  66                                 .buffer_bytes_max = 60000,
  67                                 .period_bytes_min = 64,
  68                                 .period_bytes_max = 8192,
  69                                 .periods_min = 1,
  70                                 .periods_max = 1024},
  71        .snd_line6_rates = {
  72                            .nrats = 1,
  73                            .rats = &podhd_ratden},
  74        .bytes_per_frame = PODHD_BYTES_PER_FRAME
  75};
  76
  77/*
  78        POD HD destructor.
  79*/
  80static void podhd_destruct(struct usb_interface *interface)
  81{
  82        struct usb_line6_podhd *podhd = usb_get_intfdata(interface);
  83
  84        if (podhd == NULL)
  85                return;
  86        line6_cleanup_audio(&podhd->line6);
  87}
  88
  89/*
  90        Try to init POD HD device.
  91*/
  92static int podhd_try_init(struct usb_interface *interface,
  93                          struct usb_line6_podhd *podhd)
  94{
  95        int err;
  96        struct usb_line6 *line6 = &podhd->line6;
  97
  98        if ((interface == NULL) || (podhd == NULL))
  99                return -ENODEV;
 100
 101        /* initialize audio system: */
 102        err = line6_init_audio(line6);
 103        if (err < 0)
 104                return err;
 105
 106        /* initialize MIDI subsystem: */
 107        err = line6_init_midi(line6);
 108        if (err < 0)
 109                return err;
 110
 111        /* initialize PCM subsystem: */
 112        err = line6_init_pcm(line6, &podhd_pcm_properties);
 113        if (err < 0)
 114                return err;
 115
 116        /* register USB audio system: */
 117        err = line6_register_audio(line6);
 118        return err;
 119}
 120
 121/*
 122        Init POD HD device (and clean up in case of failure).
 123*/
 124int line6_podhd_init(struct usb_interface *interface,
 125                     struct usb_line6_podhd *podhd)
 126{
 127        int err = podhd_try_init(interface, podhd);
 128
 129        if (err < 0)
 130                podhd_destruct(interface);
 131
 132        return err;
 133}
 134
 135/*
 136        POD HD device disconnected.
 137*/
 138void line6_podhd_disconnect(struct usb_interface *interface)
 139{
 140        struct usb_line6_podhd *podhd;
 141
 142        if (interface == NULL)
 143                return;
 144        podhd = usb_get_intfdata(interface);
 145
 146        if (podhd != NULL) {
 147                struct snd_line6_pcm *line6pcm = podhd->line6.line6pcm;
 148
 149                if (line6pcm != NULL)
 150                        line6_pcm_disconnect(line6pcm);
 151        }
 152
 153        podhd_destruct(interface);
 154}
 155