<commit_before>/*
 * Freescale DMA ALSA SoC PCM driver
 *
 * Author: <NAME> <<EMAIL>>
 *
 * Copyright 2007-2008 Freescale Semiconductor, Inc.  This file is licensed
 * under the terms of the GNU General Public License version 2.  This
 * program is licensed "as is" without any warranty of any kind, whether
 * express or implied.
 *
 * This driver implements ASoC support for the Elo DMA controller, which is
 * the DMA controller on Freescale 83xx, 85xx, and 86xx SOCs. In ALSA terms,
 * the PCM driver is what handles the DMA buffer.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/delay.h>

#include <sound/driver.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>

#include <asm/io.h>

#include "fsl_dma.h"

/*
 * The formats that the DMA controller supports, which is anything
 * that is 8, 16, or 32 bits.
 */
#define FSLDMA_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 	| \
			    SNDRV_PCM_FMTBIT_U8 	| \
			    SNDRV_PCM_FMTBIT_S16_LE     | \
			    SNDRV_PCM_FMTBIT_S16_BE     | \
			    SNDRV_PCM_FMTBIT_U16_LE     | \
			    SNDRV_PCM_FMTBIT_U16_BE     | \
			    SNDRV_PCM_FMTBIT_S24_LE     | \
			    SNDRV_PCM_FMTBIT_S24_BE     | \
			    SNDRV_PCM_FMTBIT_U24_LE     | \
			    SNDRV_PCM_FMTBIT_U24_BE     | \
			    SNDRV_PCM_FMTBIT_S32_LE     | \
			    SNDRV_PCM_FMTBIT_S32_BE     | \
			    SNDRV_PCM_FMTBIT_U32_LE     | \
			    SNDRV_PCM_FMTBIT_U32_BE)

#define FSLDMA_PCM_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
			  SNDRV_PCM_RATE_CONTINUOUS)

/* DMA global data.  This structure is used by fsl_dma_open() to determine
 * which DMA channels to assign to a substream.  Unfortunately, ASoC V1 does
 * not allow the machine driver to provide this information to the PCM
 * driver in advance, and there's no way to differentiate between the two
 * DMA controllers.  So for now, this driver only supports one SSI device
 * using two DMA channels.  We cannot support multiple DMA devices.
 *
 * ssi_stx_phys: bus address of SSI STX register
 * ssi_srx_phys: bus address of SSI SRX register
 * dma_channel: pointer to the DMA channel's registers
 * irq: IRQ for this DMA channel
 * assigned: set to 1 if that DMA channel is assigned to a substream
 */
static struct {
	dma_addr_t ssi_stx_phys;
	dma_addr_t ssi_srx_phys;
	struct ccsr_dma_channel __iomem *dma_channel[2];
	unsigned int irq[2];
	unsigned int assigned[2];
} dma_global_data;

/*
 * The number of DMA links to use.  Two is the bare minimum, but if you
 * have really small links you might need more.
 */
#define NUM_DMA_LINKS   2

/** fsl_dma_private: p-substream DMA data
 *
 * Each substream has a 1-to-1 association with a DMA channel.
 *
 * The link[] array is first because it needs to be aligned on a 32-byte
 * boundary, so putting it first will ensure alignment without padding the
 * structure.
 *
 * @link[]: array of link descriptors
 * @controller_id: which DMA controller (0, 1, ...)
 * @channel_id: which DMA channel on the controller (0, 1, 2, ...)
 * @dma_channel: pointer to the DMA channel's registers
 * @irq: IRQ for this DMA channel
 * @substream: pointer to the substream object, needed by the ISR
 * @ssi_sxx_phys: bus address of the STX or SRX register to use
 * @ld_buf_phys: physical address of the LD buffer
 * @current_link: index into link[] of the link currently being processed
 * @dma_buf_phys: physical address of the DMA buffer
 * @dma_buf_next: physical address of the next period to process
 * @dma_buf_end: physical address of the byte after the end of the DMA
 * @buffer period_size: the size of a single period
 * @num_periods: the number of periods in the DMA buffer
 */
struct fsl_dma_private {
	struct fsl_dma_link_descriptor link[NUM_DMA_LINKS];
	unsigned int controller_id;
	unsigned int channel_id;
	struct ccsr_dma_channel __iomem *dma_channel;
	unsigned int irq;
	struct snd_pcm_substream *substream;
	dma_addr_t ssi_sxx_phys;
	dma_addr_t ld_buf_phys;
	unsigned int current_link;
	dma_addr_t dma_buf_phys;
	dma_addr_t dma_buf_next;
	dma_addr_t dma_buf_end;
	size_t period_size;
	unsigned int num_periods;
};

/**
 * fsl_dma_hardare: define characteristics of the PCM hardware.
 *
 * The PCM hardware is the Freescale DMA controller.  This structure defines
 * the capabilities of that hardware.
 *
 * Since the sampling rate and data format are not controlled by the DMA
 * controller, we specify no limits for those values.  The only exception is
 * period_bytes_min, which is set to a reasonably low value to prevent the
 * DMA controller from generating too many interrupts per second.
 *
 * Since each link descriptor has a 32-bit byte count field, we set
 * period_bytes_max to the largest 32-bit number.  We also have no maximum
 * number of periods.
 */
static const struct snd_pcm_hardware fsl_dma_hardware = {

	.info   		= SNDRV_PCM_INFO_INTERLEAVED,
	.formats		= FSLDMA_PCM_FORMATS,
	.rates  		= FSLDMA_PCM_RATES,
	.rate_min       	= 5512,
	.rate_max       	= 192000,
	.period_bytes_min       = 512,  	/* A reasonable limit */
	.period_bytes_max       = (u32) -1,
	.periods_min    	= NUM_DMA_LINKS,
	.periods_max    	= (unsigned int) -1,
	.buffer_bytes_max       = 128 * 1024,   /* A reasonable limit */
};<commit_msg>[ALSA] mpc8610: Add mmap support<commit_after>/*
 * Freescale DMA ALSA SoC PCM driver
 *
 * Author: <NAME> <<EMAIL>>
 *
 * Copyright 2007-2008 Freescale Semiconductor, Inc.  This file is licensed
 * under the terms of the GNU General Public License version 2.  This
 * program is licensed "as is" without any warranty of any kind, whether
 * express or implied.
 *
 * This driver implements ASoC support for the Elo DMA controller, which is
 * the DMA controller on Freescale 83xx, 85xx, and 86xx SOCs. In ALSA terms,
 * the PCM driver is what handles the DMA buffer.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/delay.h>

#include <sound/driver.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>

#include <asm/io.h>

#include "fsl_dma.h"

/*
 * The formats that the DMA controller supports, which is anything
 * that is 8, 16, or 32 bits.
 */
#define FSLDMA_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 	| \
			    SNDRV_PCM_FMTBIT_U8 	| \
			    SNDRV_PCM_FMTBIT_S16_LE     | \
			    SNDRV_PCM_FMTBIT_S16_BE     | \
			    SNDRV_PCM_FMTBIT_U16_LE     | \
			    SNDRV_PCM_FMTBIT_U16_BE     | \
			    SNDRV_PCM_FMTBIT_S24_LE     | \
			    SNDRV_PCM_FMTBIT_S24_BE     | \
			    SNDRV_PCM_FMTBIT_U24_LE     | \
			    SNDRV_PCM_FMTBIT_U24_BE     | \
			    SNDRV_PCM_FMTBIT_S32_LE     | \
			    SNDRV_PCM_FMTBIT_S32_BE     | \
			    SNDRV_PCM_FMTBIT_U32_LE     | \
			    SNDRV_PCM_FMTBIT_U32_BE)

#define FSLDMA_PCM_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
			  SNDRV_PCM_RATE_CONTINUOUS)

/* DMA global data.  This structure is used by fsl_dma_open() to determine
 * which DMA channels to assign to a substream.  Unfortunately, ASoC V1 does
 * not allow the machine driver to provide this information to the PCM
 * driver in advance, and there's no way to differentiate between the two
 * DMA controllers.  So for now, this driver only supports one SSI device
 * using two DMA channels.  We cannot support multiple DMA devices.
 *
 * ssi_stx_phys: bus address of SSI STX register
 * ssi_srx_phys: bus address of SSI SRX register
 * dma_channel: pointer to the DMA channel's registers
 * irq: IRQ for this DMA channel
 * assigned: set to 1 if that DMA channel is assigned to a substream
 */
static struct {
	dma_addr_t ssi_stx_phys;
	dma_addr_t ssi_srx_phys;
	struct ccsr_dma_channel __iomem *dma_channel[2];
	unsigned int irq[2];
	unsigned int assigned[2];
} dma_global_data;

/*
 * The number of DMA links to use.  Two is the bare minimum, but if you
 * have really small links you might need more.
 */
#define NUM_DMA_LINKS   2

/** fsl_dma_private: p-substream DMA data
 *
 * Each substream has a 1-to-1 association with a DMA channel.
 *
 * The link[] array is first because it needs to be aligned on a 32-byte
 * boundary, so putting it first will ensure alignment without padding the
 * structure.
 *
 * @link[]: array of link descriptors
 * @controller_id: which DMA controller (0, 1, ...)
 * @channel_id: which DMA channel on the controller (0, 1, 2, ...)
 * @dma_channel: pointer to the DMA channel's registers
 * @irq: IRQ for this DMA channel
 * @substream: pointer to the substream object, needed by the ISR
 * @ssi_sxx_phys: bus address of the STX or SRX register to use
 * @ld_buf_phys: physical address of the LD buffer
 * @current_link: index into link[] of the link currently being processed
 * @dma_buf_phys: physical address of the DMA buffer
 * @dma_buf_next: physical address of the next period to process
 * @dma_buf_end: physical address of the byte after the end of the DMA
 * @buffer period_size: the size of a single period
 * @num_periods: the number of periods in the DMA buffer
 */
struct fsl_dma_private {
	struct fsl_dma_link_descriptor link[NUM_DMA_LINKS];
	unsigned int controller_id;
	unsigned int channel_id;
	struct ccsr_dma_channel __iomem *dma_channel;
	unsigned int irq;
	struct snd_pcm_substream *substream;
	dma_addr_t ssi_sxx_phys;
	dma_addr_t ld_buf_phys;
	unsigned int current_link;
	dma_addr_t dma_buf_phys;
	dma_addr_t dma_buf_next;
	dma_addr_t dma_buf_end;
	size_t period_size;
	unsigned int num_periods;
};

/**
 * fsl_dma_hardare: define characteristics of the PCM hardware.
 *
 * The PCM hardware is the Freescale DMA controller.  This structure defines
 * the capabilities of that hardware.
 *
 * Since the sampling rate and data format are not controlled by the DMA
 * controller, we specify no limits for those values.  The only exception is
 * period_bytes_min, which is set to a reasonably low value to prevent the
 * DMA controller from generating too many interrupts per second.
 *
 * Since each link descriptor has a 32-bit byte count field, we set
 * period_bytes_max to the largest 32-bit number.  We also have no maximum
 * number of periods.
 */
static const struct snd_pcm_hardware fsl_dma_hardware = {

	.info   		= SNDRV_PCM_INFO_INTERLEAVED |
				  SNDRV_PCM_INFO_MMAP |
				  SNDRV_PCM_INFO_MMAP_VALID,
	.formats		= FSLDMA_PCM_FORMATS,
	.rates  		= FSLDMA_PCM_RATES,
	.rate_min       	= 5512,
	.rate_max       	= 192000,
	.period_bytes_min       = 512,  	/* A reasonable limit */
	.period_bytes_max       = (u32) -1,
	.periods_min    	= NUM_DMA_LINKS,
	.periods_max    	= (unsigned int) -1,
	.buffer_bytes_max       = 128 * 1024,   /* A reasonable limit */
};
{'fraction_non_alphanumeric': 0.07360193542383921, 'fraction_numerical': 0.0195403368381874, 'mean_word_length': 3.583368869936034, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5796265', 'n_tokens_mistral': 3859, 'n_tokens_neox': 3619, 'n_words': 1252}