Update of /cvsroot/alsa/alsa-kernel/pci/ice1712 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9698/pci/ice1712
Modified Files: ice1712.c ice1712.h ice1724.c Log Message: - added the support of independent surround PCM for ice1724. Index: ice1712.c =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/pci/ice1712/ice1712.c,v retrieving revision 1.40 retrieving revision 1.41 diff -u -r1.40 -r1.41 --- ice1712.c 21 Jan 2004 18:32:47 -0000 1.40 +++ ice1712.c 10 Feb 2004 15:35:03 -0000 1.41 @@ -2375,6 +2375,7 @@ ice->omni = omni ? 1 : 0; spin_lock_init(&ice->reg_lock); init_MUTEX(&ice->gpio_mutex); + init_MUTEX(&ice->open_mutex); ice->gpio.set_mask = snd_ice1712_set_gpio_mask; ice->gpio.set_dir = snd_ice1712_set_gpio_dir; ice->gpio.set_data = snd_ice1712_set_gpio_data; Index: ice1712.h =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/pci/ice1712/ice1712.h,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- ice1712.h 29 Dec 2003 15:41:45 -0000 1.15 +++ ice1712.h 10 Feb 2004 15:35:03 -0000 1.16 @@ -335,6 +335,9 @@ unsigned short hoontech_boxconfig[4]; unsigned int cur_rate; /* current rate */ + struct semaphore open_mutex; + snd_pcm_substream_t *pcm_reserved[4]; + unsigned int akm_codecs; akm4xxx_t *akm; struct snd_ice1712_spdif spdif; Index: ice1724.c =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/pci/ice1712/ice1724.c,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- ice1724.c 2 Feb 2004 13:47:55 -0000 1.24 +++ ice1724.c 10 Feb 2004 15:35:03 -0000 1.25 @@ -237,6 +237,18 @@ if (ice->capture_pro_substream) snd_pcm_period_elapsed(ice->capture_pro_substream); } + if (mtstat & VT1724_MULTI_PDMA1) { + if (ice->playback_con_substream_ds[0]) + snd_pcm_period_elapsed(ice->playback_con_substream_ds[0]); + } + if (mtstat & VT1724_MULTI_PDMA2) { + if (ice->playback_con_substream_ds[1]) + snd_pcm_period_elapsed(ice->playback_con_substream_ds[1]); + } + if (mtstat & VT1724_MULTI_PDMA3) { + if (ice->playback_con_substream_ds[2]) + snd_pcm_period_elapsed(ice->playback_con_substream_ds[2]); + } if (mtstat & VT1724_MULTI_PDMA4) { if (ice->playback_con_substream) snd_pcm_period_elapsed(ice->playback_con_substream); @@ -282,16 +294,6 @@ .mask = 0, }; -static unsigned int hw_channels[] = { - 2, 4, 6, 8 -}; - -static snd_pcm_hw_constraint_list_t hw_constraints_channels = { - .count = ARRAY_SIZE(hw_channels), - .list = hw_channels, - .mask = 0, -}; - static int snd_vt1724_pcm_trigger(snd_pcm_substream_t *substream, int cmd) { ice1712_t *ice = snd_pcm_substream_chip(substream); @@ -300,21 +302,16 @@ struct list_head *pos; snd_pcm_substream_t *s; + what = 0; + snd_pcm_group_for_each(pos, substream) { + s = snd_pcm_group_substream_entry(pos); + what |= (unsigned long)(s->runtime->private_data); + snd_pcm_trigger_done(s, substream); + } + switch (cmd) { case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - what = 0; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); - if (s == ice->playback_pro_substream) - what |= VT1724_PDMA0_PAUSE; - else if (s == ice->capture_pro_substream) - what |= VT1724_RDMA0_PAUSE; - else if (s == ice->playback_con_substream) - what |= VT1724_PDMA4_PAUSE; - else if (s == ice->capture_con_substream) - what |= VT1724_RDMA1_PAUSE; - } spin_lock(&ice->reg_lock); old = inb(ICEMT1724(ice, DMA_PAUSE)); if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) @@ -327,24 +324,6 @@ case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_STOP: - what = 0; - s = substream; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); - if (s == ice->playback_pro_substream) { - what |= VT1724_PDMA0_START; - snd_pcm_trigger_done(s, substream); - } else if (s == ice->capture_pro_substream) { - what |= VT1724_RDMA0_START; - snd_pcm_trigger_done(s, substream); - } else if (s == ice->playback_con_substream) { - what |= VT1724_PDMA4_START; - snd_pcm_trigger_done(s, substream); - } else if (s == ice->capture_con_substream) { - what |= VT1724_RDMA1_START; - snd_pcm_trigger_done(s, substream); - } - } spin_lock(&ice->reg_lock); old = inb(ICEMT1724(ice, DMA_CONTROL)); if (cmd == SNDRV_PCM_TRIGGER_START) @@ -364,8 +343,10 @@ /* */ -#define DMA_STARTS (VT1724_RDMA0_START|VT1724_PDMA0_START|VT1724_RDMA1_START|VT1724_PDMA4_START) -#define DMA_PAUSES (VT1724_RDMA0_PAUSE|VT1724_PDMA0_PAUSE|VT1724_RDMA1_PAUSE|VT1724_PDMA4_PAUSE) +#define DMA_STARTS (VT1724_RDMA0_START|VT1724_PDMA0_START|VT1724_RDMA1_START|\ + VT1724_PDMA1_START|VT1724_PDMA2_START|VT1724_PDMA3_START|VT1724_PDMA4_START) +#define DMA_PAUSES (VT1724_RDMA0_PAUSE|VT1724_PDMA0_PAUSE|VT1724_RDMA1_PAUSE|\ + VT1724_PDMA1_PAUSE|VT1724_PDMA2_PAUSE|VT1724_PDMA3_PAUSE|VT1724_PDMA4_PAUSE) static void snd_vt1724_set_pro_rate(ice1712_t *ice, unsigned int rate, int force) { @@ -448,13 +429,52 @@ snd_pcm_hw_params_t * hw_params) { ice1712_t *ice = snd_pcm_substream_chip(substream); + int i, chs; + chs = params_channels(hw_params); + down(&ice->open_mutex); + /* mark surround channels */ + if (substream == ice->playback_pro_substream) { + chs = chs / 2 - 1; + for (i = 0; i < chs; i++) { + if (ice->pcm_reserved[i] && ice->pcm_reserved[i] != substream) { + up(&ice->open_mutex); + return -EBUSY; + } + ice->pcm_reserved[i] = substream; + } + for (; i < 3; i++) { + if (ice->pcm_reserved[i] == substream) + ice->pcm_reserved[i] = NULL; + } + } else { + for (i = 0; i < 3; i++) { + if (ice->playback_con_substream_ds[i] == substream) { + if (ice->pcm_reserved[i] && ice->pcm_reserved[i] != substream) { + up(&ice->open_mutex); + return -EBUSY; + } + ice->pcm_reserved[i] = substream; + break; + } + } + } + up(&ice->open_mutex); snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0); return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); } static int snd_vt1724_pcm_hw_free(snd_pcm_substream_t * substream) { + ice1712_t *ice = snd_pcm_substream_chip(substream); + int i; + + down(&ice->open_mutex); + /* unmark surround channels */ + for (i = 0; i < 3; i++) + if (ice->pcm_reserved[i] == substream) + ice->pcm_reserved[i] = NULL; + up(&ice->open_mutex); return snd_pcm_lib_free_pages(substream); } @@ -593,14 +613,14 @@ .rate_max = 192000, .channels_min = 2, .channels_max = 8, - .buffer_bytes_max = (1UL << 21), /* 18bits dword */ + .buffer_bytes_max = (1UL << 21), /* 19bits dword */ .period_bytes_min = 8 * 4 * 2, /* FIXME: constraints needed */ .period_bytes_max = (1UL << 21), - .periods_min = 1, + .periods_min = 2, .periods_max = 1024, }; -static snd_pcm_hardware_t snd_vt1724_capture_pro = +static snd_pcm_hardware_t snd_vt1724_2ch_stereo = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -612,10 +632,10 @@ .rate_max = 192000, .channels_min = 2, .channels_max = 2, - .buffer_bytes_max = (256*1024), + .buffer_bytes_max = (1UL << 18), /* 16bits dword */ .period_bytes_min = 2 * 4 * 2, - .period_bytes_max = (256*1024), - .periods_min = 1, + .period_bytes_max = (1UL << 18), + .periods_min = 2, .periods_max = 1024, }; @@ -628,7 +648,9 @@ { snd_pcm_runtime_t *runtime = substream->runtime; ice1712_t *ice = snd_pcm_substream_chip(substream); + int chs; + runtime->private_data = (void*)VT1724_PDMA0_START; /* irq/status/trigger bit */ ice->playback_pro_substream = substream; runtime->hw = snd_vt1724_playback_pro; snd_pcm_set_sync(substream); @@ -639,7 +661,17 @@ else snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_96); - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels); + down(&ice->open_mutex); + /* calculate the currently available channels */ + for (chs = 0; chs < 3; chs++) { + if (ice->pcm_reserved[chs]) + break; + } + chs = (chs + 1) * 2; + runtime->hw.channels_max = chs; + if (chs > 2) /* channels must be even */ + snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2); + up(&ice->open_mutex); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, VT1724_BUFFER_ALIGN); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, @@ -652,8 +684,9 @@ ice1712_t *ice = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; + runtime->private_data = (void*)VT1724_RDMA0_START; /* irq/status/trigger bit */ ice->capture_pro_substream = substream; - runtime->hw = snd_vt1724_capture_pro; + runtime->hw = snd_vt1724_2ch_stereo; snd_pcm_set_sync(substream); snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); if ((ice->eeprom.data[ICE_EEP2_ACLINK] & 0x80) && @@ -735,25 +768,6 @@ * SPDIF PCM */ -static snd_pcm_hardware_t snd_vt1724_playback_spdif = -{ - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START), - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000, - .rate_min = 4000, - .rate_max = 192000, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = (256*1024), - .period_bytes_min = 2 * 4 * 2, - .period_bytes_max = (256*1024), - .periods_min = 1, - .periods_max = 1024, -}; - const static struct vt1724_pcm_reg vt1724_playback_spdif_reg = { .addr = VT1724_MT_PDMA4_ADDR, .size = VT1724_MT_PDMA4_SIZE, @@ -795,8 +809,9 @@ ice1712_t *ice = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; + runtime->private_data = (void*)VT1724_PDMA4_START; /* irq/status/trigger bit */ ice->playback_con_substream = substream; - runtime->hw = snd_vt1724_playback_spdif; + runtime->hw = snd_vt1724_2ch_stereo; snd_pcm_set_sync(substream); snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); @@ -820,8 +835,9 @@ ice1712_t *ice = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; + runtime->private_data = (void*)VT1724_RDMA1_START; /* irq/status/trigger bit */ ice->capture_con_substream = substream; - runtime->hw = snd_vt1724_playback_spdif; + runtime->hw = snd_vt1724_2ch_stereo; snd_pcm_set_sync(substream); snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_96); @@ -903,6 +919,127 @@ /* + * independent surround PCMs + */ + +const static struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = { + { + .addr = VT1724_MT_PDMA1_ADDR, + .size = VT1724_MT_PDMA1_SIZE, + .count = VT1724_MT_PDMA1_COUNT, + .start = VT1724_PDMA1_START, + .pause = VT1724_PDMA1_PAUSE, + }, + { + .addr = VT1724_MT_PDMA2_ADDR, + .size = VT1724_MT_PDMA2_SIZE, + .count = VT1724_MT_PDMA2_COUNT, + .start = VT1724_PDMA2_START, + .pause = VT1724_PDMA2_PAUSE, + }, + { + .addr = VT1724_MT_PDMA3_ADDR, + .size = VT1724_MT_PDMA3_SIZE, + .count = VT1724_MT_PDMA3_COUNT, + .start = VT1724_PDMA3_START, + .pause = VT1724_PDMA3_PAUSE, + }, +}; + +static int snd_vt1724_playback_indep_prepare(snd_pcm_substream_t * substream) +{ + ice1712_t *ice = snd_pcm_substream_chip(substream); + unsigned char val; + + spin_lock(&ice->reg_lock); + val = 3 - substream->number; + if (inb(ICEMT1724(ice, BURST)) < val) + outb(val, ICEMT1724(ice, BURST)); + spin_unlock(&ice->reg_lock); + return snd_vt1724_pcm_prepare(substream, &vt1724_playback_dma_regs[substream->number]); +} + +static snd_pcm_uframes_t snd_vt1724_playback_indep_pointer(snd_pcm_substream_t * substream) +{ + return snd_vt1724_pcm_pointer(substream, &vt1724_playback_dma_regs[substream->number]); +} + +static int snd_vt1724_playback_indep_open(snd_pcm_substream_t *substream) +{ + ice1712_t *ice = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + + down(&ice->open_mutex); + /* already used by PDMA0? */ + if (ice->pcm_reserved[substream->number]) { + up(&ice->open_mutex); + return -EBUSY; /* FIXME: should handle blocking mode properly */ + } + up(&ice->open_mutex); + runtime->private_data = (void*)(1 << (substream->number + 4)); + ice->playback_con_substream_ds[substream->number] = substream; + runtime->hw = snd_vt1724_2ch_stereo; + snd_pcm_set_sync(substream); + snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); + + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_192); + return 0; +} + +static int snd_vt1724_playback_indep_close(snd_pcm_substream_t * substream) +{ + ice1712_t *ice = snd_pcm_substream_chip(substream); + + if (PRO_RATE_RESET) + snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0); + ice->playback_con_substream_ds[substream->number] = NULL; + ice->pcm_reserved[substream->number] = NULL; + + return 0; +} + +static snd_pcm_ops_t snd_vt1724_playback_indep_ops = { + .open = snd_vt1724_playback_indep_open, + .close = snd_vt1724_playback_indep_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_vt1724_pcm_hw_params, + .hw_free = snd_vt1724_pcm_hw_free, + .prepare = snd_vt1724_playback_indep_prepare, + .trigger = snd_vt1724_pcm_trigger, + .pointer = snd_vt1724_playback_indep_pointer, +}; + + +static int __devinit snd_vt1724_pcm_indep(ice1712_t * ice, int device) +{ + snd_pcm_t *pcm; + int play; + int err; + + play = ice->num_total_dacs / 2 - 1; + if (play <= 0) + return 0; + + err = snd_pcm_new(ice->card, "ICE1724 Surrounds", device, play, 0, &pcm); + if (err < 0) + return err; + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_vt1724_playback_indep_ops); + + pcm->private_data = ice; + pcm->info_flags = 0; + strcpy(pcm->name, "ICE1724 Surround PCM"); + + snd_pcm_lib_preallocate_pci_pages_for_all(ice->pci, pcm, 64*1024, 64*1024); + + ice->pcm_ds = pcm; + + return 0; +} + + +/* * Mixer section */ @@ -1808,6 +1945,7 @@ ice->vt1724 = 1; spin_lock_init(&ice->reg_lock); init_MUTEX(&ice->gpio_mutex); + init_MUTEX(&ice->open_mutex); ice->gpio.set_mask = snd_vt1724_set_gpio_mask; ice->gpio.set_dir = snd_vt1724_set_gpio_dir; ice->gpio.set_data = snd_vt1724_set_gpio_data; @@ -1932,6 +2070,11 @@ return err; } + if ((err = snd_vt1724_pcm_indep(ice, pcm_dev++)) < 0) { + snd_card_free(card); + return err; + } + if ((err = snd_vt1724_ac97_mixer(ice)) < 0) { snd_card_free(card); return err; ------------------------------------------------------- The SF.Net email is sponsored by EclipseCon 2004 Premiere Conference on Open Tools Development and Integration See the breadth of Eclipse activity. February 3-5 in Anaheim, CA. http://www.eclipsecon.org/osdn _______________________________________________ Alsa-cvslog mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/alsa-cvslog