ifx_ssc.c 64 KB

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