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 <asm/io.h> 24 #include "oxygen.h" 25 26 u8 oxygen_read8(struct oxygen *chip, unsigned int reg) 27 { 28 return inb(chip->addr + reg); 29 } 30 EXPORT_SYMBOL(oxygen_read8); 31 32 u16 oxygen_read16(struct oxygen *chip, unsigned int reg) 33 { 34 return inw(chip->addr + reg); 35 } 36 EXPORT_SYMBOL(oxygen_read16); 37 38 u32 oxygen_read32(struct oxygen *chip, unsigned int reg) 39 { 40 return inl(chip->addr + reg); 41 } 42 EXPORT_SYMBOL(oxygen_read32); 43 44 void oxygen_write8(struct oxygen *chip, unsigned int reg, u8 value) 45 { 46 outb(value, chip->addr + reg); 47 chip->saved_registers._8[reg] = value; 48 } 49 EXPORT_SYMBOL(oxygen_write8); 50 51 void oxygen_write16(struct oxygen *chip, unsigned int reg, u16 value) 52 { 53 outw(value, chip->addr + reg); 54 chip->saved_registers._16[reg / 2] = cpu_to_le16(value); 55 } 56 EXPORT_SYMBOL(oxygen_write16); 57 58 void oxygen_write32(struct oxygen *chip, unsigned int reg, u32 value) 59 { 60 outl(value, chip->addr + reg); 61 chip->saved_registers._32[reg / 4] = cpu_to_le32(value); 62 } 63 EXPORT_SYMBOL(oxygen_write32); 64 65 void oxygen_write8_masked(struct oxygen *chip, unsigned int reg, 66 u8 value, u8 mask) 67 { 68 u8 tmp = inb(chip->addr + reg); 69 tmp &= ~mask; 70 tmp |= value & mask; 71 outb(tmp, chip->addr + reg); 72 chip->saved_registers._8[reg] = tmp; 73 } 74 EXPORT_SYMBOL(oxygen_write8_masked); 75 76 void oxygen_write16_masked(struct oxygen *chip, unsigned int reg, 77 u16 value, u16 mask) 78 { 79 u16 tmp = inw(chip->addr + reg); 80 tmp &= ~mask; 81 tmp |= value & mask; 82 outw(tmp, chip->addr + reg); 83 chip->saved_registers._16[reg / 2] = cpu_to_le16(tmp); 84 } 85 EXPORT_SYMBOL(oxygen_write16_masked); 86 87 void oxygen_write32_masked(struct oxygen *chip, unsigned int reg, 88 u32 value, u32 mask) 89 { 90 u32 tmp = inl(chip->addr + reg); 91 tmp &= ~mask; 92 tmp |= value & mask; 93 outl(tmp, chip->addr + reg); 94 chip->saved_registers._32[reg / 4] = cpu_to_le32(tmp); 95 } 96 EXPORT_SYMBOL(oxygen_write32_masked); 97 98 static int oxygen_ac97_wait(struct oxygen *chip, unsigned int mask) 99 { 100 u8 status = 0; 101 102 /* 103 * Reading the status register also clears the bits, so we have to save 104 * the read bits in status. 105 */ 106 wait_event_timeout(chip->ac97_waitqueue, 107 ({ status |= oxygen_read8(chip, OXYGEN_AC97_INTERRUPT_STATUS); 108 status & mask; }), 109 msecs_to_jiffies(1) + 1); 110 /* 111 * Check even after a timeout because this function should not require 112 * the AC'97 interrupt to be enabled. 113 */ 114 status |= oxygen_read8(chip, OXYGEN_AC97_INTERRUPT_STATUS); 115 return status & mask ? 0 : -EIO; 116 } 117 118 /* 119 * About 10% of AC'97 register reads or writes fail to complete, but even those 120 * where the controller indicates completion aren't guaranteed to have actually 121 * happened. 122 * 123 * It's hard to assign blame to either the controller or the codec because both 124 * were made by C-Media ... 125 */ 126 127 void oxygen_write_ac97(struct oxygen *chip, unsigned int codec, 128 unsigned int index, u16 data) 129 { 130 unsigned int count, succeeded; 131 u32 reg; 132 133 reg = data; 134 reg |= index << OXYGEN_AC97_REG_ADDR_SHIFT; 135 reg |= OXYGEN_AC97_REG_DIR_WRITE; 136 reg |= codec << OXYGEN_AC97_REG_CODEC_SHIFT; 137 succeeded = 0; 138 for (count = 5; count > 0; --count) { 139 udelay(5); 140 oxygen_write32(chip, OXYGEN_AC97_REGS, reg); 141 /* require two "completed" writes, just to be sure */ 142 if (oxygen_ac97_wait(chip, OXYGEN_AC97_INT_WRITE_DONE) >= 0 && 143 ++succeeded >= 2) { 144 chip->saved_ac97_registers[codec][index / 2] = data; 145 return; 146 } 147 } 148 snd_printk(KERN_ERR "AC'97 write timeout\n"); 149 } 150 EXPORT_SYMBOL(oxygen_write_ac97); 151 152 u16 oxygen_read_ac97(struct oxygen *chip, unsigned int codec, 153 unsigned int index) 154 { 155 unsigned int count; 156 unsigned int last_read = UINT_MAX; 157 u32 reg; 158 159 reg = index << OXYGEN_AC97_REG_ADDR_SHIFT; 160 reg |= OXYGEN_AC97_REG_DIR_READ; 161 reg |= codec << OXYGEN_AC97_REG_CODEC_SHIFT; 162 for (count = 5; count > 0; --count) { 163 udelay(5); 164 oxygen_write32(chip, OXYGEN_AC97_REGS, reg); 165 udelay(10); 166 if (oxygen_ac97_wait(chip, OXYGEN_AC97_INT_READ_DONE) >= 0) { 167 u16 value = oxygen_read16(chip, OXYGEN_AC97_REGS); 168 /* we require two consecutive reads of the same value */ 169 if (value == last_read) 170 return value; 171 last_read = value; 172 /* 173 * Invert the register value bits to make sure that two 174 * consecutive unsuccessful reads do not return the same 175 * value. 176 */ 177 reg ^= 0xffff; 178 } 179 } 180 snd_printk(KERN_ERR "AC'97 read timeout on codec %u\n", codec); 181 return 0; 182 } 183 EXPORT_SYMBOL(oxygen_read_ac97); 184 185 void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec, 186 unsigned int index, u16 data, u16 mask) 187 { 188 u16 value = oxygen_read_ac97(chip, codec, index); 189 value &= ~mask; 190 value |= data & mask; 191 oxygen_write_ac97(chip, codec, index, value); 192 } 193 EXPORT_SYMBOL(oxygen_write_ac97_masked); 194 195 void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data) 196 { 197 unsigned int count; 198 199 /* should not need more than 7.68 us (24 * 320 ns) */ 200 count = 10; 201 while ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & OXYGEN_SPI_BUSY) 202 && count > 0) { 203 udelay(1); 204 --count; 205 } 206 207 oxygen_write8(chip, OXYGEN_SPI_DATA1, data); 208 oxygen_write8(chip, OXYGEN_SPI_DATA2, data >> 8); 209 if (control & OXYGEN_SPI_DATA_LENGTH_3) 210 oxygen_write8(chip, OXYGEN_SPI_DATA3, data >> 16); 211 oxygen_write8(chip, OXYGEN_SPI_CONTROL, control); 212 } 213 EXPORT_SYMBOL(oxygen_write_spi); 214 215 void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data) 216 { 217 unsigned long timeout; 218 219 /* should not need more than about 300 us */ 220 timeout = jiffies + msecs_to_jiffies(1); 221 do { 222 if (!(oxygen_read16(chip, OXYGEN_2WIRE_BUS_STATUS) 223 & OXYGEN_2WIRE_BUSY)) 224 break; 225 udelay(1); 226 cond_resched(); 227 } while (time_after_eq(timeout, jiffies)); 228 229 oxygen_write8(chip, OXYGEN_2WIRE_MAP, map); 230 oxygen_write8(chip, OXYGEN_2WIRE_DATA, data); 231 oxygen_write8(chip, OXYGEN_2WIRE_CONTROL, 232 device | OXYGEN_2WIRE_DIR_WRITE); 233 } 234 EXPORT_SYMBOL(oxygen_write_i2c); 235