blob: 6c0f7f21c2481f8861daf5948e95f78cccf2abcc [file] [log] [blame]
Stefan Hajnoczi16dc1042011-11-23 08:20:42 +00001/*
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 struct usb_line6 *line6;
84
85 if (podhd == NULL)
86 return;
87 line6 = &podhd->line6;
88 if (line6 == NULL)
89 return;
90 line6_cleanup_audio(line6);
91}
92
93/*
94 Try to init POD HD device.
95*/
96static int podhd_try_init(struct usb_interface *interface,
97 struct usb_line6_podhd *podhd)
98{
99 int err;
100 struct usb_line6 *line6 = &podhd->line6;
101
102 if ((interface == NULL) || (podhd == NULL))
103 return -ENODEV;
104
105 /* initialize audio system: */
106 err = line6_init_audio(line6);
107 if (err < 0)
108 return err;
109
110 /* initialize MIDI subsystem: */
111 err = line6_init_midi(line6);
112 if (err < 0)
113 return err;
114
115 /* initialize PCM subsystem: */
116 err = line6_init_pcm(line6, &podhd_pcm_properties);
117 if (err < 0)
118 return err;
119
120 /* register USB audio system: */
121 err = line6_register_audio(line6);
122 return err;
123}
124
125/*
126 Init POD HD device (and clean up in case of failure).
127*/
128int line6_podhd_init(struct usb_interface *interface,
129 struct usb_line6_podhd *podhd)
130{
131 int err = podhd_try_init(interface, podhd);
132
133 if (err < 0)
134 podhd_destruct(interface);
135
136 return err;
137}
138
139/*
140 POD HD device disconnected.
141*/
142void line6_podhd_disconnect(struct usb_interface *interface)
143{
144 struct usb_line6_podhd *podhd;
145
146 if (interface == NULL)
147 return;
148 podhd = usb_get_intfdata(interface);
149
150 if (podhd != NULL) {
151 struct snd_line6_pcm *line6pcm = podhd->line6.line6pcm;
152
153 if (line6pcm != NULL)
154 line6_pcm_disconnect(line6pcm);
155 }
156
157 podhd_destruct(interface);
158}