sm.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:11k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*****************************************************************************/
  2. /*
  3.  * sm.h  --  soundcard radio modem driver internal header.
  4.  *
  5.  * Copyright (C) 1996-1999  Thomas Sailer (sailer@ife.ee.ethz.ch)
  6.  *
  7.  * This program is free software; you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License as published by
  9.  * the Free Software Foundation; either version 2 of the License, or
  10.  * (at your option) any later version.
  11.  *
  12.  * This program is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  * GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with this program; if not, write to the Free Software
  19.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  *  Please note that the GPL allows you to use the driver, NOT the radio.
  22.  *  In order to use the radio, you need a license from the communications
  23.  *  authority of your country.
  24.  *
  25.  */
  26. #ifndef _SM_H
  27. #define _SM_H
  28. /* ---------------------------------------------------------------------- */
  29. #include <linux/hdlcdrv.h>
  30. #include <linux/soundmodem.h>
  31. #include <asm/processor.h>
  32. #include <linux/bitops.h>
  33. #include <linux/parport.h>
  34. #define SM_DEBUG
  35. /* ---------------------------------------------------------------------- */
  36. /*
  37.  * Information that need to be kept for each board.
  38.  */
  39. struct sm_state {
  40. struct hdlcdrv_state hdrv;
  41. const struct modem_tx_info *mode_tx;
  42. const struct modem_rx_info *mode_rx;
  43. const struct hardware_info *hwdrv;
  44. struct pardevice *pardev;
  45. /*
  46.  * Hardware (soundcard) access routines state
  47.  */
  48. struct {
  49. void *ibuf;
  50. unsigned int ifragsz;
  51. unsigned int ifragptr;
  52. unsigned int i16bit;
  53. void *obuf;
  54. unsigned int ofragsz;
  55. unsigned int ofragptr;
  56. unsigned int o16bit;
  57. int ptt_cnt;
  58. } dma;
  59. union {
  60. long hw[32/sizeof(long)];
  61. } hw;
  62. /*
  63.  * state of the modem code
  64.  */
  65. union {
  66. long m[48/sizeof(long)];
  67. } m;
  68. union {
  69. long d[256/sizeof(long)];
  70. } d;
  71. #define DIAGDATALEN 64
  72. struct diag_data {
  73. unsigned int mode;
  74. unsigned int flags;
  75. volatile int ptr;
  76. short data[DIAGDATALEN];
  77. } diag;
  78. #ifdef SM_DEBUG
  79. struct debug_vals {
  80. unsigned long last_jiffies;
  81. unsigned cur_intcnt;
  82. unsigned last_intcnt;
  83. unsigned mod_cyc;
  84. unsigned demod_cyc;
  85. unsigned dma_residue;
  86. } debug_vals;
  87. #endif /* SM_DEBUG */
  88. };
  89. /* ---------------------------------------------------------------------- */
  90. /*
  91.  * Mode definition structure
  92.  */
  93. struct modem_tx_info {
  94. const char *name;
  95. unsigned int loc_storage;
  96. int srate;
  97. int bitrate;
  98.         void (*modulator_u8)(struct sm_state *, unsigned char *, unsigned int);
  99.         void (*modulator_s16)(struct sm_state *, short *, unsigned int);
  100.         void (*init)(struct sm_state *);
  101. };
  102. struct modem_rx_info {
  103. const char *name;
  104. unsigned int loc_storage;
  105. int srate;
  106. int bitrate;
  107. unsigned int overlap;
  108. unsigned int sperbit;
  109.         void (*demodulator_u8)(struct sm_state *, const unsigned char *, unsigned int);
  110.         void (*demodulator_s16)(struct sm_state *, const short *, unsigned int);
  111.         void (*init)(struct sm_state *);
  112. };
  113. /* ---------------------------------------------------------------------- */
  114. /*
  115.  * Soundcard driver definition structure
  116.  */
  117. struct hardware_info {
  118. char *hw_name; /* used for request_{region,irq,dma} */
  119. unsigned int loc_storage;
  120. /*
  121.  * mode specific open/close
  122.  */
  123. int (*open)(struct net_device *, struct sm_state *);
  124. int (*close)(struct net_device *, struct sm_state *);
  125. int (*ioctl)(struct net_device *, struct sm_state *, struct ifreq *,
  126.      struct hdlcdrv_ioctl *, int);
  127. int (*sethw)(struct net_device *, struct sm_state *, char *);
  128. };
  129. /* --------------------------------------------------------------------- */
  130. extern const char sm_drvname[];
  131. extern const char sm_drvinfo[];
  132. /* --------------------------------------------------------------------- */
  133. /*
  134.  * ===================== diagnostics stuff ===============================
  135.  */
  136. static inline void diag_trigger(struct sm_state *sm)
  137. {
  138. if (sm->diag.ptr < 0)
  139. if (!(sm->diag.flags & SM_DIAGFLAG_DCDGATE) || sm->hdrv.hdlcrx.dcd)
  140. sm->diag.ptr = 0;
  141. }
  142. /* --------------------------------------------------------------------- */
  143. #define SHRT_MAX ((short)(((unsigned short)(~0U))>>1))
  144. #define SHRT_MIN (-SHRT_MAX-1)
  145. static inline void diag_add(struct sm_state *sm, int valinp, int valdemod)
  146. {
  147. int val;
  148. if ((sm->diag.mode != SM_DIAGMODE_INPUT &&
  149.      sm->diag.mode != SM_DIAGMODE_DEMOD) ||
  150.     sm->diag.ptr >= DIAGDATALEN || sm->diag.ptr < 0)
  151. return;
  152. val = (sm->diag.mode == SM_DIAGMODE_DEMOD) ? valdemod : valinp;
  153. /* clip */
  154. if (val > SHRT_MAX)
  155. val = SHRT_MAX;
  156. if (val < SHRT_MIN)
  157. val = SHRT_MIN;
  158. sm->diag.data[sm->diag.ptr++] = val;
  159. }
  160. /* --------------------------------------------------------------------- */
  161. static inline void diag_add_one(struct sm_state *sm, int val)
  162. {
  163. if ((sm->diag.mode != SM_DIAGMODE_INPUT &&
  164.      sm->diag.mode != SM_DIAGMODE_DEMOD) ||
  165.     sm->diag.ptr >= DIAGDATALEN || sm->diag.ptr < 0)
  166. return;
  167. /* clip */
  168. if (val > SHRT_MAX)
  169. val = SHRT_MAX;
  170. if (val < SHRT_MIN)
  171. val = SHRT_MIN;
  172. sm->diag.data[sm->diag.ptr++] = val;
  173. }
  174. /* --------------------------------------------------------------------- */
  175. static inline void diag_add_constellation(struct sm_state *sm, int vali, int valq)
  176. {
  177. if ((sm->diag.mode != SM_DIAGMODE_CONSTELLATION) ||
  178.     sm->diag.ptr >= DIAGDATALEN-1 || sm->diag.ptr < 0)
  179. return;
  180. /* clip */
  181. if (vali > SHRT_MAX)
  182. vali = SHRT_MAX;
  183. if (vali < SHRT_MIN)
  184. vali = SHRT_MIN;
  185. if (valq > SHRT_MAX)
  186. valq = SHRT_MAX;
  187. if (valq < SHRT_MIN)
  188. valq = SHRT_MIN;
  189. sm->diag.data[sm->diag.ptr++] = vali;
  190. sm->diag.data[sm->diag.ptr++] = valq;
  191. }
  192. /* --------------------------------------------------------------------- */
  193. /*
  194.  * ===================== utility functions ===============================
  195.  */
  196. #if 0
  197. static inline unsigned int hweight32(unsigned int w)
  198. __attribute__ ((unused));
  199. static inline unsigned int hweight16(unsigned short w)
  200. __attribute__ ((unused));
  201. static inline unsigned int hweight8(unsigned char w)
  202.         __attribute__ ((unused));
  203. static inline unsigned int hweight32(unsigned int w)
  204. {
  205.         unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
  206.         res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
  207.         res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
  208.         res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
  209.         return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
  210. }
  211. static inline unsigned int hweight16(unsigned short w)
  212. {
  213.         unsigned short res = (w & 0x5555) + ((w >> 1) & 0x5555);
  214.         res = (res & 0x3333) + ((res >> 2) & 0x3333);
  215.         res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
  216.         return (res & 0x00FF) + ((res >> 8) & 0x00FF);
  217. }
  218. static inline unsigned int hweight8(unsigned char w)
  219. {
  220.         unsigned short res = (w & 0x55) + ((w >> 1) & 0x55);
  221.         res = (res & 0x33) + ((res >> 2) & 0x33);
  222.         return (res & 0x0F) + ((res >> 4) & 0x0F);
  223. }
  224. #endif
  225. static inline unsigned int gcd(unsigned int x, unsigned int y)
  226. __attribute__ ((unused));
  227. static inline unsigned int lcm(unsigned int x, unsigned int y)
  228. __attribute__ ((unused));
  229. static inline unsigned int gcd(unsigned int x, unsigned int y)
  230. {
  231. for (;;) {
  232. if (!x)
  233. return y;
  234. if (!y)
  235. return x;
  236. if (x > y)
  237. x %= y;
  238. else
  239. y %= x;
  240. }
  241. }
  242. static inline unsigned int lcm(unsigned int x, unsigned int y)
  243. {
  244. return x * y / gcd(x, y);
  245. }
  246. /* --------------------------------------------------------------------- */
  247. /*
  248.  * ===================== profiling =======================================
  249.  */
  250. #ifdef __i386__
  251. #include <asm/msr.h>
  252. /*
  253.  * only do 32bit cycle counter arithmetic; we hope we won't overflow.
  254.  * in fact, overflowing modems would require over 2THz CPU clock speeds :-)
  255.  */
  256. #define time_exec(var,cmd)                                              
  257. ({                                                                      
  258. if (cpu_has_tsc) {                                              
  259. unsigned int cnt1, cnt2;                                
  260. rdtscl(cnt1);                                           
  261. cmd;                                                    
  262. rdtscl(cnt2);                                           
  263. var = cnt2-cnt1;                                        
  264. } else {                                                        
  265. cmd;                                                    
  266. }                                                               
  267. })
  268. #else /* __i386__ */
  269. #define time_exec(var,cmd) cmd
  270. #endif /* __i386__ */
  271. /* --------------------------------------------------------------------- */
  272. extern const struct modem_tx_info sm_afsk1200_tx;
  273. extern const struct modem_tx_info sm_afsk2400_7_tx;
  274. extern const struct modem_tx_info sm_afsk2400_8_tx;
  275. extern const struct modem_tx_info sm_afsk2666_tx;
  276. extern const struct modem_tx_info sm_psk4800_tx;
  277. extern const struct modem_tx_info sm_hapn4800_8_tx;
  278. extern const struct modem_tx_info sm_hapn4800_10_tx;
  279. extern const struct modem_tx_info sm_hapn4800_pm8_tx;
  280. extern const struct modem_tx_info sm_hapn4800_pm10_tx;
  281. extern const struct modem_tx_info sm_fsk9600_4_tx;
  282. extern const struct modem_tx_info sm_fsk9600_5_tx;
  283. extern const struct modem_rx_info sm_afsk1200_rx;
  284. extern const struct modem_rx_info sm_afsk2400_7_rx;
  285. extern const struct modem_rx_info sm_afsk2400_8_rx;
  286. extern const struct modem_rx_info sm_afsk2666_rx;
  287. extern const struct modem_rx_info sm_psk4800_rx;
  288. extern const struct modem_rx_info sm_hapn4800_8_rx;
  289. extern const struct modem_rx_info sm_hapn4800_10_rx;
  290. extern const struct modem_rx_info sm_hapn4800_pm8_rx;
  291. extern const struct modem_rx_info sm_hapn4800_pm10_rx;
  292. extern const struct modem_rx_info sm_fsk9600_4_rx;
  293. extern const struct modem_rx_info sm_fsk9600_5_rx;
  294. extern const struct hardware_info sm_hw_sbc;
  295. extern const struct hardware_info sm_hw_sbcfdx;
  296. extern const struct hardware_info sm_hw_wss;
  297. extern const struct hardware_info sm_hw_wssfdx;
  298. extern const struct modem_tx_info *sm_modem_tx_table[];
  299. extern const struct modem_rx_info *sm_modem_rx_table[];
  300. extern const struct hardware_info *sm_hardware_table[];
  301. /* --------------------------------------------------------------------- */
  302. void sm_output_status(struct sm_state *sm);
  303. /*void sm_output_open(struct sm_state *sm);*/
  304. /*void sm_output_close(struct sm_state *sm);*/
  305. /* --------------------------------------------------------------------- */
  306. extern void inline sm_int_freq(struct sm_state *sm)
  307. {
  308. #ifdef SM_DEBUG
  309. unsigned long cur_jiffies = jiffies;
  310. /*
  311.  * measure the interrupt frequency
  312.  */
  313. sm->debug_vals.cur_intcnt++;
  314. if ((cur_jiffies - sm->debug_vals.last_jiffies) >= HZ) {
  315. sm->debug_vals.last_jiffies = cur_jiffies;
  316. sm->debug_vals.last_intcnt = sm->debug_vals.cur_intcnt;
  317. sm->debug_vals.cur_intcnt = 0;
  318. }
  319. #endif /* SM_DEBUG */
  320. }
  321. /* --------------------------------------------------------------------- */
  322. #endif /* _SM_H */