linux/sound/pci/emu10k1/p16v.c
<<
>>
Prefs
   1/*
   2 *  Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
   3 *  Driver p16v chips
   4 *  Version: 0.25
   5 *
   6 *  FEATURES currently supported:
   7 *    Output fixed at S32_LE, 2 channel to hw:0,0
   8 *    Rates: 44.1, 48, 96, 192.
   9 *
  10 *  Changelog:
  11 *  0.8
  12 *    Use separate card based buffer for periods table.
  13 *  0.9
  14 *    Use 2 channel output streams instead of 8 channel.
  15 *       (8 channel output streams might be good for ASIO type output)
  16 *    Corrected speaker output, so Front -> Front etc.
  17 *  0.10
  18 *    Fixed missed interrupts.
  19 *  0.11
  20 *    Add Sound card model number and names.
  21 *    Add Analog volume controls.
  22 *  0.12
  23 *    Corrected playback interrupts. Now interrupt per period, instead of half period.
  24 *  0.13
  25 *    Use single trigger for multichannel.
  26 *  0.14
  27 *    Mic capture now works at fixed: S32_LE, 96000Hz, Stereo.
  28 *  0.15
  29 *    Force buffer_size / period_size == INTEGER.
  30 *  0.16
  31 *    Update p16v.c to work with changed alsa api.
  32 *  0.17
  33 *    Update p16v.c to work with changed alsa api. Removed boot_devs.
  34 *  0.18
  35 *    Merging with snd-emu10k1 driver.
  36 *  0.19
  37 *    One stereo channel at 24bit now works.
  38 *  0.20
  39 *    Added better register defines.
  40 *  0.21
  41 *    Integrated with snd-emu10k1 driver.
  42 *  0.22
  43 *    Removed #if 0 ... #endif
  44 *  0.23
  45 *    Implement different capture rates.
  46 *  0.24
  47 *    Implement different capture source channels.
  48 *    e.g. When HD Capture source is set to SPDIF,
  49 *    setting HD Capture channel to 0 captures from CDROM digital input.
  50 *    setting HD Capture channel to 1 captures from SPDIF in.
  51 *  0.25
  52 *    Include capture buffer sizes.
  53 *
  54 *  BUGS:
  55 *    Some stability problems when unloading the snd-p16v kernel module.
  56 *    --
  57 *
  58 *  TODO:
  59 *    SPDIF out.
  60 *    Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz.
  61 *    Currently capture fixed at 48000Hz.
  62 *
  63 *    --
  64 *  GENERAL INFO:
  65 *    Model: SB0240
  66 *    P16V Chip: CA0151-DBS
  67 *    Audigy 2 Chip: CA0102-IAT
  68 *    AC97 Codec: STAC 9721
  69 *    ADC: Philips 1361T (Stereo 24bit)
  70 *    DAC: CS4382-K (8-channel, 24bit, 192Khz)
  71 *
  72 *  This code was initially based on code from ALSA's emu10k1x.c which is:
  73 *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
  74 *
  75 *   This program is free software; you can redistribute it and/or modify
  76 *   it under the terms of the GNU General Public License as published by
  77 *   the Free Software Foundation; either version 2 of the License, or
  78 *   (at your option) any later version.
  79 *
  80 *   This program is distributed in the hope that it will be useful,
  81 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  82 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  83 *   GNU General Public License for more details.
  84 *
  85 *   You should have received a copy of the GNU General Public License
  86 *   along with this program; if not, write to the Free Software
  87 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  88 *
  89 */
  90#include <linux/delay.h>
  91#include <linux/init.h>
  92#include <linux/interrupt.h>
  93#include <linux/pci.h>
  94#include <linux/slab.h>
  95#include <linux/vmalloc.h>
  96#include <linux/moduleparam.h>
  97#include <sound/core.h>
  98#include <sound/initval.h>
  99#include <sound/pcm.h>
 100#include <sound/ac97_codec.h>
 101#include <sound/info.h>
 102#include <sound/tlv.h>
 103#include <sound/emu10k1.h>
 104#include "p16v.h"
 105
 106#define SET_CHANNEL 0  /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
 107#define PCM_FRONT_CHANNEL 0
 108#define PCM_REAR_CHANNEL 1
 109#define PCM_CENTER_LFE_CHANNEL 2
 110#define PCM_SIDE_CHANNEL 3
 111#define CONTROL_FRONT_CHANNEL 0
 112#define CONTROL_REAR_CHANNEL 3
 113#define CONTROL_CENTER_LFE_CHANNEL 1
 114#define CONTROL_SIDE_CHANNEL 2
 115
 116/* Card IDs:
 117 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2002 -> Audigy2 ZS 7.1 Model:SB0350
 118 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1007 -> Audigy2 6.1    Model:SB0240
 119 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1002 -> Audigy2 Platinum  Model:SB msb0240230009266
 120 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2007 -> Audigy4 Pro Model:SB0380 M1SB0380472001901E
 121 *
 122 */
 123
 124 /* hardware definition */
 125static struct snd_pcm_hardware snd_p16v_playback_hw = {
 126        .info =                 SNDRV_PCM_INFO_MMAP | 
 127                                SNDRV_PCM_INFO_INTERLEAVED |
 128                                SNDRV_PCM_INFO_BLOCK_TRANSFER |
 129                                SNDRV_PCM_INFO_RESUME |
 130                                SNDRV_PCM_INFO_MMAP_VALID |
 131                                SNDRV_PCM_INFO_SYNC_START,
 132        .formats =              SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */
 133        .rates =                SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, 
 134        .rate_min =             44100,
 135        .rate_max =             192000,
 136        .channels_min =         8, 
 137        .channels_max =         8,
 138        .buffer_bytes_max =     ((65536 - 64) * 8),
 139        .period_bytes_min =     64,
 140        .period_bytes_max =     (65536 - 64),
 141        .periods_min =          2,
 142        .periods_max =          8,
 143        .fifo_size =            0,
 144};
 145
 146static struct snd_pcm_hardware snd_p16v_capture_hw = {
 147        .info =                 (SNDRV_PCM_INFO_MMAP |
 148                                 SNDRV_PCM_INFO_INTERLEAVED |
 149                                 SNDRV_PCM_INFO_BLOCK_TRANSFER |
 150                                 SNDRV_PCM_INFO_RESUME |
 151                                 SNDRV_PCM_INFO_MMAP_VALID),
 152        .formats =              SNDRV_PCM_FMTBIT_S32_LE,
 153        .rates =                SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, 
 154        .rate_min =             44100,
 155        .rate_max =             192000,
 156        .channels_min =         2,
 157        .channels_max =         2,
 158        .buffer_bytes_max =     (65536 - 64),
 159        .period_bytes_min =     64,
 160        .period_bytes_max =     (65536 - 128) >> 1,  /* size has to be N*64 bytes */
 161        .periods_min =          2,
 162        .periods_max =          2,
 163        .fifo_size =            0,
 164};
 165
 166static void snd_p16v_pcm_free_substream(struct snd_pcm_runtime *runtime)
 167{
 168        struct snd_emu10k1_pcm *epcm = runtime->private_data;
 169  
 170        if (epcm) {
 171                /* dev_dbg(emu->card->dev, "epcm free: %p\n", epcm); */
 172                kfree(epcm);
 173        }
 174}
 175
 176/* open_playback callback */
 177static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substream, int channel_id)
 178{
 179        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 180        struct snd_emu10k1_voice *channel = &(emu->p16v_voices[channel_id]);
 181        struct snd_emu10k1_pcm *epcm;
 182        struct snd_pcm_runtime *runtime = substream->runtime;
 183        int err;
 184
 185        epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 186        /* dev_dbg(emu->card->dev, "epcm kcalloc: %p\n", epcm); */
 187
 188        if (epcm == NULL)
 189                return -ENOMEM;
 190        epcm->emu = emu;
 191        epcm->substream = substream;
 192        /*
 193        dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n",
 194                   substream->pcm->device, channel_id);
 195        */
 196        runtime->private_data = epcm;
 197        runtime->private_free = snd_p16v_pcm_free_substream;
 198  
 199        runtime->hw = snd_p16v_playback_hw;
 200
 201        channel->emu = emu;
 202        channel->number = channel_id;
 203
 204        channel->use=1;
 205#if 0 /* debug */
 206        dev_dbg(emu->card->dev,
 207                   "p16v: open channel_id=%d, channel=%p, use=0x%x\n",
 208                   channel_id, channel, channel->use);
 209        dev_dbg(emu->card->dev, "open:channel_id=%d, chip=%p, channel=%p\n",
 210               channel_id, chip, channel);
 211#endif /* debug */
 212        /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */
 213        channel->epcm = epcm;
 214        if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
 215                return err;
 216
 217        runtime->sync.id32[0] = substream->pcm->card->number;
 218        runtime->sync.id32[1] = 'P';
 219        runtime->sync.id32[2] = 16;
 220        runtime->sync.id32[3] = 'V';
 221
 222        return 0;
 223}
 224/* open_capture callback */
 225static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream, int channel_id)
 226{
 227        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 228        struct snd_emu10k1_voice *channel = &(emu->p16v_capture_voice);
 229        struct snd_emu10k1_pcm *epcm;
 230        struct snd_pcm_runtime *runtime = substream->runtime;
 231        int err;
 232
 233        epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 234        /* dev_dbg(emu->card->dev, "epcm kcalloc: %p\n", epcm); */
 235
 236        if (epcm == NULL)
 237                return -ENOMEM;
 238        epcm->emu = emu;
 239        epcm->substream = substream;
 240        /*
 241        dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n",
 242                   substream->pcm->device, channel_id);
 243        */
 244        runtime->private_data = epcm;
 245        runtime->private_free = snd_p16v_pcm_free_substream;
 246  
 247        runtime->hw = snd_p16v_capture_hw;
 248
 249        channel->emu = emu;
 250        channel->number = channel_id;
 251
 252        channel->use=1;
 253#if 0 /* debug */
 254        dev_dbg(emu->card->dev,
 255                   "p16v: open channel_id=%d, channel=%p, use=0x%x\n",
 256                   channel_id, channel, channel->use);
 257        dev_dbg(emu->card->dev, "open:channel_id=%d, chip=%p, channel=%p\n",
 258               channel_id, chip, channel);
 259#endif /* debug */
 260        /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */
 261        channel->epcm = epcm;
 262        if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
 263                return err;
 264
 265        return 0;
 266}
 267
 268
 269/* close callback */
 270static int snd_p16v_pcm_close_playback(struct snd_pcm_substream *substream)
 271{
 272        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 273        //struct snd_pcm_runtime *runtime = substream->runtime;
 274        //struct snd_emu10k1_pcm *epcm = runtime->private_data;
 275        emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use = 0;
 276        /* FIXME: maybe zero others */
 277        return 0;
 278}
 279
 280/* close callback */
 281static int snd_p16v_pcm_close_capture(struct snd_pcm_substream *substream)
 282{
 283        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 284        //struct snd_pcm_runtime *runtime = substream->runtime;
 285        //struct snd_emu10k1_pcm *epcm = runtime->private_data;
 286        emu->p16v_capture_voice.use = 0;
 287        /* FIXME: maybe zero others */
 288        return 0;
 289}
 290
 291static int snd_p16v_pcm_open_playback_front(struct snd_pcm_substream *substream)
 292{
 293        return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
 294}
 295
 296static int snd_p16v_pcm_open_capture(struct snd_pcm_substream *substream)
 297{
 298        // Only using channel 0 for now, but the card has 2 channels.
 299        return snd_p16v_pcm_open_capture_channel(substream, 0);
 300}
 301
 302/* hw_params callback */
 303static int snd_p16v_pcm_hw_params_playback(struct snd_pcm_substream *substream,
 304                                      struct snd_pcm_hw_params *hw_params)
 305{
 306        int result;
 307        result = snd_pcm_lib_malloc_pages(substream,
 308                                        params_buffer_bytes(hw_params));
 309        return result;
 310}
 311
 312/* hw_params callback */
 313static int snd_p16v_pcm_hw_params_capture(struct snd_pcm_substream *substream,
 314                                      struct snd_pcm_hw_params *hw_params)
 315{
 316        int result;
 317        result = snd_pcm_lib_malloc_pages(substream,
 318                                        params_buffer_bytes(hw_params));
 319        return result;
 320}
 321
 322
 323/* hw_free callback */
 324static int snd_p16v_pcm_hw_free_playback(struct snd_pcm_substream *substream)
 325{
 326        int result;
 327        result = snd_pcm_lib_free_pages(substream);
 328        return result;
 329}
 330
 331/* hw_free callback */
 332static int snd_p16v_pcm_hw_free_capture(struct snd_pcm_substream *substream)
 333{
 334        int result;
 335        result = snd_pcm_lib_free_pages(substream);
 336        return result;
 337}
 338
 339
 340/* prepare playback callback */
 341static int snd_p16v_pcm_prepare_playback(struct snd_pcm_substream *substream)
 342{
 343        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 344        struct snd_pcm_runtime *runtime = substream->runtime;
 345        int channel = substream->pcm->device - emu->p16v_device_offset;
 346        u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel));
 347        u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
 348        int i;
 349        u32 tmp;
 350        
 351#if 0 /* debug */
 352        dev_dbg(emu->card->dev,
 353                "prepare:channel_number=%d, rate=%d, "
 354                   "format=0x%x, channels=%d, buffer_size=%ld, "
 355                   "period_size=%ld, periods=%u, frames_to_bytes=%d\n",
 356                   channel, runtime->rate, runtime->format, runtime->channels,
 357                   runtime->buffer_size, runtime->period_size,
 358                   runtime->periods, frames_to_bytes(runtime, 1));
 359        dev_dbg(emu->card->dev,
 360                "dma_addr=%x, dma_area=%p, table_base=%p\n",
 361                   runtime->dma_addr, runtime->dma_area, table_base);
 362        dev_dbg(emu->card->dev,
 363                "dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",
 364                   emu->p16v_buffer.addr, emu->p16v_buffer.area,
 365                   emu->p16v_buffer.bytes);
 366#endif /* debug */
 367        tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
 368        switch (runtime->rate) {
 369        case 44100:
 370          snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x8080);
 371          break;
 372        case 96000:
 373          snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x4040);
 374          break;
 375        case 192000:
 376          snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x2020);
 377          break;
 378        case 48000:
 379        default:
 380          snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x0000);
 381          break;
 382        }
 383        /* FIXME: Check emu->buffer.size before actually writing to it. */
 384        for(i = 0; i < runtime->periods; i++) {
 385                table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
 386                table_base[(i*2)+1]=period_size_bytes<<16;
 387        }
 388 
 389        snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_ADDR, channel, emu->p16v_buffer.addr+(8*16*channel));
 390        snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
 391        snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0);
 392        snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
 393        //snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
 394        snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes
 395        snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0);
 396        snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0);
 397        snd_emu10k1_ptr20_write(emu, 0x08, channel, 0);
 398
 399        return 0;
 400}
 401
 402/* prepare capture callback */
 403static int snd_p16v_pcm_prepare_capture(struct snd_pcm_substream *substream)
 404{
 405        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 406        struct snd_pcm_runtime *runtime = substream->runtime;
 407        int channel = substream->pcm->device - emu->p16v_device_offset;
 408        u32 tmp;
 409
 410        /*
 411        dev_dbg(emu->card->dev, "prepare capture:channel_number=%d, rate=%d, "
 412               "format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, "
 413               "frames_to_bytes=%d\n",
 414               channel, runtime->rate, runtime->format, runtime->channels,
 415               runtime->buffer_size, runtime->period_size,
 416               frames_to_bytes(runtime, 1));
 417        */
 418        tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
 419        switch (runtime->rate) {
 420        case 44100:
 421          snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0800);
 422          break;
 423        case 96000:
 424          snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0400);
 425          break;
 426        case 192000:
 427          snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0200);
 428          break;
 429        case 48000:
 430        default:
 431          snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0000);
 432          break;
 433        }
 434        /* FIXME: Check emu->buffer.size before actually writing to it. */
 435        snd_emu10k1_ptr20_write(emu, 0x13, channel, 0);
 436        snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
 437        snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size) << 16); // buffer size in bytes
 438        snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0);
 439        //snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */
 440        //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel));
 441
 442        return 0;
 443}
 444
 445static void snd_p16v_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
 446{
 447        unsigned long flags;
 448        unsigned int enable;
 449
 450        spin_lock_irqsave(&emu->emu_lock, flags);
 451        enable = inl(emu->port + INTE2) | intrenb;
 452        outl(enable, emu->port + INTE2);
 453        spin_unlock_irqrestore(&emu->emu_lock, flags);
 454}
 455
 456static void snd_p16v_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb)
 457{
 458        unsigned long flags;
 459        unsigned int disable;
 460
 461        spin_lock_irqsave(&emu->emu_lock, flags);
 462        disable = inl(emu->port + INTE2) & (~intrenb);
 463        outl(disable, emu->port + INTE2);
 464        spin_unlock_irqrestore(&emu->emu_lock, flags);
 465}
 466
 467/* trigger_playback callback */
 468static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
 469                                    int cmd)
 470{
 471        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 472        struct snd_pcm_runtime *runtime;
 473        struct snd_emu10k1_pcm *epcm;
 474        int channel;
 475        int result = 0;
 476        struct snd_pcm_substream *s;
 477        u32 basic = 0;
 478        u32 inte = 0;
 479        int running = 0;
 480
 481        switch (cmd) {
 482        case SNDRV_PCM_TRIGGER_START:
 483                running=1;
 484                break;
 485        case SNDRV_PCM_TRIGGER_STOP:
 486        default:
 487                running = 0;
 488                break;
 489        }
 490        snd_pcm_group_for_each_entry(s, substream) {
 491                if (snd_pcm_substream_chip(s) != emu ||
 492                    s->stream != SNDRV_PCM_STREAM_PLAYBACK)
 493                        continue;
 494                runtime = s->runtime;
 495                epcm = runtime->private_data;
 496                channel = substream->pcm->device-emu->p16v_device_offset;
 497                /* dev_dbg(emu->card->dev, "p16v channel=%d\n", channel); */
 498                epcm->running = running;
 499                basic |= (0x1<<channel);
 500                inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel);
 501                snd_pcm_trigger_done(s, substream);
 502        }
 503        /* dev_dbg(emu->card->dev, "basic=0x%x, inte=0x%x\n", basic, inte); */
 504
 505        switch (cmd) {
 506        case SNDRV_PCM_TRIGGER_START:
 507                snd_p16v_intr_enable(emu, inte);
 508                snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)| (basic));
 509                break;
 510        case SNDRV_PCM_TRIGGER_STOP:
 511                snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
 512                snd_p16v_intr_disable(emu, inte);
 513                break;
 514        default:
 515                result = -EINVAL;
 516                break;
 517        }
 518        return result;
 519}
 520
 521/* trigger_capture callback */
 522static int snd_p16v_pcm_trigger_capture(struct snd_pcm_substream *substream,
 523                                   int cmd)
 524{
 525        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 526        struct snd_pcm_runtime *runtime = substream->runtime;
 527        struct snd_emu10k1_pcm *epcm = runtime->private_data;
 528        int channel = 0;
 529        int result = 0;
 530        u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP;
 531
 532        switch (cmd) {
 533        case SNDRV_PCM_TRIGGER_START:
 534                snd_p16v_intr_enable(emu, inte);
 535                snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
 536                epcm->running = 1;
 537                break;
 538        case SNDRV_PCM_TRIGGER_STOP:
 539                snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));
 540                snd_p16v_intr_disable(emu, inte);
 541                //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel));
 542                epcm->running = 0;
 543                break;
 544        default:
 545                result = -EINVAL;
 546                break;
 547        }
 548        return result;
 549}
 550
 551/* pointer_playback callback */
 552static snd_pcm_uframes_t
 553snd_p16v_pcm_pointer_playback(struct snd_pcm_substream *substream)
 554{
 555        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 556        struct snd_pcm_runtime *runtime = substream->runtime;
 557        struct snd_emu10k1_pcm *epcm = runtime->private_data;
 558        snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
 559        int channel = substream->pcm->device - emu->p16v_device_offset;
 560        if (!epcm->running)
 561                return 0;
 562
 563        ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
 564        ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
 565        ptr4 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
 566        if (ptr3 != ptr4) ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
 567        ptr2 = bytes_to_frames(runtime, ptr1);
 568        ptr2+= (ptr4 >> 3) * runtime->period_size;
 569        ptr=ptr2;
 570        if (ptr >= runtime->buffer_size)
 571                ptr -= runtime->buffer_size;
 572
 573        return ptr;
 574}
 575
 576/* pointer_capture callback */
 577static snd_pcm_uframes_t
 578snd_p16v_pcm_pointer_capture(struct snd_pcm_substream *substream)
 579{
 580        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 581        struct snd_pcm_runtime *runtime = substream->runtime;
 582        struct snd_emu10k1_pcm *epcm = runtime->private_data;
 583        snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
 584        int channel = 0;
 585
 586        if (!epcm->running)
 587                return 0;
 588
 589        ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel);
 590        ptr2 = bytes_to_frames(runtime, ptr1);
 591        ptr=ptr2;
 592        if (ptr >= runtime->buffer_size) {
 593                ptr -= runtime->buffer_size;
 594                dev_warn(emu->card->dev, "buffer capture limited!\n");
 595        }
 596        /*
 597        dev_dbg(emu->card->dev, "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, "
 598               "buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n",
 599               ptr1, ptr2, ptr, (int)runtime->buffer_size,
 600               (int)runtime->period_size, (int)runtime->frame_bits,
 601               (int)runtime->rate);
 602        */
 603        return ptr;
 604}
 605
 606/* operators */
 607static struct snd_pcm_ops snd_p16v_playback_front_ops = {
 608        .open =        snd_p16v_pcm_open_playback_front,
 609        .close =       snd_p16v_pcm_close_playback,
 610        .ioctl =       snd_pcm_lib_ioctl,
 611        .hw_params =   snd_p16v_pcm_hw_params_playback,
 612        .hw_free =     snd_p16v_pcm_hw_free_playback,
 613        .prepare =     snd_p16v_pcm_prepare_playback,
 614        .trigger =     snd_p16v_pcm_trigger_playback,
 615        .pointer =     snd_p16v_pcm_pointer_playback,
 616};
 617
 618static struct snd_pcm_ops snd_p16v_capture_ops = {
 619        .open =        snd_p16v_pcm_open_capture,
 620        .close =       snd_p16v_pcm_close_capture,
 621        .ioctl =       snd_pcm_lib_ioctl,
 622        .hw_params =   snd_p16v_pcm_hw_params_capture,
 623        .hw_free =     snd_p16v_pcm_hw_free_capture,
 624        .prepare =     snd_p16v_pcm_prepare_capture,
 625        .trigger =     snd_p16v_pcm_trigger_capture,
 626        .pointer =     snd_p16v_pcm_pointer_capture,
 627};
 628
 629
 630int snd_p16v_free(struct snd_emu10k1 *chip)
 631{
 632        // release the data
 633        if (chip->p16v_buffer.area) {
 634                snd_dma_free_pages(&chip->p16v_buffer);
 635                /*
 636                dev_dbg(chip->card->dev, "period lables free: %p\n",
 637                           &chip->p16v_buffer);
 638                */
 639        }
 640        return 0;
 641}
 642
 643int snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
 644{
 645        struct snd_pcm *pcm;
 646        struct snd_pcm_substream *substream;
 647        int err;
 648        int capture=1;
 649  
 650        /* dev_dbg(emu->card->dev, "snd_p16v_pcm called. device=%d\n", device); */
 651        emu->p16v_device_offset = device;
 652        if (rpcm)
 653                *rpcm = NULL;
 654
 655        if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0)
 656                return err;
 657  
 658        pcm->private_data = emu;
 659        // Single playback 8 channel device.
 660        // Single capture 2 channel device.
 661        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops);
 662        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_p16v_capture_ops);
 663
 664        pcm->info_flags = 0;
 665        pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
 666        strcpy(pcm->name, "p16v");
 667        emu->pcm_p16v = pcm;
 668
 669        for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 
 670            substream; 
 671            substream = substream->next) {
 672                if ((err = snd_pcm_lib_preallocate_pages(substream, 
 673                                                         SNDRV_DMA_TYPE_DEV, 
 674                                                         snd_dma_pci_data(emu->pci), 
 675                                                         ((65536 - 64) * 8), ((65536 - 64) * 8))) < 0) 
 676                        return err;
 677                /*
 678                dev_dbg(emu->card->dev,
 679                           "preallocate playback substream: err=%d\n", err);
 680                */
 681        }
 682
 683        for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 
 684              substream; 
 685              substream = substream->next) {
 686                if ((err = snd_pcm_lib_preallocate_pages(substream, 
 687                                                   SNDRV_DMA_TYPE_DEV, 
 688                                                   snd_dma_pci_data(emu->pci), 
 689                                                   65536 - 64, 65536 - 64)) < 0)
 690                        return err;
 691                /*
 692                dev_dbg(emu->card->dev,
 693                           "preallocate capture substream: err=%d\n", err);
 694                */
 695        }
 696  
 697        if (rpcm)
 698                *rpcm = pcm;
 699  
 700        return 0;
 701}
 702
 703static int snd_p16v_volume_info(struct snd_kcontrol *kcontrol,
 704                                struct snd_ctl_elem_info *uinfo)
 705{
 706        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 707        uinfo->count = 2;
 708        uinfo->value.integer.min = 0;
 709        uinfo->value.integer.max = 255;
 710        return 0;
 711}
 712
 713static int snd_p16v_volume_get(struct snd_kcontrol *kcontrol,
 714                               struct snd_ctl_elem_value *ucontrol)
 715{
 716        struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 717        int high_low = (kcontrol->private_value >> 8) & 0xff;
 718        int reg = kcontrol->private_value & 0xff;
 719        u32 value;
 720
 721        value = snd_emu10k1_ptr20_read(emu, reg, high_low);
 722        if (high_low) {
 723                ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
 724                ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
 725        } else {
 726                ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */
 727                ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */
 728        }
 729        return 0;
 730}
 731
 732static int snd_p16v_volume_put(struct snd_kcontrol *kcontrol,
 733                               struct snd_ctl_elem_value *ucontrol)
 734{
 735        struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 736        int high_low = (kcontrol->private_value >> 8) & 0xff;
 737        int reg = kcontrol->private_value & 0xff;
 738        u32 value, oval;
 739
 740        oval = value = snd_emu10k1_ptr20_read(emu, reg, 0);
 741        if (high_low == 1) {
 742                value &= 0xffff;
 743                value |= ((0xff - ucontrol->value.integer.value[0]) << 24) |
 744                        ((0xff - ucontrol->value.integer.value[1]) << 16);
 745        } else {
 746                value &= 0xffff0000;
 747                value |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
 748                        ((0xff - ucontrol->value.integer.value[1]) );
 749        }
 750        if (value != oval) {
 751                snd_emu10k1_ptr20_write(emu, reg, 0, value);
 752                return 1;
 753        }
 754        return 0;
 755}
 756
 757static int snd_p16v_capture_source_info(struct snd_kcontrol *kcontrol,
 758                                        struct snd_ctl_elem_info *uinfo)
 759{
 760        static char *texts[8] = {
 761                "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S",
 762                "CDIF", "FX", "AC97"
 763        };
 764
 765        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 766        uinfo->count = 1;
 767        uinfo->value.enumerated.items = 8;
 768        if (uinfo->value.enumerated.item > 7)
 769                uinfo->value.enumerated.item = 7;
 770        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
 771        return 0;
 772}
 773
 774static int snd_p16v_capture_source_get(struct snd_kcontrol *kcontrol,
 775                                        struct snd_ctl_elem_value *ucontrol)
 776{
 777        struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 778
 779        ucontrol->value.enumerated.item[0] = emu->p16v_capture_source;
 780        return 0;
 781}
 782
 783static int snd_p16v_capture_source_put(struct snd_kcontrol *kcontrol,
 784                                        struct snd_ctl_elem_value *ucontrol)
 785{
 786        struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 787        unsigned int val;
 788        int change = 0;
 789        u32 mask;
 790        u32 source;
 791
 792        val = ucontrol->value.enumerated.item[0] ;
 793        if (val > 7)
 794                return -EINVAL;
 795        change = (emu->p16v_capture_source != val);
 796        if (change) {
 797                emu->p16v_capture_source = val;
 798                source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
 799                mask = snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & 0xffff;
 800                snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, source | mask);
 801        }
 802        return change;
 803}
 804
 805static int snd_p16v_capture_channel_info(struct snd_kcontrol *kcontrol,
 806                                         struct snd_ctl_elem_info *uinfo)
 807{
 808        static char *texts[4] = { "0", "1", "2", "3",  };
 809
 810        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 811        uinfo->count = 1;
 812        uinfo->value.enumerated.items = 4;
 813        if (uinfo->value.enumerated.item > 3)
 814                uinfo->value.enumerated.item = 3;
 815        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
 816        return 0;
 817}
 818
 819static int snd_p16v_capture_channel_get(struct snd_kcontrol *kcontrol,
 820                                        struct snd_ctl_elem_value *ucontrol)
 821{
 822        struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 823
 824        ucontrol->value.enumerated.item[0] = emu->p16v_capture_channel;
 825        return 0;
 826}
 827
 828static int snd_p16v_capture_channel_put(struct snd_kcontrol *kcontrol,
 829                                        struct snd_ctl_elem_value *ucontrol)
 830{
 831        struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 832        unsigned int val;
 833        int change = 0;
 834        u32 tmp;
 835
 836        val = ucontrol->value.enumerated.item[0] ;
 837        if (val > 3)
 838                return -EINVAL;
 839        change = (emu->p16v_capture_channel != val);
 840        if (change) {
 841                emu->p16v_capture_channel = val;
 842                tmp = snd_emu10k1_ptr20_read(emu, CAPTURE_P16V_SOURCE, 0) & 0xfffc;
 843                snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, tmp | val);
 844        }
 845        return change;
 846}
 847static const DECLARE_TLV_DB_SCALE(snd_p16v_db_scale1, -5175, 25, 1);
 848
 849#define P16V_VOL(xname,xreg,xhl) { \
 850        .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
 851        .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |             \
 852                  SNDRV_CTL_ELEM_ACCESS_TLV_READ,               \
 853        .info = snd_p16v_volume_info, \
 854        .get = snd_p16v_volume_get, \
 855        .put = snd_p16v_volume_put, \
 856        .tlv = { .p = snd_p16v_db_scale1 },     \
 857        .private_value = ((xreg) | ((xhl) << 8)) \
 858}
 859
 860static struct snd_kcontrol_new p16v_mixer_controls[] = {
 861        P16V_VOL("HD Analog Front Playback Volume", PLAYBACK_VOLUME_MIXER9, 0),
 862        P16V_VOL("HD Analog Rear Playback Volume", PLAYBACK_VOLUME_MIXER10, 1),
 863        P16V_VOL("HD Analog Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER9, 1),
 864        P16V_VOL("HD Analog Side Playback Volume", PLAYBACK_VOLUME_MIXER10, 0),
 865        P16V_VOL("HD SPDIF Front Playback Volume", PLAYBACK_VOLUME_MIXER7, 0),
 866        P16V_VOL("HD SPDIF Rear Playback Volume", PLAYBACK_VOLUME_MIXER8, 1),
 867        P16V_VOL("HD SPDIF Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER7, 1),
 868        P16V_VOL("HD SPDIF Side Playback Volume", PLAYBACK_VOLUME_MIXER8, 0),
 869        {
 870                .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 871                .name =         "HD source Capture",
 872                .info =         snd_p16v_capture_source_info,
 873                .get =          snd_p16v_capture_source_get,
 874                .put =          snd_p16v_capture_source_put
 875        },
 876        {
 877                .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 878                .name =         "HD channel Capture",
 879                .info =         snd_p16v_capture_channel_info,
 880                .get =          snd_p16v_capture_channel_get,
 881                .put =          snd_p16v_capture_channel_put
 882        },
 883};
 884
 885
 886int snd_p16v_mixer(struct snd_emu10k1 *emu)
 887{
 888        int i, err;
 889        struct snd_card *card = emu->card;
 890
 891        for (i = 0; i < ARRAY_SIZE(p16v_mixer_controls); i++) {
 892                if ((err = snd_ctl_add(card, snd_ctl_new1(&p16v_mixer_controls[i],
 893                                                          emu))) < 0)
 894                        return err;
 895        }
 896        return 0;
 897}
 898
 899#ifdef CONFIG_PM_SLEEP
 900
 901#define NUM_CHS 1       /* up to 4, but only first channel is used */
 902
 903int snd_p16v_alloc_pm_buffer(struct snd_emu10k1 *emu)
 904{
 905        emu->p16v_saved = vmalloc(NUM_CHS * 4 * 0x80);
 906        if (! emu->p16v_saved)
 907                return -ENOMEM;
 908        return 0;
 909}
 910
 911void snd_p16v_free_pm_buffer(struct snd_emu10k1 *emu)
 912{
 913        vfree(emu->p16v_saved);
 914}
 915
 916void snd_p16v_suspend(struct snd_emu10k1 *emu)
 917{
 918        int i, ch;
 919        unsigned int *val;
 920
 921        val = emu->p16v_saved;
 922        for (ch = 0; ch < NUM_CHS; ch++)
 923                for (i = 0; i < 0x80; i++, val++)
 924                        *val = snd_emu10k1_ptr20_read(emu, i, ch);
 925}
 926
 927void snd_p16v_resume(struct snd_emu10k1 *emu)
 928{
 929        int i, ch;
 930        unsigned int *val;
 931
 932        val = emu->p16v_saved;
 933        for (ch = 0; ch < NUM_CHS; ch++)
 934                for (i = 0; i < 0x80; i++, val++)
 935                        snd_emu10k1_ptr20_write(emu, i, ch, *val);
 936}
 937#endif
 938