1 /* 2 * C-Media CMI8788 driver - helper functions 3 * 4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 5 * 6 * 7 * This driver is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License, version 2. 9 * 10 * This driver is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this driver; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20 #include <linux/delay.h> 21 #include <linux/sched.h> 22 #include <sound/core.h> 23 #include <sound/mpu401.h> 24 #include <asm/io.h> 25 #include "oxygen.h" 26 27 u8 oxygen_read8(struct oxygen *chip, unsigned int reg) 28 { 29 return inb(chip->addr + reg); 30 } 31 EXPORT_SYMBOL(oxygen_read8); 32 33 u16 oxygen_read16(struct oxygen *chip, unsigned int reg) 34 { 35 return inw(chip->addr + reg); 36 } 37 EXPORT_SYMBOL(oxygen_read16); 38 39 u32 oxygen_read32(struct oxygen *chip, unsigned int reg) 40 { 41 return inl(chip->addr + reg); 42 } 43 EXPORT_SYMBOL(oxygen_read32); 44 45 void oxygen_write8(struct oxygen *chip, unsigned int reg, u8 value) 46 { 47 outb(value, chip->addr + reg); 48 chip->saved_registers._8[reg] = value; 49 } 50 EXPORT_SYMBOL(oxygen_write8); 51 52 void oxygen_write16(struct oxygen *chip, unsigned int reg, u16 value) 53 { 54 outw(value, chip->addr + reg); 55 chip->saved_registers._16[reg / 2] = cpu_to_le16(value); 56 } 57 EXPORT_SYMBOL(oxygen_write16); 58 59 void oxygen_write32(struct oxygen *chip, unsigned int reg, u32 value) 60 { 61 outl(value, chip->addr + reg); 62 chip->saved_registers._32[reg / 4] = cpu_to_le32(value); 63 } 64 EXPORT_SYMBOL(oxygen_write32); 65 66 void oxygen_write8_masked(struct oxygen *chip, unsigned int reg, 67 u8 value, u8 mask) 68 { 69 u8 tmp = inb(chip->addr + reg); 70 tmp &= ~mask; 71 tmp |= value & mask; 72 outb(tmp, chip->addr + reg); 73 chip->saved_registers._8[reg] = tmp; 74 } 75 EXPORT_SYMBOL(oxygen_write8_masked); 76 77 void oxygen_write16_masked(struct oxygen *chip, unsigned int reg, 78 u16 value, u16 mask) 79 { 80 u16 tmp = inw(chip->addr + reg); 81 tmp &= ~mask; 82 tmp |= value & mask; 83 outw(tmp, chip->addr + reg); 84 chip->saved_registers._16[reg / 2] = cpu_to_le16(tmp); 85 } 86 EXPORT_SYMBOL(oxygen_write16_masked); 87 88 void oxygen_write32_masked(struct oxygen *chip, unsigned int reg, 89 u32 value, u32 mask) 90 { 91 u32 tmp = inl(chip->addr + reg); 92 tmp &= ~mask; 93 tmp |= value & mask; 94 outl(tmp, chip->addr + reg); 95 chip->saved_registers._32[reg / 4] = cpu_to_le32(tmp); 96 } 97 EXPORT_SYMBOL(oxygen_write32_masked); 98 99 static int oxygen_ac97_wait(struct oxygen *chip, unsigned int mask) 100 { 101 u8 status = 0; 102 103 /* 104 * Reading the status register also clears the bits, so we have to save 105 * the read bits in status. 106 */ 107 wait_event_timeout(chip->ac97_waitqueue, 108 ({ status |= oxygen_read8(chip, OXYGEN_AC97_INTERRUPT_STATUS); 109 status & mask; }), 110 msecs_to_jiffies(1) + 1); 111 /* 112 * Check even after a timeout because this function should not require 113 * the AC'97 interrupt to be enabled. 114 */ 115 status |= oxygen_read8(chip, OXYGEN_AC97_INTERRUPT_STATUS); 116 return status & mask ? 0 : -EIO; 117 } 118 119 /* 120 * About 10% of AC'97 register reads or writes fail to complete, but even those 121 * where the controller indicates completion aren't guaranteed to have actually 122 * happened. 123 * 124 * It's hard to assign blame to either the controller or the codec because both 125 * were made by C-Media ... 126 */ 127 128 void oxygen_write_ac97(struct oxygen *chip, unsigned int codec, 129 unsigned int index, u16 data) 130 { 131 unsigned int count, succeeded; 132 u32 reg; 133 134 reg = data; 135 reg |= index << OXYGEN_AC97_REG_ADDR_SHIFT; 136 reg |= OXYGEN_AC97_REG_DIR_WRITE; 137 reg |= codec << OXYGEN_AC97_REG_CODEC_SHIFT; 138 succeeded = 0; 139 for (count = 5; count > 0; --count) { 140 udelay(5); 141 oxygen_write32(chip, OXYGEN_AC97_REGS, reg); 142 /* require two "completed" writes, just to be sure */ 143 if (oxygen_ac97_wait(chip, OXYGEN_AC97_INT_WRITE_DONE) >= 0 && 144 ++succeeded >= 2) { 145 chip->saved_ac97_registers[codec][index / 2] = data; 146 return; 147 } 148 } 149 snd_printk(KERN_ERR "AC'97 write timeout\n"); 150 } 151 EXPORT_SYMBOL(oxygen_write_ac97); 152 153 u16 oxygen_read_ac97(struct oxygen *chip, unsigned int codec, 154 unsigned int index) 155 { 156 unsigned int count; 157 unsigned int last_read = UINT_MAX; 158 u32 reg; 159 160 reg = index << OXYGEN_AC97_REG_ADDR_SHIFT; 161 reg |= OXYGEN_AC97_REG_DIR_READ; 162 reg |= codec << OXYGEN_AC97_REG_CODEC_SHIFT; 163 for (count = 5; count > 0; --count) { 164 udelay(5); 165 oxygen_write32(chip, OXYGEN_AC97_REGS, reg); 166 udelay(10); 167 if (oxygen_ac97_wait(chip, OXYGEN_AC97_INT_READ_DONE) >= 0) { 168 u16 value = oxygen_read16(chip, OXYGEN_AC97_REGS); 169 /* we require two consecutive reads of the same value */ 170 if (value == last_read) 171 return value; 172 last_read = value; 173 /* 174 * Invert the register value bits to make sure that two 175 * consecutive unsuccessful reads do not return the same 176 * value. 177 */ 178 reg ^= 0xffff; 179 } 180 } 181 snd_printk(KERN_ERR "AC'97 read timeout on codec %u\n", codec); 182 return 0; 183 } 184 EXPORT_SYMBOL(oxygen_read_ac97); 185 186 void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec, 187 unsigned int index, u16 data, u16 mask) 188 { 189 u16 value = oxygen_read_ac97(chip, codec, index); 190 value &= ~mask; 191 value |= data & mask; 192 oxygen_write_ac97(chip, codec, index, value); 193 } 194 EXPORT_SYMBOL(oxygen_write_ac97_masked); 195 196 void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data) 197 { 198 unsigned int count; 199 200 /* should not need more than 7.68 us (24 * 320 ns) */ 201 count = 10; 202 while ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & OXYGEN_SPI_BUSY) 203 && count > 0) { 204 udelay(1); 205 --count; 206 } 207 208 oxygen_write8(chip, OXYGEN_SPI_DATA1, data); 209 oxygen_write8(chip, OXYGEN_SPI_DATA2, data >> 8); 210 if (control & OXYGEN_SPI_DATA_LENGTH_3) 211 oxygen_write8(chip, OXYGEN_SPI_DATA3, data >> 16); 212 oxygen_write8(chip, OXYGEN_SPI_CONTROL, control); 213 } 214 EXPORT_SYMBOL(oxygen_write_spi); 215 216 void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data) 217 { 218 /* should not need more than about 300 us */ 219 msleep(1); 220 221 oxygen_write8(chip, OXYGEN_2WIRE_MAP, map); 222 oxygen_write8(chip, OXYGEN_2WIRE_DATA, data); 223 oxygen_write8(chip, OXYGEN_2WIRE_CONTROL, 224 device | OXYGEN_2WIRE_DIR_WRITE); 225 } 226 EXPORT_SYMBOL(oxygen_write_i2c); 227 228 static void _write_uart(struct oxygen *chip, unsigned int port, u8 data) 229 { 230 if (oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_TX_FULL) 231 msleep(1); 232 oxygen_write8(chip, OXYGEN_MPU401 + port, data); 233 } 234 235 void oxygen_reset_uart(struct oxygen *chip) 236 { 237 _write_uart(chip, 1, MPU401_RESET); 238 msleep(1); /* wait for ACK */ 239 _write_uart(chip, 1, MPU401_ENTER_UART); 240 } 241 EXPORT_SYMBOL(oxygen_reset_uart); 242 243 void oxygen_write_uart(struct oxygen *chip, u8 data) 244 { 245 _write_uart(chip, 0, data); 246 } 247 EXPORT_SYMBOL(oxygen_write_uart); 248 249 u16 oxygen_read_eeprom(struct oxygen *chip, unsigned int index) 250 { 251 unsigned int timeout; 252 253 oxygen_write8(chip, OXYGEN_EEPROM_CONTROL, 254 index | OXYGEN_EEPROM_DIR_READ); 255 for (timeout = 0; timeout < 100; ++timeout) { 256 udelay(1); 257 if (!(oxygen_read8(chip, OXYGEN_EEPROM_STATUS) 258 & OXYGEN_EEPROM_BUSY)) 259 break; 260 } 261 return oxygen_read16(chip, OXYGEN_EEPROM_DATA); 262 } 263 264 void oxygen_write_eeprom(struct oxygen *chip, unsigned int index, u16 value) 265 { 266 unsigned int timeout; 267 268 oxygen_write16(chip, OXYGEN_EEPROM_DATA, value); 269 oxygen_write8(chip, OXYGEN_EEPROM_CONTROL, 270 index | OXYGEN_EEPROM_DIR_WRITE); 271 for (timeout = 0; timeout < 10; ++timeout) { 272 msleep(1); 273 if (!(oxygen_read8(chip, OXYGEN_EEPROM_STATUS) 274 & OXYGEN_EEPROM_BUSY)) 275 return; 276 } 277 snd_printk(KERN_ERR "EEPROM write timeout\n"); 278 } 279