linux/drivers/media/pci/tw686x/tw686x-audio.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2015 VanguardiaSur - www.vanguardiasur.com.ar
   4 *
   5 * Based on the audio support from the tw6869 driver:
   6 * Copyright 2015 www.starterkit.ru <info@starterkit.ru>
   7 *
   8 * Based on:
   9 * Driver for Intersil|Techwell TW6869 based DVR cards
  10 * (c) 2011-12 liran <jli11@intersil.com> [Intersil|Techwell China]
  11 */
  12
  13#include <linux/types.h>
  14#include <linux/kernel.h>
  15#include <linux/module.h>
  16#include <linux/init.h>
  17#include <linux/kmod.h>
  18#include <linux/mutex.h>
  19#include <linux/pci.h>
  20#include <linux/delay.h>
  21
  22#include <sound/core.h>
  23#include <sound/initval.h>
  24#include <sound/pcm.h>
  25#include <sound/control.h>
  26#include "tw686x.h"
  27#include "tw686x-regs.h"
  28
  29#define AUDIO_CHANNEL_OFFSET 8
  30
  31void tw686x_audio_irq(struct tw686x_dev *dev, unsigned long requests,
  32                      unsigned int pb_status)
  33{
  34        unsigned long flags;
  35        unsigned int ch, pb;
  36
  37        for_each_set_bit(ch, &requests, max_channels(dev)) {
  38                struct tw686x_audio_channel *ac = &dev->audio_channels[ch];
  39                struct tw686x_audio_buf *done = NULL;
  40                struct tw686x_audio_buf *next = NULL;
  41                struct tw686x_dma_desc *desc;
  42
  43                pb = !!(pb_status & BIT(AUDIO_CHANNEL_OFFSET + ch));
  44
  45                spin_lock_irqsave(&ac->lock, flags);
  46
  47                /* Sanity check */
  48                if (!ac->ss || !ac->curr_bufs[0] || !ac->curr_bufs[1]) {
  49                        spin_unlock_irqrestore(&ac->lock, flags);
  50                        continue;
  51                }
  52
  53                if (!list_empty(&ac->buf_list)) {
  54                        next = list_first_entry(&ac->buf_list,
  55                                        struct tw686x_audio_buf, list);
  56                        list_move_tail(&next->list, &ac->buf_list);
  57                        done = ac->curr_bufs[!pb];
  58                        ac->curr_bufs[pb] = next;
  59                }
  60                spin_unlock_irqrestore(&ac->lock, flags);
  61
  62                if (!done || !next)
  63                        continue;
  64                /*
  65                 * Checking for a non-nil dma_desc[pb]->virt buffer is
  66                 * the same as checking for memcpy DMA mode.
  67                 */
  68                desc = &ac->dma_descs[pb];
  69                if (desc->virt) {
  70                        memcpy(done->virt, desc->virt,
  71                               dev->period_size);
  72                } else {
  73                        u32 reg = pb ? ADMA_B_ADDR[ch] : ADMA_P_ADDR[ch];
  74                        reg_write(dev, reg, next->dma);
  75                }
  76                ac->ptr = done->dma - ac->buf[0].dma;
  77                snd_pcm_period_elapsed(ac->ss);
  78        }
  79}
  80
  81/*
  82 * Audio parameters are global and shared among all
  83 * capture channels. The driver prevents changes to
  84 * the parameters if any audio channel is capturing.
  85 */
  86static const struct snd_pcm_hardware tw686x_capture_hw = {
  87        .info                   = (SNDRV_PCM_INFO_MMAP |
  88                                   SNDRV_PCM_INFO_INTERLEAVED |
  89                                   SNDRV_PCM_INFO_BLOCK_TRANSFER |
  90                                   SNDRV_PCM_INFO_MMAP_VALID),
  91        .formats                = SNDRV_PCM_FMTBIT_S16_LE,
  92        .rates                  = SNDRV_PCM_RATE_8000_48000,
  93        .rate_min               = 8000,
  94        .rate_max               = 48000,
  95        .channels_min           = 1,
  96        .channels_max           = 1,
  97        .buffer_bytes_max       = TW686X_AUDIO_PAGE_MAX * AUDIO_DMA_SIZE_MAX,
  98        .period_bytes_min       = AUDIO_DMA_SIZE_MIN,
  99        .period_bytes_max       = AUDIO_DMA_SIZE_MAX,
 100        .periods_min            = TW686X_AUDIO_PERIODS_MIN,
 101        .periods_max            = TW686X_AUDIO_PERIODS_MAX,
 102};
 103
 104static int tw686x_pcm_open(struct snd_pcm_substream *ss)
 105{
 106        struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
 107        struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
 108        struct snd_pcm_runtime *rt = ss->runtime;
 109        int err;
 110
 111        ac->ss = ss;
 112        rt->hw = tw686x_capture_hw;
 113
 114        err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
 115        if (err < 0)
 116                return err;
 117
 118        return 0;
 119}
 120
 121static int tw686x_pcm_close(struct snd_pcm_substream *ss)
 122{
 123        struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
 124        struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
 125
 126        ac->ss = NULL;
 127        return 0;
 128}
 129
 130static int tw686x_pcm_prepare(struct snd_pcm_substream *ss)
 131{
 132        struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
 133        struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
 134        struct snd_pcm_runtime *rt = ss->runtime;
 135        unsigned int period_size = snd_pcm_lib_period_bytes(ss);
 136        struct tw686x_audio_buf *p_buf, *b_buf;
 137        unsigned long flags;
 138        int i;
 139
 140        spin_lock_irqsave(&dev->lock, flags);
 141        /*
 142         * Given the audio parameters are global (i.e. shared across
 143         * DMA channels), we need to check new params are allowed.
 144         */
 145        if (((dev->audio_rate != rt->rate) ||
 146             (dev->period_size != period_size)) && dev->audio_enabled)
 147                goto err_audio_busy;
 148
 149        tw686x_disable_channel(dev, AUDIO_CHANNEL_OFFSET + ac->ch);
 150        spin_unlock_irqrestore(&dev->lock, flags);
 151
 152        if (dev->audio_rate != rt->rate) {
 153                u32 reg;
 154
 155                dev->audio_rate = rt->rate;
 156                reg = ((125000000 / rt->rate) << 16) +
 157                       ((125000000 % rt->rate) << 16) / rt->rate;
 158
 159                reg_write(dev, AUDIO_CONTROL2, reg);
 160        }
 161
 162        if (dev->period_size != period_size) {
 163                u32 reg;
 164
 165                dev->period_size = period_size;
 166                reg = reg_read(dev, AUDIO_CONTROL1);
 167                reg &= ~(AUDIO_DMA_SIZE_MASK << AUDIO_DMA_SIZE_SHIFT);
 168                reg |= period_size << AUDIO_DMA_SIZE_SHIFT;
 169
 170                reg_write(dev, AUDIO_CONTROL1, reg);
 171        }
 172
 173        if (rt->periods < TW686X_AUDIO_PERIODS_MIN ||
 174            rt->periods > TW686X_AUDIO_PERIODS_MAX)
 175                return -EINVAL;
 176
 177        spin_lock_irqsave(&ac->lock, flags);
 178        INIT_LIST_HEAD(&ac->buf_list);
 179
 180        for (i = 0; i < rt->periods; i++) {
 181                ac->buf[i].dma = rt->dma_addr + period_size * i;
 182                ac->buf[i].virt = rt->dma_area + period_size * i;
 183                INIT_LIST_HEAD(&ac->buf[i].list);
 184                list_add_tail(&ac->buf[i].list, &ac->buf_list);
 185        }
 186
 187        p_buf = list_first_entry(&ac->buf_list, struct tw686x_audio_buf, list);
 188        list_move_tail(&p_buf->list, &ac->buf_list);
 189
 190        b_buf = list_first_entry(&ac->buf_list, struct tw686x_audio_buf, list);
 191        list_move_tail(&b_buf->list, &ac->buf_list);
 192
 193        ac->curr_bufs[0] = p_buf;
 194        ac->curr_bufs[1] = b_buf;
 195        ac->ptr = 0;
 196
 197        if (dev->dma_mode != TW686X_DMA_MODE_MEMCPY) {
 198                reg_write(dev, ADMA_P_ADDR[ac->ch], p_buf->dma);
 199                reg_write(dev, ADMA_B_ADDR[ac->ch], b_buf->dma);
 200        }
 201
 202        spin_unlock_irqrestore(&ac->lock, flags);
 203
 204        return 0;
 205
 206err_audio_busy:
 207        spin_unlock_irqrestore(&dev->lock, flags);
 208        return -EBUSY;
 209}
 210
 211static int tw686x_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
 212{
 213        struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
 214        struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
 215        unsigned long flags;
 216        int err = 0;
 217
 218        switch (cmd) {
 219        case SNDRV_PCM_TRIGGER_START:
 220                if (ac->curr_bufs[0] && ac->curr_bufs[1]) {
 221                        spin_lock_irqsave(&dev->lock, flags);
 222                        dev->audio_enabled = 1;
 223                        tw686x_enable_channel(dev,
 224                                AUDIO_CHANNEL_OFFSET + ac->ch);
 225                        spin_unlock_irqrestore(&dev->lock, flags);
 226
 227                        mod_timer(&dev->dma_delay_timer,
 228                                  jiffies + msecs_to_jiffies(100));
 229                } else {
 230                        err = -EIO;
 231                }
 232                break;
 233        case SNDRV_PCM_TRIGGER_STOP:
 234                spin_lock_irqsave(&dev->lock, flags);
 235                dev->audio_enabled = 0;
 236                tw686x_disable_channel(dev, AUDIO_CHANNEL_OFFSET + ac->ch);
 237                spin_unlock_irqrestore(&dev->lock, flags);
 238
 239                spin_lock_irqsave(&ac->lock, flags);
 240                ac->curr_bufs[0] = NULL;
 241                ac->curr_bufs[1] = NULL;
 242                spin_unlock_irqrestore(&ac->lock, flags);
 243                break;
 244        default:
 245                err = -EINVAL;
 246        }
 247        return err;
 248}
 249
 250static snd_pcm_uframes_t tw686x_pcm_pointer(struct snd_pcm_substream *ss)
 251{
 252        struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
 253        struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
 254
 255        return bytes_to_frames(ss->runtime, ac->ptr);
 256}
 257
 258static const struct snd_pcm_ops tw686x_pcm_ops = {
 259        .open = tw686x_pcm_open,
 260        .close = tw686x_pcm_close,
 261        .prepare = tw686x_pcm_prepare,
 262        .trigger = tw686x_pcm_trigger,
 263        .pointer = tw686x_pcm_pointer,
 264};
 265
 266static int tw686x_snd_pcm_init(struct tw686x_dev *dev)
 267{
 268        struct snd_card *card = dev->snd_card;
 269        struct snd_pcm *pcm;
 270        struct snd_pcm_substream *ss;
 271        unsigned int i;
 272        int err;
 273
 274        err = snd_pcm_new(card, card->driver, 0, 0, max_channels(dev), &pcm);
 275        if (err < 0)
 276                return err;
 277
 278        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &tw686x_pcm_ops);
 279        snd_pcm_chip(pcm) = dev;
 280        pcm->info_flags = 0;
 281        strscpy(pcm->name, "tw686x PCM", sizeof(pcm->name));
 282
 283        for (i = 0, ss = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
 284             ss; ss = ss->next, i++)
 285                snprintf(ss->name, sizeof(ss->name), "vch%u audio", i);
 286
 287        snd_pcm_set_managed_buffer_all(pcm,
 288                                SNDRV_DMA_TYPE_DEV,
 289                                &dev->pci_dev->dev,
 290                                TW686X_AUDIO_PAGE_MAX * AUDIO_DMA_SIZE_MAX,
 291                                TW686X_AUDIO_PAGE_MAX * AUDIO_DMA_SIZE_MAX);
 292        return 0;
 293}
 294
 295static void tw686x_audio_dma_free(struct tw686x_dev *dev,
 296                                  struct tw686x_audio_channel *ac)
 297{
 298        int pb;
 299
 300        for (pb = 0; pb < 2; pb++) {
 301                if (!ac->dma_descs[pb].virt)
 302                        continue;
 303                pci_free_consistent(dev->pci_dev, ac->dma_descs[pb].size,
 304                                    ac->dma_descs[pb].virt,
 305                                    ac->dma_descs[pb].phys);
 306                ac->dma_descs[pb].virt = NULL;
 307        }
 308}
 309
 310static int tw686x_audio_dma_alloc(struct tw686x_dev *dev,
 311                                  struct tw686x_audio_channel *ac)
 312{
 313        int pb;
 314
 315        /*
 316         * In the memcpy DMA mode we allocate a consistent buffer
 317         * and use it for the DMA capture. Otherwise, DMA
 318         * acts on the ALSA buffers as received in pcm_prepare.
 319         */
 320        if (dev->dma_mode != TW686X_DMA_MODE_MEMCPY)
 321                return 0;
 322
 323        for (pb = 0; pb < 2; pb++) {
 324                u32 reg = pb ? ADMA_B_ADDR[ac->ch] : ADMA_P_ADDR[ac->ch];
 325                void *virt;
 326
 327                virt = pci_alloc_consistent(dev->pci_dev, AUDIO_DMA_SIZE_MAX,
 328                                            &ac->dma_descs[pb].phys);
 329                if (!virt) {
 330                        dev_err(&dev->pci_dev->dev,
 331                                "dma%d: unable to allocate audio DMA %s-buffer\n",
 332                                ac->ch, pb ? "B" : "P");
 333                        return -ENOMEM;
 334                }
 335                ac->dma_descs[pb].virt = virt;
 336                ac->dma_descs[pb].size = AUDIO_DMA_SIZE_MAX;
 337                reg_write(dev, reg, ac->dma_descs[pb].phys);
 338        }
 339        return 0;
 340}
 341
 342void tw686x_audio_free(struct tw686x_dev *dev)
 343{
 344        unsigned long flags;
 345        u32 dma_ch_mask;
 346        u32 dma_cmd;
 347
 348        spin_lock_irqsave(&dev->lock, flags);
 349        dma_cmd = reg_read(dev, DMA_CMD);
 350        dma_ch_mask = reg_read(dev, DMA_CHANNEL_ENABLE);
 351        reg_write(dev, DMA_CMD, dma_cmd & ~0xff00);
 352        reg_write(dev, DMA_CHANNEL_ENABLE, dma_ch_mask & ~0xff00);
 353        spin_unlock_irqrestore(&dev->lock, flags);
 354
 355        if (!dev->snd_card)
 356                return;
 357        snd_card_free(dev->snd_card);
 358        dev->snd_card = NULL;
 359}
 360
 361int tw686x_audio_init(struct tw686x_dev *dev)
 362{
 363        struct pci_dev *pci_dev = dev->pci_dev;
 364        struct snd_card *card;
 365        int err, ch;
 366
 367        /* Enable external audio */
 368        reg_write(dev, AUDIO_CONTROL1, BIT(0));
 369
 370        err = snd_card_new(&pci_dev->dev, SNDRV_DEFAULT_IDX1,
 371                           SNDRV_DEFAULT_STR1,
 372                           THIS_MODULE, 0, &card);
 373        if (err < 0)
 374                return err;
 375
 376        dev->snd_card = card;
 377        strscpy(card->driver, "tw686x", sizeof(card->driver));
 378        strscpy(card->shortname, "tw686x", sizeof(card->shortname));
 379        strscpy(card->longname, pci_name(pci_dev), sizeof(card->longname));
 380        snd_card_set_dev(card, &pci_dev->dev);
 381
 382        for (ch = 0; ch < max_channels(dev); ch++) {
 383                struct tw686x_audio_channel *ac;
 384
 385                ac = &dev->audio_channels[ch];
 386                spin_lock_init(&ac->lock);
 387                ac->dev = dev;
 388                ac->ch = ch;
 389
 390                err = tw686x_audio_dma_alloc(dev, ac);
 391                if (err < 0)
 392                        goto err_cleanup;
 393        }
 394
 395        err = tw686x_snd_pcm_init(dev);
 396        if (err < 0)
 397                goto err_cleanup;
 398
 399        err = snd_card_register(card);
 400        if (!err)
 401                return 0;
 402
 403err_cleanup:
 404        for (ch = 0; ch < max_channels(dev); ch++) {
 405                if (!dev->audio_channels[ch].dev)
 406                        continue;
 407                tw686x_audio_dma_free(dev, &dev->audio_channels[ch]);
 408        }
 409        snd_card_free(card);
 410        dev->snd_card = NULL;
 411        return err;
 412}
 413