📄 hal_pxa.c
字号:
/************************************************************
* 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 + -