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