cregit-Linux how code gets into the kernel

Release 4.8 sound/parisc/harmony.c

Directory: sound/parisc
/* Hewlett-Packard Harmony audio driver
 *
 *   This is a driver for the Harmony audio chipset found
 *   on the LASI ASIC of various early HP PA-RISC workstations.
 *
 *   Copyright (C) 2004, Kyle McMartin <kyle@{debian.org,parisc-linux.org}>
 *
 *     Based on the previous Harmony incarnations by,
 *       Copyright 2000 (c) Linuxcare Canada, Alex deVries
 *       Copyright 2000-2003 (c) Helge Deller
 *       Copyright 2001 (c) Matthieu Delahaye
 *       Copyright 2001 (c) Jean-Christophe Vaugeois
 *       Copyright 2003 (c) Laurent Canet
 *       Copyright 2004 (c) Stuart Brady
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License, version 2, as
 *   published by the Free Software Foundation.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Notes:
 *   - graveyard and silence buffers last for lifetime of
 *     the driver. playback and capture buffers are allocated
 *     per _open()/_close().
 * 
 * TODO:
 *
 */

#include <linux/init.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/control.h>
#include <sound/rawmidi.h>
#include <sound/initval.h>
#include <sound/info.h>

#include <asm/hardware.h>
#include <asm/parisc-device.h>

#include "harmony.h"


static int index = SNDRV_DEFAULT_IDX1;	
/* Index 0-MAX */

static char *id = SNDRV_DEFAULT_STR1;	
/* ID for this card */
module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for Harmony driver.");
module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for Harmony driver.");



static struct parisc_device_id snd_harmony_devtable[] = {
	/* bushmaster / flounder */
	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, 
	/* 712 / 715 */
	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007B }, 
	/* pace */
	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007E }, 
	/* outfield / coral II */
	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007F },
	{ 0, }
};

MODULE_DEVICE_TABLE(parisc, snd_harmony_devtable);


#define NAME "harmony"

#define PFX  NAME ": "


static unsigned int snd_harmony_rates[] = {
	5512, 6615, 8000, 9600,
	11025, 16000, 18900, 22050,
	27428, 32000, 33075, 37800,
	44100, 48000
};


static unsigned int rate_bits[14] = {
	HARMONY_SR_5KHZ, HARMONY_SR_6KHZ, HARMONY_SR_8KHZ,
	HARMONY_SR_9KHZ, HARMONY_SR_11KHZ, HARMONY_SR_16KHZ,
	HARMONY_SR_18KHZ, HARMONY_SR_22KHZ, HARMONY_SR_27KHZ,
	HARMONY_SR_32KHZ, HARMONY_SR_33KHZ, HARMONY_SR_37KHZ,
	HARMONY_SR_44KHZ, HARMONY_SR_48KHZ
};


static struct snd_pcm_hw_constraint_list hw_constraint_rates = {
	.count = ARRAY_SIZE(snd_harmony_rates),
	.list = snd_harmony_rates,
	.mask = 0,
};


static inline unsigned long harmony_read(struct snd_harmony *h, unsigned r) { return __raw_readl(h->iobase + r); }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox2180.77%133.33%
takashi iwaitakashi iwai311.54%133.33%
jaroslav kyselajaroslav kysela27.69%133.33%
Total26100.00%3100.00%


static inline void harmony_write(struct snd_harmony *h, unsigned r, unsigned long v) { __raw_writel(v, h->iobase + r); }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox2790.00%150.00%
takashi iwaitakashi iwai310.00%150.00%
Total30100.00%2100.00%


static inline void harmony_wait_for_control(struct snd_harmony *h) { while (harmony_read(h, HARMONY_CNTL) & HARMONY_CNTL_C) ; }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox2083.33%133.33%
takashi iwaitakashi iwai312.50%133.33%
jaroslav kyselajaroslav kysela14.17%133.33%
Total24100.00%3100.00%


static inline void harmony_reset(struct snd_harmony *h) { harmony_write(h, HARMONY_RESET, 1); mdelay(50); harmony_write(h, HARMONY_RESET, 0); }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox3291.43%150.00%
takashi iwaitakashi iwai38.57%150.00%
Total35100.00%2100.00%


static void harmony_disable_interrupts(struct snd_harmony *h) { u32 dstatus; harmony_wait_for_control(h); dstatus = harmony_read(h, HARMONY_DSTATUS); dstatus &= ~HARMONY_DSTATUS_IE; harmony_write(h, HARMONY_DSTATUS, dstatus); }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox3173.81%125.00%
jaroslav kyselajaroslav kysela921.43%250.00%
takashi iwaitakashi iwai24.76%125.00%
Total42100.00%4100.00%


static void harmony_enable_interrupts(struct snd_harmony *h) { u32 dstatus; harmony_wait_for_control(h); dstatus = harmony_read(h, HARMONY_DSTATUS); dstatus |= HARMONY_DSTATUS_IE; harmony_write(h, HARMONY_DSTATUS, dstatus); }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox3175.61%133.33%
jaroslav kyselajaroslav kysela819.51%133.33%
takashi iwaitakashi iwai24.88%133.33%
Total41100.00%3100.00%


static void harmony_mute(struct snd_harmony *h) { unsigned long flags; spin_lock_irqsave(&h->mixer_lock, flags); harmony_wait_for_control(h); harmony_write(h, HARMONY_GAINCTL, HARMONY_GAIN_SILENCE); spin_unlock_irqrestore(&h->mixer_lock, flags); }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox3673.47%133.33%
jaroslav kyselajaroslav kysela1122.45%133.33%
takashi iwaitakashi iwai24.08%133.33%
Total49100.00%3100.00%


static void harmony_unmute(struct snd_harmony *h) { unsigned long flags; spin_lock_irqsave(&h->mixer_lock, flags); harmony_wait_for_control(h); harmony_write(h, HARMONY_GAINCTL, h->st.gain); spin_unlock_irqrestore(&h->mixer_lock, flags); }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox3667.92%133.33%
jaroslav kyselajaroslav kysela1528.30%133.33%
takashi iwaitakashi iwai23.77%133.33%
Total53100.00%3100.00%


static void harmony_set_control(struct snd_harmony *h) { u32 ctrl; unsigned long flags; spin_lock_irqsave(&h->lock, flags); ctrl = (HARMONY_CNTL_C | (h->st.format << 6) | (h->st.stereo << 5) | (h->st.rate)); harmony_wait_for_control(h); harmony_write(h, HARMONY_CNTL, ctrl); spin_unlock_irqrestore(&h->lock, flags); }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox6980.23%133.33%
jaroslav kyselajaroslav kysela1517.44%133.33%
takashi iwaitakashi iwai22.33%133.33%
Total86100.00%3100.00%


static irqreturn_t snd_harmony_interrupt(int irq, void *dev) { u32 dstatus; struct snd_harmony *h = dev; spin_lock(&h->lock); harmony_disable_interrupts(h); harmony_wait_for_control(h); dstatus = harmony_read(h, HARMONY_DSTATUS); spin_unlock(&h->lock); if (dstatus & HARMONY_DSTATUS_PN) { if (h->psubs && h->st.playing) { spin_lock(&h->lock); h->pbuf.buf += h->pbuf.count; /* PAGE_SIZE */ h->pbuf.buf %= h->pbuf.size; /* MAX_BUFS*PAGE_SIZE */ harmony_write(h, HARMONY_PNXTADD, h->pbuf.addr + h->pbuf.buf); h->stats.play_intr++; spin_unlock(&h->lock); snd_pcm_period_elapsed(h->psubs); } else { spin_lock(&h->lock); harmony_write(h, HARMONY_PNXTADD, h->sdma.addr); h->stats.silence_intr++; spin_unlock(&h->lock); } } if (dstatus & HARMONY_DSTATUS_RN) { if (h->csubs && h->st.capturing) { spin_lock(&h->lock); h->cbuf.buf += h->cbuf.count; h->cbuf.buf %= h->cbuf.size; harmony_write(h, HARMONY_RNXTADD, h->cbuf.addr + h->cbuf.buf); h->stats.rec_intr++; spin_unlock(&h->lock); snd_pcm_period_elapsed(h->csubs); } else { spin_lock(&h->lock); harmony_write(h, HARMONY_RNXTADD, h->gdma.addr); h->stats.graveyard_intr++; spin_unlock(&h->lock); } } spin_lock(&h->lock); harmony_enable_interrupts(h); spin_unlock(&h->lock); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox19655.68%233.33%
jaroslav kyselajaroslav kysela14240.34%233.33%
stuart bradystuart brady123.41%116.67%
takashi iwaitakashi iwai20.57%116.67%
Total352100.00%6100.00%


static unsigned int snd_harmony_rate_bits(int rate) { unsigned int i; for (i = 0; i < ARRAY_SIZE(snd_harmony_rates); i++) if (snd_harmony_rates[i] == rate) return rate_bits[i]; return HARMONY_SR_44KHZ; }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox3879.17%150.00%
jaroslav kyselajaroslav kysela1020.83%150.00%
Total48100.00%2100.00%

static struct snd_pcm_hardware snd_harmony_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER), .formats = (SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW), .rates = (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT), .rate_min = 5512, .rate_max = 48000, .channels_min = 1, .channels_max = 2, .buffer_bytes_max = MAX_BUF_SIZE, .period_bytes_min = BUF_SIZE, .period_bytes_max = BUF_SIZE, .periods_min = 1, .periods_max = MAX_BUFS, .fifo_size = 0, }; static struct snd_pcm_hardware snd_harmony_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER), .formats = (SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW), .rates = (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT), .rate_min = 5512, .rate_max = 48000, .channels_min = 1, .channels_max = 2, .buffer_bytes_max = MAX_BUF_SIZE, .period_bytes_min = BUF_SIZE, .period_bytes_max = BUF_SIZE, .periods_min = 1, .periods_max = MAX_BUFS, .fifo_size = 0, };
static int snd_harmony_playback_trigger(struct snd_pcm_substream *ss, int cmd) { struct snd_harmony *h = snd_pcm_substream_chip(ss); if (h->st.capturing) return -EBUSY; spin_lock(&h->lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: h->st.playing = 1; harmony_write(h, HARMONY_PNXTADD, h->pbuf.addr); harmony_write(h, HARMONY_RNXTADD, h->gdma.addr); harmony_unmute(h); harmony_enable_interrupts(h); break; case SNDRV_PCM_TRIGGER_STOP: h->st.playing = 0; harmony_mute(h); harmony_write(h, HARMONY_PNXTADD, h->sdma.addr); harmony_disable_interrupts(h); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_SUSPEND: default: spin_unlock(&h->lock); snd_BUG(); return -EINVAL; } spin_unlock(&h->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox8550.30%120.00%
jaroslav kyselajaroslav kysela6437.87%120.00%
stuart bradystuart brady137.69%120.00%
takashi iwaitakashi iwai74.14%240.00%
Total169100.00%5100.00%


static int snd_harmony_capture_trigger(struct snd_pcm_substream *ss, int cmd) { struct snd_harmony *h = snd_pcm_substream_chip(ss); if (h->st.playing) return -EBUSY; spin_lock(&h->lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: h->st.capturing = 1; harmony_write(h, HARMONY_PNXTADD, h->sdma.addr); harmony_write(h, HARMONY_RNXTADD, h->cbuf.addr); harmony_unmute(h); harmony_enable_interrupts(h); break; case SNDRV_PCM_TRIGGER_STOP: h->st.capturing = 0; harmony_mute(h); harmony_write(h, HARMONY_RNXTADD, h->gdma.addr); harmony_disable_interrupts(h); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_SUSPEND: default: spin_unlock(&h->lock); snd_BUG(); return -EINVAL; } spin_unlock(&h->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox8852.07%120.00%
jaroslav kyselajaroslav kysela6136.09%120.00%
stuart bradystuart brady137.69%120.00%
takashi iwaitakashi iwai74.14%240.00%
Total169100.00%5100.00%


static int snd_harmony_set_data_format(struct snd_harmony *h, int fmt, int force) { int o = h->st.format; int n; switch(fmt) { case SNDRV_PCM_FORMAT_S16_BE: n = HARMONY_DF_16BIT_LINEAR; break; case SNDRV_PCM_FORMAT_A_LAW: n = HARMONY_DF_8BIT_ALAW; break; case SNDRV_PCM_FORMAT_MU_LAW: n = HARMONY_DF_8BIT_ULAW; break; default: n = HARMONY_DF_16BIT_LINEAR; break; } if (force || o != n) { snd_pcm_format_set_silence(fmt, h->sdma.area, SILENCE_BUFSZ / (snd_pcm_format_physical_width(fmt) / 8)); } return n; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela6060.00%125.00%
matthew wilcoxmatthew wilcox3838.00%250.00%
takashi iwaitakashi iwai22.00%125.00%
Total100100.00%4100.00%


static int snd_harmony_playback_prepare(struct snd_pcm_substream *ss) { struct snd_harmony *h = snd_pcm_substream_chip(ss); struct snd_pcm_runtime *rt = ss->runtime; if (h->st.capturing) return -EBUSY; h->pbuf.size = snd_pcm_lib_buffer_bytes(ss); h->pbuf.count = snd_pcm_lib_period_bytes(ss); if (h->pbuf.buf >= h->pbuf.size) h->pbuf.buf = 0; h->st.playing = 0; h->st.rate = snd_harmony_rate_bits(rt->rate); h->st.format = snd_harmony_set_data_format(h, rt->format, 0); if (rt->channels == 2) h->st.stereo = HARMONY_SS_STEREO; else h->st.stereo = HARMONY_SS_MONO; harmony_set_control(h); h->pbuf.addr = rt->dma_addr; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela8047.90%233.33%
matthew wilcoxmatthew wilcox6740.12%233.33%
stuart bradystuart brady148.38%116.67%
takashi iwaitakashi iwai63.59%116.67%
Total167100.00%6100.00%


static int snd_harmony_capture_prepare(struct snd_pcm_substream *ss) { struct snd_harmony *h = snd_pcm_substream_chip(ss); struct snd_pcm_runtime *rt = ss->runtime; if (h->st.playing) return -EBUSY; h->cbuf.size = snd_pcm_lib_buffer_bytes(ss); h->cbuf.count = snd_pcm_lib_period_bytes(ss); if (h->cbuf.buf >= h->cbuf.size) h->cbuf.buf = 0; h->st.capturing = 0; h->st.rate = snd_harmony_rate_bits(rt->rate); h->st.format = snd_harmony_set_data_format(h, rt->format, 0); if (rt->channels == 2) h->st.stereo = HARMONY_SS_STEREO; else h->st.stereo = HARMONY_SS_MONO; harmony_set_control(h); h->cbuf.addr = rt->dma_addr; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox7645.51%233.33%
jaroslav kyselajaroslav kysela7142.51%233.33%
stuart bradystuart brady148.38%116.67%
takashi iwaitakashi iwai63.59%116.67%
Total167100.00%6100.00%


static snd_pcm_uframes_t snd_harmony_playback_pointer(struct snd_pcm_substream *ss) { struct snd_pcm_runtime *rt = ss->runtime; struct snd_harmony *h = snd_pcm_substream_chip(ss); unsigned long pcuradd; unsigned long played; if (!(h->st.playing) || (h->psubs == NULL)) return 0; if ((h->pbuf.addr == 0) || (h->pbuf.size == 0)) return 0; pcuradd = harmony_read(h, HARMONY_PCURADD); played = pcuradd - h->pbuf.addr; #ifdef HARMONY_DEBUG printk(KERN_DEBUG PFX "playback_pointer is 0x%lx-0x%lx = %d bytes\n", pcuradd, h->pbuf.addr, played); #endif if (pcuradd > h->pbuf.addr + h->pbuf.size) { return 0; } return bytes_to_frames(rt, played); }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox9261.33%133.33%
jaroslav kyselajaroslav kysela5234.67%133.33%
takashi iwaitakashi iwai64.00%133.33%
Total150100.00%3100.00%


static snd_pcm_uframes_t snd_harmony_capture_pointer(struct snd_pcm_substream *ss) { struct snd_pcm_runtime *rt = ss->runtime; struct snd_harmony *h = snd_pcm_substream_chip(ss); unsigned long rcuradd; unsigned long caught; if (!(h->st.capturing) || (h->csubs == NULL)) return 0; if ((h->cbuf.addr == 0) || (h->cbuf.size == 0)) return 0; rcuradd = harmony_read(h, HARMONY_RCURADD); caught = rcuradd - h->cbuf.addr; #ifdef HARMONY_DEBUG printk(KERN_DEBUG PFX "capture_pointer is 0x%lx-0x%lx = %d bytes\n", rcuradd, h->cbuf.addr, caught); #endif if (rcuradd > h->cbuf.addr + h->cbuf.size) { return 0; } return bytes_to_frames(rt, caught); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela8154.00%133.33%
matthew wilcoxmatthew wilcox6342.00%133.33%
takashi iwaitakashi iwai64.00%133.33%
Total150100.00%3100.00%


static int snd_harmony_playback_open(struct snd_pcm_substream *ss) { struct snd_harmony *h = snd_pcm_substream_chip(ss); struct snd_pcm_runtime *rt = ss->runtime; int err; h->psubs = ss; rt->hw = snd_harmony_playback; snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraint_rates); err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS); if (err < 0) return err; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela5570.51%133.33%
matthew wilcoxmatthew wilcox1721.79%133.33%
takashi iwaitakashi iwai67.69%133.33%
Total78100.00%3100.00%


static int snd_harmony_capture_open(struct snd_pcm_substream *ss) { struct snd_harmony *h = snd_pcm_substream_chip(ss); struct snd_pcm_runtime *rt = ss->runtime; int err; h->csubs = ss; rt->hw = snd_harmony_capture; snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraint_rates); err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS); if (err < 0) return err; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela5570.51%133.33%
matthew wilcoxmatthew wilcox1721.79%133.33%
takashi iwaitakashi iwai67.69%133.33%
Total78100.00%3100.00%


static int snd_harmony_playback_close(struct snd_pcm_substream *ss) { struct snd_harmony *h = snd_pcm_substream_chip(ss); h->psubs = NULL; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
matthew wilcoxmatthew wilcox1756.67%133.33%
jaroslav kyselajaroslav kysela930.00%133.33%
takashi iwaitakashi iwai413.33%133.33%
Total30100.00%3100.00%


static int snd_harmony_capture_close(struct snd_pcm_substream *ss) { struct snd_harmony *h = snd_pcm_substream_chip(ss); h->csubs = NULL; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela2066.67%133.33%
matthew wilcoxmatthew wilcox620.00%133.33%
takashi iwaitakashi iwai413.33%133.33%
Total30100.00%3100.00%


static int snd_harmony_hw_params(struct snd_pcm_substream *ss, struct snd_pcm_hw_params *hw) { int err; struct snd_harmony *h = snd_pcm_substream_chip(ss); err = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw)); if (err > 0 && h->dma.type == SNDRV_DMA_TYPE_CONTINUOUS) ss->runtime->dma_addr = __pa(ss->runtime->dma_area); return err; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela5068.49%240.00%
matthew wilcoxmatthew wilcox1723.29%240.00%
takashi iwaitakashi iwai68.22%120.00%
Total73100.00%5100.00%


static int snd_harmony_hw_free(struct snd_pcm_substream *ss) { return snd_pcm_lib_free_pages(ss); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela1164.71%133.33%
matthew wilcoxmatthew wilcox423.53%133.33%
takashi iwaitakashi iwai211.76%133.33%
Total17100.00%3100.00%

static struct snd_pcm_ops snd_harmony_playback_ops = { .open = snd_harmony_playback_open, .close = snd_harmony_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_harmony_hw_params, .hw_free = snd_harmony_hw_free, .prepare = snd_harmony_playback_prepare, .trigger = snd_harmony_playback_trigger, .pointer = snd_harmony_playback_pointer, }; static struct snd_pcm_ops snd_harmony_capture_ops = { .open = snd_harmony_capture_open, .close = snd_harmony_capture_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_harmony_hw_params, .hw_free = snd_harmony_hw_free, .prepare = snd_harmony_capture_prepare, .trigger = snd_harmony_capture_trigger, .pointer = snd_harmony_capture_pointer, };
static int snd_harmony_pcm_init(struct snd_harmony *h) { struct snd_pcm *pcm; int err; if (snd_BUG_ON(!h)) return -EINVAL; harmony_disable_interrupts(h); err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm); if (err < 0) return err; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_harmony_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_harmony_capture_ops); pcm->private_data = h; pcm->info_flags = 0; strcpy(pcm->name, "harmony"); h->pcm = pcm; h->psubs = NULL; h->csubs = NULL; /* initialize graveyard buffer */ h->dma.type = SNDRV_DMA_TYPE_DEV; h->dma.dev = &h->dev->dev; err = snd_dma_alloc_pages(h->dma.type, h->dma.dev, BUF_SIZE*GRAVEYARD_BUFS, &h->gdma); if (err < 0) { printk(KERN_ERR PFX "cannot allocate graveyard buffer!\n"); return err; } /* initialize silence buffers */ err = snd_dma_alloc_pages(h->dma.type, h->dma.dev, BUF_SIZE*SILENCE_BUFS, &h->sdma); if (err < 0) { printk(KERN_ERR PFX "cannot allocate silence buffer!\n"); return err;