source: rtems/c/src/lib/libbsp/sparc/shared/can/canmux.c @ 4a7d1026

4.115
Last change on this file since 4a7d1026 was 4a7d1026, checked in by Daniel Hellstrom <daniel@…>, on 04/13/15 at 08:25:52

sparc bsps: updated license to rtems.org

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 *  CAN_MUX driver. Present in GR712RC.
3 *
4 *  COPYRIGHT (c) 2008.
5 *  Cobham Gaisler AB.
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.org/license/LICENSE.
10 */
11
12#include <rtems/libio.h>
13#include <stdlib.h>
14#include <stdio.h>
15#include <string.h>
16#include <bsp.h>
17#include <rtems/bspIo.h> /* printk */
18
19#include <bsp/canmux.h>
20#include <ambapp.h>
21
22#ifndef GAISLER_CANMUX
23#define GAISLER_CANMUX 0x081
24#endif
25
26#if !defined(CANMUX_DEVNAME)
27 #undef CANMUX_DEVNAME
28 #define CANMUX_DEVNAME "/dev/canmux"
29#endif
30
31/* Enable debug output? */
32/* #define DEBUG */
33
34#ifdef DEBUG
35#define DBG(x...) printk(x)
36#else
37#define DBG(x...)
38#endif
39
40#define BUSA_SELECT (1 << 0)
41#define BUSB_SELECT (1 << 1)
42
43struct canmux_priv {
44        volatile unsigned int *muxreg;
45        rtems_id devsem;
46        int open;
47};
48
49static struct canmux_priv *priv;
50
51static rtems_device_driver canmux_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
52static rtems_device_driver canmux_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
53static rtems_device_driver canmux_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
54static rtems_device_driver canmux_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
55static rtems_device_driver canmux_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
56static rtems_device_driver canmux_initialize(rtems_device_major_number major, rtems_device_minor_number unused, void *arg);
57
58
59static rtems_device_driver canmux_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
60{
61        rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t*)arg;
62       
63        DBG("CAN_MUX:  IOCTL %d\n\r", ioarg->command);
64
65        ioarg->ioctl_return = 0;
66        switch(ioarg->command) {
67        case CANMUX_IOC_BUSA_SATCAN: *priv->muxreg &= ~BUSA_SELECT; break;
68        case CANMUX_IOC_BUSA_OCCAN1: *priv->muxreg |= BUSA_SELECT;  break;
69        case CANMUX_IOC_BUSB_SATCAN: *priv->muxreg &= ~BUSB_SELECT; break;
70        case CANMUX_IOC_BUSB_OCCAN2: *priv->muxreg |= BUSB_SELECT; break;
71        default: return RTEMS_NOT_DEFINED;
72        }
73
74        return RTEMS_SUCCESSFUL;
75}
76
77static rtems_device_driver canmux_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
78{
79        rtems_libio_rw_args_t *rw_args=(rtems_libio_rw_args_t*)arg;
80       
81        rw_args->bytes_moved = 0;
82
83        return RTEMS_SUCCESSFUL;
84}
85
86static rtems_device_driver canmux_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
87{
88        rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t*)arg;
89       
90        rw_args->bytes_moved = 0;
91       
92        return RTEMS_SUCCESSFUL;
93}
94
95
96static rtems_device_driver canmux_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
97{
98        DBG("CAN_MUX: Closing %d\n\r",minor);
99
100        priv->open = 0;
101        return RTEMS_SUCCESSFUL;
102}
103
104
105static rtems_device_driver canmux_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
106{
107        DBG("CAN_MUX: Opening %d\n\r",minor);
108       
109        rtems_semaphore_obtain(priv->devsem,RTEMS_WAIT, RTEMS_NO_TIMEOUT);
110        if (priv->open) {
111                rtems_semaphore_release(priv->devsem);
112                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
113        }
114        priv->open = 1;
115        rtems_semaphore_release(priv->devsem);
116
117        DBG("CAN_MUX: Opening %d success\n\r",minor);
118
119        return RTEMS_SUCCESSFUL;
120}
121
122static rtems_device_driver canmux_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
123{
124        struct ambapp_apb_info d;
125        char fs_name[20];
126        rtems_status_code status;
127
128        DBG("CAN_MUX: Initialize..\n\r");
129
130        strcpy(fs_name, CANMUX_DEVNAME);
131       
132        /* Find core and initialize register pointer */
133        if (!ambapp_find_apbslv(&ambapp_plb, VENDOR_GAISLER, GAISLER_CANMUX, &d)) {
134                printk("CAN_MUX: Failed to find CAN_MUX core\n\r");
135                return -1;
136        }
137       
138        status = rtems_io_register_name(fs_name, major, minor);
139        if (RTEMS_SUCCESSFUL != status)
140                rtems_fatal_error_occurred(status);
141
142        /* Create private structure */
143        if ((priv = malloc(sizeof(struct canmux_priv))) == NULL) {
144                printk("CAN_MUX driver could not allocate memory for priv structure\n\r");
145                return -1;
146        }
147       
148        priv->muxreg = (unsigned int*)d.start;
149
150        status = rtems_semaphore_create(
151                rtems_build_name('M', 'd', 'v', '0'),
152                1,
153                RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | \
154                RTEMS_NO_PRIORITY_CEILING,
155                0,
156                &priv->devsem);
157        if (status != RTEMS_SUCCESSFUL) {
158                printk("CAN_MUX: Failed to create dev semaphore (%d)\n\r", status);
159                free(priv);
160                return RTEMS_UNSATISFIED;
161        }
162       
163        priv->open = 0;
164
165        return RTEMS_SUCCESSFUL;
166}
167
168
169#define CANMUX_DRIVER_TABLE_ENTRY { canmux_initialize, canmux_open, canmux_close, canmux_read, canmux_write, canmux_ioctl }
170
171static rtems_driver_address_table canmux_driver = CANMUX_DRIVER_TABLE_ENTRY;
172
173int canmux_register(void)
174{
175        rtems_status_code r;
176        rtems_device_major_number m;
177
178        DBG("CAN_MUX: canmux_register called\n\r");
179
180        if ((r = rtems_io_register_driver(0, &canmux_driver, &m)) == RTEMS_SUCCESSFUL) {
181                DBG("CAN_MUX driver successfully registered, major: %d\n\r", m);
182        } else {
183                switch(r) {
184                case RTEMS_TOO_MANY:
185                        printk("CAN_MUX rtems_io_register_driver failed: RTEMS_TOO_MANY\n\r"); break;
186                case RTEMS_INVALID_NUMBER: 
187                        printk("CAN_MUX rtems_io_register_driver failed: RTEMS_INVALID_NUMBER\n\r"); break;
188                case RTEMS_RESOURCE_IN_USE:
189                        printk("CAN_MUX rtems_io_register_driver failed: RTEMS_RESOURCE_IN_USE\n\r"); break;
190                default:
191                        printk("CAN_MUX rtems_io_register_driver failed\n\r");
192                }
193                return 1;
194        }
195
196        return 0;
197}
Note: See TracBrowser for help on using the repository browser.