aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/es1968.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/es1968.c')
-rw-r--r--sound/pci/es1968.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 7c17f45d876d..ab0a6156a704 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -112,6 +112,10 @@
112#include <sound/ac97_codec.h> 112#include <sound/ac97_codec.h>
113#include <sound/initval.h> 113#include <sound/initval.h>
114 114
115#ifdef CONFIG_SND_ES1968_RADIO
116#include <sound/tea575x-tuner.h>
117#endif
118
115#define CARD_NAME "ESS Maestro1/2" 119#define CARD_NAME "ESS Maestro1/2"
116#define DRIVER_NAME "ES1968" 120#define DRIVER_NAME "ES1968"
117 121
@@ -553,6 +557,10 @@ struct es1968 {
553 spinlock_t ac97_lock; 557 spinlock_t ac97_lock;
554 struct tasklet_struct hwvol_tq; 558 struct tasklet_struct hwvol_tq;
555#endif 559#endif
560
561#ifdef CONFIG_SND_ES1968_RADIO
562 struct snd_tea575x tea;
563#endif
556}; 564};
557 565
558static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); 566static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
@@ -2571,6 +2579,63 @@ static int __devinit snd_es1968_input_register(struct es1968 *chip)
2571} 2579}
2572#endif /* CONFIG_SND_ES1968_INPUT */ 2580#endif /* CONFIG_SND_ES1968_INPUT */
2573 2581
2582#ifdef CONFIG_SND_ES1968_RADIO
2583#define GPIO_DATA 0x60
2584#define IO_MASK 4 /* mask register offset from GPIO_DATA
2585 bits 1=unmask write to given bit */
2586#define IO_DIR 8 /* direction register offset from GPIO_DATA
2587 bits 0/1=read/write direction */
2588/* mask bits for GPIO lines */
2589#define STR_DATA 0x0040 /* GPIO6 */
2590#define STR_CLK 0x0080 /* GPIO7 */
2591#define STR_WREN 0x0100 /* GPIO8 */
2592#define STR_MOST 0x0200 /* GPIO9 */
2593
2594static void snd_es1968_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
2595{
2596 struct es1968 *chip = tea->private_data;
2597 unsigned long io = chip->io_port + GPIO_DATA;
2598 u16 val = 0;
2599
2600 val |= (pins & TEA575X_DATA) ? STR_DATA : 0;
2601 val |= (pins & TEA575X_CLK) ? STR_CLK : 0;
2602 val |= (pins & TEA575X_WREN) ? STR_WREN : 0;
2603
2604 outw(val, io);
2605}
2606
2607static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea)
2608{
2609 struct es1968 *chip = tea->private_data;
2610 unsigned long io = chip->io_port + GPIO_DATA;
2611 u16 val = inw(io);
2612
2613 return (val & STR_DATA) ? TEA575X_DATA : 0 |
2614 (val & STR_MOST) ? TEA575X_MOST : 0;
2615}
2616
2617static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output)
2618{
2619 struct es1968 *chip = tea->private_data;
2620 unsigned long io = chip->io_port + GPIO_DATA;
2621 u16 odir = inw(io + IO_DIR);
2622
2623 if (output) {
2624 outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
2625 outw(odir | STR_DATA | STR_CLK | STR_WREN, io + IO_DIR);
2626 } else {
2627 outw(~(STR_CLK | STR_WREN | STR_DATA | STR_MOST), io + IO_MASK);
2628 outw((odir & ~(STR_DATA | STR_MOST)) | STR_CLK | STR_WREN, io + IO_DIR);
2629 }
2630}
2631
2632static struct snd_tea575x_ops snd_es1968_tea_ops = {
2633 .set_pins = snd_es1968_tea575x_set_pins,
2634 .get_pins = snd_es1968_tea575x_get_pins,
2635 .set_direction = snd_es1968_tea575x_set_direction,
2636};
2637#endif
2638
2574static int snd_es1968_free(struct es1968 *chip) 2639static int snd_es1968_free(struct es1968 *chip)
2575{ 2640{
2576#ifdef CONFIG_SND_ES1968_INPUT 2641#ifdef CONFIG_SND_ES1968_INPUT
@@ -2585,6 +2650,10 @@ static int snd_es1968_free(struct es1968 *chip)
2585 outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */ 2650 outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */
2586 } 2651 }
2587 2652
2653#ifdef CONFIG_SND_ES1968_RADIO
2654 snd_tea575x_exit(&chip->tea);
2655#endif
2656
2588 if (chip->irq >= 0) 2657 if (chip->irq >= 0)
2589 free_irq(chip->irq, chip); 2658 free_irq(chip->irq, chip);
2590 snd_es1968_free_gameport(chip); 2659 snd_es1968_free_gameport(chip);
@@ -2723,6 +2792,15 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2723 2792
2724 snd_card_set_dev(card, &pci->dev); 2793 snd_card_set_dev(card, &pci->dev);
2725 2794
2795#ifdef CONFIG_SND_ES1968_RADIO
2796 chip->tea.private_data = chip;
2797 chip->tea.ops = &snd_es1968_tea_ops;
2798 strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card));
2799 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
2800 if (!snd_tea575x_init(&chip->tea))
2801 printk(KERN_INFO "es1968: detected TEA575x radio\n");
2802#endif
2803
2726 *chip_ret = chip; 2804 *chip_ret = chip;
2727 2805
2728 return 0; 2806 return 0;