xref: /kernel/linux/linux-5.10/sound/pci/emu10k1/p16v.c (revision 8c2ecf20)
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 */
111static 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
132static 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
152static 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 */
160static 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 */
208static 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 */
253static 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 */
264static 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
274static 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
279static 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/* prepare playback callback */
286static int snd_p16v_pcm_prepare_playback(struct snd_pcm_substream *substream)
287{
288	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
289	struct snd_pcm_runtime *runtime = substream->runtime;
290	int channel = substream->pcm->device - emu->p16v_device_offset;
291	u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel));
292	u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
293	int i;
294	u32 tmp;
295
296#if 0 /* debug */
297	dev_dbg(emu->card->dev,
298		"prepare:channel_number=%d, rate=%d, "
299		   "format=0x%x, channels=%d, buffer_size=%ld, "
300		   "period_size=%ld, periods=%u, frames_to_bytes=%d\n",
301		   channel, runtime->rate, runtime->format, runtime->channels,
302		   runtime->buffer_size, runtime->period_size,
303		   runtime->periods, frames_to_bytes(runtime, 1));
304	dev_dbg(emu->card->dev,
305		"dma_addr=%x, dma_area=%p, table_base=%p\n",
306		   runtime->dma_addr, runtime->dma_area, table_base);
307	dev_dbg(emu->card->dev,
308		"dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",
309		   emu->p16v_buffer.addr, emu->p16v_buffer.area,
310		   emu->p16v_buffer.bytes);
311#endif /* debug */
312	tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
313        switch (runtime->rate) {
314	case 44100:
315	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x8080);
316	  break;
317	case 96000:
318	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x4040);
319	  break;
320	case 192000:
321	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x2020);
322	  break;
323	case 48000:
324	default:
325	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x0000);
326	  break;
327	}
328	/* FIXME: Check emu->buffer.size before actually writing to it. */
329	for(i = 0; i < runtime->periods; i++) {
330		table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
331		table_base[(i*2)+1]=period_size_bytes<<16;
332	}
333
334	snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_ADDR, channel, emu->p16v_buffer.addr+(8*16*channel));
335	snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
336	snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0);
337	snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
338	//snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
339	snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes
340	snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0);
341	snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0);
342	snd_emu10k1_ptr20_write(emu, 0x08, channel, 0);
343
344	return 0;
345}
346
347/* prepare capture callback */
348static int snd_p16v_pcm_prepare_capture(struct snd_pcm_substream *substream)
349{
350	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
351	struct snd_pcm_runtime *runtime = substream->runtime;
352	int channel = substream->pcm->device - emu->p16v_device_offset;
353	u32 tmp;
354
355	/*
356	dev_dbg(emu->card->dev, "prepare capture:channel_number=%d, rate=%d, "
357	       "format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, "
358	       "frames_to_bytes=%d\n",
359	       channel, runtime->rate, runtime->format, runtime->channels,
360	       runtime->buffer_size, runtime->period_size,
361	       frames_to_bytes(runtime, 1));
362	*/
363	tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
364        switch (runtime->rate) {
365	case 44100:
366	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0800);
367	  break;
368	case 96000:
369	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0400);
370	  break;
371	case 192000:
372	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0200);
373	  break;
374	case 48000:
375	default:
376	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0000);
377	  break;
378	}
379	/* FIXME: Check emu->buffer.size before actually writing to it. */
380	snd_emu10k1_ptr20_write(emu, 0x13, channel, 0);
381	snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
382	snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size) << 16); // buffer size in bytes
383	snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0);
384	//snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */
385	//snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel));
386
387	return 0;
388}
389
390static void snd_p16v_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
391{
392	unsigned long flags;
393	unsigned int enable;
394
395	spin_lock_irqsave(&emu->emu_lock, flags);
396	enable = inl(emu->port + INTE2) | intrenb;
397	outl(enable, emu->port + INTE2);
398	spin_unlock_irqrestore(&emu->emu_lock, flags);
399}
400
401static void snd_p16v_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb)
402{
403	unsigned long flags;
404	unsigned int disable;
405
406	spin_lock_irqsave(&emu->emu_lock, flags);
407	disable = inl(emu->port + INTE2) & (~intrenb);
408	outl(disable, emu->port + INTE2);
409	spin_unlock_irqrestore(&emu->emu_lock, flags);
410}
411
412/* trigger_playback callback */
413static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
414				    int cmd)
415{
416	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
417	struct snd_pcm_runtime *runtime;
418	struct snd_emu10k1_pcm *epcm;
419	int channel;
420	int result = 0;
421        struct snd_pcm_substream *s;
422	u32 basic = 0;
423	u32 inte = 0;
424	int running = 0;
425
426	switch (cmd) {
427	case SNDRV_PCM_TRIGGER_START:
428		running=1;
429		break;
430	case SNDRV_PCM_TRIGGER_STOP:
431	default:
432		running = 0;
433		break;
434	}
435        snd_pcm_group_for_each_entry(s, substream) {
436		if (snd_pcm_substream_chip(s) != emu ||
437		    s->stream != SNDRV_PCM_STREAM_PLAYBACK)
438			continue;
439		runtime = s->runtime;
440		epcm = runtime->private_data;
441		channel = substream->pcm->device-emu->p16v_device_offset;
442		/* dev_dbg(emu->card->dev, "p16v channel=%d\n", channel); */
443		epcm->running = running;
444		basic |= (0x1<<channel);
445		inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel);
446                snd_pcm_trigger_done(s, substream);
447        }
448	/* dev_dbg(emu->card->dev, "basic=0x%x, inte=0x%x\n", basic, inte); */
449
450	switch (cmd) {
451	case SNDRV_PCM_TRIGGER_START:
452		snd_p16v_intr_enable(emu, inte);
453		snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)| (basic));
454		break;
455	case SNDRV_PCM_TRIGGER_STOP:
456		snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
457		snd_p16v_intr_disable(emu, inte);
458		break;
459	default:
460		result = -EINVAL;
461		break;
462	}
463	return result;
464}
465
466/* trigger_capture callback */
467static int snd_p16v_pcm_trigger_capture(struct snd_pcm_substream *substream,
468                                   int cmd)
469{
470	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
471	struct snd_pcm_runtime *runtime = substream->runtime;
472	struct snd_emu10k1_pcm *epcm = runtime->private_data;
473	int channel = 0;
474	int result = 0;
475	u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP;
476
477	switch (cmd) {
478	case SNDRV_PCM_TRIGGER_START:
479		snd_p16v_intr_enable(emu, inte);
480		snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
481		epcm->running = 1;
482		break;
483	case SNDRV_PCM_TRIGGER_STOP:
484		snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));
485		snd_p16v_intr_disable(emu, inte);
486		//snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel));
487		epcm->running = 0;
488		break;
489	default:
490		result = -EINVAL;
491		break;
492	}
493	return result;
494}
495
496/* pointer_playback callback */
497static snd_pcm_uframes_t
498snd_p16v_pcm_pointer_playback(struct snd_pcm_substream *substream)
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	snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
504	int channel = substream->pcm->device - emu->p16v_device_offset;
505	if (!epcm->running)
506		return 0;
507
508	ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
509	ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
510	ptr4 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
511	if (ptr3 != ptr4) ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
512	ptr2 = bytes_to_frames(runtime, ptr1);
513	ptr2+= (ptr4 >> 3) * runtime->period_size;
514	ptr=ptr2;
515        if (ptr >= runtime->buffer_size)
516		ptr -= runtime->buffer_size;
517
518	return ptr;
519}
520
521/* pointer_capture callback */
522static snd_pcm_uframes_t
523snd_p16v_pcm_pointer_capture(struct snd_pcm_substream *substream)
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	snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
529	int channel = 0;
530
531	if (!epcm->running)
532		return 0;
533
534	ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel);
535	ptr2 = bytes_to_frames(runtime, ptr1);
536	ptr=ptr2;
537	if (ptr >= runtime->buffer_size) {
538		ptr -= runtime->buffer_size;
539		dev_warn(emu->card->dev, "buffer capture limited!\n");
540	}
541	/*
542	dev_dbg(emu->card->dev, "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, "
543	       "buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n",
544	       ptr1, ptr2, ptr, (int)runtime->buffer_size,
545	       (int)runtime->period_size, (int)runtime->frame_bits,
546	       (int)runtime->rate);
547	*/
548	return ptr;
549}
550
551/* operators */
552static const struct snd_pcm_ops snd_p16v_playback_front_ops = {
553	.open =        snd_p16v_pcm_open_playback_front,
554	.close =       snd_p16v_pcm_close_playback,
555	.prepare =     snd_p16v_pcm_prepare_playback,
556	.trigger =     snd_p16v_pcm_trigger_playback,
557	.pointer =     snd_p16v_pcm_pointer_playback,
558};
559
560static const struct snd_pcm_ops snd_p16v_capture_ops = {
561	.open =        snd_p16v_pcm_open_capture,
562	.close =       snd_p16v_pcm_close_capture,
563	.prepare =     snd_p16v_pcm_prepare_capture,
564	.trigger =     snd_p16v_pcm_trigger_capture,
565	.pointer =     snd_p16v_pcm_pointer_capture,
566};
567
568
569int snd_p16v_free(struct snd_emu10k1 *chip)
570{
571	// release the data
572	if (chip->p16v_buffer.area) {
573		snd_dma_free_pages(&chip->p16v_buffer);
574		/*
575		dev_dbg(chip->card->dev, "period lables free: %p\n",
576			   &chip->p16v_buffer);
577		*/
578	}
579	return 0;
580}
581
582int snd_p16v_pcm(struct snd_emu10k1 *emu, int device)
583{
584	struct snd_pcm *pcm;
585	struct snd_pcm_substream *substream;
586	int err;
587        int capture=1;
588
589	/* dev_dbg(emu->card->dev, "snd_p16v_pcm called. device=%d\n", device); */
590	emu->p16v_device_offset = device;
591
592	if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0)
593		return err;
594
595	pcm->private_data = emu;
596	// Single playback 8 channel device.
597	// Single capture 2 channel device.
598	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops);
599	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_p16v_capture_ops);
600
601	pcm->info_flags = 0;
602	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
603	strcpy(pcm->name, "p16v");
604	emu->pcm_p16v = pcm;
605
606	for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
607	    substream;
608	    substream = substream->next) {
609		snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV,
610					   &emu->pci->dev,
611					   (65536 - 64) * 8,
612					   (65536 - 64) * 8);
613		/*
614		dev_dbg(emu->card->dev,
615			   "preallocate playback substream: err=%d\n", err);
616		*/
617	}
618
619	for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
620	      substream;
621	      substream = substream->next) {
622		snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV,
623					   &emu->pci->dev,
624					   65536 - 64, 65536 - 64);
625		/*
626		dev_dbg(emu->card->dev,
627			   "preallocate capture substream: err=%d\n", err);
628		*/
629	}
630
631	return 0;
632}
633
634static int snd_p16v_volume_info(struct snd_kcontrol *kcontrol,
635				struct snd_ctl_elem_info *uinfo)
636{
637        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
638        uinfo->count = 2;
639        uinfo->value.integer.min = 0;
640        uinfo->value.integer.max = 255;
641        return 0;
642}
643
644static int snd_p16v_volume_get(struct snd_kcontrol *kcontrol,
645			       struct snd_ctl_elem_value *ucontrol)
646{
647        struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
648	int high_low = (kcontrol->private_value >> 8) & 0xff;
649	int reg = kcontrol->private_value & 0xff;
650	u32 value;
651
652	value = snd_emu10k1_ptr20_read(emu, reg, high_low);
653	if (high_low) {
654		ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
655		ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
656	} else {
657		ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */
658		ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */
659	}
660	return 0;
661}
662
663static int snd_p16v_volume_put(struct snd_kcontrol *kcontrol,
664			       struct snd_ctl_elem_value *ucontrol)
665{
666        struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
667	int high_low = (kcontrol->private_value >> 8) & 0xff;
668	int reg = kcontrol->private_value & 0xff;
669        u32 value, oval;
670
671	oval = value = snd_emu10k1_ptr20_read(emu, reg, 0);
672	if (high_low == 1) {
673		value &= 0xffff;
674		value |= ((0xff - ucontrol->value.integer.value[0]) << 24) |
675			((0xff - ucontrol->value.integer.value[1]) << 16);
676	} else {
677		value &= 0xffff0000;
678		value |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
679			((0xff - ucontrol->value.integer.value[1]) );
680	}
681	if (value != oval) {
682		snd_emu10k1_ptr20_write(emu, reg, 0, value);
683		return 1;
684	}
685	return 0;
686}
687
688static int snd_p16v_capture_source_info(struct snd_kcontrol *kcontrol,
689					struct snd_ctl_elem_info *uinfo)
690{
691	static const char * const texts[8] = {
692		"SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S",
693		"CDIF", "FX", "AC97"
694	};
695
696	return snd_ctl_enum_info(uinfo, 1, 8, texts);
697}
698
699static int snd_p16v_capture_source_get(struct snd_kcontrol *kcontrol,
700					struct snd_ctl_elem_value *ucontrol)
701{
702	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
703
704	ucontrol->value.enumerated.item[0] = emu->p16v_capture_source;
705	return 0;
706}
707
708static int snd_p16v_capture_source_put(struct snd_kcontrol *kcontrol,
709					struct snd_ctl_elem_value *ucontrol)
710{
711	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
712	unsigned int val;
713	int change = 0;
714	u32 mask;
715	u32 source;
716
717	val = ucontrol->value.enumerated.item[0] ;
718	if (val > 7)
719		return -EINVAL;
720	change = (emu->p16v_capture_source != val);
721	if (change) {
722		emu->p16v_capture_source = val;
723		source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
724		mask = snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & 0xffff;
725		snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, source | mask);
726	}
727        return change;
728}
729
730static int snd_p16v_capture_channel_info(struct snd_kcontrol *kcontrol,
731					 struct snd_ctl_elem_info *uinfo)
732{
733	static const char * const texts[4] = { "0", "1", "2", "3", };
734
735	return snd_ctl_enum_info(uinfo, 1, 4, texts);
736}
737
738static int snd_p16v_capture_channel_get(struct snd_kcontrol *kcontrol,
739					struct snd_ctl_elem_value *ucontrol)
740{
741	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
742
743	ucontrol->value.enumerated.item[0] = emu->p16v_capture_channel;
744	return 0;
745}
746
747static int snd_p16v_capture_channel_put(struct snd_kcontrol *kcontrol,
748					struct snd_ctl_elem_value *ucontrol)
749{
750	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
751	unsigned int val;
752	int change = 0;
753	u32 tmp;
754
755	val = ucontrol->value.enumerated.item[0] ;
756	if (val > 3)
757		return -EINVAL;
758	change = (emu->p16v_capture_channel != val);
759	if (change) {
760		emu->p16v_capture_channel = val;
761		tmp = snd_emu10k1_ptr20_read(emu, CAPTURE_P16V_SOURCE, 0) & 0xfffc;
762		snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, tmp | val);
763	}
764        return change;
765}
766static const DECLARE_TLV_DB_SCALE(snd_p16v_db_scale1, -5175, 25, 1);
767
768#define P16V_VOL(xname,xreg,xhl) { \
769	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
770        .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |             \
771                  SNDRV_CTL_ELEM_ACCESS_TLV_READ,               \
772	.info = snd_p16v_volume_info, \
773	.get = snd_p16v_volume_get, \
774	.put = snd_p16v_volume_put, \
775	.tlv = { .p = snd_p16v_db_scale1 },	\
776	.private_value = ((xreg) | ((xhl) << 8)) \
777}
778
779static const struct snd_kcontrol_new p16v_mixer_controls[] = {
780	P16V_VOL("HD Analog Front Playback Volume", PLAYBACK_VOLUME_MIXER9, 0),
781	P16V_VOL("HD Analog Rear Playback Volume", PLAYBACK_VOLUME_MIXER10, 1),
782	P16V_VOL("HD Analog Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER9, 1),
783	P16V_VOL("HD Analog Side Playback Volume", PLAYBACK_VOLUME_MIXER10, 0),
784	P16V_VOL("HD SPDIF Front Playback Volume", PLAYBACK_VOLUME_MIXER7, 0),
785	P16V_VOL("HD SPDIF Rear Playback Volume", PLAYBACK_VOLUME_MIXER8, 1),
786	P16V_VOL("HD SPDIF Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER7, 1),
787	P16V_VOL("HD SPDIF Side Playback Volume", PLAYBACK_VOLUME_MIXER8, 0),
788	{
789		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
790		.name =		"HD source Capture",
791		.info =		snd_p16v_capture_source_info,
792		.get =		snd_p16v_capture_source_get,
793		.put =		snd_p16v_capture_source_put
794	},
795	{
796		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
797		.name =		"HD channel Capture",
798		.info =		snd_p16v_capture_channel_info,
799		.get =		snd_p16v_capture_channel_get,
800		.put =		snd_p16v_capture_channel_put
801	},
802};
803
804
805int snd_p16v_mixer(struct snd_emu10k1 *emu)
806{
807	int i, err;
808        struct snd_card *card = emu->card;
809
810	for (i = 0; i < ARRAY_SIZE(p16v_mixer_controls); i++) {
811		if ((err = snd_ctl_add(card, snd_ctl_new1(&p16v_mixer_controls[i],
812							  emu))) < 0)
813			return err;
814	}
815        return 0;
816}
817
818#ifdef CONFIG_PM_SLEEP
819
820#define NUM_CHS	1	/* up to 4, but only first channel is used */
821
822int snd_p16v_alloc_pm_buffer(struct snd_emu10k1 *emu)
823{
824	emu->p16v_saved = vmalloc(array_size(NUM_CHS * 4, 0x80));
825	if (! emu->p16v_saved)
826		return -ENOMEM;
827	return 0;
828}
829
830void snd_p16v_free_pm_buffer(struct snd_emu10k1 *emu)
831{
832	vfree(emu->p16v_saved);
833}
834
835void snd_p16v_suspend(struct snd_emu10k1 *emu)
836{
837	int i, ch;
838	unsigned int *val;
839
840	val = emu->p16v_saved;
841	for (ch = 0; ch < NUM_CHS; ch++)
842		for (i = 0; i < 0x80; i++, val++)
843			*val = snd_emu10k1_ptr20_read(emu, i, ch);
844}
845
846void snd_p16v_resume(struct snd_emu10k1 *emu)
847{
848	int i, ch;
849	unsigned int *val;
850
851	val = emu->p16v_saved;
852	for (ch = 0; ch < NUM_CHS; ch++)
853		for (i = 0; i < 0x80; i++, val++)
854			snd_emu10k1_ptr20_write(emu, i, ch, *val);
855}
856#endif
857