root/sound/pci/emu10k1/p16v.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snd_p16v_pcm_free_substream
  2. snd_p16v_pcm_open_playback_channel
  3. snd_p16v_pcm_open_capture_channel
  4. snd_p16v_pcm_close_playback
  5. snd_p16v_pcm_close_capture
  6. snd_p16v_pcm_open_playback_front
  7. snd_p16v_pcm_open_capture
  8. snd_p16v_pcm_hw_params_playback
  9. snd_p16v_pcm_hw_params_capture
  10. snd_p16v_pcm_hw_free_playback
  11. snd_p16v_pcm_hw_free_capture
  12. snd_p16v_pcm_prepare_playback
  13. snd_p16v_pcm_prepare_capture
  14. snd_p16v_intr_enable
  15. snd_p16v_intr_disable
  16. snd_p16v_pcm_trigger_playback
  17. snd_p16v_pcm_trigger_capture
  18. snd_p16v_pcm_pointer_playback
  19. snd_p16v_pcm_pointer_capture
  20. snd_p16v_free
  21. snd_p16v_pcm
  22. snd_p16v_volume_info
  23. snd_p16v_volume_get
  24. snd_p16v_volume_put
  25. snd_p16v_capture_source_info
  26. snd_p16v_capture_source_get
  27. snd_p16v_capture_source_put
  28. snd_p16v_capture_channel_info
  29. snd_p16v_capture_channel_get
  30. snd_p16v_capture_channel_put
  31. snd_p16v_mixer
  32. snd_p16v_alloc_pm_buffer
  33. snd_p16v_free_pm_buffer
  34. snd_p16v_suspend
  35. snd_p16v_resume

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

/* [<][>][^][v][top][bottom][index][help] */