www.pudn.com > 422.rar > ioctl.c


/* ioctl.c
 * Linux serial-bus device driver.
 * Written by wang song yue  email:wsy5228@sina.com
 * This software is released under the GPL-License.
 * Version 0.1  28 october 2005
 */

#include 
#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS)
#define MODVERSIONS
#endif

#if defined (MODVERSIONS)
#include 
#endif

#include 
#include 

#include "../include/main.h"
#include "../include/ioctl.h"
#include "../include/s16c554.h"

int serial_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
//	int i=0;
	unsigned short channel=0;
	unsigned  lsb=0, msb=0;
	struct msgobj_t *obj;
	struct chip_t *chip = objects_p[MINOR_NR]->hostchip;
	struct canfifo_t *fifo = objects_p[MINOR_NR]->fifo;
 if(MINOR_NR==0)
        {
          tts_io_addr=0xffd00000;
        }
        else if(MINOR_NR==1)
        {
                tts_io_addr=0xffd00008;
        }
        else if(MINOR_NR==2)
        {
                tts_io_addr=0xffd00010;
                                                                                                               
        }
                                                                                                               
        else if(MINOR_NR==3)
        {
                tts_io_addr=0xffd00018;
                                                                                                               
        }
                                                                                                               

// printk("i am in serial_ioctl  minor=%d,serial_io_addr=0x%x\n",MINOR_NR,tts_io_addr);
	/* Initialize hardware pointers */
	if ( (obj = objects_p[MINOR_NR]) == NULL) {
		CANMSG("Could not assign buffer structure\n");
		return -1;
	}
	if ( (chip = obj->hostchip) == NULL) {
		CANMSG("Device is not correctly configured.\n");
		CANMSG("Please reload the driver.\n");
		return -1;
	}

	switch (cmd) {
		case STATE: {
                  return serial_read_reg(chip,arg);     
			//for (i=0x0; i<0x20; i++)
			//	CANMSG("0x%x is 0x%x\n",i,serial_read_reg(chip,i));
		//	break;
		}
		case CMD_START: {
			if (chips_p[arg]->chipspecops->start_chip(chip))
				return -1;
			break;
		}
		case CMD_STOP: {
			if (chips_p[arg]->chipspecops->stop_chip(chip))
				return -1;
			break;
		}
		case CONF_FILTER: {
			if (!strcmp(chip->chip_type,"16c554")) {
			
				unsigned char lcr, mcr;
				lcr = (unsigned char) ((arg >> 8)&0xff);
				mcr = (unsigned char) (arg&0xff);

	DEBUGMSG("configuring 	LCR= %02x, MCR=%02x\n", lcr, mcr);
                           if (chips_p[channel]->chipspecops->standard_mask(chip,
                                                                lcr,mcr)) {
                                CANMSG("Error setting LCR ,MCR  registers\n");
                                return -1;
                        }

			//	serial_write_reg(chip,id1,SJAACR);
			//serial_write_reg(chip,id0,SJACMR);
			}

			/* In- and output buffer re-initialization */
			
			fifo->tx_readp = fifo->buf_tx_entry;
			fifo->tx_writep = fifo->buf_tx_entry;
			fifo->rx_readp = fifo->buf_rx_entry;
			fifo->rx_writep = fifo->buf_rx_entry;
			fifo->rx_size= MAX_BUF_LENGTH * sizeof(struct serialmsg_t);
			fifo->tx_size = fifo->rx_size;

			#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))
				init_waitqueue(&fifo->readq);
				init_waitqueue(&fifo->writeq);
			#else
				init_waitqueue_head(&fifo->readq);
				init_waitqueue_head(&fifo->writeq);
			#endif

			fifo->rx_in_progress = 0;
			fifo->tx_in_progress = 0;

			fifo->head = fifo->tail = 0; //TEMP!!
			
			break;
		}

		case CONF_BAUD: {
                                 printk("config baudrate!!!!!!!!!!!\n");
                                   switch(arg)
                                       {
                                         case 300:{lsb=0x80;msb=0x01;break;}
                                         case 600:{lsb=0xc0;msb=0x00;break;}
                                         case 1200:{lsb=0x60;msb=0x00;break;}
                                         case 2400:{lsb=0x30;msb=0x00;break;}
                                         case 3600:{lsb=0x20;msb=0x00;break;}
                                         case 4800:{lsb=0x18;msb=0x00;break;}
                                         case 7200:{lsb=0x10;msb=0x00;break;}
                                         case 9600:{lsb=0x0c;msb=0x00;break;}
                                         case 14400:{lsb=0x08;msb=0x00;break;}
                                         case 19200:{lsb=0x06;msb=0x00;break;}
                                         case 28800:{lsb=0x04;msb=0x00;break;}
                                         case 38400:{lsb=0x03;msb=0x00;break;}
                                         case 57600:{lsb=0x02;msb=0x00;break;}
                                         case 115200:{lsb=0x01;msb=0x00;break;}
                                         default:CANMSG("NOT a valid bauldrate!!\n");
                                       }
                                  
	//		channel = arg & 0xff;
	//		btr0 = (arg >> 8) & 0xff;
	//		btr1 = (arg >> 16) & 0xff;

			if (chips_p[channel]->chipspecops->set_btregs(chip,
								lsb, msb)) {
				CANMSG("Error setting LSB ,MSB  registers\n");
				return -1;
			}
			break;
		}
		default: {
			CANMSG("Not a valid ioctl command\n");
			return -EINVAL;
		}
		
	}

	return 0;
}