davinci 6446 UART1 rs485驱动

来源:互联网 发布:网络分层模型详解 编辑:程序博客网 时间:2024/05/20 07:34

原文地址:http://blog.sina.com.cn/s/blog_87f8cc4e01019zfd.html

自己写的DM6446中uart1驱动来实现485通信。在linux-2.6.18_pro500中uart驱动在8250.c中。这里贴出自己的实现的驱动。

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include<linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include<linux/mtd/partitions.h>
#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE)
#include <linux/mtd/physmap.h>
#endif
#include <linux/serial.h>
#include <linux/serial_8250.h>

#include <asm/setup.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>

#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>

#include <asm/arch/common.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mux.h>
#include <asm/arch/clock.h>
#include <asm/arch/nand.h>
#include <asm/arch/mmc.h>
#include <asm/arch/edma.h>
#include <asm/arch/i2c-client.h>

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/delay.h>
#include<linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_reg.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/nmi.h>
#include <linux/mutex.h>

#include <asm/io.h>
#include <asm/irq.h>


#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/ctype.h>
#include <linux/delay.h>


#include <linux/videodev.h>
#include <linux/device.h>

#include <linux/cdev.h>
#include <linux/types.h>
#include <asm/uaccess.h>

#define davinci_readb(a) (*(volatile unsignedchar  *)IO_ADDRESS(a))
#define davinci_readw(a) (*(volatile unsignedshort *)IO_ADDRESS(a))
#define davinci_readl(a) (*(volatile unsignedint   *)IO_ADDRESS(a))

#define davinci_writeb(v,a) (*(volatileunsigned char  *)IO_ADDRESS(a) = (v))
#define davinci_writew(v,a) (*(volatile unsignedshort *)IO_ADDRESS(a) = (v))
#define davinci_writel(v,a) (*(volatile unsignedint   *)IO_ADDRESS(a) = (v))

#undef DEV_485_BUG
#define DEV_485_BUG

#ifdef DEV_485_BUG
#define debug_print3(fmt, args...) printk( "dev_485: " fmt, ##args)
#else
#define  debug_print3(x...)
#endif


static int  Opened=0;

static int Major=0;

#define DRIVER_NAME "max485"

struct max485_chip_info {
    struct cdevcdev;
    struct mutexupdate_lock;
};

 struct class *max485_class;

//static unsigned int kuart1_base;

//static unsigned int kpsc_epcpr;
//static unsigned int kpsc_ptcmd;
//static unsigned int kpsc_ptstat;
//static unsigned int kpsc_pdstat;
//static unsigned int kpsc_pdctl;
//static unsigned int kpsc_mdctl_uart1;

//static unsigned int kgpio_base;
//static unsigned int kpinmux_base;

//static unsigned int kpsc_mdstat_uart1;
//static unsigned int kpsc_mdctl_gpio;
//static unsigned int kpsc_mdstat_gpio;

#define UART1_BASE_  (0x01c00000 +0x20400)//

#define PSC_EPCPR (0x01C40000 +0x1070)
#define PSC_PTCMD (0x01C40000 +0x1120)
#define PSC_PTSTAT (0x01C40000 +0x1128)
#define PSC_PDSTAT (0x01C40000 +0x1200)
#define PSC_PDCTL (0x01C40000 +0x1300)
#define PSC_MDCTL_UART1 (0x01C40000 +0x1200)

#define GPIO_BASE (0x01C67000)
#define PINMUX_BASE (0x01C40000)

#define PSC_MDSTAT_UART1 (0x01C41850)
#define PSC_MDCTL_GPIO (0x01C41A68)
#define PSC_MDSTAT_GPIO (0x01C41868)


#define kuart1_base UART1_BASE_
#define kpsc_epcpr PSC_EPCPR
#define kpsc_ptcmd PSC_PTCMD
#define kpsc_ptstat PSC_PTSTAT
#define kpsc_pdstat PSC_PDSTAT
#define kpsc_pdctl  PSC_PDCTL
#define kpsc_mdctl_uart1 PSC_MDCTL_UART1
#define kpsc_mdstat_uart1 PSC_MDSTAT_UART1
#define kpsc_mdctl_gpio PSC_MDCTL_GPIO
#define kpsc_mdstat_gpio PSC_MDSTAT_GPIO
#define kpinmux_base PINMUX_BASE

 

 

//static inline void
static void
serial_out(unsigned int value, unsigned int reg)
{
 davinci_writel(value, reg );
}

//static inline unsigned int
static unsigned int
serial_in(unsigned int reg)
{
 unsigned int value;
 value = davinci_readl(reg);
 return value;
}

unsigned int serial_in_pwr (unsigned int offset)
{
 // FIXME read procedure to set
 return davinci_readl(offset);
}

unsigned int serial_out_pwr (unsigned int value, unsigned intoffset)
{
 return davinci_writel(value, offset);
}

#if 0
void phy_to_kern (void)
{
 kuart1_base  =(unsigned int)(ioremap(UART1_BASE_  , 0x22)); //34bytes
 kpsc_epcpr  =(unsigned int)(ioremap(PSC_EPCPR  , 0x04));//new
 kpsc_ptcmd   =(unsigned int)(ioremap(PSC_PTCMD  , 0x04));
 kpsc_ptstat   =(unsigned int)(ioremap(PSC_PTSTAT  , 0x04));
 kpsc_pdstat  =(unsigned int)(ioremap(PSC_PDSTAT  , 0x04));//new
 kpsc_pdctl  =(unsigned int)(ioremap(PSC_PDCTL  , 0x04));//new
 kpsc_mdctl_uart1 = (unsignedint)(ioremap(PSC_MDCTL_UART1, 0x04));
 kgpio_base   =(unsigned int)(ioremap(GPIO_BASE  , 0x20)); //32bytes
 kpinmux_base  = (unsignedint)(ioremap(PINMUX_BASE  , 0x08)); //8bytes
 
 
 kpsc_mdstat_uart1  = (unsignedint)(ioremap(PSC_MDSTAT_UART1, 0x04)); //for
 kpsc_mdctl_gpio   = (unsignedint)(ioremap(PSC_MDCTL_GPIO  , 0x04)); //forgpio
 kpsc_mdstat_gpio = (unsignedint)(ioremap(PSC_MDSTAT_GPIO , 0x04)); //for gpio
 
 debug_print3("kuart1_base 0x%x\n",kuart1_base    );
 debug_print3("kpsc_ptcmd 0x%x\n",kpsc_ptcmd     );
 debug_print3("kpsc_ptsta 0x%x\n",kpsc_ptstat    );
 debug_print3("kpsc_mdctl_uart1 0x%x\n",kpsc_mdctl_uart1);
 debug_print3("kgpio_base 0x%x\n",kgpio_base );
 debug_print3("kpinmux_base 0x%x\n",kpinmux_base );
 debug_print3("kpsc_mdctl_gpio 0x%x\n",kpsc_mdctl_gpio );
 debug_print3("kpsc_epcpr 0x%x\n",kpsc_epcpr     );
 debug_print3("kpsc_pdstat 0x%x\n",kpsc_pdstat    );
 debug_print3("kpsc_pdctl 0x%x\n",kpsc_pdctl     );
}
#endif

void poweron_uart1(void)
{
 unsigned int reg_mdctl_uart1, reg_ptcmd,reg_ptstat;
 unsigned int reg_epcpr, reg_pdstat, reg_pdctl;
 unsigned int reg_mdstat_uart1;
 
 //reg_epcpr    =serial_in(reg_epcpr ); //new
 //reg_pdstat    =serial_in(reg_pdstat);  //new
 //reg_pdctl    =serial_in(reg_pdctl );  //new

 //22Aug updated after finding that uartPWREMU_MGMT is still 0x3 and following values
 //RS485: kpsc_epcpr 0xc4860070
 //RS485: kpsc_pdstat 0xc4866200
 //RS485: kpsc_pdctl 0xc4868300
 
 //already there
 reg_mdctl_uart1  =serial_in(kpsc_mdctl_uart1);
 debug_print3("Before powering on reg_mdctl_uart1= 0x%x\n", reg_mdctl_uart1);
 reg_mdctl_uart1 |=0x03;               //Module Powerenabled                                   
 serial_out(reg_mdctl_uart1,kpsc_mdctl_uart1);                    
 
 //22Aug
 reg_pdstat = serial_in(kpsc_pdstat);
 debug_print3("reg_pdstat in poweron_uart1()s =0x%x\n", reg_pdstat);
 if (!(reg_pdstat & 0x01))
 {
   debug_print3("pdstat- off. Powering on...\n");
   reg_pdctl =serial_in(kpsc_pdstat);
   reg_pdctl |=0x01;
   serial_out(reg_pdctl,kpsc_pdctl);

   reg_ptcmd = serial_in(kpsc_ptcmd);
   reg_ptcmd =0x01;                                                
   serial_out(reg_ptcmd,kpsc_ptcmd);                               

   
   do                                                               
                                                                  
    reg_epcpr =serial_in(kpsc_epcpr);   
                                                                  
    while (!((reg_epcpr & 0x01) == 0));
   
   debug_print3("reg_epcpr done...\n");
    
    
    reg_pdctl= serial_in(kpsc_pdctl);   
    reg_pdctl|= 0x100;
    serial_out(reg_pdctl, kpsc_pdctl);
    
    
   do                                                               
                                                                  
    reg_ptstat =serial_in(kpsc_ptstat);                           
                                                                  
   while (!((reg_ptstat & 0x01) == 0));
   debug_print3("reg_ptstatdone...\n");
  }
  else
  {
   reg_ptcmd =serial_in(kpsc_ptcmd);                                 
   reg_ptcmd =0x01;                                                    
   serial_out(reg_ptcmd,kpsc_ptcmd);                                  

    
   do                                                               
                                                                  
    reg_ptstat =serial_in(kpsc_ptstat);                           
                                                                  
   while (!((reg_ptstat & 0x01) == 0));
   debug_print3("reg_ptstatdone...\n");
  }
  
  
  do
  {
   reg_mdstat_uart1= serial_in(kpsc_mdstat_uart1);
  }
  while (! ((reg_mdstat_uart1& 0x1F) == 0x03));
  debug_print3("reg_mdstat_uart1...\n");
 
   //alreadythere
  // reg_ptcmd = serial_in(kpsc_ptcmd);
  // reg_ptcmd =0x01;                                                
  // serial_out(reg_ptcmd,kpsc_ptcmd);                               
  // do                                                               
  //                                                                
  //  reg_ptstat =serial_in(kpsc_ptstat);                           
  //                                                                
  //  while (!((reg_ptstat & 0x01) ==0));                            
  debug_print3("Powering ON theUART1 moduleDone........\n");      
 
}

#if 0
static int enable_tranciver(DIR dir)
{
 unsigned int reg_outdata01;
 unsigned int one = 0x01;
 
 if (dir == TX)
 {
   reg_outdata01 =serial_in(kgpio_base + OUT_DATA01);
   debug_print3("TX:: OUT_DATA01= %x\n",reg_outdata01);
   reg_outdata01|=   (one<< TXRX_CTL_PIN);
   serial_out(reg_outdata01,kgpio_base + OUT_DATA01);
   reg_outdata01 =serial_in(kgpio_base + OUT_DATA01);
   debug_print3("TX:: OUT_DATA01= %x\n",reg_outdata01);
 }
 else if (dir == RX)
 {
   reg_outdata01 =serial_in(kgpio_base + OUT_DATA01);
   debug_print3("RX:: OUT_DATA01= %x\n",reg_outdata01);
   reg_outdata01&= 0xFDFFFFFF;
   //reg_outdata01&=   ~(one<< TXRX_CTL_PIN);
   debug_print3("RX:: regoutdata= %x\n",reg_outdata01);
   serial_out(reg_outdata01,kgpio_base + OUT_DATA01);
   reg_outdata01 =serial_in(kgpio_base + OUT_DATA01);
   debug_print3("RX:: OUT_DATA01= %x\n",reg_outdata01);
 }
 else
 {
  debug_print3("ERROR: wrongdirection %d", dir);
  return -1;
 }
 return 0;
}
#endif


static int poweron_gpio(void)
{
 unsigned int reg_mdctl_gpio, reg_ptcmd,reg_ptstat;
 unsigned int reg_epcpr, reg_pdstat, reg_pdctl;
 unsigned int reg_mdstat_gpio;


 
 
 reg_mdctl_gpio  =serial_in_pwr(kpsc_mdctl_gpio);
 reg_mdctl_gpio =0x03;               //Module Powerenabled                                   
 serial_out_pwr(reg_mdctl_gpio,kpsc_mdctl_gpio);                    
 
 //22Aug
 reg_pdstat = serial_in(kpsc_pdstat);
 debug_print3("reg_pdstat in poweron_gpio()s =0x%x\n", reg_pdstat);
 if (!(reg_pdstat & 0x01))
 {
   debug_print3("pdstat- off. Powering on...\n");
   reg_pdctl =serial_in(kpsc_pdstat);
   reg_pdctl |=0x01;
   serial_out(reg_pdctl,kpsc_pdctl);

   reg_ptcmd = serial_in(kpsc_ptcmd);
   reg_ptcmd =0x01;                                                
   serial_out(reg_ptcmd,kpsc_ptcmd);                               

   
   do                                                               
                                                                  
    reg_epcpr =serial_in(kpsc_epcpr);   
                                                                  
    while (!((reg_epcpr & 0x01) == 0));
   
   debug_print3("reg_epcpr done...\n");
    
    
    reg_pdctl= serial_in(kpsc_pdctl);   
    reg_pdctl|= 0x100;
    serial_out(reg_pdctl, kpsc_pdctl);
    
    
   do                                                               
                                                                  
    reg_ptstat =serial_in(kpsc_ptstat);                           
                                                                  
   while (!((reg_ptstat & 0x01) == 0));
   debug_print3("reg_ptstatdone...\n");
  }
  else
  {
   reg_ptcmd =serial_in(kpsc_ptcmd);                                 
   reg_ptcmd =0x01;                                                    
   serial_out(reg_ptcmd,kpsc_ptcmd);                                  

    
   do                                                               
                                                                  
    reg_ptstat =serial_in(kpsc_ptstat);                           
                                                                  
   while (!((reg_ptstat & 0x01) == 0));
   debug_print3("reg_ptstatdone...\n");
  }
  
  
  do
  {
   reg_mdstat_gpio= serial_in(kpsc_mdstat_gpio);
  }
  while (! ((reg_mdstat_gpio& 0x1F) == 0x03));
  debug_print3("reg_mdstat_gpio...\n");

                                                                   
  debug_print3("Powering ON the GPIO moduleDone........\n");      
 
   
 
  return 0;
}

#definePINMUX0  0x00)
#define PINMUX1  ( 0x04)


void config_gpio (void)
{
 unsigned int reg_pinmux0,reg_pinmux1;//reg_dir01, reg_outdata01;
 
 debug_print3("Config GPIOEntered....\n");      
 
 
  reg_pinmux0 = serial_in(kpinmux_base +PINMUX0);   //PINMUX 0
   debug_print3("PINMUX0 =%x\n",reg_pinmux0);
  reg_pinmux0 &=0xFFFCFFFF; //Disable ATA and HDIREN
  serial_out(reg_pinmux0,kpinmux_base +PINMUX0);
  reg_pinmux0 = serial_in(kpinmux_base +PINMUX0); 
   debug_print3("set PINMUX0 =%x\n",reg_pinmux0);
  reg_pinmux1 = serial_in(kpinmux_base +PINMUX1); 
   debug_print3("PINMUX1 =%x\n",reg_pinmux1);// PINMUX 1
  reg_pinmux1 |= 0x00000063; //Enable I2C, UART1 and UART0
  serial_out(reg_pinmux1, kpinmux_base +PINMUX1);           

   reg_pinmux1 =serial_in(kpinmux_base + PINMUX1); 
   debug_print3("set PINMUX1 =%x\n",reg_pinmux1);// PINMUX 1

#if 0
 
  reg_dir01 = serial_in(kgpio_base +DIR01);   
  debug_print2("DIR01 = %x\n",reg_dir01);
  reg_dir01 &=0xF9FFFFFF;     
  serial_out(reg_dir01, kgpio_base + DIR01);
  reg_dir01 = serial_in(kgpio_base +DIR01);   
  debug_print2("DIR01 = %x\n",reg_dir01);
 
 
 
  reg_outdata01 = serial_in(kgpio_base +OUT_DATA01);
  debug_print2("OUT_DATA01 =%x\n",reg_outdata01);
  reg_outdata01&=  0xFBFFFFFF;
  reg_outdata01|=  0x02000000;  
  serial_out(reg_outdata01 ,kgpio_base +OUT_DATA01);
  reg_outdata01 = serial_in(kgpio_base +OUT_DATA01);
  debug_print2("OUT_DATA01 =%x\n",reg_outdata01);

  debug_print1("Configuring GPIODone........\n");      
#endif


}

void reset_dlab (void)
{
 unsigned int reg_lcr;
 //reg_lcr = 0x00;
 //serial_out(reg_lcr, kuart1_base + LCR);
  
 
  reg_lcr = serial_in(kuart1_base +0xc);  // For R/W of IERregister
  debug_print3("LCR = %x\n",reg_lcr);
  reg_lcr &= 0x7F;
  serial_out(reg_lcr, kuart1_base +0xc);   
  reg_lcr = serial_in(kuart1_base +0xc);  // For R/W of IERregister
  debug_print3("LCR = %x\n",reg_lcr);
}


void disable_interrupt (void)
{
 unsigned int reg_IER;
 
 
 reset_dlab();
 
 
  reg_IER = 0x0;
  serial_out(reg_IER , kuart1_base + 0x4);
 
}

void set_dlab (void)
{
 unsigned int reg_lcr;
 
 //reg_lcr = 0x80;
 //serial_out(reg_lcr, kuart1_base + LCR);
 
  reg_lcr = serial_in(kuart1_base +0xc);  // For R/W of DLL...registers
  debug_print3("LCR = %x\n",reg_lcr);
  reg_lcr |=(1<<7);
  serial_out(reg_lcr, kuart1_base + 0xc);
  reg_lcr = serial_in(kuart1_base +0xc);  // For R/W of DLL...registers
  debug_print3("LCR = %x\n",reg_lcr);
   
 
}

void set_baud_rate (void)
{
 unsigned int reg_dll, reg_dlh;
 
 
 set_dlab();
 
 
 reg_dll =0x0F;   
 serial_out(reg_dll, kuart1_base + 0x20);
 
 reg_dlh = 0x00;
 serial_out(reg_dlh , kuart1_base +0x24); 
}

 

void config_fifo(unsigned int enable)
{
 //FCR (RO) and IIR (WO) share address : DLAB =x
 unsigned int reg_fcr;
 
 
  reg_fcr = serial_in(kuart1_base + 0x8);
  if(enable)
   reg_fcr |=0x00000001;  // Enable FIFO
  else
   reg_fcr &=0xFFFFFFFE;  // DisableFIFO
  serial_out(reg_fcr, kuart1_base + 0x8);
  
}


void set_protocol(void)
{
 unsigned int reg_lcr, reg_mcr;

 //If loopback is enabled TX,RX data can beverified
#ifdef LOOPBACK
 reg_mcr = 0x00000010;
  serial_out(reg_mcr, kuart1_base + 0x10);
#else
 reg_mcr = 0x00000000;
  serial_out(reg_mcr, kuart1_base + 0x10);
#endif 

 
  reg_lcr =0x00000003;  // No Parity, 1 stopbit, 8-bit data.
  serial_out(reg_lcr, kuart1_base + 0xc);
 
}



void reset_uart1(void)
{
  unsigned int reg_pwremu_mgmt;//, delay;
 
  reg_pwremu_mgmt = 0x0001;  //Reset
  serial_out(reg_pwremu_mgmt, kuart1_base +0x30);      //UTRST = 1 - tx is active
 
  reg_pwremu_mgmt |=(1<<14 |1<<13 |1<<0);  // Enable txand rx and FREE
  serial_out(reg_pwremu_mgmt, kuart1_base +0x30);      //UTRST = 1 - tx is active
 
}


void enable_interrupt(void)
{
 unsigned int reg_IER;
 
 
 reset_dlab();
 
 
  reg_IER = 0x3;
  serial_out(reg_IER , kuart1_base + 0x4); 
  debug_print3("Enabling InterruptDone...\n");

}

 

void check_reg(void)
{
 unsigned intreg_mdctl_uart1,reg_ptstat,reg_mdctl_gpio,reg_ptcmd,reg_pinmux0,reg_pinmux1,reg_dir01,reg_outdata01,reg_dll;
 
 unsigned int reg_dlh,reg_mcr,reg_lcr,reg_pwremu_mgmt,reg_mdstat_uart1,reg_mdstat_gpio,reg_lsr;//reg_fcr,
 
 unsigned int reg_epcpr, reg_pdstat, reg_pdctl;
 

 reg_mdctl_uart1  =serial_in(kpsc_mdctl_uart1);
 reg_epcpr    =serial_in(kpsc_epcpr ); //new
 reg_pdstat    =serial_in(kpsc_pdstat);  //new
 reg_pdctl    =serial_in(kpsc_pdctl );  //new
 reg_ptstat    =serial_in(kpsc_ptstat);
 reg_mdctl_gpio  = serial_in_pwr(kpsc_mdctl_gpio);
 reg_ptcmd     =serial_in_pwr(kpsc_ptcmd);
 reg_ptstat    =serial_in_pwr(kpsc_ptstat);
 reg_pinmux0   =serial_in(kpinmux_base +0);   // PINMUX0
 reg_pinmux1   =serial_in(kpinmux_base +0x04);   //PINMUX 1
 //reg_dir01    =serial_in(kgpio_base + 0x10);
 //reg_outdata01  = serial_in(kgpio_base +0x14);
 reg_mdstat_uart1 =serial_in(kpsc_mdstat_uart1);
 reg_mdstat_gpio =serial_in(kpsc_mdstat_gpio);
 
 //reg_fcr = serial_in(kuart1_base + FCR);
 reg_mcr = serial_in(kuart1_base + 0x10);
 reg_lcr = serial_in(kuart1_base + 0xc);
 reg_pwremu_mgmt  =serial_in(kuart1_base + 0x30); 
 
 //set_dlab();
 reg_dll = serial_in(kuart1_base +0x20); // Low byte
 reg_dlh = serial_in(kuart1_base +0x24); // High byte
 reg_lsr = serial_in((volatile unsignedint)kuart1_base + 0x14);
 
 debug_print3("reg_mdctl_uart1 =0x%x\n",reg_mdctl_uart1  );
 debug_print3("reg_epcpr    =0x%x\n",reg_epcpr     );
 debug_print3("reg_pdstat   =0x%x\n",reg_pdstat    );
 debug_print3("reg_pdctl    =0x%x\n",reg_pdctl     );
 debug_print3("reg_ptstat   =0x%x\n",reg_ptstat    );
 debug_print3("reg_mdctl_gpio  = 0x%x\n",reg_mdctl_gpio  );
 debug_print3("reg_ptcmd    =0x%x\n",reg_ptcmd     );
 debug_print3("reg_pinmux0    =0x%x\n",reg_pinmux0    );
 debug_print3("reg_pinmux1    =0x%x\n",reg_pinmux1    );
 debug_print3("reg_dir01    = 0x%x\n",reg_dir01    );
 debug_print3("reg_outdata01   = 0x%x\n",reg_outdata01  );
 debug_print3("reg_dll = 0x%x\n", reg_dll);
 debug_print3("reg_dlh = 0x%x\n", reg_dlh);
 //debug_print1("reg_fcr = 0x%x\n",reg_fcr);
 debug_print3("reg_mcr = 0x%x\n", reg_mcr);
 debug_print3("reg_lcr = 0x%x\n", reg_lcr);
 debug_print3(" reg_pwremu_mgmt =0x%x\n", reg_pwremu_mgmt);
 debug_print3(" reg_mdstat_uart1= 0x%x\n", reg_mdstat_uart1);
 debug_print3(" reg_mdstat_gpio =0x%x\n", reg_mdstat_gpio);
 debug_print3(" LSR = 0x%x\n",reg_lsr);
 
 

}

 
static ssize_t device_read(struct file *fp, char *buffer, size_tlen, loff_t *offset)
{
  unsigned int reg_lsr,reg_iir, reg_ier;
  unsigned char byte = 0x42;//=*(int*)buffer;
  unsigned int count = 0;
  int retval;
  //TODO: get no. of byte to be read from user dorelated stuffs.
 
 
 reset_dlab();

#ifdef BOARD_DVPB
 enable_tranciver(RX);
#endif
 
 
 //do
  //{
  // reg_iir =serial_in(kuart1_base + IIR);
  // //mdelay(1000);
  //}
 //while (((reg_iir & 0x0000000E)!= 0x04));
 //while (((reg_iir & 0x0000000E)!= 0x02));
 
 // Wait till the transmit FIFO isempty                                  
 do
  {
   // Read the Status Register tocheck if the Transmit FIFO isempty    
   reg_lsr = serial_in((volatileunsigned int)kuart1_base + 0x14);
   //debug_print3("Kernellsr...0x%x\n",reg_lsr);
    reg_lsr =reg_lsr & 0x01;
   count++;
  }
  while((reg_lsr != 0x01) || (count< 10000));

 
 reg_ier = serial_in(kuart1_base + 0x04);
 reg_iir = serial_in(kuart1_base + 0x08);
 debug_print3("IIR 0x%x, IER0x%x\n",reg_iir,reg_ier);
  
  byte = serial_in(kuart1_base + 0);
  debug_print3("KERNEL: byte read =%x\n\n\n",byte);
 
  
 if ( ( retval = copy_to_user ( (void __user*)buffer,&byte, sizeof(char) ) ) == -1)
  debug_print3("ERROR: incopy_to_user inside device_write\n" );
 

  return 1;
}



static ssize_t device_write(struct file *file, const char __user*buff,size_t count, loff_t *offp)
{
  unsigned char byte,reg_lsr ;//=*(int*)buffer;
 unsigned int count1 = 0;
  int retval;
 
 reset_dlab();
 
#ifdef BOARD_DVPB
 //enable_tranciver(TX);
#endif

 
 if(( retval = copy_from_user (&byte, (void __user *) buff, count ) ) == -1)
 debug_print3("ERROR: in copy_from_user insidedevice_write\n" );

 //unsigned long copy_from_user(void *to,constvoid __user *from,unsigned long count);
 debug_print3("anger To be sentbyte:%c\n",byte);
 
 // Wait till the transmit FIFO isempty                                  
 do
   {
    // Read the Status Registerto check if the Transmit FIFO isempty    
  reg_lsr = serial_in((volatile unsignedint)kuart1_base + 0x14);
  //debug_print3("Kernellsr...0x%x\n",reg_lsr);
     reg_lsr = reg_lsr & 0x20;
    count1++;
   }
   while(reg_lsr!=0x20);
 
 debug_print3("Count afterlsr!=0x20...0x%x\n",count1);
 serial_out(byte, kuart1_base + 0);
  return 1;
}


static int device_open(struct inode *inod, struct file *fp)
{
 
  printk("device_openentered...\n" );  
 
  //  If devie is opened returnbusy status
 // if (Opened)
 //   return-EBUSY;
  //else
  {
   Opened=1;


 
  // Remapping physical adress tokernel space
   //phy_to_kern();
 
   
  poweron_gpio();  
 
 
 poweron_uart1();
   
   
   config_gpio();

 
   
 disable_interrupt ();
 
   
 set_baud_rate();
  
   
   //in fops...
   
   
  config_fifo(0);//DISABLE
    
   
   set_protocol();
   
   
   reset_uart1();
   
   
   enable_interrupt();
   
   
   check_reg();
   
  }
 
 return 0;
}


static struct file_operations uart1_fops = {
   .owner  = THIS_MODULE,
   .read  =device_read,  
   .write  = device_write,
   .open  =device_open, 
 .release  = NULL,
};

static void max485_setup_cdev(struct max485_chip_info *dev,intindex)
{
      int err,max485_dev=MKDEV(Major,index);
      cdev_init(&dev->cdev,&uart1_fops);
      dev->cdev.owner=THIS_MODULE;
      err=cdev_add(&dev->cdev,max485_dev,1);
      if(err)
             printk(KERN_NOTICE "error %d adding max485 %d/n",err,index);
}

int __init init_module(void)
{
  //Registering device
 
 int err=0;
 int result;
  dev_t max485_dev;
  struct max485_chip_info*chip; 

    if(!(chip = kzalloc(sizeof(struct max485_chip_info), GFP_KERNEL))){
           err = -ENOMEM;
          return err;
     }
   
  if(Major)
               {
                       result=register_chrdev_region(max485_dev,1,DRIVER_NAME);
               }
               else{
                       result=alloc_chrdev_region(&max485_dev,0,1,DRIVER_NAME);
                       Major=MAJOR(max485_dev);
                    debug_print3( "Major %d\n", Major);
               }
               if (result < 0) {
                       debug_print3( "Unable to get Major region, error %d\n",result);
                err=result;
                 
               }
              max485_setup_cdev(chip,0);
   max485_class =class_create(THIS_MODULE, "max485");
        if(IS_ERR(max485_class))
       {
           printk("Err: failed in creating max485_class\n");
  kfree(chip);
           return -1;
       }
        debug_print3("start device_class for max485\n");
        class_device_create( max485_class, NULL, max485_dev, 0,"max485""%d",0);
         debug_print3 (KERN_INFO "Registered character driverpcf8574a  sensor\n");

   return err;
}

void __exit cleanup_module(void)
{
 //int ret;
 
  //iounmap((void *)kuart1_base  );
 //iounmap((void *) kpsc_ptcmd );
 //iounmap((void *) kpsc_ptstat );
 //iounmap((void *)kpsc_mdctl_uart1  );
 //iounmap((void *) kgpio_base );
 //iounmap((void *) kpinmux_base );
 //iounmap((void *) kpsc_mdctl_gpio);
  //  Unregister device
  
   device_destroy(max485_class, MKDEV(Major, 0));
   class_destroy(max485_class);
       unregister_chrdev_region(MKDEV(Major, 0), 1);

}

module_init(init_module);
module_exit(cleanup_module);

MODULE_DESCRIPTION("PCF8574A erternal IO");
MODULE_AUTHOR("Wang, <@.com>");
MODULE_LICENSE("GPL");

 

应用程序:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include "ioport-pcf8574a.h"
#include <sys/ioctl.h>

static int set_opt(int fd,int nSpeed, int nBits, char nEvent,int nStop)
{
 struct termios newtio,oldtio;
 if ( tcgetattr( fd,&oldtio) != 0)//取属性(termios结构);
 {
  perror("SetupSerial1\n\r");
  return -1;
 }
 
 bzero( &newtio, sizeof( newtio ));
 newtio.c_cflag |= CLOCAL | CREAD;
 newtio.c_cflag &= ~CSIZE;

 switch( nBits )
 {
  case 7:
  newtio.c_cflag |= CS7;
  break;
  case 8:
  newtio.c_cflag |= CS8;
  break;
 }

 switch( nEvent )
 {
  case 'O':
  newtio.c_cflag |= PARENB;
  newtio.c_cflag |= PARODD;
  newtio.c_iflag |= (INPCK |ISTRIP);
  break;
  case 'E':
  newtio.c_iflag |= (INPCK |ISTRIP);
  newtio.c_cflag |= PARENB;
  newtio.c_cflag&= ~PARODD;
  break;
  case 'N':
  newtio.c_cflag&= ~PARENB;
  break;
 }

 switch( nSpeed )
 {
  case 1200:
   cfsetispeed(&newtio,B1200);
   cfsetospeed(&newtio,B1200); 
   break;
  case 2400:
   cfsetispeed(&newtio,B2400);//设置输入速度
   cfsetospeed(&newtio,B2400);//设置输出速度
   break;
  case 4800:
   cfsetispeed(&newtio,B4800);
   cfsetospeed(&newtio,B4800);
   break;
  case 9600:
   cfsetispeed(&newtio,B9600);
   cfsetospeed(&newtio,B9600);
   break;
  case 19200:
   cfsetispeed(&newtio,B19200);
   cfsetospeed(&newtio,B19200);
   break;
  case 38400:
   cfsetispeed(&newtio,B38400);
   cfsetospeed(&newtio,B38400);
   break;
  case 57600:
   cfsetispeed(&newtio,B57600);
   cfsetospeed(&newtio,B57600);
   break;
  case 115200:
   cfsetispeed(&newtio,B115200);
   cfsetospeed(&newtio,B115200);
   break;
  default:
   cfsetispeed(&newtio,B9600);
   cfsetospeed(&newtio,B9600);
   break;
 }

 if( nStop== 1 )
  newtio.c_cflag&= ~CSTOPB;
 else if ( nStop == 2 )
  newtio.c_cflag |= CSTOPB;
 newtio.c_cc[VTIME] = 0;
 newtio.c_cc[VMIN] = 0;
 tcflush(fd,TCIFLUSH);//刷清未决输入和/或输出;
 if((tcsetattr(fd,TCSANOW,&newtio))!=0)//设置属性(termios结构);
 {
  printf("com set error=%d\n\r",(tcsetattr(fd,TCSANOW,&newtio)));
  return -1;
 }
 printf("set done!\n");

 return 0;
}


static int open_port(int fd,int comport)
{
 char*dev[]={"/dev/tts/0","/dev/tts/1","/dev/ttyS2"};
 long vdisable;
 if (comport==1)
 {
  fd = open( "/dev/ttyS0",O_RDWR|O_NOCTTY|O_NDELAY);
  if (-1 == fd){
  perror("Can't Open SerialPort");
  return(-1);
  }
  else
  printf("open ttyS0.....\n");
 }
 else if(comport==2)
 {
  fd = open( "/dev/ttyS1",O_RDWR|O_NOCTTY|O_NDELAY);
  //fd = open( "/dev/ttyS1",O_RDWR);
  if (-1 == fd){
  perror("Can't Open SerialPort");
  return(-1);
  }
  else
  printf("open ttyS1.....\n");
 }
 else if (comport==3)
 {
  fd = open( "/dev/ttyS2",O_RDWR|O_NOCTTY|O_NDELAY);
  if (-1 == fd){
  perror("Can't Open SerialPort");
  return(-1);
  }
  else
  printf("open ttyS2.....\n");
 }
 //
 if(fcntl(fd, F_SETFL, 0)<0)
  printf("fcntlfailed!\n");
 else
  printf("fcntl=%d\n",fcntl(fd,F_SETFL,0));
 if(isatty(STDIN_FILENO)==0)
  printf("standard input is not aterminal device\n");
 else
  printf("isattysuccess!\n");
 printf("fd-open=%d\n",fd);
 return fd;
}


int main(int argc, char *argv[])
{
 int fd;
 int fdio;
 int nread,i;
 unsigned char iord;
 char buff[]="Hello anger\n";
 char rbuff[128];
 int rs485_dev;
 printf("test uart\n\r");
 
 if((fd=open_port(fd,2))<0)
 {
  printf("open_porterror\n\r");
  return -1;
 
 
 printf("start set\n\r");
 if((i=set_opt(fd,57600,8,'N',1))<0)
 {
  printf("set_opterror\n\r");
  return;
 }
 printf("fd=%d\n\r",fd);


 fdio = open("/dev/exioport0",O_RDWR);
 if (-1 == fdio){
  perror("Can't Open ioPort");
  return(-1);
  }
 

 ioctl(fdio,EX_GPIO_CONTROL_MAX485_HIGH);
 ioctl(fdio,EX_GPIO_READ_PORT,&iord);
 printf("ioctl read data=0x%x\n\r",iord);

 ioctl(fdio,EX_GPIO_CONTROL_MAX485_LOW);
 ioctl(fdio,EX_GPIO_READ_PORT,&iord);
 printf("ioctl read data=0x%x\n\r",iord);
 
 
 while(1)
 {
  nread =0;
  nread=read(fd,rbuff,128);
  if(nread)
  {
   printf("read=%d,%s\n\r",nread,rbuff);
   
   ioctl(fdio,EX_GPIO_CONTROL_MAX485_HIGH);
   write(fd,buff,12);
   usleep(100000);
   usleep(100000);
   usleep(100000);
   ioctl(fdio,EX_GPIO_CONTROL_MAX485_LOW);
  }
 
 }

 //close(fd);
 //close(fdio);
 return;
}


0 0