diff options
Diffstat (limited to 'sound/pci/es1968.c')
| -rw-r--r-- | sound/pci/es1968.c | 692 |
1 files changed, 432 insertions, 260 deletions
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 3747a436f0c..5bb1cf60330 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -94,21 +94,28 @@ * places. */ -#include <sound/driver.h> #include <asm/io.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/init.h> #include <linux/pci.h> +#include <linux/dma-mapping.h> #include <linux/slab.h> #include <linux/gameport.h> -#include <linux/moduleparam.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/input.h> + #include <sound/core.h> #include <sound/pcm.h> #include <sound/mpu401.h> #include <sound/ac97_codec.h> #include <sound/initval.h> +#ifdef CONFIG_SND_ES1968_RADIO +#include <media/tea575x.h> +#endif + #define CARD_NAME "ESS Maestro1/2" #define DRIVER_NAME "ES1968" @@ -125,16 +132,17 @@ MODULE_SUPPORTED_DEVICE("{{ESS,Maestro 2e}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 1-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int total_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1024 }; static int pcm_substreams_p[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4 }; static int pcm_substreams_c[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 }; -static int clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; +static int clock[SNDRV_CARDS]; static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; #ifdef SUPPORT_JOYSTICK -static int joystick[SNDRV_CARDS]; +static bool joystick[SNDRV_CARDS]; #endif +static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); @@ -158,6 +166,9 @@ MODULE_PARM_DESC(enable_mpu, "Enable MPU401. (0 = off, 1 = on, 2 = auto)"); module_param_array(joystick, bool, NULL, 0444); MODULE_PARM_DESC(joystick, "Enable joystick."); #endif +module_param_array(radio_nr, int, NULL, 0444); +MODULE_PARM_DESC(radio_nr, "Radio device numbers"); + #define NR_APUS 64 @@ -217,7 +228,7 @@ MODULE_PARM_DESC(joystick, "Enable joystick."); #define RINGB_EN_2CODEC 0x0020 #define RINGB_SING_BIT_DUAL 0x0040 -/* ****Port Adresses**** */ +/* ****Port Addresses**** */ /* Write & Read */ #define ESM_INDEX 0x02 @@ -429,46 +440,6 @@ MODULE_PARM_DESC(joystick, "Enable joystick."); #define ESM_MODE_PLAY 0 #define ESM_MODE_CAPTURE 1 -/* acpi states */ -enum { - ACPI_D0=0, - ACPI_D1, - ACPI_D2, - ACPI_D3 -}; - -/* bits in the acpi masks */ -#define ACPI_12MHZ ( 1 << 15) -#define ACPI_24MHZ ( 1 << 14) -#define ACPI_978 ( 1 << 13) -#define ACPI_SPDIF ( 1 << 12) -#define ACPI_GLUE ( 1 << 11) -#define ACPI__10 ( 1 << 10) /* reserved */ -#define ACPI_PCIINT ( 1 << 9) -#define ACPI_HV ( 1 << 8) /* hardware volume */ -#define ACPI_GPIO ( 1 << 7) -#define ACPI_ASSP ( 1 << 6) -#define ACPI_SB ( 1 << 5) /* sb emul */ -#define ACPI_FM ( 1 << 4) /* fm emul */ -#define ACPI_RB ( 1 << 3) /* ringbus / aclink */ -#define ACPI_MIDI ( 1 << 2) -#define ACPI_GP ( 1 << 1) /* game port */ -#define ACPI_WP ( 1 << 0) /* wave processor */ - -#define ACPI_ALL (0xffff) -#define ACPI_SLEEP (~(ACPI_SPDIF|ACPI_ASSP|ACPI_SB|ACPI_FM| \ - ACPI_MIDI|ACPI_GP|ACPI_WP)) -#define ACPI_NONE (ACPI__10) - -/* these masks indicate which units we care about at - which states */ -static u16 acpi_state_mask[] = { - [ACPI_D0] = ACPI_ALL, - [ACPI_D1] = ACPI_SLEEP, - [ACPI_D2] = ACPI_SLEEP, - [ACPI_D3] = ACPI_NONE -}; - /* APU use in the driver */ enum snd_enum_apu_type { @@ -520,7 +491,7 @@ struct esschan { /* linked list */ struct list_head list; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP u16 wc_map[4]; #endif }; @@ -555,21 +526,16 @@ struct es1968 { /* ALSA Stuff */ struct snd_ac97 *ac97; - struct snd_kcontrol *master_switch; /* for h/w volume control */ - struct snd_kcontrol *master_volume; - struct snd_rawmidi *rmidi; spinlock_t reg_lock; - spinlock_t ac97_lock; - struct tasklet_struct hwvol_tq; unsigned int in_suspend; /* Maestro Stuff */ u16 maestro_map[32]; int bobclient; /* active timer instancs */ int bob_freq; /* timer frequency */ - struct semaphore memory_mutex; /* memory lock */ + struct mutex memory_mutex; /* memory lock */ /* APU states */ unsigned char apu[NR_APUS]; @@ -578,18 +544,33 @@ struct es1968 { struct list_head substream_list; spinlock_t substream_lock; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP u16 apu_map[NR_APUS][NR_APU_REGS]; #endif #ifdef SUPPORT_JOYSTICK struct gameport *gameport; #endif + +#ifdef CONFIG_SND_ES1968_INPUT + struct input_dev *input_dev; + char phys[64]; /* physical device path */ +#else + struct snd_kcontrol *master_switch; /* for h/w volume control */ + struct snd_kcontrol *master_volume; +#endif + struct work_struct hwvol_work; + +#ifdef CONFIG_SND_ES1968_RADIO + struct v4l2_device v4l2_dev; + struct snd_tea575x tea; + unsigned int tea575x_tuner; +#endif }; -static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); -static struct pci_device_id snd_es1968_ids[] = { +static DEFINE_PCI_DEVICE_TABLE(snd_es1968_ids) = { /* Maestro 1 */ { 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO }, /* Maestro 2 */ @@ -651,43 +632,49 @@ static int snd_es1968_ac97_wait(struct es1968 *chip) return 0; cond_resched(); } - snd_printd("es1968: ac97 timeout\n"); + dev_dbg(chip->card->dev, "ac97 timeout\n"); + return 1; /* timeout */ +} + +static int snd_es1968_ac97_wait_poll(struct es1968 *chip) +{ + int timeout = 100000; + + while (timeout-- > 0) { + if (!(inb(chip->io_port + ESM_AC97_INDEX) & 1)) + return 0; + } + dev_dbg(chip->card->dev, "ac97 timeout\n"); return 1; /* timeout */ } static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) { struct es1968 *chip = ac97->private_data; - unsigned long flags; snd_es1968_ac97_wait(chip); /* Write the bus */ - spin_lock_irqsave(&chip->ac97_lock, flags); outw(val, chip->io_port + ESM_AC97_DATA); /*msleep(1);*/ outb(reg, chip->io_port + ESM_AC97_INDEX); /*msleep(1);*/ - spin_unlock_irqrestore(&chip->ac97_lock, flags); } static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg) { u16 data = 0; struct es1968 *chip = ac97->private_data; - unsigned long flags; snd_es1968_ac97_wait(chip); - spin_lock_irqsave(&chip->ac97_lock, flags); outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX); /*msleep(1);*/ - if (! snd_es1968_ac97_wait(chip)) { + if (!snd_es1968_ac97_wait_poll(chip)) { data = inw(chip->io_port + ESM_AC97_DATA); /*msleep(1);*/ } - spin_unlock_irqrestore(&chip->ac97_lock, flags); return data; } @@ -700,7 +687,7 @@ static void apu_index_set(struct es1968 *chip, u16 index) for (i = 0; i < 1000; i++) if (__maestro_read(chip, IDR1_CRAM_POINTER) == index) return; - snd_printd("es1968: APU register select failed. (Timeout)\n"); + dev_dbg(chip->card->dev, "APU register select failed. (Timeout)\n"); } /* no spinlock */ @@ -712,14 +699,15 @@ static void apu_data_set(struct es1968 *chip, u16 data) return; __maestro_write(chip, IDR0_DATA_PORT, data); } - snd_printd("es1968: APU register set probably failed (Timeout)!\n"); + dev_dbg(chip->card->dev, "APU register set probably failed (Timeout)!\n"); } /* no spinlock */ static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data) { - snd_assert(channel < NR_APUS, return); -#ifdef CONFIG_PM + if (snd_BUG_ON(channel >= NR_APUS)) + return; +#ifdef CONFIG_PM_SLEEP chip->apu_map[channel][reg] = data; #endif reg |= (channel << 4); @@ -737,7 +725,8 @@ static void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data) static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg) { - snd_assert(channel < NR_APUS, return 0); + if (snd_BUG_ON(channel >= NR_APUS)) + return 0; reg |= (channel << 4); apu_index_set(chip, reg); return __maestro_read(chip, IDR0_DATA_PORT); @@ -880,10 +869,9 @@ static void snd_es1968_bob_dec(struct es1968 *chip) snd_es1968_bob_stop(chip); else if (chip->bob_freq > ESM_BOB_FREQ) { /* check reduction of timer frequency */ - struct list_head *p; int max_freq = ESM_BOB_FREQ; - list_for_each(p, &chip->substream_list) { - struct esschan *es = list_entry(p, struct esschan, list); + struct esschan *es; + list_for_each_entry(es, &chip->substream_list, list) { if (max_freq < es->bob_freq) max_freq = es->bob_freq; } @@ -1006,7 +994,7 @@ static void snd_es1968_program_wavecache(struct es1968 *chip, struct esschan *es /* set the wavecache control reg */ wave_set_register(chip, es->apu[channel] << 3, tmpval); -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP es->wc_map[channel] = tmpval; #endif } @@ -1353,16 +1341,15 @@ static struct snd_pcm_hardware snd_es1968_capture = { static int calc_available_memory_size(struct es1968 *chip) { - struct list_head *p; int max_size = 0; - - down(&chip->memory_mutex); - list_for_each(p, &chip->buf_list) { - struct esm_memory *buf = list_entry(p, struct esm_memory, list); + struct esm_memory *buf; + + mutex_lock(&chip->memory_mutex); + list_for_each_entry(buf, &chip->buf_list, list) { if (buf->empty && buf->buf.bytes > max_size) max_size = buf->buf.bytes; } - up(&chip->memory_mutex); + mutex_unlock(&chip->memory_mutex); if (max_size >= 128*1024) max_size = 127*1024; return max_size; @@ -1372,23 +1359,21 @@ static int calc_available_memory_size(struct es1968 *chip) static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size) { struct esm_memory *buf; - struct list_head *p; - - size = ((size + ESM_MEM_ALIGN - 1) / ESM_MEM_ALIGN) * ESM_MEM_ALIGN; - down(&chip->memory_mutex); - list_for_each(p, &chip->buf_list) { - buf = list_entry(p, struct esm_memory, list); + + size = ALIGN(size, ESM_MEM_ALIGN); + mutex_lock(&chip->memory_mutex); + list_for_each_entry(buf, &chip->buf_list, list) { if (buf->empty && buf->buf.bytes >= size) goto __found; } - up(&chip->memory_mutex); + mutex_unlock(&chip->memory_mutex); return NULL; __found: if (buf->buf.bytes > size) { struct esm_memory *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL); if (chunk == NULL) { - up(&chip->memory_mutex); + mutex_unlock(&chip->memory_mutex); return NULL; } chunk->buf = buf->buf; @@ -1400,7 +1385,7 @@ __found: list_add(&chunk->list, &buf->list); } buf->empty = 0; - up(&chip->memory_mutex); + mutex_unlock(&chip->memory_mutex); return buf; } @@ -1409,7 +1394,7 @@ static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf) { struct esm_memory *chunk; - down(&chip->memory_mutex); + mutex_lock(&chip->memory_mutex); buf->empty = 1; if (buf->list.prev != &chip->buf_list) { chunk = list_entry(buf->list.prev, struct esm_memory, list); @@ -1428,7 +1413,7 @@ static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf) kfree(chunk); } } - up(&chip->memory_mutex); + mutex_unlock(&chip->memory_mutex); } static void snd_es1968_free_dmabuf(struct es1968 *chip) @@ -1437,7 +1422,7 @@ static void snd_es1968_free_dmabuf(struct es1968 *chip) if (! chip->dma.area) return; - snd_dma_reserve_buf(&chip->dma, snd_dma_pci_buf_id(chip->pci)); + snd_dma_free_pages(&chip->dma); while ((p = chip->buf_list.next) != &chip->buf_list) { struct esm_memory *chunk = list_entry(p, struct esm_memory, list); list_del(p); @@ -1445,7 +1430,7 @@ static void snd_es1968_free_dmabuf(struct es1968 *chip) } } -static int __devinit +static int snd_es1968_init_dmabuf(struct es1968 *chip) { int err; @@ -1453,20 +1438,19 @@ snd_es1968_init_dmabuf(struct es1968 *chip) chip->dma.dev.type = SNDRV_DMA_TYPE_DEV; chip->dma.dev.dev = snd_dma_pci_data(chip->pci); - if (! snd_dma_get_reserved_buf(&chip->dma, snd_dma_pci_buf_id(chip->pci))) { - err = snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(chip->pci), - chip->total_bufsize, &chip->dma); - if (err < 0 || ! chip->dma.area) { - snd_printk(KERN_ERR "es1968: can't allocate dma pages for size %d\n", - chip->total_bufsize); - return -ENOMEM; - } - if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) { - snd_dma_free_pages(&chip->dma); - snd_printk(KERN_ERR "es1968: DMA buffer beyond 256MB.\n"); - return -ENOMEM; - } + err = snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), + chip->total_bufsize, &chip->dma); + if (err < 0 || ! chip->dma.area) { + dev_err(chip->card->dev, + "can't allocate dma pages for size %d\n", + chip->total_bufsize); + return -ENOMEM; + } + if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) { + snd_dma_free_pages(&chip->dma); + dev_err(chip->card->dev, "DMA buffer beyond 256MB.\n"); + return -ENOMEM; } INIT_LIST_HEAD(&chip->buf_list); @@ -1506,7 +1490,8 @@ static int snd_es1968_hw_params(struct snd_pcm_substream *substream, } chan->memory = snd_es1968_new_memory(chip, size); if (chan->memory == NULL) { - // snd_printd("cannot allocate dma buffer: size = %d\n", size); + dev_dbg(chip->card->dev, + "cannot allocate dma buffer: size = %d\n", size); return -ENOMEM; } snd_pcm_set_runtime_buffer(substream, &chan->memory->buf); @@ -1591,10 +1576,7 @@ static int snd_es1968_playback_open(struct snd_pcm_substream *substream) runtime->hw = snd_es1968_playback; runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = calc_available_memory_size(chip); -#if 0 - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - 1024); -#endif + spin_lock_irq(&chip->substream_lock); list_add(&es->list, &chip->substream_list); spin_unlock_irq(&chip->substream_lock); @@ -1650,10 +1632,8 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream) runtime->hw = snd_es1968_capture; runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */ -#if 0 - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - 1024); -#endif + snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES); + spin_lock_irq(&chip->substream_lock); list_add(&es->list, &chip->substream_list); spin_unlock_irq(&chip->substream_lock); @@ -1725,7 +1705,7 @@ static struct snd_pcm_ops snd_es1968_capture_ops = { */ #define CLOCK_MEASURE_BUFSIZE 16768 /* enough large for a single shot */ -static void __devinit es1968_measure_clock(struct es1968 *chip) +static void es1968_measure_clock(struct es1968 *chip) { int i, apu; unsigned int pa, offset, t; @@ -1737,11 +1717,13 @@ static void __devinit es1968_measure_clock(struct es1968 *chip) /* search 2 APUs (although one apu is enough) */ if ((apu = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY)) < 0) { - snd_printk(KERN_ERR "Hmm, cannot find empty APU pair!?\n"); + dev_err(chip->card->dev, "Hmm, cannot find empty APU pair!?\n"); return; } if ((memory = snd_es1968_new_memory(chip, CLOCK_MEASURE_BUFSIZE)) == NULL) { - snd_printk(KERN_ERR "cannot allocate dma buffer - using default clock %d\n", chip->clock); + dev_warn(chip->card->dev, + "cannot allocate dma buffer - using default clock %d\n", + chip->clock); snd_es1968_free_apu_pair(chip, apu); return; } @@ -1802,7 +1784,7 @@ static void __devinit es1968_measure_clock(struct es1968 *chip) else t += stop_time.tv_usec - start_time.tv_usec; if (t == 0) { - snd_printk(KERN_ERR "?? calculation error..\n"); + dev_err(chip->card->dev, "?? calculation error..\n"); } else { offset *= 1000; offset = (offset / t) * 1000 + ((offset % t) * 1000) / t; @@ -1810,7 +1792,7 @@ static void __devinit es1968_measure_clock(struct es1968 *chip) if (offset >= 40000 && offset <= 50000) chip->clock = (chip->clock * offset) / 48000; } - printk(KERN_INFO "es1968: clocking to %d\n", chip->clock); + dev_info(chip->card->dev, "clocking to %d\n", chip->clock); } snd_es1968_free_memory(chip, memory); snd_es1968_free_apu_pair(chip, apu); @@ -1827,7 +1809,7 @@ static void snd_es1968_pcm_free(struct snd_pcm *pcm) esm->pcm = NULL; } -static int __devinit +static int snd_es1968_pcm(struct es1968 *chip, int device) { struct snd_pcm *pcm; @@ -1862,6 +1844,22 @@ snd_es1968_pcm(struct es1968 *chip, int device) return 0; } +/* + * suppress jitter on some maestros when playing stereo + */ +static void snd_es1968_suppress_jitter(struct es1968 *chip, struct esschan *es) +{ + unsigned int cp1; + unsigned int cp2; + unsigned int diff; + + cp1 = __apu_get_register(chip, 0, 5); + cp2 = __apu_get_register(chip, 1, 5); + diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1); + + if (diff > 1) + __maestro_write(chip, IDR0_DATA_PORT, cp1); +} /* * update pointer @@ -1891,18 +1889,19 @@ static void snd_es1968_update_pcm(struct es1968 *chip, struct esschan *es) } } -/* - */ -static void es1968_update_hw_volume(unsigned long private_data) +/* The hardware volume works by incrementing / decrementing 2 counters + (without wrap around) in response to volume button presses and then + generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7 + of a byte wide register. The meaning of bits 0 and 4 is unknown. */ +static void es1968_update_hw_volume(struct work_struct *work) { - struct es1968 *chip = (struct es1968 *) private_data; + struct es1968 *chip = container_of(work, struct es1968, hwvol_work); int x, val; - unsigned long flags; /* Figure out which volume control button was pushed, based on differences from the default register values. */ - x = inb(chip->io_port + 0x1c); + x = inb(chip->io_port + 0x1c) & 0xee; /* Reset the volume control registers. */ outb(0x88, chip->io_port + 0x1c); outb(0x88, chip->io_port + 0x1d); @@ -1912,48 +1911,69 @@ static void es1968_update_hw_volume(unsigned long private_data) if (chip->in_suspend) return; +#ifndef CONFIG_SND_ES1968_INPUT if (! chip->master_switch || ! chip->master_volume) return; - /* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */ - spin_lock_irqsave(&chip->ac97_lock, flags); - val = chip->ac97->regs[AC97_MASTER]; - if (x & 1) { + val = snd_ac97_read(chip->ac97, AC97_MASTER); + switch (x) { + case 0x88: /* mute */ val ^= 0x8000; - chip->ac97->regs[AC97_MASTER] = val; - outw(val, chip->io_port + ESM_AC97_DATA); - outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX); - snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, - &chip->master_switch->id); - } else { - val &= 0x7fff; - if (((x>>1) & 7) > 4) { - /* volume up */ - if ((val & 0xff) > 0) - val--; - if ((val & 0xff00) > 0) - val -= 0x0100; - } else { - /* volume down */ - if ((val & 0xff) < 0x1f) - val++; - if ((val & 0xff00) < 0x1f00) - val += 0x0100; - } - chip->ac97->regs[AC97_MASTER] = val; - outw(val, chip->io_port + ESM_AC97_DATA); - outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX); + break; + case 0xaa: + /* volume up */ + if ((val & 0x7f) > 0) + val--; + if ((val & 0x7f00) > 0) + val -= 0x0100; + break; + case 0x66: + /* volume down */ + if ((val & 0x7f) < 0x1f) + val++; + if ((val & 0x7f00) < 0x1f00) + val += 0x0100; + break; + } + if (snd_ac97_update(chip->ac97, AC97_MASTER, val)) snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id); +#else + if (!chip->input_dev) + return; + + val = 0; + switch (x) { + case 0x88: + /* The counters have not changed, yet we've received a HV + interrupt. According to tests run by various people this + happens when pressing the mute button. */ + val = KEY_MUTE; + break; + case 0xaa: + /* counters increased by 1 -> volume up */ + val = KEY_VOLUMEUP; + break; + case 0x66: + /* counters decreased by 1 -> volume down */ + val = KEY_VOLUMEDOWN; + break; } - spin_unlock_irqrestore(&chip->ac97_lock, flags); + + if (val) { + input_report_key(chip->input_dev, val, 1); + input_sync(chip->input_dev); + input_report_key(chip->input_dev, val, 0); + input_sync(chip->input_dev); + } +#endif } /* * interrupt handler */ -static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id) { struct es1968 *chip = dev_id; u32 event; @@ -1964,22 +1984,24 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *r outw(inw(chip->io_port + 4) & 1, chip->io_port + 4); if (event & ESM_HWVOL_IRQ) - tasklet_hi_schedule(&chip->hwvol_tq); /* we'll do this later */ + schedule_work(&chip->hwvol_work); /* else ack 'em all, i imagine */ outb(0xFF, chip->io_port + 0x1A); if ((event & ESM_MPU401_IRQ) && chip->rmidi) { - snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); + snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); } if (event & ESM_SOUND_IRQ) { - struct list_head *p; + struct esschan *es; spin_lock(&chip->substream_lock); - list_for_each(p, &chip->substream_list) { - struct esschan *es = list_entry(p, struct esschan, list); - if (es->running) + list_for_each_entry(es, &chip->substream_list, list) { + if (es->running) { snd_es1968_update_pcm(chip, es); + if (es->fmt & ESS_FMT_STEREO) + snd_es1968_suppress_jitter(chip, es); + } } spin_unlock(&chip->substream_lock); if (chip->in_measurement) { @@ -1997,12 +2019,14 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *r * Mixer stuff */ -static int __devinit +static int snd_es1968_mixer(struct es1968 *chip) { struct snd_ac97_bus *pbus; struct snd_ac97_template ac97; - struct snd_ctl_elem_id id; +#ifndef CONFIG_SND_ES1968_INPUT + struct snd_ctl_elem_id elem_id; +#endif int err; static struct snd_ac97_bus_ops ops = { .write = snd_es1968_ac97_write, @@ -2018,15 +2042,17 @@ snd_es1968_mixer(struct es1968 *chip) if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0) return err; +#ifndef CONFIG_SND_ES1968_INPUT /* attach master switch / volumes for h/w volume control */ - memset(&id, 0, sizeof(id)); - id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(id.name, "Master Playback Switch"); - chip->master_switch = snd_ctl_find_id(chip->card, &id); - memset(&id, 0, sizeof(id)); - id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(id.name, "Master Playback Volume"); - chip->master_volume = snd_ctl_find_id(chip->card, &id); + memset(&elem_id, 0, sizeof(elem_id)); + elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + strcpy(elem_id.name, "Master Playback Switch"); + chip->master_switch = snd_ctl_find_id(chip->card, &elem_id); + memset(&elem_id, 0, sizeof(elem_id)); + elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + strcpy(elem_id.name, "Master Playback Volume"); + chip->master_volume = snd_ctl_find_id(chip->card, &elem_id); +#endif return 0; } @@ -2086,7 +2112,7 @@ static void snd_es1968_ac97_reset(struct es1968 *chip) outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c); #if 0 /* the loop here needs to be much better if we want it.. */ - snd_printk(KERN_INFO "trying software reset\n"); + dev_info(chip->card->dev, "trying software reset\n"); /* try and do a software reset */ outb(0x80 | 0x7c, ioaddr + 0x30); for (w = 0;; w++) { @@ -2151,21 +2177,6 @@ static void snd_es1968_reset(struct es1968 *chip) } /* - * power management - */ -static void snd_es1968_set_acpi(struct es1968 *chip, int state) -{ - u16 active_mask = acpi_state_mask[state]; - - pci_set_power_state(chip->pci, state); - /* make sure the units we care about are on - XXX we might want to do this before state flipping? */ - pci_write_config_word(chip->pci, 0x54, ~ active_mask); - pci_write_config_word(chip->pci, 0x56, ~ active_mask); -} - - -/* * initialize maestro chip */ static void snd_es1968_chip_init(struct es1968 *chip) @@ -2187,9 +2198,6 @@ static void snd_es1968_chip_init(struct es1968 *chip) * IRQs. */ - /* do config work at full power */ - snd_es1968_set_acpi(chip, ACPI_D0); - /* Config Reg A */ pci_read_config_word(pci, ESM_CONFIG_A, &w); @@ -2286,7 +2294,7 @@ static void snd_es1968_chip_init(struct es1968 *chip) outb(0x88, iobase+0x1f); /* it appears some maestros (dell 7500) only work if these are set, - regardless of wether we use the assp or not. */ + regardless of whether we use the assp or not. */ outb(0, iobase + ASSP_CONTROL_B); outb(3, iobase + ASSP_CONTROL_A); /* M: Reserved bits... */ @@ -2368,45 +2376,56 @@ static void snd_es1968_start_irq(struct es1968 *chip) w = ESM_HIRQ_DSIE | ESM_HIRQ_HW_VOLUME; if (chip->rmidi) w |= ESM_HIRQ_MPU401; + outb(w, chip->io_port + 0x1A); outw(w, chip->io_port + ESM_PORT_HOST_IRQ); } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP /* * PM support */ -static int es1968_suspend(struct pci_dev *pci, pm_message_t state) +static int es1968_suspend(struct device *dev) { - struct snd_card *card = pci_get_drvdata(pci); + struct pci_dev *pci = to_pci_dev(dev); + struct snd_card *card = dev_get_drvdata(dev); struct es1968 *chip = card->private_data; if (! chip->do_pm) return 0; chip->in_suspend = 1; + cancel_work_sync(&chip->hwvol_work); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); snd_es1968_bob_stop(chip); - snd_es1968_set_acpi(chip, ACPI_D3); + pci_disable_device(pci); pci_save_state(pci); + pci_set_power_state(pci, PCI_D3hot); return 0; } -static int es1968_resume(struct pci_dev *pci) +static int es1968_resume(struct device *dev) { - struct snd_card *card = pci_get_drvdata(pci); + struct pci_dev *pci = to_pci_dev(dev); + struct snd_card *card = dev_get_drvdata(dev); struct es1968 *chip = card->private_data; - struct list_head *p; + struct esschan *es; if (! chip->do_pm) return 0; /* restore all our config */ + pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - pci_enable_device(pci); + if (pci_enable_device(pci) < 0) { + dev_err(dev, "pci_enable_device failed, disabling device\n"); + snd_card_disconnect(card); + return -EIO; + } pci_set_master(pci); + snd_es1968_chip_init(chip); /* need to restore the base pointers.. */ @@ -2420,8 +2439,7 @@ static int es1968_resume(struct pci_dev *pci) /* restore ac97 state */ snd_ac97_resume(chip->ac97); - list_for_each(p, &chip->substream_list) { - struct esschan *es = list_entry(p, struct esschan, list); + list_for_each_entry(es, &chip->substream_list, list) { switch (es->mode) { case ESM_MODE_PLAY: snd_es1968_playback_setup(chip, es, es->substream->runtime); @@ -2440,11 +2458,16 @@ static int es1968_resume(struct pci_dev *pci) chip->in_suspend = 0; return 0; } -#endif /* CONFIG_PM */ + +static SIMPLE_DEV_PM_OPS(es1968_pm, es1968_suspend, es1968_resume); +#define ES1968_PM_OPS &es1968_pm +#else +#define ES1968_PM_OPS NULL +#endif /* CONFIG_PM_SLEEP */ #ifdef SUPPORT_JOYSTICK #define JOYSTICK_ADDR 0x200 -static int __devinit snd_es1968_create_gameport(struct es1968 *chip, int dev) +static int snd_es1968_create_gameport(struct es1968 *chip, int dev) { struct gameport *gp; struct resource *r; @@ -2459,7 +2482,8 @@ static int __devinit snd_es1968_create_gameport(struct es1968 *chip, int dev) chip->gameport = gp = gameport_allocate_port(); if (!gp) { - printk(KERN_ERR "es1968: cannot allocate memory for gameport\n"); + dev_err(chip->card->dev, + "cannot allocate memory for gameport\n"); release_and_free_resource(r); return -ENOMEM; } @@ -2494,20 +2518,142 @@ static inline int snd_es1968_create_gameport(struct es1968 *chip, int dev) { ret static inline void snd_es1968_free_gameport(struct es1968 *chip) { } #endif +#ifdef CONFIG_SND_ES1968_INPUT +static int snd_es1968_input_register(struct es1968 *chip) +{ + struct input_dev *input_dev; + int err; + + input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; + + snprintf(chip->phys, sizeof(chip->phys), "pci-%s/input0", + pci_name(chip->pci)); + + input_dev->name = chip->card->driver; + input_dev->phys = chip->phys; + input_dev->id.bustype = BUS_PCI; + input_dev->id.vendor = chip->pci->vendor; + input_dev->id.product = chip->pci->device; + input_dev->dev.parent = &chip->pci->dev; + + __set_bit(EV_KEY, input_dev->evbit); + __set_bit(KEY_MUTE, input_dev->keybit); + __set_bit(KEY_VOLUMEDOWN, input_dev->keybit); + __set_bit(KEY_VOLUMEUP, input_dev->keybit); + + err = input_register_device(input_dev); + if (err) { + input_free_device(input_dev); + return err; + } + + chip->input_dev = input_dev; + return 0; +} +#endif /* CONFIG_SND_ES1968_INPUT */ + +#ifdef CONFIG_SND_ES1968_RADIO +#define GPIO_DATA 0x60 +#define IO_MASK 4 /* mask register offset from GPIO_DATA + bits 1=unmask write to given bit */ +#define IO_DIR 8 /* direction register offset from GPIO_DATA + bits 0/1=read/write direction */ + +/* GPIO to TEA575x maps */ +struct snd_es1968_tea575x_gpio { + u8 data, clk, wren, most; + char *name; +}; + +static struct snd_es1968_tea575x_gpio snd_es1968_tea575x_gpios[] = { + { .data = 6, .clk = 7, .wren = 8, .most = 9, .name = "SF64-PCE2" }, + { .data = 7, .clk = 8, .wren = 6, .most = 10, .name = "M56VAP" }, +}; + +#define get_tea575x_gpio(chip) \ + (&snd_es1968_tea575x_gpios[(chip)->tea575x_tuner]) + + +static void snd_es1968_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) +{ + struct es1968 *chip = tea->private_data; + struct snd_es1968_tea575x_gpio gpio = *get_tea575x_gpio(chip); + u16 val = 0; + + val |= (pins & TEA575X_DATA) ? (1 << gpio.data) : 0; + val |= (pins & TEA575X_CLK) ? (1 << gpio.clk) : 0; + val |= (pins & TEA575X_WREN) ? (1 << gpio.wren) : 0; + + outw(val, chip->io_port + GPIO_DATA); +} + +static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea) +{ + struct es1968 *chip = tea->private_data; + struct snd_es1968_tea575x_gpio gpio = *get_tea575x_gpio(chip); + u16 val = inw(chip->io_port + GPIO_DATA); + u8 ret = 0; + + if (val & (1 << gpio.data)) + ret |= TEA575X_DATA; + if (val & (1 << gpio.most)) + ret |= TEA575X_MOST; + + return ret; +} + +static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output) +{ + struct es1968 *chip = tea->private_data; + unsigned long io = chip->io_port + GPIO_DATA; + u16 odir = inw(io + IO_DIR); + struct snd_es1968_tea575x_gpio gpio = *get_tea575x_gpio(chip); + + if (output) { + outw(~((1 << gpio.data) | (1 << gpio.clk) | (1 << gpio.wren)), + io + IO_MASK); + outw(odir | (1 << gpio.data) | (1 << gpio.clk) | (1 << gpio.wren), + io + IO_DIR); + } else { + outw(~((1 << gpio.clk) | (1 << gpio.wren) | (1 << gpio.data) | (1 << gpio.most)), + io + IO_MASK); + outw((odir & ~((1 << gpio.data) | (1 << gpio.most))) + | (1 << gpio.clk) | (1 << gpio.wren), io + IO_DIR); + } +} + +static struct snd_tea575x_ops snd_es1968_tea_ops = { + .set_pins = snd_es1968_tea575x_set_pins, + .get_pins = snd_es1968_tea575x_get_pins, + .set_direction = snd_es1968_tea575x_set_direction, +}; +#endif + static int snd_es1968_free(struct es1968 *chip) { + cancel_work_sync(&chip->hwvol_work); +#ifdef CONFIG_SND_ES1968_INPUT + if (chip->input_dev) + input_unregister_device(chip->input_dev); +#endif + if (chip->io_port) { - synchronize_irq(chip->irq); + if (chip->irq >= 0) + synchronize_irq(chip->irq); outw(1, chip->io_port + 0x04); /* clear WP interrupts */ outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */ } +#ifdef CONFIG_SND_ES1968_RADIO + snd_tea575x_exit(&chip->tea); + v4l2_device_unregister(&chip->v4l2_dev); +#endif + if (chip->irq >= 0) - free_irq(chip->irq, (void *)chip); + free_irq(chip->irq, chip); snd_es1968_free_gameport(chip); - snd_es1968_set_acpi(chip, ACPI_D3); - chip->master_switch = NULL; - chip->master_volume = NULL; pci_release_regions(chip->pci); pci_disable_device(chip->pci); kfree(chip); @@ -2525,27 +2671,30 @@ struct ess_device_list { unsigned short vendor; /* subsystem vendor id */ }; -static struct ess_device_list pm_whitelist[] __devinitdata = { +static struct ess_device_list pm_whitelist[] = { { TYPE_MAESTRO2E, 0x0e11 }, /* Compaq Armada */ { TYPE_MAESTRO2E, 0x1028 }, { TYPE_MAESTRO2E, 0x103c }, { TYPE_MAESTRO2E, 0x1179 }, { TYPE_MAESTRO2E, 0x14c0 }, /* HP omnibook 4150 */ { TYPE_MAESTRO2E, 0x1558 }, + { TYPE_MAESTRO2E, 0x125d }, /* a PCI card, e.g. Terratec DMX */ + { TYPE_MAESTRO2, 0x125d }, /* a PCI card, e.g. SF64-PCE2 */ }; -static struct ess_device_list mpu_blacklist[] __devinitdata = { +static struct ess_device_list mpu_blacklist[] = { { TYPE_MAESTRO2, 0x125d }, }; -static int __devinit snd_es1968_create(struct snd_card *card, - struct pci_dev *pci, - int total_bufsize, - int play_streams, - int capt_streams, - int chip_type, - int do_pm, - struct es1968 **chip_ret) +static int snd_es1968_create(struct snd_card *card, + struct pci_dev *pci, + int total_bufsize, + int play_streams, + int capt_streams, + int chip_type, + int do_pm, + int radio_nr, + struct es1968 **chip_ret) { static struct snd_device_ops ops = { .dev_free = snd_es1968_dev_free, @@ -2559,9 +2708,10 @@ static int __devinit snd_es1968_create(struct snd_card *card, if ((err = pci_enable_device(pci)) < 0) return err; /* check, if we can restrict PCI DMA transfers to 28 bits */ - if (pci_set_dma_mask(pci, 0x0fffffff) < 0 || - pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { - snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); + if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { + dev_err(card->dev, + "architecture does not support 28bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; } @@ -2578,9 +2728,8 @@ static int __devinit snd_es1968_create(struct snd_card *card, spin_lock_init(&chip->substream_lock); INIT_LIST_HEAD(&chip->buf_list); INIT_LIST_HEAD(&chip->substream_list); - spin_lock_init(&chip->ac97_lock); - init_MUTEX(&chip->memory_mutex); - tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip); + mutex_init(&chip->memory_mutex); + INIT_WORK(&chip->hwvol_work, es1968_update_hw_volume); chip->card = card; chip->pci = pci; chip->irq = -1; @@ -2594,9 +2743,9 @@ static int __devinit snd_es1968_create(struct snd_card *card, return err; } chip->io_port = pci_resource_start(pci, 0); - if (request_irq(pci->irq, snd_es1968_interrupt, SA_INTERRUPT|SA_SHIRQ, - "ESS Maestro", (void*)chip)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); + if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED, + KBUILD_MODNAME, chip)) { + dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); snd_es1968_free(chip); return -EBUSY; } @@ -2626,7 +2775,7 @@ static int __devinit snd_es1968_create(struct snd_card *card, } if (do_pm > 1) { /* not matched; disabling pm */ - printk(KERN_INFO "es1968: not attempting power management.\n"); + dev_info(card->dev, "not attempting power management.\n"); do_pm = 0; } } @@ -2639,7 +2788,32 @@ static int __devinit snd_es1968_create(struct snd_card *card, return err; } - snd_card_set_dev(card, &pci->dev); +#ifdef CONFIG_SND_ES1968_RADIO + /* don't play with GPIOs on laptops */ + if (chip->pci->subsystem_vendor != 0x125d) + goto no_radio; + err = v4l2_device_register(&pci->dev, &chip->v4l2_dev); + if (err < 0) { + snd_es1968_free(chip); + return err; + } + chip->tea.v4l2_dev = &chip->v4l2_dev; + chip->tea.private_data = chip; + chip->tea.radio_nr = radio_nr; + chip->tea.ops = &snd_es1968_tea_ops; + sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); + for (i = 0; i < ARRAY_SIZE(snd_es1968_tea575x_gpios); i++) { + chip->tea575x_tuner = i; + if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) { + dev_info(card->dev, "detected TEA575x radio type %s\n", + get_tea575x_gpio(chip)->name); + strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name, + sizeof(chip->tea.card)); + break; + } + } +no_radio: +#endif *chip_ret = chip; @@ -2649,8 +2823,8 @@ static int __devinit snd_es1968_create(struct snd_card *card, /* */ -static int __devinit snd_es1968_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) +static int snd_es1968_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) { static int dev; struct snd_card *card; @@ -2665,9 +2839,10 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci, return -ENOENT; } - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (!card) - return -ENOMEM; + err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, + 0, &card); + if (err < 0) + return err; if (total_bufsize[dev] < 128) total_bufsize[dev] = 128; @@ -2679,6 +2854,7 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci, pcm_substreams_c[dev], pci_id->driver_data, use_pm[dev], + radio_nr[dev], &chip)) < 0) { snd_card_free(card); return err; @@ -2724,14 +2900,23 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci, } if (enable_mpu[dev]) { if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, - chip->io_port + ESM_MPU401_PORT, 1, - chip->irq, 0, &chip->rmidi)) < 0) { - printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n"); + chip->io_port + ESM_MPU401_PORT, + MPU401_INFO_INTEGRATED | + MPU401_INFO_IRQ_HOOK, + -1, &chip->rmidi)) < 0) { + dev_warn(card->dev, "skipping MPU-401 MIDI support..\n"); } } snd_es1968_create_gameport(chip, dev); +#ifdef CONFIG_SND_ES1968_INPUT + err = snd_es1968_input_register(chip); + if (err) + dev_warn(card->dev, + "Input device registration failed with error %i", err); +#endif + snd_es1968_start_irq(chip); chip->clock = clock[dev]; @@ -2750,32 +2935,19 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci, return 0; } -static void __devexit snd_es1968_remove(struct pci_dev *pci) +static void snd_es1968_remove(struct pci_dev *pci) { snd_card_free(pci_get_drvdata(pci)); - pci_set_drvdata(pci, NULL); } -static struct pci_driver driver = { - .name = "ES1968 (ESS Maestro)", +static struct pci_driver es1968_driver = { + .name = KBUILD_MODNAME, .id_table = snd_es1968_ids, .probe = snd_es1968_probe, - .remove = __devexit_p(snd_es1968_remove), -#ifdef CONFIG_PM - .suspend = es1968_suspend, - .resume = es1968_resume, -#endif + .remove = snd_es1968_remove, + .driver = { + .pm = ES1968_PM_OPS, + }, }; -static int __init alsa_card_es1968_init(void) -{ - return pci_register_driver(&driver); -} - -static void __exit alsa_card_es1968_exit(void) -{ - pci_unregister_driver(&driver); -} - -module_init(alsa_card_es1968_init) -module_exit(alsa_card_es1968_exit) +module_pci_driver(es1968_driver); |
