]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/pcan_dongle.c
The LinCAN driver license unified according to DCE FEE CTU head and superiors request.
[lincan.git] / lincan / src / pcan_dongle.c
index 10b6efa782aa74def0fe4dc8de20648ebf93959e..386725b23123ca6dbe385ec3f3ae58d0bacb9d51 100644 (file)
@@ -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 <http://dce.felk.cvut.cz>   */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz>             */
+/* Copyright (C) 2005 Klaus Hitschler <klaus.hitschler@gmx.de>            */
+/* Copyright (C) 2005-2006 Jose Pascual Ramírez <josepascual@almudi.com>  */
+/* 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 <arnaud@wanadoo.nl>      */
+/* Contributions: Marcel Offermans <marcel.offermans@luminis.nl>          */
+/*                Philipp Baer <philipp.baer@informatik.uni-ulm.de>       */
+/*                                                                        */
+/* 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.  */
+/**************************************************************************/
+
 
 /****************************************************************************/
 //
 #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);
   
@@ -527,7 +510,7 @@ int pcan_dongle_release_io(struct candevice_t *candev)
 int pcan_dongle_reset(struct candevice_t *candev)
 {
        int i=0;
-       struct chip_t *chip;
+       struct canchip_t *chip;
        int chipnr;
        unsigned cdr;
        
@@ -632,14 +615,14 @@ 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;
        candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
        candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL | sjaOCR_TX0_LH;
 
-       candev->chip[chipnr]->flags |= CHIP_IRQ_VME;  // I don't want setup call request_irq 
+       candev->chip[chipnr]->flags |= CHIP_IRQ_CUSTOM;  // I don't want setup call request_irq 
                                      // I'm going to do it through parport_register_device 
 
      }
@@ -664,7 +647,7 @@ int pcan_dongle_init_chip_data(struct candevice_t *candev, int chipnr)
  * Return Value: The function always returns zero
  * File: src/template.c
  */
-int pcan_dongle_init_obj_data(struct chip_t *chip, int objnr)
+int pcan_dongle_init_obj_data(struct canchip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
        chip->msgobj[objnr]->obj_flags=0;
@@ -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;