aboutsummaryrefslogtreecommitdiff
path: root/sound/pci/es1968.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/es1968.c')
-rw-r--r--sound/pci/es1968.c152
1 files changed, 90 insertions, 62 deletions
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index a1f32b5ae0d..5bb1cf60330 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -113,7 +113,7 @@
#include <sound/initval.h>
#ifdef CONFIG_SND_ES1968_RADIO
-#include <sound/tea575x-tuner.h>
+#include <media/tea575x.h>
#endif
#define CARD_NAME "ESS Maestro1/2"
@@ -564,6 +564,7 @@ struct es1968 {
#ifdef CONFIG_SND_ES1968_RADIO
struct v4l2_device v4l2_dev;
struct snd_tea575x tea;
+ unsigned int tea575x_tuner;
#endif
};
@@ -631,7 +632,7 @@ 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 */
}
@@ -643,7 +644,7 @@ static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
if (!(inb(chip->io_port + ESM_AC97_INDEX) & 1))
return 0;
}
- snd_printd("es1968: ac97 timeout\n");
+ dev_dbg(chip->card->dev, "ac97 timeout\n");
return 1; /* timeout */
}
@@ -686,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 */
@@ -698,7 +699,7 @@ 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 */
@@ -1421,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);
@@ -1437,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);
@@ -1490,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);
@@ -1716,11 +1717,13 @@ static void 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;
}
@@ -1781,7 +1784,7 @@ static void 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;
@@ -1789,7 +1792,7 @@ static void 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);
@@ -2109,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++) {
@@ -2417,8 +2420,7 @@ static int es1968_resume(struct device *dev)
pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "es1968: pci_enable_device failed, "
- "disabling device\n");
+ dev_err(dev, "pci_enable_device failed, disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
@@ -2480,7 +2482,8 @@ static int 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;
}
@@ -2557,37 +2560,47 @@ static int snd_es1968_input_register(struct es1968 *chip)
bits 1=unmask write to given bit */
#define IO_DIR 8 /* direction register offset from GPIO_DATA
bits 0/1=read/write direction */
-/* mask bits for GPIO lines */
-#define STR_DATA 0x0040 /* GPIO6 */
-#define STR_CLK 0x0080 /* GPIO7 */
-#define STR_WREN 0x0100 /* GPIO8 */
-#define STR_MOST 0x0200 /* GPIO9 */
+
+/* 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;
- unsigned long io = chip->io_port + GPIO_DATA;
+ struct snd_es1968_tea575x_gpio gpio = *get_tea575x_gpio(chip);
u16 val = 0;
- val |= (pins & TEA575X_DATA) ? STR_DATA : 0;
- val |= (pins & TEA575X_CLK) ? STR_CLK : 0;
- val |= (pins & TEA575X_WREN) ? STR_WREN : 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, io);
+ outw(val, chip->io_port + GPIO_DATA);
}
static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea)
{
struct es1968 *chip = tea->private_data;
- unsigned long io = chip->io_port + GPIO_DATA;
- u16 val = inw(io);
- u8 ret;
+ struct snd_es1968_tea575x_gpio gpio = *get_tea575x_gpio(chip);
+ u16 val = inw(chip->io_port + GPIO_DATA);
+ u8 ret = 0;
- ret = 0;
- if (val & STR_DATA)
+ if (val & (1 << gpio.data))
ret |= TEA575X_DATA;
- if (val & STR_MOST)
+ if (val & (1 << gpio.most))
ret |= TEA575X_MOST;
+
return ret;
}
@@ -2596,13 +2609,18 @@ static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool outpu
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(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
- outw(odir | STR_DATA | STR_CLK | STR_WREN, io + IO_DIR);
+ 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(~(STR_CLK | STR_WREN | STR_DATA | STR_MOST), io + IO_MASK);
- outw((odir & ~(STR_DATA | STR_MOST)) | STR_CLK | STR_WREN, io + IO_DIR);
+ 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);
}
}
@@ -2692,7 +2710,8 @@ static int snd_es1968_create(struct snd_card *card,
/* check, if we can restrict PCI DMA transfers to 28 bits */
if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
- snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
+ dev_err(card->dev,
+ "architecture does not support 28bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -2726,7 +2745,7 @@ static int snd_es1968_create(struct snd_card *card,
chip->io_port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED,
KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+ dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
snd_es1968_free(chip);
return -EBUSY;
}
@@ -2756,7 +2775,7 @@ static int 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;
}
}
@@ -2769,9 +2788,10 @@ static int 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);
@@ -2781,10 +2801,18 @@ static int snd_es1968_create(struct snd_card *card,
chip->tea.private_data = chip;
chip->tea.radio_nr = radio_nr;
chip->tea.ops = &snd_es1968_tea_ops;
- strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card));
sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
- if (!snd_tea575x_init(&chip->tea, THIS_MODULE))
- printk(KERN_INFO "es1968: detected TEA575x radio\n");
+ 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;
@@ -2811,7 +2839,8 @@ static int snd_es1968_probe(struct pci_dev *pci,
return -ENOENT;
}
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+ err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+ 0, &card);
if (err < 0)
return err;
@@ -2875,7 +2904,7 @@ static int snd_es1968_probe(struct pci_dev *pci,
MPU401_INFO_INTEGRATED |
MPU401_INFO_IRQ_HOOK,
-1, &chip->rmidi)) < 0) {
- printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n");
+ dev_warn(card->dev, "skipping MPU-401 MIDI support..\n");
}
}
@@ -2884,8 +2913,8 @@ static int snd_es1968_probe(struct pci_dev *pci,
#ifdef CONFIG_SND_ES1968_INPUT
err = snd_es1968_input_register(chip);
if (err)
- snd_printk(KERN_WARNING "Input device registration "
- "failed with error %i", err);
+ dev_warn(card->dev,
+ "Input device registration failed with error %i", err);
#endif
snd_es1968_start_irq(chip);
@@ -2909,7 +2938,6 @@ static int snd_es1968_probe(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 es1968_driver = {