diff options
Diffstat (limited to 'sound/pci/oxygen/oxygen_lib.c')
-rw-r--r-- | sound/pci/oxygen/oxygen_lib.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index b1997216b4af..84f481d41efa 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c | |||
@@ -35,6 +35,30 @@ MODULE_DESCRIPTION("C-Media CMI8788 helper library"); | |||
35 | MODULE_LICENSE("GPL v2"); | 35 | MODULE_LICENSE("GPL v2"); |
36 | 36 | ||
37 | 37 | ||
38 | static inline int oxygen_uart_input_ready(struct oxygen *chip) | ||
39 | { | ||
40 | return !(oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_RX_EMPTY); | ||
41 | } | ||
42 | |||
43 | static void oxygen_read_uart(struct oxygen *chip) | ||
44 | { | ||
45 | if (unlikely(!oxygen_uart_input_ready(chip))) { | ||
46 | /* no data, but read it anyway to clear the interrupt */ | ||
47 | oxygen_read8(chip, OXYGEN_MPU401); | ||
48 | return; | ||
49 | } | ||
50 | do { | ||
51 | u8 data = oxygen_read8(chip, OXYGEN_MPU401); | ||
52 | if (data == MPU401_ACK) | ||
53 | continue; | ||
54 | if (chip->uart_input_count >= ARRAY_SIZE(chip->uart_input)) | ||
55 | chip->uart_input_count = 0; | ||
56 | chip->uart_input[chip->uart_input_count++] = data; | ||
57 | } while (oxygen_uart_input_ready(chip)); | ||
58 | if (chip->model.uart_input) | ||
59 | chip->model.uart_input(chip); | ||
60 | } | ||
61 | |||
38 | static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) | 62 | static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) |
39 | { | 63 | { |
40 | struct oxygen *chip = dev_id; | 64 | struct oxygen *chip = dev_id; |
@@ -87,8 +111,12 @@ static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) | |||
87 | if (status & OXYGEN_INT_GPIO) | 111 | if (status & OXYGEN_INT_GPIO) |
88 | schedule_work(&chip->gpio_work); | 112 | schedule_work(&chip->gpio_work); |
89 | 113 | ||
90 | if ((status & OXYGEN_INT_MIDI) && chip->midi) | 114 | if (status & OXYGEN_INT_MIDI) { |
91 | snd_mpu401_uart_interrupt(0, chip->midi->private_data); | 115 | if (chip->midi) |
116 | snd_mpu401_uart_interrupt(0, chip->midi->private_data); | ||
117 | else | ||
118 | oxygen_read_uart(chip); | ||
119 | } | ||
92 | 120 | ||
93 | if (status & OXYGEN_INT_AC97) | 121 | if (status & OXYGEN_INT_AC97) |
94 | wake_up(&chip->ac97_waitqueue); | 122 | wake_up(&chip->ac97_waitqueue); |