X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/f911e79d724fdac3af2847cec6383a71e907b00a..9c8ab08d7e8fca3916a7f91a3c001d151989137c:/lincan/src/pcan_dongle.c diff --git a/lincan/src/pcan_dongle.c b/lincan/src/pcan_dongle.c index 6bd3496..386725b 100644 --- a/lincan/src/pcan_dongle.c +++ b/lincan/src/pcan_dongle.c @@ -1,32 +1,42 @@ -/****************************************************************************/ -// Ingenieria Almudi (www.almudi.com) -// Ported to LinCAN by Jose Pascual Ramírez (josepascual@almudi.com) -// -// -// Copyright (C) 2001,2002,2003,2004 PEAK System-Technik GmbH -// -// linux@peak-system.com -// www.peak-system.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., 675 Mass Ave, Cambridge, MA 02139, USA. -// -// Maintainer(s): Klaus Hitschler (klaus.hitschler@gmx.de) -// -// Contributions: Marcel Offermans (marcel.offermans@luminis.nl) -// Philipp Baer (philipp.baer@informatik.uni-ulm.de) -/****************************************************************************/ +/**************************************************************************/ +/* File: pcan_dongle.h - PEAK's printer port dongle addapter */ +/* */ +/* LinCAN - (Not only) Linux CAN bus driver */ +/* Copyright (C) 2002-2009 DCE FEE CTU Prague */ +/* Copyright (C) 2002-2009 Pavel Pisa */ +/* Copyright (C) 2005 Klaus Hitschler */ +/* Copyright (C) 2005-2006 Jose Pascual Ramírez */ +/* Copyright (C) 2001,2002,2003,2004 PEAK System-Technik GmbH */ +/* Funded by OCERA and FRESCOR IST projects */ +/* Based on CAN driver code by Arnaud Westenberg */ +/* Contributions: Marcel Offermans */ +/* Philipp Baer */ +/* */ +/* LinCAN is free software; you can redistribute it and/or modify it */ +/* under terms of the GNU General Public License as published by the */ +/* Free Software Foundation; either version 2, or (at your option) any */ +/* later version. LinCAN 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 LinCAN; see file */ +/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */ +/* Cambridge, MA 02139, USA. */ +/* */ +/* To allow use of LinCAN in the compact embedded systems firmware */ +/* and RT-executives (RTEMS for example), main authors agree with next */ +/* special exception: */ +/* */ +/* Including LinCAN header files in a file, instantiating LinCAN generics */ +/* or templates, or linking other files with LinCAN objects to produce */ +/* an application image/executable, does not by itself cause the */ +/* resulting application image/executable to be covered by */ +/* the GNU General Public License. */ +/* This exception does not however invalidate any other reasons */ +/* why the executable file might be covered by the GNU Public License. */ +/* Publication of enhanced or derived LinCAN files is required although. */ +/**************************************************************************/ + /****************************************************************************/ // @@ -105,11 +115,11 @@ #define ECR_PORT_SIZE 1 // size of the associated ECR register #define DNG_DEFAULT_COUNT 4 // count of defaults for init -typedef void (*PARPORT_IRQ_HANLDER)(int, void *, struct pt_regs *); +typedef void (*PARPORT_IRQ_HANLDER)(CAN_IRQ_HANDLER_ARGS(irq_number, dev_id)); /****************************************************************************/ // GLOBALS -spinlock_t pcan_lock = SPIN_LOCK_UNLOCKED; +CAN_DEFINE_SPINLOCK(pcan_lock); /****************************************************************************/ // LOCALS @@ -140,13 +150,13 @@ char dongle_type[] = "epp_dongle"; static void _parport_disable_irq(struct DONGLE_PORT *dng) { u16 _PC_ = (u16)dng->dwPort + 2; - outb(inb(_PC_) & ~0x10, _PC_); + can_outb(can_inb(_PC_) & ~0x10, _PC_); } static void _parport_enable_irq(struct DONGLE_PORT *dng) { u16 _PC_ = (u16)dng->dwPort + 2; - outb(inb(_PC_) | 0x10, _PC_); + can_outb(can_inb(_PC_) | 0x10, _PC_); } @@ -157,29 +167,20 @@ static u8 pcan_dongle_sp_readreg(struct DONGLE_PORT *dng, u8 port) // read a reg u16 _PB_ = _PA_ + 1; u16 _PC_ = _PB_ + 1; u8 b0, b1 ; - u8 irqEnable = inb(_PC_) & 0x10; // don't influence irqEnable - unsigned long flags; - - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) - save_flags(flags); - cli(); - #else - spin_lock_irqsave(&pcan_lock, flags); - #endif - - outb((0x0B ^ 0x0D) | irqEnable, _PC_); - outb((port & 0x1F) | 0x80, _PA_); - outb((0x0B ^ 0x0C) | irqEnable, _PC_); - b1=nibble_decode[inb(_PB_)>>3]; - outb(0x40, _PA_); - b0=nibble_decode[inb(_PB_)>>3]; - outb((0x0B ^ 0x0D) | irqEnable, _PC_); - - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) - restore_flags(flags); - #else - spin_unlock_irqrestore(&pcan_lock, flags); - #endif + u8 irqEnable = can_inb(_PC_) & 0x10; // don't influence irqEnable + can_spin_irqflags_t flags; + + can_spin_lock_irqsave(&pcan_lock, flags); + + can_outb((0x0B ^ 0x0D) | irqEnable, _PC_); + can_outb((port & 0x1F) | 0x80, _PA_); + can_outb((0x0B ^ 0x0C) | irqEnable, _PC_); + b1=nibble_decode[can_inb(_PB_)>>3]; + can_outb(0x40, _PA_); + b0=nibble_decode[can_inb(_PB_)>>3]; + can_outb((0x0B ^ 0x0D) | irqEnable, _PC_); + + can_spin_unlock_irqrestore(&pcan_lock, flags); return (b1 << 4) | b0 ; } @@ -188,27 +189,18 @@ static void pcan_dongle_writereg(struct DONGLE_PORT *dng, u8 port, u8 data) // w { u16 _PA_ = (u16)dng->dwPort; u16 _PC_ = _PA_ + 2; - u8 irqEnable = inb(_PC_) & 0x10; // don't influence irqEnable - unsigned long flags; - - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) - save_flags(flags); - cli(); - #else - spin_lock_irqsave(&pcan_lock, flags); - #endif - - outb((0x0B ^ 0x0D) | irqEnable, _PC_); - outb(port & 0x1F, _PA_); - outb((0x0B ^ 0x0C) | irqEnable, _PC_); - outb(data, _PA_); - outb((0x0B ^ 0x0D) | irqEnable, _PC_); - - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) - restore_flags(flags); - #else - spin_unlock_irqrestore(&pcan_lock, flags); - #endif + u8 irqEnable = can_inb(_PC_) & 0x10; // don't influence irqEnable + can_spin_irqflags_t flags; + + can_spin_lock_irqsave(&pcan_lock, flags); + + can_outb((0x0B ^ 0x0D) | irqEnable, _PC_); + can_outb(port & 0x1F, _PA_); + can_outb((0x0B ^ 0x0C) | irqEnable, _PC_); + can_outb(data, _PA_); + can_outb((0x0B ^ 0x0D) | irqEnable, _PC_); + + can_spin_unlock_irqrestore(&pcan_lock, flags); } // functions for EPP port @@ -217,27 +209,18 @@ static u8 pcan_dongle_epp_readreg(struct DONGLE_PORT *dng, u8 port) // read a re u16 _PA_ = (u16)dng->dwPort; u16 _PC_ = _PA_ + 2; u8 wert; - u8 irqEnable = inb(_PC_) & 0x10; // don't influence irqEnable - unsigned long flags; - - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) - save_flags(flags); - cli(); - #else - spin_lock_irqsave(&pcan_lock, flags); - #endif - - outb((0x0B ^ 0x0F) | irqEnable, _PC_); - outb((port & 0x1F) | 0x80, _PA_); - outb((0x0B ^ 0x2E) | irqEnable, _PC_); - wert = inb(_PA_); - outb((0x0B ^ 0x0F) | irqEnable, _PC_); - - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) - restore_flags(flags); - #else - spin_unlock_irqrestore(&pcan_lock, flags); - #endif + u8 irqEnable = can_inb(_PC_) & 0x10; // don't influence irqEnable + can_spin_irqflags_t flags; + + can_spin_lock_irqsave(&pcan_lock, flags); + + can_outb((0x0B ^ 0x0F) | irqEnable, _PC_); + can_outb((port & 0x1F) | 0x80, _PA_); + can_outb((0x0B ^ 0x2E) | irqEnable, _PC_); + wert = can_inb(_PA_); + can_outb((0x0B ^ 0x0F) | irqEnable, _PC_); + + can_spin_unlock_irqrestore(&pcan_lock, flags); return wert; } @@ -287,8 +270,8 @@ static void setECR(struct DONGLE_PORT *dng) { u16 wEcr = dng->wEcr; - dng->ucOldECRContent = inb(wEcr); - outb((dng->ucOldECRContent & 0x1F) | 0x20, wEcr); + dng->ucOldECRContent = can_inb(wEcr); + can_outb((dng->ucOldECRContent & 0x1F) | 0x20, wEcr); if (dng->ucOldECRContent == 0xff) DEBUGMSG("%s: realy ECP mode configured?\n", DEVICE_NAME); @@ -298,7 +281,7 @@ static void restoreECR(struct DONGLE_PORT *dng) { u16 wEcr = dng->wEcr; - outb(dng->ucOldECRContent, wEcr); + can_outb(dng->ucOldECRContent, wEcr); DEBUGMSG("%s: restore ECR\n", DEVICE_NAME); } @@ -364,8 +347,8 @@ static int pcan_dongle_open(struct DONGLE_PORT *dng) wPort = (u16)dng->dwPort; // save old port contents - dng->ucOldDataContent = inb(wPort); - dng->ucOldControlContent = inb(wPort + 2); + dng->ucOldDataContent = can_inb(wPort); + dng->ucOldControlContent = can_inb(wPort + 2); // switch to epp mode if possible if (dng->wType == HW_DONGLE_SJA_EPP) @@ -391,8 +374,8 @@ static int pcan_dongle_release(struct DONGLE_PORT *dng) restoreECR(dng); // restore port state - outb(dng->ucOldDataContent, wPort); - outb(dng->ucOldControlContent, wPort + 2); + can_outb(dng->ucOldDataContent, wPort); + can_outb(dng->ucOldControlContent, wPort + 2); parport_release(dng->pardev); @@ -632,7 +615,7 @@ int pcan_dongle_init_chip_data(struct candevice_t *candev, int chipnr) candev->chip[chipnr]->chip_type=CHIP_TYPE; - candev->chip[chipnr]->chip_base_addr=candev->io_addr; + candev->chip[chipnr]->chip_base_addr=can_ioport2ioptr(candev->io_addr); candev->chip[chipnr]->clock = 16000000; candev->chip[chipnr]->int_clk_reg = 0x0; candev->chip[chipnr]->int_bus_reg = 0x0; @@ -706,7 +689,7 @@ int pcan_dongle_program_irq(struct candevice_t *candev) * Return Value: The function does not return a value * File: src/template.c */ -void pcan_dongle_write_register(unsigned data, unsigned long address) +void pcan_dongle_write_register(unsigned data, can_ioptr_t address) { address -= dongle_port.chip->chip_base_addr; // it's in mutiplexed mode @@ -725,7 +708,7 @@ void pcan_dongle_write_register(unsigned data, unsigned long address) * Return Value: The function returns the value stored in @address * File: src/template.c */ -unsigned pcan_dongle_read_register(unsigned long address) +unsigned pcan_dongle_read_register(can_ioptr_t address) { u8 val;