File indexing completed on 2025-05-11 08:24:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
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
0053
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;
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
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
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 }