1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Line 6 Linux USB driver 4 * 5 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 6 */ 7 8 #include <linux/slab.h> 9 #include <sound/core.h> 10 #include <sound/pcm.h> 11 #include <sound/pcm_params.h> 12 13 #include "capture.h" 14 #include "driver.h" 15 #include "pcm.h" 16 #include "playback.h" 17 18 /* 19 Software stereo volume control. 20 */ 21 static void change_volume(struct urb *urb_out, int volume[], 22 int bytes_per_frame) 23 { 24 int chn = 0; 25 26 if (volume[0] == 256 && volume[1] == 256) 27 return; /* maximum volume - no change */ 28 29 if (bytes_per_frame == 4) { 30 __le16 *p, *buf_end; 31 32 p = (__le16 *)urb_out->transfer_buffer; 33 buf_end = p + urb_out->transfer_buffer_length / sizeof(*p); 34 35 for (; p < buf_end; ++p) { 36 short pv = le16_to_cpu(*p); 37 int val = (pv * volume[chn & 1]) >> 8; 38 pv = clamp(val, -0x8000, 0x7fff); 39 *p = cpu_to_le16(pv); 40 ++chn; 41 } 42 } else if (bytes_per_frame == 6) { 43 unsigned char *p, *buf_end; 44 45 p = (unsigned char *)urb_out->transfer_buffer; 46 buf_end = p + urb_out->transfer_buffer_length; 47 48 for (; p < buf_end; p += 3) { 49 int val; 50 51 val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16); 52 val = (val * volume[chn & 1]) >> 8; 53 val = clamp(val, -0x800000, 0x7fffff); 54 p[0] = val; 55 p[1] = val >> 8; 56 p[2] = val >> 16; 57 ++chn; 58 } 59 } 60 } 61 62 /* 63 Create signal for impulse response test. 64 */ 65 static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm, 66 struct urb *urb_out, int bytes_per_frame) 67 { 68 int frames = urb_out->transfer_buffer_length / bytes_per_frame; 69 70 if (bytes_per_frame == 4) { 71 int i; 72 short *pi = (short *)line6pcm->prev_fbuf; 73 short *po = (short *)urb_out->transfer_buffer; 74 75 for (i = 0; i < frames; ++i) { 76 po[0] = pi[0]; 77 po[1] = 0; 78 pi += 2; 79 po += 2; 80 } 81 } else if (bytes_per_frame == 6) { 82 int i, j; 83 unsigned char *pi = line6pcm->prev_fbuf; 84 unsigned char *po = urb_out->transfer_buffer; 85 86 for (i = 0; i < frames; ++i) { 87 for (j = 0; j < bytes_per_frame / 2; ++j) 88 po[j] = pi[j]; 89 90 for (; j < bytes_per_frame; ++j) 91 po[j] = 0; 92 93 pi += bytes_per_frame; 94 po += bytes_per_frame; 95 } 96 } 97 if (--line6pcm->impulse_count <= 0) { 98 ((unsigned char *)(urb_out->transfer_buffer))[bytes_per_frame - 99 1] = 100 line6pcm->impulse_volume; 101 line6pcm->impulse_count = line6pcm->impulse_period; 102 } 103 } 104 105 /* 106 Add signal to buffer for software monitoring. 107 */ 108 static void add_monitor_signal(struct urb *urb_out, unsigned char *signal, 109 int volume, int bytes_per_frame) 110 { 111 if (volume == 0) 112 return; /* zero volume - no change */ 113 114 if (bytes_per_frame == 4) { 115 __le16 *pi, *po, *buf_end; 116 117 pi = (__le16 *)signal; 118 po = (__le16 *)urb_out->transfer_buffer; 119 buf_end = po + urb_out->transfer_buffer_length / sizeof(*po); 120 121 for (; po < buf_end; ++pi, ++po) { 122 short pov = le16_to_cpu(*po); 123 short piv = le16_to_cpu(*pi); 124 int val = pov + ((piv * volume) >> 8); 125 pov = clamp(val, -0x8000, 0x7fff); 126 *po = cpu_to_le16(pov); 127 } 128 } 129 130 /* 131 We don't need to handle devices with 6 bytes per frame here 132 since they all support hardware monitoring. 133 */ 134 } 135 136 /* 137 Find a free URB, prepare audio data, and submit URB. 138 must be called in line6pcm->out.lock context 139 */ 140 static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) 141 { 142 int index; 143 int i, urb_size, urb_frames; 144 int ret; 145 const int bytes_per_frame = 146 line6pcm->properties->bytes_per_channel * 147 line6pcm->properties->playback_hw.channels_max; 148 const int frame_increment = 149 line6pcm->properties->rates.rats[0].num_min; 150 const int frame_factor = 151 line6pcm->properties->rates.rats[0].den * 152 (line6pcm->line6->intervals_per_second / LINE6_ISO_INTERVAL); 153 struct urb *urb_out; 154 155 index = find_first_zero_bit(&line6pcm->out.active_urbs, 156 line6pcm->line6->iso_buffers); 157 158 if (index < 0 || index >= line6pcm->line6->iso_buffers) { 159 dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); 160 return -EINVAL; 161 } 162 163 urb_out = line6pcm->out.urbs[index]; 164 urb_size = 0; 165 166 /* TODO: this may not work for LINE6_ISO_PACKETS != 1 */ 167 for (i = 0; i < LINE6_ISO_PACKETS; ++i) { 168 /* compute frame size for given sampling rate */ 169 int fsize = 0; 170 struct usb_iso_packet_descriptor *fout = 171 &urb_out->iso_frame_desc[i]; 172 173 fsize = line6pcm->prev_fsize; 174 if (fsize == 0) { 175 int n; 176 177 line6pcm->out.count += frame_increment; 178 n = line6pcm->out.count / frame_factor; 179 line6pcm->out.count -= n * frame_factor; 180 fsize = n; 181 } 182 183 fsize *= bytes_per_frame; 184 185 fout->offset = urb_size; 186 fout->length = fsize; 187 urb_size += fsize; 188 } 189 190 if (urb_size == 0) { 191 /* can't determine URB size */ 192 dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n"); 193 return -EINVAL; 194 } 195 196 urb_frames = urb_size / bytes_per_frame; 197 urb_out->transfer_buffer = 198 line6pcm->out.buffer + 199 index * LINE6_ISO_PACKETS * line6pcm->max_packet_size_out; 200 urb_out->transfer_buffer_length = urb_size; 201 urb_out->context = line6pcm; 202 203 if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running) && 204 !test_bit(LINE6_FLAG_PAUSE_PLAYBACK, &line6pcm->flags)) { 205 struct snd_pcm_runtime *runtime = 206 get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime; 207 208 if (line6pcm->out.pos + urb_frames > runtime->buffer_size) { 209 /* 210 The transferred area goes over buffer boundary, 211 copy the data to the temp buffer. 212 */ 213 int len; 214 215 len = runtime->buffer_size - line6pcm->out.pos; 216 217 if (len > 0) { 218 memcpy(urb_out->transfer_buffer, 219 runtime->dma_area + 220 line6pcm->out.pos * bytes_per_frame, 221 len * bytes_per_frame); 222 memcpy(urb_out->transfer_buffer + 223 len * bytes_per_frame, runtime->dma_area, 224 (urb_frames - len) * bytes_per_frame); 225 } else 226 dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", 227 len); 228 } else { 229 memcpy(urb_out->transfer_buffer, 230 runtime->dma_area + 231 line6pcm->out.pos * bytes_per_frame, 232 urb_out->transfer_buffer_length); 233 } 234 235 line6pcm->out.pos += urb_frames; 236 if (line6pcm->out.pos >= runtime->buffer_size) 237 line6pcm->out.pos -= runtime->buffer_size; 238 239 change_volume(urb_out, line6pcm->volume_playback, 240 bytes_per_frame); 241 } else { 242 memset(urb_out->transfer_buffer, 0, 243 urb_out->transfer_buffer_length); 244 } 245 246 spin_lock_nested(&line6pcm->in.lock, SINGLE_DEPTH_NESTING); 247 if (line6pcm->prev_fbuf) { 248 if (test_bit(LINE6_STREAM_IMPULSE, &line6pcm->out.running)) { 249 create_impulse_test_signal(line6pcm, urb_out, 250 bytes_per_frame); 251 if (test_bit(LINE6_STREAM_PCM, &line6pcm->in.running)) { 252 line6_capture_copy(line6pcm, 253 urb_out->transfer_buffer, 254 urb_out-> 255 transfer_buffer_length); 256 line6_capture_check_period(line6pcm, 257 urb_out->transfer_buffer_length); 258 } 259 } else { 260 if (!(line6pcm->line6->properties->capabilities & LINE6_CAP_HWMON) 261 && line6pcm->out.running && line6pcm->in.running) 262 add_monitor_signal(urb_out, line6pcm->prev_fbuf, 263 line6pcm->volume_monitor, 264 bytes_per_frame); 265 } 266 line6pcm->prev_fbuf = NULL; 267 line6pcm->prev_fsize = 0; 268 } 269 spin_unlock(&line6pcm->in.lock); 270 271 ret = usb_submit_urb(urb_out, GFP_ATOMIC); 272 273 if (ret == 0) 274 set_bit(index, &line6pcm->out.active_urbs); 275 else 276 dev_err(line6pcm->line6->ifcdev, 277 "URB out #%d submission failed (%d)\n", index, ret); 278 279 return 0; 280 } 281 282 /* 283 Submit all currently available playback URBs. 284 must be called in line6pcm->out.lock context 285 */ 286 int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm) 287 { 288 int ret = 0, i; 289 290 for (i = 0; i < line6pcm->line6->iso_buffers; ++i) { 291 ret = submit_audio_out_urb(line6pcm); 292 if (ret < 0) 293 break; 294 } 295 296 return ret; 297 } 298 299 /* 300 Callback for completed playback URB. 301 */ 302 static void audio_out_callback(struct urb *urb) 303 { 304 int i, index, length = 0, shutdown = 0; 305 unsigned long flags; 306 struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context; 307 struct snd_pcm_substream *substream = 308 get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK); 309 const int bytes_per_frame = 310 line6pcm->properties->bytes_per_channel * 311 line6pcm->properties->playback_hw.channels_max; 312 313 #if USE_CLEAR_BUFFER_WORKAROUND 314 memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); 315 #endif 316 317 line6pcm->out.last_frame = urb->start_frame; 318 319 /* find index of URB */ 320 for (index = 0; index < line6pcm->line6->iso_buffers; index++) 321 if (urb == line6pcm->out.urbs[index]) 322 break; 323 324 if (index >= line6pcm->line6->iso_buffers) 325 return; /* URB has been unlinked asynchronously */ 326 327 for (i = 0; i < LINE6_ISO_PACKETS; i++) 328 length += urb->iso_frame_desc[i].length; 329 330 spin_lock_irqsave(&line6pcm->out.lock, flags); 331 332 if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running)) { 333 struct snd_pcm_runtime *runtime = substream->runtime; 334 335 line6pcm->out.pos_done += 336 length / bytes_per_frame; 337 338 if (line6pcm->out.pos_done >= runtime->buffer_size) 339 line6pcm->out.pos_done -= runtime->buffer_size; 340 } 341 342 clear_bit(index, &line6pcm->out.active_urbs); 343 344 for (i = 0; i < LINE6_ISO_PACKETS; i++) 345 if (urb->iso_frame_desc[i].status == -EXDEV) { 346 shutdown = 1; 347 break; 348 } 349 350 if (test_and_clear_bit(index, &line6pcm->out.unlink_urbs)) 351 shutdown = 1; 352 353 if (!shutdown) { 354 submit_audio_out_urb(line6pcm); 355 356 if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running)) { 357 line6pcm->out.bytes += length; 358 if (line6pcm->out.bytes >= line6pcm->out.period) { 359 line6pcm->out.bytes %= line6pcm->out.period; 360 spin_unlock(&line6pcm->out.lock); 361 snd_pcm_period_elapsed(substream); 362 spin_lock(&line6pcm->out.lock); 363 } 364 } 365 } 366 spin_unlock_irqrestore(&line6pcm->out.lock, flags); 367 } 368 369 /* open playback callback */ 370 static int snd_line6_playback_open(struct snd_pcm_substream *substream) 371 { 372 int err; 373 struct snd_pcm_runtime *runtime = substream->runtime; 374 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 375 376 err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 377 &line6pcm->properties->rates); 378 if (err < 0) 379 return err; 380 381 runtime->hw = line6pcm->properties->playback_hw; 382 return 0; 383 } 384 385 /* close playback callback */ 386 static int snd_line6_playback_close(struct snd_pcm_substream *substream) 387 { 388 return 0; 389 } 390 391 /* playback operators */ 392 const struct snd_pcm_ops snd_line6_playback_ops = { 393 .open = snd_line6_playback_open, 394 .close = snd_line6_playback_close, 395 .hw_params = snd_line6_hw_params, 396 .hw_free = snd_line6_hw_free, 397 .prepare = snd_line6_prepare, 398 .trigger = snd_line6_trigger, 399 .pointer = snd_line6_pointer, 400 }; 401 402 int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) 403 { 404 struct usb_line6 *line6 = line6pcm->line6; 405 int i; 406 407 line6pcm->out.urbs = kcalloc(line6->iso_buffers, sizeof(struct urb *), 408 GFP_KERNEL); 409 if (line6pcm->out.urbs == NULL) 410 return -ENOMEM; 411 412 /* create audio URBs and fill in constant values: */ 413 for (i = 0; i < line6->iso_buffers; ++i) { 414 struct urb *urb; 415 416 /* URB for audio out: */ 417 urb = line6pcm->out.urbs[i] = 418 usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); 419 420 if (urb == NULL) 421 return -ENOMEM; 422 423 urb->dev = line6->usbdev; 424 urb->pipe = 425 usb_sndisocpipe(line6->usbdev, 426 line6->properties->ep_audio_w & 427 USB_ENDPOINT_NUMBER_MASK); 428 urb->transfer_flags = URB_ISO_ASAP; 429 urb->start_frame = -1; 430 urb->number_of_packets = LINE6_ISO_PACKETS; 431 urb->interval = LINE6_ISO_INTERVAL; 432 urb->error_count = 0; 433 urb->complete = audio_out_callback; 434 if (usb_urb_ep_type_check(urb)) 435 return -EINVAL; 436 } 437 438 return 0; 439 } 440
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.