1/************************************************** 2 * 3 * drivers/ifx/serial/ifx_ssc.c 4 * 5 * Driver for IFX_SSC serial ports 6 * 7 * Copyright (C) 2004 Infineon Technologies AG 8 * Author Michael Schoenenborn (IFX COM TI BT) 9 * 10 */ 11#define IFX_SSC_DRV_VERSION "0.2.1" 12/* 13 ************************************************** 14 * 15 * This driver was originally based on the INCA-IP driver, but due to 16 * fundamental conceptual drawbacks there has been changed a lot. 17 * 18 * Based on INCA-IP driver Copyright (c) 2003 Gary Jennejohn <gj@denx.de> 19 * Based on the VxWorks drivers Copyright (c) 2002, Infineon Technologies. 20 * 21 * This program is free software; you can redistribute it and/or modify 22 * it under the terms of the GNU General Public License as published by 23 * the Free Software Foundation; either version 2 of the License, or 24 * (at your option) any later version. 25 * 26 * This program is distributed in the hope that it will be useful, 27 * but WITHOUT ANY WARRANTY; without even the implied warranty of 28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29 * GNU General Public License for more details. 30 * 31 * You should have received a copy of the GNU General Public License 32 * along with this program; if not, write to the Free Software 33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 34 * 35 */ 36 37// ### TO DO: general issues: 38// - power management 39// - interrupt handling (direct/indirect) 40// - pin/mux-handling (just overall concept due to project dependency) 41// - multiple instances capability 42// - slave functionality 43 44/* 45 * Include section 46 */ 47#ifndef EXPORT_SYMTAB 48#define EXPORT_SYMTAB 49#endif 50 51#include <linux/config.h> 52#include <linux/module.h> 53#include <linux/errno.h> 54#include <linux/signal.h> 55#include <linux/sched.h> 56#include <linux/timer.h> 57#include <linux/interrupt.h> 58#include <linux/major.h> 59#include <linux/string.h> 60#include <linux/fs.h> 61#include <linux/proc_fs.h> 62#include <linux/fcntl.h> 63#include <linux/ptrace.h> 64#include <linux/mm.h> 65#include <linux/ioport.h> 66#include <linux/init.h> 67#include <linux/delay.h> 68#include <linux/spinlock.h> 69#include <linux/slab.h> 70//#include <linux/poll.h> 71 72#include <asm/system.h> 73#include <asm/io.h> 74#include <asm/irq.h> 75#include <asm/uaccess.h> 76#include <asm/bitops.h> 77 78#include <linux/types.h> 79#include <linux/kernel.h> 80#include <linux/version.h> 81 82#include <asm/amazon/amazon.h> 83#include <asm/amazon/irq.h> 84#include <asm/amazon/ifx_ssc_defines.h> 85#include <asm/amazon/ifx_ssc.h> 86 87#ifdef SSC_FRAME_INT_ENABLE 88#undef SSC_FRAME_INT_ENABLE 89#endif 90 91#define not_yet 92 93#define SPI_VINETIC 94 95/* 96 * Deal with CONFIG_MODVERSIONS 97 */ 98#if CONFIG_MODVERSIONS==1 99# include <linux/modversions.h> 100#endif 101 102MODULE_LICENSE("GPL"); 103MODULE_AUTHOR("Michael Schoenenborn"); 104MODULE_DESCRIPTION("IFX SSC driver"); 105MODULE_SUPPORTED_DEVICE("ifx_ssc"); 106MODULE_PARM(maj, "i"); 107MODULE_PARM_DESC(maj, "Major device number"); 108 109/* allow the user to set the major device number */ 110static int maj = 0; 111 112 113/* 114 * This is the per-channel data structure containing pointers, flags 115 * and variables for the port. This driver supports a maximum of PORT_CNT. 116 * isp is allocated in ifx_ssc_init() based on the chip version. 117 */ 118static struct ifx_ssc_port *isp; 119 120/* prototypes for fops */ 121static ssize_t ifx_ssc_read(struct file *, char *, size_t, loff_t *); 122static ssize_t ifx_ssc_write(struct file *, const char *, size_t, loff_t *); 123//static unsigned int ifx_ssc_poll(struct file *, struct poll_table_struct *); 124int ifx_ssc_ioctl(struct inode *, struct file *, unsigned int, unsigned long); 125int ifx_ssc_open(struct inode *, struct file *); 126int ifx_ssc_close(struct inode *, struct file *); 127 128/* other forward declarations */ 129static unsigned int ifx_ssc_get_kernel_clk(struct ifx_ssc_port *info); 130static void ifx_ssc_rx_int(int, void *, struct pt_regs *); 131static void ifx_ssc_tx_int(int, void *, struct pt_regs *); 132static void ifx_ssc_err_int(int, void *, struct pt_regs *); 133#ifdef SSC_FRAME_INT_ENABLE 134static void ifx_ssc_frm_int(int, void *, struct pt_regs *); 135#endif 136static void tx_int(struct ifx_ssc_port *); 137static int ifx_ssc1_read_proc(char *, char **, off_t, int, int *, void *); 138static void ifx_gpio_init(void); 139/************************************************************************ 140 * Function declaration 141 ************************************************************************/ 142//interrupt.c 143extern unsigned int amazon_get_fpi_hz(void); 144extern void disable_amazon_irq(unsigned int irq_nr); 145extern void enable_amazon_irq(unsigned int irq_nr); 146extern void mask_and_ack_amazon_irq(unsigned int irq_nr); 147 148 149/*****************************************************************/ 150typedef struct { 151 int (*request)(unsigned int irq, 152 void (*handler)(int, void *, struct pt_regs *), 153 unsigned long irqflags, 154 const char * devname, 155 void *dev_id); 156 void (*free)(unsigned int irq, void *dev_id); 157 void (*enable)(unsigned int irq); 158 void (*disable)(unsigned int irq); 159 void (*clear)(unsigned int irq); 160} ifx_int_wrapper_t; 161 162static ifx_int_wrapper_t ifx_int_wrapper = { 163 request: request_irq, // IM action: enable int 164 free: free_irq, // IM action: disable int 165 enable: enable_amazon_irq, 166 disable: disable_amazon_irq, 167 clear: mask_and_ack_amazon_irq, 168 //end: 169}; 170 171/* Fops-struct */ 172static struct file_operations ifx_ssc_fops = { 173 owner: THIS_MODULE, 174 read: ifx_ssc_read, /* read */ 175 write: ifx_ssc_write, /* write */ 176// poll: ifx_ssc_poll, /* poll */ 177 ioctl: ifx_ssc_ioctl, /* ioctl */ 178 open: ifx_ssc_open, /* open */ 179 release: ifx_ssc_close, /* release */ 180}; 181 182 183static inline unsigned int ifx_ssc_get_kernel_clk(struct ifx_ssc_port *info) 184{ // ATTENTION: This function assumes that the CLC register is set with the 185 // appropriate value for RMC. 186 unsigned int rmc; 187 188 rmc = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CLC) & 189 IFX_CLC_RUN_DIVIDER_MASK) >> IFX_CLC_RUN_DIVIDER_OFFSET; 190 if (rmc == 0){ 191 printk("ifx_ssc_get_kernel_clk rmc==0 \n"); 192 return (0); 193 } 194 return (amazon_get_fpi_hz() / rmc); 195} 196 197#ifndef not_yet 198#ifdef IFX_SSC_INT_USE_BH 199/* 200 * This routine is used by the interrupt handler to schedule 201 * processing in the software interrupt portion of the driver 202 * (also known as the "bottom half"). This can be called any 203 * number of times for any channel without harm. 204 */ 205static inline void 206ifx_ssc_sched_event(struct ifx_ssc_port *info, int event) 207{ 208 info->event |= 1 << event; /* remember what kind of event and who */ 209 queue_task(&info->tqueue, &tq_cyclades); /* it belongs to */ 210 mark_bh(CYCLADES_BH); /* then trigger event */ 211} /* ifx_ssc_sched_event */ 212 213 214/* 215 * This routine is used to handle the "bottom half" processing for the 216 * serial driver, known also the "software interrupt" processing. 217 * This processing is done at the kernel interrupt level, after the 218 * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This 219 * is where time-consuming activities which can not be done in the 220 * interrupt driver proper are done; the interrupt driver schedules 221 * them using ifx_ssc_sched_event(), and they get done here. 222 * 223 * This is done through one level of indirection--the task queue. 224 * When a hardware interrupt service routine wants service by the 225 * driver's bottom half, it enqueues the appropriate tq_struct (one 226 * per port) to the tq_cyclades work queue and sets a request flag 227 * via mark_bh for processing that queue. When the time is right, 228 * do_ifx_ssc_bh is called (because of the mark_bh) and it requests 229 * that the work queue be processed. 230 * 231 * Although this may seem unwieldy, it gives the system a way to 232 * pass an argument (in this case the pointer to the ifx_ssc_port 233 * structure) to the bottom half of the driver. Previous kernels 234 * had to poll every port to see if that port needed servicing. 235 */ 236static void 237do_ifx_ssc_bh(void) 238{ 239 run_task_queue(&tq_cyclades); 240} /* do_ifx_ssc_bh */ 241 242static void 243do_softint(void *private_) 244{ 245 struct ifx_ssc_port *info = (struct ifx_ssc_port *) private_; 246 247 if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { 248 wake_up_interruptible(&info->open_wait); 249 info->flags &= ~(ASYNC_NORMAL_ACTIVE| 250 ASYNC_CALLOUT_ACTIVE); 251 } 252 if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) { 253 wake_up_interruptible(&info->open_wait); 254 } 255 if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) { 256 wake_up_interruptible(&info->delta_msr_wait); 257 } 258 if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { 259 wake_up_interruptible(&tty->write_wait); 260 } 261#ifdef Z_WAKE 262 if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) { 263 wake_up_interruptible(&info->shutdown_wait); 264 } 265#endif 266} /* do_softint */ 267#endif /* IFX_SSC_INT_USE_BH */ 268#endif // not_yet 269 270inline static void 271rx_int(struct ifx_ssc_port *info) 272{ 273 int fifo_fill_lev, bytes_in_buf, i; 274 unsigned long tmp_val; 275 unsigned long *tmp_ptr; 276 unsigned int rx_valid_cnt; 277 /* number of words waiting in the RX FIFO */ 278 fifo_fill_lev = (READ_PERIPHERAL_REGISTER(info->mapbase + 279 IFX_SSC_FSTAT) & 280 IFX_SSC_FSTAT_RECEIVED_WORDS_MASK) >> 281 IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET; 282 // Note: There are always 32 bits in a fifo-entry except for the last 283 // word of a contigous transfer block and except for not in rx-only 284 // mode and CON.ENBV set. But for this case it should be a convention 285 // in software which helps: 286 // In tx or rx/tx mode all transfers from the buffer to the FIFO are 287 // 32-bit wide, except for the last three bytes, which could be a 288 // combination of 16- and 8-bit access. 289 // => The whole block is received as 32-bit words as a contigous stream, 290 // even if there was a gap in tx which has the fifo run out of data! 291 // Just the last fifo entry *may* be partially filled (0, 1, 2 or 3 bytes)! 292 293 /* free space in the RX buffer */ 294 bytes_in_buf = info->rxbuf_end - info->rxbuf_ptr; 295 // transfer with 32 bits per entry 296 while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0)) { 297 tmp_ptr = (unsigned long *)info->rxbuf_ptr; 298 *tmp_ptr = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RB); 299 info->rxbuf_ptr += 4; 300 info->stats.rxBytes += 4; 301 fifo_fill_lev --; 302 bytes_in_buf -= 4; 303 } // while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0)) 304 // now do the rest as mentioned in STATE.RXBV 305 while ((bytes_in_buf > 0) && (fifo_fill_lev > 0)) { 306 rx_valid_cnt = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & 307 IFX_SSC_STATE_RX_BYTE_VALID_MASK) >> 308 IFX_SSC_STATE_RX_BYTE_VALID_OFFSET; 309 if (rx_valid_cnt == 0) break; 310 if (rx_valid_cnt > bytes_in_buf) { 311 // ### TO DO: warning message: not block aligned data, other data 312 // in this entry will be lost 313 rx_valid_cnt = bytes_in_buf; 314 } 315 tmp_val = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RB); 316 317 for (i=0; i<rx_valid_cnt; i++) { 318 *info->rxbuf_ptr = (tmp_val >> ( 8 * (rx_valid_cnt - i-1))) & 0xff; 319/* 320 *info->rxbuf_ptr = tmp_val & 0xff; 321 tmp_val >>= 8; 322*/ 323 bytes_in_buf--; 324 325 326 info->rxbuf_ptr++; 327 } 328 info->stats.rxBytes += rx_valid_cnt; 329 } // while ((bytes_in_buf > 0) && (fifo_fill_lev > 0)) 330 331 // check if transfer is complete 332 if (info->rxbuf_ptr >= info->rxbuf_end) { 333 ifx_int_wrapper.disable(info->rxirq); 334 /* wakeup any processes waiting in read() */ 335 wake_up_interruptible(&info->rwait); 336 /* and in poll() */ 337 //wake_up_interruptible(&info->pwait); 338 } else if ((info->opts.modeRxTx == IFX_SSC_MODE_RX) && 339 (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) == 0)) { 340 // if buffer not filled completely and rx request done initiate new transfer 341/* 342 if (info->rxbuf_end - info->rxbuf_ptr < 65536) 343*/ 344 if (info->rxbuf_end - info->rxbuf_ptr < IFX_SSC_RXREQ_BLOCK_SIZE) 345 WRITE_PERIPHERAL_REGISTER((info->rxbuf_end - info->rxbuf_ptr) << 346 IFX_SSC_RXREQ_RXCOUNT_OFFSET, 347 info->mapbase + IFX_SSC_RXREQ); 348 else 349 WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 350 info->mapbase + IFX_SSC_RXREQ); 351 } 352} // rx_int 353 354inline static void 355tx_int(struct ifx_ssc_port *info) 356{ 357 358 int fifo_space, fill, i; 359 fifo_space = ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_ID) & 360 IFX_SSC_PERID_TXFS_MASK) >> IFX_SSC_PERID_TXFS_OFFSET) - 361 ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_FSTAT) & 362 IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK) >> 363 IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET); 364 365 if (fifo_space == 0) 366 return; 367 368 fill = info->txbuf_end - info->txbuf_ptr; 369 370 if (fill > fifo_space * 4) 371 fill = fifo_space * 4; 372 373 for (i = 0; i < fill / 4; i++) { 374 // at first 32 bit access 375 WRITE_PERIPHERAL_REGISTER(*(UINT32 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB); 376 info->txbuf_ptr += 4; 377 } 378 379 fifo_space -= fill / 4; 380 info->stats.txBytes += fill & ~0x3; 381 fill &= 0x3; 382 if ((fifo_space > 0) & (fill > 1)) { 383 // trailing 16 bit access 384 WRITE_PERIPHERAL_REGISTER_16(*(UINT16 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB); 385 info->txbuf_ptr += 2; 386 info->stats.txBytes += 2; 387 fifo_space --; 388/* added by bingtao */ 389 fill -=2; 390 } 391 if ((fifo_space > 0) & (fill > 0)) { 392 // trailing 8 bit access 393 WRITE_PERIPHERAL_REGISTER_8(*(UINT8 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB); 394 info->txbuf_ptr ++; 395 info->stats.txBytes ++; 396/* 397 fifo_space --; 398*/ 399 } 400 401 // check if transmission complete 402 if (info->txbuf_ptr >= info->txbuf_end) { 403 ifx_int_wrapper.disable(info->txirq); 404 kfree(info->txbuf); 405 info->txbuf = NULL; 406 /* wake up any process waiting in poll() */ 407 //wake_up_interruptible(&info->pwait); 408 } 409 410} // tx_int 411 412static void 413ifx_ssc_rx_int(int irq, void *dev_id, struct pt_regs *regs) 414{ 415 struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id; 416 //WRITE_PERIPHERAL_REGISTER(IFX_SSC_R_BIT, info->mapbase + IFX_SSC_IRN_CR); 417 rx_int(info); 418} 419 420static void 421ifx_ssc_tx_int(int irq, void *dev_id, struct pt_regs *regs) 422{ 423 struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id; 424 //WRITE_PERIPHERAL_REGISTER(IFX_SSC_T_BIT, info->mapbase + IFX_SSC_IRN_CR); 425 tx_int(info); 426} 427 428static void 429ifx_ssc_err_int(int irq, void *dev_id, struct pt_regs *regs) 430{ 431 struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id; 432 unsigned int state; 433 unsigned int write_back = 0; 434 unsigned long flags; 435 436 437 local_irq_save(flags); 438 state = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE); 439 440 if ((state & IFX_SSC_STATE_RX_UFL) != 0) { 441 info->stats.rxUnErr++; 442 write_back |= IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR; 443 } 444 if ((state & IFX_SSC_STATE_RX_OFL) != 0) { 445 info->stats.rxOvErr++; 446 write_back |= IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR; 447 } 448 if ((state & IFX_SSC_STATE_TX_OFL) != 0) { 449 info->stats.txOvErr++; 450 write_back |= IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR; 451 } 452 if ((state & IFX_SSC_STATE_TX_UFL) != 0) { 453 info->stats.txUnErr++; 454 write_back |= IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR; 455 } 456// if ((state & IFX_SSC_STATE_ABORT_ERR) != 0) { 457// info->stats.abortErr++; 458// write_back |= IFX_SSC_WHBSTATE_CLR_ABORT_ERROR; 459// } 460 if ((state & IFX_SSC_STATE_MODE_ERR) != 0) { 461 info->stats.modeErr++; 462 write_back |= IFX_SSC_WHBSTATE_CLR_MODE_ERROR; 463 } 464 465 if (write_back) 466 WRITE_PERIPHERAL_REGISTER(write_back, 467 info->mapbase + IFX_SSC_WHBSTATE); 468 469 local_irq_restore(flags); 470} 471 472#ifdef SSC_FRAME_INT_ENABLE 473static void 474ifx_ssc_frm_int(int irq, void *dev_id, struct pt_regs *regs) 475{ 476 // ### TO DO: wake up framing wait-queue in conjunction with batch execution 477} 478#endif 479 480static void 481ifx_ssc_abort(struct ifx_ssc_port *info) 482{ 483 unsigned long flags; 484 bool enabled; 485 486 local_irq_save(flags); 487 488 // disable all int's 489 ifx_int_wrapper.disable(info->rxirq); 490 ifx_int_wrapper.disable(info->txirq); 491 ifx_int_wrapper.disable(info->errirq); 492/* 493 ifx_int_wrapper.disable(info->frmirq); 494*/ 495 local_irq_restore(flags); 496 497 // disable SSC (also aborts a receive request!) 498 // ### TO DO: Perhaps it's better to abort after the receiption of a 499 // complete word. The disable cuts the transmission immediatly and 500 // releases the chip selects. This could result in unpredictable 501 // behavior of connected external devices! 502 enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 503 & IFX_SSC_STATE_IS_ENABLED) != 0; 504 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, 505 info->mapbase + IFX_SSC_WHBSTATE); 506 507 508 // flush fifos 509 WRITE_PERIPHERAL_REGISTER(IFX_SSC_XFCON_FIFO_FLUSH, 510 info->mapbase + IFX_SSC_TXFCON); 511 WRITE_PERIPHERAL_REGISTER(IFX_SSC_XFCON_FIFO_FLUSH, 512 info->mapbase + IFX_SSC_RXFCON); 513 514 // free txbuf 515 if (info->txbuf != NULL) { 516 kfree(info->txbuf); 517 info->txbuf = NULL; 518 } 519 520 // wakeup read process 521 if (info->rxbuf != NULL) 522 wake_up_interruptible(&info->rwait); 523 524 // clear pending int's 525 ifx_int_wrapper.clear(info->rxirq); 526 ifx_int_wrapper.clear(info->txirq); 527 ifx_int_wrapper.clear(info->errirq); 528/* 529 ifx_int_wrapper.clear(info->frmirq); 530*/ 531 532 // clear error flags 533 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ALL_ERROR, 534 info->mapbase + IFX_SSC_WHBSTATE); 535 536 //printk("IFX SSC%d: Transmission aborted\n", info->port_nr); 537 // enable SSC 538 if (enabled) 539 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, 540 info->mapbase + IFX_SSC_WHBSTATE); 541 542} // ifx_ssc_abort 543 544 545/* 546 * This routine is called whenever a port is opened. It enforces 547 * exclusive opening of a port and enables interrupts, etc. 548 */ 549int 550ifx_ssc_open(struct inode *inode, struct file * filp) 551{ 552 struct ifx_ssc_port *info; 553 int line; 554 int from_kernel = 0; 555 556 if ((inode == (struct inode *)0) || (inode == (struct inode *)1)) { 557 from_kernel = 1; 558 line = (int)inode; 559 } 560 else { 561 line = MINOR(filp->f_dentry->d_inode->i_rdev); 562 filp->f_op = &ifx_ssc_fops; 563 } 564 565 /* don't open more minor devices than we can support */ 566 if (line < 0 || line >= PORT_CNT) 567 return -ENXIO; 568 569 info = &isp[line]; 570 571 /* exclusive open */ 572 if (info->port_is_open != 0) 573 return -EBUSY; 574 info->port_is_open++; 575 576 ifx_int_wrapper.disable(info->rxirq); 577 ifx_int_wrapper.disable(info->txirq); 578 ifx_int_wrapper.disable(info->errirq); 579/* 580 ifx_int_wrapper.disable(info->frmirq); 581*/ 582 583 /* Flush and enable TX/RX FIFO */ 584 WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_TXFIFO_FL << 585 IFX_SSC_XFCON_ITL_OFFSET) | 586 IFX_SSC_XFCON_FIFO_FLUSH | 587 IFX_SSC_XFCON_FIFO_ENABLE, 588 info->mapbase + IFX_SSC_TXFCON); 589 WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_RXFIFO_FL << 590 IFX_SSC_XFCON_ITL_OFFSET) | 591 IFX_SSC_XFCON_FIFO_FLUSH | 592 IFX_SSC_XFCON_FIFO_ENABLE, 593 info->mapbase + IFX_SSC_RXFCON); 594 595 596 /* logically flush the software FIFOs */ 597 info->rxbuf_ptr = 0; 598 info->txbuf_ptr = 0; 599 600 /* clear all error bits */ 601 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ALL_ERROR, 602 info->mapbase + IFX_SSC_WHBSTATE); 603 604 // clear pending interrupts 605 ifx_int_wrapper.clear(info->rxirq); 606 ifx_int_wrapper.clear(info->txirq); 607 ifx_int_wrapper.clear(info->errirq); 608/* 609 ifx_int_wrapper.clear(info->frmirq); 610*/ 611 612 // enable SSC 613 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, 614 info->mapbase + IFX_SSC_WHBSTATE); 615 616 MOD_INC_USE_COUNT; 617 618 return 0; 619} /* ifx_ssc_open */ 620EXPORT_SYMBOL(ifx_ssc_open); 621 622/* 623 * This routine is called when a particular device is closed. 624 */ 625int 626ifx_ssc_close(struct inode *inode, struct file *filp) 627{ 628 struct ifx_ssc_port *info; 629 int idx; 630 631 if ((inode == (struct inode *)0) || (inode == (struct inode *)1)) 632 idx = (int)inode; 633 else 634 idx = MINOR(filp->f_dentry->d_inode->i_rdev); 635 636 if (idx < 0 || idx >= PORT_CNT) 637 return -ENXIO; 638 639 info = &isp[idx]; 640 if (!info) 641 return -ENXIO; 642 643 // disable SSC 644 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, 645 info->mapbase + IFX_SSC_WHBSTATE); 646 647 // call abort function to disable int's, flush fifos... 648 ifx_ssc_abort(info); 649 650 info->port_is_open --; 651 MOD_DEC_USE_COUNT; 652 653 return 0; 654} /* ifx_ssc_close */ 655EXPORT_SYMBOL(ifx_ssc_close); 656 657/* added by bingtao */ 658/* helper routine to handle reads from the kernel or user-space */ 659/* info->rxbuf : never kfree and contains valid data */ 660/* should be points to NULL after copying data !!! */ 661static ssize_t 662ifx_ssc_read_helper_poll(struct ifx_ssc_port *info, char *buf, size_t len, 663 int from_kernel) 664{ 665 ssize_t ret_val; 666 unsigned long flags; 667 668 if (info->opts.modeRxTx == IFX_SSC_MODE_TX) 669 return -EFAULT; 670 local_irq_save(flags); 671 info->rxbuf_ptr = info->rxbuf; 672 info->rxbuf_end = info->rxbuf + len; 673 local_irq_restore(flags); 674/* Vinetic driver always works in IFX_SSC_MODE_RXTX */ 675/* TXRX in poll mode */ 676 while (info->rxbuf_ptr < info->rxbuf_end){ 677/* This is the key point, if you don't check this condition 678 kfree (NULL) will happen 679 because tx only need write into FIFO, it's much fast than rx 680 So when rx still waiting , tx already finish and release buf 681*/ 682 if (info->txbuf_ptr < info->txbuf_end) { 683 tx_int(info); 684 } 685 686 rx_int(info); 687 }; 688 689 ret_val = info->rxbuf_ptr - info->rxbuf; 690 return (ret_val); 691} // ifx_ssc_read_helper_poll 692 693/* helper routine to handle reads from the kernel or user-space */ 694/* info->rx_buf : never kfree and contains valid data */ 695/* should be points to NULL after copying data !!! */ 696static ssize_t 697ifx_ssc_read_helper(struct ifx_ssc_port *info, char *buf, size_t len, 698 int from_kernel) 699{ 700 ssize_t ret_val; 701 unsigned long flags; 702 DECLARE_WAITQUEUE(wait, current); 703 704 if (info->opts.modeRxTx == IFX_SSC_MODE_TX) 705 return -EFAULT; 706 local_irq_save(flags); 707 info->rxbuf_ptr = info->rxbuf; 708 info->rxbuf_end = info->rxbuf + len; 709 if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) { 710 if ((info->txbuf == NULL) || 711 (info->txbuf != info->txbuf_ptr) || 712 (info->txbuf_end != len + info->txbuf)) { 713 local_irq_restore(flags); 714 printk("IFX SSC - %s: write must be called before calling " 715 "read in combined RX/TX!\n", __FUNCTION__); 716 return -EFAULT; 717 } 718 local_irq_restore(flags); 719 /* should enable tx, right?*/ 720 tx_int(info); 721 if (info->txbuf_ptr < info->txbuf_end){ 722 ifx_int_wrapper.enable(info->txirq); 723 } 724 725 ifx_int_wrapper.enable(info->rxirq); 726 } else { // rx mode 727 local_irq_restore(flags); 728 if (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) & 729 IFX_SSC_RXCNT_TODO_MASK) 730 return -EBUSY; 731 ifx_int_wrapper.enable(info->rxirq); 732 // rx request limited to ' bytes 733/* 734 if (len < 65536) 735*/ 736 if (len < IFX_SSC_RXREQ_BLOCK_SIZE) 737 WRITE_PERIPHERAL_REGISTER(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 738 info->mapbase + IFX_SSC_RXREQ); 739 else 740 WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 741 info->mapbase + IFX_SSC_RXREQ); 742 } 743 744 __add_wait_queue(&info->rwait, &wait); 745 set_current_state(TASK_INTERRUPTIBLE); 746 // wakeup done in rx_int 747 748 do { 749 local_irq_save(flags); 750 if (info->rxbuf_ptr >= info->rxbuf_end) 751 break; 752 local_irq_restore(flags); 753 754// if (filp->f_flags & O_NONBLOCK) 755// { 756// N = -EAGAIN; 757// goto out; 758// } 759 if (signal_pending(current)) { 760 ret_val = -ERESTARTSYS; 761 goto out; 762 } 763 schedule(); 764 } while (1); 765 766 ret_val = info->rxbuf_ptr - info->rxbuf; // should be equal to len 767 local_irq_restore(flags); 768 769 out: 770 current->state = TASK_RUNNING; 771 __remove_wait_queue(&info->rwait, &wait); 772 return (ret_val); 773} // ifx_ssc_read_helper 774 775 776#if 0 777/* helper routine to handle reads from the kernel or user-space */ 778/* appropriate in interrupt context */ 779static ssize_t 780ifx_ssc_read_helper(struct ifx_ssc_port *info, char *buf, size_t len, 781 int from_kernel) 782{ 783 ssize_t ret_val; 784 unsigned long flags; 785 DECLARE_WAITQUEUE(wait, current); 786 787 if (info->opts.modeRxTx == IFX_SSC_MODE_TX) 788 return -EFAULT; 789 local_irq_save(flags); 790 info->rxbuf_ptr = info->rxbuf; 791 info->rxbuf_end = info->rxbuf + len; 792 if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) { 793 if ((info->txbuf == NULL) || 794 (info->txbuf != info->txbuf_ptr) || 795 (info->txbuf_end != len + info->txbuf)) { 796 local_irq_restore(flags); 797 printk("IFX SSC - %s: write must be called before calling " 798 "read in combined RX/TX!\n", __FUNCTION__); 799 return -EFAULT; 800 } 801 local_irq_restore(flags); 802 /* should enable tx, right?*/ 803 tx_int(info); 804 if (!in_irq()){ 805 if (info->txbuf_ptr < info->txbuf_end){ 806 ifx_int_wrapper.enable(info->txirq); 807 } 808 ifx_int_wrapper.enable(info->rxirq); 809 } 810 } else { // rx mode 811 local_irq_restore(flags); 812 if (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) & 813 IFX_SSC_RXCNT_TODO_MASK) 814 return -EBUSY; 815 if (!in_irq()){ 816 ifx_int_wrapper.enable(info->rxirq); 817 } 818 819 if (len < IFX_SSC_RXREQ_BLOCK_SIZE) 820 WRITE_PERIPHERAL_REGISTER(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 821 info->mapbase + IFX_SSC_RXREQ); 822 else 823 WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 824 info->mapbase + IFX_SSC_RXREQ); 825 } 826 if (in_irq()){ 827 do { 828 rx_int(info); 829 if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) { 830 tx_int(info); 831 } 832 833 if (info->rxbuf_ptr >= info->rxbuf_end) 834 break; 835 } while (1); 836 ret_val = info->rxbuf_ptr - info->rxbuf; 837 }else{ 838 __add_wait_queue(&info->rwait, &wait); 839 set_current_state(TASK_INTERRUPTIBLE); 840 // wakeup done in rx_int 841 842 do { 843 local_irq_save(flags); 844 if (info->rxbuf_ptr >= info->rxbuf_end) 845 break; 846 local_irq_restore(flags); 847 848 if (signal_pending(current)) { 849 ret_val = -ERESTARTSYS; 850 goto out; 851 } 852 schedule(); 853 } while (1); 854 855 ret_val = info->rxbuf_ptr - info->rxbuf; // should be equal to len 856 local_irq_restore(flags); 857 858 out: 859 current->state = TASK_RUNNING; 860 __remove_wait_queue(&info->rwait, &wait); 861 } 862 return (ret_val); 863} // ifx_ssc_read_helper 864#endif 865 866/* helper routine to handle writes to the kernel or user-space */ 867/* info->txbuf has two cases: 868 * 1) return value < 0 (-EFAULT), not touched at all 869 * 2) kfree and points to NULL in interrupt routine (but maybe later ) 870 */ 871static ssize_t 872ifx_ssc_write_helper(struct ifx_ssc_port *info, const char *buf, 873 size_t len, int from_kernel) 874{ 875 // check if in tx or tx/rx mode 876 if (info->opts.modeRxTx == IFX_SSC_MODE_RX) 877 return -EFAULT; 878 879 info->txbuf_ptr = info->txbuf; 880 info->txbuf_end = len + info->txbuf; 881 /* start the transmission (not in rx/tx, see read helper) */ 882 if (info->opts.modeRxTx == IFX_SSC_MODE_TX) { 883 tx_int(info); 884 if (info->txbuf_ptr < info->txbuf_end){ 885 ifx_int_wrapper.enable(info->txirq); 886 } 887 } 888 //local_irq_restore(flags); 889 return len; 890} 891 892/* 893 * kernel interfaces for read and write. 894 * The caller must set port to: n for SSC<m> with n=m-1 (e.g. n=0 for SSC1) 895 */ 896ssize_t 897ifx_ssc_kread(int port, char *kbuf, size_t len) 898{ 899 struct ifx_ssc_port *info; 900 ssize_t ret_val; 901 902 if (port < 0 || port >= PORT_CNT) 903 return -ENXIO; 904 905 if (len == 0) 906 return 0; 907 908 info = &isp[port]; 909 910 // check if reception in progress 911 if (info->rxbuf != NULL){ 912 printk("SSC device busy\n"); 913 return -EBUSY; 914 } 915 916 info->rxbuf = kbuf; 917 if (info->rxbuf == NULL){ 918 printk("SSC device error\n"); 919 return -EINVAL; 920 } 921 922/* changed by bingtao */ 923 /* change by TaiCheng */ 924 //if (!in_irq()){ 925 if (0){ 926 ret_val = ifx_ssc_read_helper(info, kbuf, len, 1); 927 }else{ 928 ret_val = ifx_ssc_read_helper_poll(info, kbuf, len, 1); 929 }; 930 info->rxbuf = NULL; 931 932 // ### TO DO: perhaps warn if ret_val != len 933 ifx_int_wrapper.disable(info->rxirq); 934 935 return (ret_val); 936} // ifx_ssc_kread 937EXPORT_SYMBOL(ifx_ssc_kread); 938 939ssize_t 940ifx_ssc_kwrite(int port, const char *kbuf, size_t len) 941{ 942 struct ifx_ssc_port *info; 943 ssize_t ret_val; 944 945 if (port < 0 || port >= PORT_CNT) 946 return -ENXIO; 947 948 if (len == 0) 949 return 0; 950 951 info = &isp[port]; 952 953 // check if transmission in progress 954 if (info->txbuf != NULL) 955 return -EBUSY; 956 info->txbuf = (char *)kbuf; 957 958 ret_val = ifx_ssc_write_helper(info, info->txbuf, len, 1); 959 if (ret_val < 0){ 960 info->txbuf = NULL; 961 } 962 return ret_val; 963} 964EXPORT_SYMBOL(ifx_ssc_kwrite); 965 966 967/* 968 * user interfaces to read and write 969 */ 970static ssize_t 971ifx_ssc_read(struct file *filp, char *ubuf, size_t len, loff_t *off) 972{ 973 ssize_t ret_val; 974 int idx; 975 struct ifx_ssc_port *info; 976 977/* 978 if (len == 0) 979 return (0); 980*/ 981 idx = MINOR(filp->f_dentry->d_inode->i_rdev); 982 info = &isp[idx]; 983 984 // check if reception in progress 985 if (info->rxbuf != NULL) 986 return -EBUSY; 987 988 info->rxbuf = kmalloc(len+ 3, GFP_KERNEL); 989 if (info->rxbuf == NULL) 990 return -ENOMEM; 991 992 ret_val = ifx_ssc_read_helper(info, info->rxbuf, len, 0); 993 // ### TO DO: perhaps warn if ret_val != len 994 if (copy_to_user((void*)ubuf, info->rxbuf, ret_val) != 0) 995 ret_val = -EFAULT; 996 997 ifx_int_wrapper.disable(info->rxirq); 998 999 kfree(info->rxbuf); 1000 info->rxbuf = NULL; 1001 return (ret_val); 1002} // ifx_ssc_read 1003 1004/* 1005 * As many bytes as we have free space for are copied from the user 1006 * into txbuf and the actual byte count is returned. The transmission is 1007 * always kicked off by calling the appropriate TX routine. 1008 */ 1009static ssize_t 1010ifx_ssc_write(struct file *filp, const char *ubuf, size_t len, loff_t *off) 1011{ 1012 int idx; 1013 struct ifx_ssc_port *info; 1014 int ret_val; 1015 1016 if (len == 0) 1017 return (0); 1018 1019 idx = MINOR(filp->f_dentry->d_inode->i_rdev); 1020 info = &isp[idx]; 1021 1022 // check if transmission in progress 1023 if (info->txbuf != NULL) 1024 return -EBUSY; 1025 1026 info->txbuf = kmalloc(len+ 3, GFP_KERNEL); 1027 if (info->txbuf == NULL) 1028 return -ENOMEM; 1029 1030 ret_val = copy_from_user(info->txbuf, ubuf, len); 1031 if (ret_val == 0) 1032 ret_val = ifx_ssc_write_helper(info, info->txbuf, len, 0); 1033 else 1034 ret_val = -EFAULT; 1035 if (ret_val < 0) { 1036 kfree(info->txbuf); // otherwise will be done in ISR 1037 info->txbuf = NULL; 1038 } 1039 return (ret_val); 1040} /* ifx_ssc_write */ 1041 1042 1043/* 1044 * ------------------------------------------------------------ 1045 * ifx_ssc_ioctl() and friends 1046 * ------------------------------------------------------------ 1047 */ 1048 1049/*----------------------------------------------------------------------------- 1050 FUNC-NAME : ifx_ssc_frm_status_get 1051 LONG-NAME : framing status get 1052 PURPOSE : Get the actual status of the framing. 1053 1054 PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. 1055 1056 RESULT : pointer to a structure ifx_ssc_frm_status which holds busy and 1057 count values. 1058 1059 REMARKS : Returns a register value independent of framing is enabled or 1060 not! Changes structure inside of info, so the return value isn't 1061 needed at all, but could be used for simple access. 1062-----------------------------------------------------------------------------*/ 1063static struct ifx_ssc_frm_status * 1064ifx_ssc_frm_status_get(struct ifx_ssc_port *info) 1065{ 1066 unsigned long tmp; 1067 1068 tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFSTAT); 1069 info->frm_status.DataBusy = (tmp & IFX_SSC_SFSTAT_IN_DATA) > 0; 1070 info->frm_status.PauseBusy = (tmp & IFX_SSC_SFSTAT_IN_PAUSE) > 0; 1071 info->frm_status.DataCount = (tmp & IFX_SSC_SFSTAT_DATA_COUNT_MASK) 1072 >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET; 1073 info->frm_status.PauseCount = (tmp & IFX_SSC_SFSTAT_PAUSE_COUNT_MASK) 1074 >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET; 1075 tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON); 1076 info->frm_status.EnIntAfterData = 1077 (tmp & IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE) > 0; 1078 info->frm_status.EnIntAfterPause = 1079 (tmp & IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE) > 0; 1080 return (&info->frm_status); 1081} // ifx_ssc_frm_status_get 1082 1083 1084/*----------------------------------------------------------------------------- 1085 FUNC-NAME : ifx_ssc_frm_control_get 1086 LONG-NAME : framing control get 1087 PURPOSE : Get the actual control values of the framing. 1088 1089 PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. 1090 1091 RESULT : pointer to a structure ifx_ssc_frm_opts which holds control bits 1092 and count reload values. 1093 1094 REMARKS : Changes structure inside of info, so the return value isn't 1095 needed at all, but could be used for simple access. 1096-----------------------------------------------------------------------------*/ 1097static struct ifx_ssc_frm_opts * 1098ifx_ssc_frm_control_get(struct ifx_ssc_port *info) 1099{ 1100 unsigned long tmp; 1101 1102 tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON); 1103 info->frm_opts.FrameEnable = (tmp & IFX_SSC_SFCON_SF_ENABLE) > 0; 1104 info->frm_opts.DataLength = (tmp & IFX_SSC_SFCON_DATA_LENGTH_MASK) 1105 >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET; 1106 info->frm_opts.PauseLength = (tmp & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) 1107 >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET; 1108 info->frm_opts.IdleData = (tmp & IFX_SSC_SFCON_PAUSE_DATA_MASK) 1109 >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET; 1110 info->frm_opts.IdleClock = (tmp & IFX_SSC_SFCON_PAUSE_CLOCK_MASK) 1111 >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET; 1112 info->frm_opts.StopAfterPause = 1113 (tmp & IFX_SSC_SFCON_STOP_AFTER_PAUSE) > 0; 1114 return (&info->frm_opts); 1115} // ifx_ssc_frm_control_get 1116 1117 1118/*----------------------------------------------------------------------------- 1119 FUNC-NAME : ifx_ssc_frm_control_set 1120 LONG-NAME : framing control set 1121 PURPOSE : Set the actual control values of the framing. 1122 1123 PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. 1124 1125 RESULT : pointer to a structure ifx_ssc_frm_opts which holds control bits 1126 and count reload values. 1127 1128 REMARKS : 1129-----------------------------------------------------------------------------*/ 1130static int 1131ifx_ssc_frm_control_set(struct ifx_ssc_port *info) 1132{ 1133 unsigned long tmp; 1134 1135 // check parameters 1136 if ((info->frm_opts.DataLength > IFX_SSC_SFCON_DATA_LENGTH_MAX) || 1137 (info->frm_opts.DataLength < 1) || 1138 (info->frm_opts.PauseLength > IFX_SSC_SFCON_PAUSE_LENGTH_MAX) || 1139 (info->frm_opts.PauseLength < 1) || 1140 ((info->frm_opts.IdleData & ~(IFX_SSC_SFCON_PAUSE_DATA_MASK >> 1141 IFX_SSC_SFCON_PAUSE_DATA_OFFSET)) != 0 ) || 1142 ((info->frm_opts.IdleClock & ~(IFX_SSC_SFCON_PAUSE_CLOCK_MASK >> 1143 IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET)) != 0 )) 1144 return -EINVAL; 1145 1146 // read interrupt bits (they're not changed here) 1147 tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON) & 1148 (IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE | 1149 IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE); 1150 1151 // set all values with respect to it's bit position (for data and pause 1152 // length set N-1) 1153 tmp = (info->frm_opts.DataLength - 1) << IFX_SSC_SFCON_DATA_LENGTH_OFFSET; 1154 tmp |= (info->frm_opts.PauseLength - 1) << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET; 1155 tmp |= info->frm_opts.IdleData << IFX_SSC_SFCON_PAUSE_DATA_OFFSET; 1156 tmp |= info->frm_opts.IdleClock << IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET; 1157 tmp |= info->frm_opts.FrameEnable * IFX_SSC_SFCON_SF_ENABLE; 1158 tmp |= info->frm_opts.StopAfterPause * IFX_SSC_SFCON_STOP_AFTER_PAUSE; 1159 1160 WRITE_PERIPHERAL_REGISTER(tmp, info->mapbase + IFX_SSC_SFCON); 1161 1162 return 0; 1163} // ifx_ssc_frm_control_set 1164 1165 1166/*----------------------------------------------------------------------------- 1167 FUNC-NAME : ifx_ssc_rxtx_mode_set 1168 LONG-NAME : rxtx mode set 1169 PURPOSE : Set the transmission mode. 1170 1171 PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. 1172 1173 RESULT : Returns error code 1174 1175 REMARKS : Assumes that SSC not used (SSC disabled, device not opened yet 1176 or just closed) 1177-----------------------------------------------------------------------------*/ 1178static int 1179ifx_ssc_rxtx_mode_set(struct ifx_ssc_port *info, unsigned int val) 1180{ 1181 unsigned long tmp; 1182 1183 // check parameters 1184 if (!(info) || (val & ~(IFX_SSC_MODE_MASK))) 1185 return -EINVAL; 1186 /*check BUSY and RXCNT*/ 1187 if ( READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & IFX_SSC_STATE_BUSY 1188 ||READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) & IFX_SSC_RXCNT_TODO_MASK) 1189 return -EBUSY; 1190 // modify 1191 tmp = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CON) & 1192 ~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF)) | (val); 1193 WRITE_PERIPHERAL_REGISTER(tmp, info->mapbase + IFX_SSC_CON); 1194 info->opts.modeRxTx = val; 1195/* 1196 printk(KERN_DEBUG "IFX SSC%d: Setting mode to %s%s\n", 1197 info->port_nr, 1198 ((val & IFX_SSC_CON_RX_OFF) == 0) ? "rx ":"", 1199 ((val & IFX_SSC_CON_TX_OFF) == 0) ? "tx":""); 1200*/ 1201 return 0; 1202} // ifx_ssc_rxtx_mode_set 1203 1204void ifx_gpio_init(void) 1205{ 1206 u32 temp; 1207/* set gpio pin p0.10(SPI_DIN) p0.11(SPI_DOUT) p0.12(SPI_CLK) p0.13(SPI_CS2) direction */ 1208 temp = *(AMAZON_GPIO_P0_DIR) ; 1209 temp &= 0xFFFFFBFF; 1210 temp |= 0x3800; 1211 *(AMAZON_GPIO_P0_DIR) = temp; 1212/* set port 0 alternate select register 0 */ 1213 temp = *(AMAZON_GPIO_P0_ALTSEL0) ; 1214 temp &= 0xFFFFC3FF; 1215 temp |= 0x00001c00; 1216 *(AMAZON_GPIO_P0_ALTSEL0) = temp; 1217 1218/* set port 0 alternate select register 1 */ 1219 temp = *(AMAZON_GPIO_P0_ALTSEL1) ; 1220 temp &= 0xFFFFC3FF; 1221 temp |= 0x00002000; 1222 *(AMAZON_GPIO_P0_ALTSEL1) = temp; 1223 1224/* set port 0 open drain mode register */ 1225 temp = *(AMAZON_GPIO_P0_OD); 1226 temp |= 0x00003800; /* set output pin normal mode */ 1227 *(AMAZON_GPIO_P0_OD)= temp; 1228} 1229 1230/* 1231 * This routine intializes the SSC appropriately depending 1232 * on slave/master and full-/half-duplex mode. 1233 * It assumes that the SSC is disabled and the fifo's and buffers 1234 * are flushes later on. 1235 */ 1236static int 1237ifx_ssc_sethwopts(struct ifx_ssc_port *info) 1238{ 1239 unsigned long flags, bits; 1240 struct ifx_ssc_hwopts *opts = &info->opts; 1241 1242 /* sanity checks */ 1243 if ((opts->dataWidth < IFX_SSC_MIN_DATA_WIDTH) || 1244 (opts->dataWidth > IFX_SSC_MAX_DATA_WIDTH)) { 1245 printk("%s: sanity check failed\n", __FUNCTION__); 1246 return -EINVAL; 1247 } 1248 bits = (opts->dataWidth - 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET; 1249 bits |= IFX_SSC_CON_ENABLE_BYTE_VALID; 1250// if (opts->abortErrDetect) 1251// bits |= IFX_SSC_CON_ABORT_ERR_CHECK; 1252 if (opts->rxOvErrDetect) 1253 bits |= IFX_SSC_CON_RX_OFL_CHECK; 1254 if (opts->rxUndErrDetect) 1255 bits |= IFX_SSC_CON_RX_UFL_CHECK; 1256 if (opts->txOvErrDetect) 1257 bits |= IFX_SSC_CON_TX_OFL_CHECK; 1258 if (opts->txUndErrDetect) 1259 bits |= IFX_SSC_CON_TX_UFL_CHECK; 1260 if (opts->loopBack) 1261 bits |= IFX_SSC_CON_LOOPBACK_MODE; 1262 if (opts->echoMode) 1263 bits |= IFX_SSC_CON_ECHO_MODE_ON; 1264 if (opts->headingControl) 1265 bits |= IFX_SSC_CON_MSB_FIRST; 1266 if (opts->clockPhase) 1267 bits |= IFX_SSC_CON_LATCH_THEN_SHIFT; 1268 if (opts->clockPolarity) 1269 bits |= IFX_SSC_CON_CLOCK_FALL; 1270 switch (opts->modeRxTx) { 1271 case IFX_SSC_MODE_TX: 1272 bits |= IFX_SSC_CON_RX_OFF; 1273 break; 1274 case IFX_SSC_MODE_RX: 1275 bits |= IFX_SSC_CON_TX_OFF; 1276 break; 1277 } // switch (opts->modeRxT) 1278 local_irq_save(flags); 1279 WRITE_PERIPHERAL_REGISTER(bits, info->mapbase + IFX_SSC_CON); 1280 WRITE_PERIPHERAL_REGISTER((info->opts.gpoCs << IFX_SSC_GPOCON_ISCSB0_POS) | 1281 (info->opts.gpoInv << IFX_SSC_GPOCON_INVOUT0_POS), 1282 info->mapbase + IFX_SSC_GPOCON); 1283 //master mode 1284 if (opts->masterSelect){ 1285 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_MASTER_SELECT,info->mapbase + IFX_SSC_WHBSTATE); 1286 }else{ 1287 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_MASTER_SELECT,info->mapbase + IFX_SSC_WHBSTATE); 1288 } 1289 // init serial framing 1290 WRITE_PERIPHERAL_REGISTER(0, info->mapbase + IFX_SSC_SFCON); 1291 /* set up the port pins */ 1292 //check for general requirements to switch (external) pad/pin characteristics 1293 ifx_gpio_init(); 1294 local_irq_restore(flags); 1295 1296 return 0; 1297} // ifx_ssc_sethwopts 1298 1299static int 1300ifx_ssc_set_baud(struct ifx_ssc_port *info, unsigned int baud) 1301{ 1302 unsigned int ifx_ssc_clock; 1303 unsigned int br; 1304 unsigned long flags; 1305 bool enabled; 1306 1307 ifx_ssc_clock = ifx_ssc_get_kernel_clk(info); 1308 if (ifx_ssc_clock ==0) 1309 return -EINVAL; 1310 1311 local_irq_save(flags); 1312 /* have to disable the SSC to set the baudrate */ 1313 enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 1314 & IFX_SSC_STATE_IS_ENABLED) != 0; 1315 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, 1316 info->mapbase + IFX_SSC_WHBSTATE); 1317 1318 // compute divider 1319 br = ((ifx_ssc_clock >> 1)/baud) - 1; 1320 asm("SYNC"); 1321 if (br > 0xffff || 1322 ((br == 0) && 1323 ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & 1324 IFX_SSC_STATE_IS_MASTER) == 0))){ 1325 local_irq_restore(flags); 1326 printk("%s: illegal baudrate %u\n", __FUNCTION__, baud); 1327 return -EINVAL; 1328 } 1329 WRITE_PERIPHERAL_REGISTER(br, info->mapbase + IFX_SSC_BR); 1330 if (enabled) 1331 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, 1332 info->mapbase + IFX_SSC_WHBSTATE); 1333 1334 local_irq_restore(flags); 1335 return 0; 1336} // ifx_ssc_set_baud 1337 1338static int 1339ifx_ssc_hwinit(struct ifx_ssc_port *info) 1340{ 1341 unsigned long flags; 1342 bool enabled; 1343 1344 /* have to disable the SSC */ 1345 enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 1346 & IFX_SSC_STATE_IS_ENABLED) != 0; 1347 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, 1348 info->mapbase + IFX_SSC_WHBSTATE); 1349 1350 if (ifx_ssc_sethwopts(info) < 0) 1351 { 1352 printk("%s: setting the hardware options failed\n", 1353 __FUNCTION__); 1354 return -EINVAL; 1355 } 1356 1357 if (ifx_ssc_set_baud(info, info->baud) < 0) { 1358 printk("%s: setting the baud rate failed\n", __FUNCTION__); 1359 return -EINVAL; 1360 } 1361 local_irq_save(flags); 1362 /* TX FIFO */ 1363 WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_TXFIFO_FL << 1364 IFX_SSC_XFCON_ITL_OFFSET) | 1365 IFX_SSC_XFCON_FIFO_ENABLE, 1366 info->mapbase + IFX_SSC_TXFCON); 1367 /* RX FIFO */ 1368 WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_RXFIFO_FL << 1369 IFX_SSC_XFCON_ITL_OFFSET) | 1370 IFX_SSC_XFCON_FIFO_ENABLE, 1371 info->mapbase + IFX_SSC_RXFCON); 1372 local_irq_restore(flags); 1373 if (enabled) 1374 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, 1375 info->mapbase + IFX_SSC_WHBSTATE); 1376 return 0; 1377} // ifx_ssc_hwinit 1378 1379/*----------------------------------------------------------------------------- 1380 FUNC-NAME : ifx_ssc_batch_exec 1381 LONG-NAME : 1382 PURPOSE : 1383 1384 PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. 1385 1386 RESULT : Returns error code 1387 1388 REMARKS : 1389-----------------------------------------------------------------------------*/ 1390static int 1391ifx_ssc_batch_exec(struct ifx_ssc_port *info, struct ifx_ssc_batch_list *batch_anchor) 1392{ 1393 // ### TO DO: implement user space batch execution 1394 // first, copy the whole linked list from user to kernel space 1395 // save some hardware options 1396 // execute list 1397 // restore hardware options if selected 1398 return -EFAULT; 1399} // ifx_ssc_batch_exec 1400 1401 1402/* 1403 * This routine allows the driver to implement device- 1404 * specific ioctl's. If the ioctl number passed in cmd is 1405 * not recognized by the driver, it should return ENOIOCTLCMD. 1406 */ 1407int 1408ifx_ssc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 1409 unsigned long data) 1410{ 1411 struct ifx_ssc_port *info; 1412 int line, ret_val = 0; 1413 unsigned long flags; 1414 unsigned long tmp; 1415 int from_kernel = 0; 1416 1417 if ((inode == (struct inode *)0) || (inode == (struct inode *)1)) 1418 { 1419 from_kernel = 1; 1420 line = (int)inode; 1421 } 1422 else 1423 line = MINOR(filp->f_dentry->d_inode->i_rdev); 1424 1425 /* don't use more minor devices than we can support */ 1426 if (line < 0 || line >= PORT_CNT) 1427 return -ENXIO; 1428 1429 info = &isp[line]; 1430 1431 switch (cmd) { 1432 case IFX_SSC_STATS_READ: 1433 /* data must be a pointer to a struct ifx_ssc_statistics */ 1434 if (from_kernel) 1435 memcpy((void *)data, (void *)&info->stats, 1436 sizeof(struct ifx_ssc_statistics)); 1437 else 1438 if (copy_to_user((void *)data, 1439 (void *)&info->stats, 1440 sizeof(struct ifx_ssc_statistics))) 1441 ret_val = -EFAULT; 1442 break; 1443 case IFX_SSC_STATS_RESET: 1444 /* just resets the statistics counters */ 1445 memset((void *)&info->stats, 0, sizeof(struct ifx_ssc_statistics)); 1446 break; 1447 case IFX_SSC_BAUD_SET: 1448 /* if the buffers are not empty then the port is */ 1449 /* busy and we shouldn't change things on-the-fly! */ 1450 if (!info->txbuf || !info->rxbuf || 1451 (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 1452 & IFX_SSC_STATE_BUSY)) { 1453 ret_val = -EBUSY; 1454 break; 1455 } 1456 /* misuse flags */ 1457 if (from_kernel) 1458 flags = *((unsigned long *)data); 1459 else 1460 if (copy_from_user((void *)&flags, 1461 (void *)data, sizeof(flags))) 1462 { 1463 ret_val = -EFAULT; 1464 break; 1465 } 1466 if (flags == 0) 1467 { 1468 ret_val = -EINVAL; 1469 break; 1470 } 1471 if (ifx_ssc_set_baud(info, flags) < 0) 1472 { 1473 ret_val = -EINVAL; 1474 break; 1475 } 1476 info->baud = flags; 1477 break; 1478 case IFX_SSC_BAUD_GET: 1479 if (from_kernel) 1480 *((unsigned int *)data) = info->baud; 1481 else 1482 if (copy_to_user((void *)data, 1483 (void *)&info->baud, 1484 sizeof(unsigned long))) 1485 ret_val = -EFAULT; 1486 break; 1487 case IFX_SSC_RXTX_MODE_SET: 1488 if (from_kernel) 1489 tmp = *((unsigned long *)data); 1490 else 1491 if (copy_from_user((void *)&tmp, 1492 (void *)data, sizeof(tmp))) { 1493 ret_val = -EFAULT; 1494 break; 1495 } 1496 ret_val = ifx_ssc_rxtx_mode_set(info, tmp); 1497 break; 1498 case IFX_SSC_RXTX_MODE_GET: 1499 tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CON) & 1500 (~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF)); 1501 if (from_kernel) 1502 *((unsigned int *)data) = tmp; 1503 else 1504 if (copy_to_user((void *)data, 1505 (void *)&tmp, 1506 sizeof(tmp))) 1507 ret_val = -EFAULT; 1508 break; 1509 1510 case IFX_SSC_ABORT: 1511 ifx_ssc_abort(info); 1512 break; 1513 1514 case IFX_SSC_GPO_OUT_SET: 1515 if (from_kernel) 1516 tmp = *((unsigned long *)data); 1517 else 1518 if (copy_from_user((void *)&tmp, 1519 (void *)data, sizeof(tmp))) { 1520 ret_val = -EFAULT; 1521 break; 1522 } 1523 if (tmp > IFX_SSC_MAX_GPO_OUT) 1524 ret_val = -EINVAL; 1525 else 1526 WRITE_PERIPHERAL_REGISTER 1527 (1<<(tmp + IFX_SSC_WHBGPOSTAT_SETOUT0_POS), 1528 info->mapbase + IFX_SSC_WHBGPOSTAT); 1529 break; 1530 case IFX_SSC_GPO_OUT_CLR: 1531 if (from_kernel) 1532 tmp = *((unsigned long *)data); 1533 else 1534 if (copy_from_user((void *)&tmp, 1535 (void *)data, sizeof(tmp))) { 1536 ret_val = -EFAULT; 1537 break; 1538 } 1539 if (tmp > IFX_SSC_MAX_GPO_OUT) 1540 ret_val = -EINVAL; 1541 else { 1542 WRITE_PERIPHERAL_REGISTER 1543 (1<<(tmp + IFX_SSC_WHBGPOSTAT_CLROUT0_POS), 1544 info->mapbase + IFX_SSC_WHBGPOSTAT); 1545 } 1546 break; 1547 case IFX_SSC_GPO_OUT_GET: 1548 tmp = READ_PERIPHERAL_REGISTER 1549 (info->mapbase + IFX_SSC_GPOSTAT); 1550 if (from_kernel) 1551 *((unsigned int *)data) = tmp; 1552 else 1553 if (copy_to_user((void *)data, 1554 (void *)&tmp, 1555 sizeof(tmp))) 1556 ret_val = -EFAULT; 1557 break; 1558 case IFX_SSC_FRM_STATUS_GET: 1559 ifx_ssc_frm_status_get(info); 1560 if (from_kernel) 1561 memcpy((void *)data, (void *)&info->frm_status, 1562 sizeof(struct ifx_ssc_frm_status)); 1563 else 1564 if (copy_to_user((void *)data, 1565 (void *)&info->frm_status, 1566 sizeof(struct ifx_ssc_frm_status))) 1567 ret_val = -EFAULT; 1568 break; 1569 case IFX_SSC_FRM_CONTROL_GET: 1570 ifx_ssc_frm_control_get(info); 1571 if (from_kernel) 1572 memcpy((void *)data, (void *)&info->frm_opts, 1573 sizeof(struct ifx_ssc_frm_opts)); 1574 else 1575 if (copy_to_user((void *)data, 1576 (void *)&info->frm_opts, 1577 sizeof(struct ifx_ssc_frm_opts))) 1578 ret_val = -EFAULT; 1579 break; 1580 case IFX_SSC_FRM_CONTROL_SET: 1581 if (from_kernel) 1582 memcpy((void *)&info->frm_opts, (void *)data, 1583 sizeof(struct ifx_ssc_frm_opts)); 1584 else 1585 if (copy_to_user((void *)&info->frm_opts, 1586 (void *)data, 1587 sizeof(struct ifx_ssc_frm_opts))){ 1588 ret_val = -EFAULT; 1589 break; 1590 } 1591 ret_val = ifx_ssc_frm_control_set(info); 1592 break; 1593 case IFX_SSC_HWOPTS_SET: 1594 /* data must be a pointer to a struct ifx_ssc_hwopts */ 1595 /* if the buffers are not empty then the port is */ 1596 /* busy and we shouldn't change things on-the-fly! */ 1597 if (!info->txbuf || !info->rxbuf || 1598 (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 1599 & IFX_SSC_STATE_BUSY)) { 1600 ret_val = -EBUSY; 1601 break; 1602 } 1603 if (from_kernel) 1604 memcpy((void *)&info->opts, (void *)data, 1605 sizeof(struct ifx_ssc_hwopts)); 1606 else 1607 if (copy_from_user((void *)&info->opts, 1608 (void *)data, 1609 sizeof(struct ifx_ssc_hwopts))) 1610 { 1611 ret_val = -EFAULT; 1612 break; 1613 } 1614 if (ifx_ssc_hwinit(info) < 0) 1615 { 1616 ret_val = -EIO; 1617 } 1618 break; 1619 case IFX_SSC_HWOPTS_GET: 1620 /* data must be a pointer to a struct ifx_ssc_hwopts */ 1621 if (from_kernel) 1622 memcpy((void *)data, (void *)&info->opts, 1623 sizeof(struct ifx_ssc_hwopts)); 1624 else 1625 if (copy_to_user((void *)data, 1626 (void *)&info->opts, 1627 sizeof(struct ifx_ssc_hwopts))) 1628 ret_val = -EFAULT; 1629 break; 1630 default: 1631 ret_val = -ENOIOCTLCMD; 1632 } 1633 1634 return ret_val; 1635} /* ifx_ssc_ioctl */ 1636EXPORT_SYMBOL(ifx_ssc_ioctl); 1637 1638///* the poll routine */ 1639//static unsigned int 1640//ifx_ssc_poll(struct file *filp, struct poll_table_struct *pts) 1641//{ 1642// int unit = MINOR(filp->f_dentry->d_inode->i_rdev); 1643// struct ifx_ssc_port *info; 1644// unsigned int mask = 0; 1645// int spc; 1646// 1647// info = &isp[unit]; 1648// 1649// /* add event to the wait queues */ 1650// /* DO NOT FORGET TO DO A WAKEUP ON THESE !!!! */ 1651// poll_wait(filp, &info->pwait, pts); 1652// 1653// /* are there bytes in the RX SW-FIFO? */ 1654// if (info->rxrp != info->rxwp) 1655// mask |= POLLIN | POLLRDNORM; 1656// 1657// /* free space in the TX SW-FIFO */ 1658// spc = info->txrp - info->txwp - 1; 1659// if (spc < 0) 1660// spc += TX_BUFSIZE; 1661//#ifdef IFX_SSC_USEDMA 1662// /* writing always works, except in the DMA case when all descriptors */ 1663// /* are used up */ 1664// if (unit == 1 && info->dma_freecnt == 0) 1665// spc = 0; 1666//#endif 1667// if (spc > 0) 1668// mask |= POLLOUT | POLLWRNORM; 1669// 1670// return (mask); 1671//} 1672 1673static int 1674ifx_ssc1_read_proc(char *page, char **start, off_t offset, int count, int *eof, void *data) 1675{ 1676 int off = 0; 1677 unsigned long flags; 1678 1679 /* don't want any interrupts here */ 1680 save_flags(flags); 1681 cli(); 1682 1683 1684 /* print statistics */ 1685 off += sprintf(page+off, "Statistics for Infineon Synchronous Serial Controller SSC1\n"); 1686 off += sprintf(page+off, "RX overflow errors %d\n", isp[0].stats.rxOvErr); 1687 off += sprintf(page+off, "RX underflow errors %d\n", isp[0].stats.rxUnErr); 1688 off += sprintf(page+off, "TX overflow errors %d\n", isp[0].stats.txOvErr); 1689 off += sprintf(page+off, "TX underflow errors %d\n", isp[0].stats.txUnErr); 1690 off += sprintf(page+off, "Abort errors %d\n", isp[0].stats.abortErr); 1691 off += sprintf(page+off, "Mode errors %d\n", isp[0].stats.modeErr); 1692 off += sprintf(page+off, "RX Bytes %d\n", isp[0].stats.rxBytes); 1693 off += sprintf(page+off, "TX Bytes %d\n", isp[0].stats.txBytes); 1694 1695 restore_flags (flags); /* XXXXX */ 1696 *eof = 1; 1697 return (off); 1698} 1699 1700 1701/* 1702 * This routine prints out the appropriate serial driver version number 1703 */ 1704static inline void 1705show_version(void) 1706{ 1707#if 0 1708 printk("Infineon Technologies Synchronous Serial Controller (SSC) driver\n" 1709 " version %s - built %s %s\n", IFX_SSC_DRV_VERSION, __DATE__, __TIME__); 1710#endif 1711} /* show_version */ 1712 1713 1714/* 1715 * Due to the fact that a port can be dynamically switched between slave 1716 * and master mode using an IOCTL the hardware is not initialized here, 1717 * but in ifx_ssc_hwinit() as a result of an IOCTL. 1718 */ 1719int __init 1720ifx_ssc_init(void) 1721{ 1722 struct ifx_ssc_port *info; 1723 int i, nbytes; 1724 unsigned long flags; 1725 int ret_val; 1726 1727 // ### TO DO: dynamic port count evaluation due to pin multiplexing 1728 1729 ret_val = -ENOMEM; 1730 nbytes = PORT_CNT * sizeof(struct ifx_ssc_port); 1731 isp = (struct ifx_ssc_port *)kmalloc(nbytes, GFP_KERNEL); 1732 if (isp == NULL) 1733 { 1734 printk("%s: no memory for isp\n", __FUNCTION__); 1735 return (ret_val); 1736 } 1737 memset(isp, 0, nbytes); 1738 1739 show_version(); 1740 1741 /* register the device */ 1742 ret_val = -ENXIO; 1743/* 1744 i = maj; 1745*/ 1746 if ((i = register_chrdev(maj, "ssc", &ifx_ssc_fops)) < 0) 1747 { 1748 printk("Unable to register major %d for the Infineon SSC\n", maj); 1749 if (maj == 0){ 1750 goto errout; 1751 } 1752 else{ 1753 maj = 0; 1754 if ((i = register_chrdev(maj, "ssc", &ifx_ssc_fops)) < 0) 1755 { 1756 printk("Unable to register major %d for the Infineon SSC\n", maj); 1757 goto errout; 1758 } 1759 } 1760 } 1761 if (maj == 0) maj = i; 1762 //printk("registered major %d for Infineon SSC\n", maj); 1763 1764 /* set default values in ifx_ssc_port */ 1765 for (i = 0; i < PORT_CNT; i++) { 1766 info = &isp[i]; 1767 info->port_nr = i; 1768 /* default values for the HwOpts */ 1769 info->opts.AbortErrDetect = IFX_SSC_DEF_ABRT_ERR_DETECT; 1770 info->opts.rxOvErrDetect = IFX_SSC_DEF_RO_ERR_DETECT; 1771 info->opts.rxUndErrDetect = IFX_SSC_DEF_RU_ERR_DETECT; 1772 info->opts.txOvErrDetect = IFX_SSC_DEF_TO_ERR_DETECT; 1773 info->opts.txUndErrDetect = IFX_SSC_DEF_TU_ERR_DETECT; 1774 info->opts.loopBack = IFX_SSC_DEF_LOOP_BACK; 1775 info->opts.echoMode = IFX_SSC_DEF_ECHO_MODE; 1776 info->opts.idleValue = IFX_SSC_DEF_IDLE_DATA; 1777 info->opts.clockPolarity = IFX_SSC_DEF_CLOCK_POLARITY; 1778 info->opts.clockPhase = IFX_SSC_DEF_CLOCK_PHASE; 1779 info->opts.headingControl = IFX_SSC_DEF_HEADING_CONTROL; 1780 info->opts.dataWidth = IFX_SSC_DEF_DATA_WIDTH; 1781 info->opts.modeRxTx = IFX_SSC_DEF_MODE_RXTX; 1782 info->opts.gpoCs = IFX_SSC_DEF_GPO_CS; 1783 info->opts.gpoInv = IFX_SSC_DEF_GPO_INV; 1784 info->opts.masterSelect = IFX_SSC_DEF_MASTERSLAVE; 1785 info->baud = IFX_SSC_DEF_BAUDRATE; 1786 info->rxbuf = NULL; 1787 info->txbuf = NULL; 1788 /* values specific to SSC1 */ 1789 if (i == 0) { 1790 info->mapbase = AMAZON_SSC_BASE_ADD_0; 1791 // ### TO DO: power management 1792 1793 // setting interrupt vectors 1794 info->txirq = IFX_SSC_TIR; 1795 info->rxirq = IFX_SSC_RIR; 1796 info->errirq = IFX_SSC_EIR; 1797/* 1798 info->frmirq = IFX_SSC_FIR; 1799*/ 1800 } 1801 /* activate SSC */ 1802 /* CLC.DISS = 0 */ 1803 WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_RMC << IFX_CLC_RUN_DIVIDER_OFFSET, info->mapbase + IFX_SSC_CLC); 1804 1805// ### TO DO: multiple instances 1806 1807 init_waitqueue_head(&info->rwait); 1808 //init_waitqueue_head(&info->pwait); 1809 1810 local_irq_save(flags); 1811 1812 // init serial framing register 1813 WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_SFCON, info->mapbase + IFX_SSC_SFCON); 1814 1815 /* try to get the interrupts */ 1816 // ### TO DO: interrupt handling with multiple instances 1817 ret_val = ifx_int_wrapper.request(info->txirq, ifx_ssc_tx_int, 1818 0, "ifx_ssc_tx", info); 1819 if (ret_val){ 1820 printk("%s: unable to get irq %d\n", __FUNCTION__, 1821 info->txirq); 1822 local_irq_restore(flags); 1823 goto errout; 1824 } 1825 ret_val = ifx_int_wrapper.request(info->rxirq, ifx_ssc_rx_int, 1826 0, "ifx_ssc_rx", info); 1827 if (ret_val){ 1828 printk("%s: unable to get irq %d\n", __FUNCTION__, 1829 info->rxirq); 1830 local_irq_restore(flags); 1831 goto irqerr; 1832 } 1833 ret_val = ifx_int_wrapper.request(info->errirq, ifx_ssc_err_int, 1834 0, "ifx_ssc_err", info); 1835 if (ret_val){ 1836 printk("%s: unable to get irq %d\n", __FUNCTION__, 1837 info->errirq); 1838 local_irq_restore(flags); 1839 goto irqerr; 1840 } 1841/* 1842 ret_val = ifx_int_wrapper.request(info->frmirq, ifx_ssc_frm_int, 1843 0, "ifx_ssc_frm", info); 1844 if (ret_val){ 1845 printk("%s: unable to get irq %d\n", __FUNCTION__, 1846 info->frmirq); 1847 local_irq_restore(flags); 1848 goto irqerr; 1849 } 1850 1851*/ 1852 WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_IRNEN, info->mapbase + IFX_SSC_IRN_EN); 1853 1854 local_irq_restore(flags); 1855 } // for (i = 0; i < PORT_CNT; i++) 1856 1857 /* init the SSCs with default values */ 1858 for (i = 0; i < PORT_CNT; i++) 1859 { 1860 info = &isp[i]; 1861 if (ifx_ssc_hwinit(info) < 0) 1862 { 1863 printk("%s: hardware init failed for port %d\n", 1864 __FUNCTION__, i); 1865 goto irqerr; 1866 } 1867 } 1868 1869 /* register /proc read handler */ 1870 // ### TO DO: multiple instances 1871 /* for SSC1, which is always present */ 1872 create_proc_read_entry("driver/ssc1", 0, NULL, ifx_ssc1_read_proc, NULL); 1873 return 0; 1874 1875irqerr: 1876 // ### TO DO: multiple instances 1877 ifx_int_wrapper.free(isp[0].txirq,&isp[0]); 1878 ifx_int_wrapper.free(isp[0].rxirq,&isp[0]); 1879 ifx_int_wrapper.free(isp[0].errirq,&isp[0]); 1880/* 1881 ifx_int_wrapper.free(isp[0].frmirq, &isp[0]); 1882*/ 1883errout: 1884 /* free up any allocated memory in the error case */ 1885 kfree(isp); 1886 return (ret_val); 1887} /* ifx_ssc_init */ 1888 1889 1890void 1891ifx_ssc_cleanup_module(void) 1892{ 1893 int i; 1894 1895 /* free up any allocated memory */ 1896 for (i = 0; i < PORT_CNT; i++) 1897 { 1898 /* disable the SSC */ 1899 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE,isp[i].mapbase + IFX_SSC_WHBSTATE); 1900 /* free the interrupts */ 1901 ifx_int_wrapper.free(isp[i].txirq, &isp[i]); 1902 ifx_int_wrapper.free(isp[i].rxirq, &isp[i]); 1903 ifx_int_wrapper.free(isp[i].errirq, &isp[i]); 1904/* 1905 ifx_int_wrapper.free(isp[i].frmirq, &isp[i]); 1906 1907 if (isp[i].rxbuf != NULL) 1908 kfree(isp[i].rxbuf); 1909 if (isp[i].txbuf != NULL) 1910 kfree(isp[i].txbuf); 1911*/ 1912 } 1913 kfree(isp); 1914 /* unregister the device */ 1915 if (unregister_chrdev(maj, "ssc")) 1916 { 1917 printk("Unable to unregister major %d for the SSC\n", maj); 1918 } 1919 /* delete /proc read handler */ 1920 remove_proc_entry("driver/ssc1", NULL); 1921 remove_proc_entry("driver/ssc2", NULL); 1922} /* ifx_ssc_cleanup_module */ 1923 1924module_exit(ifx_ssc_cleanup_module); 1925 1926/* Module entry-points */ 1927module_init(ifx_ssc_init); 1928 1929#ifndef MODULE 1930static int __init 1931ifx_ssc_set_maj(char *str) 1932{ 1933 maj = simple_strtol(str, NULL, 0); 1934 return 1; 1935} 1936__setup("ssc_maj=", ifx_ssc_set_maj); 1937#endif /* !MODULE */ 1938 1939#define AMAZON_SSC_EMSG(fmt,arg...) printk("%s: "fmt,__FUNCTION__, ##arg) 1940/* Brief: chip select enable 1941 */ 1942inline int amazon_ssc_cs_low(u32 pin) 1943{ 1944 int ret=0; 1945 if ((ret=ifx_ssc_ioctl((struct inode *)0, NULL,IFX_SSC_GPO_OUT_CLR, (unsigned long)&pin))){ 1946 AMAZON_SSC_EMSG("clear CS %d fails\n",pin); 1947 } 1948 wmb(); 1949 return ret; 1950} 1951EXPORT_SYMBOL(amazon_ssc_cs_low); 1952/* Brief: chip select disable 1953 */ 1954inline int amazon_ssc_cs_high(u32 pin) 1955{ 1956 int ret=0; 1957 if ((ret=ifx_ssc_ioctl((struct inode *)0, NULL,IFX_SSC_GPO_OUT_SET, (unsigned long)&pin))){ 1958 AMAZON_SSC_EMSG("set CS %d fails\n", pin); 1959 } 1960 wmb(); 1961 return ret; 1962} 1963EXPORT_SYMBOL(amazon_ssc_cs_high); 1964/* Brief: one SSC session 1965 * Parameter: 1966 * tx_buf 1967 * tx_len 1968 * rx_buf 1969 * rx_len 1970 * session_mode: IFX_SSC_MODE_RXTX or IFX_SSC_MODE_TX 1971 * Return: >=0 number of bytes received (if rx_buf != 0) or transmitted 1972 * <0 error code 1973 * Description: 1974 * 0. copy data to internal buffer 1975 * 1. Write command 1976 * 2a. If SSC_SESSION_MODE_TXONLY, read tx_len data 1977 * 2b. If not Read back (tx_len + rx_len) data 1978 * 3. copy internal buffer to rx buf if necessary 1979 */ 1980static int ssc_session(char * tx_buf, u32 tx_len, char * rx_buf, u32 rx_len) 1981{ 1982 int ret=0; 1983 1984 char * ssc_tx_buf=NULL; 1985 char * ssc_rx_buf=NULL; 1986 1987// volatile char ssc_tx_buf[128]={0}; 1988// volatile char ssc_rx_buf[128]={0}; 1989 1990 int eff_size=0; 1991 u8 mode=0; 1992 1993 if (tx_buf == NULL && tx_len ==0 && rx_buf == NULL && rx_len == 0){ 1994 AMAZON_SSC_EMSG("invalid parameters\n"); 1995 ret=-EINVAL; 1996 goto ssc_session_exit; 1997 }else if (tx_buf == NULL || tx_len == 0){ 1998 if (rx_buf != NULL && rx_len != 0){ 1999 mode = IFX_SSC_MODE_RX; 2000 }else{ 2001 AMAZON_SSC_EMSG("invalid parameters\n"); 2002 ret=-EINVAL; 2003 goto ssc_session_exit; 2004 } 2005 }else if (rx_buf == NULL || rx_len ==0){ 2006 if (tx_buf != NULL && tx_len != 0){ 2007 mode = IFX_SSC_MODE_TX; 2008 }else{ 2009 AMAZON_SSC_EMSG("invalid parameters\n"); 2010 ret=-EINVAL; 2011 goto ssc_session_exit; 2012 } 2013 }else{ 2014 mode = IFX_SSC_MODE_RXTX; 2015 } 2016 2017 if (mode == IFX_SSC_MODE_RXTX){ 2018 eff_size = tx_len + rx_len; 2019 }else if (mode == IFX_SSC_MODE_RX){ 2020 eff_size = rx_len; 2021 }else{ 2022 eff_size = tx_len; 2023 } 2024 2025 //4 bytes alignment, required by driver 2026 /* change by TaiCheng */ 2027 //if (in_irq()){ 2028 if (1){ 2029 ssc_tx_buf = (char*) kmalloc(sizeof(char) * ((eff_size + 3) & (~3)), GFP_ATOMIC); 2030 ssc_rx_buf = (char*) kmalloc(sizeof(char) * ((eff_size + 3) & (~3)), GFP_ATOMIC); 2031 }else{ 2032 ssc_tx_buf = (char*) kmalloc(sizeof(char) * ((eff_size + 3) & (~3)), GFP_KERNEL); 2033 ssc_rx_buf = (char*) kmalloc(sizeof(char) * ((eff_size + 3) & (~3)), GFP_KERNEL); 2034 } 2035 if (ssc_tx_buf == NULL || ssc_rx_buf == NULL){ 2036 AMAZON_SSC_EMSG("no memory for size of %d\n", eff_size); 2037 ret = -ENOMEM; 2038 goto ssc_session_exit; 2039 } 2040 memset((void*)ssc_tx_buf, 0, eff_size); 2041 memset((void*)ssc_rx_buf, 0, eff_size); 2042 2043 if (tx_len>0){ 2044 memcpy(ssc_tx_buf, tx_buf, tx_len); 2045 } 2046 2047 ret=ifx_ssc_kwrite(0, ssc_tx_buf, eff_size); 2048 2049 if (ret > 0) { 2050 ssc_tx_buf = NULL; //should be freed by ifx_ssc_kwrite 2051 } 2052 2053 if ( ret != eff_size ){ 2054 AMAZON_SSC_EMSG("ifx_ssc_write return %d\n",ret); 2055 goto ssc_session_exit; 2056 } 2057 ret=ifx_ssc_kread(0, ssc_rx_buf,eff_size); 2058 if ( ret != eff_size ){ 2059 AMAZON_SSC_EMSG("ifx_ssc_read return %d\n",ret); 2060 goto ssc_session_exit; 2061 } 2062 2063 memcpy(rx_buf, ssc_rx_buf+tx_len, rx_len); 2064 2065 if (mode == IFX_SSC_MODE_TX) { 2066 ret = tx_len; 2067 }else{ 2068 ret = rx_len; 2069 } 2070ssc_session_exit: 2071 2072 if (ssc_tx_buf != NULL) kfree(ssc_tx_buf); 2073 if (ssc_rx_buf != NULL) kfree(ssc_rx_buf); 2074 2075 if (ret<0) { 2076 printk("ssc session fails\n"); 2077 } 2078 return ret; 2079} 2080/* Brief: TX-RX session 2081 * Parameter: 2082 * tx_buf 2083 * tx_len 2084 * rx_buf 2085 * rx_len 2086 * Return: >=0 number of bytes received 2087 * <0 error code 2088 * Description: 2089 * 1. TX session 2090 * 2. RX session 2091 */ 2092int amazon_ssc_txrx(char * tx_buf, u32 tx_len, char * rx_buf, u32 rx_len) 2093{ 2094 return ssc_session(tx_buf,tx_len,rx_buf,rx_len); 2095} 2096EXPORT_SYMBOL(amazon_ssc_txrx); 2097/* Brief: TX only session 2098 * Parameter: 2099 * tx_buf 2100 * tx_len 2101 * Return: >=0 number of bytes transmitted 2102 * <0 error code 2103 */ 2104int amazon_ssc_tx(char * tx_buf, u32 tx_len) 2105{ 2106 return ssc_session(tx_buf,tx_len,NULL,0); 2107} 2108EXPORT_SYMBOL(amazon_ssc_tx); 2109/* Brief: RX only session 2110 * Parameter: 2111 * rx_buf 2112 * rx_len 2113 * Return: >=0 number of bytes received 2114 * <0 error code 2115 */ 2116int amazon_ssc_rx(char * rx_buf, u32 rx_len) 2117{ 2118 return ssc_session(NULL,0,rx_buf,rx_len); 2119} 2120EXPORT_SYMBOL(amazon_ssc_rx); 2121 2122