0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 #include <linux/delay.h>
0077 #include <linux/init.h>
0078 #include <linux/interrupt.h>
0079 #include <linux/pci.h>
0080 #include <linux/slab.h>
0081 #include <linux/vmalloc.h>
0082 #include <linux/moduleparam.h>
0083 #include <sound/core.h>
0084 #include <sound/initval.h>
0085 #include <sound/pcm.h>
0086 #include <sound/ac97_codec.h>
0087 #include <sound/info.h>
0088 #include <sound/tlv.h>
0089 #include <sound/emu10k1.h>
0090 #include "p16v.h"
0091
0092 #define SET_CHANNEL 0
0093 #define PCM_FRONT_CHANNEL 0
0094 #define PCM_REAR_CHANNEL 1
0095 #define PCM_CENTER_LFE_CHANNEL 2
0096 #define PCM_SIDE_CHANNEL 3
0097 #define CONTROL_FRONT_CHANNEL 0
0098 #define CONTROL_REAR_CHANNEL 3
0099 #define CONTROL_CENTER_LFE_CHANNEL 1
0100 #define CONTROL_SIDE_CHANNEL 2
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 static const struct snd_pcm_hardware snd_p16v_playback_hw = {
0112 .info = SNDRV_PCM_INFO_MMAP |
0113 SNDRV_PCM_INFO_INTERLEAVED |
0114 SNDRV_PCM_INFO_BLOCK_TRANSFER |
0115 SNDRV_PCM_INFO_RESUME |
0116 SNDRV_PCM_INFO_MMAP_VALID |
0117 SNDRV_PCM_INFO_SYNC_START,
0118 .formats = SNDRV_PCM_FMTBIT_S32_LE,
0119 .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100,
0120 .rate_min = 44100,
0121 .rate_max = 192000,
0122 .channels_min = 8,
0123 .channels_max = 8,
0124 .buffer_bytes_max = ((65536 - 64) * 8),
0125 .period_bytes_min = 64,
0126 .period_bytes_max = (65536 - 64),
0127 .periods_min = 2,
0128 .periods_max = 8,
0129 .fifo_size = 0,
0130 };
0131
0132 static const struct snd_pcm_hardware snd_p16v_capture_hw = {
0133 .info = (SNDRV_PCM_INFO_MMAP |
0134 SNDRV_PCM_INFO_INTERLEAVED |
0135 SNDRV_PCM_INFO_BLOCK_TRANSFER |
0136 SNDRV_PCM_INFO_RESUME |
0137 SNDRV_PCM_INFO_MMAP_VALID),
0138 .formats = SNDRV_PCM_FMTBIT_S32_LE,
0139 .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100,
0140 .rate_min = 44100,
0141 .rate_max = 192000,
0142 .channels_min = 2,
0143 .channels_max = 2,
0144 .buffer_bytes_max = (65536 - 64),
0145 .period_bytes_min = 64,
0146 .period_bytes_max = (65536 - 128) >> 1,
0147 .periods_min = 2,
0148 .periods_max = 2,
0149 .fifo_size = 0,
0150 };
0151
0152 static void snd_p16v_pcm_free_substream(struct snd_pcm_runtime *runtime)
0153 {
0154 struct snd_emu10k1_pcm *epcm = runtime->private_data;
0155
0156 kfree(epcm);
0157 }
0158
0159
0160 static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substream, int channel_id)
0161 {
0162 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
0163 struct snd_emu10k1_voice *channel = &(emu->p16v_voices[channel_id]);
0164 struct snd_emu10k1_pcm *epcm;
0165 struct snd_pcm_runtime *runtime = substream->runtime;
0166 int err;
0167
0168 epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
0169
0170
0171 if (epcm == NULL)
0172 return -ENOMEM;
0173 epcm->emu = emu;
0174 epcm->substream = substream;
0175
0176
0177
0178
0179 runtime->private_data = epcm;
0180 runtime->private_free = snd_p16v_pcm_free_substream;
0181
0182 runtime->hw = snd_p16v_playback_hw;
0183
0184 channel->emu = emu;
0185 channel->number = channel_id;
0186
0187 channel->use=1;
0188 #if 0
0189 dev_dbg(emu->card->dev,
0190 "p16v: open channel_id=%d, channel=%p, use=0x%x\n",
0191 channel_id, channel, channel->use);
0192 dev_dbg(emu->card->dev, "open:channel_id=%d, chip=%p, channel=%p\n",
0193 channel_id, chip, channel);
0194 #endif
0195
0196 channel->epcm = epcm;
0197 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
0198 if (err < 0)
0199 return err;
0200
0201 runtime->sync.id32[0] = substream->pcm->card->number;
0202 runtime->sync.id32[1] = 'P';
0203 runtime->sync.id32[2] = 16;
0204 runtime->sync.id32[3] = 'V';
0205
0206 return 0;
0207 }
0208
0209 static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream, int channel_id)
0210 {
0211 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
0212 struct snd_emu10k1_voice *channel = &(emu->p16v_capture_voice);
0213 struct snd_emu10k1_pcm *epcm;
0214 struct snd_pcm_runtime *runtime = substream->runtime;
0215 int err;
0216
0217 epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
0218
0219
0220 if (epcm == NULL)
0221 return -ENOMEM;
0222 epcm->emu = emu;
0223 epcm->substream = substream;
0224
0225
0226
0227
0228 runtime->private_data = epcm;
0229 runtime->private_free = snd_p16v_pcm_free_substream;
0230
0231 runtime->hw = snd_p16v_capture_hw;
0232
0233 channel->emu = emu;
0234 channel->number = channel_id;
0235
0236 channel->use=1;
0237 #if 0
0238 dev_dbg(emu->card->dev,
0239 "p16v: open channel_id=%d, channel=%p, use=0x%x\n",
0240 channel_id, channel, channel->use);
0241 dev_dbg(emu->card->dev, "open:channel_id=%d, chip=%p, channel=%p\n",
0242 channel_id, chip, channel);
0243 #endif
0244
0245 channel->epcm = epcm;
0246 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
0247 if (err < 0)
0248 return err;
0249
0250 return 0;
0251 }
0252
0253
0254
0255 static int snd_p16v_pcm_close_playback(struct snd_pcm_substream *substream)
0256 {
0257 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
0258
0259
0260 emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use = 0;
0261
0262 return 0;
0263 }
0264
0265
0266 static int snd_p16v_pcm_close_capture(struct snd_pcm_substream *substream)
0267 {
0268 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
0269
0270
0271 emu->p16v_capture_voice.use = 0;
0272
0273 return 0;
0274 }
0275
0276 static int snd_p16v_pcm_open_playback_front(struct snd_pcm_substream *substream)
0277 {
0278 return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
0279 }
0280
0281 static int snd_p16v_pcm_open_capture(struct snd_pcm_substream *substream)
0282 {
0283
0284 return snd_p16v_pcm_open_capture_channel(substream, 0);
0285 }
0286
0287
0288 static int snd_p16v_pcm_prepare_playback(struct snd_pcm_substream *substream)
0289 {
0290 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
0291 struct snd_pcm_runtime *runtime = substream->runtime;
0292 int channel = substream->pcm->device - emu->p16v_device_offset;
0293 u32 *table_base = (u32 *)(emu->p16v_buffer->area+(8*16*channel));
0294 u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
0295 int i;
0296 u32 tmp;
0297
0298 #if 0
0299 dev_dbg(emu->card->dev,
0300 "prepare:channel_number=%d, rate=%d, "
0301 "format=0x%x, channels=%d, buffer_size=%ld, "
0302 "period_size=%ld, periods=%u, frames_to_bytes=%d\n",
0303 channel, runtime->rate, runtime->format, runtime->channels,
0304 runtime->buffer_size, runtime->period_size,
0305 runtime->periods, frames_to_bytes(runtime, 1));
0306 dev_dbg(emu->card->dev,
0307 "dma_addr=%x, dma_area=%p, table_base=%p\n",
0308 runtime->dma_addr, runtime->dma_area, table_base);
0309 dev_dbg(emu->card->dev,
0310 "dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",
0311 emu->p16v_buffer->addr, emu->p16v_buffer->area,
0312 emu->p16v_buffer->bytes);
0313 #endif
0314 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
0315 switch (runtime->rate) {
0316 case 44100:
0317 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x8080);
0318 break;
0319 case 96000:
0320 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x4040);
0321 break;
0322 case 192000:
0323 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x2020);
0324 break;
0325 case 48000:
0326 default:
0327 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x0000);
0328 break;
0329 }
0330
0331 for(i = 0; i < runtime->periods; i++) {
0332 table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
0333 table_base[(i*2)+1]=period_size_bytes<<16;
0334 }
0335
0336 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_ADDR, channel, emu->p16v_buffer->addr+(8*16*channel));
0337 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
0338 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0);
0339 snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
0340
0341 snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0);
0342 snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0);
0343 snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0);
0344 snd_emu10k1_ptr20_write(emu, 0x08, channel, 0);
0345
0346 return 0;
0347 }
0348
0349
0350 static int snd_p16v_pcm_prepare_capture(struct snd_pcm_substream *substream)
0351 {
0352 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
0353 struct snd_pcm_runtime *runtime = substream->runtime;
0354 int channel = substream->pcm->device - emu->p16v_device_offset;
0355 u32 tmp;
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
0366 switch (runtime->rate) {
0367 case 44100:
0368 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0800);
0369 break;
0370 case 96000:
0371 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0400);
0372 break;
0373 case 192000:
0374 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0200);
0375 break;
0376 case 48000:
0377 default:
0378 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0000);
0379 break;
0380 }
0381
0382 snd_emu10k1_ptr20_write(emu, 0x13, channel, 0);
0383 snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
0384 snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size) << 16);
0385 snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0);
0386
0387
0388
0389 return 0;
0390 }
0391
0392 static void snd_p16v_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
0393 {
0394 unsigned long flags;
0395 unsigned int enable;
0396
0397 spin_lock_irqsave(&emu->emu_lock, flags);
0398 enable = inl(emu->port + INTE2) | intrenb;
0399 outl(enable, emu->port + INTE2);
0400 spin_unlock_irqrestore(&emu->emu_lock, flags);
0401 }
0402
0403 static void snd_p16v_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb)
0404 {
0405 unsigned long flags;
0406 unsigned int disable;
0407
0408 spin_lock_irqsave(&emu->emu_lock, flags);
0409 disable = inl(emu->port + INTE2) & (~intrenb);
0410 outl(disable, emu->port + INTE2);
0411 spin_unlock_irqrestore(&emu->emu_lock, flags);
0412 }
0413
0414
0415 static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
0416 int cmd)
0417 {
0418 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
0419 struct snd_pcm_runtime *runtime;
0420 struct snd_emu10k1_pcm *epcm;
0421 int channel;
0422 int result = 0;
0423 struct snd_pcm_substream *s;
0424 u32 basic = 0;
0425 u32 inte = 0;
0426 int running = 0;
0427
0428 switch (cmd) {
0429 case SNDRV_PCM_TRIGGER_START:
0430 running=1;
0431 break;
0432 case SNDRV_PCM_TRIGGER_STOP:
0433 default:
0434 running = 0;
0435 break;
0436 }
0437 snd_pcm_group_for_each_entry(s, substream) {
0438 if (snd_pcm_substream_chip(s) != emu ||
0439 s->stream != SNDRV_PCM_STREAM_PLAYBACK)
0440 continue;
0441 runtime = s->runtime;
0442 epcm = runtime->private_data;
0443 channel = substream->pcm->device-emu->p16v_device_offset;
0444
0445 epcm->running = running;
0446 basic |= (0x1<<channel);
0447 inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel);
0448 snd_pcm_trigger_done(s, substream);
0449 }
0450
0451
0452 switch (cmd) {
0453 case SNDRV_PCM_TRIGGER_START:
0454 snd_p16v_intr_enable(emu, inte);
0455 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)| (basic));
0456 break;
0457 case SNDRV_PCM_TRIGGER_STOP:
0458 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
0459 snd_p16v_intr_disable(emu, inte);
0460 break;
0461 default:
0462 result = -EINVAL;
0463 break;
0464 }
0465 return result;
0466 }
0467
0468
0469 static int snd_p16v_pcm_trigger_capture(struct snd_pcm_substream *substream,
0470 int cmd)
0471 {
0472 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
0473 struct snd_pcm_runtime *runtime = substream->runtime;
0474 struct snd_emu10k1_pcm *epcm = runtime->private_data;
0475 int channel = 0;
0476 int result = 0;
0477 u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP;
0478
0479 switch (cmd) {
0480 case SNDRV_PCM_TRIGGER_START:
0481 snd_p16v_intr_enable(emu, inte);
0482 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
0483 epcm->running = 1;
0484 break;
0485 case SNDRV_PCM_TRIGGER_STOP:
0486 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));
0487 snd_p16v_intr_disable(emu, inte);
0488
0489 epcm->running = 0;
0490 break;
0491 default:
0492 result = -EINVAL;
0493 break;
0494 }
0495 return result;
0496 }
0497
0498
0499 static snd_pcm_uframes_t
0500 snd_p16v_pcm_pointer_playback(struct snd_pcm_substream *substream)
0501 {
0502 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
0503 struct snd_pcm_runtime *runtime = substream->runtime;
0504 struct snd_emu10k1_pcm *epcm = runtime->private_data;
0505 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
0506 int channel = substream->pcm->device - emu->p16v_device_offset;
0507 if (!epcm->running)
0508 return 0;
0509
0510 ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
0511 ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
0512 ptr4 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
0513 if (ptr3 != ptr4) ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
0514 ptr2 = bytes_to_frames(runtime, ptr1);
0515 ptr2+= (ptr4 >> 3) * runtime->period_size;
0516 ptr=ptr2;
0517 if (ptr >= runtime->buffer_size)
0518 ptr -= runtime->buffer_size;
0519
0520 return ptr;
0521 }
0522
0523
0524 static snd_pcm_uframes_t
0525 snd_p16v_pcm_pointer_capture(struct snd_pcm_substream *substream)
0526 {
0527 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
0528 struct snd_pcm_runtime *runtime = substream->runtime;
0529 struct snd_emu10k1_pcm *epcm = runtime->private_data;
0530 snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
0531 int channel = 0;
0532
0533 if (!epcm->running)
0534 return 0;
0535
0536 ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel);
0537 ptr2 = bytes_to_frames(runtime, ptr1);
0538 ptr=ptr2;
0539 if (ptr >= runtime->buffer_size) {
0540 ptr -= runtime->buffer_size;
0541 dev_warn(emu->card->dev, "buffer capture limited!\n");
0542 }
0543
0544
0545
0546
0547
0548
0549
0550 return ptr;
0551 }
0552
0553
0554 static const struct snd_pcm_ops snd_p16v_playback_front_ops = {
0555 .open = snd_p16v_pcm_open_playback_front,
0556 .close = snd_p16v_pcm_close_playback,
0557 .prepare = snd_p16v_pcm_prepare_playback,
0558 .trigger = snd_p16v_pcm_trigger_playback,
0559 .pointer = snd_p16v_pcm_pointer_playback,
0560 };
0561
0562 static const struct snd_pcm_ops snd_p16v_capture_ops = {
0563 .open = snd_p16v_pcm_open_capture,
0564 .close = snd_p16v_pcm_close_capture,
0565 .prepare = snd_p16v_pcm_prepare_capture,
0566 .trigger = snd_p16v_pcm_trigger_capture,
0567 .pointer = snd_p16v_pcm_pointer_capture,
0568 };
0569
0570 int snd_p16v_pcm(struct snd_emu10k1 *emu, int device)
0571 {
0572 struct snd_pcm *pcm;
0573 struct snd_pcm_substream *substream;
0574 int err;
0575 int capture=1;
0576
0577
0578 emu->p16v_device_offset = device;
0579
0580 err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm);
0581 if (err < 0)
0582 return err;
0583
0584 pcm->private_data = emu;
0585
0586
0587 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops);
0588 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_p16v_capture_ops);
0589
0590 pcm->info_flags = 0;
0591 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
0592 strcpy(pcm->name, "p16v");
0593 emu->pcm_p16v = pcm;
0594
0595 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
0596 substream;
0597 substream = substream->next) {
0598 snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV,
0599 &emu->pci->dev,
0600 (65536 - 64) * 8,
0601 (65536 - 64) * 8);
0602
0603
0604
0605
0606 }
0607
0608 for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
0609 substream;
0610 substream = substream->next) {
0611 snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV,
0612 &emu->pci->dev,
0613 65536 - 64, 65536 - 64);
0614
0615
0616
0617
0618 }
0619
0620 return 0;
0621 }
0622
0623 static int snd_p16v_volume_info(struct snd_kcontrol *kcontrol,
0624 struct snd_ctl_elem_info *uinfo)
0625 {
0626 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0627 uinfo->count = 2;
0628 uinfo->value.integer.min = 0;
0629 uinfo->value.integer.max = 255;
0630 return 0;
0631 }
0632
0633 static int snd_p16v_volume_get(struct snd_kcontrol *kcontrol,
0634 struct snd_ctl_elem_value *ucontrol)
0635 {
0636 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
0637 int high_low = (kcontrol->private_value >> 8) & 0xff;
0638 int reg = kcontrol->private_value & 0xff;
0639 u32 value;
0640
0641 value = snd_emu10k1_ptr20_read(emu, reg, high_low);
0642 if (high_low) {
0643 ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff);
0644 ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff);
0645 } else {
0646 ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff);
0647 ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff);
0648 }
0649 return 0;
0650 }
0651
0652 static int snd_p16v_volume_put(struct snd_kcontrol *kcontrol,
0653 struct snd_ctl_elem_value *ucontrol)
0654 {
0655 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
0656 int high_low = (kcontrol->private_value >> 8) & 0xff;
0657 int reg = kcontrol->private_value & 0xff;
0658 u32 value, oval;
0659
0660 oval = value = snd_emu10k1_ptr20_read(emu, reg, 0);
0661 if (high_low == 1) {
0662 value &= 0xffff;
0663 value |= ((0xff - ucontrol->value.integer.value[0]) << 24) |
0664 ((0xff - ucontrol->value.integer.value[1]) << 16);
0665 } else {
0666 value &= 0xffff0000;
0667 value |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
0668 ((0xff - ucontrol->value.integer.value[1]) );
0669 }
0670 if (value != oval) {
0671 snd_emu10k1_ptr20_write(emu, reg, 0, value);
0672 return 1;
0673 }
0674 return 0;
0675 }
0676
0677 static int snd_p16v_capture_source_info(struct snd_kcontrol *kcontrol,
0678 struct snd_ctl_elem_info *uinfo)
0679 {
0680 static const char * const texts[8] = {
0681 "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S",
0682 "CDIF", "FX", "AC97"
0683 };
0684
0685 return snd_ctl_enum_info(uinfo, 1, 8, texts);
0686 }
0687
0688 static int snd_p16v_capture_source_get(struct snd_kcontrol *kcontrol,
0689 struct snd_ctl_elem_value *ucontrol)
0690 {
0691 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
0692
0693 ucontrol->value.enumerated.item[0] = emu->p16v_capture_source;
0694 return 0;
0695 }
0696
0697 static int snd_p16v_capture_source_put(struct snd_kcontrol *kcontrol,
0698 struct snd_ctl_elem_value *ucontrol)
0699 {
0700 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
0701 unsigned int val;
0702 int change = 0;
0703 u32 mask;
0704 u32 source;
0705
0706 val = ucontrol->value.enumerated.item[0] ;
0707 if (val > 7)
0708 return -EINVAL;
0709 change = (emu->p16v_capture_source != val);
0710 if (change) {
0711 emu->p16v_capture_source = val;
0712 source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
0713 mask = snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & 0xffff;
0714 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, source | mask);
0715 }
0716 return change;
0717 }
0718
0719 static int snd_p16v_capture_channel_info(struct snd_kcontrol *kcontrol,
0720 struct snd_ctl_elem_info *uinfo)
0721 {
0722 static const char * const texts[4] = { "0", "1", "2", "3", };
0723
0724 return snd_ctl_enum_info(uinfo, 1, 4, texts);
0725 }
0726
0727 static int snd_p16v_capture_channel_get(struct snd_kcontrol *kcontrol,
0728 struct snd_ctl_elem_value *ucontrol)
0729 {
0730 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
0731
0732 ucontrol->value.enumerated.item[0] = emu->p16v_capture_channel;
0733 return 0;
0734 }
0735
0736 static int snd_p16v_capture_channel_put(struct snd_kcontrol *kcontrol,
0737 struct snd_ctl_elem_value *ucontrol)
0738 {
0739 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
0740 unsigned int val;
0741 int change = 0;
0742 u32 tmp;
0743
0744 val = ucontrol->value.enumerated.item[0] ;
0745 if (val > 3)
0746 return -EINVAL;
0747 change = (emu->p16v_capture_channel != val);
0748 if (change) {
0749 emu->p16v_capture_channel = val;
0750 tmp = snd_emu10k1_ptr20_read(emu, CAPTURE_P16V_SOURCE, 0) & 0xfffc;
0751 snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, tmp | val);
0752 }
0753 return change;
0754 }
0755 static const DECLARE_TLV_DB_SCALE(snd_p16v_db_scale1, -5175, 25, 1);
0756
0757 #define P16V_VOL(xname,xreg,xhl) { \
0758 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
0759 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
0760 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
0761 .info = snd_p16v_volume_info, \
0762 .get = snd_p16v_volume_get, \
0763 .put = snd_p16v_volume_put, \
0764 .tlv = { .p = snd_p16v_db_scale1 }, \
0765 .private_value = ((xreg) | ((xhl) << 8)) \
0766 }
0767
0768 static const struct snd_kcontrol_new p16v_mixer_controls[] = {
0769 P16V_VOL("HD Analog Front Playback Volume", PLAYBACK_VOLUME_MIXER9, 0),
0770 P16V_VOL("HD Analog Rear Playback Volume", PLAYBACK_VOLUME_MIXER10, 1),
0771 P16V_VOL("HD Analog Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER9, 1),
0772 P16V_VOL("HD Analog Side Playback Volume", PLAYBACK_VOLUME_MIXER10, 0),
0773 P16V_VOL("HD SPDIF Front Playback Volume", PLAYBACK_VOLUME_MIXER7, 0),
0774 P16V_VOL("HD SPDIF Rear Playback Volume", PLAYBACK_VOLUME_MIXER8, 1),
0775 P16V_VOL("HD SPDIF Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER7, 1),
0776 P16V_VOL("HD SPDIF Side Playback Volume", PLAYBACK_VOLUME_MIXER8, 0),
0777 {
0778 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0779 .name = "HD source Capture",
0780 .info = snd_p16v_capture_source_info,
0781 .get = snd_p16v_capture_source_get,
0782 .put = snd_p16v_capture_source_put
0783 },
0784 {
0785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0786 .name = "HD channel Capture",
0787 .info = snd_p16v_capture_channel_info,
0788 .get = snd_p16v_capture_channel_get,
0789 .put = snd_p16v_capture_channel_put
0790 },
0791 };
0792
0793
0794 int snd_p16v_mixer(struct snd_emu10k1 *emu)
0795 {
0796 int i, err;
0797 struct snd_card *card = emu->card;
0798
0799 for (i = 0; i < ARRAY_SIZE(p16v_mixer_controls); i++) {
0800 err = snd_ctl_add(card, snd_ctl_new1(&p16v_mixer_controls[i], emu));
0801 if (err < 0)
0802 return err;
0803 }
0804 return 0;
0805 }
0806
0807 #ifdef CONFIG_PM_SLEEP
0808
0809 #define NUM_CHS 1
0810
0811 int snd_p16v_alloc_pm_buffer(struct snd_emu10k1 *emu)
0812 {
0813 emu->p16v_saved = vmalloc(array_size(NUM_CHS * 4, 0x80));
0814 if (! emu->p16v_saved)
0815 return -ENOMEM;
0816 return 0;
0817 }
0818
0819 void snd_p16v_free_pm_buffer(struct snd_emu10k1 *emu)
0820 {
0821 vfree(emu->p16v_saved);
0822 }
0823
0824 void snd_p16v_suspend(struct snd_emu10k1 *emu)
0825 {
0826 int i, ch;
0827 unsigned int *val;
0828
0829 val = emu->p16v_saved;
0830 for (ch = 0; ch < NUM_CHS; ch++)
0831 for (i = 0; i < 0x80; i++, val++)
0832 *val = snd_emu10k1_ptr20_read(emu, i, ch);
0833 }
0834
0835 void snd_p16v_resume(struct snd_emu10k1 *emu)
0836 {
0837 int i, ch;
0838 unsigned int *val;
0839
0840 val = emu->p16v_saved;
0841 for (ch = 0; ch < NUM_CHS; ch++)
0842 for (i = 0; i < 0x80; i++, val++)
0843 snd_emu10k1_ptr20_write(emu, i, ch, *val);
0844 }
0845 #endif