440 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Line 6 Linux USB driver4 *5 * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.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*/21static 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*/65static 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*/108static 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 here132 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 context139*/140static 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 } else226 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 else276 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 context285 */286int 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*/302static 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_WORKAROUND314 memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);315#endif316 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 */370static 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 */386static int snd_line6_playback_close(struct snd_pcm_substream *substream)387{388 return 0;389}390 391/* playback operators */392const 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 402int 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