--- zzzz-none-000/linux-3.10.107/sound/pci/oxygen/oxygen_io.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/sound/pci/oxygen/oxygen_io.c 2021-02-04 17:41:59.000000000 +0000 @@ -20,9 +20,9 @@ #include #include #include +#include #include #include -#include #include "oxygen.h" u8 oxygen_read8(struct oxygen *chip, unsigned int reg) @@ -147,7 +147,7 @@ return; } } - snd_printk(KERN_ERR "AC'97 write timeout\n"); + dev_err(chip->card->dev, "AC'97 write timeout\n"); } EXPORT_SYMBOL(oxygen_write_ac97); @@ -179,7 +179,7 @@ reg ^= 0xffff; } } - snd_printk(KERN_ERR "AC'97 read timeout on codec %u\n", codec); + dev_err(chip->card->dev, "AC'97 read timeout on codec %u\n", codec); return 0; } EXPORT_SYMBOL(oxygen_read_ac97); @@ -194,23 +194,36 @@ } EXPORT_SYMBOL(oxygen_write_ac97_masked); -void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data) +static int oxygen_wait_spi(struct oxygen *chip) { unsigned int count; - /* should not need more than 30.72 us (24 * 1.28 us) */ - count = 10; - while ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & OXYGEN_SPI_BUSY) - && count > 0) { + /* + * Higher timeout to be sure: 200 us; + * actual transaction should not need more than 40 us. + */ + for (count = 50; count > 0; count--) { udelay(4); - --count; + if ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & + OXYGEN_SPI_BUSY) == 0) + return 0; } + dev_err(chip->card->dev, "oxygen: SPI wait timeout\n"); + return -EIO; +} +int oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data) +{ + /* + * We need to wait AFTER initiating the SPI transaction, + * otherwise read operations will not work. + */ oxygen_write8(chip, OXYGEN_SPI_DATA1, data); oxygen_write8(chip, OXYGEN_SPI_DATA2, data >> 8); if (control & OXYGEN_SPI_DATA_LENGTH_3) oxygen_write8(chip, OXYGEN_SPI_DATA3, data >> 16); oxygen_write8(chip, OXYGEN_SPI_CONTROL, control); + return oxygen_wait_spi(chip); } EXPORT_SYMBOL(oxygen_write_spi); @@ -275,5 +288,5 @@ & OXYGEN_EEPROM_BUSY)) return; } - snd_printk(KERN_ERR "EEPROM write timeout\n"); + dev_err(chip->card->dev, "EEPROM write timeout\n"); }