]>
Commit | Line | Data |
---|---|---|
16dc1040 | 1 | /* |
c6fffce9 | 2 | * Line 6 Pod HD |
16dc1040 SH |
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 | ||
ccddbe4a TI |
12 | #include <linux/usb.h> |
13 | #include <linux/slab.h> | |
14 | #include <linux/module.h> | |
16dc1040 SH |
15 | #include <sound/core.h> |
16 | #include <sound/pcm.h> | |
17 | ||
16dc1040 SH |
18 | #include "driver.h" |
19 | #include "pcm.h" | |
ccddbe4a TI |
20 | |
21 | enum { | |
22 | LINE6_PODHD300, | |
23 | LINE6_PODHD400, | |
24 | LINE6_PODHD500_0, | |
25 | LINE6_PODHD500_1, | |
26 | }; | |
27 | ||
16dc1040 SH |
28 | #define PODHD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */ |
29 | ||
30 | static struct snd_ratden podhd_ratden = { | |
31 | .num_min = 48000, | |
32 | .num_max = 48000, | |
33 | .num_step = 1, | |
34 | .den = 1, | |
35 | }; | |
36 | ||
37 | static struct line6_pcm_properties podhd_pcm_properties = { | |
1263f611 | 38 | .playback_hw = { |
16dc1040 SH |
39 | .info = (SNDRV_PCM_INFO_MMAP | |
40 | SNDRV_PCM_INFO_INTERLEAVED | | |
41 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | |
42 | SNDRV_PCM_INFO_MMAP_VALID | | |
43 | SNDRV_PCM_INFO_PAUSE | | |
16dc1040 SH |
44 | SNDRV_PCM_INFO_SYNC_START), |
45 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | |
46 | .rates = SNDRV_PCM_RATE_48000, | |
47 | .rate_min = 48000, | |
48 | .rate_max = 48000, | |
49 | .channels_min = 2, | |
50 | .channels_max = 2, | |
51 | .buffer_bytes_max = 60000, | |
52 | .period_bytes_min = 64, | |
53 | .period_bytes_max = 8192, | |
54 | .periods_min = 1, | |
55 | .periods_max = 1024}, | |
1263f611 | 56 | .capture_hw = { |
16dc1040 SH |
57 | .info = (SNDRV_PCM_INFO_MMAP | |
58 | SNDRV_PCM_INFO_INTERLEAVED | | |
59 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | |
60 | SNDRV_PCM_INFO_MMAP_VALID | | |
16dc1040 SH |
61 | SNDRV_PCM_INFO_SYNC_START), |
62 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | |
63 | .rates = SNDRV_PCM_RATE_48000, | |
64 | .rate_min = 48000, | |
65 | .rate_max = 48000, | |
66 | .channels_min = 2, | |
67 | .channels_max = 2, | |
68 | .buffer_bytes_max = 60000, | |
69 | .period_bytes_min = 64, | |
70 | .period_bytes_max = 8192, | |
71 | .periods_min = 1, | |
72 | .periods_max = 1024}, | |
1263f611 | 73 | .rates = { |
16dc1040 SH |
74 | .nrats = 1, |
75 | .rats = &podhd_ratden}, | |
76 | .bytes_per_frame = PODHD_BYTES_PER_FRAME | |
77 | }; | |
78 | ||
16dc1040 SH |
79 | /* |
80 | Try to init POD HD device. | |
81 | */ | |
f66fd990 TI |
82 | static int podhd_init(struct usb_line6 *line6, |
83 | const struct usb_device_id *id) | |
16dc1040 SH |
84 | { |
85 | int err; | |
16dc1040 | 86 | |
16dc1040 SH |
87 | /* initialize MIDI subsystem: */ |
88 | err = line6_init_midi(line6); | |
89 | if (err < 0) | |
90 | return err; | |
91 | ||
92 | /* initialize PCM subsystem: */ | |
93 | err = line6_init_pcm(line6, &podhd_pcm_properties); | |
94 | if (err < 0) | |
95 | return err; | |
96 | ||
97 | /* register USB audio system: */ | |
85a9339b | 98 | return snd_card_register(line6->card); |
16dc1040 SH |
99 | } |
100 | ||
ccddbe4a TI |
101 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) |
102 | #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) | |
103 | ||
104 | /* table of devices that work with this driver */ | |
105 | static const struct usb_device_id podhd_id_table[] = { | |
106 | { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, | |
107 | { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, | |
108 | { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, | |
109 | { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, | |
110 | {} | |
111 | }; | |
112 | ||
113 | MODULE_DEVICE_TABLE(usb, podhd_id_table); | |
114 | ||
115 | static const struct line6_properties podhd_properties_table[] = { | |
116 | [LINE6_PODHD300] = { | |
117 | .id = "PODHD300", | |
118 | .name = "POD HD300", | |
119 | .capabilities = LINE6_CAP_CONTROL | |
120 | | LINE6_CAP_PCM | |
121 | | LINE6_CAP_HWMON, | |
122 | .altsetting = 5, | |
123 | .ep_ctrl_r = 0x84, | |
124 | .ep_ctrl_w = 0x03, | |
125 | .ep_audio_r = 0x82, | |
126 | .ep_audio_w = 0x01, | |
127 | }, | |
128 | [LINE6_PODHD400] = { | |
129 | .id = "PODHD400", | |
130 | .name = "POD HD400", | |
131 | .capabilities = LINE6_CAP_CONTROL | |
132 | | LINE6_CAP_PCM | |
133 | | LINE6_CAP_HWMON, | |
134 | .altsetting = 5, | |
135 | .ep_ctrl_r = 0x84, | |
136 | .ep_ctrl_w = 0x03, | |
137 | .ep_audio_r = 0x82, | |
138 | .ep_audio_w = 0x01, | |
139 | }, | |
140 | [LINE6_PODHD500_0] = { | |
141 | .id = "PODHD500", | |
142 | .name = "POD HD500", | |
143 | .capabilities = LINE6_CAP_CONTROL | |
144 | | LINE6_CAP_PCM | |
145 | | LINE6_CAP_HWMON, | |
146 | .altsetting = 1, | |
147 | .ep_ctrl_r = 0x81, | |
148 | .ep_ctrl_w = 0x01, | |
149 | .ep_audio_r = 0x86, | |
150 | .ep_audio_w = 0x02, | |
151 | }, | |
152 | [LINE6_PODHD500_1] = { | |
153 | .id = "PODHD500", | |
154 | .name = "POD HD500", | |
155 | .capabilities = LINE6_CAP_CONTROL | |
156 | | LINE6_CAP_PCM | |
157 | | LINE6_CAP_HWMON, | |
158 | .altsetting = 1, | |
159 | .ep_ctrl_r = 0x81, | |
160 | .ep_ctrl_w = 0x01, | |
161 | .ep_audio_r = 0x86, | |
162 | .ep_audio_w = 0x02, | |
163 | }, | |
164 | }; | |
165 | ||
ccddbe4a TI |
166 | /* |
167 | Probe USB device. | |
168 | */ | |
169 | static int podhd_probe(struct usb_interface *interface, | |
170 | const struct usb_device_id *id) | |
171 | { | |
aca514b8 | 172 | return line6_probe(interface, id, |
85a9339b | 173 | &podhd_properties_table[id->driver_info], |
b3313476 | 174 | podhd_init, sizeof(struct usb_line6)); |
ccddbe4a TI |
175 | } |
176 | ||
177 | static struct usb_driver podhd_driver = { | |
178 | .name = KBUILD_MODNAME, | |
179 | .probe = podhd_probe, | |
180 | .disconnect = line6_disconnect, | |
181 | #ifdef CONFIG_PM | |
182 | .suspend = line6_suspend, | |
183 | .resume = line6_resume, | |
184 | .reset_resume = line6_resume, | |
185 | #endif | |
186 | .id_table = podhd_id_table, | |
187 | }; | |
188 | ||
189 | module_usb_driver(podhd_driver); | |
190 | ||
c6fffce9 | 191 | MODULE_DESCRIPTION("Line 6 PODHD USB driver"); |
ccddbe4a | 192 | MODULE_LICENSE("GPL"); |