Commit 8cc72361 authored by Wai Yew CHAY's avatar Wai Yew CHAY Committed by Takashi Iwai

ALSA: SB X-Fi driver merge

The Sound Blaster X-Fi driver supports Creative solutions based on
20K1 and 20K2 chipsets.

Supported hardware :

Creative Sound Blaster X-Fi Titanium Fatal1ty® Champion Series
Creative Sound Blaster X-Fi Titanium Fatal1ty Professional Series
Creative Sound Blaster X-Fi Titanium Professional Audio
Creative Sound Blaster X-Fi Titanium
Creative Sound Blaster X-Fi Elite Pro
Creative Sound Blaster X-Fi Platinum
Creative Sound Blaster X-Fi Fatal1ty
Creative Sound Blaster X-Fi XtremeGamer
Creative Sound Blaster X-Fi XtremeMusic

Current release features:

* ALSA PCM Playback
* ALSA Record
* ALSA Mixer

Note:

* External I/O modules detection not included.
Signed-off-by: default avatarWai Yew CHAY <wychay@ctl.creative.com>
Singed-off-by: default avatarRyan RICHARDS <ryan_richards@creativelabs.com>
Signed-off-by: Takashi Iwai's avatarTakashi Iwai <tiwai@suse.de>
parent 091bf762
......@@ -460,6 +460,25 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
The power-management is supported.
Module snd-ctxfi
----------------
Module for Creative Sound Blaster X-Fi boards (20k1 / 20k2 chips)
* Creative Sound Blaster X-Fi Titanium Fatal1ty Champion Series
* Creative Sound Blaster X-Fi Titanium Fatal1ty Professional Series
* Creative Sound Blaster X-Fi Titanium Professional Audio
* Creative Sound Blaster X-Fi Titanium
* Creative Sound Blaster X-Fi Elite Pro
* Creative Sound Blaster X-Fi Platinum
* Creative Sound Blaster X-Fi Fatal1ty
* Creative Sound Blaster X-Fi XtremeGamer
* Creative Sound Blaster X-Fi XtremeMusic
reference_rate - reference sample rate, 44100 or 48000 (default)
multiple - multiple to ref. sample rate, 1 or 2 (default)
This module supports multiple cards.
Module snd-darla20
------------------
......
......@@ -275,6 +275,16 @@ config SND_CS5535AUDIO
To compile this driver as a module, choose M here: the module
will be called snd-cs5535audio.
config SND_CTXFI
tristate "Creative Sound Blaster X-Fi"
select SND_PCM
help
If you want to use soundcards based on Creative Sound Blastr X-Fi
boards with 20k1 or 20k2 chips, say Y here.
To compile this driver as a module, choose M here: the module
will be called snd-ctxfi.
config SND_DARLA20
tristate "(Echoaudio) Darla20"
select FW_LOADER
......
......@@ -59,6 +59,7 @@ obj-$(CONFIG_SND) += \
ali5451/ \
au88x0/ \
aw2/ \
ctxfi/ \
ca0106/ \
cs46xx/ \
cs5535audio/ \
......
snd-ctxfi-objs := xfi.o ctatc.o ctvmem.o ctpcm.o ctmixer.o ctresource.o \
ctsrc.o ctamixer.o ctdaio.o ctimap.o cthardware.o \
cthw20k2.o cthw20k1.o
obj-$(CONFIG_SND_CTXFI) += snd-ctxfi.o
This diff is collapsed.
/**
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
*
* This source file is released under GPL v2 license (no other versions).
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions.
*/
#ifndef _20K2REGISTERS_H_
#define _20K2REGISTERS_H_
/* Timer Registers */
#define TIMER_TIMR 0x1B7004
#define INTERRUPT_GIP 0x1B7010
#define INTERRUPT_GIE 0x1B7014
/* I2C Registers */
#define I2C_IF_ADDRESS 0x1B9000
#define I2C_IF_WDATA 0x1B9004
#define I2C_IF_RDATA 0x1B9008
#define I2C_IF_STATUS 0x1B900C
#define I2C_IF_WLOCK 0x1B9010
/* Global Control Registers */
#define GLOBAL_CNTL_GCTL 0x1B7090
/* PLL Registers */
#define PLL_CTL 0x1B7080
#define PLL_STAT 0x1B7084
#define PLL_ENB 0x1B7088
/* SRC Registers */
#define SRC_CTL 0x1A0000 /* 0x1A0000 + (256 * Chn) */
#define SRC_CCR 0x1A0004 /* 0x1A0004 + (256 * Chn) */
#define SRC_IMAP 0x1A0008 /* 0x1A0008 + (256 * Chn) */
#define SRC_CA 0x1A0010 /* 0x1A0010 + (256 * Chn) */
#define SRC_CF 0x1A0014 /* 0x1A0014 + (256 * Chn) */
#define SRC_SA 0x1A0018 /* 0x1A0018 + (256 * Chn) */
#define SRC_LA 0x1A001C /* 0x1A001C + (256 * Chn) */
#define SRC_CTLSWR 0x1A0020 /* 0x1A0020 + (256 * Chn) */
#define SRC_CD 0x1A0080 /* 0x1A0080 + (256 * Chn) + (4 * Regn) */
#define SRC_MCTL 0x1A012C
#define SRC_IP 0x1A102C /* 0x1A102C + (256 * Regn) */
#define SRC_ENB 0x1A282C /* 0x1A282C + (256 * Regn) */
#define SRC_ENBSTAT 0x1A202C
#define SRC_ENBSA 0x1A232C
#define SRC_DN0Z 0x1A0030
#define SRC_DN1Z 0x1A0040
#define SRC_UPZ 0x1A0060
/* GPIO Registers */
#define GPIO_DATA 0x1B7020
#define GPIO_CTRL 0x1B7024
/* Virtual memory registers */
#define VMEM_PTPAL 0x1C6300 /* 0x1C6300 + (16 * Chn) */
#define VMEM_PTPAH 0x1C6304 /* 0x1C6304 + (16 * Chn) */
#define VMEM_CTL 0x1C7000
/* Transport Registers */
#define TRANSPORT_ENB 0x1B6000
#define TRANSPORT_CTL 0x1B6004
#define TRANSPORT_INT 0x1B6008
/* Audio IO */
#define AUDIO_IO_AIM 0x1B5000 /* 0x1B5000 + (0x04 * Chn) */
#define AUDIO_IO_TX_CTL 0x1B5400 /* 0x1B5400 + (0x40 * Chn) */
#define AUDIO_IO_TX_CSTAT_L 0x1B5408 /* 0x1B5408 + (0x40 * Chn) */
#define AUDIO_IO_TX_CSTAT_H 0x1B540C /* 0x1B540C + (0x40 * Chn) */
#define AUDIO_IO_RX_CTL 0x1B5410 /* 0x1B5410 + (0x40 * Chn) */
#define AUDIO_IO_RX_SRT_CTL 0x1B5420 /* 0x1B5420 + (0x40 * Chn) */
#define AUDIO_IO_MCLK 0x1B5600
#define AUDIO_IO_TX_BLRCLK 0x1B5604
#define AUDIO_IO_RX_BLRCLK 0x1B5608
/* Mixer */
#define MIXER_AMOPLO 0x130000 /* 0x130000 + (8 * Chn) [4095 : 0] */
#define MIXER_AMOPHI 0x130004 /* 0x130004 + (8 * Chn) [4095 : 0] */
#define MIXER_PRING_LO_HI 0x188000 /* 0x188000 + (4 * Chn) [4095 : 0] */
#define MIXER_PMOPLO 0x138000 /* 0x138000 + (8 * Chn) [4095 : 0] */
#define MIXER_PMOPHI 0x138004 /* 0x138004 + (8 * Chn) [4095 : 0] */
#define MIXER_AR_ENABLE 0x19000C
#endif
This diff is collapsed.
/**
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
*
* This source file is released under GPL v2 license (no other versions).
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions.
*
* @File ctamixer.h
*
* @Brief
* This file contains the definition of the Audio Mixer
* resource management object.
*
* @Author Liu Chun
* @Date May 21 2008
*
*/
#ifndef CTAMIXER_H
#define CTAMIXER_H
#include "ctresource.h"
#include <linux/spinlock.h>
/* Define the descriptor of a summation node resource */
struct sum {
struct rsc rsc; /* Basic resource info */
unsigned char idx[8];
};
/* Define sum resource request description info */
struct sum_desc {
unsigned int msr;
};
struct sum_mgr {
struct rsc_mgr mgr; /* Basic resource manager info */
spinlock_t mgr_lock;
/* request one sum resource */
int (*get_sum)(struct sum_mgr *mgr,
const struct sum_desc *desc, struct sum **rsum);
/* return one sum resource */
int (*put_sum)(struct sum_mgr *mgr, struct sum *sum);
};
/* Constructor and destructor of daio resource manager */
int sum_mgr_create(void *hw, struct sum_mgr **rsum_mgr);
int sum_mgr_destroy(struct sum_mgr *sum_mgr);
/* Define the descriptor of a amixer resource */
struct amixer_rsc_ops;
struct amixer {
struct rsc rsc; /* Basic resource info */
unsigned char idx[8];
struct rsc *input; /* pointer to a resource acting as source */
struct sum *sum; /* Put amixer output to this summation node */
struct amixer_rsc_ops *ops; /* AMixer specific operations */
};
struct amixer_rsc_ops {
int (*set_input)(struct amixer *amixer, struct rsc *rsc);
int (*set_scale)(struct amixer *amixer, unsigned int scale);
int (*set_invalid_squash)(struct amixer *amixer, unsigned int iv);
int (*set_sum)(struct amixer *amixer, struct sum *sum);
int (*commit_write)(struct amixer *amixer);
/* Only for interleaved recording */
int (*commit_raw_write)(struct amixer *amixer);
int (*setup)(struct amixer *amixer, struct rsc *input,
unsigned int scale, struct sum *sum);
int (*get_scale)(struct amixer *amixer);
};
/* Define amixer resource request description info */
struct amixer_desc {
unsigned int msr;
};
struct amixer_mgr {
struct rsc_mgr mgr; /* Basic resource manager info */
spinlock_t mgr_lock;
/* request one amixer resource */
int (*get_amixer)(struct amixer_mgr *mgr,
const struct amixer_desc *desc,
struct amixer **ramixer);
/* return one amixer resource */
int (*put_amixer)(struct amixer_mgr *mgr, struct amixer *amixer);
};
/* Constructor and destructor of amixer resource manager */
int amixer_mgr_create(void *hw, struct amixer_mgr **ramixer_mgr);
int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr);
#endif /* CTAMIXER_H */
This diff is collapsed.
/**
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
*
* This source file is released under GPL v2 license (no other versions).
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions.
*
* @File ctatc.h
*
* @Brief
* This file contains the definition of the device resource management object.
*
* @Author Liu Chun
* @Date Mar 28 2008
*
*/
#ifndef CTATC_H
#define CTATC_H
#include <linux/types.h>
#include <linux/spinlock_types.h>
#include <linux/pci.h>
#include <linux/timer.h>
#include <sound/core.h>
#include "ctvmem.h"
#include "ctresource.h"
enum CTALSADEVS { /* Types of alsa devices */
FRONT,
REAR,
CLFE,
SURROUND,
IEC958,
MIXER,
NUM_CTALSADEVS /* This should always be the last */
};
enum CTCARDS {
CTSB0760,
CTHENDRIX,
CTSB08801,
CTSB08802,
CTSB08803,
NUM_CTCARDS /* This should always be the last */
};
struct ct_atc_chip_sub_details {
u16 subsys;
const char *nm_model;
};
struct ct_atc_chip_details {
u16 vendor;
u16 device;
const struct ct_atc_chip_sub_details *sub_details;
const char *nm_card;
};
struct ct_atc;
/* alsa pcm stream descriptor */
struct ct_atc_pcm {
struct snd_pcm_substream *substream;
void (*interrupt)(struct ct_atc_pcm *apcm);
unsigned int started:1;
unsigned int stop_timer:1;
struct timer_list timer;
spinlock_t timer_lock;
unsigned int position;
/* Only mono and interleaved modes are supported now. */
struct ct_vm_block *vm_block;
void *src; /* SRC for interacting with host memory */
void **srccs; /* SRCs for sample rate conversion */
void **srcimps; /* SRC Input Mappers */
void **amixers; /* AMIXERs for routing converted data */
void *mono; /* A SUM resource for mixing chs to one */
unsigned char n_srcc; /* Number of converting SRCs */
unsigned char n_srcimp; /* Number of SRC Input Mappers */
unsigned char n_amixer; /* Number of AMIXERs */
};
/* Chip resource management object */
struct ct_atc {
struct pci_dev *pci;
struct snd_card *card;
unsigned int rsr; /* reference sample rate in Hz */
unsigned int msr; /* master sample rate in rsr */
unsigned int pll_rate; /* current rate of Phase Lock Loop */
const struct ct_atc_chip_details *chip_details;
enum CTCARDS model;
/* Create all alsa devices */
int (*create_alsa_devs)(struct ct_atc *atc);
struct ct_vm *vm; /* device virtual memory manager for this card */
int (*map_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
void (*unmap_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index);
spinlock_t atc_lock;
spinlock_t vm_lock;
int (*pcm_playback_prepare)(struct ct_atc *atc,
struct ct_atc_pcm *apcm);
int (*pcm_playback_start)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
int (*pcm_playback_stop)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
int (*pcm_playback_position)(struct ct_atc *atc,
struct ct_atc_pcm *apcm);
int (*spdif_passthru_playback_prepare)(struct ct_atc *atc,
struct ct_atc_pcm *apcm);
int (*pcm_capture_prepare)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
int (*pcm_capture_start)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
int (*pcm_capture_stop)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
int (*pcm_capture_position)(struct ct_atc *atc,
struct ct_atc_pcm *apcm);
int (*pcm_release_resources)(struct ct_atc *atc,
struct ct_atc_pcm *apcm);
int (*select_line_in)(struct ct_atc *atc);
int (*select_mic_in)(struct ct_atc *atc);
int (*select_digit_io)(struct ct_atc *atc);
int (*line_front_unmute)(struct ct_atc *atc, unsigned char state);
int (*line_surround_unmute)(struct ct_atc *atc, unsigned char state);
int (*line_clfe_unmute)(struct ct_atc *atc, unsigned char state);
int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state);
int (*line_in_unmute)(struct ct_atc *atc, unsigned char state);
int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state);
int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state);
int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status);
int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status);
int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state);
int (*have_digit_io_switch)(struct ct_atc *atc);
/* Don't touch! Used for internal object. */
void *rsc_mgrs[NUM_RSCTYP]; /* chip resource managers */
void *mixer; /* internal mixer object */
void *hw; /* chip specific hardware access object */
void **daios; /* digital audio io resources */
void **pcm; /* SUMs for collecting all pcm stream */
void **srcs; /* Sample Rate Converters for input signal */
void **srcimps; /* input mappers for SRCs */
unsigned char n_daio;
unsigned char n_src;
unsigned char n_srcimp;
unsigned char n_pcm;
};
int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
unsigned int rsr, unsigned int msr,
struct ct_atc **ratc);
#endif /* CTATC_H */
This diff is collapsed.
/**
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
*
* This source file is released under GPL v2 license (no other versions).
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions.
*
* @File ctdaio.h
*
* @Brief
* This file contains the definition of Digital Audio Input Output
* resource management object.
*
* @Author Liu Chun
* @Date May 23 2008
*
*/
#ifndef CTDAIO_H
#define CTDAIO_H
#include "ctresource.h"
#include "ctimap.h"
#include <linux/spinlock.h>
#include <linux/list.h>
/* Define the descriptor of a daio resource */
enum DAIOTYP {
LINEO1,
LINEO2,
LINEO3,
LINEO4,
SPDIFOO, /* S/PDIF Out (Flexijack/Optical) */
LINEIM,
SPDIFIO, /* S/PDIF In (Flexijack/Optical) on the card */
SPDIFI1, /* S/PDIF In on internal Drive Bay */
NUM_DAIOTYP
};
struct dao_rsc_ops;
struct dai_rsc_ops;
struct daio_mgr;
struct daio {
struct rsc rscl; /* Basic resource info for left TX/RX */
struct rsc rscr; /* Basic resource info for right TX/RX */
enum DAIOTYP type;
};
struct dao {
struct daio daio;
struct dao_rsc_ops *ops; /* DAO specific operations */
struct imapper **imappers;
struct daio_mgr *mgr;
void *hw;
void *ctrl_blk;
};
struct dai {
struct daio daio;
struct dai_rsc_ops *ops; /* DAI specific operations */
void *hw;
void *ctrl_blk;
};
struct dao_desc {
unsigned int msr:4;
unsigned int passthru:1;
};
struct dao_rsc_ops {
int (*set_spos)(struct dao *dao, unsigned int spos);
int (*commit_write)(struct dao *dao);
int (*get_spos)(struct dao *dao, unsigned int *spos);
int (*reinit)(struct dao *dao, const struct dao_desc *desc);
int (*set_left_input)(struct dao *dao, struct rsc *input);
int (*set_right_input)(struct dao *dao, struct rsc *input);
int (*clear_left_input)(struct dao *dao);
int (*clear_right_input)(struct dao *dao);
};
struct dai_rsc_ops {
int (*set_srt_srcl)(struct dai *dai, struct rsc *src);
int (*set_srt_srcr)(struct dai *dai, struct rsc *src);
int (*set_srt_msr)(struct dai *dai, unsigned int msr);
int (*set_enb_src)(struct dai *dai, unsigned int enb);
int (*set_enb_srt)(struct dai *dai, unsigned int enb);
int (*commit_write)(struct dai *dai);
};
/* Define daio resource request description info */
struct daio_desc {
unsigned int type:4;
unsigned int msr:4;
unsigned int passthru:1;
};
struct daio_mgr {
struct rsc_mgr mgr; /* Basic resource manager info */
spinlock_t mgr_lock;
spinlock_t imap_lock;
struct list_head imappers;
struct imapper *init_imap;
unsigned int init_imap_added;
/* request one daio resource */
int (*get_daio)(struct daio_mgr *mgr,
const struct daio_desc *desc, struct daio **rdaio);
/* return one daio resource */
int (*put_daio)(struct daio_mgr *mgr, struct daio *daio);
int (*daio_enable)(struct daio_mgr *mgr, struct daio *daio);
int (*daio_disable)(struct daio_mgr *mgr, struct daio *daio);
int (*imap_add)(struct daio_mgr *mgr, struct imapper *entry);
int (*imap_delete)(struct daio_mgr *mgr, struct imapper *entry);
int (*commit_write)(struct daio_mgr *mgr);
};
/* Constructor and destructor of daio resource manager */
int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr);
int daio_mgr_destroy(struct daio_mgr *daio_mgr);
#endif /* CTDAIO_H */
/**
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
*
* This source file is released under GPL v2 license (no other versions).
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions.
*
* @file ctdrv.h
*
* @breaf
* This file contains the definition of card IDs supported by this driver.
*
* @author Liu Chun
*
*/
#ifndef CTDRV_H
#define CTDRV_H
#define PCI_VENDOR_CREATIVE 0x1102
#define PCI_DEVICE_CREATIVE_20K1 0x0005
#define PCI_DEVICE_CREATIVE_20K2 0x000B
#define PCI_SUBVENDOR_CREATIVE 0x1102
#define PCI_SUBSYS_CREATIVE_SB0760 0x0024
#define PCI_SUBSYS_CREATIVE_SB08801 0x0041
#define PCI_SUBSYS_CREATIVE_SB08802 0x0042
#define PCI_SUBSYS_CREATIVE_SB08803 0x0043
#define PCI_SUBSYS_CREATIVE_HENDRIX 0x6000
#endif /* CTDRV_H */
/**
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
*
* This source file is released under GPL v2 license (no other versions).
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions.
*
* @File cthardware.c
*
* @Brief
* This file contains the implementation of hardware access methord.
*
* @Author Liu Chun
* @Date Jun 26 2008
*
*/
#include "cthardware.h"
#include "cthw20k1.h"
#include "cthw20k2.h"
#include <linux/bug.h>
static enum CHIPTYP get_chip_type(struct hw *hw)
{
enum CHIPTYP type = ATCNONE;
switch (hw->pci->device) {
case 0x0005: /* 20k1 device */
type = ATC20K1;
break;
case 0x000B: /* 20k2 device */
type = ATC20K2;
break;
default:
type = ATCNONE;
break;
}
return type;
}
int create_hw_obj(struct pci_dev *pci, struct hw **rhw)
{
int err = 0;
switch (pci->device) {
case 0x0005: /* 20k1 device */
err = create_20k1_hw_obj(rhw);
break;
case 0x000B: /* 20k2 device */
err = create_20k2_hw_obj(rhw);
break;
default:
err = -ENODEV;
break;
}
if (err)
return err;
(*rhw)->pci = pci;
(*rhw)->get_chip_type = get_chip_type;
return 0;
}
int destroy_hw_obj(struct hw *hw)
{
int err = 0;
switch (hw->pci->device) {
case 0x0005: /* 20k1 device */
err = destroy_20k1_hw_obj(hw);
break;
case 0x000B: /* 20k2 device */
err = destroy_20k2_hw_obj(hw);
break;
default:
err = -ENODEV;
break;
}
return err;
}