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_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_substream
 170                                                      *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 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        else
 332                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        strlcpy(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