linux/sound/usb/hiface/pcm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Linux driver for M2Tech hiFace compatible devices
   4 *
   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 USB
  11 */
  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          0x2
  20#define PCM_N_URBS      8
  21#define PCM_PACKET_SIZE 4096
  22#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_STOPPING
  46};
  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 = 1024
  98};
  99
 100/* message values used to change the sample rate */
 101#define HIFACE_SET_RATE_REQUEST 0xb0
 102
 103#define HIFACE_RATE_44100  0x43
 104#define HIFACE_RATE_48000  0x4b
 105#define HIFACE_RATE_88200  0x42
 106#define HIFACE_RATE_96000  0x4a
 107#define HIFACE_RATE_176400 0x40
 108#define HIFACE_RATE_192000 0x48
 109#define HIFACE_RATE_352800 0x58
 110#define HIFACE_RATE_384000 0x68
 111
 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 to
 119         * ALSA constraints
 120         */
 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 00
 154         * USBIO: Vendor 0xb0(wValue=0x004b, wIndex=0x0000)
 155         * 43 b0 4b 00 00 00 00 00
 156         * This control message doesn't have any ack from the
 157         * other side
 158         */
 159        ret = usb_control_msg(device, usb_sndctrlpipe(device, 0),
 160                              HIFACE_SET_RATE_REQUEST,
 161                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
 162                              rate_value, 0, NULL, 0, 100);
 163        if (ret < 0) {
 164                dev_err(&device->dev, "Error setting samplerate %d.\n", rate);
 165                return ret;
 166        }
 167
 168        return 0;
 169}
 170
 171static struct pcm_substream *hiface_pcm_get_substream(struct snd_pcm_substream
 172                                                      *alsa_sub)
 173{
 174        struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 175        struct device *device = &rt->chip->dev->dev;
 176
 177        if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
 178                return &rt->playback;
 179
 180        dev_err(device, "Error getting pcm substream slot.\n");
 181        return NULL;
 182}
 183
 184/* call with stream_mutex locked */
 185static void hiface_pcm_stream_stop(struct pcm_runtime *rt)
 186{
 187        int i, time;
 188
 189        if (rt->stream_state != STREAM_DISABLED) {
 190                rt->stream_state = STREAM_STOPPING;
 191
 192                for (i = 0; i < PCM_N_URBS; i++) {
 193                        time = usb_wait_anchor_empty_timeout(
 194                                        &rt->out_urbs[i].submitted, 100);
 195                        if (!time)
 196                                usb_kill_anchored_urbs(
 197                                        &rt->out_urbs[i].submitted);
 198                        usb_kill_urb(&rt->out_urbs[i].instance);
 199                }
 200
 201                rt->stream_state = STREAM_DISABLED;
 202        }
 203}
 204
 205/* call with stream_mutex locked */
 206static int hiface_pcm_stream_start(struct pcm_runtime *rt)
 207{
 208        int ret = 0;
 209        int i;
 210
 211        if (rt->stream_state == STREAM_DISABLED) {
 212
 213                /* reset panic state when starting a new stream */
 214                rt->panic = false;
 215
 216                /* submit our out urbs zero init */
 217                rt->stream_state = STREAM_STARTING;
 218                for (i = 0; i < PCM_N_URBS; i++) {
 219                        memset(rt->out_urbs[i].buffer, 0, PCM_PACKET_SIZE);
 220                        usb_anchor_urb(&rt->out_urbs[i].instance,
 221                                       &rt->out_urbs[i].submitted);
 222                        ret = usb_submit_urb(&rt->out_urbs[i].instance,
 223                                             GFP_ATOMIC);
 224                        if (ret) {
 225                                hiface_pcm_stream_stop(rt);
 226                                return ret;
 227                        }
 228                }
 229
 230                /* wait for first out urb to return (sent in in urb handler) */
 231                wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond,
 232                                   HZ);
 233                if (rt->stream_wait_cond) {
 234                        struct device *device = &rt->chip->dev->dev;
 235                        dev_dbg(device, "%s: Stream is running wakeup event\n",
 236                                 __func__);
 237                        rt->stream_state = STREAM_RUNNING;
 238                } else {
 239                        hiface_pcm_stream_stop(rt);
 240                        return -EIO;
 241                }
 242        }
 243        return ret;
 244}
 245
 246/* The hardware wants word-swapped 32-bit values */
 247static void memcpy_swahw32(u8 *dest, u8 *src, unsigned int n)
 248{
 249        unsigned int i;
 250
 251        for (i = 0; i < n / 4; i++)
 252                ((u32 *)dest)[i] = swahw32(((u32 *)src)[i]);
 253}
 254
 255/* call with substream locked */
 256/* returns true if a period elapsed */
 257static bool hiface_pcm_playback(struct pcm_substream *sub, struct pcm_urb *urb)
 258{
 259        struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
 260        struct device *device = &urb->chip->dev->dev;
 261        u8 *source;
 262        unsigned int pcm_buffer_size;
 263
 264        WARN_ON(alsa_rt->format != SNDRV_PCM_FORMAT_S32_LE);
 265
 266        pcm_buffer_size = snd_pcm_lib_buffer_bytes(sub->instance);
 267
 268        if (sub->dma_off + PCM_PACKET_SIZE <= pcm_buffer_size) {
 269                dev_dbg(device, "%s: (1) buffer_size %#x dma_offset %#x\n", __func__,
 270                         (unsigned int) pcm_buffer_size,
 271                         (unsigned int) sub->dma_off);
 272
 273                source = alsa_rt->dma_area + sub->dma_off;
 274                memcpy_swahw32(urb->buffer, source, PCM_PACKET_SIZE);
 275        } else {
 276                /* wrap around at end of ring buffer */
 277                unsigned int len;
 278
 279                dev_dbg(device, "%s: (2) buffer_size %#x dma_offset %#x\n", __func__,
 280                         (unsigned int) pcm_buffer_size,
 281                         (unsigned int) sub->dma_off);
 282
 283                len = pcm_buffer_size - sub->dma_off;
 284
 285                source = alsa_rt->dma_area + sub->dma_off;
 286                memcpy_swahw32(urb->buffer, source, len);
 287
 288                source = alsa_rt->dma_area;
 289                memcpy_swahw32(urb->buffer + len, source,
 290                               PCM_PACKET_SIZE - len);
 291        }
 292        sub->dma_off += PCM_PACKET_SIZE;
 293        if (sub->dma_off >= pcm_buffer_size)
 294                sub->dma_off -= pcm_buffer_size;
 295
 296        sub->period_off += PCM_PACKET_SIZE;
 297        if (sub->period_off >= alsa_rt->period_size) {
 298                sub->period_off %= alsa_rt->period_size;
 299                return true;
 300        }
 301        return false;
 302}
 303
 304static void hiface_pcm_out_urb_handler(struct urb *usb_urb)
 305{
 306        struct pcm_urb *out_urb = usb_urb->context;
 307        struct pcm_runtime *rt = out_urb->chip->pcm;
 308        struct pcm_substream *sub;
 309        bool do_period_elapsed = false;
 310        unsigned long flags;
 311        int ret;
 312
 313        if (rt->panic || rt->stream_state == STREAM_STOPPING)
 314                return;
 315
 316        if (unlikely(usb_urb->status == -ENOENT ||      /* unlinked */
 317                     usb_urb->status == -ENODEV ||      /* device removed */
 318                     usb_urb->status == -ECONNRESET ||  /* unlinked */
 319                     usb_urb->status == -ESHUTDOWN)) {  /* device disabled */
 320                goto out_fail;
 321        }
 322
 323        if (rt->stream_state == STREAM_STARTING) {
 324                rt->stream_wait_cond = true;
 325                wake_up(&rt->stream_wait_queue);
 326        }
 327
 328        /* now send our playback data (if a free out urb was found) */
 329        sub = &rt->playback;
 330        spin_lock_irqsave(&sub->lock, flags);
 331        if (sub->active)
 332                do_period_elapsed = hiface_pcm_playback(sub, out_urb);
 333        else
 334                memset(out_urb->buffer, 0, PCM_PACKET_SIZE);
 335
 336        spin_unlock_irqrestore(&sub->lock, flags);
 337
 338        if (do_period_elapsed)
 339                snd_pcm_period_elapsed(sub->instance);
 340
 341        ret = usb_submit_urb(&out_urb->instance, GFP_ATOMIC);
 342        if (ret < 0)
 343                goto out_fail;
 344
 345        return;
 346
 347out_fail:
 348        rt->panic = true;
 349}
 350
 351static int hiface_pcm_open(struct snd_pcm_substream *alsa_sub)
 352{
 353        struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 354        struct pcm_substream *sub = NULL;
 355        struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
 356        int ret;
 357
 358        if (rt->panic)
 359                return -EPIPE;
 360
 361        mutex_lock(&rt->stream_mutex);
 362        alsa_rt->hw = pcm_hw;
 363
 364        if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
 365                sub = &rt->playback;
 366
 367        if (!sub) {
 368                struct device *device = &rt->chip->dev->dev;
 369                mutex_unlock(&rt->stream_mutex);
 370                dev_err(device, "Invalid stream type\n");
 371                return -EINVAL;
 372        }
 373
 374        if (rt->extra_freq) {
 375                alsa_rt->hw.rates |= SNDRV_PCM_RATE_KNOT;
 376                alsa_rt->hw.rate_max = 384000;
 377
 378                /* explicit constraints needed as we added SNDRV_PCM_RATE_KNOT */
 379                ret = snd_pcm_hw_constraint_list(alsa_sub->runtime, 0,
 380                                                 SNDRV_PCM_HW_PARAM_RATE,
 381                                                 &constraints_extra_rates);
 382                if (ret < 0) {
 383                        mutex_unlock(&rt->stream_mutex);
 384                        return ret;
 385                }
 386        }
 387
 388        sub->instance = alsa_sub;
 389        sub->active = false;
 390        mutex_unlock(&rt->stream_mutex);
 391        return 0;
 392}
 393
 394static int hiface_pcm_close(struct snd_pcm_substream *alsa_sub)
 395{
 396        struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 397        struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
 398        unsigned long flags;
 399
 400        if (rt->panic)
 401                return 0;
 402
 403        mutex_lock(&rt->stream_mutex);
 404        if (sub) {
 405                hiface_pcm_stream_stop(rt);
 406
 407                /* deactivate substream */
 408                spin_lock_irqsave(&sub->lock, flags);
 409                sub->instance = NULL;
 410                sub->active = false;
 411                spin_unlock_irqrestore(&sub->lock, flags);
 412
 413        }
 414        mutex_unlock(&rt->stream_mutex);
 415        return 0;
 416}
 417
 418static int hiface_pcm_hw_params(struct snd_pcm_substream *alsa_sub,
 419                                struct snd_pcm_hw_params *hw_params)
 420{
 421        return snd_pcm_lib_alloc_vmalloc_buffer(alsa_sub,
 422                                                params_buffer_bytes(hw_params));
 423}
 424
 425static int hiface_pcm_hw_free(struct snd_pcm_substream *alsa_sub)
 426{
 427        return snd_pcm_lib_free_vmalloc_buffer(alsa_sub);
 428}
 429
 430static int hiface_pcm_prepare(struct snd_pcm_substream *alsa_sub)
 431{
 432        struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 433        struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
 434        struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
 435        int ret;
 436
 437        if (rt->panic)
 438                return -EPIPE;
 439        if (!sub)
 440                return -ENODEV;
 441
 442        mutex_lock(&rt->stream_mutex);
 443
 444        hiface_pcm_stream_stop(rt);
 445
 446        sub->dma_off = 0;
 447        sub->period_off = 0;
 448
 449        if (rt->stream_state == STREAM_DISABLED) {
 450
 451                ret = hiface_pcm_set_rate(rt, alsa_rt->rate);
 452                if (ret) {
 453                        mutex_unlock(&rt->stream_mutex);
 454                        return ret;
 455                }
 456                ret = hiface_pcm_stream_start(rt);
 457                if (ret) {
 458                        mutex_unlock(&rt->stream_mutex);
 459                        return ret;
 460                }
 461        }
 462        mutex_unlock(&rt->stream_mutex);
 463        return 0;
 464}
 465
 466static int hiface_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)
 467{
 468        struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
 469        struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 470
 471        if (rt->panic)
 472                return -EPIPE;
 473        if (!sub)
 474                return -ENODEV;
 475
 476        switch (cmd) {
 477        case SNDRV_PCM_TRIGGER_START:
 478        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 479                spin_lock_irq(&sub->lock);
 480                sub->active = true;
 481                spin_unlock_irq(&sub->lock);
 482                return 0;
 483
 484        case SNDRV_PCM_TRIGGER_STOP:
 485        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 486                spin_lock_irq(&sub->lock);
 487                sub->active = false;
 488                spin_unlock_irq(&sub->lock);
 489                return 0;
 490
 491        default:
 492                return -EINVAL;
 493        }
 494}
 495
 496static snd_pcm_uframes_t hiface_pcm_pointer(struct snd_pcm_substream *alsa_sub)
 497{
 498        struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
 499        struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 500        unsigned long flags;
 501        snd_pcm_uframes_t dma_offset;
 502
 503        if (rt->panic || !sub)
 504                return SNDRV_PCM_POS_XRUN;
 505
 506        spin_lock_irqsave(&sub->lock, flags);
 507        dma_offset = sub->dma_off;
 508        spin_unlock_irqrestore(&sub->lock, flags);
 509        return bytes_to_frames(alsa_sub->runtime, dma_offset);
 510}
 511
 512static const struct snd_pcm_ops pcm_ops = {
 513        .open = hiface_pcm_open,
 514        .close = hiface_pcm_close,
 515        .ioctl = snd_pcm_lib_ioctl,
 516        .hw_params = hiface_pcm_hw_params,
 517        .hw_free = hiface_pcm_hw_free,
 518        .prepare = hiface_pcm_prepare,
 519        .trigger = hiface_pcm_trigger,
 520        .pointer = hiface_pcm_pointer,
 521        .page = snd_pcm_lib_get_vmalloc_page,
 522};
 523
 524static int hiface_pcm_init_urb(struct pcm_urb *urb,
 525                               struct hiface_chip *chip,
 526                               unsigned int ep,
 527                               void (*handler)(struct urb *))
 528{
 529        urb->chip = chip;
 530        usb_init_urb(&urb->instance);
 531
 532        urb->buffer = kzalloc(PCM_PACKET_SIZE, GFP_KERNEL);
 533        if (!urb->buffer)
 534                return -ENOMEM;
 535
 536        usb_fill_bulk_urb(&urb->instance, chip->dev,
 537                          usb_sndbulkpipe(chip->dev, ep), (void *)urb->buffer,
 538                          PCM_PACKET_SIZE, handler, urb);
 539        if (usb_urb_ep_type_check(&urb->instance))
 540                return -EINVAL;
 541        init_usb_anchor(&urb->submitted);
 542
 543        return 0;
 544}
 545
 546void hiface_pcm_abort(struct hiface_chip *chip)
 547{
 548        struct pcm_runtime *rt = chip->pcm;
 549
 550        if (rt) {
 551                rt->panic = true;
 552
 553                mutex_lock(&rt->stream_mutex);
 554                hiface_pcm_stream_stop(rt);
 555                mutex_unlock(&rt->stream_mutex);
 556        }
 557}
 558
 559static void hiface_pcm_destroy(struct hiface_chip *chip)
 560{
 561        struct pcm_runtime *rt = chip->pcm;
 562        int i;
 563
 564        for (i = 0; i < PCM_N_URBS; i++)
 565                kfree(rt->out_urbs[i].buffer);
 566
 567        kfree(chip->pcm);
 568        chip->pcm = NULL;
 569}
 570
 571static void hiface_pcm_free(struct snd_pcm *pcm)
 572{
 573        struct pcm_runtime *rt = pcm->private_data;
 574
 575        if (rt)
 576                hiface_pcm_destroy(rt->chip);
 577}
 578
 579int hiface_pcm_init(struct hiface_chip *chip, u8 extra_freq)
 580{
 581        int i;
 582        int ret;
 583        struct snd_pcm *pcm;
 584        struct pcm_runtime *rt;
 585
 586        rt = kzalloc(sizeof(*rt), GFP_KERNEL);
 587        if (!rt)
 588                return -ENOMEM;
 589
 590        rt->chip = chip;
 591        rt->stream_state = STREAM_DISABLED;
 592        if (extra_freq)
 593                rt->extra_freq = 1;
 594
 595        init_waitqueue_head(&rt->stream_wait_queue);
 596        mutex_init(&rt->stream_mutex);
 597        spin_lock_init(&rt->playback.lock);
 598
 599        for (i = 0; i < PCM_N_URBS; i++) {
 600                ret = hiface_pcm_init_urb(&rt->out_urbs[i], chip, OUT_EP,
 601                                    hiface_pcm_out_urb_handler);
 602                if (ret < 0)
 603                        goto error;
 604        }
 605
 606        ret = snd_pcm_new(chip->card, "USB-SPDIF Audio", 0, 1, 0, &pcm);
 607        if (ret < 0) {
 608                dev_err(&chip->dev->dev, "Cannot create pcm instance\n");
 609                goto error;
 610        }
 611
 612        pcm->private_data = rt;
 613        pcm->private_free = hiface_pcm_free;
 614
 615        strlcpy(pcm->name, "USB-SPDIF Audio", sizeof(pcm->name));
 616        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops);
 617
 618        rt->instance = pcm;
 619
 620        chip->pcm = rt;
 621        return 0;
 622
 623error:
 624        for (i = 0; i < PCM_N_URBS; i++)
 625                kfree(rt->out_urbs[i].buffer);
 626        kfree(rt);
 627        return ret;
 628}
 629