Changeset 777 for GPL/trunk/alsa-kernel/pci/emu10k1/io.c
- Timestamp:
- Apr 21, 2025, 7:17:25 PM (4 months ago)
- Location:
- GPL/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/trunk
- Property svn:mergeinfo changed
/GPL/branches/uniaud32-exp merged: 766-767,770-771,773-774
- Property svn:mergeinfo changed
-
GPL/trunk/alsa-kernel/pci/emu10k1/io.c
r772 r777 291 291 void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value) 292 292 { 293 unsigned long flags; 294 295 spin_lock_irqsave(&emu->emu_lock, flags); 293 #ifndef TARGET_OS2 294 if (snd_BUG_ON(!mutex_is_locked(&emu->emu1010.lock))) 295 return; 296 #endif 296 297 snd_emu1010_fpga_write_locked(emu, reg, value); 297 spin_unlock_irqrestore(&emu->emu_lock, flags); 298 } 299 300 static void snd_emu1010_fpga_read_locked(struct snd_emu10k1 *emu, u32 reg, u32 *value) 298 } 299 300 void snd_emu1010_fpga_write_lock(struct snd_emu10k1 *emu, u32 reg, u32 value) 301 { 302 snd_emu1010_fpga_lock(emu); 303 snd_emu1010_fpga_write_locked(emu, reg, value); 304 snd_emu1010_fpga_unlock(emu); 305 } 306 307 void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value) 301 308 { 302 309 // The higest input pin is used as the designated interrupt trigger, … … 305 312 // so using this function often causes an IRQ as a side effect. 306 313 u32 mask = emu->card_capabilities->ca0108_chip ? 0x1f : 0x7f; 314 315 #ifndef TARGET_OS2 316 if (snd_BUG_ON(!mutex_is_locked(&emu->emu1010.lock))) 317 return; 318 #endif 307 319 if (snd_BUG_ON(reg > 0x3f)) 308 320 return; … … 315 327 } 316 328 317 void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value)318 {319 unsigned long flags;320 321 spin_lock_irqsave(&emu->emu_lock, flags);322 snd_emu1010_fpga_read_locked(emu, reg, value);323 spin_unlock_irqrestore(&emu->emu_lock, flags);324 }325 326 329 /* Each Destination has one and only one Source, 327 330 * but one Source can feed any number of Destinations simultaneously. … … 329 332 void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src) 330 333 { 331 unsigned long flags;332 333 334 if (snd_BUG_ON(dst & ~0x71f)) 334 335 return; 335 336 if (snd_BUG_ON(src & ~0x71f)) 336 337 return; 337 spin_lock_irqsave(&emu->emu_lock, flags); 338 snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTHI, dst >> 8); 339 snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTLO, dst & 0x1f); 340 snd_emu1010_fpga_write_locked(emu, EMU_HANA_SRCHI, src >> 8); 341 snd_emu1010_fpga_write_locked(emu, EMU_HANA_SRCLO, src & 0x1f); 342 spin_unlock_irqrestore(&emu->emu_lock, flags); 338 snd_emu1010_fpga_write(emu, EMU_HANA_DESTHI, dst >> 8); 339 snd_emu1010_fpga_write(emu, EMU_HANA_DESTLO, dst & 0x1f); 340 snd_emu1010_fpga_write(emu, EMU_HANA_SRCHI, src >> 8); 341 snd_emu1010_fpga_write(emu, EMU_HANA_SRCLO, src & 0x1f); 343 342 } 344 343 345 344 u32 snd_emu1010_fpga_link_dst_src_read(struct snd_emu10k1 *emu, u32 dst) 346 345 { 347 unsigned long flags;348 346 u32 hi, lo; 349 347 350 348 if (snd_BUG_ON(dst & ~0x71f)) 351 349 return 0; 352 spin_lock_irqsave(&emu->emu_lock, flags); 353 snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTHI, dst >> 8); 354 snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTLO, dst & 0x1f); 355 snd_emu1010_fpga_read_locked(emu, EMU_HANA_SRCHI, &hi); 356 snd_emu1010_fpga_read_locked(emu, EMU_HANA_SRCLO, &lo); 357 spin_unlock_irqrestore(&emu->emu_lock, flags); 350 snd_emu1010_fpga_write(emu, EMU_HANA_DESTHI, dst >> 8); 351 snd_emu1010_fpga_write(emu, EMU_HANA_DESTLO, dst & 0x1f); 352 snd_emu1010_fpga_read(emu, EMU_HANA_SRCHI, &hi); 353 snd_emu1010_fpga_read(emu, EMU_HANA_SRCLO, &lo); 358 354 return (hi << 8) | lo; 359 355 } … … 429 425 430 426 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, leds); 427 } 428 429 void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, int dock, 430 const struct firmware *fw_entry) 431 { 432 __always_unused u16 write_post; 433 434 // On E-MU 1010 rev1 the FPGA is a Xilinx Spartan IIE XC2S50E. 435 // On E-MU 0404b it is a Xilinx Spartan III XC3S50. 436 // The wiring is as follows: 437 // GPO7 -> FPGA input & 1K resistor -> FPGA /PGMN <- FPGA output 438 // In normal operation, the active low reset line is held up by 439 // an FPGA output, while the GPO pin performs its duty as control 440 // register access strobe signal. Writing the respective bit to 441 // EMU_HANA_FPGA_CONFIG puts the FPGA output into high-Z mode, at 442 // which point the GPO pin can control the reset line through the 443 // resistor. 444 // GPO6 -> FPGA CCLK & FPGA input 445 // GPO5 -> FPGA DIN (dual function) 446 447 // If the FPGA is already programmed, return it to programming mode 448 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 449 dock ? EMU_HANA_FPGA_CONFIG_AUDIODOCK : 450 EMU_HANA_FPGA_CONFIG_HANA); 451 452 // Assert reset line for 100uS 453 outw(0x00, emu->port + A_GPIO); 454 write_post = inw(emu->port + A_GPIO); 455 udelay(100); 456 outw(0x80, emu->port + A_GPIO); 457 write_post = inw(emu->port + A_GPIO); 458 udelay(100); // Allow FPGA memory to clean 459 460 // Upload the netlist. Keep reset line high! 461 for (int n = 0; n < fw_entry->size; n++) { 462 u8 value = fw_entry->data[n]; 463 for (int i = 0; i < 8; i++) { 464 u16 reg = 0x80; 465 if (value & 1) 466 reg |= 0x20; 467 value >>= 1; 468 outw(reg, emu->port + A_GPIO); 469 write_post = inw(emu->port + A_GPIO); 470 outw(reg | 0x40, emu->port + A_GPIO); 471 write_post = inw(emu->port + A_GPIO); 472 } 473 } 474 475 // After programming, set GPIO bit 4 high again. 476 // This appears to be a config word that the rev1 Hana 477 // firmware reads; weird things happen without this. 478 outw(0x10, emu->port + A_GPIO); 479 write_post = inw(emu->port + A_GPIO); 431 480 } 432 481
Note:
See TracChangeset
for help on using the changeset viewer.