⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal_pxa.c

📁 usb isp1761驱动源代码 可编进内核。
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************
 * Philips ISP176x Hardware Abstraction Layer code file
 *
 * (c) 2002 Koninklijke Philips Electronics N.V. All rights reserved. <usb.linux@philips.com>
 *
 * 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 program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * File Name: hal_x86.c
 *
 * Refering linux kernel version 2.6.9
 *
 * History:
 *
 * Date                Author                  Comments
 * ---------------------------------------------------------------------
 * Nov 29 2005        Prabhakar Kalasani      Initial Creation     
 *
 **********************************************************************
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>  
#include <linux/usb.h>
#include <linux/poll.h>
#include <linux/platform_device.h>
#include <linux/vmalloc.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/unaligned.h>
#include <asm/dma.h>

/*--------------------------------------------------------------*
 *               linux system include files
 *--------------------------------------------------------------*/
#include "hal_x86.h" // We can use the x86 headers for now.
#include "../hal/hal_intf.h"
#include "../hal/isp1761.h"

/*--------------------------------------------------------------*
 *               Local variable Definitions
 *--------------------------------------------------------------*/
struct isp1761_dev              isp1761_loc_dev[ISP1761_LAST_DEV];
static  struct isp1761_hal      hal_data;
static struct platform_device *s_pdev;
int      iolength = 0;
static   __u32            isp1761_base = 0;

/*--------------------------------------------------------------*
 *               Local # Definitions
 *--------------------------------------------------------------*/
#define         isp1761_driver_name     "1761-m6"
#define         ISP1761_IO_EXTENT ((1 << 17)-1) // 17 address bits used.
#define         ISP1761_REGSET_LEN   0xffff

#undef CONFIG_PM /* PM no workie yet. */

/*--------------------------------------------------------------*
 *               Local Function 
 *--------------------------------------------------------------*/

static int __devexit isp1761_remove (struct platform_device *pdev);
static int __devinit isp1761_probe (struct platform_device *pdev);
#ifdef CONFIG_PM
static int isp1761_pci_suspend (struct pci_dev *dev, __u32 state);
static int isp1761_pci_resume (struct pci_dev *dev);
#endif
static irqreturn_t  isp1761_pci_isr (int irq, void *dev_id);


/*--------------------------------------------------------------*
 *              ISP 1761 interrupt locking functions
 *--------------------------------------------------------------*/
int             isp1761_hw_lock = 0;
int             isp1761_hw_isr = 0;

void isp1761_disable_interrupt(int      irq) {
    /* DUMMY functions
     * Not used */
    disable_irq(irq);
    return;
}
void isp1761_enable_interrupt(int       irq) {
    /* DUMMY functions
     * Not used */
    enable_irq(irq);
    return;
}

/*--------------------------------------------------------------*
 *               ISP1761 Interrupt Service Routine
 *--------------------------------------------------------------*/
/*Interrupt Service Routine for device controller*/
irqreturn_t isp1761_pci_dc_isr(int irq, void *data)
{
    struct isp1761_dev *dev;
    dev = &isp1761_loc_dev[ISP1761_DC];

    hal_entry("%s: Entered\n",__FUNCTION__);
    /*not ready yet*/
    if(dev->active == 0)
    {
        printk("isp1761_pci_dc_isr: dev->active is NULL \n");
        return IRQ_NONE;
    }

    /* Get the source of interrupts for Device Controller
     * Device Controller interrupts are cleared by the driver
     * during processing
     */

    /*unblock the device interrupt*/

    isp1761_reg_write32(dev, DEV_UNLOCK_REGISTER, 0xaa37);
    dev->int_reg = isp1761_reg_read32(dev, DEV_INTERRUPT_REGISTER, dev->int_reg);
    hal_int("isp1761_pci_dc_isr:INTERRUPT_REGISTER 0x%x\n",dev->int_reg);
    /*clear the interrupt source*/
    isp1761_reg_write32(dev, 0x218, dev->int_reg);
    dev->int_reg &= 0x03fffdb9;
    if(dev->int_reg)
        dev->handler(dev, dev->isr_data);
    hal_entry("%s: Exit\n",__FUNCTION__);
    return IRQ_HANDLED;
}

/* Interrupt Service Routine of isp1761                                   
 * Reads the source of interrupt and calls the corresponding driver's ISR.
 * Before calling the driver's ISR clears the source of interrupt.
 * The drivers can get the source of interrupt from the dev->int_reg field
 */
irqreturn_t     isp1761_pci_isr(int irq, void *__data) 
{
    __u32               irq_mask = 0;
    struct isp1761_dev  *dev;
    hal_entry("%s: Entered\n",__FUNCTION__);
    /* Process the Host Controller Driver */
    dev = &isp1761_loc_dev[ISP1761_HC];
    /* Get the source of interrupts for Host Controller*/
    dev->int_reg = isp1761_reg_read32(dev, HC_INTERRUPT_REG,dev->int_reg);
    isp1761_reg_write32(dev,HC_INTERRUPT_REG,dev->int_reg);
    irq_mask = isp1761_reg_read32(dev, HC_INTENABLE_REG,irq_mask);

    dev->int_reg &= irq_mask; /*shared irq ??*/
    /*call the Host Isr if any valid(minus otg)interrupt is present*/
    if(dev->int_reg & ~HC_OTG_INTERRUPT)                
        dev->handler(dev,dev->isr_data);
#ifdef OTG
#ifndef MSEC_INT_BASED
    mdelay(1);
#endif
    /*process otg interrupt if there is any*/
    if(dev->int_reg & HC_OTG_INTERRUPT){
        u32     otg_int;        
#ifndef MSEC_INT_BASED
        mdelay(1);
#endif
        otg_int = (dev->int_reg & HC_OTG_INTERRUPT);
        /* Process OTG controller Driver 
         * Since OTG is part of  HC interrupt register, 
         * the interrupt source will be HC interrupt Register
         * */
        dev = &isp1761_loc_dev[ISP1761_OTG];
        /* Read the source of  OTG_INT and clear the
           interrupt source */
        dev->int_reg = otg_int; 
        dev->handler(dev, dev->isr_data,r);
    }   
#endif
    hal_entry("%s: Exit\n",__FUNCTION__);
    return IRQ_HANDLED;
} /* End of isp1362_pci_isr */

/*--------------------------------------------------------------*
 *               PCI Driver Interface Functions
 *--------------------------------------------------------------*/

/* Pci driver interface functions */
static struct platform_driver isp1761_platform_driver = {
probe:         isp1761_probe,
remove:        isp1761_remove,
driver:        { .name = "isp1761" }
};


/*--------------------------------------------------------------*
 *               ISP1761 Read write routine 
 *--------------------------------------------------------------*/

/* Write a 32 bit Register of isp1761 */
void isp1761_reg_write32(struct isp1761_dev *dev,__u16 reg,__u32 data)
{ 
    /* Write the 32bit to the register address given to us*/
    writel(data,dev->baseaddress+reg);
    //printk("Wrote to 0x%08x value 0x%08x\n", isp1761_base + reg, data);
}


/* Read a 32 bit Register of isp1761 */
__u32 isp1761_reg_read32(struct isp1761_dev *dev,__u16 reg,__u32 data)
{ 

    data = readl(dev->baseaddress + reg);
    //printk("Read from 0x%08x is 0x%08x\n", isp1761_base + reg, data);
    return data;
}


/* Read a 16 bit Register of isp1761 */
__u16 isp1761_reg_read16(struct isp1761_dev *dev,__u16 reg,__u16 data)
{ 
    data = readw(dev->baseaddress+reg);
    return data;
}

/* Write a 16 bit Register of isp1761 */
void isp1761_reg_write16(struct isp1761_dev *dev,__u16 reg,__u16 data)
{ 
    //printk("Wrote to 0x%08x value 0x%04x\n", isp1761_base + reg, data);
    writew(data,dev->baseaddress+reg);

}

/*--------------------------------------------------------------*
 *  
 * Module dtatils: isp1761_mem_read
 *
 * Memory read using PIO method.
 *
 *  Input: struct isp1761_driver *drv  -->  Driver structure.
 *                      __u32 start_add     --> Starting address of memory 
 *              __u32 end_add     ---> End address 
 *              
 *              __u32 * buffer      --> Buffer pointer.
 *              __u32 length       ---> Length 
 *              __u16 dir          ---> Direction ( Inc or Dec)
 *                      
 *  Output     int Length  ----> Number of bytes read 
 *
 *  Called by: system function 
 * 
 * 
 *--------------------------------------------------------------*/
/* Memory read function PIO */

int     
isp1761_mem_read(struct isp1761_dev *dev, __u32 start_add, 
        __u32 end_add, __u32 * buffer, __u32 length, __u16 dir)
{
    u8 *temp_base_mem = 0;      
    u8 *one = (u8 *) buffer;
    u16 *two = (u16 *) buffer;
    int a = (int)length;
    u32 w;
    temp_base_mem= (dev->baseaddress + start_add);
    /*initialize the Register 0x33C-used to manage Multiple threads */
    writel(start_add,dev->baseaddress+0x33c);

last:
    w = readl(temp_base_mem);
    if(a == 1){
        *one=(u8)w;
        return 0;
    }
    if(a == 2){
        *two=(u16)w;
        return 0;
    }   


    if(a == 3){
        *two=(u16)w;
        two += 1;
        w >>= 16;
        *two = (u8)(w);
        return 0;

    }


    while(a>0){
        *buffer = w;
        temp_base_mem = temp_base_mem+4;
        start_add +=4;
        a -= 4;
        if(a == 0)
            break;
        if(a < 4){
            buffer += 1;
            one = (u8 *)buffer;
            two = (u16 *)buffer;
            goto last;
        }
        buffer += 1;
        w = readl(temp_base_mem); 
    }
    return ((a < 0) || (a == 0))?0:(-1);

}

/*--------------------------------------------------------------*
 *  
 * Module dtatils: isp1761_mem_write
 *
 * Memory write using PIO method.
 *
 *  Input: struct isp1761_driver *drv  -->  Driver structure.
 *                      __u32 start_add     --> Starting address of memory 
 *              __u32 end_add     ---> End address 
 *              
 *              __u32 * buffer      --> Buffer pointer.
 *              __u32 length       ---> Length 
 *              __u16 dir          ---> Direction ( Inc or Dec)
 *                      
 *  Output     int Length  ----> Number of bytes read 
 *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -