Loading sound/pci/oxygen/oxygen.h +6 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ struct oxygen_model { void (*update_dac_volume)(struct oxygen *chip); void (*update_dac_mute)(struct oxygen *chip); void (*gpio_changed)(struct oxygen *chip); void (*uart_input)(struct oxygen *chip); void (*ac97_switch)(struct oxygen *chip, unsigned int reg, unsigned int mute); const unsigned int *dac_tlv; Loading Loading @@ -125,6 +126,8 @@ struct oxygen { __le32 _32[OXYGEN_IO_SIZE / 4]; } saved_registers; u16 saved_ac97_registers[2][0x40]; unsigned int uart_input_count; u8 uart_input[32]; struct oxygen_model model; }; Loading Loading @@ -174,6 +177,9 @@ void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec, void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data); void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data); void oxygen_reset_uart(struct oxygen *chip); void oxygen_write_uart(struct oxygen *chip, u8 data); static inline void oxygen_set_bits8(struct oxygen *chip, unsigned int reg, u8 value) { Loading sound/pci/oxygen/oxygen_io.c +21 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/delay.h> #include <linux/sched.h> #include <sound/core.h> #include <sound/mpu401.h> #include <asm/io.h> #include "oxygen.h" Loading Loading @@ -232,3 +233,23 @@ void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data) device | OXYGEN_2WIRE_DIR_WRITE); } EXPORT_SYMBOL(oxygen_write_i2c); static void _write_uart(struct oxygen *chip, unsigned int port, u8 data) { if (oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_TX_FULL) msleep(1); oxygen_write8(chip, OXYGEN_MPU401 + port, data); } void oxygen_reset_uart(struct oxygen *chip) { _write_uart(chip, 1, MPU401_RESET); _write_uart(chip, 1, MPU401_ENTER_UART); } EXPORT_SYMBOL(oxygen_reset_uart); void oxygen_write_uart(struct oxygen *chip, u8 data) { _write_uart(chip, 0, data); } EXPORT_SYMBOL(oxygen_write_uart); sound/pci/oxygen/oxygen_lib.c +30 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,30 @@ MODULE_DESCRIPTION("C-Media CMI8788 helper library"); MODULE_LICENSE("GPL v2"); static inline int oxygen_uart_input_ready(struct oxygen *chip) { return !(oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_RX_EMPTY); } static void oxygen_read_uart(struct oxygen *chip) { if (unlikely(!oxygen_uart_input_ready(chip))) { /* no data, but read it anyway to clear the interrupt */ oxygen_read8(chip, OXYGEN_MPU401); return; } do { u8 data = oxygen_read8(chip, OXYGEN_MPU401); if (data == MPU401_ACK) continue; if (chip->uart_input_count >= ARRAY_SIZE(chip->uart_input)) chip->uart_input_count = 0; chip->uart_input[chip->uart_input_count++] = data; } while (oxygen_uart_input_ready(chip)); if (chip->model.uart_input) chip->model.uart_input(chip); } static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) { struct oxygen *chip = dev_id; Loading Loading @@ -87,8 +111,12 @@ static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) if (status & OXYGEN_INT_GPIO) schedule_work(&chip->gpio_work); if ((status & OXYGEN_INT_MIDI) && chip->midi) if (status & OXYGEN_INT_MIDI) { if (chip->midi) snd_mpu401_uart_interrupt(0, chip->midi->private_data); else oxygen_read_uart(chip); } if (status & OXYGEN_INT_AC97) wake_up(&chip->ac97_waitqueue); Loading Loading
sound/pci/oxygen/oxygen.h +6 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ struct oxygen_model { void (*update_dac_volume)(struct oxygen *chip); void (*update_dac_mute)(struct oxygen *chip); void (*gpio_changed)(struct oxygen *chip); void (*uart_input)(struct oxygen *chip); void (*ac97_switch)(struct oxygen *chip, unsigned int reg, unsigned int mute); const unsigned int *dac_tlv; Loading Loading @@ -125,6 +126,8 @@ struct oxygen { __le32 _32[OXYGEN_IO_SIZE / 4]; } saved_registers; u16 saved_ac97_registers[2][0x40]; unsigned int uart_input_count; u8 uart_input[32]; struct oxygen_model model; }; Loading Loading @@ -174,6 +177,9 @@ void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec, void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data); void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data); void oxygen_reset_uart(struct oxygen *chip); void oxygen_write_uart(struct oxygen *chip, u8 data); static inline void oxygen_set_bits8(struct oxygen *chip, unsigned int reg, u8 value) { Loading
sound/pci/oxygen/oxygen_io.c +21 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/delay.h> #include <linux/sched.h> #include <sound/core.h> #include <sound/mpu401.h> #include <asm/io.h> #include "oxygen.h" Loading Loading @@ -232,3 +233,23 @@ void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data) device | OXYGEN_2WIRE_DIR_WRITE); } EXPORT_SYMBOL(oxygen_write_i2c); static void _write_uart(struct oxygen *chip, unsigned int port, u8 data) { if (oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_TX_FULL) msleep(1); oxygen_write8(chip, OXYGEN_MPU401 + port, data); } void oxygen_reset_uart(struct oxygen *chip) { _write_uart(chip, 1, MPU401_RESET); _write_uart(chip, 1, MPU401_ENTER_UART); } EXPORT_SYMBOL(oxygen_reset_uart); void oxygen_write_uart(struct oxygen *chip, u8 data) { _write_uart(chip, 0, data); } EXPORT_SYMBOL(oxygen_write_uart);
sound/pci/oxygen/oxygen_lib.c +30 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,30 @@ MODULE_DESCRIPTION("C-Media CMI8788 helper library"); MODULE_LICENSE("GPL v2"); static inline int oxygen_uart_input_ready(struct oxygen *chip) { return !(oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_RX_EMPTY); } static void oxygen_read_uart(struct oxygen *chip) { if (unlikely(!oxygen_uart_input_ready(chip))) { /* no data, but read it anyway to clear the interrupt */ oxygen_read8(chip, OXYGEN_MPU401); return; } do { u8 data = oxygen_read8(chip, OXYGEN_MPU401); if (data == MPU401_ACK) continue; if (chip->uart_input_count >= ARRAY_SIZE(chip->uart_input)) chip->uart_input_count = 0; chip->uart_input[chip->uart_input_count++] = data; } while (oxygen_uart_input_ready(chip)); if (chip->model.uart_input) chip->model.uart_input(chip); } static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) { struct oxygen *chip = dev_id; Loading Loading @@ -87,8 +111,12 @@ static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) if (status & OXYGEN_INT_GPIO) schedule_work(&chip->gpio_work); if ((status & OXYGEN_INT_MIDI) && chip->midi) if (status & OXYGEN_INT_MIDI) { if (chip->midi) snd_mpu401_uart_interrupt(0, chip->midi->private_data); else oxygen_read_uart(chip); } if (status & OXYGEN_INT_AC97) wake_up(&chip->ac97_waitqueue); Loading