aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/emu10k1/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/emu10k1/io.c')
-rw-r--r--sound/pci/emu10k1/io.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index 029e7856c43b..116e1c8d9361 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -30,6 +30,7 @@
30#include <sound/core.h> 30#include <sound/core.h>
31#include <sound/emu10k1.h> 31#include <sound/emu10k1.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include "p17v.h"
33 34
34unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn) 35unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn)
35{ 36{
@@ -167,6 +168,109 @@ int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
167 return 0; 168 return 0;
168} 169}
169 170
171/* The ADC does not support i2c read, so only write is implemented */
172int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu,
173 u32 reg,
174 u32 value)
175{
176 u32 tmp;
177 int timeout = 0;
178 int status;
179 int retry;
180 if ((reg > 0x7f) || (value > 0x1ff)) {
181 snd_printk(KERN_ERR "i2c_write: invalid values.\n");
182 return -EINVAL;
183 }
184
185 tmp = reg << 25 | value << 16;
186 // snd_printk("I2C-write:reg=0x%x, value=0x%x\n", reg, value);
187 /* Not sure what this I2C channel controls. */
188 /* snd_emu10k1_ptr_write(emu, P17V_I2C_0, 0, tmp); */
189
190 /* This controls the I2C connected to the WM8775 ADC Codec */
191 snd_emu10k1_ptr20_write(emu, P17V_I2C_1, 0, tmp);
192 tmp = snd_emu10k1_ptr20_read(emu, P17V_I2C_1, 0); /* write post */
193
194 for (retry = 0; retry < 10; retry++) {
195 /* Send the data to i2c */
196 //tmp = snd_emu10k1_ptr_read(emu, P17V_I2C_ADDR, 0);
197 //tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK);
198 tmp = 0;
199 tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD);
200 snd_emu10k1_ptr20_write(emu, P17V_I2C_ADDR, 0, tmp);
201
202 /* Wait till the transaction ends */
203 while (1) {
204 udelay(10);
205 status = snd_emu10k1_ptr20_read(emu, P17V_I2C_ADDR, 0);
206 // snd_printk("I2C:status=0x%x\n", status);
207 timeout++;
208 if ((status & I2C_A_ADC_START) == 0)
209 break;
210
211 if (timeout > 1000) {
212 snd_printk("emu10k1:I2C:timeout status=0x%x\n", status);
213 break;
214 }
215 }
216 //Read back and see if the transaction is successful
217 if ((status & I2C_A_ADC_ABORT) == 0)
218 break;
219 }
220
221 if (retry == 10) {
222 snd_printk(KERN_ERR "Writing to ADC failed!\n");
223 return -EINVAL;
224 }
225
226 return 0;
227}
228
229int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, int reg, int value)
230{
231 if (reg < 0 || reg > 0x3f)
232 return 1;
233 reg += 0x40; /* 0x40 upwards are registers. */
234 if (value < 0 || value > 0x3f) /* 0 to 0x3f are values */
235 return 1;
236 outl(reg, emu->port + A_IOCFG);
237 udelay(10);
238 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
239 udelay(10);
240 outl(value, emu->port + A_IOCFG);
241 udelay(10);
242 outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
243
244 return 0;
245}
246
247int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, int reg, int *value)
248{
249 if (reg < 0 || reg > 0x3f)
250 return 1;
251 reg += 0x40; /* 0x40 upwards are registers. */
252 outl(reg, emu->port + A_IOCFG);
253 udelay(10);
254 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
255 udelay(10);
256 *value = ((inl(emu->port + A_IOCFG) >> 8) & 0x7f);
257
258 return 0;
259}
260
261/* Each Destination has one and only one Source,
262 * but one Source can feed any number of Destinations simultaneously.
263 */
264int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, int dst, int src)
265{
266 snd_emu1010_fpga_write(emu, 0x00, ((dst >> 8) & 0x3f) );
267 snd_emu1010_fpga_write(emu, 0x01, (dst & 0x3f) );
268 snd_emu1010_fpga_write(emu, 0x02, ((src >> 8) & 0x3f) );
269 snd_emu1010_fpga_write(emu, 0x03, (src & 0x3f) );
270
271 return 0;
272}
273
170void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb) 274void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
171{ 275{
172 unsigned long flags; 276 unsigned long flags;