OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [char/] [mbus.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/************************************************************************/
2
/*                                                                      */
3
/*  mbus.c - functions for the mbus driver                              */
4
/*                                                                      */
5
/*  (C) Copyright 1999, Martin Floeer (mfloeer@axcent.de)               */      /*                                                                      */
6
/*                                                                      */
7
/************************************************************************/
8
 
9
 
10
 
11
 
12
#ifndef __KERNEL__
13
#define __KERNEL__
14
#endif
15
#include <linux/kernel.h>
16
#include <linux/malloc.h>
17
#include <linux/fs.h>
18
#include <linux/errno.h>
19
#include <linux/types.h>
20
#include <linux/proc_fs.h>
21
#include <linux/fcntl.h>
22
#include <linux/sched.h>
23
 
24
#include <asm/coldfire.h>
25
#include <asm/types.h>
26
#include <asm/mcfsim.h>
27
#include <asm/mcfmbus.h>
28
 
29
#include <asm/system.h>
30
#include <asm/segment.h>
31
 
32
#include "mbus.h"
33
 
34
 
35
 
36
int mbus_major = MBUS_MAJOR;
37
int mbus_nr_devs = MBUS_NR_DEVS;
38
 
39
Mbus_Dev *mbus_devices;
40
 
41
 
42
volatile char *mbus_base=(char*) (MCF_MBAR + MCFMBUS_BASE);
43
 
44
 
45
static unsigned char mbus_transfer_complete(void)
46
{
47
        if((*(mbus_base + MCFMBUS_MBSR) & MCFMBUS_MBSR_MCF) != 0) return(0x1);
48
        return(0x0);
49
}
50
 
51
 
52
static unsigned char mbus_idle(void)
53
{
54
        if((*(mbus_base + MCFMBUS_MBSR) & MCFMBUS_MBSR_MBB) == 0) return(0x1);
55
        return(0x0);
56
}
57
 
58
static unsigned char mbus_interrupt_pending(void)
59
{
60
        if((*(mbus_base + MCFMBUS_MBSR) & MCFMBUS_MBSR_MIF) != 0) return(0x1);
61
        return(0x0);
62
}
63
 
64
 
65
static void mbus_clear_interrupt(void)
66
{
67
        *(mbus_base + MCFMBUS_MBSR) = *(mbus_base + MCFMBUS_MBSR) & ~MCFMBUS_MBSR_MIF;
68
}
69
 
70
 
71
static unsigned char mbus_arbitration_lost(void)
72
{
73
        if((*(mbus_base + MCFMBUS_MBSR) & MCFMBUS_MBSR_MAL) != 0) return(0x1);
74
        return(0x0);
75
}
76
 
77
 
78
static unsigned char mbus_received_acknowledge(void)
79
{
80
        if((*(mbus_base + MCFMBUS_MBSR) & MCFMBUS_MBSR_RXAK) == 0) return(0x1);
81
        return(0x0);
82
}
83
 
84
 
85
static void mbus_set_address(unsigned char address)
86
{
87
        *(mbus_base + MCFMBUS_MADR) = MCFMBUS_MADR_ADDR(address);
88
}
89
 
90
 
91
static void mbus_set_clock(unsigned char clock)
92
{
93
        *(mbus_base + MCFMBUS_MFDR) = clock;
94
}
95
 
96
static void mbus_set_direction(unsigned char state)
97
{
98
        if(state == 0x1) *(mbus_base + MCFMBUS_MBCR) = *(mbus_base + MCFMBUS_MBCR) | MCFMBUS_MBCR_MTX;  /* transmit mode */
99
                else *(mbus_base + MCFMBUS_MBCR) = *(mbus_base + MCFMBUS_MBCR) & ~MCFMBUS_MBCR_MTX;                             /* transmit mode */
100
}
101
 
102
 
103
static void mbus_set_mode(unsigned char state)
104
{
105
        if(state == 0x1) *(mbus_base + MCFMBUS_MBCR) = *(mbus_base + MCFMBUS_MBCR) | MCFMBUS_MBCR_MSTA; /* master mode */
106
                else *(mbus_base + MCFMBUS_MBCR) = *(mbus_base + MCFMBUS_MBCR) & ~MCFMBUS_MBCR_MSTA;                            /* slave mode */
107
}
108
 
109
 
110
static void mbus_repeat_start(void)
111
{
112
        *(mbus_base + MCFMBUS_MBCR) = *(mbus_base + MCFMBUS_MBCR) | MCFMBUS_MBCR_RSTA;  /* generate repeat start cycle */
113
}
114
 
115
static int mbus_error()
116
{
117
        if(mbus_arbitration_lost() == 0x1) return(-1);
118
        if(mbus_received_acknowledge() == 0x0) return (-2);
119
        return(0);
120
}
121
 
122
void mbus_interrupt(int irq, void *dev_id, struct pt_regs *regs)
123
{
124
 
125
 
126
        int error;
127
 
128
        mbus_clear_interrupt();
129
 
130
        error = mbus_error();
131
        if(error!=0)
132
        {
133
                MBUS_STATE = error;
134
                mbus_set_mode(MBUS_SLAVE);                                      /* generate stop signal */
135
                return;
136
        }
137
 
138
        if(MBUS_MODE == 0x1)                                                    /* which mbus mode*/
139
        {
140
                                                /*** transmit ***/
141
                if(MBUS_DATA_COUNT < 0)
142
                {
143
 
144
                        *(mbus_base + MCFMBUS_MBDR) = MBUS_DEST_ADDRESS_BUFFER;
145
                        /* put destination address to mbus */
146
                        MBUS_DATA_COUNT++;
147
                }
148
                else
149
                {
150
                        if(MBUS_DATA_COUNT != MBUS_DATA_NUMBER)                 /* last byte transmit ? */
151
                        {
152
 
153
 
154
                                *(mbus_base + MCFMBUS_MBDR) = *MBUS_DATA++;     /* put data to mbus *//* so funkt es */
155
 
156
                                MBUS_DATA_COUNT++;
157
                        }
158
                        else
159
                        {
160
 
161
                                mbus_set_mode(MBUS_SLAVE);                      /* generate stop signal */
162
                                MBUS_STATE = MBUS_STATE_IDLE;
163
                        }
164
                }
165
        }
166
        else
167
        {                                                                                                                               /*** receive ***/
168
                if(MBUS_DATA_COUNT < 0)
169
                {
170
                        if(MBUS_DATA_COUNT == -2)
171
                        {
172
                                *(mbus_base + MCFMBUS_MBDR) =
173
                                MBUS_DEST_ADDRESS_BUFFER;       /* put
174
                                destination address to mbus */
175
                                MBUS_DATA_COUNT++;
176
                        }
177
                        else
178
                        {
179
                                mbus_set_direction(MBUS_RECEIVE);                                       /* receive mbus */
180
                                *MBUS_DATA = *(mbus_base + MCFMBUS_MBDR);                                               /* dummy read from mbus */
181
                                MBUS_DATA_COUNT++;
182
                        }
183
                }
184
                else
185
                {
186
                        if(MBUS_DATA_COUNT != MBUS_DATA_NUMBER)                                 /* last byte receive ? */
187
                        {
188
                                *MBUS_DATA++ = *(mbus_base + MCFMBUS_MBDR);                                     /* read data from mbus */
189
                                MBUS_DATA_COUNT++;
190
                        }
191
                        else
192
                        {
193
                                mbus_set_mode(MBUS_SLAVE);                                                      /* generate stop signal */
194
                                MBUS_STATE = MBUS_STATE_IDLE;
195
                        }
196
 
197
 
198
                }
199
        }
200
}
201
 
202
/*
203
 * This function starts the transmission of one char
204
 *
205
 * Paramters:
206
 *  slave_address1                      7 bit Slave address (a7,a6,a5,a4,a3,a2,a1,X)
207
 *  data_address                        8 bit Slave destination data Address
208
 *  buf                                 source data buffer
209
 * Returns:
210
 *                                                      None
211
 */
212
void mbus_putchar(unsigned char slave_address, unsigned char data_address, char
213
*buf)
214
{
215
        while(mbus_idle() == 0x0);                                                              /* wait for bus idle */
216
        MBUS_STATE = MBUS_STATE_BUSY;
217
 
218
 
219
        mbus_set_direction(MBUS_TRANSMIT);                                                              /* transmit mbus */
220
        mbus_set_mode(MBUS_MASTER);
221
 
222
        MBUS_MODE = MBUS_TRANSMIT;
223
        MBUS_DATA_COUNT = -1;                                                                   /* INIT data counter */
224
        MBUS_DATA_NUMBER = 1;                                                                   /* INIT data number */
225
        MBUS_DEST_ADDRESS_BUFFER = data_address;
226
        MBUS_DATA = buf;
227
 
228
        *(mbus_base + MCFMBUS_MBDR) = slave_address & ~MCFMBUS_MBDR_READ;       /* send mbus_address and write access*/
229
}
230
 
231
/*
232
 * This function starts the receiving of one char
233
 *
234
 * Paramters:
235
 *  slave_address1                      7 bit Slave address (a7,a6,a5,a4,a3,a2,a1,X)
236
 *  data_address                        8 bit Slave source data Address
237
 *  buf                                 destination data buffer
238
 * Returns:
239
 *                                                      None
240
 */
241
void mbus_getchar(unsigned char slave_address, unsigned char data_address, char *buf)
242
{
243
        while(mbus_idle() == 0x0);                                      /* wait for bus idle */
244
 
245
        MBUS_STATE = MBUS_STATE_BUSY;
246
 
247
        mbus_set_direction(MBUS_TRANSMIT);                              /* transmit mbus */
248
        mbus_set_mode(MBUS_MASTER);
249
 
250
        MBUS_MODE = MBUS_RECEIVE;
251
        MBUS_DATA_COUNT = -2;                                           /* INIT data counter */
252
        MBUS_DATA_NUMBER = 1;                                           /* INIT data number */
253
        MBUS_DEST_ADDRESS_BUFFER = data_address;
254
        MBUS_DATA = buf;
255
 
256
        *(mbus_base + MCFMBUS_MBDR) = slave_address & ~MCFMBUS_MBDR_READ;       /* send mbus_address and write access*/
257
}
258
 
259
/*
260
 * This function starts the transmission of n char
261
 *
262
 * Paramters:
263
 *  slave_address1                      7 bit Slave address (a7,a6,a5,a4,a3,a2,a1,X)
264
 *  dest_address                        8 bit Slave destination data Address
265
 *  buf                                 source data buffer
266
 * Returns:
267
 *                                                      None
268
 */
269
void mbus_putchars(unsigned char slave_address, unsigned char data_address, char *buf, int number)
270
{
271
        while(mbus_idle() == 0x0);                                      /* wait for bus idle */
272
        MBUS_STATE = MBUS_STATE_BUSY;
273
 
274
        mbus_set_direction(MBUS_TRANSMIT);                                                              /* transmit mbus */
275
        mbus_set_mode(MBUS_MASTER);
276
        MBUS_MODE = MBUS_TRANSMIT;
277
        MBUS_DATA_COUNT = -1;                                                                                           /* INIT data counter */
278
        MBUS_DATA_NUMBER = number;                                                                                      /* INIT data number */
279
        MBUS_DEST_ADDRESS_BUFFER = data_address;
280
        MBUS_DATA = buf;
281
        *(mbus_base + MCFMBUS_MBDR) = slave_address & ~MCFMBUS_MBDR_READ;       /* send mbus_address and write access*/
282
 
283
}
284
 
285
 
286
unsigned char mbus_busy_event(void)
287
{
288
/*      unsigned char state;
289
 
290
 
291
        if(MBUS_STATE == MBUS_STATE_BUSY) state = 0x1;
292
                else state= 0x0;
293
 
294
        return(state);*/
295
 
296
        if(MBUS_STATE == MBUS_STATE_BUSY) return 0x1;
297
 
298
        return 0x0;
299
}
300
 
301
 
302
 
303
int mbus_open (struct inode * inode, struct file *filp)
304
{
305
 
306
        int minor = MINOR(inode->i_rdev);
307
        Mbus_Dev *dev;
308
        if (minor >= mbus_nr_devs) {
309
                        return -ENODEV;
310
                        printk("Error: no such device \n");
311
                        }
312
 
313
 
314
        dev = &mbus_devices[minor];
315
        dev->name="mbus";
316
        /*Initialisierung mbus*/
317
 
318
        mbus_set_clock(MCFMBUS_CLK);
319
 
320
        mbus_set_address(MCFMBUS_ADDRESS);
321
 
322
        *(mbus_base + MCFMBUS_MBCR) = MCFMBUS_MBCR_MEN ;        /* first enable M-BUS   */
323
                                                        /* Interrupt disable    */
324
                                                        /* set to Slave mode    */
325
                                                        /* set to receive mode  */
326
                                                        /* with acknowledge     */
327
        if (request_irq(MCFMBUS_IRQ_VECTOR, mbus_interrupt, 0, dev->name, NULL)) printk(" kein Interrupt\n");
328
        *(volatile unsigned char*)(MCF_MBAR + MCFSIM_ICR3) = MCFMBUS_IRQ_LEVEL | MCFSIM_ICR_AUTOVEC;    /* set MBUS IRQ-Level and autovector */
329
        mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_MBUS);
330
        *(mbus_base + MCFMBUS_MBCR) = *(mbus_base + MCFMBUS_MBCR) | MCFMBUS_MBCR_MIEN ;         /* Interrupt enable*/
331
 
332
        /*Ender Initialisierung mbus*/
333
 
334
        return 0;
335
}
336
 
337
mbus_release(struct inode * inode, struct file *filp)
338
{
339
*(volatile unsigned char*)(MCF_MBAR + MCFSIM_ICR3)= 0x0;
340
mcf_setimr(mcf_getimr()  | MCFSIM_IMR_MBUS);
341
free_irq(MCFMBUS_IRQ_VECTOR, NULL);
342
}
343
/*
344
* Using the read function:      first Byte of buf slave address
345
*                               second Byte of buf dest address
346
*                               following Bytes read buffer
347
*/
348
 
349
read_write_t mbus_read (struct inode *inode, struct file *filp, char *buf,
350
count_t count)
351
{
352
 
353
        Mbus_Dev *dev= filp->private_data;
354
        char address=*buf++, dest_address=*buf++;
355
        if (count> 3)   {
356
                        printk(KERN_ERR "nur ein Zeichen Lesen\n");
357
                        return -1;
358
                        }
359
        dev->usage++;
360
 
361
        mbus_getchar(address, dest_address, buf);
362
 
363
        dev->usage--;
364
        return 0;
365
}
366
 
367
/*
368
* Using the write function:             first Byte of buf slave address
369
*                                       second Byte of buf dest address
370
*                                       following Bytes  write buffer
371
*/
372
 
373
read_write_t mbus_write (struct inode *inode, struct file *filp, char *buf,
374
count_t count)
375
{
376
        Mbus_Dev *dev= filp->private_data;
377
 
378
        char address=*buf++, dest_address=*buf++;
379
        count = count -2;
380
 
381
        dev->usage++;
382
 
383
        mbus_putchars(address, dest_address, buf, count);
384
 
385
        dev->usage--;
386
        return 0;
387
}
388
 
389
 
390
struct file_operations mbus_fops =
391
{
392
NULL,
393
mbus_read,
394
mbus_write,
395
NULL,
396
NULL,
397
NULL,
398
NULL,
399
mbus_open,
400
mbus_release,
401
 
402
};
403
 
404
int mbus_init(void)
405
{
406
        int result, i;
407
        result = register_chrdev(mbus_major, "mbus",  &mbus_fops);
408
 
409
        if (result<0)
410
                {
411
                printk("keine Major\n");
412
                }
413
 
414
 
415
        mbus_devices = kmalloc(mbus_nr_devs * sizeof(Mbus_Dev), GFP_KERNEL);
416
 
417
        if (!mbus_devices)
418
                {
419
                result = -ENOMEM;
420
                goto fail_malloc;
421
                }
422
 
423
 
424
        return 0;
425
 
426
        fail_malloc:    unregister_chrdev(mbus_major, "mbus");
427
                        return result;
428
 
429
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.