aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ctxfi
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-06-02 15:55:22 +0200
committerTakashi Iwai <tiwai@suse.de>2009-06-02 15:55:22 +0200
commitbd05dbd3b22612455283610b4e006ee3e421b13d (patch)
tree06868be09771d6908acd657b1a9f66b0fb209bce /sound/pci/ctxfi
parent67fbf880631bb4493ad8d23f25562abdf09dc01d (diff)
parentc76157d9286ed598c241c212aa5a3c6e5107bd82 (diff)
downloadkernel_samsung_smdk4412-bd05dbd3b22612455283610b4e006ee3e421b13d.zip
kernel_samsung_smdk4412-bd05dbd3b22612455283610b4e006ee3e421b13d.tar.gz
kernel_samsung_smdk4412-bd05dbd3b22612455283610b4e006ee3e421b13d.tar.bz2
Merge branch 'topic/ctxfi-fix' into topic/ctxfi
Diffstat (limited to 'sound/pci/ctxfi')
-rw-r--r--sound/pci/ctxfi/ctatc.c35
-rw-r--r--sound/pci/ctxfi/ctatc.h5
-rw-r--r--sound/pci/ctxfi/cthw20k1.c16
-rw-r--r--sound/pci/ctxfi/cthw20k2.c17
-rw-r--r--sound/pci/ctxfi/ctmixer.c8
-rw-r--r--sound/pci/ctxfi/ctpcm.c25
-rw-r--r--sound/pci/ctxfi/ctvmem.c77
-rw-r--r--sound/pci/ctxfi/ctvmem.h16
8 files changed, 92 insertions, 107 deletions
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index ead104e..6849475 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -72,15 +72,15 @@ static struct {
[FRONT] = { .create = ct_alsa_pcm_create,
.destroy = NULL,
.public_name = "Front/WaveIn"},
- [REAR] = { .create = ct_alsa_pcm_create,
+ [SURROUND] = { .create = ct_alsa_pcm_create,
.destroy = NULL,
- .public_name = "Rear"},
+ .public_name = "Surround"},
[CLFE] = { .create = ct_alsa_pcm_create,
.destroy = NULL,
.public_name = "Center/LFE"},
- [SURROUND] = { .create = ct_alsa_pcm_create,
+ [SIDE] = { .create = ct_alsa_pcm_create,
.destroy = NULL,
- .public_name = "Surround"},
+ .public_name = "Side"},
[IEC958] = { .create = ct_alsa_pcm_create,
.destroy = NULL,
.public_name = "IEC958 Non-audio"},
@@ -119,7 +119,6 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm);
static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
{
- unsigned long flags;
struct snd_pcm_runtime *runtime;
struct ct_vm *vm;
@@ -129,9 +128,7 @@ static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
runtime = apcm->substream->runtime;
vm = atc->vm;
- spin_lock_irqsave(&atc->vm_lock, flags);
- apcm->vm_block = vm->map(vm, runtime->dma_area, runtime->dma_bytes);
- spin_unlock_irqrestore(&atc->vm_lock, flags);
+ apcm->vm_block = vm->map(vm, apcm->substream, runtime->dma_bytes);
if (NULL == apcm->vm_block)
return -ENOENT;
@@ -141,7 +138,6 @@ static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
{
- unsigned long flags;
struct ct_vm *vm;
if (NULL == apcm->vm_block)
@@ -149,9 +145,7 @@ static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
vm = atc->vm;
- spin_lock_irqsave(&atc->vm_lock, flags);
vm->unmap(vm, apcm->vm_block);
- spin_unlock_irqrestore(&atc->vm_lock, flags);
apcm->vm_block = NULL;
}
@@ -161,9 +155,7 @@ static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index)
struct ct_vm *vm;
void *kvirt_addr;
unsigned long phys_addr;
- unsigned long flags;
- spin_lock_irqsave(&atc->vm_lock, flags);
vm = atc->vm;
kvirt_addr = vm->get_ptp_virt(vm, index);
if (kvirt_addr == NULL)
@@ -171,8 +163,6 @@ static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index)
else
phys_addr = virt_to_phys(kvirt_addr);
- spin_unlock_irqrestore(&atc->vm_lock, flags);
-
return phys_addr;
}
@@ -180,16 +170,15 @@ static unsigned int convert_format(snd_pcm_format_t snd_format)
{
switch (snd_format) {
case SNDRV_PCM_FORMAT_U8:
- case SNDRV_PCM_FORMAT_S8:
return SRC_SF_U8;
case SNDRV_PCM_FORMAT_S16_LE:
- case SNDRV_PCM_FORMAT_U16_LE:
return SRC_SF_S16;
case SNDRV_PCM_FORMAT_S24_3LE:
return SRC_SF_S24;
- case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S32_LE:
return SRC_SF_S32;
+ case SNDRV_PCM_FORMAT_FLOAT_LE:
+ return SRC_SF_F32;
default:
printk(KERN_ERR "ctxfi: not recognized snd format is %d \n",
snd_format);
@@ -264,6 +253,9 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
return 0;
}
+ /* first release old resources */
+ atc->pcm_release_resources(atc, apcm);
+
/* Get SRC resource */
desc.multi = apcm->substream->runtime->channels;
desc.msr = atc->msr;
@@ -506,6 +498,9 @@ atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
int n_srcimp = 0, n_amixer = 0, n_srcc = 0, n_sum = 0;
struct src_node_conf_t src_node_conf[2] = {{0} };
+ /* first release old resources */
+ atc->pcm_release_resources(atc, apcm);
+
/* The numbers of converting SRCs and SRCIMPs should be determined
* by pitch value. */
@@ -777,6 +772,9 @@ static int spdif_passthru_playback_get_resources(struct ct_atc *atc,
int n_amixer = apcm->substream->runtime->channels, i = 0;
unsigned int pitch = 0, rsr = atc->pll_rate;
+ /* first release old resources */
+ atc->pcm_release_resources(atc, apcm);
+
/* Get SRC resource */
desc.multi = apcm->substream->runtime->channels;
desc.msr = 1;
@@ -1562,7 +1560,6 @@ int ct_atc_create(struct snd_card *card, struct pci_dev *pci,
atc_set_ops(atc);
spin_lock_init(&atc->atc_lock);
- spin_lock_init(&atc->vm_lock);
/* Find card model */
err = atc_identify_card(atc);
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index 286c993..b86d12c 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -29,9 +29,9 @@
enum CTALSADEVS { /* Types of alsa devices */
FRONT,
- REAR,
- CLFE,
SURROUND,
+ CLFE,
+ SIDE,
IEC958,
MIXER,
NUM_CTALSADEVS /* This should always be the last */
@@ -101,7 +101,6 @@ struct ct_atc {
unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index);
spinlock_t atc_lock;
- spinlock_t vm_lock;
int (*pcm_playback_prepare)(struct ct_atc *atc,
struct ct_atc_pcm *apcm);
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index 44283bd..b7b8e6f 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -1249,19 +1249,15 @@ static int hw_trn_init(struct hw *hw, const struct trn_conf *info)
}
trnctl = 0x13; /* 32-bit, 4k-size page */
-#if BITS_PER_LONG == 64
- ptp_phys_low = info->vm_pgt_phys & ((1UL<<32)-1);
- ptp_phys_high = (info->vm_pgt_phys>>32) & ((1UL<<32)-1);
- trnctl |= (1<<2);
-#elif BITS_PER_LONG == 32
- ptp_phys_low = info->vm_pgt_phys & (~0UL);
- ptp_phys_high = 0;
-#else
-# error "Unknown BITS_PER_LONG!"
-#endif
+ ptp_phys_low = (u32)info->vm_pgt_phys;
+ ptp_phys_high = upper_32_bits(info->vm_pgt_phys);
+ if (sizeof(void *) == 8) /* 64bit address */
+ trnctl |= (1 << 2);
+#if 0 /* Only 4k h/w pages for simplicitiy */
#if PAGE_SIZE == 8192
trnctl |= (1<<5);
#endif
+#endif
hw_write_20kx(hw, PTPALX, ptp_phys_low);
hw_write_20kx(hw, PTPAHX, ptp_phys_high);
hw_write_20kx(hw, TRNCTL, trnctl);
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index 7c24c2c..3497287 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -1203,19 +1203,10 @@ static int hw_trn_init(struct hw *hw, const struct trn_conf *info)
}
vmctl = 0x80000C0F; /* 32-bit, 4k-size page */
-#if BITS_PER_LONG == 64
- ptp_phys_low = info->vm_pgt_phys & ((1UL<<32)-1);
- ptp_phys_high = (info->vm_pgt_phys>>32) & ((1UL<<32)-1);
- vmctl |= (3<<8);
-#elif BITS_PER_LONG == 32
- ptp_phys_low = info->vm_pgt_phys & (~0UL);
- ptp_phys_high = 0;
-#else
-# error "Unknown BITS_PER_LONG!"
-#endif
-#if PAGE_SIZE == 8192
-# error "Don't support 8k-page!"
-#endif
+ ptp_phys_low = (u32)info->vm_pgt_phys;
+ ptp_phys_high = upper_32_bits(info->vm_pgt_phys);
+ if (sizeof(void *) == 8) /* 64bit address */
+ vmctl |= (3 << 8);
/* Write page table physical address to all PTPAL registers */
for (i = 0; i < 64; i++) {
hw_write_20kx(hw, VMEM_PTPAL+(16*i), ptp_phys_low);
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c
index b795076..177c46e 100644
--- a/sound/pci/ctxfi/ctmixer.c
+++ b/sound/pci/ctxfi/ctmixer.c
@@ -168,7 +168,7 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
},
[MIXER_WAVES_P] = {
.ctl = 1,
- .name = "Surround Playback Volume",
+ .name = "Side Playback Volume",
},
[MIXER_WAVEC_P] = {
.ctl = 1,
@@ -176,7 +176,7 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
},
[MIXER_WAVER_P] = {
.ctl = 1,
- .name = "Rear Playback Volume",
+ .name = "Surround Playback Volume",
},
[MIXER_PCM_C_S] = {
@@ -213,7 +213,7 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
},
[MIXER_WAVES_P_S] = {
.ctl = 1,
- .name = "Surround Playback Switch",
+ .name = "Side Playback Switch",
},
[MIXER_WAVEC_P_S] = {
.ctl = 1,
@@ -221,7 +221,7 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
},
[MIXER_WAVER_P_S] = {
.ctl = 1,
- .name = "Rear Playback Switch",
+ .name = "Surround Playback Switch",
},
[MIXER_DIGITAL_IO_S] = {
.ctl = 0,
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c
index a64cb0e..52ddf19 100644
--- a/sound/pci/ctxfi/ctpcm.c
+++ b/sound/pci/ctxfi/ctpcm.c
@@ -26,12 +26,10 @@ static struct snd_pcm_hardware ct_pcm_playback_hw = {
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE),
.formats = (SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_U16_LE |
SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE),
+ SNDRV_PCM_FMTBIT_S32_LE |
+ SNDRV_PCM_FMTBIT_FLOAT_LE),
.rates = (SNDRV_PCM_RATE_CONTINUOUS |
SNDRV_PCM_RATE_8000_192000),
.rate_min = 8000,
@@ -52,8 +50,7 @@ static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = {
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE),
- .formats = (SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_U16_LE),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = (SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_32000),
@@ -77,12 +74,10 @@ static struct snd_pcm_hardware ct_pcm_capture_hw = {
SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_MMAP_VALID),
.formats = (SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_U16_LE |
SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE),
+ SNDRV_PCM_FMTBIT_S32_LE |
+ SNDRV_PCM_FMTBIT_FLOAT_LE),
.rates = (SNDRV_PCM_RATE_CONTINUOUS |
SNDRV_PCM_RATE_8000_96000),
.rate_min = 8000,
@@ -447,6 +442,7 @@ static struct snd_pcm_ops ct_pcm_playback_ops = {
.prepare = ct_pcm_playback_prepare,
.trigger = ct_pcm_playback_trigger,
.pointer = ct_pcm_playback_pointer,
+ .page = snd_pcm_sgbuf_ops_page,
};
/* PCM operators for capture */
@@ -459,6 +455,7 @@ static struct snd_pcm_ops ct_pcm_capture_ops = {
.prepare = ct_pcm_capture_prepare,
.trigger = ct_pcm_capture_trigger,
.pointer = ct_pcm_capture_pointer,
+ .page = snd_pcm_sgbuf_ops_page,
};
/* Create ALSA pcm device */
@@ -469,12 +466,10 @@ int ct_alsa_pcm_create(struct ct_atc *atc,
struct snd_pcm *pcm;
int err;
int playback_count, capture_count;
- char name[128];
- strncpy(name, device_name, sizeof(name));
playback_count = (IEC958 == device) ? 1 : 8;
capture_count = (FRONT == device) ? 1 : 0;
- err = snd_pcm_new(atc->card, name, device,
+ err = snd_pcm_new(atc->card, "ctxfi", device,
playback_count, capture_count, &pcm);
if (err < 0) {
printk(KERN_ERR "ctxfi: snd_pcm_new failed!! Err=%d\n", err);
@@ -484,7 +479,7 @@ int ct_alsa_pcm_create(struct ct_atc *atc,
pcm->private_data = atc;
pcm->info_flags = 0;
pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
- strcpy(pcm->name, device_name);
+ strlcpy(pcm->name, device_name, sizeof(pcm->name));
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops);
@@ -492,7 +487,7 @@ int ct_alsa_pcm_create(struct ct_atc *atc,
snd_pcm_set_ops(pcm,
SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops);
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
return 0;
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
index cecf77e..b7f8e58 100644
--- a/sound/pci/ctxfi/ctvmem.c
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -18,12 +18,11 @@
#include "ctvmem.h"
#include <linux/slab.h>
#include <linux/mm.h>
-#include <asm/page.h> /* for PAGE_SIZE macro definition */
#include <linux/io.h>
-#include <asm/pgtable.h>
+#include <sound/pcm.h>
-#define CT_PTES_PER_PAGE (PAGE_SIZE / sizeof(void *))
-#define CT_ADDRS_PER_PAGE (CT_PTES_PER_PAGE * PAGE_SIZE)
+#define CT_PTES_PER_PAGE (CT_PAGE_SIZE / sizeof(void *))
+#define CT_ADDRS_PER_PAGE (CT_PTES_PER_PAGE * CT_PAGE_SIZE)
/* *
* Find or create vm block based on requested @size.
@@ -35,25 +34,34 @@ get_vm_block(struct ct_vm *vm, unsigned int size)
struct ct_vm_block *block = NULL, *entry = NULL;
struct list_head *pos = NULL;
+ size = CT_PAGE_ALIGN(size);
+ if (size > vm->size) {
+ printk(KERN_ERR "ctxfi: Fail! No sufficient device virtural "
+ "memory space available!\n");
+ return NULL;
+ }
+
+ mutex_lock(&vm->lock);
list_for_each(pos, &vm->unused) {
entry = list_entry(pos, struct ct_vm_block, list);
if (entry->size >= size)
break; /* found a block that is big enough */
}
if (pos == &vm->unused)
- return NULL;
+ goto out;
if (entry->size == size) {
/* Move the vm node from unused list to used list directly */
list_del(&entry->list);
list_add(&entry->list, &vm->used);
vm->size -= size;
- return entry;
+ block = entry;
+ goto out;
}
block = kzalloc(sizeof(*block), GFP_KERNEL);
if (NULL == block)
- return NULL;
+ goto out;
block->addr = entry->addr;
block->size = size;
@@ -62,6 +70,8 @@ get_vm_block(struct ct_vm *vm, unsigned int size)
entry->size -= size;
vm->size -= size;
+ out:
+ mutex_unlock(&vm->lock);
return block;
}
@@ -70,6 +80,9 @@ static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block)
struct ct_vm_block *entry = NULL, *pre_ent = NULL;
struct list_head *pos = NULL, *pre = NULL;
+ block->size = CT_PAGE_ALIGN(block->size);
+
+ mutex_lock(&vm->lock);
list_del(&block->list);
vm->size += block->size;
@@ -106,61 +119,41 @@ static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block)
pos = pre;
pre = pos->prev;
}
+ mutex_unlock(&vm->lock);
}
/* Map host addr (kmalloced/vmalloced) to device logical addr. */
static struct ct_vm_block *
-ct_vm_map(struct ct_vm *vm, void *host_addr, int size)
+ct_vm_map(struct ct_vm *vm, struct snd_pcm_substream *substream, int size)
{
- struct ct_vm_block *block = NULL;
- unsigned long pte_start;
- unsigned long i;
- unsigned long pages;
- unsigned long start_phys;
+ struct ct_vm_block *block;
+ unsigned int pte_start;
+ unsigned i, pages;
unsigned long *ptp;
- /* do mapping */
- if ((unsigned long)host_addr >= VMALLOC_START) {
- printk(KERN_ERR "ctxfi: "
- "Fail! Not support vmalloced addr now!\n");
- return NULL;
- }
-
- if (size > vm->size) {
- printk(KERN_ERR "ctxfi: Fail! No sufficient device virtural "
- "memory space available!\n");
- return NULL;
- }
-
- start_phys = (virt_to_phys(host_addr) & PAGE_MASK);
- pages = (PAGE_ALIGN(virt_to_phys(host_addr) + size)
- - start_phys) >> PAGE_SHIFT;
-
- ptp = vm->ptp[0];
-
- block = get_vm_block(vm, (pages << PAGE_SHIFT));
+ block = get_vm_block(vm, size);
if (block == NULL) {
printk(KERN_ERR "ctxfi: No virtual memory block that is big "
"enough to allocate!\n");
return NULL;
}
- pte_start = (block->addr >> PAGE_SHIFT);
- for (i = 0; i < pages; i++)
- ptp[pte_start+i] = start_phys + (i << PAGE_SHIFT);
+ ptp = vm->ptp[0];
+ pte_start = (block->addr >> CT_PAGE_SHIFT);
+ pages = block->size >> CT_PAGE_SHIFT;
+ for (i = 0; i < pages; i++) {
+ unsigned long addr;
+ addr = snd_pcm_sgbuf_get_addr(substream, i << CT_PAGE_SHIFT);
+ ptp[pte_start + i] = addr;
+ }
- block->addr += (virt_to_phys(host_addr) & (~PAGE_MASK));
block->size = size;
-
return block;
}
static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block)
{
/* do unmapping */
- block->size = ((block->addr + block->size + PAGE_SIZE - 1)
- & PAGE_MASK) - (block->addr & PAGE_MASK);
- block->addr &= PAGE_MASK;
put_vm_block(vm, block);
}
@@ -191,6 +184,8 @@ int ct_vm_create(struct ct_vm **rvm)
if (NULL == vm)
return -ENOMEM;
+ mutex_init(&vm->lock);
+
/* Allocate page table pages */
for (i = 0; i < CT_PTP_NUM; i++) {
vm->ptp[i] = kmalloc(PAGE_SIZE, GFP_KERNEL);
diff --git a/sound/pci/ctxfi/ctvmem.h b/sound/pci/ctxfi/ctvmem.h
index 4eb5bdd..01e4fd0 100644
--- a/sound/pci/ctxfi/ctvmem.h
+++ b/sound/pci/ctxfi/ctvmem.h
@@ -20,24 +20,36 @@
#define CT_PTP_NUM 1 /* num of device page table pages */
-#include <linux/spinlock.h>
+#include <linux/mutex.h>
#include <linux/list.h>
+/* The chip can handle the page table of 4k pages
+ * (emu20k1 can handle even 8k pages, but we don't use it right now)
+ */
+#define CT_PAGE_SIZE 4096
+#define CT_PAGE_SHIFT 12
+#define CT_PAGE_MASK (~(PAGE_SIZE - 1))
+#define CT_PAGE_ALIGN(addr) ALIGN(addr, CT_PAGE_SIZE)
+
struct ct_vm_block {
unsigned int addr; /* starting logical addr of this block */
unsigned int size; /* size of this device virtual mem block */
struct list_head list;
};
+struct snd_pcm_substream;
+
/* Virtual memory management object for card device */
struct ct_vm {
void *ptp[CT_PTP_NUM]; /* Device page table pages */
unsigned int size; /* Available addr space in bytes */
struct list_head unused; /* List of unused blocks */
struct list_head used; /* List of used blocks */
+ struct mutex lock;
/* Map host addr (kmalloced/vmalloced) to device logical addr. */
- struct ct_vm_block *(*map)(struct ct_vm *, void *host_addr, int size);
+ struct ct_vm_block *(*map)(struct ct_vm *, struct snd_pcm_substream *,
+ int size);
/* Unmap device logical addr area. */
void (*unmap)(struct ct_vm *, struct ct_vm_block *block);
void *(*get_ptp_virt)(struct ct_vm *vm, int index);