?? rf_dev.c
字號(hào):
/*************************************************************************** rf_dev.c - The device-interface for the rf ------------------- begin : 2002 authors : Linus Gasser emails : linus.gasser@epfl.ch ***************************************************************************//*************************************************************************** Changes ------- date - name - description 02-10-01 - ineiti - create 02-12-11 - ineiti - changed the name from daq.c **************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************//** * This is the linux-device part of the rf-implementation */#define DBG_LVL 0#include "system.h"#include "debugging.h"#include "channel_rf.h"#include "rf_io.h"#include "rf_dev.h"#include "rf_eeprom.h"#include "memory.h"#include "mmx.h"device_t *rf_cards;int num_cards;static int rf_open ( struct inode *inode,struct file *filp ) { PR_DBG( 4, "Opening RF driver\n" ); return 0;}static int rf_release ( struct inode *inode,struct file *filp ) { PR_DBG( 4, "Closing RF\n" ); return 0;}/* arg is not meaningful if no arg is passed in user space */static int rf_ioctl( struct inode *inode,struct file *filp, unsigned int cmd, unsigned long arg ) { int ret,tmp; int fpga_size = 0; int gain,freq,time, nbr_rf = MINOR( inode->i_rdev ); device_t *dev_rf; unsigned int baseptr; unsigned int rx_pci_address; unsigned int tx_pci_address; unsigned int mbox_pci_address; int i; char bit; dev_rf = &rf_cards[ nbr_rf ]; baseptr = (int)dev_rf->data_base; PR_DBG( 4, "Accessing card-number: %i\n", nbr_rf ); rx_pci_address = ( unsigned int ) virt_to_phys( dev_rf->rx_buffer ); tx_pci_address = ( unsigned int ) virt_to_phys( dev_rf->tx_buffer ); mbox_pci_address = ( unsigned int ) virt_to_phys( dev_rf->mboxes ); switch( cmd ) { case RF_FPGA_RESET: PR_DBG( 4, "Resetting FPGA logic\n" ); tmp = inl( dev_rf->addr[1] + 0x6C ); outl( tmp | 0x10000, dev_rf->addr[1] + 0x6C ); /* Set PROGRAM value to LOW */ rf_writel( 0x00000000, baseptr + 0x200000 ); /* A21, !D31 */ rf_writel( 0xFF, baseptr + 0x200000 ); /* A21, D31 */ udelay( 20 ); PR_DBG( 4, "Readback=%x\n",readl( baseptr + 0x200000 ) ); break; case RF_FPGA_PROGRAM: /* verify addresses */ if( ( ret = verify_area( VERIFY_READ, ( void * )arg, sizeof( int ) ) ) != 0 ) { PR_DBG( 4, "FPGA_PROGRAM: size verify error: %d\n", ret ); return -1; } get_user( fpga_size,( unsigned int * )arg ); PR_DBG( 4, "FPGA_PROGRAM: size : %d OK\n", fpga_size ); if( ( ret = verify_area( VERIFY_READ, ( void * )arg, fpga_size ) ) != 0 ) { PR_DBG( 4, "FPGA_PROGRAM: verify error: %d\n", ret ); return -1; } // Give Local Bus control to GAL arbiter tmp = inl( dev_rf->addr[1] + 0x6C ); outl( tmp | 0x10000, dev_rf->addr[1] + 0x6C ); PR_DBG( 4, "Start loading\n" ); // Set PROGRAM value to LOW rf_writel( 0x00000000, baseptr + 0x200000 ); // put PROGRAM* low rf_writel( 0xFFFFFFFF, baseptr + 0x200000 ); // put PROGRAM* high /* Was 1 but some errors appear. Could be as big as 100 ( from the Xilynx doc ). Looking for INIT is the correct method, but this doesn't work. WHY ? */ udelay( 10 ); for( i = 0; i < fpga_size; ++i ) { /* +4 : We have the buffer size ( 4 bytes ) at the beginning */ get_user( bit,( unsigned char * )arg + i + 4 ); if ( bit ) { writel( 0xFFFFFFFF,baseptr+0x220000 ); mb( ); } else { rf_writel( 0x00000000, baseptr + 0x220000 ); } } for( i = 0; i < 250; ++i ) rf_writel( 0xFFFFFFFF, baseptr + 0x220000 ); udelay( 100 ); // sleep 20usec // Give Local bus Control to FPGA tmp = inl( dev_rf->addr[1] + 0x6C ); outl( tmp & ( ~0x10000 ), dev_rf->addr[1] + 0x6C ); PR_DBG( 4, "FPGA LOAD = %x\n",readl( baseptr + 0x200000 ) ); PR_DBG( 4, "Writing %x\n",rx_pci_address ); rf_writel( rx_pci_address,baseptr+0x400000 ); PR_DBG( 4, "Read back %x\n",readl( baseptr + 0x400000 ) ); rf_writel( 0,baseptr+DAC_BUFFER ); break; case RF_GETPHYS_RX: put_user( rx_pci_address, ( unsigned long * )arg ); break; case RF_GETPHYS_TX: put_user( tx_pci_address, ( unsigned long * )arg ); break; case RF_GETPHYS_MBOX: put_user( mbox_pci_address, ( unsigned long * )arg ); break; case RF_SET_TEST_TX1: setmode( dev_rf, TEST_TX1 ); break; case RF_SET_TEST_TX2: setmode( dev_rf, TEST_TX2 ); break; case RF_SET_TEST_RX1: setmode( dev_rf, TEST_RX1 ); break; case RF_SET_TEST_RX2: setmode( dev_rf, TEST_RX2 ); break; case RF_SET_TX_PA_GAIN: get_user( gain,( int * )arg ); writegain( dev_rf, TX_PA_GAIN,gain ); break; case RF_SET_TX_MED_GAIN: get_user( gain,( int * )arg ); writegain( dev_rf, TX_MED_GAIN,gain ); break; case RF_SET_TX_IF_GAIN: get_user( gain,( int * )arg ); writegain( dev_rf, TX_IF_GAIN,gain ); break; case RF_SET_RX_IF_GAIN: get_user( gain,( int * )arg ); writegain( dev_rf, RX_IF_GAIN,gain ); break; case RF_SET_SDAC: get_user( gain,( int * )arg ); write_sdac( dev_rf, gain ); break; case RF_SET_FSYN: get_user( freq,( unsigned int * )arg ); PR_DBG( 4, "freq=%d\n",freq ); write_lo( dev_rf, freq ); break; case RF_TEST_FPGA_MEM: return( test_FPGA_mem( dev_rf ) ); break; case RF_TEST_ADC_DMA: get_user( time,( unsigned int * )arg ); return( test_adc_dma( dev_rf, time ) ); break; case RF_TEST_DAC_DMA: get_user( time,( unsigned int * )arg ); return( test_dac_dma( dev_rf, time ) ); break; case RF_START_TEST_DAC: return( start_test_dac( dev_rf ) ); break; case RF_STOP_TEST_DAC: return( stop_test_dac( dev_rf ) ); break; case RF_DUMP_PLX_REGS: PR_DBG( 4, "PLX 9080 Local Register Dump\n" ); for ( i=0;i<256;i+=4 ) { tmp = inl( dev_rf->addr[1] + i ); PR_DBG( 4, "%x:%x\n",i,tmp ); } break; case RF_EEPROM_WRITE: rf_ee_write_data( dev_rf ); break; case RF_EEPROM_READ: rf_ee_read_data( dev_rf ); break; default: return -EPERM; break; } PR_DBG( 4, "Done with ioctl %x\n",cmd ); return 0;}static struct file_operations rf_fops[] = { { THIS_MODULE, NULL, //llseek NULL, //read NULL, //write NULL, //readdir NULL, //poll rf_ioctl, //ioctl NULL, //mmap rf_open, //open NULL, //flush rf_release, //release NULL, //fsync NULL, //fasync NULL, //check_media_change NULL, //revalidate NULL } } ; //lockint init_dev( void ) { device_t *dev_rf; int res = 0, i; unsigned short vendor = 0x10b5; unsigned short id = 0x9080; unsigned short ind,index[256]; unsigned char bus[256]; unsigned char function[256]; // Register the device if( ( res = register_chrdev( RF_MAJOR, "rf", rf_fops ) ) < 0 ) { PR_DBG( 4, "can't register, major : %d, error: %d\n", RF_MAJOR, res ); return -EIO; } else { PR_DBG( 4, "register OK, major : %d\n", RF_MAJOR ); } // Check for PCI Bios if( pcibios_present( ) ) { PR_DBG( 4, "pci bios present\n" ); } else { PR_DBG( 4, "NO pci bios found\n" ); return -ENODEV; } // Look for 1 PLX 9080#define MAX_DEV 256 rf_cards = swr_malloc( sizeof( device_t ) * MAX_ANTENNAS ); for( ind = 0; ind < MAX_DEV; ++ind ) { res = pcibios_find_device( vendor, id, ind, &bus[num_cards], &function[num_cards] ); if( res == PCIBIOS_SUCCESSFUL ) { PR_DBG( 4, "card found: bus: 0x%02x, index: 0x%02x, function: 0x%02x\n", bus[num_cards], index[num_cards], function[num_cards] ); index[num_cards] = ind; num_cards++; } } if( num_cards==0 ) { // Loop has ended, and device not found PR_DBG( 4, "No card found\n" ); return -ENODEV; // Must look if there is another return code } for ( i=0; i < num_cards; i++ ) { PR_DBG( 0, "Detected card number %i\n", i ); // Now read the configuration dev_rf = &rf_cards[ i ]; dev_rf->vendor = vendor; dev_rf->id = id; dev_rf->index = index[ i ]; dev_rf->bus = bus[ i ]; dev_rf->func = function[ i ]; dump_config( dev_rf, bus[i], function[i] ); pthread_mutex_init( &dev_rf->mutex, NULL ); // Now map the DMA Memory Space dev_rf->data_base = (unsigned int)ioremap_nocache( dev_rf->addr[2],RAMSIZE ); PR_DBG( 4, "Starting RF\n" ); PR_DBG( 4, "I/O Virtual address is : 0x%x\n", dev_rf->data_base ); } // END OF MODULE Initializations dev_rf = &rf_cards[ 0 ]; PR_DBG( 4, "dev_rf = %p\n",dev_rf ); return 0;}void cleanup_dev( void ) { int i; device_t *dev_rf; for ( i=0; i < num_cards; i++ ) { PR_DBG( 4, "Freeing dispatcher %i\n", i ); dev_rf = &rf_cards[ i ]; PR_DBG( 4, "Removing rf card %i\n", i ); // Unmap the FPGA memory space iounmap( ( char * )dev_rf->data_base ); dev_rf->data_base = 0; dev_rf->offset = 0; } // unregister device unregister_chrdev( RF_MAJOR, "rf" ); PR_DBG( 4, "unregister, major : %d\n", RF_MAJOR );}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -