2007-12-23 19:50:57 +01:00
# ifndef OXYGEN_H_INCLUDED
# define OXYGEN_H_INCLUDED
# include <linux/mutex.h>
# include <linux/spinlock.h>
2008-01-28 08:34:21 +01:00
# include <linux/wait.h>
2007-12-23 19:50:57 +01:00
# include <linux/workqueue.h>
# include "oxygen_regs.h"
/* 1 << PCM_x == OXYGEN_CHANNEL_x */
# define PCM_A 0
# define PCM_B 1
# define PCM_C 2
# define PCM_SPDIF 3
# define PCM_MULTICH 4
# define PCM_AC97 5
# define PCM_COUNT 6
2008-05-13 09:19:53 +02:00
# define OXYGEN_IO_SIZE 0x100
2008-03-19 08:19:41 +01:00
/* model-specific configuration of outputs/inputs */
2008-09-22 09:03:42 +02:00
# define PLAYBACK_0_TO_I2S 0x0001
/* PLAYBACK_0_TO_AC97_0 not implemented */
# define PLAYBACK_1_TO_SPDIF 0x0004
# define PLAYBACK_2_TO_AC97_1 0x0008
# define CAPTURE_0_FROM_I2S_1 0x0010
# define CAPTURE_0_FROM_I2S_2 0x0020
/* CAPTURE_0_FROM_AC97_0 not implemented */
# define CAPTURE_1_FROM_SPDIF 0x0080
# define CAPTURE_2_FROM_I2S_2 0x0100
# define CAPTURE_2_FROM_AC97_1 0x0200
/* CAPTURE_3_FROM_I2S_3 not implemented */
# define MIDI_OUTPUT 0x0800
# define MIDI_INPUT 0x1000
2008-03-19 08:19:41 +01:00
2008-01-14 08:56:01 +01:00
enum {
CONTROL_SPDIF_PCM ,
CONTROL_SPDIF_INPUT_BITS ,
2008-01-14 08:57:05 +01:00
CONTROL_MIC_CAPTURE_SWITCH ,
CONTROL_LINE_CAPTURE_SWITCH ,
CONTROL_CD_CAPTURE_SWITCH ,
CONTROL_AUX_CAPTURE_SWITCH ,
2008-01-14 08:56:01 +01:00
CONTROL_COUNT
} ;
2007-12-23 19:50:57 +01:00
# define OXYGEN_PCI_SUBID(sv, sd) \
. vendor = PCI_VENDOR_ID_CMEDIA , \
. device = 0x8788 , \
. subvendor = sv , \
. subdevice = sd
struct pci_dev ;
struct snd_card ;
struct snd_pcm_substream ;
2008-01-16 08:32:53 +01:00
struct snd_pcm_hardware ;
2007-12-23 19:50:57 +01:00
struct snd_pcm_hw_params ;
2008-01-16 08:32:08 +01:00
struct snd_kcontrol_new ;
2007-12-23 19:50:57 +01:00
struct snd_rawmidi ;
2008-09-22 08:55:19 +02:00
struct oxygen ;
2007-12-23 19:50:57 +01:00
struct oxygen_model {
const char * shortname ;
const char * longname ;
const char * chip ;
struct module * owner ;
2008-09-22 08:56:01 +02:00
int ( * probe ) ( struct oxygen * chip , unsigned long driver_data ) ;
2007-12-23 19:50:57 +01:00
void ( * init ) ( struct oxygen * chip ) ;
2008-01-16 08:32:08 +01:00
int ( * control_filter ) ( struct snd_kcontrol_new * template ) ;
2007-12-23 19:50:57 +01:00
int ( * mixer_init ) ( struct oxygen * chip ) ;
void ( * cleanup ) ( struct oxygen * chip ) ;
2008-05-13 09:24:39 +02:00
void ( * suspend ) ( struct oxygen * chip ) ;
void ( * resume ) ( struct oxygen * chip ) ;
2008-01-16 08:32:53 +01:00
void ( * pcm_hardware_filter ) ( unsigned int channel ,
struct snd_pcm_hardware * hardware ) ;
2007-12-23 19:50:57 +01:00
void ( * set_dac_params ) ( struct oxygen * chip ,
struct snd_pcm_hw_params * params ) ;
void ( * set_adc_params ) ( struct oxygen * chip ,
struct snd_pcm_hw_params * params ) ;
void ( * update_dac_volume ) ( struct oxygen * chip ) ;
void ( * update_dac_mute ) ( struct oxygen * chip ) ;
2008-01-28 08:36:55 +01:00
void ( * gpio_changed ) ( struct oxygen * chip ) ;
2008-04-09 09:16:14 +02:00
void ( * ac97_switch ) ( struct oxygen * chip ,
unsigned int reg , unsigned int mute ) ;
2008-04-16 09:15:45 +02:00
const unsigned int * dac_tlv ;
2008-01-21 08:51:55 +01:00
size_t model_data_size ;
2008-09-22 09:02:08 +02:00
unsigned int device_config ;
2008-01-25 08:37:49 +01:00
u8 dac_channels ;
2008-04-16 09:13:36 +02:00
u8 dac_volume_min ;
u8 dac_volume_max ;
2008-03-19 08:20:59 +01:00
u8 misc_flags ;
2008-01-16 08:28:54 +01:00
u8 function_flags ;
2008-01-17 09:05:09 +01:00
u16 dac_i2s_format ;
u16 adc_i2s_format ;
2007-12-23 19:50:57 +01:00
} ;
2008-09-22 08:55:19 +02:00
struct oxygen {
unsigned long addr ;
spinlock_t reg_lock ;
struct mutex mutex ;
struct snd_card * card ;
struct pci_dev * pci ;
struct snd_rawmidi * midi ;
int irq ;
void * model_data ;
unsigned int interrupt_mask ;
u8 dac_volume [ 8 ] ;
u8 dac_mute ;
u8 pcm_active ;
u8 pcm_running ;
u8 dac_routing ;
u8 spdif_playback_enable ;
u8 revision ;
u8 has_ac97_0 ;
u8 has_ac97_1 ;
u32 spdif_bits ;
u32 spdif_pcm_bits ;
struct snd_pcm_substream * streams [ PCM_COUNT ] ;
struct snd_kcontrol * controls [ CONTROL_COUNT ] ;
struct work_struct spdif_input_bits_work ;
struct work_struct gpio_work ;
wait_queue_head_t ac97_waitqueue ;
union {
u8 _8 [ OXYGEN_IO_SIZE ] ;
__le16 _16 [ OXYGEN_IO_SIZE / 2 ] ;
__le32 _32 [ OXYGEN_IO_SIZE / 4 ] ;
} saved_registers ;
u16 saved_ac97_registers [ 2 ] [ 0x40 ] ;
struct oxygen_model model ;
} ;
2007-12-23 19:50:57 +01:00
/* oxygen_lib.c */
2008-03-19 08:20:59 +01:00
int oxygen_pci_probe ( struct pci_dev * pci , int index , char * id ,
2008-09-22 08:56:01 +02:00
const struct oxygen_model * model ,
unsigned long driver_data ) ;
2007-12-23 19:50:57 +01:00
void oxygen_pci_remove ( struct pci_dev * pci ) ;
2008-05-13 09:24:39 +02:00
# ifdef CONFIG_PM
int oxygen_pci_suspend ( struct pci_dev * pci , pm_message_t state ) ;
int oxygen_pci_resume ( struct pci_dev * pci ) ;
# endif
2007-12-23 19:50:57 +01:00
/* oxygen_mixer.c */
int oxygen_mixer_init ( struct oxygen * chip ) ;
void oxygen_update_dac_routing ( struct oxygen * chip ) ;
void oxygen_update_spdif_source ( struct oxygen * chip ) ;
/* oxygen_pcm.c */
int oxygen_pcm_init ( struct oxygen * chip ) ;
/* oxygen_io.c */
u8 oxygen_read8 ( struct oxygen * chip , unsigned int reg ) ;
u16 oxygen_read16 ( struct oxygen * chip , unsigned int reg ) ;
u32 oxygen_read32 ( struct oxygen * chip , unsigned int reg ) ;
void oxygen_write8 ( struct oxygen * chip , unsigned int reg , u8 value ) ;
void oxygen_write16 ( struct oxygen * chip , unsigned int reg , u16 value ) ;
void oxygen_write32 ( struct oxygen * chip , unsigned int reg , u32 value ) ;
void oxygen_write8_masked ( struct oxygen * chip , unsigned int reg ,
u8 value , u8 mask ) ;
void oxygen_write16_masked ( struct oxygen * chip , unsigned int reg ,
u16 value , u16 mask ) ;
void oxygen_write32_masked ( struct oxygen * chip , unsigned int reg ,
u32 value , u32 mask ) ;
u16 oxygen_read_ac97 ( struct oxygen * chip , unsigned int codec ,
unsigned int index ) ;
void oxygen_write_ac97 ( struct oxygen * chip , unsigned int codec ,
unsigned int index , u16 data ) ;
void oxygen_write_ac97_masked ( struct oxygen * chip , unsigned int codec ,
unsigned int index , u16 data , u16 mask ) ;
void oxygen_write_spi ( struct oxygen * chip , u8 control , unsigned int data ) ;
2008-04-07 10:23:37 +02:00
void oxygen_write_i2c ( struct oxygen * chip , u8 device , u8 map , u8 data ) ;
2007-12-23 19:50:57 +01:00
static inline void oxygen_set_bits8 ( struct oxygen * chip ,
unsigned int reg , u8 value )
{
oxygen_write8_masked ( chip , reg , value , value ) ;
}
static inline void oxygen_set_bits16 ( struct oxygen * chip ,
unsigned int reg , u16 value )
{
oxygen_write16_masked ( chip , reg , value , value ) ;
}
static inline void oxygen_set_bits32 ( struct oxygen * chip ,
unsigned int reg , u32 value )
{
oxygen_write32_masked ( chip , reg , value , value ) ;
}
static inline void oxygen_clear_bits8 ( struct oxygen * chip ,
unsigned int reg , u8 value )
{
oxygen_write8_masked ( chip , reg , 0 , value ) ;
}
static inline void oxygen_clear_bits16 ( struct oxygen * chip ,
unsigned int reg , u16 value )
{
oxygen_write16_masked ( chip , reg , 0 , value ) ;
}
static inline void oxygen_clear_bits32 ( struct oxygen * chip ,
unsigned int reg , u32 value )
{
oxygen_write32_masked ( chip , reg , 0 , value ) ;
}
static inline void oxygen_ac97_set_bits ( struct oxygen * chip , unsigned int codec ,
unsigned int index , u16 value )
{
oxygen_write_ac97_masked ( chip , codec , index , value , value ) ;
}
static inline void oxygen_ac97_clear_bits ( struct oxygen * chip ,
unsigned int codec ,
unsigned int index , u16 value )
{
oxygen_write_ac97_masked ( chip , codec , index , 0 , value ) ;
}
# endif