/*
* Driver for CS4231 sound chips found on Sparcs.
* Copyright (C) 2002, 2008 David S. Miller <[email protected]>
*
* Based entirely upon drivers/sbus/audio/cs4231.c which is:
* Copyright (C) 1996, 1997, 1998 Derrick J Brashear ([email protected])
* and also sound/isa/cs423x/cs4231_lib.c which is:
* Copyright (c) by Jaroslav Kysela <[email protected]>
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/info.h>
#include <sound/control.h>
#include <sound/timer.h>
#include <sound/initval.h>
#include <sound/pcm_params.h>
#ifdef CONFIG_SBUS
#define SBUS_SUPPORT
#endif
#if defined(CONFIG_PCI) && defined(CONFIG_SPARC64)
#define EBUS_SUPPORT
#include <linux/pci.h>
#include <asm/ebus_dma.h>
#endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
/* Enable this card */
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Sun CS4231 soundcard.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for Sun CS4231 soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable Sun CS4231 soundcard.");
MODULE_AUTHOR("Jaroslav Kysela, Derrick J. Brashear and David S. Miller");
MODULE_DESCRIPTION("Sun CS4231");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}");
#ifdef SBUS_SUPPORT
struct sbus_dma_info {
spinlock_t lock; /* DMA access lock */
int dir;
void __iomem *regs;
};
#endif
struct snd_cs4231;
struct cs4231_dma_control {
void (*prepare)(struct cs4231_dma_control *dma_cont,
int dir);
void (*enable)(struct cs4231_dma_control *dma_cont, int on);
int (*request)(struct cs4231_dma_control *dma_cont,
dma_addr_t bus_addr, size_t len);
unsigned int (*address)(struct cs4231_dma_control *dma_cont);
#ifdef EBUS_SUPPORT
struct ebus_dma_info ebus_info;
#endif
#ifdef SBUS_SUPPORT
struct sbus_dma_info sbus_info;
#endif
};
struct snd_cs4231 {
spinlock_t lock; /* registers access lock */
void __iomem *port;
struct cs4231_dma_control p_dma;
struct cs4231_dma_control c_dma;
u32 flags;
#define CS4231_FLAG_EBUS 0x00000001
#define CS4231_FLAG_PLAYBACK 0x00000002
#define CS4231_FLAG_CAPTURE 0x00000004
struct snd_card *card;
struct snd_pcm *pcm;
struct snd_pcm_substream *playback_substream;
unsigned int p_periods_sent;
struct snd_pcm_substream *capture_substream;
unsigned int c_periods_sent;
struct snd_timer *timer;
unsigned short mode;
#define CS4231_MODE_NONE 0x0000
#define CS4231_MODE_PLAY 0x0001
#define CS4231_MODE_RECORD 0x0002
#define CS4231_MODE_TIMER 0x0004
#define CS4231_MODE_OPEN (CS4231_MODE_PLAY | CS4231_MODE_RECORD | \
CS4231_MODE_TIMER)
unsigned char image[32]; /* registers image */
int mce_bit;
int calibrate_mute;
struct mutex mce_mutex; /* mutex for mce register */
struct mutex open_mutex; /* mutex for ALSA open/close */
struct platform_device *op;
unsigned int irq[2];
unsigned int regs_size;
struct snd_cs4231 *next;
};
/* Eventually we can use sound/isa/cs423x/cs4231_lib.c directly, but for
* now.... -DaveM
*/
/* IO ports */
#include <sound/cs4231-regs.h>
/* XXX offsets are different than PC ISA chips... */
#define CS4231U(chip, x) ((chip)->port + ((c_d_c_CS4231##x) << 2))
/* SBUS DMA register defines. */
#define APCCSR 0x10UL /* APC DMA CSR */
#define APCCVA 0x20UL /* APC Capture DMA Address */
#define APCCC 0x24UL /* APC Capture Count */
#define APCCNVA 0x28UL /* APC Capture DMA Next Address */
#define APCCNC 0x2cUL /* APC Capture Next Count */
#define APCPVA 0x30UL /* APC Play DMA Address */
#define APCPC 0x34UL /* APC Play Count */
#define APCPNVA 0x38UL /* APC Play DMA Next Address */
#define APCPNC 0x3cUL /* APC Play Next Count */
/* Defines for SBUS DMA-routines */
#define APCVA 0x0UL /* APC DMA Address */
#define APCC 0x4UL /* APC Count */
#define APCNVA 0x8UL /* APC DMA Next Address */
#define APCNC 0xcUL /* APC Next Count */
#define APC_PLAY 0x30UL /* Play registers start at 0x30 */
#define APC_RECORD 0x20UL /* Record registers start at 0x20 */
/* APCCSR bits */
#define APC_INT_PENDING 0x800000 /* Interrupt Pending */
#define APC_PLAY_INT 0x400000 /* Playback interrupt */
#define APC_CAPT_INT 0x200000 /* Capture interrupt */
#define APC_GENL_INT 0x100000 /* General interrupt */
#define APC_XINT_ENA 0x80000 /* General ext int. enable */
#define APC_XINT_PLAY 0x40000 /* Playback ext intr */
#define APC_XINT_CAPT 0x20000 /* Capture ext intr */
#define APC_XINT_GENL 0x10000 /* Error ext intr */
#define APC_XINT_EMPT 0x8000 /* Pipe empty interrupt (0 write to pva) */
#define APC_XINT_PEMP 0x4000 /* Play pipe empty (pva and pnva not set) */
#define APC_XINT_PNVA 0x2000 /* Playback NVA dirty */
#define APC_XINT_PENA 0x1000 /* play pipe empty Int enable */
#define APC_XINT_COVF 0x800 /* Cap data dropped on floor */
#define APC_XINT_CNVA 0x400 /* Capture NVA dirty */
#define APC_XINT_CEMP 0x200 /* Capture pipe empty (cva and cnva not set) */
#define APC_XINT_CENA 0x100 /* Cap. pipe empty int enable */
#define APC_PPAUSE 0x80 /* Pause the play DMA */
#define APC_CPAUSE 0x40 /* Pause the capture DMA */
#define APC_CDC_RESET 0x20 /* CODEC RESET */
#define APC_PDMA_READY 0x08 /* Play DMA Go */
#define APC_CDMA_READY 0x04 /* Capture DMA Go */
#define APC_CHIP_RESET 0x01 /* Reset the chip */
/* EBUS DMA register offsets */
#define EBDMA_CSR 0x00UL /* Control/Status */
#define EBDMA_ADDR 0x04UL /* DMA Address */
#define EBDMA_COUNT 0x08UL /* DMA Count */
/*
* Some variables
*/
static unsigned char freq_bits[14] = {
/* 5510 */ 0x00 | CS4231_XTAL2,
/* 6620 */ 0x0E | CS4231_XTAL2,
/* 8000 */ 0x00 | CS4231_XTAL1,
/* 9600 */ 0x0E | CS4231_XTAL1,
/* 11025 */ 0x02 | CS4231_XTAL2,
/* 16000 */ 0x02 | CS4231_XTAL1,
/* 18900 */ 0x04 | CS4231_XTAL2,
/* 22050 */ 0x06 | CS4231_XTAL2,
/* 27042 */ 0x04 | CS4231_XTAL1,
/* 32000 */ 0x06 | CS4231_XTAL1,
/* 33075 */ 0x0C | CS4231_XTAL2,
/* 37800 */ 0x08 | CS4231_XTAL2,
/* 44100 */ 0x0A | CS4231_XTAL2,
/* 48000 */ 0x0C | CS4231_XTAL1
};
static unsigned int rates[14] = {
5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
27042, 32000, 33075, 37800, 44100, 48000
};
static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
.count = ARRAY_SIZE(rates),
.list = rates,
};
static int snd_cs4231_xrate(struct snd_pcm_runtime *runtime)
{
return snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&hw_constraints_rates);
}
static unsigned char snd_cs4231_original_image[32] =
{
0x00, /* 00/00 - lic */
0x00, /* 01/01 - ric */
0x9f, /* 02/02 - la1ic */
0x9f, /* 03/03 - ra1ic */
0x9f, /* 04/04 - la2ic */
0x9f, /* 05/05 - ra2ic */
0xbf, /* 06/06 - loc */
0xbf, /* 07/07 - roc */
0x20, /* 08/08 - pdfr */
CS4231_AUTOCALIB, /* 09/09 - ic */
0x00, /* 0a/10 - pc */
0x00, /* 0b/11 - ti */
CS4231_MODE2, /* 0c/12 - mi */
0x00, /* 0d/13 - lbc */
0x00, /* 0e/14 - pbru */
0x00, /* 0f/15 - pbrl */
0x80, /* 10/16 - afei */
0x01, /* 11/17 - afeii */
0x9f, /* 12/18 - llic */
0x9f, /* 13/19 - rlic */
0x00, /* 14/20 - tlb */
0x00, /* 15/21 - thb */
0x00, /* 16/22 - la3mic/reserved */
0x00, /* 17/23 - ra3mic/reserved */
0x00, /* 18/24 - afs */
0x00, /* 19/25 - lamoc/version */
0x00, /* 1a/26 - mioc */
0x00, /* 1b/27 - ramoc/reserved */
0x20, /* 1c/28 - cdfr */
0x00, /* 1d/29 - res4 */
0x00, /* 1e/30 - cbru */
0x00, /* 1f/31 - cbrl */
};
static u8 __cs4231_readb(struct snd_cs4231 *cp,
mmc-pxamci.rar_Before
版权申诉
54 浏览量
2022-09-23
00:49:23
上传
评论
收藏 11KB RAR 举报
alvarocfc
- 粉丝: 109
- 资源: 1万+
最新资源
- keil2 + proteus + 8051.exe
- 1961ee27df03bd4595d28e24b00dde4e_744c805f7e4fb4d40fa3f695bfbab035_8(1).c
- mediapipe-0.9.0.1-cp37-cp37m-win-amd64.whl.zip
- windows注册表编辑工具
- mediapipe-0.9.0.1-cp37-cp37m-win-amd64.whl.zip
- 校园通行码预约管理系统20240522075502
- 车类型数据集6250张VOC+YOLO格式.zip
- The PyTorch implementation of STGCN.STGCN-main.zip
- 092300108.cpp
- 车类型数据集6000张VOC+YOLO格式.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈