Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:06

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  CAN_MUX driver. Present in GR712RC.
0005  *
0006  *  COPYRIGHT (c) 2008.
0007  *  Cobham Gaisler AB.
0008  *
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, this list of conditions and the following disclaimer.
0014  * 2. Redistributions in binary form must reproduce the above copyright
0015  *    notice, this list of conditions and the following disclaimer in the
0016  *    documentation and/or other materials provided with the distribution.
0017  *
0018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028  * POSSIBILITY OF SUCH DAMAGE.
0029  */
0030 
0031 #include <rtems/libio.h>
0032 #include <stdlib.h>
0033 #include <stdio.h>
0034 #include <string.h>
0035 #include <bsp.h>
0036 #include <rtems/bspIo.h> /* printk */
0037 
0038 #include <grlib/canmux.h>
0039 #include <grlib/ambapp.h>
0040 
0041 #include <grlib/grlib_impl.h>
0042 
0043 #ifndef GAISLER_CANMUX
0044 #define GAISLER_CANMUX 0x081
0045 #endif
0046 
0047 #if !defined(CANMUX_DEVNAME) 
0048  #undef CANMUX_DEVNAME
0049  #define CANMUX_DEVNAME "/dev/canmux"
0050 #endif
0051 
0052 /* Enable debug output? */
0053 /* #define DEBUG */
0054 
0055 #ifdef DEBUG
0056 #define DBG(x...) printk(x)
0057 #else
0058 #define DBG(x...) 
0059 #endif
0060 
0061 #define BUSA_SELECT (1 << 0)
0062 #define BUSB_SELECT (1 << 1)
0063 
0064 struct canmux_priv {
0065     volatile unsigned int *muxreg;
0066     rtems_id devsem;
0067     int open;
0068 };
0069 
0070 static struct canmux_priv *priv;
0071 
0072 static rtems_device_driver canmux_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0073 static rtems_device_driver canmux_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0074 static rtems_device_driver canmux_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0075 static rtems_device_driver canmux_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0076 static rtems_device_driver canmux_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0077 static rtems_device_driver canmux_initialize(rtems_device_major_number major, rtems_device_minor_number unused, void *arg);
0078 
0079 
0080 static rtems_device_driver canmux_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0081 {
0082     rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t*)arg;
0083     
0084     DBG("CAN_MUX:  IOCTL %d\n\r", ioarg->command);
0085 
0086     ioarg->ioctl_return = 0;
0087     switch(ioarg->command) {
0088     case CANMUX_IOC_BUSA_SATCAN: *priv->muxreg &= ~BUSA_SELECT; break;
0089     case CANMUX_IOC_BUSA_OCCAN1: *priv->muxreg |= BUSA_SELECT;  break;
0090     case CANMUX_IOC_BUSB_SATCAN: *priv->muxreg &= ~BUSB_SELECT; break;
0091     case CANMUX_IOC_BUSB_OCCAN2: *priv->muxreg |= BUSB_SELECT; break;
0092     default: return RTEMS_NOT_DEFINED;
0093     }
0094 
0095     return RTEMS_SUCCESSFUL;
0096 }
0097 
0098 static rtems_device_driver canmux_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0099 {
0100     rtems_libio_rw_args_t *rw_args=(rtems_libio_rw_args_t*)arg;
0101     
0102     rw_args->bytes_moved = 0;
0103 
0104     return RTEMS_SUCCESSFUL;
0105 }
0106 
0107 static rtems_device_driver canmux_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0108 {
0109     rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t*)arg;
0110     
0111     rw_args->bytes_moved = 0;
0112     
0113     return RTEMS_SUCCESSFUL;
0114 }
0115 
0116 
0117 static rtems_device_driver canmux_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0118 {
0119     DBG("CAN_MUX: Closing %d\n\r",minor);
0120 
0121     priv->open = 0;
0122     return RTEMS_SUCCESSFUL;
0123 }
0124 
0125 
0126 static rtems_device_driver canmux_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0127 {
0128     DBG("CAN_MUX: Opening %d\n\r",minor);
0129     
0130     rtems_semaphore_obtain(priv->devsem,RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0131     if (priv->open) {
0132         rtems_semaphore_release(priv->devsem);
0133         return RTEMS_RESOURCE_IN_USE; /* EBUSY */
0134     }
0135     priv->open = 1;
0136     rtems_semaphore_release(priv->devsem);
0137 
0138     DBG("CAN_MUX: Opening %d success\n\r",minor);
0139 
0140     return RTEMS_SUCCESSFUL;
0141 }
0142 
0143 static rtems_device_driver canmux_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0144 {
0145     struct ambapp_apb_info d;
0146     char fs_name[20];
0147     rtems_status_code status;
0148 
0149     DBG("CAN_MUX: Initialize..\n\r");
0150 
0151     strcpy(fs_name, CANMUX_DEVNAME);
0152     
0153     /* Find core and initialize register pointer */
0154     if (!ambapp_find_apbslv(ambapp_plb(), VENDOR_GAISLER, GAISLER_CANMUX, &d)) {
0155         printk("CAN_MUX: Failed to find CAN_MUX core\n\r");
0156         return -1;
0157     }
0158     
0159     status = rtems_io_register_name(fs_name, major, minor);
0160     if (RTEMS_SUCCESSFUL != status)
0161         rtems_fatal_error_occurred(status);
0162 
0163     /* Create private structure */
0164     if ((priv = grlib_malloc(sizeof(*priv))) == NULL) {
0165         printk("CAN_MUX driver could not allocate memory for priv structure\n\r");
0166         return -1;
0167     }
0168     
0169     priv->muxreg = (unsigned int*)d.start;
0170 
0171     status = rtems_semaphore_create(
0172         rtems_build_name('M', 'd', 'v', '0'),
0173         1,
0174         RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | \
0175         RTEMS_NO_PRIORITY_CEILING,
0176         0, 
0177         &priv->devsem);
0178     if (status != RTEMS_SUCCESSFUL) {
0179         printk("CAN_MUX: Failed to create dev semaphore (%d)\n\r", status);
0180         free(priv);
0181         return RTEMS_UNSATISFIED;
0182     }
0183     
0184     priv->open = 0;
0185 
0186     return RTEMS_SUCCESSFUL;
0187 }
0188 
0189 
0190 #define CANMUX_DRIVER_TABLE_ENTRY { canmux_initialize, canmux_open, canmux_close, canmux_read, canmux_write, canmux_ioctl }
0191 
0192 static rtems_driver_address_table canmux_driver = CANMUX_DRIVER_TABLE_ENTRY;
0193 
0194 int canmux_register(void)
0195 {
0196     rtems_status_code r;
0197     rtems_device_major_number m;
0198 
0199     DBG("CAN_MUX: canmux_register called\n\r");
0200 
0201     if ((r = rtems_io_register_driver(0, &canmux_driver, &m)) == RTEMS_SUCCESSFUL) {
0202         DBG("CAN_MUX driver successfully registered, major: %d\n\r", m);
0203     } else {
0204         switch(r) {
0205         case RTEMS_TOO_MANY:
0206             printk("CAN_MUX rtems_io_register_driver failed: RTEMS_TOO_MANY\n\r"); break;
0207         case RTEMS_INVALID_NUMBER:  
0208             printk("CAN_MUX rtems_io_register_driver failed: RTEMS_INVALID_NUMBER\n\r"); break;
0209         case RTEMS_RESOURCE_IN_USE:
0210             printk("CAN_MUX rtems_io_register_driver failed: RTEMS_RESOURCE_IN_USE\n\r"); break;
0211         default:
0212             printk("CAN_MUX rtems_io_register_driver failed\n\r");
0213         }
0214         return 1;
0215     }
0216 
0217     return 0;
0218 }