cregit-Linux how code gets into the kernel

Release 4.7 sound/pci/aw2/aw2-alsa.c

Directory: sound/pci/aw2
/*****************************************************************************
 *
 * Copyright (C) 2008 Cedric Bregardis <cedric.bregardis@free.fr> and
 * Jean-Christian Hassler <jhassler@free.fr>
 *
 * This file is part of the Audiowerk2 ALSA driver
 *
 * The Audiowerk2 ALSA driver is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2.
 *
 * The Audiowerk2 ALSA driver 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 the Audiowerk2 ALSA driver; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
 * USA.
 *
 *****************************************************************************/
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/control.h>

#include "saa7146.h"
#include "aw2-saa7146.h"

MODULE_AUTHOR("Cedric Bregardis <cedric.bregardis@free.fr>, "
	      "Jean-Christian Hassler <jhassler@free.fr>");
MODULE_DESCRIPTION("Emagic Audiowerk 2 sound driver");
MODULE_LICENSE("GPL");

/*********************************
 * DEFINES
 ********************************/

#define CTL_ROUTE_ANALOG 0

#define CTL_ROUTE_DIGITAL 1

/*********************************
 * TYPEDEFS
 ********************************/
  /* hardware definition */

static struct snd_pcm_hardware snd_aw2_playback_hw = {
	.info = (SNDRV_PCM_INFO_MMAP |
		 SNDRV_PCM_INFO_INTERLEAVED |
		 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
	.formats = SNDRV_PCM_FMTBIT_S16_LE,
	.rates = SNDRV_PCM_RATE_44100,
	.rate_min = 44100,
	.rate_max = 44100,
	.channels_min = 2,
	.channels_max = 4,
	.buffer_bytes_max = 32768,
	.period_bytes_min = 4096,
	.period_bytes_max = 32768,
	.periods_min = 1,
	.periods_max = 1024,
};


static struct snd_pcm_hardware snd_aw2_capture_hw = {
	.info = (SNDRV_PCM_INFO_MMAP |
		 SNDRV_PCM_INFO_INTERLEAVED |
		 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
	.formats = SNDRV_PCM_FMTBIT_S16_LE,
	.rates = SNDRV_PCM_RATE_44100,
	.rate_min = 44100,
	.rate_max = 44100,
	.channels_min = 2,
	.channels_max = 2,
	.buffer_bytes_max = 32768,
	.period_bytes_min = 4096,
	.period_bytes_max = 32768,
	.periods_min = 1,
	.periods_max = 1024,
};


struct aw2_pcm_device {
	
struct snd_pcm *pcm;
	
unsigned int stream_number;
	
struct aw2 *chip;
};


struct aw2 {
	
struct snd_aw2_saa7146 saa7146;

	
struct pci_dev *pci;
	
int irq;
	
spinlock_t reg_lock;
	
struct mutex mtx;

	
unsigned long iobase_phys;
	
void __iomem *iobase_virt;

	
struct snd_card *card;

	
struct aw2_pcm_device device_playback[NB_STREAM_PLAYBACK];
	
struct aw2_pcm_device device_capture[NB_STREAM_CAPTURE];
};

/*********************************
 * FUNCTION DECLARATIONS
 ********************************/
static int snd_aw2_dev_free(struct snd_device *device);
static int snd_aw2_create(struct snd_card *card,
			  struct pci_dev *pci, struct aw2 **rchip);
static int snd_aw2_probe(struct pci_dev *pci,
			 const struct pci_device_id *pci_id);
static void snd_aw2_remove(struct pci_dev *pci);
static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream);
static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream);
static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream);
static int snd_aw2_pcm_capture_close(struct snd_pcm_substream *substream);
static int snd_aw2_pcm_hw_params(struct snd_pcm_substream *substream,
				 struct snd_pcm_hw_params *hw_params);
static int snd_aw2_pcm_hw_free(struct snd_pcm_substream *substream);
static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream);
static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream);
static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream,
					int cmd);
static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream,
				       int cmd);
static snd_pcm_uframes_t snd_aw2_pcm_pointer_playback(struct snd_pcm_substream
						      *substream);
static snd_pcm_uframes_t snd_aw2_pcm_pointer_capture(struct snd_pcm_substream
						     *substream);
static int snd_aw2_new_pcm(struct aw2 *chip);

static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol,
					       struct snd_ctl_elem_info *uinfo);
static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol,
					      struct snd_ctl_elem_value
					      *ucontrol);
static int snd_aw2_control_switch_capture_put(struct snd_kcontrol *kcontrol,
					      struct snd_ctl_elem_value
					      *ucontrol);

/*********************************
 * VARIABLES
 ********************************/

static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;

static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;

static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;

module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Audiowerk2 soundcard.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for the Audiowerk2 soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard.");


static const struct pci_device_id snd_aw2_ids[] = {
	{PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0, 0,
	 0, 0, 0},
	{0}
};

MODULE_DEVICE_TABLE(pci, snd_aw2_ids);

/* pci_driver definition */

static struct pci_driver aw2_driver = {
	.name = KBUILD_MODNAME,
	.id_table = snd_aw2_ids,
	.probe = snd_aw2_probe,
	.remove = snd_aw2_remove,
};


module_pci_driver(aw2_driver);

/* operators for playback PCM alsa interface */

static struct snd_pcm_ops snd_aw2_playback_ops = {
	.open = snd_aw2_pcm_playback_open,
	.close = snd_aw2_pcm_playback_close,
	.ioctl = snd_pcm_lib_ioctl,
	.hw_params = snd_aw2_pcm_hw_params,
	.hw_free = snd_aw2_pcm_hw_free,
	.prepare = snd_aw2_pcm_prepare_playback,
	.trigger = snd_aw2_pcm_trigger_playback,
	.pointer = snd_aw2_pcm_pointer_playback,
};

/* operators for capture PCM alsa interface */

static struct snd_pcm_ops snd_aw2_capture_ops = {
	.open = snd_aw2_pcm_capture_open,
	.close = snd_aw2_pcm_capture_close,
	.ioctl = snd_pcm_lib_ioctl,
	.hw_params = snd_aw2_pcm_hw_params,
	.hw_free = snd_aw2_pcm_hw_free,
	.prepare = snd_aw2_pcm_prepare_capture,
	.trigger = snd_aw2_pcm_trigger_capture,
	.pointer = snd_aw2_pcm_pointer_capture,
};


static struct snd_kcontrol_new aw2_control = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.name = "PCM Capture Route",
	.index = 0,
	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
	.private_value = 0xffff,
	.info = snd_aw2_control_switch_capture_info,
	.get = snd_aw2_control_switch_capture_get,
	.put = snd_aw2_control_switch_capture_put
};

/*********************************
 * FUNCTION IMPLEMENTATIONS
 ********************************/

/* component-destructor */

static int snd_aw2_dev_free(struct snd_device *device) { struct aw2 *chip = device->device_data; /* Free hardware */ snd_aw2_saa7146_free(&chip->saa7146); /* release the irq */ if (chip->irq >= 0) free_irq(chip->irq, (void *)chip); /* release the i/o ports & memory */ iounmap(chip->iobase_virt); pci_release_regions(chip->pci); /* disable the PCI entry */ pci_disable_device(chip->pci); /* release the data */ kfree(chip); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis83100.00%1100.00%
Total83100.00%1100.00%

/* chip-specific constructor */
static int snd_aw2_create(struct snd_card *card, struct pci_dev *pci, struct aw2 **rchip) { struct aw2 *chip; int err; static struct snd_device_ops ops = { .dev_free = snd_aw2_dev_free, }; *rchip = NULL; /* initialize the PCI entry */ err = pci_enable_device(pci); if (err < 0) return err; pci_set_master(pci); /* check PCI availability (32bit DMA) */ if ((dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) || (dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)) < 0)) { dev_err(card->dev, "Impossible to set 32bit mask DMA\n"); pci_disable_device(pci); return -ENXIO; } chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; } /* initialize the stuff */ chip->card = card; chip->pci = pci; chip->irq = -1; /* (1) PCI resource allocation */ err = pci_request_regions(pci, "Audiowerk2"); if (err < 0) { pci_disable_device(pci); kfree(chip); return err; } chip->iobase_phys = pci_resource_start(pci, 0); chip->iobase_virt = ioremap_nocache(chip->iobase_phys, pci_resource_len(pci, 0)); if (chip->iobase_virt == NULL) { dev_err(card->dev, "unable to remap memory region"); pci_release_regions(pci); pci_disable_device(pci); kfree(chip); return -ENOMEM; } /* (2) initialization of the chip hardware */ snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt); if (request_irq(pci->irq, snd_aw2_saa7146_interrupt, IRQF_SHARED, KBUILD_MODNAME, chip)) { dev_err(card->dev, "Cannot grab irq %d\n", pci->irq); iounmap(chip->iobase_virt); pci_release_regions(chip->pci); pci_disable_device(chip->pci); kfree(chip); return -EBUSY; } chip->irq = pci->irq; err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); if (err < 0) { free_irq(chip->irq, (void *)chip); iounmap(chip->iobase_virt); pci_release_regions(chip->pci); pci_disable_device(chip->pci); kfree(chip); return err; } *rchip = chip; dev_info(card->dev, "Audiowerk 2 sound card (saa7146 chipset) detected and managed\n"); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis38487.67%116.67%
takashi iwaitakashi iwai388.68%350.00%
quentin lambertquentin lambert81.83%116.67%
yang hongyangyang hongyang81.83%116.67%
Total438100.00%6100.00%

/* constructor */
static int snd_aw2_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { static int dev; struct snd_card *card; struct aw2 *chip; int err; /* (1) Continue if device is not enabled, else inc dev */ if (dev >= SNDRV_CARDS) return -ENODEV; if (!enable[dev]) { dev++; return -ENOENT; } /* (2) Create card instance */ err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, 0, &card); if (err < 0) return err; /* (3) Create main component */ err = snd_aw2_create(card, pci, &chip); if (err < 0) { snd_card_free(card); return err; } /* initialize mutex */ mutex_init(&chip->mtx); /* init spinlock */ spin_lock_init(&chip->reg_lock); /* (4) Define driver ID and name string */ strcpy(card->driver, "aw2"); strcpy(card->shortname, "Audiowerk2"); sprintf(card->longname, "%s with SAA7146 irq %i", card->shortname, chip->irq); /* (5) Create other components */ snd_aw2_new_pcm(chip); /* (6) Register card instance */ err = snd_card_register(card); if (err < 0) { snd_card_free(card); return err; } /* (7) Set PCI driver data */ pci_set_drvdata(pci, card); dev++; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis21293.81%133.33%
takashi iwaitakashi iwai146.19%266.67%
Total226100.00%3100.00%

/* destructor */
static void snd_aw2_remove(struct pci_dev *pci) { snd_card_free(pci_get_drvdata(pci)); }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis19100.00%1100.00%
Total19100.00%1100.00%

/* open callback */
static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; dev_dbg(substream->pcm->card->dev, "Playback_open\n"); runtime->hw = snd_aw2_playback_hw; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis3276.19%150.00%
takashi iwaitakashi iwai1023.81%150.00%
Total42100.00%2100.00%

/* close callback */
static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis14100.00%1100.00%
Total14100.00%1100.00%


static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; dev_dbg(substream->pcm->card->dev, "Capture_open\n"); runtime->hw = snd_aw2_capture_hw; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis3276.19%150.00%
takashi iwaitakashi iwai1023.81%150.00%
Total42100.00%2100.00%

/* close callback */
static int snd_aw2_pcm_capture_close(struct snd_pcm_substream *substream) { /* TODO: something to do ? */ return 0; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis15100.00%1100.00%
Total15100.00%1100.00%

/* hw_params callback */
static int snd_aw2_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis27100.00%1100.00%
Total27100.00%1100.00%

/* hw_free callback */
static int snd_aw2_pcm_hw_free(struct snd_pcm_substream *substream) { return snd_pcm_lib_free_pages(substream); }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis17100.00%1100.00%
Total17100.00%1100.00%

/* prepare callback for playback */
static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream) { struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); struct aw2 *chip = pcm_device->chip; struct snd_pcm_runtime *runtime = substream->runtime; unsigned long period_size, buffer_size; mutex_lock(&chip->mtx); period_size = snd_pcm_lib_period_bytes(substream); buffer_size = snd_pcm_lib_buffer_bytes(substream); snd_aw2_saa7146_pcm_init_playback(&chip->saa7146, pcm_device->stream_number, runtime->dma_addr, period_size, buffer_size); /* Define Interrupt callback */ snd_aw2_saa7146_define_it_playback_callback(pcm_device->stream_number, (snd_aw2_saa7146_it_cb) snd_pcm_period_elapsed, (void *)substream); mutex_unlock(&chip->mtx); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis117100.00%1100.00%
Total117100.00%1100.00%

/* prepare callback for capture */
static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream) { struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); struct aw2 *chip = pcm_device->chip; struct snd_pcm_runtime *runtime = substream->runtime; unsigned long period_size, buffer_size; mutex_lock(&chip->mtx); period_size = snd_pcm_lib_period_bytes(substream); buffer_size = snd_pcm_lib_buffer_bytes(substream); snd_aw2_saa7146_pcm_init_capture(&chip->saa7146, pcm_device->stream_number, runtime->dma_addr, period_size, buffer_size); /* Define Interrupt callback */ snd_aw2_saa7146_define_it_capture_callback(pcm_device->stream_number, (snd_aw2_saa7146_it_cb) snd_pcm_period_elapsed, (void *)substream); mutex_unlock(&chip->mtx); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis117100.00%1100.00%
Total117100.00%1100.00%

/* playback trigger callback */
static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream, int cmd) { int status = 0; struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); struct aw2 *chip = pcm_device->chip; spin_lock(&chip->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: snd_aw2_saa7146_pcm_trigger_start_playback(&chip->saa7146, pcm_device-> stream_number); break; case SNDRV_PCM_TRIGGER_STOP: snd_aw2_saa7146_pcm_trigger_stop_playback(&chip->saa7146, pcm_device-> stream_number); break; default: status = -EINVAL; } spin_unlock(&chip->reg_lock); return status; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis101100.00%1100.00%
Total101100.00%1100.00%

/* capture trigger callback */
static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream, int cmd) { int status = 0; struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); struct aw2 *chip = pcm_device->chip; spin_lock(&chip->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: snd_aw2_saa7146_pcm_trigger_start_capture(&chip->saa7146, pcm_device-> stream_number); break; case SNDRV_PCM_TRIGGER_STOP: snd_aw2_saa7146_pcm_trigger_stop_capture(&chip->saa7146, pcm_device-> stream_number); break; default: status = -EINVAL; } spin_unlock(&chip->reg_lock); return status; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis101100.00%1100.00%
Total101100.00%1100.00%

/* playback pointer callback */
static snd_pcm_uframes_t snd_aw2_pcm_pointer_playback(struct snd_pcm_substream *substream) { struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); struct aw2 *chip = pcm_device->chip; unsigned int current_ptr; /* get the current hardware pointer */ struct snd_pcm_runtime *runtime = substream->runtime; current_ptr = snd_aw2_saa7146_get_hw_ptr_playback(&chip->saa7146, pcm_device->stream_number, runtime->dma_area, runtime->buffer_size); return bytes_to_frames(substream->runtime, current_ptr); }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis76100.00%1100.00%
Total76100.00%1100.00%

/* capture pointer callback */
static snd_pcm_uframes_t snd_aw2_pcm_pointer_capture(struct snd_pcm_substream *substream) { struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); struct aw2 *chip = pcm_device->chip; unsigned int current_ptr; /* get the current hardware pointer */ struct snd_pcm_runtime *runtime = substream->runtime; current_ptr = snd_aw2_saa7146_get_hw_ptr_capture(&chip->saa7146, pcm_device->stream_number, runtime->dma_area, runtime->buffer_size); return bytes_to_frames(substream->runtime, current_ptr); }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis76100.00%1100.00%
Total76100.00%1100.00%

/* create a pcm device */
static int snd_aw2_new_pcm(struct aw2 *chip) { struct snd_pcm *pcm_playback_ana; struct snd_pcm *pcm_playback_num; struct snd_pcm *pcm_capture; struct aw2_pcm_device *pcm_device; int err = 0; /* Create new Alsa PCM device */ err = snd_pcm_new(chip->card, "Audiowerk2 analog playback", 0, 1, 0, &pcm_playback_ana); if (err < 0) { dev_err(chip->card->dev, "snd_pcm_new error (0x%X)\n", err); return err; } /* Creation ok */ pcm_device = &chip->device_playback[NUM_STREAM_PLAYBACK_ANA]; /* Set PCM device name */ strcpy(pcm_playback_ana->name, "Analog playback"); /* Associate private data to PCM device */ pcm_playback_ana->private_data = pcm_device; /* set operators of PCM device */ snd_pcm_set_ops(pcm_playback_ana, SNDRV_PCM_STREAM_PLAYBACK, &snd_aw2_playback_ops); /* store PCM device */ pcm_device->pcm = pcm_playback_ana; /* give base chip pointer to our internal pcm device structure */ pcm_device->chip = chip; /* Give stream number to PCM device */ pcm_device->stream_number = NUM_STREAM_PLAYBACK_ANA; /* pre-allocation of buffers */ /* Preallocate continuous pages. */ err = snd_pcm_lib_preallocate_pages_for_all(pcm_playback_ana, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data (chip->pci), 64 * 1024, 64 * 1024); if (err) dev_err(chip->card->dev, "snd_pcm_lib_preallocate_pages_for_all error (0x%X)\n", err); err = snd_pcm_new(chip->card, "Audiowerk2 digital playback", 1, 1, 0, &pcm_playback_num); if (err < 0) { dev_err(chip->card->dev, "snd_pcm_new error (0x%X)\n", err); return err; } /* Creation ok */ pcm_device = &chip->device_playback[NUM_STREAM_PLAYBACK_DIG]; /* Set PCM device name */ strcpy(pcm_playback_num->name, "Digital playback"); /* Associate private data to PCM device */ pcm_playback_num->private_data = pcm_device; /* set operators of PCM device */ snd_pcm_set_ops(pcm_playback_num, SNDRV_PCM_STREAM_PLAYBACK, &snd_aw2_playback_ops); /* store PCM device */ pcm_device->pcm = pcm_playback_num; /* give base chip pointer to our internal pcm device structure */ pcm_device->chip = chip; /* Give stream number to PCM device */ pcm_device->stream_number = NUM_STREAM_PLAYBACK_DIG; /* pre-allocation of buffers */ /* Preallocate continuous pages. */ err = snd_pcm_lib_preallocate_pages_for_all(pcm_playback_num, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data (chip->pci), 64 * 1024, 64 * 1024); if (err) dev_err(chip->card->dev, "snd_pcm_lib_preallocate_pages_for_all error (0x%X)\n", err); err = snd_pcm_new(chip->card, "Audiowerk2 capture", 2, 0, 1, &pcm_capture); if (err < 0) { dev_err(chip->card->dev, "snd_pcm_new error (0x%X)\n", err); return err; } /* Creation ok */ pcm_device = &chip->device_capture[NUM_STREAM_CAPTURE_ANA]; /* Set PCM device name */ strcpy(pcm_capture->name, "Capture"); /* Associate private data to PCM device */ pcm_capture->private_data = pcm_device; /* set operators of PCM device */ snd_pcm_set_ops(pcm_capture, SNDRV_PCM_STREAM_CAPTURE, &snd_aw2_capture_ops); /* store PCM device */ pcm_device->pcm = pcm_capture; /* give base chip pointer to our internal pcm device structure */ pcm_device->chip = chip; /* Give stream number to PCM device */ pcm_device->stream_number = NUM_STREAM_CAPTURE_ANA; /* pre-allocation of buffers */ /* Preallocate continuous pages. */ err = snd_pcm_lib_preallocate_pages_for_all(pcm_capture, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data (chip->pci), 64 * 1024, 64 * 1024); if (err) dev_err(chip->card->dev, "snd_pcm_lib_preallocate_pages_for_all error (0x%X)\n", err); /* Create control */ err = snd_ctl_add(chip->card, snd_ctl_new1(&aw2_control, chip)); if (err < 0) { dev_err(chip->card->dev, "snd_ctl_add error (0x%X)\n", err); return err; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis46789.29%150.00%
takashi iwaitakashi iwai5610.71%150.00%
Total523100.00%2100.00%


static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static const char * const texts[2] = { "Analog", "Digital" }; return snd_ctl_enum_info(uinfo, 1, 2, texts); }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis3784.09%150.00%
takashi iwaitakashi iwai715.91%150.00%
Total44100.00%2100.00%


static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct aw2 *chip = snd_kcontrol_chip(kcontrol); if (snd_aw2_saa7146_is_using_digital_input(&chip->saa7146)) ucontrol->value.enumerated.item[0] = CTL_ROUTE_DIGITAL; else ucontrol->value.enumerated.item[0] = CTL_ROUTE_ANALOG; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis66100.00%1100.00%
Total66100.00%1100.00%


static int snd_aw2_control_switch_capture_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct aw2 *chip = snd_kcontrol_chip(kcontrol); int changed = 0; int is_disgital = snd_aw2_saa7146_is_using_digital_input(&chip->saa7146); if (((ucontrol->value.integer.value[0] == CTL_ROUTE_DIGITAL) && !is_disgital) || ((ucontrol->value.integer.value[0] == CTL_ROUTE_ANALOG) && is_disgital)) { snd_aw2_saa7146_use_digital_input(&chip->saa7146, !is_disgital); changed = 1; } return changed; }

Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis103100.00%1100.00%
Total103100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
cedric bregardiscedric bregardis286792.57%15.56%
takashi iwaitakashi iwai1966.33%950.00%
quentin lambertquentin lambert80.26%15.56%
yang hongyangyang hongyang80.26%15.56%
benoit tainebenoit taine60.19%15.56%
h hartley sweetenh hartley sweeten30.10%15.56%
andrew mortonandrew morton30.10%15.56%
paul gortmakerpaul gortmaker30.10%15.56%
anssi hannulaanssi hannula20.06%15.56%
rusty russellrusty russell10.03%15.56%
bill pembertonbill pemberton0.00%00.00%
Total3097100.00%18100.00%
Directory: sound/pci/aw2
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}