613 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Linux driver for M2Tech hiFace compatible devices4 *5 * Copyright 2012-2013 (C) M2TECH S.r.l and Amarula Solutions B.V.6 *7 * Authors: Michael Trimarchi <michael@amarulasolutions.com>8 * Antonio Ospite <ao2@amarulasolutions.com>9 *10 * The driver is based on the work done in TerraTec DMX 6Fire USB11 */12 13#include <linux/slab.h>14#include <sound/pcm.h>15 16#include "pcm.h"17#include "chip.h"18 19#define OUT_EP 0x220#define PCM_N_URBS 821#define PCM_PACKET_SIZE 409622#define PCM_BUFFER_SIZE (2 * PCM_N_URBS * PCM_PACKET_SIZE)23 24struct pcm_urb {25 struct hiface_chip *chip;26 27 struct urb instance;28 struct usb_anchor submitted;29 u8 *buffer;30};31 32struct pcm_substream {33 spinlock_t lock;34 struct snd_pcm_substream *instance;35 36 bool active;37 snd_pcm_uframes_t dma_off; /* current position in alsa dma_area */38 snd_pcm_uframes_t period_off; /* current position in current period */39};40 41enum { /* pcm streaming states */42 STREAM_DISABLED, /* no pcm streaming */43 STREAM_STARTING, /* pcm streaming requested, waiting to become ready */44 STREAM_RUNNING, /* pcm streaming running */45 STREAM_STOPPING46};47 48struct pcm_runtime {49 struct hiface_chip *chip;50 struct snd_pcm *instance;51 52 struct pcm_substream playback;53 bool panic; /* if set driver won't do anymore pcm on device */54 55 struct pcm_urb out_urbs[PCM_N_URBS];56 57 struct mutex stream_mutex;58 u8 stream_state; /* one of STREAM_XXX */59 u8 extra_freq;60 wait_queue_head_t stream_wait_queue;61 bool stream_wait_cond;62};63 64static const unsigned int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000,65 352800, 384000 };66static const struct snd_pcm_hw_constraint_list constraints_extra_rates = {67 .count = ARRAY_SIZE(rates),68 .list = rates,69 .mask = 0,70};71 72static const struct snd_pcm_hardware pcm_hw = {73 .info = SNDRV_PCM_INFO_MMAP |74 SNDRV_PCM_INFO_INTERLEAVED |75 SNDRV_PCM_INFO_BLOCK_TRANSFER |76 SNDRV_PCM_INFO_PAUSE |77 SNDRV_PCM_INFO_MMAP_VALID |78 SNDRV_PCM_INFO_BATCH,79 80 .formats = SNDRV_PCM_FMTBIT_S32_LE,81 82 .rates = SNDRV_PCM_RATE_44100 |83 SNDRV_PCM_RATE_48000 |84 SNDRV_PCM_RATE_88200 |85 SNDRV_PCM_RATE_96000 |86 SNDRV_PCM_RATE_176400 |87 SNDRV_PCM_RATE_192000,88 89 .rate_min = 44100,90 .rate_max = 192000, /* changes in hiface_pcm_open to support extra rates */91 .channels_min = 2,92 .channels_max = 2,93 .buffer_bytes_max = PCM_BUFFER_SIZE,94 .period_bytes_min = PCM_PACKET_SIZE,95 .period_bytes_max = PCM_BUFFER_SIZE,96 .periods_min = 2,97 .periods_max = 102498};99 100/* message values used to change the sample rate */101#define HIFACE_SET_RATE_REQUEST 0xb0102 103#define HIFACE_RATE_44100 0x43104#define HIFACE_RATE_48000 0x4b105#define HIFACE_RATE_88200 0x42106#define HIFACE_RATE_96000 0x4a107#define HIFACE_RATE_176400 0x40108#define HIFACE_RATE_192000 0x48109#define HIFACE_RATE_352800 0x58110#define HIFACE_RATE_384000 0x68111 112static int hiface_pcm_set_rate(struct pcm_runtime *rt, unsigned int rate)113{114 struct usb_device *device = rt->chip->dev;115 u16 rate_value;116 int ret;117 118 /* We are already sure that the rate is supported here thanks to119 * ALSA constraints120 */121 switch (rate) {122 case 44100:123 rate_value = HIFACE_RATE_44100;124 break;125 case 48000:126 rate_value = HIFACE_RATE_48000;127 break;128 case 88200:129 rate_value = HIFACE_RATE_88200;130 break;131 case 96000:132 rate_value = HIFACE_RATE_96000;133 break;134 case 176400:135 rate_value = HIFACE_RATE_176400;136 break;137 case 192000:138 rate_value = HIFACE_RATE_192000;139 break;140 case 352800:141 rate_value = HIFACE_RATE_352800;142 break;143 case 384000:144 rate_value = HIFACE_RATE_384000;145 break;146 default:147 dev_err(&device->dev, "Unsupported rate %d\n", rate);148 return -EINVAL;149 }150 151 /*152 * USBIO: Vendor 0xb0(wValue=0x0043, wIndex=0x0000)153 * 43 b0 43 00 00 00 00 00154 * USBIO: Vendor 0xb0(wValue=0x004b, wIndex=0x0000)155 * 43 b0 4b 00 00 00 00 00156 * This control message doesn't have any ack from the157 * other side158 */159 ret = usb_control_msg_send(device, 0,160 HIFACE_SET_RATE_REQUEST,161 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,162 rate_value, 0, NULL, 0, 100, GFP_KERNEL);163 if (ret)164 dev_err(&device->dev, "Error setting samplerate %d.\n", rate);165 166 return ret;167}168 169static struct pcm_substream *hiface_pcm_get_substream(struct snd_pcm_substream170 *alsa_sub)171{172 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);173 struct device *device = &rt->chip->dev->dev;174 175 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)176 return &rt->playback;177 178 dev_err(device, "Error getting pcm substream slot.\n");179 return NULL;180}181 182/* call with stream_mutex locked */183static void hiface_pcm_stream_stop(struct pcm_runtime *rt)184{185 int i, time;186 187 if (rt->stream_state != STREAM_DISABLED) {188 rt->stream_state = STREAM_STOPPING;189 190 for (i = 0; i < PCM_N_URBS; i++) {191 time = usb_wait_anchor_empty_timeout(192 &rt->out_urbs[i].submitted, 100);193 if (!time)194 usb_kill_anchored_urbs(195 &rt->out_urbs[i].submitted);196 usb_kill_urb(&rt->out_urbs[i].instance);197 }198 199 rt->stream_state = STREAM_DISABLED;200 }201}202 203/* call with stream_mutex locked */204static int hiface_pcm_stream_start(struct pcm_runtime *rt)205{206 int ret = 0;207 int i;208 209 if (rt->stream_state == STREAM_DISABLED) {210 211 /* reset panic state when starting a new stream */212 rt->panic = false;213 214 /* submit our out urbs zero init */215 rt->stream_state = STREAM_STARTING;216 for (i = 0; i < PCM_N_URBS; i++) {217 memset(rt->out_urbs[i].buffer, 0, PCM_PACKET_SIZE);218 usb_anchor_urb(&rt->out_urbs[i].instance,219 &rt->out_urbs[i].submitted);220 ret = usb_submit_urb(&rt->out_urbs[i].instance,221 GFP_ATOMIC);222 if (ret) {223 hiface_pcm_stream_stop(rt);224 return ret;225 }226 }227 228 /* wait for first out urb to return (sent in urb handler) */229 wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond,230 HZ);231 if (rt->stream_wait_cond) {232 struct device *device = &rt->chip->dev->dev;233 dev_dbg(device, "%s: Stream is running wakeup event\n",234 __func__);235 rt->stream_state = STREAM_RUNNING;236 } else {237 hiface_pcm_stream_stop(rt);238 return -EIO;239 }240 }241 return ret;242}243 244/* The hardware wants word-swapped 32-bit values */245static void memcpy_swahw32(u8 *dest, u8 *src, unsigned int n)246{247 unsigned int i;248 249 for (i = 0; i < n / 4; i++)250 ((u32 *)dest)[i] = swahw32(((u32 *)src)[i]);251}252 253/* call with substream locked */254/* returns true if a period elapsed */255static bool hiface_pcm_playback(struct pcm_substream *sub, struct pcm_urb *urb)256{257 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;258 struct device *device = &urb->chip->dev->dev;259 u8 *source;260 unsigned int pcm_buffer_size;261 262 WARN_ON(alsa_rt->format != SNDRV_PCM_FORMAT_S32_LE);263 264 pcm_buffer_size = snd_pcm_lib_buffer_bytes(sub->instance);265 266 if (sub->dma_off + PCM_PACKET_SIZE <= pcm_buffer_size) {267 dev_dbg(device, "%s: (1) buffer_size %#x dma_offset %#x\n", __func__,268 (unsigned int) pcm_buffer_size,269 (unsigned int) sub->dma_off);270 271 source = alsa_rt->dma_area + sub->dma_off;272 memcpy_swahw32(urb->buffer, source, PCM_PACKET_SIZE);273 } else {274 /* wrap around at end of ring buffer */275 unsigned int len;276 277 dev_dbg(device, "%s: (2) buffer_size %#x dma_offset %#x\n", __func__,278 (unsigned int) pcm_buffer_size,279 (unsigned int) sub->dma_off);280 281 len = pcm_buffer_size - sub->dma_off;282 283 source = alsa_rt->dma_area + sub->dma_off;284 memcpy_swahw32(urb->buffer, source, len);285 286 source = alsa_rt->dma_area;287 memcpy_swahw32(urb->buffer + len, source,288 PCM_PACKET_SIZE - len);289 }290 sub->dma_off += PCM_PACKET_SIZE;291 if (sub->dma_off >= pcm_buffer_size)292 sub->dma_off -= pcm_buffer_size;293 294 sub->period_off += PCM_PACKET_SIZE;295 if (sub->period_off >= alsa_rt->period_size) {296 sub->period_off %= alsa_rt->period_size;297 return true;298 }299 return false;300}301 302static void hiface_pcm_out_urb_handler(struct urb *usb_urb)303{304 struct pcm_urb *out_urb = usb_urb->context;305 struct pcm_runtime *rt = out_urb->chip->pcm;306 struct pcm_substream *sub;307 bool do_period_elapsed = false;308 unsigned long flags;309 int ret;310 311 if (rt->panic || rt->stream_state == STREAM_STOPPING)312 return;313 314 if (unlikely(usb_urb->status == -ENOENT || /* unlinked */315 usb_urb->status == -ENODEV || /* device removed */316 usb_urb->status == -ECONNRESET || /* unlinked */317 usb_urb->status == -ESHUTDOWN)) { /* device disabled */318 goto out_fail;319 }320 321 if (rt->stream_state == STREAM_STARTING) {322 rt->stream_wait_cond = true;323 wake_up(&rt->stream_wait_queue);324 }325 326 /* now send our playback data (if a free out urb was found) */327 sub = &rt->playback;328 spin_lock_irqsave(&sub->lock, flags);329 if (sub->active)330 do_period_elapsed = hiface_pcm_playback(sub, out_urb);331 else332 memset(out_urb->buffer, 0, PCM_PACKET_SIZE);333 334 spin_unlock_irqrestore(&sub->lock, flags);335 336 if (do_period_elapsed)337 snd_pcm_period_elapsed(sub->instance);338 339 ret = usb_submit_urb(&out_urb->instance, GFP_ATOMIC);340 if (ret < 0)341 goto out_fail;342 343 return;344 345out_fail:346 rt->panic = true;347}348 349static int hiface_pcm_open(struct snd_pcm_substream *alsa_sub)350{351 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);352 struct pcm_substream *sub = NULL;353 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;354 int ret;355 356 if (rt->panic)357 return -EPIPE;358 359 mutex_lock(&rt->stream_mutex);360 alsa_rt->hw = pcm_hw;361 362 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)363 sub = &rt->playback;364 365 if (!sub) {366 struct device *device = &rt->chip->dev->dev;367 mutex_unlock(&rt->stream_mutex);368 dev_err(device, "Invalid stream type\n");369 return -EINVAL;370 }371 372 if (rt->extra_freq) {373 alsa_rt->hw.rates |= SNDRV_PCM_RATE_KNOT;374 alsa_rt->hw.rate_max = 384000;375 376 /* explicit constraints needed as we added SNDRV_PCM_RATE_KNOT */377 ret = snd_pcm_hw_constraint_list(alsa_sub->runtime, 0,378 SNDRV_PCM_HW_PARAM_RATE,379 &constraints_extra_rates);380 if (ret < 0) {381 mutex_unlock(&rt->stream_mutex);382 return ret;383 }384 }385 386 sub->instance = alsa_sub;387 sub->active = false;388 mutex_unlock(&rt->stream_mutex);389 return 0;390}391 392static int hiface_pcm_close(struct snd_pcm_substream *alsa_sub)393{394 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);395 struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);396 unsigned long flags;397 398 if (rt->panic)399 return 0;400 401 mutex_lock(&rt->stream_mutex);402 if (sub) {403 hiface_pcm_stream_stop(rt);404 405 /* deactivate substream */406 spin_lock_irqsave(&sub->lock, flags);407 sub->instance = NULL;408 sub->active = false;409 spin_unlock_irqrestore(&sub->lock, flags);410 411 }412 mutex_unlock(&rt->stream_mutex);413 return 0;414}415 416static int hiface_pcm_prepare(struct snd_pcm_substream *alsa_sub)417{418 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);419 struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);420 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;421 int ret;422 423 if (rt->panic)424 return -EPIPE;425 if (!sub)426 return -ENODEV;427 428 mutex_lock(&rt->stream_mutex);429 430 hiface_pcm_stream_stop(rt);431 432 sub->dma_off = 0;433 sub->period_off = 0;434 435 if (rt->stream_state == STREAM_DISABLED) {436 437 ret = hiface_pcm_set_rate(rt, alsa_rt->rate);438 if (ret) {439 mutex_unlock(&rt->stream_mutex);440 return ret;441 }442 ret = hiface_pcm_stream_start(rt);443 if (ret) {444 mutex_unlock(&rt->stream_mutex);445 return ret;446 }447 }448 mutex_unlock(&rt->stream_mutex);449 return 0;450}451 452static int hiface_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)453{454 struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);455 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);456 457 if (rt->panic)458 return -EPIPE;459 if (!sub)460 return -ENODEV;461 462 switch (cmd) {463 case SNDRV_PCM_TRIGGER_START:464 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:465 spin_lock_irq(&sub->lock);466 sub->active = true;467 spin_unlock_irq(&sub->lock);468 return 0;469 470 case SNDRV_PCM_TRIGGER_STOP:471 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:472 spin_lock_irq(&sub->lock);473 sub->active = false;474 spin_unlock_irq(&sub->lock);475 return 0;476 477 default:478 return -EINVAL;479 }480}481 482static snd_pcm_uframes_t hiface_pcm_pointer(struct snd_pcm_substream *alsa_sub)483{484 struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);485 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);486 unsigned long flags;487 snd_pcm_uframes_t dma_offset;488 489 if (rt->panic || !sub)490 return SNDRV_PCM_POS_XRUN;491 492 spin_lock_irqsave(&sub->lock, flags);493 dma_offset = sub->dma_off;494 spin_unlock_irqrestore(&sub->lock, flags);495 return bytes_to_frames(alsa_sub->runtime, dma_offset);496}497 498static const struct snd_pcm_ops pcm_ops = {499 .open = hiface_pcm_open,500 .close = hiface_pcm_close,501 .prepare = hiface_pcm_prepare,502 .trigger = hiface_pcm_trigger,503 .pointer = hiface_pcm_pointer,504};505 506static int hiface_pcm_init_urb(struct pcm_urb *urb,507 struct hiface_chip *chip,508 unsigned int ep,509 void (*handler)(struct urb *))510{511 urb->chip = chip;512 usb_init_urb(&urb->instance);513 514 urb->buffer = kzalloc(PCM_PACKET_SIZE, GFP_KERNEL);515 if (!urb->buffer)516 return -ENOMEM;517 518 usb_fill_bulk_urb(&urb->instance, chip->dev,519 usb_sndbulkpipe(chip->dev, ep), (void *)urb->buffer,520 PCM_PACKET_SIZE, handler, urb);521 if (usb_urb_ep_type_check(&urb->instance))522 return -EINVAL;523 init_usb_anchor(&urb->submitted);524 525 return 0;526}527 528void hiface_pcm_abort(struct hiface_chip *chip)529{530 struct pcm_runtime *rt = chip->pcm;531 532 if (rt) {533 rt->panic = true;534 535 mutex_lock(&rt->stream_mutex);536 hiface_pcm_stream_stop(rt);537 mutex_unlock(&rt->stream_mutex);538 }539}540 541static void hiface_pcm_destroy(struct hiface_chip *chip)542{543 struct pcm_runtime *rt = chip->pcm;544 int i;545 546 for (i = 0; i < PCM_N_URBS; i++)547 kfree(rt->out_urbs[i].buffer);548 549 kfree(chip->pcm);550 chip->pcm = NULL;551}552 553static void hiface_pcm_free(struct snd_pcm *pcm)554{555 struct pcm_runtime *rt = pcm->private_data;556 557 if (rt)558 hiface_pcm_destroy(rt->chip);559}560 561int hiface_pcm_init(struct hiface_chip *chip, u8 extra_freq)562{563 int i;564 int ret;565 struct snd_pcm *pcm;566 struct pcm_runtime *rt;567 568 rt = kzalloc(sizeof(*rt), GFP_KERNEL);569 if (!rt)570 return -ENOMEM;571 572 rt->chip = chip;573 rt->stream_state = STREAM_DISABLED;574 if (extra_freq)575 rt->extra_freq = 1;576 577 init_waitqueue_head(&rt->stream_wait_queue);578 mutex_init(&rt->stream_mutex);579 spin_lock_init(&rt->playback.lock);580 581 for (i = 0; i < PCM_N_URBS; i++) {582 ret = hiface_pcm_init_urb(&rt->out_urbs[i], chip, OUT_EP,583 hiface_pcm_out_urb_handler);584 if (ret < 0)585 goto error;586 }587 588 ret = snd_pcm_new(chip->card, "USB-SPDIF Audio", 0, 1, 0, &pcm);589 if (ret < 0) {590 dev_err(&chip->dev->dev, "Cannot create pcm instance\n");591 goto error;592 }593 594 pcm->private_data = rt;595 pcm->private_free = hiface_pcm_free;596 597 strscpy(pcm->name, "USB-SPDIF Audio", sizeof(pcm->name));598 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops);599 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC,600 NULL, 0, 0);601 602 rt->instance = pcm;603 604 chip->pcm = rt;605 return 0;606 607error:608 for (i = 0; i < PCM_N_URBS; i++)609 kfree(rt->out_urbs[i].buffer);610 kfree(rt);611 return ret;612}613