History

Merge tag 'staging-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging tree update from Greg Kroah-Hartman: "Here is the big staging tree update for the 3.7-rc1 merge window. There are a few patches in here that are outside of the staging area, namely HID and IIO patches, but all of them have been acked by the relevant subsystem maintainers. The IIO stuff is still coming in through this tree as it hasn't entirely moved out of the staging tree, but is almost there. Other than that, there wa a ton of work on the comedi drivers to make them more readable and the correct style. Doing that removed a lot of code, but we added a new driver to the staging tree, so we didn't end up with a net reduction this time around: 662 files changed, 51649 insertions(+), 26582 deletions(-) All of these patches have been in the linux-next tree already. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'staging-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1094 commits) staging: comedi: jr3_pci: fix iomem dereference staging: comedi: drivers: use comedi_fc.h cmdtest helpers Staging: winbond: usb_free_urb(NULL) is safe Staging: winbond: checkpatch cleanup Staging: winbond: Removed undesired spaces, lines and tabs Staging: winbond: Typo corrections in comments Staging: winbond: Changed c99 comments to c89 comments staging: r8712u: Do not queue cloned skb staging: comedi: ni_mio_common: always lock in ni_ai_poll() staging: comedi: s626: add FIXME comment staging: comedi: s626: don't dereference insn->data staging: comedi: s526: fix if() check in s526_gpct_winsn() staging: comedi: s626: cleanup comments in s626_initialize() staging: comedi: s626: remove clear of kzalloc'ed data staging: comedi: s626: remove 'WDInterval' from private data staging: comedi: s626: remove 'ChargeEnabled' from private data staging: comedi: s626: remove 'IsBoardRevA' comment staging: comedi: s626: #if 0 out the "SAA7146 BUG WORKAROUND" staging: comedi: s626: remove 'allocatedBuf' from private data staging: comedi: s626: add final attach message ...

Linus Torvalds committed 14 years ago

Commit def7cb82 parents 06d2fe1 e187895662 files · +51649 −26582Browse files

Unified · Split

662 files
  1. Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt +15 −0
  2. Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt +41 −0
  3. Documentation/hid/hid-sensor.txt +140 −0
  4. drivers/hid/Kconfig +14 −0
  5. drivers/hid/Makefile +1 −0
  6. drivers/hid/hid-core.c +5 −0
  7. drivers/hid/hid-ids.h +6 −0
  8. drivers/hid/hid-sensor-hub.c +680 −0
  9. drivers/iio/Kconfig +6 −1
  10. drivers/iio/Makefile +5 −0
  11. drivers/iio/accel/Kconfig +16 −0
  12. drivers/iio/accel/Makefile +5 −0
  13. drivers/iio/accel/hid-sensor-accel-3d.c +418 −0
  14. drivers/iio/adc/Kconfig +38 −0
  15. drivers/iio/adc/Makefile +4 −0
  16. drivers/iio/adc/ad7266.c +1 −1
  17. drivers/iio/adc/ad7476.c +149 −61
  18. drivers/iio/adc/ad7791.c +460 −0
  19. drivers/iio/adc/ad_sigma_delta.c +558 −0
  20. drivers/iio/adc/at91_adc.c +18 −59
  21. drivers/iio/adc/lp8788_adc.c +264 −0
  22. drivers/iio/common/Kconfig +5 −0
  23. drivers/iio/common/Makefile +9 −0
  24. drivers/iio/common/hid-sensors/Kconfig +26 −0
  25. drivers/iio/common/hid-sensors/Makefile +6 −0
  26. drivers/iio/common/hid-sensors/hid-sensor-attributes.c +250 −0
  27. drivers/iio/common/hid-sensors/hid-sensor-attributes.h +57 −0
  28. drivers/iio/common/hid-sensors/hid-sensor-trigger.c +103 −0
  29. drivers/iio/common/hid-sensors/hid-sensor-trigger.h +26 −0
  30. drivers/iio/dac/Kconfig +16 −4
  31. drivers/iio/dac/Makefile +1 −0
  32. drivers/iio/dac/ad5446.c +338 −112
  33. drivers/iio/dac/ad5446.h +0 −91
  34. drivers/iio/dac/ad5755.c +650 −0
  35. drivers/iio/gyro/Kconfig +16 −0
  36. drivers/iio/gyro/Makefile +5 −0
  37. drivers/iio/gyro/hid-sensor-gyro-3d.c +418 −0
  38. drivers/iio/industrialio-buffer.c +7 −8
  39. drivers/iio/industrialio-core.c +10 −3
  40. drivers/iio/inkern.c +128 −11
  41. drivers/iio/kfifo_buf.c +23 −8
  42. drivers/iio/light/Kconfig +10 −0
  43. drivers/iio/light/Makefile +1 −0
  44. drivers/iio/light/adjd_s311.c +1 −1
  45. drivers/iio/light/hid-sensor-als.c +385 −0
  46. drivers/iio/magnetometer/Kconfig +16 −0
  47. drivers/iio/magnetometer/Makefile +5 −0
  48. drivers/iio/magnetometer/hid-sensor-magn-3d.c +419 −0
  49. drivers/power/Kconfig +7 −0
  50. drivers/power/Makefile +1 −0
  51. drivers/power/generic-adc-battery.c +422 −0
  52. drivers/staging/Kconfig +8 −2
  53. drivers/staging/Makefile +4 −1
  54. drivers/staging/android/alarm-dev.c +7 −10
  55. drivers/staging/android/ashmem.c +16 −16
  56. drivers/staging/android/binder.c +3 −3
  57. drivers/staging/android/logger.c +26 −14
  58. drivers/staging/android/logger.h +17 −7
  59. drivers/staging/android/timed_gpio.c +1 −12
  60. drivers/staging/asus_oled/asus_oled.c +45 −11
  61. drivers/staging/bcm/Bcmchar.c +2 −0
  62. drivers/staging/bcm/CmHost.c +68 −82
  63. drivers/staging/bcm/CmHost.h +19 −35
  64. drivers/staging/bcm/InterfaceInit.c +13 −4
  65. drivers/staging/bcm/InterfaceInit.h +16 −17
  66. drivers/staging/bcm/Kconfig +1 −1
  67. drivers/staging/bcm/Misc.c +4 −1
  68. drivers/staging/bcm/PHSModule.c +2 −2
  69. drivers/staging/bcm/Prototypes.h +1 −1
  70. drivers/staging/bcm/Transmit.c +106 −128
  71. drivers/staging/bcm/cntrl_SignalingInterface.h +296 −408
  72. drivers/staging/bcm/hostmibs.c +1 −1
  73. drivers/staging/bcm/nvm.c +2 −2
  74. drivers/staging/bcm/target_params.h +1 −1
  75. drivers/staging/ccg/Kconfig +1 −1
  76. drivers/staging/ccg/ccg.c +5 −9
  77. drivers/staging/ced1401/Kconfig +6 −0
  78. drivers/staging/ced1401/Makefile +3 −0
  79. drivers/staging/ced1401/TODO +10 −0
  80. drivers/staging/ced1401/ced_ioc.c +1515 −0
  81. drivers/staging/ced1401/ced_ioctl.h +345 −0
  82. drivers/staging/ced1401/machine.h +127 −0
  83. drivers/staging/ced1401/usb1401.c +1637 −0
  84. drivers/staging/ced1401/usb1401.h +249 −0
  85. drivers/staging/ced1401/use1401.h +287 −0
  86. drivers/staging/ced1401/use14_ioc.h +301 −0
  87. drivers/staging/ced1401/userspace/use1401.c +3035 −0
  88. drivers/staging/comedi/Kconfig +28 −38
  89. drivers/staging/comedi/comedi.h +554 −555
  90. drivers/staging/comedi/comedi_fops.c +73 −79
  91. drivers/staging/comedi/comedidev.h +1 −1
  92. drivers/staging/comedi/drivers.c +45 −37
  93. drivers/staging/comedi/drivers/8253.h +9 −6
  94. drivers/staging/comedi/drivers/8255.c +12 −29
  95. drivers/staging/comedi/drivers/8255_pci.c +353 −0
  96. drivers/staging/comedi/drivers/Makefile +2 −4
  97. drivers/staging/comedi/drivers/acl7225b.c +3 −3
  98. drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c +0 −195
  99. drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h +0 −27
  100. drivers/staging/comedi/drivers/addi-data/addi_common.c +7 −7
  101. drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h +0 −453
  102. drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c +9 −9
  103. drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +15 −46
  104. drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +29 −52
  105. drivers/staging/comedi/drivers/addi_apci_all.c +0 −18
  106. drivers/staging/comedi/drivers/adl_pci6208.c +87 −96
  107. drivers/staging/comedi/drivers/adl_pci7230.c +0 −190
  108. drivers/staging/comedi/drivers/adl_pci7296.c +0 −183
  109. drivers/staging/comedi/drivers/adl_pci7432.c +0 −200
  110. drivers/staging/comedi/drivers/adl_pci7x3x.c +332 −0
  111. drivers/staging/comedi/drivers/adl_pci8164.c +17 −56
  112. drivers/staging/comedi/drivers/adl_pci9111.c +278 −695
  113. drivers/staging/comedi/drivers/adl_pci9118.c +410 −649
  114. drivers/staging/comedi/drivers/adq12b.c +14 −15
  115. drivers/staging/comedi/drivers/adv_pci1710.c +316 −450
  116. drivers/staging/comedi/drivers/adv_pci1723.c +58 −164
  117. drivers/staging/comedi/drivers/adv_pci_dio.c +225 −248
  118. drivers/staging/comedi/drivers/aio_aio12_8.c +137 −81
  119. drivers/staging/comedi/drivers/aio_iiro_16.c +2 −2
  120. drivers/staging/comedi/drivers/amplc_dio200.c +49 −65
  121. drivers/staging/comedi/drivers/amplc_pc236.c +53 −55
  122. drivers/staging/comedi/drivers/amplc_pc263.c +34 −20
  123. drivers/staging/comedi/drivers/amplc_pci224.c +21 −43
  124. drivers/staging/comedi/drivers/amplc_pci230.c +45 −109
  125. drivers/staging/comedi/drivers/c6xdigio.c +3 −3
  126. drivers/staging/comedi/drivers/cb_das16_cs.c +18 −38
  127. drivers/staging/comedi/drivers/cb_pcidas.c +66 −136
  128. drivers/staging/comedi/drivers/cb_pcidas64.c +41 −87
  129. drivers/staging/comedi/drivers/cb_pcidda.c +175 −266
  130. drivers/staging/comedi/drivers/cb_pcidio.c +0 −211
  131. drivers/staging/comedi/drivers/cb_pcimdas.c +119 −160
  132. drivers/staging/comedi/drivers/cb_pcimdda.c +92 −301
  133. drivers/staging/comedi/drivers/comedi_bond.c +31 −79
  134. drivers/staging/comedi/drivers/comedi_fc.h +32 −0
  135. drivers/staging/comedi/drivers/comedi_parport.c +39 −47
  136. drivers/staging/comedi/drivers/comedi_test.c +40 −68
  137. drivers/staging/comedi/drivers/contec_pci_dio.c +45 −101
  138. drivers/staging/comedi/drivers/daqboard2000.c +202 −264
  139. drivers/staging/comedi/drivers/das08.c +149 −333
  140. drivers/staging/comedi/drivers/das08.h +4 −11
  141. drivers/staging/comedi/drivers/das08_cs.c +26 −0
  142. drivers/staging/comedi/drivers/das16.c +31 −51
  143. drivers/staging/comedi/drivers/das16m1.c +18 −36
  144. drivers/staging/comedi/drivers/das1800.c +63 −82
  145. drivers/staging/comedi/drivers/das6402.c +2 −2
  146. drivers/staging/comedi/drivers/das800.c +16 −36
  147. drivers/staging/comedi/drivers/dmm32at.c +19 −38
  148. drivers/staging/comedi/drivers/dt2801.c +6 −6
  149. drivers/staging/comedi/drivers/dt2811.c +4 −4
  150. drivers/staging/comedi/drivers/dt2814.c +14 −32
  151. drivers/staging/comedi/drivers/dt2815.c +1 −1
  152. drivers/staging/comedi/drivers/dt2817.c +1 −1
  153. drivers/staging/comedi/drivers/dt282x.c +29 −74
  154. drivers/staging/comedi/drivers/dt3000.c +16 −32
  155. drivers/staging/comedi/drivers/dt9812.c +4 −4
  156. drivers/staging/comedi/drivers/dyna_pci10xx.c +36 −125
  157. drivers/staging/comedi/drivers/fl512.c +2 −2
  158. drivers/staging/comedi/drivers/gsc_hpdi.c +11 −32
  159. drivers/staging/comedi/drivers/icp_multi.c +140 −552
  160. drivers/staging/comedi/drivers/icp_multi.h +0 −297
  161. drivers/staging/comedi/drivers/ii_pci20kc.c +2 −2
  162. drivers/staging/comedi/drivers/jr3_pci.c +5 −4
  163. drivers/staging/comedi/drivers/jr3_pci.h +2 −2
  164. drivers/staging/comedi/drivers/ke_counter.c +35 −68
  165. drivers/staging/comedi/drivers/me4000.c +618 −1018
  166. drivers/staging/comedi/drivers/me4000.h +0 −409
  167. drivers/staging/comedi/drivers/me_daq.c +99 −122
  168. drivers/staging/comedi/drivers/mite.c +135 −150
  169. drivers/staging/comedi/drivers/mite.h +16 −50
  170. drivers/staging/comedi/drivers/mpc624.c +1 −1
  171. drivers/staging/comedi/drivers/mpc8260cpm.c +1 −1
  172. drivers/staging/comedi/drivers/multiq3.c +8 −6
  173. drivers/staging/comedi/drivers/ni_6527.c +61 −110
  174. drivers/staging/comedi/drivers/ni_65xx.c +63 −118
  175. drivers/staging/comedi/drivers/ni_660x.c +46 −87
  176. drivers/staging/comedi/drivers/ni_670x.c +24 −38
  177. drivers/staging/comedi/drivers/ni_at_a2150.c +12 −34
  178. drivers/staging/comedi/drivers/ni_at_ao.c +4 −4
  179. drivers/staging/comedi/drivers/ni_atmio.c +1 −1
  180. drivers/staging/comedi/drivers/ni_atmio16d.c +26 −41
  181. drivers/staging/comedi/drivers/ni_daq_700.c +164 −48
  182. drivers/staging/comedi/drivers/ni_daq_dio24.c +8 −4
  183. drivers/staging/comedi/drivers/ni_labpc.c +198 −269
  184. drivers/staging/comedi/drivers/ni_labpc_cs.c +3 −3
  185. drivers/staging/comedi/drivers/ni_mio_common.c +88 −152
  186. drivers/staging/comedi/drivers/ni_mio_cs.c +2 −2
  187. drivers/staging/comedi/drivers/ni_pcidio.c +169 −303
  188. drivers/staging/comedi/drivers/ni_pcimio.c +30 −40
  189. drivers/staging/comedi/drivers/ni_tiocmd.c +18 −43
  190. drivers/staging/comedi/drivers/pcl711.c +18 −35
  191. drivers/staging/comedi/drivers/pcl724.c +9 −6
  192. drivers/staging/comedi/drivers/pcl725.c +2 −2
  193. drivers/staging/comedi/drivers/pcl726.c +3 −3
  194. drivers/staging/comedi/drivers/pcl730.c +4 −4
  195. drivers/staging/comedi/drivers/pcl812.c +20 −37
  196. drivers/staging/comedi/drivers/pcl816.c +14 −38
  197. drivers/staging/comedi/drivers/pcl818.c +20 −39
  198. drivers/staging/comedi/drivers/pcm3724.c +17 −9
  199. drivers/staging/comedi/drivers/pcm3730.c +6 −6
  200. drivers/staging/comedi/drivers/pcm_common.c +13 −43
  201. drivers/staging/comedi/drivers/pcmad.c +1 −1
  202. drivers/staging/comedi/drivers/pcmda12.c +1 −1
  203. drivers/staging/comedi/drivers/pcmmio.c +10 −22
  204. drivers/staging/comedi/drivers/pcmuio.c +7 −7
  205. drivers/staging/comedi/drivers/poc.c +1 −1
  206. drivers/staging/comedi/drivers/quatech_daqp_cs.c +20 −43
  207. drivers/staging/comedi/drivers/rtd520.c +21 −46
  208. drivers/staging/comedi/drivers/rti800.c +5 −5
  209. drivers/staging/comedi/drivers/rti802.c +1 −1
  210. drivers/staging/comedi/drivers/s526.c +153 −449
  211. drivers/staging/comedi/drivers/s626.c +303 −452
  212. drivers/staging/comedi/drivers/s626.h +0 −1
  213. drivers/staging/comedi/drivers/serial2002.c +8 −6
  214. drivers/staging/comedi/drivers/skel.c +28 −46
  215. drivers/staging/comedi/drivers/ssv_dnp.c +2 −5
  216. drivers/staging/comedi/drivers/usbdux.c +52 −149
  217. drivers/staging/comedi/drivers/usbduxfast.c +23 −97
  218. drivers/staging/comedi/drivers/usbduxsigma.c +45 −147
  219. drivers/staging/comedi/drivers/vmk80xx.c +8 −6
  220. drivers/staging/comedi/kcomedilib/kcomedilib_main.c +13 −10
  221. drivers/staging/comedi/range.c +10 −8
  222. drivers/staging/cptm1217/clearpad_tm1217.c +1 −12
  223. drivers/staging/crystalhd/crystalhd_lnx.c +5 −1
  224. drivers/staging/csr/Makefile +0 −1
  225. drivers/staging/csr/bh.c +90 −83
  226. drivers/staging/csr/csr_formatted_io.c +0 −27
  227. drivers/staging/csr/csr_formatted_io.h +0 −25
  228. drivers/staging/csr/csr_framework_ext.c +1 −12
  229. drivers/staging/csr/csr_panic.c +0 −1
  230. drivers/staging/csr/csr_time.c +9 −18
  231. drivers/staging/csr/csr_wifi_hip_card_sdio.c +4 −4
  232. drivers/staging/csr/csr_wifi_hip_download.c +2 −0
  233. drivers/staging/csr/csr_wifi_hip_send.c +2 −7
  234. drivers/staging/csr/csr_wifi_hip_udi.c +47 −47
  235. drivers/staging/csr/csr_wifi_hip_unifi.h +0 −1
  236. drivers/staging/csr/drv.c +9 −37
  237. drivers/staging/csr/firmware.c +2 −4
  238. drivers/staging/csr/io.c +17 −36
  239. drivers/staging/csr/monitor.c +1 −6
  240. drivers/staging/csr/netdev.c +6 −624
  241. drivers/staging/csr/sdio_events.c +2 −2
  242. drivers/staging/csr/sdio_mmc.c +21 −44
  243. drivers/staging/csr/sme_blocking.c +2 −2
  244. drivers/staging/csr/sme_native.c +1 −5
  245. drivers/staging/csr/sme_sys.c +8 −14
  246. drivers/staging/csr/sme_wext.c +3 −5
  247. drivers/staging/csr/ul_int.c +1 −4
  248. drivers/staging/csr/unifi_pdu_processing.c +1 −4
  249. drivers/staging/csr/unifi_priv.h +0 −40
  250. drivers/staging/csr/unifi_wext.h +6 −21
  251. drivers/staging/csr/wext_events.c +3 −5
  252. drivers/staging/cxt1e1/linux.c +6 −6
  253. drivers/staging/cxt1e1/musycc.c +5 −5
  254. drivers/staging/et131x/et131x.c +1 −6
  255. drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c +17 −17
  256. drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +7 −7
  257. drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +0 −2
  258. drivers/staging/gdm72xx/gdm_qos.c +59 −59
  259. drivers/staging/gdm72xx/gdm_qos.h +29 −29
  260. drivers/staging/gdm72xx/gdm_sdio.c +11 −26
  261. drivers/staging/gdm72xx/gdm_usb.c +24 −38
  262. drivers/staging/gdm72xx/gdm_usb.h +8 −8
  263. drivers/staging/gdm72xx/gdm_wimax.c +10 −6
  264. drivers/staging/gdm72xx/usb_boot.c +100 −120
  265. drivers/staging/iio/Documentation/generic_buffer.c +10 −0
  266. drivers/staging/iio/Documentation/inkernel.txt +3 −3
  267. drivers/staging/iio/Kconfig +1 −1
  268. drivers/staging/iio/TODO +1 −1
  269. drivers/staging/iio/accel/adis16201_core.c +2 −2
  270. drivers/staging/iio/accel/adis16201_ring.c +1 −2
  271. drivers/staging/iio/accel/adis16203_core.c +2 −2
  272. drivers/staging/iio/accel/adis16203_ring.c +1 −4
  273. drivers/staging/iio/accel/adis16204_core.c +2 −2
  274. drivers/staging/iio/accel/adis16204_ring.c +1 −2
  275. drivers/staging/iio/accel/adis16209_core.c +2 −2
  276. drivers/staging/iio/accel/adis16209_ring.c +1 −2
  277. drivers/staging/iio/accel/adis16220_core.c +4 −7
  278. drivers/staging/iio/accel/adis16240_core.c +2 −2
  279. drivers/staging/iio/accel/adis16240_ring.c +1 −2
  280. drivers/staging/iio/accel/kxsd9.c +3 −3
  281. drivers/staging/iio/accel/lis3l02dq.h +7 −7
  282. drivers/staging/iio/accel/lis3l02dq_core.c +10 −16
  283. drivers/staging/iio/accel/lis3l02dq_ring.c +15 −16
  284. drivers/staging/iio/accel/sca3000.h +1 −1
  285. drivers/staging/iio/accel/sca3000_core.c +6 −8
  286. drivers/staging/iio/accel/sca3000_ring.c +1 −1
  287. drivers/staging/iio/adc/Kconfig +20 −23
  288. drivers/staging/iio/adc/Makefile +1 −4
  289. drivers/staging/iio/adc/ad7192.c +67 −456
  290. drivers/staging/iio/adc/ad7298_core.c +1 −1
  291. drivers/staging/iio/adc/ad7298_ring.c +1 −2
  292. drivers/staging/iio/adc/ad7476.h +0 −66
  293. drivers/staging/iio/adc/ad7476_ring.c +0 −64
  294. drivers/staging/iio/adc/ad7606.h +1 −1
  295. drivers/staging/iio/adc/ad7606_core.c +3 −3
  296. drivers/staging/iio/adc/ad7606_ring.c +1 −2
  297. drivers/staging/iio/adc/ad7780.c +109 −128
  298. drivers/staging/iio/adc/ad7793.c +121 −567
  299. drivers/staging/iio/adc/ad7793.h +9 −1
  300. drivers/staging/iio/adc/ad7887_core.c +1 −1
  301. drivers/staging/iio/adc/ad7887_ring.c +1 −1
  302. drivers/staging/iio/adc/ad799x_ring.c +1 −2
  303. drivers/staging/iio/adc/lpc32xx_adc.c +1 −1
  304. drivers/staging/iio/adc/max1363.h +1 −1
  305. drivers/staging/iio/adc/max1363_core.c +16 −16
  306. drivers/staging/iio/adc/max1363_ring.c +1 −1
  307. drivers/staging/iio/adc/mxs-lradc.c +590 −0
  308. drivers/staging/iio/adc/spear_adc.c +9 −18
  309. drivers/staging/iio/gyro/adis16060_core.c +2 −2
  310. drivers/staging/iio/gyro/adis16080_core.c +1 −1
  311. drivers/staging/iio/gyro/adis16130_core.c +1 −1
  312. drivers/staging/iio/gyro/adis16260_core.c +3 −9
  313. drivers/staging/iio/gyro/adis16260_ring.c +1 −2
  314. drivers/staging/iio/gyro/adxrs450_core.c +1 −1
  315. drivers/staging/iio/iio_dummy_evgen.c +1 −1
  316. drivers/staging/iio/iio_hwmon.c +7 −40
  317. drivers/staging/iio/iio_simple_dummy.c +9 −15
  318. drivers/staging/iio/iio_simple_dummy.h +4 −2
  319. drivers/staging/iio/iio_simple_dummy_buffer.c +11 −2
  320. drivers/staging/iio/impedance-analyzer/ad5933.c +2 −2
  321. drivers/staging/iio/imu/adis16400.h +1 −1
  322. drivers/staging/iio/imu/adis16400_core.c +6 −12
  323. drivers/staging/iio/imu/adis16400_ring.c +1 −1
  324. drivers/staging/iio/light/isl29018.c +15 −2
  325. drivers/staging/iio/light/tsl2563.c +1 −1
  326. drivers/staging/iio/magnetometer/hmc5843.c +1 −1
  327. drivers/staging/iio/meter/ade7753.c +4 −9
  328. drivers/staging/iio/meter/ade7754.c +3 −9
  329. drivers/staging/iio/meter/ade7758.h +1 −1
  330. drivers/staging/iio/meter/ade7758_core.c +4 −9
  331. drivers/staging/iio/meter/ade7758_ring.c +1 −2
  332. drivers/staging/iio/meter/ade7759.c +3 −8
  333. drivers/staging/iio/meter/ade7854-spi.c +1 −1
  334. drivers/staging/iio/resolver/ad2s1210.c +1 −1
  335. drivers/staging/iio/ring_hw.h +1 −1
  336. drivers/staging/iio/ring_sw.c +3 −4
  337. drivers/staging/iio/trigger/Kconfig +2 −0
  338. drivers/staging/iio/trigger/iio-trig-bfin-timer.c +88 −21
  339. drivers/staging/iio/trigger/iio-trig-bfin-timer.h +24 −0
  340. drivers/staging/iio/trigger/iio-trig-gpio.c +4 −4
  341. drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +4 −4
  342. drivers/staging/iio/trigger/iio-trig-sysfs.c +16 −1
  343. drivers/staging/imx-drm/Kconfig +35 −0
  344. drivers/staging/imx-drm/Makefile +9 −0
  345. drivers/staging/imx-drm/TODO +22 −0
  346. drivers/staging/imx-drm/imx-drm-core.c +884 −0
  347. drivers/staging/imx-drm/imx-drm.h +58 −0
  348. drivers/staging/imx-drm/imx-fb.c +47 −0
  349. drivers/staging/imx-drm/imx-fbdev.c +74 −0
  350. drivers/staging/imx-drm/ipu-v3/Makefile +3 −0
  351. drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h +318 −0
  352. drivers/staging/imx-drm/ipu-v3/ipu-common.c +1143 −0
  353. drivers/staging/imx-drm/ipu-v3/ipu-dc.c +372 −0
  354. drivers/staging/imx-drm/ipu-v3/ipu-di.c +700 −0
  355. drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c +408 −0
  356. drivers/staging/imx-drm/ipu-v3/ipu-dp.c +336 −0
  357. drivers/staging/imx-drm/ipu-v3/ipu-prv.h +206 −0
  358. drivers/staging/imx-drm/ipuv3-crtc.c +579 −0
  359. drivers/staging/imx-drm/parallel-display.c +261 −0
  360. drivers/staging/ipack/Kconfig +1 −0
  361. drivers/staging/ipack/TODO +2 −23
  362. drivers/staging/ipack/bridges/tpci200.c +306 −429
  363. drivers/staging/ipack/bridges/tpci200.h +27 −12
  364. drivers/staging/ipack/devices/ipoctal.c +321 −417
  365. drivers/staging/ipack/devices/scc2698.h +58 −59
  366. drivers/staging/ipack/ipack.c +350 −22
  367. drivers/staging/ipack/ipack.h +61 −27
  368. drivers/staging/ipack/ipack_ids.h +32 −0
  369. drivers/staging/keucr/smcommon.h +0 −2
  370. drivers/staging/line6/pcm.c +7 −1
  371. drivers/staging/line6/variax.c +4 −4
  372. drivers/staging/nvec/Kconfig +1 −1
  373. drivers/staging/nvec/nvec.c +13 −12
  374. drivers/staging/olpc_dcon/olpc_dcon.c +24 −29
  375. drivers/staging/olpc_dcon/olpc_dcon_xo_1.c +9 −6
  376. drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c +4 −2
  377. drivers/staging/omap-thermal/omap-bandgap.c +12 −11
  378. drivers/staging/omap-thermal/omap-thermal-common.c +36 −6
  379. drivers/staging/omap-thermal/omap4-thermal.c +27 −27
  380. drivers/staging/omap-thermal/omap5-thermal.c +19 −19
  381. drivers/staging/omapdrm/omap_crtc.c +31 −2
  382. drivers/staging/omapdrm/omap_dmm_tiler.c +43 −8
  383. drivers/staging/omapdrm/omap_dmm_tiler.h +15 −2
  384. drivers/staging/omapdrm/omap_drv.c +18 −3
  385. drivers/staging/omapdrm/omap_drv.h +31 −2
  386. drivers/staging/omapdrm/omap_fb.c +85 −14
  387. drivers/staging/omapdrm/omap_gem.c +58 −2
  388. drivers/staging/omapdrm/omap_plane.c +90 −21
  389. drivers/staging/ozwpan/ozcdev.c +7 −7
  390. drivers/staging/ozwpan/ozevent.c +3 −3
  391. drivers/staging/ozwpan/ozhcd.c +80 −24
  392. drivers/staging/ozwpan/ozmain.c +1 −1
  393. drivers/staging/ozwpan/ozpd.c +2 −9
  394. drivers/staging/ozwpan/ozpd.h +1 −0
  395. drivers/staging/ozwpan/ozproto.c +13 −0
  396. drivers/staging/ozwpan/ozproto.h +7 −1
  397. drivers/staging/ozwpan/ozprotocol.h +5 −1
  398. drivers/staging/panel/panel.c +26 −26
  399. drivers/staging/ramster/Kconfig +21 −4
  400. drivers/staging/ramster/Makefile +6 −1
  401. drivers/staging/ramster/TODO +0 −13
  402. drivers/staging/ramster/cluster/Makefile +0 −3
  403. drivers/staging/ramster/ramster.h +27 −86
  404. drivers/staging/ramster/ramster/heartbeat.c +2 −4
  405. drivers/staging/ramster/ramster/heartbeat.h +0 −0
  406. drivers/staging/ramster/ramster/masklog.c +0 −0
  407. drivers/staging/ramster/ramster/masklog.h +0 −0
  408. drivers/staging/ramster/ramster/nodemanager.c +9 −6
  409. drivers/staging/ramster/ramster/nodemanager.h +0 −0
  410. drivers/staging/ramster/ramster/r2net.c +46 −33
  411. drivers/staging/ramster/ramster/ramster.c +985 −0
  412. drivers/staging/ramster/ramster/ramster.h +161 −0
  413. drivers/staging/ramster/ramster/ramster_nodemanager.h +0 −0
  414. drivers/staging/ramster/ramster/tcp.c +25 −28
  415. drivers/staging/ramster/ramster/tcp.h +0 −0
  416. drivers/staging/ramster/ramster/tcp_internal.h +0 −0
  417. drivers/staging/ramster/tmem.c +178 −135
  418. drivers/staging/ramster/tmem.h +62 −47
  419. drivers/staging/ramster/xvmalloc.c +0 −509
  420. drivers/staging/ramster/xvmalloc.h +0 −30
  421. drivers/staging/ramster/xvmalloc_int.h +0 −95
  422. drivers/staging/ramster/zbud.c +1060 −0
  423. drivers/staging/ramster/zbud.h +33 −0
  424. drivers/staging/ramster/zcache-main.c +1033 −2533
  425. drivers/staging/ramster/zcache.h +43 −12
  426. drivers/staging/rtl8187se/ieee80211/ieee80211.h +1 −1
  427. drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +3 −10
  428. drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c +3 −2
  429. drivers/staging/rtl8187se/r8180_core.c +2 −2
  430. drivers/staging/rtl8187se/r8180_hw.h +7 −2
  431. drivers/staging/rtl8187se/r8185b_init.c +1 −1
  432. drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c +5 −4
  433. drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h +4 −0
  434. drivers/staging/rtl8192e/rtl8192e/rtl_core.c +4 −2
  435. drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +1 −1
  436. drivers/staging/rtl8192e/rtllib.h +4 −4
  437. drivers/staging/rtl8192e/rtllib_softmac.c +8 −16
  438. drivers/staging/rtl8192e/rtllib_softmac_wx.c +4 −3
  439. drivers/staging/rtl8192u/ieee80211/ieee80211.h +2 −2
  440. drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +7 −13
  441. drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c +3 −2
  442. drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c +1 −1
  443. drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h +2 −2
  444. drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c +1 −1
  445. drivers/staging/rtl8192u/r8192U_core.c +8 −19
  446. drivers/staging/rtl8192u/r819xU_HTType.h +1 −1
  447. drivers/staging/rtl8192u/r819xU_phyreg.h +1 −1
  448. drivers/staging/rtl8712/drv_types.h +0 −9
  449. drivers/staging/rtl8712/ethernet.h +0 −8
  450. drivers/staging/rtl8712/os_intfs.c +1 −1
  451. drivers/staging/rtl8712/rtl8712_recv.c +8 −1
  452. drivers/staging/rtl8712/rtl8712_recv.h +1 −1
  453. drivers/staging/rtl8712/rtl8712_xmit.c +1 −1
  454. drivers/staging/rtl8712/rtl871x_ioctl_linux.c +1 −3
  455. drivers/staging/rtl8712/rtl871x_ioctl_set.c +1 −4
  456. drivers/staging/rtl8712/rtl871x_mlme.c +3 −2
  457. drivers/staging/rtl8712/rtl871x_pwrctrl.h +0 −20
  458. drivers/staging/rtl8712/rtl871x_recv.c +5 −4
  459. drivers/staging/rtl8712/rtl871x_security.c +4 −4
  460. drivers/staging/rtl8712/usb_intf.c +0 −1
  461. drivers/staging/rtl8712/usb_osintf.h +0 −3
  462. drivers/staging/rtl8712/usb_vendor_req.h +0 −58
  463. drivers/staging/rts5139/rts51x_fop.c +1 −1
  464. drivers/staging/rts5139/trace.h +3 −29
  465. drivers/staging/rts_pstor/ms.c +340 −532
  466. drivers/staging/rts_pstor/rtsx.c +54 −58
  467. drivers/staging/rts_pstor/rtsx_card.c +81 −105
  468. drivers/staging/rts_pstor/rtsx_chip.c +246 −317
  469. drivers/staging/rts_pstor/rtsx_scsi.c +169 −236
  470. drivers/staging/rts_pstor/rtsx_transport.c +45 −55
  471. drivers/staging/rts_pstor/sd.c +415 −640
  472. drivers/staging/rts_pstor/trace.h +3 −27
  473. drivers/staging/sbe-2t3e3/2t3e3.h +0 −1
  474. drivers/staging/sbe-2t3e3/dc.c +6 −4
  475. drivers/staging/sbe-2t3e3/module.c +11 −4
  476. drivers/staging/sbe-2t3e3/netdev.c +4 −4
  477. drivers/staging/sep/sep_main.c +1 −1
  478. drivers/staging/serqt_usb2/serqt_usb2.c +3 −8
  479. drivers/staging/silicom/Kconfig +46 −0
  480. drivers/staging/silicom/Makefile +9 −0
  481. drivers/staging/silicom/README +14 −0
  482. drivers/staging/silicom/TODO +8 −0
  483. drivers/staging/silicom/bits.h +56 −0
  484. drivers/staging/silicom/bp_ioctl.h +140 −0
  485. drivers/staging/silicom/bp_mod.c +8931 −0
  486. drivers/staging/silicom/bp_mod.h +704 −0
  487. drivers/staging/silicom/bp_proc.c +1350 −0
  488. drivers/staging/silicom/bypass.h +202 −0
  489. drivers/staging/silicom/bypasslib/Makefile +6 −0
  490. drivers/staging/silicom/bypasslib/bp_ioctl.h +198 −0
  491. drivers/staging/silicom/bypasslib/bplibk.h +47 −0
  492. drivers/staging/silicom/bypasslib/bypass.c +529 −0
  493. drivers/staging/silicom/bypasslib/libbp_sd.h +509 −0
  494. drivers/staging/silicom/libbp_sd.h +550 −0
  495. drivers/staging/slicoss/slicoss.c +14 −26
  496. drivers/staging/sm7xxfb/sm7xx.h +1 −1
  497. drivers/staging/sm7xxfb/sm7xxfb.c +49 −70
  498. drivers/staging/speakup/i18n.c +1 −0
  499. drivers/staging/speakup/speakup_soft.c +5 −10
  500. drivers/staging/telephony/ixj.c +2 −2
  501. drivers/staging/tidspbridge/Documentation/error-codes +1 −1
  502. drivers/staging/tidspbridge/core/_tiomap.h +1 −1
  503. drivers/staging/tidspbridge/core/chnl_sm.c +5 −4
  504. drivers/staging/tidspbridge/core/dsp-clock.c +2 −0
  505. drivers/staging/tidspbridge/core/io_sm.c +5 −5
  506. drivers/staging/tidspbridge/core/sync.c +1 −1
  507. drivers/staging/tidspbridge/core/tiomap3430.c +4 −4
  508. drivers/staging/tidspbridge/core/tiomap3430_pwr.c +1 −1
  509. drivers/staging/tidspbridge/core/wdt.c +4 −3
  510. drivers/staging/tidspbridge/dynload/tramp.c +4 −4
  511. drivers/staging/tidspbridge/gen/uuidutil.c +0 −21
  512. drivers/staging/tidspbridge/hw/hw_mmu.c +3 −3
  513. drivers/staging/tidspbridge/include/dspbridge/dspioctl.h +1 −1
  514. drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h +1 −1
  515. drivers/staging/tidspbridge/include/dspbridge/node.h +1 −1
  516. drivers/staging/tidspbridge/include/dspbridge/ntfy.h +1 −1
  517. drivers/staging/tidspbridge/include/dspbridge/proc.h +1 −1
  518. drivers/staging/tidspbridge/include/dspbridge/strm.h +1 −1
  519. drivers/staging/tidspbridge/include/dspbridge/sync.h +2 −2
  520. drivers/staging/tidspbridge/include/dspbridge/uuidutil.h +0 −20
  521. drivers/staging/tidspbridge/rmgr/dbdcd.c +23 −6
  522. drivers/staging/tidspbridge/rmgr/drv_interface.c +1 −13
  523. drivers/staging/tidspbridge/rmgr/dspdrv.c +2 −2
  524. drivers/staging/tidspbridge/rmgr/mgr.c +2 −2
  525. drivers/staging/tidspbridge/rmgr/nldr.c +1 −1
  526. drivers/staging/tidspbridge/rmgr/node.c +2 −3
  527. drivers/staging/tidspbridge/rmgr/proc.c +1 −1
  528. drivers/staging/usbip/Kconfig +2 −2
  529. drivers/staging/usbip/stub_dev.c +6 −2
  530. drivers/staging/usbip/stub_rx.c +1 −1
  531. drivers/staging/usbip/usbip_common.c +4 −0
  532. drivers/staging/usbip/userspace/configure.ac +6 −6
  533. drivers/staging/usbip/userspace/doc/usbip.8 +42 −24
  534. drivers/staging/usbip/userspace/doc/usbip_bind_driver.8 +0 −42
  535. drivers/staging/usbip/userspace/doc/usbipd.8 +10 −6
  536. drivers/staging/usbip/vhci_hcd.c +22 −9
  537. drivers/staging/vme/devices/vme_pio2_core.c +5 −5
  538. drivers/staging/vme/devices/vme_user.c +5 −5
  539. drivers/staging/vt6655/80211mgr.h +1 −1
  540. drivers/staging/vt6655/baseband.c +86 −86
  541. drivers/staging/vt6655/baseband.h +5 −5
  542. drivers/staging/vt6655/bssdb.c +2 −2
  543. drivers/staging/vt6655/card.c +51 −50
  544. drivers/staging/vt6655/datarate.c +1 −1
  545. drivers/staging/vt6655/device.h +2 −2
  546. drivers/staging/vt6655/device_main.c +48 −56
  547. drivers/staging/vt6655/dpc.c +1 −1
  548. drivers/staging/vt6655/hostap.c +2 −6
  549. drivers/staging/vt6655/ioctl.c +3 −6
  550. drivers/staging/vt6655/iwctl.c +3 −3
  551. drivers/staging/vt6655/key.c +1 −1
  552. drivers/staging/vt6655/mac.c +6 −6
  553. drivers/staging/vt6655/mac.h +1 −1
  554. drivers/staging/vt6655/mib.c +1 −1
  555. drivers/staging/vt6655/power.c +1 −1
  556. drivers/staging/vt6655/rf.c +41 −41
  557. drivers/staging/vt6655/rf.h +1 −1
  558. drivers/staging/vt6655/rxtx.c +21 −21
  559. drivers/staging/vt6655/tcrc.c +1 −1
  560. drivers/staging/vt6655/tcrc.h +1 −1
  561. drivers/staging/vt6655/tether.c +2 −2
  562. drivers/staging/vt6655/tkip.c +1 −1
  563. drivers/staging/vt6655/vntwifi.c +1 −1
  564. drivers/staging/vt6655/wcmd.c +3 −3
  565. drivers/staging/vt6655/wmgr.c +28 −28
  566. drivers/staging/vt6655/wmgr.h +2 −2
  567. drivers/staging/vt6655/wpa.c +1 −1
  568. drivers/staging/vt6655/wpa2.c +4 −4
  569. drivers/staging/vt6655/wpactl.c +3 −3
  570. drivers/staging/vt6655/wroute.c +1 −1
  571. drivers/staging/vt6656/80211mgr.h +2 −2
  572. drivers/staging/vt6656/baseband.c +3 −3
  573. drivers/staging/vt6656/baseband.h +1 −1
  574. drivers/staging/vt6656/bssdb.c +9 −9
  575. drivers/staging/vt6656/card.c +19 −19
  576. drivers/staging/vt6656/device.h +1 −1
  577. drivers/staging/vt6656/dpc.c +1 −1
  578. drivers/staging/vt6656/hostap.c +13 −17
  579. drivers/staging/vt6656/int.c +1 −1
  580. drivers/staging/vt6656/ioctl.c +4 −7
  581. drivers/staging/vt6656/iwctl.c +1 −1
  582. drivers/staging/vt6656/key.c +2 −2
  583. drivers/staging/vt6656/main_usb.c +10 −10
  584. drivers/staging/vt6656/power.c +1 −1
  585. drivers/staging/vt6656/rf.c +29 −29
  586. drivers/staging/vt6656/rf.h +1 −1
  587. drivers/staging/vt6656/rxtx.c +26 −26
  588. drivers/staging/vt6656/tcrc.c +1 −1
  589. drivers/staging/vt6656/tcrc.h +1 −1
  590. drivers/staging/vt6656/tether.c +2 −2
  591. drivers/staging/vt6656/tkip.c +1 −1
  592. drivers/staging/vt6656/wcmd.c +4 −4
  593. drivers/staging/vt6656/wctl.c +1 −1
  594. drivers/staging/vt6656/wmgr.c +13 −13
  595. drivers/staging/vt6656/wpa.c +1 −1
  596. drivers/staging/vt6656/wpa2.c +3 −3
  597. drivers/staging/vt6656/wpactl.c +3 −3
  598. drivers/staging/winbond/Kconfig +1 −1
  599. drivers/staging/winbond/localpara.h +2 −2
  600. drivers/staging/winbond/mds.c +1 −1
  601. drivers/staging/winbond/mto.c +1 −1
  602. drivers/staging/winbond/phy_calibration.c +7 −7
  603. drivers/staging/winbond/reg.c +1 −1
  604. drivers/staging/winbond/sme_api.h +5 −6
  605. drivers/staging/winbond/wb35reg.c +2 −2
  606. drivers/staging/winbond/wb35tx.c +74 −80
  607. drivers/staging/winbond/wb35tx_s.h +19 −27
  608. drivers/staging/wlags49_h2/README.ubuntu +6 −6
  609. drivers/staging/wlags49_h2/TODO +5 −5
  610. drivers/staging/wlags49_h2/hcf.c +10 −10
  611. drivers/staging/wlags49_h2/hcfcfg.h +1 −1
  612. drivers/staging/wlags49_h2/hcfdef.h +3 −3
  613. drivers/staging/wlags49_h2/mdd.h +4 −4
  614. drivers/staging/wlags49_h2/sta_h2.c +1 −1
  615. drivers/staging/wlags49_h2/sta_h25.c +1 −1
  616. drivers/staging/wlags49_h2/wl_enc.h +1 −1
  617. drivers/staging/wlags49_h2/wl_if.h +1 −1
  618. drivers/staging/wlags49_h2/wl_internal.h +2 −2
  619. drivers/staging/wlags49_h2/wl_main.c +9 −9
  620. drivers/staging/wlags49_h2/wl_netdev.c +19 −40
  621. drivers/staging/wlags49_h2/wl_pci.c +4 −4
  622. drivers/staging/wlags49_h2/wl_priv.c +1 −1
  623. drivers/staging/wlags49_h2/wl_profile.c +1 −1
  624. drivers/staging/wlags49_h2/wl_version.h +1 −1
  625. drivers/staging/wlags49_h2/wl_wext.c +14 −13
  626. drivers/staging/wlags49_h25/Kconfig +1 −1
  627. drivers/staging/wlags49_h25/TODO +4 −4
  628. drivers/staging/wlan-ng/cfg80211.c +7 −4
  629. drivers/staging/wlan-ng/hfa384x_usb.c +11 −26
  630. drivers/staging/wlan-ng/p80211conv.c +3 −6
  631. drivers/staging/wlan-ng/p80211netdev.c +4 −17
  632. drivers/staging/wlan-ng/p80211netdev.h +1 −1
  633. drivers/staging/wlan-ng/p80211req.c +69 −83
  634. drivers/staging/wlan-ng/p80211types.h +1 −1
  635. drivers/staging/wlan-ng/p80211wep.c +6 −12
  636. drivers/staging/wlan-ng/prism2fw.c +28 −28
  637. drivers/staging/wlan-ng/prism2sta.c +13 −40
  638. drivers/staging/xgifb/XGI_main_26.c +25 −20
  639. drivers/staging/xgifb/vb_def.h +0 −21
  640. drivers/staging/xgifb/vb_init.c +1 −4
  641. drivers/staging/xgifb/vb_setmode.c +170 −431
  642. drivers/staging/xgifb/vb_struct.h +6 −43
  643. drivers/staging/xgifb/vb_table.h +46 −148
  644. drivers/staging/zcache/tmem.c +1 −1
  645. drivers/staging/zsmalloc/zsmalloc-main.c +273 −49
  646. drivers/staging/zsmalloc/zsmalloc_int.h +0 −155
  647. include/linux/hid-sensor-hub.h +160 −0
  648. include/linux/hid-sensor-ids.h +112 −0
  649. include/linux/iio/adc/ad_sigma_delta.h +173 −0
  650. include/linux/iio/buffer.h +2 −4
  651. include/linux/iio/consumer.h +41 −3
  652. include/linux/iio/iio.h +58 −7
  653. include/linux/iio/kfifo_buf.h +3 −0
  654. include/linux/iio/machine.h +5 −0
  655. include/linux/iio/trigger.h +7 −6
  656. include/linux/iio/trigger_consumer.h +11 −0
  657. include/linux/iio/types.h +1 −0
  658. include/linux/mod_devicetable.h +8 −0
  659. include/linux/platform_data/ad5755.h +103 −0
  660. include/linux/platform_data/ad7791.h +17 −0
  661. include/linux/power/generic-adc-battery.h +29 −0
  662. scripts/mod/file2alias.c +15 −0
Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt+15−0
@@ -0,0 +1,15 @@
1* Freescale i.MX28 LRADC device driver
2
3Required properties:
4- compatible: Should be "fsl,imx28-lradc"
5- reg: Address and length of the register set for the device
6- interrupts: Should contain the LRADC interrupts
7
8Examples:
9
10 lradc@80050000 {
11 compatible = "fsl,imx28-lradc";
12 reg = <0x80050000 0x2000>;
13 interrupts = <10 14 15 16 17 18 19
14 20 21 22 23 24 25>;
15 };
Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt+41−0
@@ -0,0 +1,41 @@
1Freescale i.MX IPUv3
2====================
3
4Required properties:
5- compatible: Should be "fsl,<chip>-ipu"
6- reg: should be register base and length as documented in the
7 datasheet
8- interrupts: Should contain sync interrupt and error interrupt,
9 in this order.
10- #crtc-cells: 1, See below
11
12example:
13
14ipu: ipu@18000000 {
15 #crtc-cells = <1>;
16 compatible = "fsl,imx53-ipu";
17 reg = <0x18000000 0x080000000>;
18 interrupts = <11 10>;
19};
20
21Parallel display support
22========================
23
24Required properties:
25- compatible: Should be "fsl,imx-parallel-display"
26- crtc: the crtc this display is connected to, see below
27Optional properties:
28- interface_pix_fmt: How this display is connected to the
29 crtc. Currently supported types: "rgb24", "rgb565"
30- edid: verbatim EDID data block describing attached display.
31- ddc: phandle describing the i2c bus handling the display data
32 channel
33
34example:
35
36display@di0 {
37 compatible = "fsl,imx-parallel-display";
38 edid = [edid-data];
39 crtc = <&ipu 0>;
40 interface-pix-fmt = "rgb24";
41};
Documentation/hid/hid-sensor.txt+140−0
@@ -0,0 +1,140 @@
1
2HID Sensors Framework
3======================
4HID sensor framework provides necessary interfaces to implement sensor drivers,
5which are connected to a sensor hub. The sensor hub is a HID device and it provides
6a report descriptor conforming to HID 1.12 sensor usage tables.
7
8Description from the HID 1.12 "HID Sensor Usages" specification:
9"Standardization of HID usages for sensors would allow (but not require) sensor
10hardware vendors to provide a consistent Plug And Play interface at the USB boundary,
11thereby enabling some operating systems to incorporate common device drivers that
12could be reused between vendors, alleviating any need for the vendors to provide
13the drivers themselves."
14
15This specification describes many usage IDs, which describe the type of sensor
16and also the individual data fields. Each sensor can have variable number of
17data fields. The length and order is specified in the report descriptor. For
18example a part of report descriptor can look like:
19
20 INPUT(1)[INPUT]
21 ..
22 Field(2)
23 Physical(0020.0073)
24 Usage(1)
25 0020.045f
26 Logical Minimum(-32767)
27 Logical Maximum(32767)
28 Report Size(8)
29 Report Count(1)
30 Report Offset(16)
31 Flags(Variable Absolute)
32..
33..
34
35The report is indicating "sensor page (0x20)" contains an accelerometer-3D (0x73).
36This accelerometer-3D has some fields. Here for example field 2 is motion intensity
37(0x045f) with a logical minimum value of -32767 and logical maximum of 32767. The
38order of fields and length of each field is important as the input event raw
39data will use this format.
40
41
42Implementation
43=================
44
45This specification defines many different types of sensors with different sets of
46data fields. It is difficult to have a common input event to user space applications,
47for different sensors. For example an accelerometer can send X,Y and Z data, whereas
48an ambient light sensor can send illumination data.
49So the implementation has two parts:
50- Core hid driver
51- Individual sensor processing part (sensor drivers)
52
53Core driver
54-----------
55The core driver registers (hid-sensor-hub) registers as a HID driver. It parses
56report descriptors and identifies all the sensors present. It adds an MFD device
57with name HID-SENSOR-xxxx (where xxxx is usage id from the specification).
58For example
59HID-SENSOR-200073 is registered for an Accelerometer 3D driver.
60So if any driver with this name is inserted, then the probe routine for that
61function will be called. So an accelerometer processing driver can register
62with this name and will be probed if there is an accelerometer-3D detected.
63
64The core driver provides a set of APIs which can be used by the processing
65drivers to register and get events for that usage id. Also it provides parsing
66functions, which get and set each input/feature/output report.
67
68Individual sensor processing part (sensor drivers)
69-----------
70The processing driver will use an interface provided by the core driver to parse
71the report and get the indexes of the fields and also can get events. This driver
72can use IIO interface to use the standard ABI defined for a type of sensor.
73
74
75Core driver Interface
76=====================
77
78Callback structure:
79Each processing driver can use this structure to set some callbacks.
80 int (*suspend)(..): Callback when HID suspend is received
81 int (*resume)(..): Callback when HID resume is received
82 int (*capture_sample)(..): Capture a sample for one of its data fields
83 int (*send_event)(..): One complete event is received which can have
84 multiple data fields.
85
86Registration functions:
87int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
88 u32 usage_id,
89 struct hid_sensor_hub_callbacks *usage_callback):
90
91Registers callbacks for an usage id. The callback functions are not allowed
92to sleep.
93
94
95int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
96 u32 usage_id):
97
98Removes callbacks for an usage id.
99
100
101Parsing function:
102int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
103 u8 type,
104 u32 usage_id, u32 attr_usage_id,
105 struct hid_sensor_hub_attribute_info *info);
106
107A processing driver can look for some field of interest and check if it exists
108in a report descriptor. If it exists it will store necessary information
109so that fields can be set or get individually.
110These indexes avoid searching every time and getting field index to get or set.
111
112
113Set Feature report
114int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
115 u32 field_index, s32 value);
116
117This interface is used to set a value for a field in feature report. For example
118if there is a field report_interval, which is parsed by a call to
119sensor_hub_input_get_attribute_info before, then it can directly set that individual
120field.
121
122
123int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
124 u32 field_index, s32 *value);
125
126This interface is used to get a value for a field in input report. For example
127if there is a field report_interval, which is parsed by a call to
128sensor_hub_input_get_attribute_info before, then it can directly get that individual
129field value.
130
131
132int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
133 u32 usage_id,
134 u32 attr_usage_id, u32 report_id);
135
136This is used to get a particular field value through input reports. For example
137accelerometer wants to poll X axis value, then it can call this function with
138the usage id of X axis. HID sensors can provide events, so this is not necessary
139to poll for any field. If there is some new sample, the core driver will call
140registered callback function to process the sample.
drivers/hid/Kconfig+14−0
@@ -708,6 +708,20 @@ config HID_ZYDACRON · 707 unmodified lines
708 ---help---708 ---help---
709 Support for Zydacron remote control.709 Support for Zydacron remote control.
710 710
711config HID_SENSOR_HUB
712 tristate "HID Sensors framework support"
713 depends on USB_HID
714 select MFD_CORE
715 default n
716 -- help---
717 Support for HID Sensor framework. This creates a MFD instance
718 for a sensor hub and identifies all the sensors connected to it.
719 Each sensor is registered as a MFD cell, so that sensor specific
720 processing can be done in a separate driver. Each sensor
721 drivers can use the service provided by this driver to register
722 for events and handle data streams. Each sensor driver can format
723 data and present to user mode using input or IIO interface.
724
711endmenu725endmenu
712 726
713endif # HID727endif # HID
drivers/hid/Makefile+1−0
@@ -112,6 +112,7 @@ obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o · 111 unmodified lines
112obj-$(CONFIG_HID_WACOM) += hid-wacom.o112obj-$(CONFIG_HID_WACOM) += hid-wacom.o
113obj-$(CONFIG_HID_WALTOP) += hid-waltop.o113obj-$(CONFIG_HID_WALTOP) += hid-waltop.o
114obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o114obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o
115obj-$(CONFIG_HID_SENSOR_HUB) += hid-sensor-hub.o
115 116
116obj-$(CONFIG_USB_HID) += usbhid/117obj-$(CONFIG_USB_HID) += usbhid/
117obj-$(CONFIG_USB_MOUSE) += usbhid/118obj-$(CONFIG_USB_MOUSE) += usbhid/
drivers/hid/hid-core.c+5−0
@@ -1568,6 +1568,10 @@ static const struct hid_device_id hid_have_special_driver[] = { · 1567 unmodified lines
1568 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },1568 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
1569 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },1569 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
1570 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },1570 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
1571 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, USB_DEVICE_ID_SENSOR_HUB_1020) },
1572 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, USB_DEVICE_ID_SENSOR_HUB_09FA) },
1573 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, USB_DEVICE_ID_SENSOR_HUB_1020) },
1574 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, USB_DEVICE_ID_SENSOR_HUB_09FA) },
1571 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },1575 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
1572 { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },1576 { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
1573 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },1577 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
@@ -1665,6 +1669,7 @@ static const struct hid_device_id hid_have_special_driver[] = { · 91 unmodified lines
1665 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },1669 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1666 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },1670 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
1667 { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },1671 { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
1672 { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_SENSOR_HUB_7014) },
1668 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },1673 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
1669 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },1674 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
1670 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },1675 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
drivers/hid/hid-ids.h+6−0
@@ -429,6 +429,11 @@ · 428 unmodified lines
429#define USB_VENDOR_ID_IMATION 0x0718429#define USB_VENDOR_ID_IMATION 0x0718
430#define USB_DEVICE_ID_DISC_STAKKA 0xd000430#define USB_DEVICE_ID_DISC_STAKKA 0xd000
431 431
432#define USB_VENDOR_ID_INTEL_8086 0x8086
433#define USB_VENDOR_ID_INTEL_8087 0x8087
434#define USB_DEVICE_ID_SENSOR_HUB_1020 0x1020
435#define USB_DEVICE_ID_SENSOR_HUB_09FA 0x09FA
436
432#define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615437#define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615
433#define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070438#define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070
434 439
@@ -706,6 +711,7 @@ · 271 unmodified lines
706 711
707#define USB_VENDOR_ID_STANTUM_STM 0x0483712#define USB_VENDOR_ID_STANTUM_STM 0x0483
708#define USB_DEVICE_ID_MTP_STM 0x3261713#define USB_DEVICE_ID_MTP_STM 0x3261
714#define USB_DEVICE_ID_SENSOR_HUB_7014 0x7014
709 715
710#define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403716#define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403
711#define USB_DEVICE_ID_MTP_SITRONIX 0x5001717#define USB_DEVICE_ID_MTP_SITRONIX 0x5001
drivers/hid/hid-sensor-hub.c+680−0
@@ -0,0 +1,680 @@
1/*
2 * HID Sensors Driver
3 * Copyright (c) 2012, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 */
19#include <linux/device.h>
20#include <linux/hid.h>
21#include <linux/usb.h>
22#include "usbhid/usbhid.h"
23#include <linux/module.h>
24#include <linux/slab.h>
25#include <linux/mfd/core.h>
26#include <linux/list.h>
27#include <linux/hid-sensor-ids.h>
28#include <linux/hid-sensor-hub.h>
29#include "hid-ids.h"
30
31/**
32 * struct sensor_hub_pending - Synchronous read pending information
33 * @status: Pending status true/false.
34 * @ready: Completion synchronization data.
35 * @usage_id: Usage id for physical device, E.g. Gyro usage id.
36 * @attr_usage_id: Usage Id of a field, E.g. X-AXIS for a gyro.
37 * @raw_size: Response size for a read request.
38 * @raw_data: Place holder for received response.
39 */
40struct sensor_hub_pending {
41 bool status;
42 struct completion ready;
43 u32 usage_id;
44 u32 attr_usage_id;
45 int raw_size;
46 u8 *raw_data;
47};
48
49/**
50 * struct sensor_hub_data - Hold a instance data for a HID hub device
51 * @hsdev: Stored hid instance for current hub device.
52 * @mutex: Mutex to serialize synchronous request.
53 * @lock: Spin lock to protect pending request structure.
54 * @pending: Holds information of pending sync read request.
55 * @dyn_callback_list: Holds callback function
56 * @dyn_callback_lock: spin lock to protect callback list
57 * @hid_sensor_hub_client_devs: Stores all MFD cells for a hub instance.
58 * @hid_sensor_client_cnt: Number of MFD cells, (no of sensors attached).
59 */
60struct sensor_hub_data {
61 struct hid_sensor_hub_device *hsdev;
62 struct mutex mutex;
63 spinlock_t lock;
64 struct sensor_hub_pending pending;
65 struct list_head dyn_callback_list;
66 spinlock_t dyn_callback_lock;
67 struct mfd_cell *hid_sensor_hub_client_devs;
68 int hid_sensor_client_cnt;
69};
70
71/**
72 * struct hid_sensor_hub_callbacks_list - Stores callback list
73 * @list: list head.
74 * @usage_id: usage id for a physical device.
75 * @usage_callback: Stores registered callback functions.
76 * @priv: Private data for a physical device.
77 */
78struct hid_sensor_hub_callbacks_list {
79 struct list_head list;
80 u32 usage_id;
81 struct hid_sensor_hub_callbacks *usage_callback;
82 void *priv;
83};
84
85static int sensor_hub_check_for_sensor_page(struct hid_device *hdev)
86{
87 int i;
88 int ret = -EINVAL;
89
90 for (i = 0; i < hdev->maxcollection; i++) {
91 struct hid_collection *col = &hdev->collection[i];
92 if (col->type == HID_COLLECTION_PHYSICAL &&
93 (col->usage & HID_USAGE_PAGE) == HID_UP_SENSOR) {
94 ret = 0;
95 break;
96 }
97 }
98
99 return ret;
100}
101
102static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev,
103 int dir)
104{
105 struct hid_report *report;
106
107 list_for_each_entry(report, &hdev->report_enum[dir].report_list, list) {
108 if (report->id == id)
109 return report;
110 }
111 hid_warn(hdev, "No report with id 0x%x found\n", id);
112
113 return NULL;
114}
115
116static int sensor_hub_get_physical_device_count(
117 struct hid_report_enum *report_enum)
118{
119 struct hid_report *report;
120 struct hid_field *field;
121 int cnt = 0;
122
123 list_for_each_entry(report, &report_enum->report_list, list) {
124 field = report->field[0];
125 if (report->maxfield && field &&
126 field->physical)
127 cnt++;
128 }
129
130 return cnt;
131}
132
133static void sensor_hub_fill_attr_info(
134 struct hid_sensor_hub_attribute_info *info,
135 s32 index, s32 report_id, s32 units, s32 unit_expo, s32 size)
136{
137 info->index = index;
138 info->report_id = report_id;
139 info->units = units;
140 info->unit_expo = unit_expo;
141 info->size = size/8;
142}
143
144static struct hid_sensor_hub_callbacks *sensor_hub_get_callback(
145 struct hid_device *hdev,
146 u32 usage_id, void **priv)
147{
148 struct hid_sensor_hub_callbacks_list *callback;
149 struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
150
151 spin_lock(&pdata->dyn_callback_lock);
152 list_for_each_entry(callback, &pdata->dyn_callback_list, list)
153 if (callback->usage_id == usage_id) {
154 *priv = callback->priv;
155 spin_unlock(&pdata->dyn_callback_lock);
156 return callback->usage_callback;
157 }
158 spin_unlock(&pdata->dyn_callback_lock);
159
160 return NULL;
161}
162
163int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
164 u32 usage_id,
165 struct hid_sensor_hub_callbacks *usage_callback)
166{
167 struct hid_sensor_hub_callbacks_list *callback;
168 struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
169
170 spin_lock(&pdata->dyn_callback_lock);
171 list_for_each_entry(callback, &pdata->dyn_callback_list, list)
172 if (callback->usage_id == usage_id) {
173 spin_unlock(&pdata->dyn_callback_lock);
174 return -EINVAL;
175 }
176 callback = kzalloc(sizeof(*callback), GFP_ATOMIC);
177 if (!callback) {
178 spin_unlock(&pdata->dyn_callback_lock);
179 return -ENOMEM;
180 }
181 callback->usage_callback = usage_callback;
182 callback->usage_id = usage_id;
183 callback->priv = NULL;
184 list_add_tail(&callback->list, &pdata->dyn_callback_list);
185 spin_unlock(&pdata->dyn_callback_lock);
186
187 return 0;
188}
189EXPORT_SYMBOL_GPL(sensor_hub_register_callback);
190
191int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
192 u32 usage_id)
193{
194 struct hid_sensor_hub_callbacks_list *callback;
195 struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
196
197 spin_lock(&pdata->dyn_callback_lock);
198 list_for_each_entry(callback, &pdata->dyn_callback_list, list)
199 if (callback->usage_id == usage_id) {
200 list_del(&callback->list);
201 kfree(callback);
202 break;
203 }
204 spin_unlock(&pdata->dyn_callback_lock);
205
206 return 0;
207}
208EXPORT_SYMBOL_GPL(sensor_hub_remove_callback);
209
210int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
211 u32 field_index, s32 value)
212{
213 struct hid_report *report;
214 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
215 int ret = 0;
216
217 mutex_lock(&data->mutex);
218 report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
219 if (!report || (field_index >= report->maxfield)) {
220 ret = -EINVAL;
221 goto done_proc;
222 }
223 hid_set_field(report->field[field_index], 0, value);
224 usbhid_submit_report(hsdev->hdev, report, USB_DIR_OUT);
225 usbhid_wait_io(hsdev->hdev);
226
227done_proc:
228 mutex_unlock(&data->mutex);
229
230 return ret;
231}
232EXPORT_SYMBOL_GPL(sensor_hub_set_feature);
233
234int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
235 u32 field_index, s32 *value)
236{
237 struct hid_report *report;
238 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
239 int ret = 0;
240
241 mutex_lock(&data->mutex);
242 report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
243 if (!report || (field_index >= report->maxfield)) {
244 ret = -EINVAL;
245 goto done_proc;
246 }
247 usbhid_submit_report(hsdev->hdev, report, USB_DIR_IN);
248 usbhid_wait_io(hsdev->hdev);
249 *value = report->field[field_index]->value[0];
250
251done_proc:
252 mutex_unlock(&data->mutex);
253
254 return ret;
255}
256EXPORT_SYMBOL_GPL(sensor_hub_get_feature);
257
258
259int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
260 u32 usage_id,
261 u32 attr_usage_id, u32 report_id)
262{
263 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
264 unsigned long flags;
265 struct hid_report *report;
266 int ret_val = 0;
267
268 mutex_lock(&data->mutex);
269 memset(&data->pending, 0, sizeof(data->pending));
270 init_completion(&data->pending.ready);
271 data->pending.usage_id = usage_id;
272 data->pending.attr_usage_id = attr_usage_id;
273 data->pending.raw_size = 0;
274
275 spin_lock_irqsave(&data->lock, flags);
276 data->pending.status = true;
277 report = sensor_hub_report(report_id, hsdev->hdev, HID_INPUT_REPORT);
278 if (!report) {
279 spin_unlock_irqrestore(&data->lock, flags);
280 goto err_free;
281 }
282 usbhid_submit_report(hsdev->hdev, report, USB_DIR_IN);
283 spin_unlock_irqrestore(&data->lock, flags);
284 wait_for_completion_interruptible_timeout(&data->pending.ready, HZ*5);
285 switch (data->pending.raw_size) {
286 case 1:
287 ret_val = *(u8 *)data->pending.raw_data;
288 break;
289 case 2:
290 ret_val = *(u16 *)data->pending.raw_data;
291 break;
292 case 4:
293 ret_val = *(u32 *)data->pending.raw_data;
294 break;
295 default:
296 ret_val = 0;
297 }
298 kfree(data->pending.raw_data);
299
300err_free:
301 data->pending.status = false;
302 mutex_unlock(&data->mutex);
303
304 return ret_val;
305}
306EXPORT_SYMBOL_GPL(sensor_hub_input_attr_get_raw_value);
307
308int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
309 u8 type,
310 u32 usage_id,
311 u32 attr_usage_id,
312 struct hid_sensor_hub_attribute_info *info)
313{
314 int ret = -1;
315 int i, j;
316 int collection_index = -1;
317 struct hid_report *report;
318 struct hid_field *field;
319 struct hid_report_enum *report_enum;
320 struct hid_device *hdev = hsdev->hdev;
321
322 /* Initialize with defaults */
323 info->usage_id = usage_id;
324 info->attrib_id = attr_usage_id;
325 info->report_id = -1;
326 info->index = -1;
327 info->units = -1;
328 info->unit_expo = -1;
329
330 for (i = 0; i < hdev->maxcollection; ++i) {
331 struct hid_collection *collection = &hdev->collection[i];
332 if (usage_id == collection->usage) {
333 collection_index = i;
334 break;
335 }
336 }
337 if (collection_index == -1)
338 goto err_ret;
339
340 report_enum = &hdev->report_enum[type];
341 list_for_each_entry(report, &report_enum->report_list, list) {
342 for (i = 0; i < report->maxfield; ++i) {
343 field = report->field[i];
344 if (field->physical == usage_id &&
345 field->logical == attr_usage_id) {
346 sensor_hub_fill_attr_info(info, i, report->id,
347 field->unit, field->unit_exponent,
348 field->report_size);
349 ret = 0;
350 } else {
351 for (j = 0; j < field->maxusage; ++j) {
352 if (field->usage[j].hid ==
353 attr_usage_id &&
354 field->usage[j].collection_index ==
355 collection_index) {
356 sensor_hub_fill_attr_info(info,
357 i, report->id,
358 field->unit,
359 field->unit_exponent,
360 field->report_size);
361 ret = 0;
362 break;
363 }
364 }
365 }
366 if (ret == 0)
367 break;
368 }
369 }
370
371err_ret:
372 return ret;
373}
374EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info);
375
376#ifdef CONFIG_PM
377static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message)
378{
379 struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
380 struct hid_sensor_hub_callbacks_list *callback;
381
382 hid_dbg(hdev, " sensor_hub_suspend\n");
383 spin_lock(&pdata->dyn_callback_lock);
384 list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
385 if (callback->usage_callback->suspend)
386 callback->usage_callback->suspend(
387 pdata->hsdev, callback->priv);
388 }
389 spin_unlock(&pdata->dyn_callback_lock);
390
391 return 0;
392}
393
394static int sensor_hub_resume(struct hid_device *hdev)
395{
396 struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
397 struct hid_sensor_hub_callbacks_list *callback;
398
399 hid_dbg(hdev, " sensor_hub_resume\n");
400 spin_lock(&pdata->dyn_callback_lock);
401 list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
402 if (callback->usage_callback->resume)
403 callback->usage_callback->resume(
404 pdata->hsdev, callback->priv);
405 }
406 spin_unlock(&pdata->dyn_callback_lock);
407
408 return 0;
409}
410
411static int sensor_hub_reset_resume(struct hid_device *hdev)
412{
413 return 0;
414}
415#endif
416/*
417 * Handle raw report as sent by device
418 */
419static int sensor_hub_raw_event(struct hid_device *hdev,
420 struct hid_report *report, u8 *raw_data, int size)
421{
422 int i;
423 u8 *ptr;
424 int sz;
425 struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
426 unsigned long flags;
427 struct hid_sensor_hub_callbacks *callback = NULL;
428 struct hid_collection *collection = NULL;
429 void *priv = NULL;
430
431 hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n",
432 report->id, size, report->type);
433 hid_dbg(hdev, "maxfield:%d\n", report->maxfield);
434 if (report->type != HID_INPUT_REPORT)
435 return 1;
436
437 ptr = raw_data;
438 ptr++; /*Skip report id*/
439
440 if (!report)
441 goto err_report;
442
443 spin_lock_irqsave(&pdata->lock, flags);
444
445 for (i = 0; i < report->maxfield; ++i) {
446
447 hid_dbg(hdev, "%d collection_index:%x hid:%x sz:%x\n",
448 i, report->field[i]->usage->collection_index,
449 report->field[i]->usage->hid,
450 report->field[i]->report_size/8);
451
452 sz = report->field[i]->report_size/8;
453 if (pdata->pending.status && pdata->pending.attr_usage_id ==
454 report->field[i]->usage->hid) {
455 hid_dbg(hdev, "data was pending ...\n");
456 pdata->pending.raw_data = kmalloc(sz, GFP_ATOMIC);
457 if (pdata->pending.raw_data) {
458 memcpy(pdata->pending.raw_data, ptr, sz);
459 pdata->pending.raw_size = sz;
460 } else
461 pdata->pending.raw_size = 0;
462 complete(&pdata->pending.ready);
463 }
464 collection = &hdev->collection[
465 report->field[i]->usage->collection_index];
466 hid_dbg(hdev, "collection->usage %x\n",
467 collection->usage);
468 callback = sensor_hub_get_callback(pdata->hsdev->hdev,
469 report->field[i]->physical,
470 &priv);
471 if (callback && callback->capture_sample) {
472 if (report->field[i]->logical)
473 callback->capture_sample(pdata->hsdev,
474 report->field[i]->logical, sz, ptr,
475 callback->pdev);
476 else
477 callback->capture_sample(pdata->hsdev,
478 report->field[i]->usage->hid, sz, ptr,
479 callback->pdev);
480 }
481 ptr += sz;
482 }
483 if (callback && collection && callback->send_event)
484 callback->send_event(pdata->hsdev, collection->usage,
485 callback->pdev);
486 spin_unlock_irqrestore(&pdata->lock, flags);
487
488err_report:
489 return 1;
490}
491
492static int sensor_hub_probe(struct hid_device *hdev,
493 const struct hid_device_id *id)
494{
495 int ret;
496 struct sensor_hub_data *sd;
497 int i;
498 char *name;
499 struct hid_report *report;
500 struct hid_report_enum *report_enum;
501 struct hid_field *field;
502 int dev_cnt;
503
504 sd = kzalloc(sizeof(struct sensor_hub_data), GFP_KERNEL);
505 if (!sd) {
506 hid_err(hdev, "cannot allocate Sensor data\n");
507 return -ENOMEM;
508 }
509 sd->hsdev = kzalloc(sizeof(struct hid_sensor_hub_device), GFP_KERNEL);
510 if (!sd->hsdev) {
511 hid_err(hdev, "cannot allocate hid_sensor_hub_device\n");
512 ret = -ENOMEM;
513 goto err_free_hub;
514 }
515 hid_set_drvdata(hdev, sd);
516 sd->hsdev->hdev = hdev;
517 sd->hsdev->vendor_id = hdev->vendor;
518 sd->hsdev->product_id = hdev->product;
519 spin_lock_init(&sd->lock);
520 spin_lock_init(&sd->dyn_callback_lock);
521 mutex_init(&sd->mutex);
522 ret = hid_parse(hdev);
523 if (ret) {
524 hid_err(hdev, "parse failed\n");
525 goto err_free;
526 }
527 if (sensor_hub_check_for_sensor_page(hdev) < 0) {
528 hid_err(hdev, "sensor page not found\n");
529 goto err_free;
530 }
531 INIT_LIST_HEAD(&hdev->inputs);
532
533 ret = hid_hw_start(hdev, 0);
534 if (ret) {
535 hid_err(hdev, "hw start failed\n");
536 goto err_free;
537 }
538 ret = hid_hw_open(hdev);
539 if (ret) {
540 hid_err(hdev, "failed to open input interrupt pipe\n");
541 goto err_stop_hw;
542 }
543
544 INIT_LIST_HEAD(&sd->dyn_callback_list);
545 sd->hid_sensor_client_cnt = 0;
546 report_enum = &hdev->report_enum[HID_INPUT_REPORT];
547
548 dev_cnt = sensor_hub_get_physical_device_count(report_enum);
549 if (dev_cnt > HID_MAX_PHY_DEVICES) {
550 hid_err(hdev, "Invalid Physical device count\n");
551 ret = -EINVAL;
552 goto err_close;
553 }
554 sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt *
555 sizeof(struct mfd_cell),
556 GFP_KERNEL);
557 if (sd->hid_sensor_hub_client_devs == NULL) {
558 hid_err(hdev, "Failed to allocate memory for mfd cells\n");
559 ret = -ENOMEM;
560 goto err_close;
561 }
562 list_for_each_entry(report, &report_enum->report_list, list) {
563 hid_dbg(hdev, "Report id:%x\n", report->id);
564 field = report->field[0];
565 if (report->maxfield && field &&
566 field->physical) {
567 name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x",
568 field->physical);
569 if (name == NULL) {
570 hid_err(hdev, "Failed MFD device name\n");
571 ret = -ENOMEM;
572 goto err_free_names;
573 }
574 sd->hid_sensor_hub_client_devs[
575 sd->hid_sensor_client_cnt].name = name;
576 sd->hid_sensor_hub_client_devs[
577 sd->hid_sensor_client_cnt].platform_data =
578 sd->hsdev;
579 sd->hid_sensor_hub_client_devs[
580 sd->hid_sensor_client_cnt].pdata_size =
581 sizeof(*sd->hsdev);
582 hid_dbg(hdev, "Adding %s:%p\n", name, sd);
583 sd->hid_sensor_client_cnt++;
584 }
585 }
586 ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs,
587 sd->hid_sensor_client_cnt, NULL, 0, NULL);
588 if (ret < 0)
589 goto err_free_names;
590
591 return ret;
592
593err_free_names:
594 for (i = 0; i < sd->hid_sensor_client_cnt ; ++i)
595 kfree(sd->hid_sensor_hub_client_devs[i].name);
596 kfree(sd->hid_sensor_hub_client_devs);
597err_close:
598 hid_hw_close(hdev);
599err_stop_hw:
600 hid_hw_stop(hdev);
601err_free:
602 kfree(sd->hsdev);
603err_free_hub:
604 kfree(sd);
605
606 return ret;
607}
608
609static void sensor_hub_remove(struct hid_device *hdev)
610{
611 struct sensor_hub_data *data = hid_get_drvdata(hdev);
612 unsigned long flags;
613 int i;
614
615 hid_dbg(hdev, " hardware removed\n");
616 hid_hw_close(hdev);
617 hid_hw_stop(hdev);
618 spin_lock_irqsave(&data->lock, flags);
619 if (data->pending.status)
620 complete(&data->pending.ready);
621 spin_unlock_irqrestore(&data->lock, flags);
622 mfd_remove_devices(&hdev->dev);
623 for (i = 0; i < data->hid_sensor_client_cnt ; ++i)
624 kfree(data->hid_sensor_hub_client_devs[i].name);
625 kfree(data->hid_sensor_hub_client_devs);
626 hid_set_drvdata(hdev, NULL);
627 mutex_destroy(&data->mutex);
628 kfree(data->hsdev);
629 kfree(data);
630}
631
632static const struct hid_device_id sensor_hub_devices[] = {
633 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086,
634 USB_DEVICE_ID_SENSOR_HUB_1020) },
635 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087,
636 USB_DEVICE_ID_SENSOR_HUB_1020) },
637 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086,
638 USB_DEVICE_ID_SENSOR_HUB_09FA) },
639 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087,
640 USB_DEVICE_ID_SENSOR_HUB_09FA) },
641 { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,
642 USB_DEVICE_ID_SENSOR_HUB_7014) },
643 { }
644};
645MODULE_DEVICE_TABLE(hid, sensor_hub_devices);
646
647static const struct hid_usage_id sensor_hub_grabbed_usages[] = {
648 { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
649 { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 }
650};
651
652static struct hid_driver sensor_hub_driver = {
653 .name = "hid-sensor-hub",
654 .id_table = sensor_hub_devices,
655 .probe = sensor_hub_probe,
656 .remove = sensor_hub_remove,
657 .raw_event = sensor_hub_raw_event,
658#ifdef CONFIG_PM
659 .suspend = sensor_hub_suspend,
660 .resume = sensor_hub_resume,
661 .reset_resume = sensor_hub_reset_resume,
662#endif
663};
664
665static int __init sensor_hub_init(void)
666{
667 return hid_register_driver(&sensor_hub_driver);
668}
669
670static void __exit sensor_hub_exit(void)
671{
672 hid_unregister_driver(&sensor_hub_driver);
673}
674
675module_init(sensor_hub_init);
676module_exit(sensor_hub_exit);
677
678MODULE_DESCRIPTION("HID Sensor Hub driver");
679MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
680MODULE_LICENSE("GPL");
drivers/iio/Kconfig+6−1
@@ -1,5 +1,5 @@
1#1#
2# Industrial I/O subsytem configuration2# Industrial I/O subsystem configuration
3#3#
4 4
5menuconfig IIO5menuconfig IIO
@@ -54,10 +54,15 @@ config IIO_CONSUMERS_PER_TRIGGER · 48 unmodified lines
54 This value controls the maximum number of consumers that a54 This value controls the maximum number of consumers that a
55 given trigger may handle. Default is 2.55 given trigger may handle. Default is 2.
56 56
57source "drivers/iio/accel/Kconfig"
57source "drivers/iio/adc/Kconfig"58source "drivers/iio/adc/Kconfig"
58source "drivers/iio/amplifiers/Kconfig"59source "drivers/iio/amplifiers/Kconfig"
59source "drivers/iio/light/Kconfig"60source "drivers/iio/light/Kconfig"
60source "drivers/iio/frequency/Kconfig"61source "drivers/iio/frequency/Kconfig"
61source "drivers/iio/dac/Kconfig"62source "drivers/iio/dac/Kconfig"
63source "drivers/iio/common/Kconfig"
64source "drivers/iio/gyro/Kconfig"
65source "drivers/iio/light/Kconfig"
66source "drivers/iio/magnetometer/Kconfig"
62 67
63endif # IIO68endif # IIO
drivers/iio/Makefile+5−0
@@ -10,8 +10,13 @@ industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o · 9 unmodified lines
10obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o10obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o
11obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o11obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o
12 12
13obj-y += accel/
13obj-y += adc/14obj-y += adc/
14obj-y += amplifiers/15obj-y += amplifiers/
15obj-y += light/16obj-y += light/
16obj-y += frequency/17obj-y += frequency/
17obj-y += dac/18obj-y += dac/
19obj-y += common/
20obj-y += gyro/
21obj-y += light/
22obj-y += magnetometer/
drivers/iio/accel/Kconfig+16−0
@@ -0,0 +1,16 @@
1#
2# Accelerometer drivers
3#
4menu "Accelerometers"
5
6config HID_SENSOR_ACCEL_3D
7 depends on HID_SENSOR_HUB
8 select IIO_BUFFER
9 select IIO_TRIGGERED_BUFFER
10 select HID_SENSOR_IIO_COMMON
11 tristate "HID Acelerometers 3D"
12 help
13 Say yes here to build support for the HID SENSOR
14 accelerometers 3D.
15
16endmenu
drivers/iio/accel/Makefile+5−0
@@ -0,0 +1,5 @@
1#
2# Makefile for industrial I/O accelerometer drivers
3#
4
5obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
drivers/iio/accel/hid-sensor-accel-3d.c+418−0
@@ -0,0 +1,418 @@
1/*
2 * HID Sensors Driver
3 * Copyright (c) 2012, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 */
19#include <linux/device.h>
20#include <linux/platform_device.h>
21#include <linux/module.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/slab.h>
25#include <linux/hid-sensor-hub.h>
26#include <linux/iio/iio.h>
27#include <linux/iio/sysfs.h>
28#include <linux/iio/buffer.h>
29#include <linux/iio/trigger_consumer.h>
30#include <linux/iio/triggered_buffer.h>
31#include "../common/hid-sensors/hid-sensor-attributes.h"
32#include "../common/hid-sensors/hid-sensor-trigger.h"
33
34/*Format: HID-SENSOR-usage_id_in_hex*/
35/*Usage ID from spec for Accelerometer-3D: 0x200073*/
36#define DRIVER_NAME "HID-SENSOR-200073"
37
38enum accel_3d_channel {
39 CHANNEL_SCAN_INDEX_X,
40 CHANNEL_SCAN_INDEX_Y,
41 CHANNEL_SCAN_INDEX_Z,
42 ACCEL_3D_CHANNEL_MAX,
43};
44
45struct accel_3d_state {
46 struct hid_sensor_hub_callbacks callbacks;
47 struct hid_sensor_iio_common common_attributes;
48 struct hid_sensor_hub_attribute_info accel[ACCEL_3D_CHANNEL_MAX];
49 u32 accel_val[ACCEL_3D_CHANNEL_MAX];
50};
51
52static const u32 accel_3d_addresses[ACCEL_3D_CHANNEL_MAX] = {
53 HID_USAGE_SENSOR_ACCEL_X_AXIS,
54 HID_USAGE_SENSOR_ACCEL_Y_AXIS,
55 HID_USAGE_SENSOR_ACCEL_Z_AXIS
56};
57
58/* Channel definitions */
59static const struct iio_chan_spec accel_3d_channels[] = {
60 {
61 .type = IIO_ACCEL,
62 .modified = 1,
63 .channel2 = IIO_MOD_X,
64 .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
65 IIO_CHAN_INFO_SCALE_SHARED_BIT |
66 IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
67 IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
68 .scan_index = CHANNEL_SCAN_INDEX_X,
69 }, {
70 .type = IIO_ACCEL,
71 .modified = 1,
72 .channel2 = IIO_MOD_Y,
73 .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
74 IIO_CHAN_INFO_SCALE_SHARED_BIT |
75 IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
76 IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
77 .scan_index = CHANNEL_SCAN_INDEX_Y,
78 }, {
79 .type = IIO_ACCEL,
80 .modified = 1,
81 .channel2 = IIO_MOD_Z,
82 .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
83 IIO_CHAN_INFO_SCALE_SHARED_BIT |
84 IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
85 IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
86 .scan_index = CHANNEL_SCAN_INDEX_Z,
87 }
88};
89
90/* Adjust channel real bits based on report descriptor */
91static void accel_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels,
92 int channel, int size)
93{
94 channels[channel].scan_type.sign = 's';
95 /* Real storage bits will change based on the report desc. */
96 channels[channel].scan_type.realbits = size * 8;
97 /* Maximum size of a sample to capture is u32 */
98 channels[channel].scan_type.storagebits = sizeof(u32) * 8;
99}
100
101/* Channel read_raw handler */
102static int accel_3d_read_raw(struct iio_dev *indio_dev,
103 struct iio_chan_spec const *chan,
104 int *val, int *val2,
105 long mask)
106{
107 struct accel_3d_state *accel_state = iio_priv(indio_dev);
108 int report_id = -1;
109 u32 address;
110 int ret;
111 int ret_type;
112
113 *val = 0;
114 *val2 = 0;
115 switch (mask) {
116 case 0:
117 report_id = accel_state->accel[chan->scan_index].report_id;
118 address = accel_3d_addresses[chan->scan_index];
119 if (report_id >= 0)
120 *val = sensor_hub_input_attr_get_raw_value(
121 accel_state->common_attributes.hsdev,
122 HID_USAGE_SENSOR_ACCEL_3D, address,
123 report_id);
124 else {
125 *val = 0;
126 return -EINVAL;
127 }
128 ret_type = IIO_VAL_INT;
129 break;
130 case IIO_CHAN_INFO_SCALE:
131 *val = accel_state->accel[CHANNEL_SCAN_INDEX_X].units;
132 ret_type = IIO_VAL_INT;
133 break;
134 case IIO_CHAN_INFO_OFFSET:
135 *val = hid_sensor_convert_exponent(
136 accel_state->accel[CHANNEL_SCAN_INDEX_X].unit_expo);
137 ret_type = IIO_VAL_INT;
138 break;
139 case IIO_CHAN_INFO_SAMP_FREQ:
140 ret = hid_sensor_read_samp_freq_value(
141 &accel_state->common_attributes, val, val2);
142 ret_type = IIO_VAL_INT_PLUS_MICRO;
143 break;
144 case IIO_CHAN_INFO_HYSTERESIS:
145 ret = hid_sensor_read_raw_hyst_value(
146 &accel_state->common_attributes, val, val2);
147 ret_type = IIO_VAL_INT_PLUS_MICRO;
148 break;
149 default:
150 ret_type = -EINVAL;
151 break;
152 }
153
154 return ret_type;
155}
156
157/* Channel write_raw handler */
158static int accel_3d_write_raw(struct iio_dev *indio_dev,
159 struct iio_chan_spec const *chan,
160 int val,
161 int val2,
162 long mask)
163{
164 struct accel_3d_state *accel_state = iio_priv(indio_dev);
165 int ret = 0;
166
167 switch (mask) {
168 case IIO_CHAN_INFO_SAMP_FREQ:
169 ret = hid_sensor_write_samp_freq_value(
170 &accel_state->common_attributes, val, val2);
171 break;
172 case IIO_CHAN_INFO_HYSTERESIS:
173 ret = hid_sensor_write_raw_hyst_value(
174 &accel_state->common_attributes, val, val2);
175 break;
176 default:
177 ret = -EINVAL;
178 }
179
180 return ret;
181}
182
183static int accel_3d_write_raw_get_fmt(struct iio_dev *indio_dev,
184 struct iio_chan_spec const *chan,
185 long mask)
186{
187 return IIO_VAL_INT_PLUS_MICRO;
188}
189
190static const struct iio_info accel_3d_info = {
191 .driver_module = THIS_MODULE,
192 .read_raw = &accel_3d_read_raw,
193 .write_raw = &accel_3d_write_raw,
194 .write_raw_get_fmt = &accel_3d_write_raw_get_fmt,
195};
196
197/* Function to push data to buffer */
198static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
199{
200 struct iio_buffer *buffer = indio_dev->buffer;
201 int datum_sz;
202
203 dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
204 if (!buffer) {
205 dev_err(&indio_dev->dev, "Buffer == NULL\n");
206 return;
207 }
208 datum_sz = buffer->access->get_bytes_per_datum(buffer);
209 if (len > datum_sz) {
210 dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
211 datum_sz);
212 return;
213 }
214 iio_push_to_buffer(buffer, (u8 *)data);
215}
216
217/* Callback handler to send event after all samples are received and captured */
218static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev,
219 unsigned usage_id,
220 void *priv)
221{
222 struct iio_dev *indio_dev = platform_get_drvdata(priv);
223 struct accel_3d_state *accel_state = iio_priv(indio_dev);
224
225 dev_dbg(&indio_dev->dev, "accel_3d_proc_event [%d]\n",
226 accel_state->common_attributes.data_ready);
227 if (accel_state->common_attributes.data_ready)
228 hid_sensor_push_data(indio_dev,
229 (u8 *)accel_state->accel_val,
230 sizeof(accel_state->accel_val));
231
232 return 0;
233}
234
235/* Capture samples in local storage */
236static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
237 unsigned usage_id,
238 size_t raw_len, char *raw_data,
239 void *priv)
240{
241 struct iio_dev *indio_dev = platform_get_drvdata(priv);
242 struct accel_3d_state *accel_state = iio_priv(indio_dev);
243 int offset;
244 int ret = -EINVAL;
245
246 switch (usage_id) {
247 case HID_USAGE_SENSOR_ACCEL_X_AXIS:
248 case HID_USAGE_SENSOR_ACCEL_Y_AXIS:
249 case HID_USAGE_SENSOR_ACCEL_Z_AXIS:
250 offset = usage_id - HID_USAGE_SENSOR_ACCEL_X_AXIS;
251 accel_state->accel_val[CHANNEL_SCAN_INDEX_X + offset] =
252 *(u32 *)raw_data;
253 ret = 0;
254 break;
255 default:
256 break;
257 }
258
259 return ret;
260}
261
262/* Parse report which is specific to an usage id*/
263static int accel_3d_parse_report(struct platform_device *pdev,
264 struct hid_sensor_hub_device *hsdev,
265 struct iio_chan_spec *channels,
266 unsigned usage_id,
267 struct accel_3d_state *st)
268{
269 int ret;
270 int i;
271
272 for (i = 0; i <= CHANNEL_SCAN_INDEX_Z; ++i) {
273 ret = sensor_hub_input_get_attribute_info(hsdev,
274 HID_INPUT_REPORT,
275 usage_id,
276 HID_USAGE_SENSOR_ACCEL_X_AXIS + i,
277 &st->accel[CHANNEL_SCAN_INDEX_X + i]);
278 if (ret < 0)
279 break;
280 accel_3d_adjust_channel_bit_mask(channels,
281 CHANNEL_SCAN_INDEX_X + i,
282 st->accel[CHANNEL_SCAN_INDEX_X + i].size);
283 }
284 dev_dbg(&pdev->dev, "accel_3d %x:%x, %x:%x, %x:%x\n",
285 st->accel[0].index,
286 st->accel[0].report_id,
287 st->accel[1].index, st->accel[1].report_id,
288 st->accel[2].index, st->accel[2].report_id);
289
290 return ret;
291}
292
293/* Function to initialize the processing for usage id */
294static int __devinit hid_accel_3d_probe(struct platform_device *pdev)
295{
296 int ret = 0;
297 static const char *name = "accel_3d";
298 struct iio_dev *indio_dev;
299 struct accel_3d_state *accel_state;
300 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
301 struct iio_chan_spec *channels;
302
303 indio_dev = iio_device_alloc(sizeof(struct accel_3d_state));
304 if (indio_dev == NULL) {
305 ret = -ENOMEM;
306 goto error_ret;
307 }
308 platform_set_drvdata(pdev, indio_dev);
309
310 accel_state = iio_priv(indio_dev);
311 accel_state->common_attributes.hsdev = hsdev;
312 accel_state->common_attributes.pdev = pdev;
313
314 ret = hid_sensor_parse_common_attributes(hsdev,
315 HID_USAGE_SENSOR_ACCEL_3D,
316 &accel_state->common_attributes);
317 if (ret) {
318 dev_err(&pdev->dev, "failed to setup common attributes\n");
319 goto error_free_dev;
320 }
321
322 channels = kmemdup(accel_3d_channels,
323 sizeof(accel_3d_channels),
324 GFP_KERNEL);
325 if (!channels) {
326 dev_err(&pdev->dev, "failed to duplicate channels\n");
327 goto error_free_dev;
328 }
329
330 ret = accel_3d_parse_report(pdev, hsdev, channels,
331 HID_USAGE_SENSOR_ACCEL_3D, accel_state);
332 if (ret) {
333 dev_err(&pdev->dev, "failed to setup attributes\n");
334 goto error_free_dev_mem;
335 }
336
337 indio_dev->channels = channels;
338 indio_dev->num_channels = ARRAY_SIZE(accel_3d_channels);
339 indio_dev->dev.parent = &pdev->dev;
340 indio_dev->info = &accel_3d_info;
341 indio_dev->name = name;
342 indio_dev->modes = INDIO_DIRECT_MODE;
343
344 ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
345 NULL, NULL);
346 if (ret) {
347 dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
348 goto error_free_dev_mem;
349 }
350 accel_state->common_attributes.data_ready = false;
351 ret = hid_sensor_setup_trigger(indio_dev, name,
352 &accel_state->common_attributes);
353 if (ret < 0) {
354 dev_err(&pdev->dev, "trigger setup failed\n");
355 goto error_unreg_buffer_funcs;
356 }
357
358 ret = iio_device_register(indio_dev);
359 if (ret) {
360 dev_err(&pdev->dev, "device register failed\n");
361 goto error_remove_trigger;
362 }
363
364 accel_state->callbacks.send_event = accel_3d_proc_event;
365 accel_state->callbacks.capture_sample = accel_3d_capture_sample;
366 accel_state->callbacks.pdev = pdev;
367 ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_ACCEL_3D,
368 &accel_state->callbacks);
369 if (ret < 0) {
370 dev_err(&pdev->dev, "callback reg failed\n");
371 goto error_iio_unreg;
372 }
373
374 return ret;
375
376error_iio_unreg:
377 iio_device_unregister(indio_dev);
378error_remove_trigger:
379 hid_sensor_remove_trigger(indio_dev);
380error_unreg_buffer_funcs:
381 iio_triggered_buffer_cleanup(indio_dev);
382error_free_dev_mem:
383 kfree(indio_dev->channels);
384error_free_dev:
385 iio_device_free(indio_dev);
386error_ret:
387 return ret;
388}
389
390/* Function to deinitialize the processing for usage id */
391static int __devinit hid_accel_3d_remove(struct platform_device *pdev)
392{
393 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
394 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
395
396 sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ACCEL_3D);
397 iio_device_unregister(indio_dev);
398 hid_sensor_remove_trigger(indio_dev);
399 iio_triggered_buffer_cleanup(indio_dev);
400 kfree(indio_dev->channels);
401 iio_device_free(indio_dev);
402
403 return 0;
404}
405
406static struct platform_driver hid_accel_3d_platform_driver = {
407 .driver = {
408 .name = DRIVER_NAME,
409 .owner = THIS_MODULE,
410 },
411 .probe = hid_accel_3d_probe,
412 .remove = hid_accel_3d_remove,
413};
414module_platform_driver(hid_accel_3d_platform_driver);
415
416MODULE_DESCRIPTION("HID Sensor Accel 3D");
417MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
418MODULE_LICENSE("GPL");
drivers/iio/adc/Kconfig+38−0
@@ -3,6 +3,11 @@ · 2 unmodified lines
3#3#
4menu "Analog to digital converters"4menu "Analog to digital converters"
5 5
6config AD_SIGMA_DELTA
7 tristate
8 select IIO_BUFFER
9 select IIO_TRIGGERED_BUFFER
10
6config AD726611config AD7266
7 tristate "Analog Devices AD7265/AD7266 ADC driver"12 tristate "Analog Devices AD7265/AD7266 ADC driver"
8 depends on SPI_MASTER13 depends on SPI_MASTER
@@ -13,6 +18,33 @@ config AD7266 · 4 unmodified lines
13 Say yes here to build support for Analog Devices AD7265 and AD726618 Say yes here to build support for Analog Devices AD7265 and AD7266
14 ADCs.19 ADCs.
15 20
21config AD7791
22 tristate "Analog Devices AD7791 ADC driver"
23 depends on SPI
24 select AD_SIGMA_DELTA
25 help
26 Say yes here to build support for Analog Devices AD7787, AD7788, AD7789,
27 AD7790 and AD7791 SPI analog to digital converters (ADC). If unsure, say
28 N (but it is safe to say "Y").
29
30 To compile this driver as a module, choose M here: the module will be
31 called ad7791.
32
33config AD7476
34 tristate "Analog Devices AD7476 and similar 1-channel ADCs driver"
35 depends on SPI
36 select IIO_BUFFER
37 select IIO_TRIGGERED_BUFFER
38 help
39 Say yes here to build support for Analog Devices AD7273, AD7274, AD7276,
40 AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468,
41 AD7495, AD7910, AD7920, AD7920 SPI analog to digital converters (ADC).
42
43 If unsure, say N (but it's safe to say "Y").
44
45 To compile this driver as a module, choose M here: the
46 module will be called ad7476.
47
16config AT91_ADC48config AT91_ADC
17 tristate "Atmel AT91 ADC"49 tristate "Atmel AT91 ADC"
18 depends on ARCH_AT9150 depends on ARCH_AT91
@@ -22,4 +54,10 @@ config AT91_ADC · 3 unmodified lines
22 help54 help
23 Say yes here to build support for Atmel AT91 ADC.55 Say yes here to build support for Atmel AT91 ADC.
24 56
57config LP8788_ADC
58 bool "LP8788 ADC driver"
59 depends on MFD_LP8788
60 help
61 Say yes here to build support for TI LP8788 ADC.
62
25endmenu63endmenu
drivers/iio/adc/Makefile+4−0
@@ -2,5 +2,9 @@ · 1 unmodified line
2# Makefile for IIO ADC drivers2# Makefile for IIO ADC drivers
3#3#
4 4
5obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
5obj-$(CONFIG_AD7266) += ad7266.o6obj-$(CONFIG_AD7266) += ad7266.o
7obj-$(CONFIG_AD7476) += ad7476.o
8obj-$(CONFIG_AD7791) += ad7791.o
6obj-$(CONFIG_AT91_ADC) += at91_adc.o9obj-$(CONFIG_AT91_ADC) += at91_adc.o
10obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
drivers/iio/adc/ad7266.c+1−1
@@ -99,7 +99,7 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p) · 98 unmodified lines
99 if (ret == 0) {99 if (ret == 0) {
100 if (indio_dev->scan_timestamp)100 if (indio_dev->scan_timestamp)
101 ((s64 *)st->data)[1] = pf->timestamp;101 ((s64 *)st->data)[1] = pf->timestamp;
102 iio_push_to_buffer(buffer, (u8 *)st->data, pf->timestamp);102 iio_push_to_buffer(buffer, (u8 *)st->data);
103 }103 }
104 104
105 iio_trigger_notify_done(indio_dev->trig);105 iio_trigger_notify_done(indio_dev->trig);
drivers/iio/adc/ad7476.crenamed from drivers/staging/iio/adc/ad7476_core.c+149−61
@@ -18,8 +18,76 @@ · 17 unmodified lines
18#include <linux/iio/iio.h>18#include <linux/iio/iio.h>
19#include <linux/iio/sysfs.h>19#include <linux/iio/sysfs.h>
20#include <linux/iio/buffer.h>20#include <linux/iio/buffer.h>
21#include <linux/iio/trigger_consumer.h>
22#include <linux/iio/triggered_buffer.h>
21 23
22#include "ad7476.h"24#define RES_MASK(bits) ((1 << (bits)) - 1)
25
26struct ad7476_state;
27
28struct ad7476_chip_info {
29 unsigned int int_vref_uv;
30 struct iio_chan_spec channel[2];
31 void (*reset)(struct ad7476_state *);
32};
33
34struct ad7476_state {
35 struct spi_device *spi;
36 const struct ad7476_chip_info *chip_info;
37 struct regulator *reg;
38 struct spi_transfer xfer;
39 struct spi_message msg;
40 /*
41 * DMA (thus cache coherency maintenance) requires the
42 * transfer buffers to live in their own cache lines.
43 * Make the buffer large enough for one 16 bit sample and one 64 bit
44 * aligned 64 bit timestamp.
45 */
46 unsigned char data[ALIGN(2, sizeof(s64)) + sizeof(s64)]
47 ____cacheline_aligned;
48};
49
50enum ad7476_supported_device_ids {
51 ID_AD7091R,
52 ID_AD7276,
53 ID_AD7277,
54 ID_AD7278,
55 ID_AD7466,
56 ID_AD7467,
57 ID_AD7468,
58 ID_AD7495,
59 ID_AD7940,
60};
61
62static irqreturn_t ad7476_trigger_handler(int irq, void *p)
63{
64 struct iio_poll_func *pf = p;
65 struct iio_dev *indio_dev = pf->indio_dev;
66 struct ad7476_state *st = iio_priv(indio_dev);
67 s64 time_ns;
68 int b_sent;
69
70 b_sent = spi_sync(st->spi, &st->msg);
71 if (b_sent < 0)
72 goto done;
73
74 time_ns = iio_get_time_ns();
75
76 if (indio_dev->scan_timestamp)
77 ((s64 *)st->data)[1] = time_ns;
78
79 iio_push_to_buffer(indio_dev->buffer, st->data);
80done:
81 iio_trigger_notify_done(indio_dev->trig);
82
83 return IRQ_HANDLED;
84}
85
86static void ad7091_reset(struct ad7476_state *st)
87{
88 /* Any transfers with 8 scl cycles will reset the device */
89 spi_read(st->spi, st->data, 1);
90}
23 91
24static int ad7476_scan_direct(struct ad7476_state *st)92static int ad7476_scan_direct(struct ad7476_state *st)
25{93{
@@ -29,7 +97,7 @@ static int ad7476_scan_direct(struct ad7476_state *st) · 3 unmodified lines
29 if (ret)97 if (ret)
30 return ret;98 return ret;
31 99
32 return (st->data[0] << 8) | st->data[1];100 return be16_to_cpup((__be16 *)st->data);
33}101}
34 102
35static int ad7476_read_raw(struct iio_dev *indio_dev,103static int ad7476_read_raw(struct iio_dev *indio_dev,
@@ -40,7 +108,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, · 4 unmodified lines
40{108{
41 int ret;109 int ret;
42 struct ad7476_state *st = iio_priv(indio_dev);110 struct ad7476_state *st = iio_priv(indio_dev);
43 unsigned int scale_uv;111 int scale_uv;
44 112
45 switch (m) {113 switch (m) {
46 case IIO_CHAN_INFO_RAW:114 case IIO_CHAN_INFO_RAW:
@@ -57,62 +125,80 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, · 10 unmodified lines
57 RES_MASK(st->chip_info->channel[0].scan_type.realbits);125 RES_MASK(st->chip_info->channel[0].scan_type.realbits);
58 return IIO_VAL_INT;126 return IIO_VAL_INT;
59 case IIO_CHAN_INFO_SCALE:127 case IIO_CHAN_INFO_SCALE:
60 scale_uv = (st->int_vref_mv * 1000)128 if (!st->chip_info->int_vref_uv) {
61 >> st->chip_info->channel[0].scan_type.realbits;129 scale_uv = regulator_get_voltage(st->reg);
62 *val = scale_uv/1000;130 if (scale_uv < 0)
63 *val2 = (scale_uv%1000)*1000;131 return scale_uv;
132 } else {
133 scale_uv = st->chip_info->int_vref_uv;
134 }
135 scale_uv >>= chan->scan_type.realbits;
136 *val = scale_uv / 1000;
137 *val2 = (scale_uv % 1000) * 1000;
64 return IIO_VAL_INT_PLUS_MICRO;138 return IIO_VAL_INT_PLUS_MICRO;
65 }139 }
66 return -EINVAL;140 return -EINVAL;
67}141}
68 142
69#define AD7476_CHAN(bits) \143#define _AD7476_CHAN(bits, _shift, _info_mask) \
70 { \144 { \
71 .type = IIO_VOLTAGE, \145 .type = IIO_VOLTAGE, \
72 .indexed = 1, \146 .indexed = 1, \
73 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \147 .info_mask = _info_mask | \
74 IIO_CHAN_INFO_SCALE_SHARED_BIT, \148 IIO_CHAN_INFO_SCALE_SHARED_BIT, \
75 .scan_type = { \149 .scan_type = { \
76 .sign = 'u', \150 .sign = 'u', \
77 .realbits = bits, \151 .realbits = (bits), \
78 .storagebits = 16, \152 .storagebits = 16, \
79 .shift = 12 - bits, \153 .shift = (_shift), \
154 .endianness = IIO_BE, \
80 }, \155 }, \
81}156}
82 157
158#define AD7476_CHAN(bits) _AD7476_CHAN((bits), 13 - (bits), \
159 IIO_CHAN_INFO_RAW_SEPARATE_BIT)
160#define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits), \
161 IIO_CHAN_INFO_RAW_SEPARATE_BIT)
162#define AD7091R_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), 0)
163
83static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {164static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
84 [ID_AD7466] = {165 [ID_AD7091R] = {
85 .channel[0] = AD7476_CHAN(12),166 .channel[0] = AD7091R_CHAN(12),
86 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),167 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
168 .reset = ad7091_reset,
87 },169 },
88 [ID_AD7467] = {170 [ID_AD7276] = {
89 .channel[0] = AD7476_CHAN(10),171 .channel[0] = AD7940_CHAN(12),
90 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),172 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
91 },173 },
92 [ID_AD7468] = {174 [ID_AD7277] = {
93 .channel[0] = AD7476_CHAN(8),175 .channel[0] = AD7940_CHAN(10),
94 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),176 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
95 },177 },
96 [ID_AD7475] = {178 [ID_AD7278] = {
97 .channel[0] = AD7476_CHAN(12),179 .channel[0] = AD7940_CHAN(8),
98 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),180 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
99 },181 },
100 [ID_AD7476] = {182 [ID_AD7466] = {
101 .channel[0] = AD7476_CHAN(12),183 .channel[0] = AD7476_CHAN(12),
102 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),184 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
103 },185 },
104 [ID_AD7477] = {186 [ID_AD7467] = {
105 .channel[0] = AD7476_CHAN(10),187 .channel[0] = AD7476_CHAN(10),
106 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),188 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
107 },189 },
108 [ID_AD7478] = {190 [ID_AD7468] = {
109 .channel[0] = AD7476_CHAN(8),191 .channel[0] = AD7476_CHAN(8),
110 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),192 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
111 },193 },
112 [ID_AD7495] = {194 [ID_AD7495] = {
113 .channel[0] = AD7476_CHAN(12),195 .channel[0] = AD7476_CHAN(12),
114 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),196 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
115 .int_vref_mv = 2500,197 .int_vref_uv = 2500000,
198 },
199 [ID_AD7940] = {
200 .channel[0] = AD7940_CHAN(14),
201 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
116 },202 },
117};203};
118 204
@@ -123,10 +209,9 @@ static const struct iio_info ad7476_info = { · 4 unmodified lines
123 209
124static int __devinit ad7476_probe(struct spi_device *spi)210static int __devinit ad7476_probe(struct spi_device *spi)
125{211{
126 struct ad7476_platform_data *pdata = spi->dev.platform_data;
127 struct ad7476_state *st;212 struct ad7476_state *st;
128 struct iio_dev *indio_dev;213 struct iio_dev *indio_dev;
129 int ret, voltage_uv = 0;214 int ret;
130 215
131 indio_dev = iio_device_alloc(sizeof(*st));216 indio_dev = iio_device_alloc(sizeof(*st));
132 if (indio_dev == NULL) {217 if (indio_dev == NULL) {
@@ -134,25 +219,18 @@ static int __devinit ad7476_probe(struct spi_device *spi) · 1 unmodified line
134 goto error_ret;219 goto error_ret;
135 }220 }
136 st = iio_priv(indio_dev);221 st = iio_priv(indio_dev);
137 st->reg = regulator_get(&spi->dev, "vcc");
138 if (!IS_ERR(st->reg)) {
139 ret = regulator_enable(st->reg);
140 if (ret)
141 goto error_put_reg;
142
143 voltage_uv = regulator_get_voltage(st->reg);
144 }
145 st->chip_info =222 st->chip_info =
146 &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];223 &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];
147 224
148 if (st->chip_info->int_vref_mv)225 st->reg = regulator_get(&spi->dev, "vcc");
149 st->int_vref_mv = st->chip_info->int_vref_mv;226 if (IS_ERR(st->reg)) {
150 else if (pdata && pdata->vref_mv)227 ret = PTR_ERR(st->reg);
151 st->int_vref_mv = pdata->vref_mv;228 goto error_free_dev;
152 else if (voltage_uv)229 }
153 st->int_vref_mv = voltage_uv / 1000;230
154 else231 ret = regulator_enable(st->reg);
155 dev_warn(&spi->dev, "reference voltage unspecified\n");232 if (ret)
233 goto error_put_reg;
156 234
157 spi_set_drvdata(spi, indio_dev);235 spi_set_drvdata(spi, indio_dev);
158 236
@@ -173,57 +251,67 @@ static int __devinit ad7476_probe(struct spi_device *spi) · 14 unmodified lines
173 spi_message_init(&st->msg);251 spi_message_init(&st->msg);
174 spi_message_add_tail(&st->xfer, &st->msg);252 spi_message_add_tail(&st->xfer, &st->msg);
175 253
176 ret = ad7476_register_ring_funcs_and_init(indio_dev);254 ret = iio_triggered_buffer_setup(indio_dev, NULL,
255 &ad7476_trigger_handler, NULL);
177 if (ret)256 if (ret)
178 goto error_disable_reg;257 goto error_disable_reg;
179 258
259 if (st->chip_info->reset)
260 st->chip_info->reset(st);
261
180 ret = iio_device_register(indio_dev);262 ret = iio_device_register(indio_dev);
181 if (ret)263 if (ret)
182 goto error_ring_unregister;264 goto error_ring_unregister;
183 return 0;265 return 0;
184 266
185error_ring_unregister:267error_ring_unregister:
186 ad7476_ring_cleanup(indio_dev);268 iio_triggered_buffer_cleanup(indio_dev);
187error_disable_reg:269error_disable_reg:
188 if (!IS_ERR(st->reg))270 regulator_disable(st->reg);
189 regulator_disable(st->reg);
190error_put_reg:271error_put_reg:
191 if (!IS_ERR(st->reg))272 regulator_put(st->reg);
192 regulator_put(st->reg);273error_free_dev:
193 iio_device_free(indio_dev);274 iio_device_free(indio_dev);
194 275
195error_ret:276error_ret:
196 return ret;277 return ret;
197}278}
198 279
199static int ad7476_remove(struct spi_device *spi)280static int __devexit ad7476_remove(struct spi_device *spi)
200{281{
201 struct iio_dev *indio_dev = spi_get_drvdata(spi);282 struct iio_dev *indio_dev = spi_get_drvdata(spi);
202 struct ad7476_state *st = iio_priv(indio_dev);283 struct ad7476_state *st = iio_priv(indio_dev);
203 284
204 iio_device_unregister(indio_dev);285 iio_device_unregister(indio_dev);
205 ad7476_ring_cleanup(indio_dev);286 iio_triggered_buffer_cleanup(indio_dev);
206 if (!IS_ERR(st->reg)) {287 regulator_disable(st->reg);
207 regulator_disable(st->reg);288 regulator_put(st->reg);
208 regulator_put(st->reg);
209 }
210 iio_device_free(indio_dev);289 iio_device_free(indio_dev);
211 290
212 return 0;291 return 0;
213}292}
214 293
215static const struct spi_device_id ad7476_id[] = {294static const struct spi_device_id ad7476_id[] = {
295 {"ad7091r", ID_AD7091R},
296 {"ad7273", ID_AD7277},
297 {"ad7274", ID_AD7276},
298 {"ad7276", ID_AD7276},
299 {"ad7277", ID_AD7277},
300 {"ad7278", ID_AD7278},
216 {"ad7466", ID_AD7466},301 {"ad7466", ID_AD7466},
217 {"ad7467", ID_AD7467},302 {"ad7467", ID_AD7467},
218 {"ad7468", ID_AD7468},303 {"ad7468", ID_AD7468},
219 {"ad7475", ID_AD7475},304 {"ad7475", ID_AD7466},
220 {"ad7476", ID_AD7476},305 {"ad7476", ID_AD7466},
221 {"ad7476a", ID_AD7476},306 {"ad7476a", ID_AD7466},
222 {"ad7477", ID_AD7477},307 {"ad7477", ID_AD7467},
223 {"ad7477a", ID_AD7477},308 {"ad7477a", ID_AD7467},
224 {"ad7478", ID_AD7478},309 {"ad7478", ID_AD7468},
225 {"ad7478a", ID_AD7478},310 {"ad7478a", ID_AD7468},
226 {"ad7495", ID_AD7495},311 {"ad7495", ID_AD7495},
312 {"ad7910", ID_AD7467},
313 {"ad7920", ID_AD7466},
314 {"ad7940", ID_AD7940},
227 {}315 {}
228};316};
229MODULE_DEVICE_TABLE(spi, ad7476_id);317MODULE_DEVICE_TABLE(spi, ad7476_id);
@@ -240,5 +328,5 @@ static struct spi_driver ad7476_driver = { · 10 unmodified lines
240module_spi_driver(ad7476_driver);328module_spi_driver(ad7476_driver);
241 329
242MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");330MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
243MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC");331MODULE_DESCRIPTION("Analog Devices AD7476 and similar 1-channel ADCs");
244MODULE_LICENSE("GPL v2");332MODULE_LICENSE("GPL v2");
drivers/iio/adc/ad7791.c+460−0
@@ -0,0 +1,460 @@
1/*
2 * AD7787/AD7788/AD7789/AD7790/AD7791 SPI ADC driver
3 *
4 * Copyright 2012 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2.
8 */
9
10#include <linux/interrupt.h>
11#include <linux/device.h>
12#include <linux/kernel.h>
13#include <linux/slab.h>
14#include <linux/sysfs.h>
15#include <linux/spi/spi.h>
16#include <linux/regulator/consumer.h>
17#include <linux/err.h>
18#include <linux/sched.h>
19#include <linux/delay.h>
20#include <linux/module.h>
21
22#include <linux/iio/iio.h>
23#include <linux/iio/sysfs.h>
24#include <linux/iio/buffer.h>
25#include <linux/iio/trigger.h>
26#include <linux/iio/trigger_consumer.h>
27#include <linux/iio/triggered_buffer.h>
28#include <linux/iio/adc/ad_sigma_delta.h>
29
30#include <linux/platform_data/ad7791.h>
31
32#define AD7791_REG_COMM 0x0 /* For writes */
33#define AD7791_REG_STATUS 0x0 /* For reads */
34#define AD7791_REG_MODE 0x1
35#define AD7791_REG_FILTER 0x2
36#define AD7791_REG_DATA 0x3
37
38#define AD7791_MODE_CONTINUOUS 0x00
39#define AD7791_MODE_SINGLE 0x02
40#define AD7791_MODE_POWERDOWN 0x03
41
42#define AD7791_CH_AIN1P_AIN1N 0x00
43#define AD7791_CH_AIN2 0x01
44#define AD7791_CH_AIN1N_AIN1N 0x02
45#define AD7791_CH_AVDD_MONITOR 0x03
46
47#define AD7791_FILTER_CLK_DIV_1 (0x0 << 4)
48#define AD7791_FILTER_CLK_DIV_2 (0x1 << 4)
49#define AD7791_FILTER_CLK_DIV_4 (0x2 << 4)
50#define AD7791_FILTER_CLK_DIV_8 (0x3 << 4)
51#define AD7791_FILTER_CLK_MASK (0x3 << 4)
52#define AD7791_FILTER_RATE_120 0x0
53#define AD7791_FILTER_RATE_100 0x1
54#define AD7791_FILTER_RATE_33_3 0x2
55#define AD7791_FILTER_RATE_20 0x3
56#define AD7791_FILTER_RATE_16_6 0x4
57#define AD7791_FILTER_RATE_16_7 0x5
58#define AD7791_FILTER_RATE_13_3 0x6
59#define AD7791_FILTER_RATE_9_5 0x7
60#define AD7791_FILTER_RATE_MASK 0x7
61
62#define AD7791_MODE_BUFFER BIT(1)
63#define AD7791_MODE_UNIPOLAR BIT(2)
64#define AD7791_MODE_BURNOUT BIT(3)
65#define AD7791_MODE_SEL_MASK (0x3 << 6)
66#define AD7791_MODE_SEL(x) ((x) << 6)
67
68#define DECLARE_AD7787_CHANNELS(name, bits, storagebits) \
69const struct iio_chan_spec name[] = { \
70 AD_SD_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \
71 (bits), (storagebits), 0), \
72 AD_SD_CHANNEL(1, 1, AD7791_CH_AIN2, (bits), (storagebits), 0), \
73 AD_SD_SHORTED_CHANNEL(2, 0, AD7791_CH_AIN1N_AIN1N, \
74 (bits), (storagebits), 0), \
75 AD_SD_SUPPLY_CHANNEL(3, 2, AD7791_CH_AVDD_MONITOR, \
76 (bits), (storagebits), 0), \
77 IIO_CHAN_SOFT_TIMESTAMP(4), \
78}
79
80#define DECLARE_AD7791_CHANNELS(name, bits, storagebits) \
81const struct iio_chan_spec name[] = { \
82 AD_SD_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \
83 (bits), (storagebits), 0), \
84 AD_SD_SHORTED_CHANNEL(1, 0, AD7791_CH_AIN1N_AIN1N, \
85 (bits), (storagebits), 0), \
86 AD_SD_SUPPLY_CHANNEL(2, 1, AD7791_CH_AVDD_MONITOR, \
87 (bits), (storagebits), 0), \
88 IIO_CHAN_SOFT_TIMESTAMP(3), \
89}
90
91static DECLARE_AD7787_CHANNELS(ad7787_channels, 24, 32);
92static DECLARE_AD7791_CHANNELS(ad7790_channels, 16, 16);
93static DECLARE_AD7791_CHANNELS(ad7791_channels, 24, 32);
94
95enum {
96 AD7787,
97 AD7788,
98 AD7789,
99 AD7790,
100 AD7791,
101};
102
103enum ad7791_chip_info_flags {
104 AD7791_FLAG_HAS_FILTER = (1 << 0),
105 AD7791_FLAG_HAS_BUFFER = (1 << 1),
106 AD7791_FLAG_HAS_UNIPOLAR = (1 << 2),
107 AD7791_FLAG_HAS_BURNOUT = (1 << 3),
108};
109
110struct ad7791_chip_info {
111 const struct iio_chan_spec *channels;
112 unsigned int num_channels;
113 enum ad7791_chip_info_flags flags;
114};
115
116static const struct ad7791_chip_info ad7791_chip_infos[] = {
117 [AD7787] = {
118 .channels = ad7787_channels,
119 .num_channels = ARRAY_SIZE(ad7787_channels),
120 .flags = AD7791_FLAG_HAS_FILTER | AD7791_FLAG_HAS_BUFFER |
121 AD7791_FLAG_HAS_UNIPOLAR | AD7791_FLAG_HAS_BURNOUT,
122 },
123 [AD7788] = {
124 .channels = ad7790_channels,
125 .num_channels = ARRAY_SIZE(ad7790_channels),
126 .flags = AD7791_FLAG_HAS_UNIPOLAR,
127 },
128 [AD7789] = {
129 .channels = ad7791_channels,
130 .num_channels = ARRAY_SIZE(ad7791_channels),
131 .flags = AD7791_FLAG_HAS_UNIPOLAR,
132 },
133 [AD7790] = {
134 .channels = ad7790_channels,
135 .num_channels = ARRAY_SIZE(ad7790_channels),
136 .flags = AD7791_FLAG_HAS_FILTER | AD7791_FLAG_HAS_BUFFER |
137 AD7791_FLAG_HAS_BURNOUT,
138 },
139 [AD7791] = {
140 .channels = ad7791_channels,
141 .num_channels = ARRAY_SIZE(ad7791_channels),
142 .flags = AD7791_FLAG_HAS_FILTER | AD7791_FLAG_HAS_BUFFER |
143 AD7791_FLAG_HAS_UNIPOLAR | AD7791_FLAG_HAS_BURNOUT,
144 },
145};
146
147struct ad7791_state {
148 struct ad_sigma_delta sd;
149 uint8_t mode;
150 uint8_t filter;
151
152 struct regulator *reg;
153 const struct ad7791_chip_info *info;
154};
155
156static struct ad7791_state *ad_sigma_delta_to_ad7791(struct ad_sigma_delta *sd)
157{
158 return container_of(sd, struct ad7791_state, sd);
159}
160
161static int ad7791_set_channel(struct ad_sigma_delta *sd, unsigned int channel)
162{
163 ad_sd_set_comm(sd, channel);
164
165 return 0;
166}
167
168static int ad7791_set_mode(struct ad_sigma_delta *sd,
169 enum ad_sigma_delta_mode mode)
170{
171 struct ad7791_state *st = ad_sigma_delta_to_ad7791(sd);
172
173 switch (mode) {
174 case AD_SD_MODE_CONTINUOUS:
175 mode = AD7791_MODE_CONTINUOUS;
176 break;
177 case AD_SD_MODE_SINGLE:
178 mode = AD7791_MODE_SINGLE;
179 break;
180 case AD_SD_MODE_IDLE:
181 case AD_SD_MODE_POWERDOWN:
182 mode = AD7791_MODE_POWERDOWN;
183 break;
184 }
185
186 st->mode &= ~AD7791_MODE_SEL_MASK;
187 st->mode |= AD7791_MODE_SEL(mode);
188
189 return ad_sd_write_reg(sd, AD7791_REG_MODE, sizeof(st->mode), st->mode);
190}
191
192static const struct ad_sigma_delta_info ad7791_sigma_delta_info = {
193 .set_channel = ad7791_set_channel,
194 .set_mode = ad7791_set_mode,
195 .has_registers = true,
196 .addr_shift = 4,
197 .read_mask = BIT(3),
198};
199
200static int ad7791_read_raw(struct iio_dev *indio_dev,
201 const struct iio_chan_spec *chan, int *val, int *val2, long info)
202{
203 struct ad7791_state *st = iio_priv(indio_dev);
204 bool unipolar = !!(st->mode & AD7791_MODE_UNIPOLAR);
205 unsigned long long scale_pv;
206
207 switch (info) {
208 case IIO_CHAN_INFO_RAW:
209 return ad_sigma_delta_single_conversion(indio_dev, chan, val);
210 case IIO_CHAN_INFO_OFFSET:
211 /**
212 * Unipolar: 0 to VREF
213 * Bipolar -VREF to VREF
214 **/
215 if (unipolar)
216 *val = 0;
217 else
218 *val = -(1 << (chan->scan_type.realbits - 1));
219 return IIO_VAL_INT;
220 case IIO_CHAN_INFO_SCALE:
221 /* The monitor channel uses an internal reference. */
222 if (chan->address == AD7791_CH_AVDD_MONITOR) {
223 scale_pv = 5850000000000ULL;
224 } else {
225 int voltage_uv;
226
227 voltage_uv = regulator_get_voltage(st->reg);
228 if (voltage_uv < 0)
229 return voltage_uv;
230 scale_pv = (unsigned long long)voltage_uv * 1000000;
231 }
232 if (unipolar)
233 scale_pv >>= chan->scan_type.realbits;
234 else
235 scale_pv >>= chan->scan_type.realbits - 1;
236 *val2 = do_div(scale_pv, 1000000000);
237 *val = scale_pv;
238
239 return IIO_VAL_INT_PLUS_NANO;
240 }
241
242 return -EINVAL;
243}
244
245static const char * const ad7791_sample_freq_avail[] = {
246 [AD7791_FILTER_RATE_120] = "120",
247 [AD7791_FILTER_RATE_100] = "100",
248 [AD7791_FILTER_RATE_33_3] = "33.3",
249 [AD7791_FILTER_RATE_20] = "20",
250 [AD7791_FILTER_RATE_16_6] = "16.6",
251 [AD7791_FILTER_RATE_16_7] = "16.7",
252 [AD7791_FILTER_RATE_13_3] = "13.3",
253 [AD7791_FILTER_RATE_9_5] = "9.5",
254};
255
256static ssize_t ad7791_read_frequency(struct device *dev,
257 struct device_attribute *attr, char *buf)
258{
259 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
260 struct ad7791_state *st = iio_priv(indio_dev);
261 unsigned int rate = st->filter & AD7791_FILTER_RATE_MASK;
262
263 return sprintf(buf, "%s\n", ad7791_sample_freq_avail[rate]);
264}
265
266static ssize_t ad7791_write_frequency(struct device *dev,
267 struct device_attribute *attr, const char *buf, size_t len)
268{
269 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
270 struct ad7791_state *st = iio_priv(indio_dev);
271 int i, ret;
272
273 mutex_lock(&indio_dev->mlock);
274 if (iio_buffer_enabled(indio_dev)) {
275 mutex_unlock(&indio_dev->mlock);
276 return -EBUSY;
277 }
278 mutex_unlock(&indio_dev->mlock);
279
280 ret = -EINVAL;
281
282 for (i = 0; i < ARRAY_SIZE(ad7791_sample_freq_avail); i++) {
283 if (sysfs_streq(ad7791_sample_freq_avail[i], buf)) {
284
285 mutex_lock(&indio_dev->mlock);
286 st->filter &= ~AD7791_FILTER_RATE_MASK;
287 st->filter |= i;
288 ad_sd_write_reg(&st->sd, AD7791_REG_FILTER,
289 sizeof(st->filter), st->filter);
290 mutex_unlock(&indio_dev->mlock);
291 ret = 0;
292 break;
293 }
294 }
295
296 return ret ? ret : len;
297}
298
299static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
300 ad7791_read_frequency,
301 ad7791_write_frequency);
302
303static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("120 100 33.3 20 16.7 16.6 13.3 9.5");
304
305static struct attribute *ad7791_attributes[] = {
306 &iio_dev_attr_sampling_frequency.dev_attr.attr,
307 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
308 NULL
309};
310
311static const struct attribute_group ad7791_attribute_group = {
312 .attrs = ad7791_attributes,
313};
314
315static const struct iio_info ad7791_info = {
316 .read_raw = &ad7791_read_raw,
317 .attrs = &ad7791_attribute_group,
318 .validate_trigger = ad_sd_validate_trigger,
319 .driver_module = THIS_MODULE,
320};
321
322static const struct iio_info ad7791_no_filter_info = {
323 .read_raw = &ad7791_read_raw,
324 .validate_trigger = ad_sd_validate_trigger,
325 .driver_module = THIS_MODULE,
326};
327
328static int __devinit ad7791_setup(struct ad7791_state *st,
329 struct ad7791_platform_data *pdata)
330{
331 /* Set to poweron-reset default values */
332 st->mode = AD7791_MODE_BUFFER;
333 st->filter = AD7791_FILTER_RATE_16_6;
334
335 if (!pdata)
336 return 0;
337
338 if ((st->info->flags & AD7791_FLAG_HAS_BUFFER) && !pdata->buffered)
339 st->mode &= ~AD7791_MODE_BUFFER;
340
341 if ((st->info->flags & AD7791_FLAG_HAS_BURNOUT) &&
342 pdata->burnout_current)
343 st->mode |= AD7791_MODE_BURNOUT;
344
345 if ((st->info->flags & AD7791_FLAG_HAS_UNIPOLAR) && pdata->unipolar)
346 st->mode |= AD7791_MODE_UNIPOLAR;
347
348 return ad_sd_write_reg(&st->sd, AD7791_REG_MODE, sizeof(st->mode),
349 st->mode);
350}
351
352static int __devinit ad7791_probe(struct spi_device *spi)
353{
354 struct ad7791_platform_data *pdata = spi->dev.platform_data;
355 struct iio_dev *indio_dev;
356 struct ad7791_state *st;
357 int ret;
358
359 if (!spi->irq) {
360 dev_err(&spi->dev, "Missing IRQ.\n");
361 return -ENXIO;
362 }
363
364 indio_dev = iio_device_alloc(sizeof(*st));
365 if (!indio_dev)
366 return -ENOMEM;
367
368 st = iio_priv(indio_dev);
369
370 st->reg = regulator_get(&spi->dev, "refin");
371 if (IS_ERR(st->reg)) {
372 ret = PTR_ERR(st->reg);
373 goto err_iio_free;
374 }
375
376 ret = regulator_enable(st->reg);
377 if (ret)
378 goto error_put_reg;
379
380 st->info = &ad7791_chip_infos[spi_get_device_id(spi)->driver_data];
381 ad_sd_init(&st->sd, indio_dev, spi, &ad7791_sigma_delta_info);
382
383 spi_set_drvdata(spi, indio_dev);
384
385 indio_dev->dev.parent = &spi->dev;
386 indio_dev->name = spi_get_device_id(spi)->name;
387 indio_dev->modes = INDIO_DIRECT_MODE;
388 indio_dev->channels = st->info->channels;
389 indio_dev->num_channels = st->info->num_channels;
390 if (st->info->flags & AD7791_FLAG_HAS_FILTER)
391 indio_dev->info = &ad7791_info;
392 else
393 indio_dev->info = &ad7791_no_filter_info;
394
395 ret = ad_sd_setup_buffer_and_trigger(indio_dev);
396 if (ret)
397 goto error_disable_reg;
398
399 ret = ad7791_setup(st, pdata);
400 if (ret)
401 goto error_remove_trigger;
402
403 ret = iio_device_register(indio_dev);
404 if (ret)
405 goto error_remove_trigger;
406
407 return 0;
408
409error_remove_trigger:
410 ad_sd_cleanup_buffer_and_trigger(indio_dev);
411error_disable_reg:
412 regulator_disable(st->reg);
413error_put_reg:
414 regulator_put(st->reg);
415err_iio_free:
416 iio_device_free(indio_dev);
417
418 return ret;
419}
420
421static int __devexit ad7791_remove(struct spi_device *spi)
422{
423 struct iio_dev *indio_dev = spi_get_drvdata(spi);
424 struct ad7791_state *st = iio_priv(indio_dev);
425
426 iio_device_unregister(indio_dev);
427 ad_sd_cleanup_buffer_and_trigger(indio_dev);
428
429 regulator_disable(st->reg);
430 regulator_put(st->reg);
431
432 iio_device_free(indio_dev);
433
434 return 0;
435}
436
437static const struct spi_device_id ad7791_spi_ids[] = {
438 { "ad7787", AD7787 },
439 { "ad7788", AD7788 },
440 { "ad7789", AD7789 },
441 { "ad7790", AD7790 },
442 { "ad7791", AD7791 },
443 {}
444};
445MODULE_DEVICE_TABLE(spi, ad7791_spi_ids);
446
447static struct spi_driver ad7791_driver = {
448 .driver = {
449 .name = "ad7791",
450 .owner = THIS_MODULE,
451 },
452 .probe = ad7791_probe,
453 .remove = __devexit_p(ad7791_remove),
454 .id_table = ad7791_spi_ids,
455};
456module_spi_driver(ad7791_driver);
457
458MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
459MODULE_DESCRIPTION("Analog Device AD7787/AD7788/AD7789/AD7790/AD7791 ADC driver");
460MODULE_LICENSE("GPL v2");
drivers/iio/adc/ad_sigma_delta.c+558−0
@@ -0,0 +1,558 @@
1/*
2 * Support code for Analog Devices Sigma-Delta ADCs
3 *
4 * Copyright 2012 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2.
8 */
9
10#include <linux/interrupt.h>
11#include <linux/device.h>
12#include <linux/kernel.h>
13#include <linux/slab.h>
14#include <linux/spi/spi.h>
15#include <linux/err.h>
16#include <linux/module.h>
17
18#include <linux/iio/iio.h>
19#include <linux/iio/sysfs.h>
20#include <linux/iio/buffer.h>
21#include <linux/iio/trigger.h>
22#include <linux/iio/trigger_consumer.h>
23#include <linux/iio/triggered_buffer.h>
24#include <linux/iio/adc/ad_sigma_delta.h>
25
26#include <asm/unaligned.h>
27
28
29#define AD_SD_COMM_CHAN_MASK 0x3
30
31#define AD_SD_REG_COMM 0x00
32#define AD_SD_REG_DATA 0x03
33
34/**
35 * ad_sd_set_comm() - Set communications register
36 *
37 * @sigma_delta: The sigma delta device
38 * @comm: New value for the communications register
39 */
40void ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, uint8_t comm)
41{
42 /* Some variants use the lower two bits of the communications register
43 * to select the channel */
44 sigma_delta->comm = comm & AD_SD_COMM_CHAN_MASK;
45}
46EXPORT_SYMBOL_GPL(ad_sd_set_comm);
47
48/**
49 * ad_sd_write_reg() - Write a register
50 *
51 * @sigma_delta: The sigma delta device
52 * @reg: Address of the register
53 * @size: Size of the register (0-3)
54 * @val: Value to write to the register
55 *
56 * Returns 0 on success, an error code otherwise.
57 **/
58int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
59 unsigned int size, unsigned int val)
60{
61 uint8_t *data = sigma_delta->data;
62 struct spi_transfer t = {
63 .tx_buf = data,
64 .len = size + 1,
65 .cs_change = sigma_delta->bus_locked,
66 };
67 struct spi_message m;
68 int ret;
69
70 data[0] = (reg << sigma_delta->info->addr_shift) | sigma_delta->comm;
71
72 switch (size) {
73 case 3:
74 data[1] = val >> 16;
75 data[2] = val >> 8;
76 data[3] = val;
77 break;
78 case 2:
79 put_unaligned_be16(val, &data[1]);
80 break;
81 case 1:
82 data[1] = val;
83 break;
84 case 0:
85 break;
86 default:
87 return -EINVAL;
88 }
89
90 spi_message_init(&m);
91 spi_message_add_tail(&t, &m);
92
93 if (sigma_delta->bus_locked)
94 ret = spi_sync_locked(sigma_delta->spi, &m);
95 else
96 ret = spi_sync(sigma_delta->spi, &m);
97
98 return ret;
99}
100EXPORT_SYMBOL_GPL(ad_sd_write_reg);
101
102static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta,
103 unsigned int reg, unsigned int size, uint8_t *val)
104{
105 uint8_t *data = sigma_delta->data;
106 int ret;
107 struct spi_transfer t[] = {
108 {
109 .tx_buf = data,
110 .len = 1,
111 }, {
112 .rx_buf = val,
113 .len = size,
114 .cs_change = sigma_delta->bus_locked,
115 },
116 };
117 struct spi_message m;
118
119 spi_message_init(&m);
120
121 if (sigma_delta->info->has_registers) {
122 data[0] = reg << sigma_delta->info->addr_shift;
123 data[0] |= sigma_delta->info->read_mask;
124 spi_message_add_tail(&t[0], &m);
125 }
126 spi_message_add_tail(&t[1], &m);
127
128 if (sigma_delta->bus_locked)
129 ret = spi_sync_locked(sigma_delta->spi, &m);
130 else
131 ret = spi_sync(sigma_delta->spi, &m);
132
133 return ret;
134}
135
136/**
137 * ad_sd_read_reg() - Read a register
138 *
139 * @sigma_delta: The sigma delta device
140 * @reg: Address of the register
141 * @size: Size of the register (1-4)
142 * @val: Read value
143 *
144 * Returns 0 on success, an error code otherwise.
145 **/
146int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta,
147 unsigned int reg, unsigned int size, unsigned int *val)
148{
149 int ret;
150
151 ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->data);
152 if (ret < 0)
153 goto out;
154
155 switch (size) {
156 case 4:
157 *val = get_unaligned_be32(sigma_delta->data);
158 break;
159 case 3:
160 *val = (sigma_delta->data[0] << 16) |
161 (sigma_delta->data[1] << 8) |
162 sigma_delta->data[2];
163 break;
164 case 2:
165 *val = get_unaligned_be16(sigma_delta->data);
166 break;
167 case 1:
168 *val = sigma_delta->data[0];
169 break;
170 default:
171 ret = -EINVAL;
172 break;
173 }
174
175out:
176 return ret;
177}
178EXPORT_SYMBOL_GPL(ad_sd_read_reg);
179
180static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
181 unsigned int mode, unsigned int channel)
182{
183 int ret;
184
185 ret = ad_sigma_delta_set_channel(sigma_delta, channel);
186 if (ret)
187 return ret;
188
189 spi_bus_lock(sigma_delta->spi->master);
190 sigma_delta->bus_locked = true;
191 INIT_COMPLETION(sigma_delta->completion);
192
193 ret = ad_sigma_delta_set_mode(sigma_delta, mode);
194 if (ret < 0)
195 goto out;
196
197 sigma_delta->irq_dis = false;
198 enable_irq(sigma_delta->spi->irq);
199 ret = wait_for_completion_timeout(&sigma_delta->completion, 2*HZ);
200 if (ret == 0) {
201 sigma_delta->irq_dis = true;
202 disable_irq_nosync(sigma_delta->spi->irq);
203 ret = -EIO;
204 } else {
205 ret = 0;
206 }
207out:
208 sigma_delta->bus_locked = false;
209 spi_bus_unlock(sigma_delta->spi->master);
210 ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
211
212 return ret;
213}
214
215/**
216 * ad_sd_calibrate_all() - Performs channel calibration
217 * @sigma_delta: The sigma delta device
218 * @cb: Array of channels and calibration type to perform
219 * @n: Number of items in cb
220 *
221 * Returns 0 on success, an error code otherwise.
222 **/
223int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta,
224 const struct ad_sd_calib_data *cb, unsigned int n)
225{
226 unsigned int i;
227 int ret;
228
229 for (i = 0; i < n; i++) {
230 ret = ad_sd_calibrate(sigma_delta, cb[i].mode, cb[i].channel);
231 if (ret)
232 return ret;
233 }
234
235 return 0;
236}
237EXPORT_SYMBOL_GPL(ad_sd_calibrate_all);
238
239/**
240 * ad_sigma_delta_single_conversion() - Performs a single data conversion
241 * @indio_dev: The IIO device
242 * @chan: The conversion is done for this channel
243 * @val: Pointer to the location where to store the read value
244 *
245 * Returns: 0 on success, an error value otherwise.
246 */
247int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
248 const struct iio_chan_spec *chan, int *val)
249{
250 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
251 unsigned int sample, raw_sample;
252 int ret = 0;
253
254 if (iio_buffer_enabled(indio_dev))
255 return -EBUSY;
256
257 mutex_lock(&indio_dev->mlock);
258 ad_sigma_delta_set_channel(sigma_delta, chan->address);
259
260 spi_bus_lock(sigma_delta->spi->master);
261 sigma_delta->bus_locked = true;
262 INIT_COMPLETION(sigma_delta->completion);
263
264 ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_SINGLE);
265
266 sigma_delta->irq_dis = false;
267 enable_irq(sigma_delta->spi->irq);
268 ret = wait_for_completion_interruptible_timeout(
269 &sigma_delta->completion, HZ);
270
271 sigma_delta->bus_locked = false;
272 spi_bus_unlock(sigma_delta->spi->master);
273
274 if (ret == 0)
275 ret = -EIO;
276 if (ret < 0)
277 goto out;
278
279 ret = ad_sd_read_reg(sigma_delta, AD_SD_REG_DATA,
280 DIV_ROUND_UP(chan->scan_type.realbits + chan->scan_type.shift, 8),
281 &raw_sample);
282
283out:
284 if (!sigma_delta->irq_dis) {
285 disable_irq_nosync(sigma_delta->spi->irq);
286 sigma_delta->irq_dis = true;
287 }
288
289 ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
290 mutex_unlock(&indio_dev->mlock);
291
292 if (ret)
293 return ret;
294
295 sample = raw_sample >> chan->scan_type.shift;
296 sample &= (1 << chan->scan_type.realbits) - 1;
297 *val = sample;
298
299 ret = ad_sigma_delta_postprocess_sample(sigma_delta, raw_sample);
300 if (ret)
301 return ret;
302
303 return IIO_VAL_INT;
304}
305EXPORT_SYMBOL_GPL(ad_sigma_delta_single_conversion);
306
307static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
308{
309 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
310 unsigned int channel;
311 int ret;
312
313 ret = iio_triggered_buffer_postenable(indio_dev);
314 if (ret < 0)
315 return ret;
316
317 channel = find_first_bit(indio_dev->active_scan_mask,
318 indio_dev->masklength);
319 ret = ad_sigma_delta_set_channel(sigma_delta,
320 indio_dev->channels[channel].address);
321 if (ret)
322 goto err_predisable;
323
324 spi_bus_lock(sigma_delta->spi->master);
325 sigma_delta->bus_locked = true;
326 ret = ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_CONTINUOUS);
327 if (ret)
328 goto err_unlock;
329
330 sigma_delta->irq_dis = false;
331 enable_irq(sigma_delta->spi->irq);
332
333 return 0;
334
335err_unlock:
336 spi_bus_unlock(sigma_delta->spi->master);
337err_predisable:
338
339 return ret;
340}
341
342static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev)
343{
344 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
345
346 INIT_COMPLETION(sigma_delta->completion);
347 wait_for_completion_timeout(&sigma_delta->completion, HZ);
348
349 if (!sigma_delta->irq_dis) {
350 disable_irq_nosync(sigma_delta->spi->irq);
351 sigma_delta->irq_dis = true;
352 }
353
354 ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
355
356 sigma_delta->bus_locked = false;
357 return spi_bus_unlock(sigma_delta->spi->master);
358}
359
360static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
361{
362 struct iio_poll_func *pf = p;
363 struct iio_dev *indio_dev = pf->indio_dev;
364 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
365 unsigned int reg_size;
366 uint8_t data[16];
367 int ret;
368
369 memset(data, 0x00, 16);
370
371 /* Guaranteed to be aligned with 8 byte boundary */
372 if (indio_dev->scan_timestamp)
373 ((s64 *)data)[1] = pf->timestamp;
374
375 reg_size = indio_dev->channels[0].scan_type.realbits +
376 indio_dev->channels[0].scan_type.shift;
377 reg_size = DIV_ROUND_UP(reg_size, 8);
378
379 switch (reg_size) {
380 case 4:
381 case 2:
382 case 1:
383 ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA,
384 reg_size, &data[0]);
385 break;
386 case 3:
387 /* We store 24 bit samples in a 32 bit word. Keep the upper
388 * byte set to zero. */
389 ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA,
390 reg_size, &data[1]);
391 break;
392 }
393
394 iio_push_to_buffer(indio_dev->buffer, (uint8_t *)data);
395
396 iio_trigger_notify_done(indio_dev->trig);
397 sigma_delta->irq_dis = false;
398 enable_irq(sigma_delta->spi->irq);
399
400 return IRQ_HANDLED;
401}
402
403static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = {
404 .preenable = &iio_sw_buffer_preenable,
405 .postenable = &ad_sd_buffer_postenable,
406 .predisable = &iio_triggered_buffer_predisable,
407 .postdisable = &ad_sd_buffer_postdisable,
408 .validate_scan_mask = &iio_validate_scan_mask_onehot,
409};
410
411static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private)
412{
413 struct ad_sigma_delta *sigma_delta = private;
414
415 complete(&sigma_delta->completion);
416 disable_irq_nosync(irq);
417 sigma_delta->irq_dis = true;
418 iio_trigger_poll(sigma_delta->trig, iio_get_time_ns());
419
420 return IRQ_HANDLED;
421}
422
423/**
424 * ad_sd_validate_trigger() - validate_trigger callback for ad_sigma_delta devices
425 * @indio_dev: The IIO device
426 * @trig: The new trigger
427 *
428 * Returns: 0 if the 'trig' matches the trigger registered by the ad_sigma_delta
429 * device, -EINVAL otherwise.
430 */
431int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig)
432{
433 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
434
435 if (sigma_delta->trig != trig)
436 return -EINVAL;
437
438 return 0;
439}
440EXPORT_SYMBOL_GPL(ad_sd_validate_trigger);
441
442static const struct iio_trigger_ops ad_sd_trigger_ops = {
443 .owner = THIS_MODULE,
444};
445
446static int ad_sd_probe_trigger(struct iio_dev *indio_dev)
447{
448 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
449 int ret;
450
451 sigma_delta->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
452 indio_dev->id);
453 if (sigma_delta->trig == NULL) {
454 ret = -ENOMEM;
455 goto error_ret;
456 }
457 sigma_delta->trig->ops = &ad_sd_trigger_ops;
458 init_completion(&sigma_delta->completion);
459
460 ret = request_irq(sigma_delta->spi->irq,
461 ad_sd_data_rdy_trig_poll,
462 IRQF_TRIGGER_LOW,
463 indio_dev->name,
464 sigma_delta);
465 if (ret)
466 goto error_free_trig;
467
468 if (!sigma_delta->irq_dis) {
469 sigma_delta->irq_dis = true;
470 disable_irq_nosync(sigma_delta->spi->irq);
471 }
472 sigma_delta->trig->dev.parent = &sigma_delta->spi->dev;
473 sigma_delta->trig->private_data = sigma_delta;
474
475 ret = iio_trigger_register(sigma_delta->trig);
476 if (ret)
477 goto error_free_irq;
478
479 /* select default trigger */
480 indio_dev->trig = sigma_delta->trig;
481
482 return 0;
483
484error_free_irq:
485 free_irq(sigma_delta->spi->irq, sigma_delta);
486error_free_trig:
487 iio_trigger_free(sigma_delta->trig);
488error_ret:
489 return ret;
490}
491
492static void ad_sd_remove_trigger(struct iio_dev *indio_dev)
493{
494 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
495
496 iio_trigger_unregister(sigma_delta->trig);
497 free_irq(sigma_delta->spi->irq, sigma_delta);
498 iio_trigger_free(sigma_delta->trig);
499}
500
501/**
502 * ad_sd_setup_buffer_and_trigger() -
503 * @indio_dev: The IIO device
504 */
505int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev)
506{
507 int ret;
508
509 ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
510 &ad_sd_trigger_handler, &ad_sd_buffer_setup_ops);
511 if (ret)
512 return ret;
513
514 ret = ad_sd_probe_trigger(indio_dev);
515 if (ret) {
516 iio_triggered_buffer_cleanup(indio_dev);
517 return ret;
518 }
519
520 return 0;
521}
522EXPORT_SYMBOL_GPL(ad_sd_setup_buffer_and_trigger);
523
524/**
525 * ad_sd_cleanup_buffer_and_trigger() -
526 * @indio_dev: The IIO device
527 */
528void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev)
529{
530 ad_sd_remove_trigger(indio_dev);
531 iio_triggered_buffer_cleanup(indio_dev);
532}
533EXPORT_SYMBOL_GPL(ad_sd_cleanup_buffer_and_trigger);
534
535/**
536 * ad_sd_init() - Initializes a ad_sigma_delta struct
537 * @sigma_delta: The ad_sigma_delta device
538 * @indio_dev: The IIO device which the Sigma Delta device is used for
539 * @spi: The SPI device for the ad_sigma_delta device
540 * @info: Device specific callbacks and options
541 *
542 * This function needs to be called before any other operations are performed on
543 * the ad_sigma_delta struct.
544 */
545int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev,
546 struct spi_device *spi, const struct ad_sigma_delta_info *info)
547{
548 sigma_delta->spi = spi;
549 sigma_delta->info = info;
550 iio_device_set_drvdata(indio_dev, sigma_delta);
551
552 return 0;
553}
554EXPORT_SYMBOL_GPL(ad_sd_init);
555
556MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
557MODULE_DESCRIPTION("Analog Devices Sigma-Delta ADCs");
558MODULE_LICENSE("GPL v2");
drivers/iio/adc/at91_adc.c+18−59
@@ -82,7 +82,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) · 81 unmodified lines
82 *timestamp = pf->timestamp;82 *timestamp = pf->timestamp;
83 }83 }
84 84
85 buffer->access->store_to(buffer, (u8 *)st->buffer, pf->timestamp);85 buffer->access->store_to(buffer, (u8 *)st->buffer);
86 86
87 iio_trigger_notify_done(idev->trig);87 iio_trigger_notify_done(idev->trig);
88 st->irq_enabled = true;88 st->irq_enabled = true;
@@ -545,13 +545,6 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) · 456 unmodified lines
545 goto error_free_device;545 goto error_free_device;
546 }546 }
547 547
548 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
549 if (!res) {
550 dev_err(&pdev->dev, "No resource defined\n");
551 ret = -ENXIO;
552 goto error_ret;
553 }
554
555 platform_set_drvdata(pdev, idev);548 platform_set_drvdata(pdev, idev);
556 549
557 idev->dev.parent = &pdev->dev;550 idev->dev.parent = &pdev->dev;
@@ -566,18 +559,12 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) · 8 unmodified lines
566 goto error_free_device;559 goto error_free_device;
567 }560 }
568 561
569 if (!request_mem_region(res->start, resource_size(res),562 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
570 "AT91 adc registers")) {
571 dev_err(&pdev->dev, "Resources are unavailable.\n");
572 ret = -EBUSY;
573 goto error_free_device;
574 }
575 563
576 st->reg_base = ioremap(res->start, resource_size(res));564 st->reg_base = devm_request_and_ioremap(&pdev->dev, res);
577 if (!st->reg_base) {565 if (!st->reg_base) {
578 dev_err(&pdev->dev, "Failed to map registers.\n");
579 ret = -ENOMEM;566 ret = -ENOMEM;
580 goto error_release_mem;567 goto error_free_device;
581 }568 }
582 569
583 /*570 /*
@@ -592,45 +579,35 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) · 8 unmodified lines
592 idev);579 idev);
593 if (ret) {580 if (ret) {
594 dev_err(&pdev->dev, "Failed to allocate IRQ.\n");581 dev_err(&pdev->dev, "Failed to allocate IRQ.\n");
595 goto error_unmap_reg;582 goto error_free_device;
596 }583 }
597 584
598 st->clk = clk_get(&pdev->dev, "adc_clk");585 st->clk = devm_clk_get(&pdev->dev, "adc_clk");
599 if (IS_ERR(st->clk)) {586 if (IS_ERR(st->clk)) {
600 dev_err(&pdev->dev, "Failed to get the clock.\n");587 dev_err(&pdev->dev, "Failed to get the clock.\n");
601 ret = PTR_ERR(st->clk);588 ret = PTR_ERR(st->clk);
602 goto error_free_irq;589 goto error_free_irq;
603 }590 }
604 591
605 ret = clk_prepare(st->clk);592 ret = clk_prepare_enable(st->clk);
606 if (ret) {593 if (ret) {
607 dev_err(&pdev->dev, "Could not prepare the clock.\n");594 dev_err(&pdev->dev,
608 goto error_free_clk;595 "Could not prepare or enable the clock.\n");
609 }596 goto error_free_irq;
610
611 ret = clk_enable(st->clk);
612 if (ret) {
613 dev_err(&pdev->dev, "Could not enable the clock.\n");
614 goto error_unprepare_clk;
615 }597 }
616 598
617 st->adc_clk = clk_get(&pdev->dev, "adc_op_clk");599 st->adc_clk = devm_clk_get(&pdev->dev, "adc_op_clk");
618 if (IS_ERR(st->adc_clk)) {600 if (IS_ERR(st->adc_clk)) {
619 dev_err(&pdev->dev, "Failed to get the ADC clock.\n");601 dev_err(&pdev->dev, "Failed to get the ADC clock.\n");
620 ret = PTR_ERR(st->adc_clk);602 ret = PTR_ERR(st->adc_clk);
621 goto error_disable_clk;603 goto error_disable_clk;
622 }604 }
623 605
624 ret = clk_prepare(st->adc_clk);606 ret = clk_prepare_enable(st->adc_clk);
625 if (ret) {607 if (ret) {
626 dev_err(&pdev->dev, "Could not prepare the ADC clock.\n");608 dev_err(&pdev->dev,
627 goto error_free_adc_clk;609 "Could not prepare or enable the ADC clock.\n");
628 }610 goto error_disable_clk;
629
630 ret = clk_enable(st->adc_clk);
631 if (ret) {
632 dev_err(&pdev->dev, "Could not enable the ADC clock.\n");
633 goto error_unprepare_adc_clk;
634 }611 }
635 612
636 /*613 /*
@@ -694,23 +671,11 @@ error_remove_triggers: · 57 unmodified lines
694error_unregister_buffer:671error_unregister_buffer:
695 at91_adc_buffer_remove(idev);672 at91_adc_buffer_remove(idev);
696error_disable_adc_clk:673error_disable_adc_clk:
697 clk_disable(st->adc_clk);674 clk_disable_unprepare(st->adc_clk);
698error_unprepare_adc_clk:
699 clk_unprepare(st->adc_clk);
700error_free_adc_clk:
701 clk_put(st->adc_clk);
702error_disable_clk:675error_disable_clk:
703 clk_disable(st->clk);676 clk_disable_unprepare(st->clk);
704error_unprepare_clk:
705 clk_unprepare(st->clk);
706error_free_clk:
707 clk_put(st->clk);
708error_free_irq:677error_free_irq:
709 free_irq(st->irq, idev);678 free_irq(st->irq, idev);
710error_unmap_reg:
711 iounmap(st->reg_base);
712error_release_mem:
713 release_mem_region(res->start, resource_size(res));
714error_free_device:679error_free_device:
715 iio_device_free(idev);680 iio_device_free(idev);
716error_ret:681error_ret:
@@ -720,20 +685,14 @@ error_ret: · 3 unmodified lines
720static int __devexit at91_adc_remove(struct platform_device *pdev)685static int __devexit at91_adc_remove(struct platform_device *pdev)
721{686{
722 struct iio_dev *idev = platform_get_drvdata(pdev);687 struct iio_dev *idev = platform_get_drvdata(pdev);
723 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
724 struct at91_adc_state *st = iio_priv(idev);688 struct at91_adc_state *st = iio_priv(idev);
725 689
726 iio_device_unregister(idev);690 iio_device_unregister(idev);
727 at91_adc_trigger_remove(idev);691 at91_adc_trigger_remove(idev);
728 at91_adc_buffer_remove(idev);692 at91_adc_buffer_remove(idev);
729 clk_disable_unprepare(st->adc_clk);693 clk_disable_unprepare(st->adc_clk);
730 clk_put(st->adc_clk);694 clk_disable_unprepare(st->clk);
731 clk_disable(st->clk);
732 clk_unprepare(st->clk);
733 clk_put(st->clk);
734 free_irq(st->irq, idev);695 free_irq(st->irq, idev);
735 iounmap(st->reg_base);
736 release_mem_region(res->start, resource_size(res));
737 iio_device_free(idev);696 iio_device_free(idev);
738 697
739 return 0;698 return 0;
drivers/iio/adc/lp8788_adc.c+264−0
@@ -0,0 +1,264 @@
1/*
2 * TI LP8788 MFD - ADC driver
3 *
4 * Copyright 2012 Texas Instruments
5 *
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/delay.h>
14#include <linux/iio/iio.h>
15#include <linux/iio/driver.h>
16#include <linux/iio/machine.h>
17#include <linux/mfd/lp8788.h>
18#include <linux/module.h>
19#include <linux/mutex.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22
23/* register address */
24#define LP8788_ADC_CONF 0x60
25#define LP8788_ADC_RAW 0x61
26#define LP8788_ADC_DONE 0x63
27
28#define ADC_CONV_START 1
29
30struct lp8788_adc {
31 struct lp8788 *lp;
32 struct iio_map *map;
33 struct mutex lock;
34};
35
36static const int lp8788_scale[LPADC_MAX] = {
37 [LPADC_VBATT_5P5] = 1343101,
38 [LPADC_VIN_CHG] = 3052503,
39 [LPADC_IBATT] = 610500,
40 [LPADC_IC_TEMP] = 61050,
41 [LPADC_VBATT_6P0] = 1465201,
42 [LPADC_VBATT_5P0] = 1221001,
43 [LPADC_ADC1] = 610500,
44 [LPADC_ADC2] = 610500,
45 [LPADC_VDD] = 1025641,
46 [LPADC_VCOIN] = 757020,
47 [LPADC_ADC3] = 610500,
48 [LPADC_ADC4] = 610500,
49};
50
51static int lp8788_get_adc_result(struct lp8788_adc *adc, enum lp8788_adc_id id,
52 int *val)
53{
54 unsigned int msb;
55 unsigned int lsb;
56 unsigned int result;
57 u8 data;
58 u8 rawdata[2];
59 int size = ARRAY_SIZE(rawdata);
60 int retry = 5;
61 int ret;
62
63 data = (id << 1) | ADC_CONV_START;
64 ret = lp8788_write_byte(adc->lp, LP8788_ADC_CONF, data);
65 if (ret)
66 goto err_io;
67
68 /* retry until adc conversion is done */
69 data = 0;
70 while (retry--) {
71 usleep_range(100, 200);
72
73 ret = lp8788_read_byte(adc->lp, LP8788_ADC_DONE, &data);
74 if (ret)
75 goto err_io;
76
77 /* conversion done */
78 if (data)
79 break;
80 }
81
82 ret = lp8788_read_multi_bytes(adc->lp, LP8788_ADC_RAW, rawdata, size);
83 if (ret)
84 goto err_io;
85
86 msb = (rawdata[0] << 4) & 0x00000ff0;
87 lsb = (rawdata[1] >> 4) & 0x0000000f;
88 result = msb | lsb;
89 *val = result;
90
91 return 0;
92
93err_io:
94 return ret;
95}
96
97static int lp8788_adc_read_raw(struct iio_dev *indio_dev,
98 struct iio_chan_spec const *chan,
99 int *val, int *val2, long mask)
100{
101 struct lp8788_adc *adc = iio_priv(indio_dev);
102 enum lp8788_adc_id id = chan->channel;
103 int ret;
104
105 mutex_lock(&adc->lock);
106
107 switch (mask) {
108 case IIO_CHAN_INFO_RAW:
109 ret = lp8788_get_adc_result(adc, id, val) ? -EIO : IIO_VAL_INT;
110 break;
111 case IIO_CHAN_INFO_SCALE:
112 *val = lp8788_scale[id] / 1000000;
113 *val2 = lp8788_scale[id] % 1000000;
114 ret = IIO_VAL_INT_PLUS_MICRO;
115 break;
116 default:
117 ret = -EINVAL;
118 break;
119 }
120
121 mutex_unlock(&adc->lock);
122
123 return ret;
124}
125
126static const struct iio_info lp8788_adc_info = {
127 .read_raw = &lp8788_adc_read_raw,
128 .driver_module = THIS_MODULE,
129};
130
131#define LP8788_CHAN(_id, _type) { \
132 .type = _type, \
133 .indexed = 1, \
134 .channel = LPADC_##_id, \
135 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
136 IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
137 .datasheet_name = #_id, \
138}
139
140static const struct iio_chan_spec lp8788_adc_channels[] = {
141 [LPADC_VBATT_5P5] = LP8788_CHAN(VBATT_5P5, IIO_VOLTAGE),
142 [LPADC_VIN_CHG] = LP8788_CHAN(VIN_CHG, IIO_VOLTAGE),
143 [LPADC_IBATT] = LP8788_CHAN(IBATT, IIO_CURRENT),
144 [LPADC_IC_TEMP] = LP8788_CHAN(IC_TEMP, IIO_TEMP),
145 [LPADC_VBATT_6P0] = LP8788_CHAN(VBATT_6P0, IIO_VOLTAGE),
146 [LPADC_VBATT_5P0] = LP8788_CHAN(VBATT_5P0, IIO_VOLTAGE),
147 [LPADC_ADC1] = LP8788_CHAN(ADC1, IIO_VOLTAGE),
148 [LPADC_ADC2] = LP8788_CHAN(ADC2, IIO_VOLTAGE),
149 [LPADC_VDD] = LP8788_CHAN(VDD, IIO_VOLTAGE),
150 [LPADC_VCOIN] = LP8788_CHAN(VCOIN, IIO_VOLTAGE),
151 [LPADC_ADC3] = LP8788_CHAN(ADC3, IIO_VOLTAGE),
152 [LPADC_ADC4] = LP8788_CHAN(ADC4, IIO_VOLTAGE),
153};
154
155/* default maps used by iio consumer (lp8788-charger driver) */
156static struct iio_map lp8788_default_iio_maps[] = {
157 {
158 .consumer_dev_name = "lp8788-charger",
159 .consumer_channel = "lp8788_vbatt_5p0",
160 .adc_channel_label = "VBATT_5P0",
161 },
162 {
163 .consumer_dev_name = "lp8788-charger",
164 .consumer_channel = "lp8788_adc1",
165 .adc_channel_label = "ADC1",
166 },
167 { }
168};
169
170static int lp8788_iio_map_register(struct iio_dev *indio_dev,
171 struct lp8788_platform_data *pdata,
172 struct lp8788_adc *adc)
173{
174 struct iio_map *map;
175 int ret;
176
177 map = (!pdata || !pdata->adc_pdata) ?
178 lp8788_default_iio_maps : pdata->adc_pdata;
179
180 ret = iio_map_array_register(indio_dev, map);
181 if (ret) {
182 dev_err(adc->lp->dev, "iio map err: %d\n", ret);
183 return ret;
184 }
185
186 adc->map = map;
187 return 0;
188}
189
190static inline void lp8788_iio_map_unregister(struct iio_dev *indio_dev,
191 struct lp8788_adc *adc)
192{
193 iio_map_array_unregister(indio_dev, adc->map);
194}
195
196static int __devinit lp8788_adc_probe(struct platform_device *pdev)
197{
198 struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
199 struct iio_dev *indio_dev;
200 struct lp8788_adc *adc;
201 int ret;
202
203 indio_dev = iio_device_alloc(sizeof(*adc));
204 if (!indio_dev)
205 return -ENOMEM;
206
207 adc = iio_priv(indio_dev);
208 adc->lp = lp;
209 platform_set_drvdata(pdev, indio_dev);
210
211 ret = lp8788_iio_map_register(indio_dev, lp->pdata, adc);
212 if (ret)
213 goto err_iio_map;
214
215 mutex_init(&adc->lock);
216
217 indio_dev->dev.parent = lp->dev;
218 indio_dev->name = pdev->name;
219 indio_dev->modes = INDIO_DIRECT_MODE;
220 indio_dev->info = &lp8788_adc_info;
221 indio_dev->channels = lp8788_adc_channels;
222 indio_dev->num_channels = ARRAY_SIZE(lp8788_adc_channels);
223
224 ret = iio_device_register(indio_dev);
225 if (ret) {
226 dev_err(lp->dev, "iio dev register err: %d\n", ret);
227 goto err_iio_device;
228 }
229
230 return 0;
231
232err_iio_device:
233 lp8788_iio_map_unregister(indio_dev, adc);
234err_iio_map:
235 iio_device_free(indio_dev);
236 return ret;
237}
238
239static int __devexit lp8788_adc_remove(struct platform_device *pdev)
240{
241 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
242 struct lp8788_adc *adc = iio_priv(indio_dev);
243
244 iio_device_unregister(indio_dev);
245 lp8788_iio_map_unregister(indio_dev, adc);
246 iio_device_free(indio_dev);
247
248 return 0;
249}
250
251static struct platform_driver lp8788_adc_driver = {
252 .probe = lp8788_adc_probe,
253 .remove = __devexit_p(lp8788_adc_remove),
254 .driver = {
255 .name = LP8788_DEV_ADC,
256 .owner = THIS_MODULE,
257 },
258};
259module_platform_driver(lp8788_adc_driver);
260
261MODULE_DESCRIPTION("Texas Instruments LP8788 ADC Driver");
262MODULE_AUTHOR("Milo Kim");
263MODULE_LICENSE("GPL");
264MODULE_ALIAS("platform:lp8788-adc");
drivers/iio/common/Kconfig+5−0
@@ -0,0 +1,5 @@
1#
2# IIO common modules
3#
4
5source "drivers/iio/common/hid-sensors/Kconfig"
drivers/iio/common/Makefile+9−0
@@ -0,0 +1,9 @@
1#
2# Makefile for the IIO common modules.
3# Common modules contains modules, which can be shared among multiple
4# IIO modules. For example if the trigger processing is common for
5# multiple IIO modules then this can be moved to a common module
6# instead of duplicating in each module.
7#
8
9obj-y += hid-sensors/
drivers/iio/common/hid-sensors/Kconfig+26−0
@@ -0,0 +1,26 @@
1#
2# Hid Sensor common modules
3#
4menu "Hid Sensor IIO Common"
5
6config HID_SENSOR_IIO_COMMON
7 tristate "Common modules for all HID Sensor IIO drivers"
8 depends on HID_SENSOR_HUB
9 select IIO_TRIGGER if IIO_BUFFER
10 help
11 Say yes here to build support for HID sensor to use
12 HID sensor common processing for attributes and IIO triggers.
13 There are many attributes which can be shared among multiple
14 HID sensor drivers, this module contains processing for those
15 attributes.
16
17config HID_SENSOR_ENUM_BASE_QUIRKS
18 tristate "ENUM base quirks for HID Sensor IIO drivers"
19 depends on HID_SENSOR_IIO_COMMON
20 help
21 Say yes here to build support for sensor hub FW using
22 enumeration, which is using 1 as base instead of 0.
23 Since logical minimum is still set 0 instead of 1,
24 there is no easy way to differentiate.
25
26endmenu
drivers/iio/common/hid-sensors/Makefile+6−0
@@ -0,0 +1,6 @@
1#
2# Makefile for the Hid sensor common modules.
3#
4
5obj-$(CONFIG_HID_SENSOR_IIO_COMMON) += hid-sensor-iio-common.o
6hid-sensor-iio-common-y := hid-sensor-attributes.o hid-sensor-trigger.o
drivers/iio/common/hid-sensors/hid-sensor-attributes.c+250−0
@@ -0,0 +1,250 @@
1/*
2 * HID Sensors Driver
3 * Copyright (c) 2012, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 */
19#include <linux/device.h>
20#include <linux/platform_device.h>
21#include <linux/module.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/slab.h>
25#include <linux/hid-sensor-hub.h>
26#include <linux/iio/iio.h>
27#include <linux/iio/sysfs.h>
28#include "hid-sensor-attributes.h"
29
30static int pow_10(unsigned power)
31{
32 int i;
33 int ret = 1;
34 for (i = 0; i < power; ++i)
35 ret = ret * 10;
36
37 return ret;
38}
39
40static void simple_div(int dividend, int divisor, int *whole,
41 int *micro_frac)
42{
43 int rem;
44 int exp = 0;
45
46 *micro_frac = 0;
47 if (divisor == 0) {
48 *whole = 0;
49 return;
50 }
51 *whole = dividend/divisor;
52 rem = dividend % divisor;
53 if (rem) {
54 while (rem <= divisor) {
55 rem *= 10;
56 exp++;
57 }
58 *micro_frac = (rem / divisor) * pow_10(6-exp);
59 }
60}
61
62static void split_micro_fraction(unsigned int no, int exp, int *val1, int *val2)
63{
64 *val1 = no/pow_10(exp);
65 *val2 = no%pow_10(exp) * pow_10(6-exp);
66}
67
68/*
69VTF format uses exponent and variable size format.
70For example if the size is 2 bytes
710x0067 with VTF16E14 format -> +1.03
72To convert just change to 0x67 to decimal and use two decimal as E14 stands
73for 10^-2.
74Negative numbers are 2's complement
75*/
76static void convert_from_vtf_format(u32 value, int size, int exp,
77 int *val1, int *val2)
78{
79 int sign = 1;
80
81 if (value & BIT(size*8 - 1)) {
82 value = ((1LL << (size * 8)) - value);
83 sign = -1;
84 }
85 exp = hid_sensor_convert_exponent(exp);
86 if (exp >= 0) {
87 *val1 = sign * value * pow_10(exp);
88 *val2 = 0;
89 } else {
90 split_micro_fraction(value, -exp, val1, val2);
91 if (*val1)
92 *val1 = sign * (*val1);
93 else
94 *val2 = sign * (*val2);
95 }
96}
97
98static u32 convert_to_vtf_format(int size, int exp, int val1, int val2)
99{
100 u32 value;
101 int sign = 1;
102
103 if (val1 < 0 || val2 < 0)
104 sign = -1;
105 exp = hid_sensor_convert_exponent(exp);
106 if (exp < 0) {
107 value = abs(val1) * pow_10(-exp);
108 value += abs(val2) / pow_10(6+exp);
109 } else
110 value = abs(val1) / pow_10(exp);
111 if (sign < 0)
112 value = ((1LL << (size * 8)) - value);
113
114 return value;
115}
116
117int hid_sensor_read_samp_freq_value(struct hid_sensor_iio_common *st,
118 int *val1, int *val2)
119{
120 s32 value;
121 int ret;
122
123 ret = sensor_hub_get_feature(st->hsdev,
124 st->poll.report_id,
125 st->poll.index, &value);
126 if (ret < 0 || value < 0) {
127 *val1 = *val2 = 0;
128 return -EINVAL;
129 } else {
130 if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND)
131 simple_div(1000, value, val1, val2);
132 else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND)
133 simple_div(1, value, val1, val2);
134 else {
135 *val1 = *val2 = 0;
136 return -EINVAL;
137 }
138 }
139
140 return IIO_VAL_INT_PLUS_MICRO;
141}
142EXPORT_SYMBOL(hid_sensor_read_samp_freq_value);
143
144int hid_sensor_write_samp_freq_value(struct hid_sensor_iio_common *st,
145 int val1, int val2)
146{
147 s32 value;
148 int ret;
149
150 if (val1 < 0 || val2 < 0)
151 ret = -EINVAL;
152
153 value = val1 * pow_10(6) + val2;
154 if (value) {
155 if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND)
156 value = pow_10(9)/value;
157 else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND)
158 value = pow_10(6)/value;
159 else
160 value = 0;
161 }
162 ret = sensor_hub_set_feature(st->hsdev,
163 st->poll.report_id,
164 st->poll.index, value);
165 if (ret < 0 || value < 0)
166 ret = -EINVAL;
167
168 return ret;
169}
170EXPORT_SYMBOL(hid_sensor_write_samp_freq_value);
171
172int hid_sensor_read_raw_hyst_value(struct hid_sensor_iio_common *st,
173 int *val1, int *val2)
174{
175 s32 value;
176 int ret;
177
178 ret = sensor_hub_get_feature(st->hsdev,
179 st->sensitivity.report_id,
180 st->sensitivity.index, &value);
181 if (ret < 0 || value < 0) {
182 *val1 = *val2 = 0;
183 return -EINVAL;
184 } else {
185 convert_from_vtf_format(value, st->sensitivity.size,
186 st->sensitivity.unit_expo,
187 val1, val2);
188 }
189
190 return IIO_VAL_INT_PLUS_MICRO;
191}
192EXPORT_SYMBOL(hid_sensor_read_raw_hyst_value);
193
194int hid_sensor_write_raw_hyst_value(struct hid_sensor_iio_common *st,
195 int val1, int val2)
196{
197 s32 value;
198 int ret;
199
200 value = convert_to_vtf_format(st->sensitivity.size,
201 st->sensitivity.unit_expo,
202 val1, val2);
203 ret = sensor_hub_set_feature(st->hsdev,
204 st->sensitivity.report_id,
205 st->sensitivity.index, value);
206 if (ret < 0 || value < 0)
207 ret = -EINVAL;
208
209 return ret;
210}
211EXPORT_SYMBOL(hid_sensor_write_raw_hyst_value);
212
213int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
214 u32 usage_id,
215 struct hid_sensor_iio_common *st)
216{
217
218 sensor_hub_input_get_attribute_info(hsdev,
219 HID_FEATURE_REPORT, usage_id,
220 HID_USAGE_SENSOR_PROP_REPORT_INTERVAL,
221 &st->poll);
222
223 sensor_hub_input_get_attribute_info(hsdev,
224 HID_FEATURE_REPORT, usage_id,
225 HID_USAGE_SENSOR_PROP_REPORT_STATE,
226 &st->report_state);
227
228 sensor_hub_input_get_attribute_info(hsdev,
229 HID_FEATURE_REPORT, usage_id,
230 HID_USAGE_SENSOR_PROY_POWER_STATE,
231 &st->power_state);
232
233 sensor_hub_input_get_attribute_info(hsdev,
234 HID_FEATURE_REPORT, usage_id,
235 HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS,
236 &st->sensitivity);
237
238 hid_dbg(hsdev->hdev, "common attributes: %x:%x, %x:%x, %x:%x %x:%x\n",
239 st->poll.index, st->poll.report_id,
240 st->report_state.index, st->report_state.report_id,
241 st->power_state.index, st->power_state.report_id,
242 st->sensitivity.index, st->sensitivity.report_id);
243
244 return 0;
245}
246EXPORT_SYMBOL(hid_sensor_parse_common_attributes);
247
248MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
249MODULE_DESCRIPTION("HID Sensor common attribute processing");
250MODULE_LICENSE("GPL");
drivers/iio/common/hid-sensors/hid-sensor-attributes.h+57−0
@@ -0,0 +1,57 @@
1/*
2 * HID Sensors Driver
3 * Copyright (c) 2012, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 */
19#ifndef _HID_SENSORS_ATTRIBUTES_H
20#define _HID_SENSORS_ATTRIBUTES_H
21
22/* Common hid sensor iio structure */
23struct hid_sensor_iio_common {
24 struct hid_sensor_hub_device *hsdev;
25 struct platform_device *pdev;
26 unsigned usage_id;
27 bool data_ready;
28 struct hid_sensor_hub_attribute_info poll;
29 struct hid_sensor_hub_attribute_info report_state;
30 struct hid_sensor_hub_attribute_info power_state;
31 struct hid_sensor_hub_attribute_info sensitivity;
32};
33
34/*Convert from hid unit expo to regular exponent*/
35static inline int hid_sensor_convert_exponent(int unit_expo)
36{
37 if (unit_expo < 0x08)
38 return unit_expo;
39 else if (unit_expo <= 0x0f)
40 return -(0x0f-unit_expo+1);
41 else
42 return 0;
43}
44
45int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
46 u32 usage_id,
47 struct hid_sensor_iio_common *st);
48int hid_sensor_write_raw_hyst_value(struct hid_sensor_iio_common *st,
49 int val1, int val2);
50int hid_sensor_read_raw_hyst_value(struct hid_sensor_iio_common *st,
51 int *val1, int *val2);
52int hid_sensor_write_samp_freq_value(struct hid_sensor_iio_common *st,
53 int val1, int val2);
54int hid_sensor_read_samp_freq_value(struct hid_sensor_iio_common *st,
55 int *val1, int *val2);
56
57#endif
drivers/iio/common/hid-sensors/hid-sensor-trigger.c+103−0
@@ -0,0 +1,103 @@
1/*
2 * HID Sensors Driver
3 * Copyright (c) 2012, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 */
19#include <linux/device.h>
20#include <linux/platform_device.h>
21#include <linux/module.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/slab.h>
25#include <linux/hid-sensor-hub.h>
26#include <linux/iio/iio.h>
27#include <linux/iio/trigger.h>
28#include <linux/iio/sysfs.h>
29#include "hid-sensor-attributes.h"
30#include "hid-sensor-trigger.h"
31
32static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
33 bool state)
34{
35 struct hid_sensor_iio_common *st = trig->private_data;
36 int state_val;
37
38 state_val = state ? 1 : 0;
39#if (defined CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS) || \
40 (defined CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS_MODULE)
41 ++state_val;
42#endif
43 st->data_ready = state;
44 sensor_hub_set_feature(st->hsdev, st->power_state.report_id,
45 st->power_state.index,
46 (s32)state_val);
47
48 sensor_hub_set_feature(st->hsdev, st->report_state.report_id,
49 st->report_state.index,
50 (s32)state_val);
51
52 return 0;
53}
54
55void hid_sensor_remove_trigger(struct iio_dev *indio_dev)
56{
57 iio_trigger_unregister(indio_dev->trig);
58 iio_trigger_free(indio_dev->trig);
59 indio_dev->trig = NULL;
60}
61EXPORT_SYMBOL(hid_sensor_remove_trigger);
62
63static const struct iio_trigger_ops hid_sensor_trigger_ops = {
64 .owner = THIS_MODULE,
65 .set_trigger_state = &hid_sensor_data_rdy_trigger_set_state,
66};
67
68int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
69 struct hid_sensor_iio_common *attrb)
70{
71 int ret;
72 struct iio_trigger *trig;
73
74 trig = iio_trigger_alloc("%s-dev%d", name, indio_dev->id);
75 if (trig == NULL) {
76 dev_err(&indio_dev->dev, "Trigger Allocate Failed\n");
77 ret = -ENOMEM;
78 goto error_ret;
79 }
80
81 trig->dev.parent = indio_dev->dev.parent;
82 trig->private_data = attrb;
83 trig->ops = &hid_sensor_trigger_ops;
84 ret = iio_trigger_register(trig);
85
86 if (ret) {
87 dev_err(&indio_dev->dev, "Trigger Register Failed\n");
88 goto error_free_trig;
89 }
90 indio_dev->trig = trig;
91
92 return ret;
93
94error_free_trig:
95 iio_trigger_free(trig);
96error_ret:
97 return ret;
98}
99EXPORT_SYMBOL(hid_sensor_setup_trigger);
100
101MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
102MODULE_DESCRIPTION("HID Sensor trigger processing");
103MODULE_LICENSE("GPL");
drivers/iio/common/hid-sensors/hid-sensor-trigger.h+26−0
@@ -0,0 +1,26 @@
1/*
2 * HID Sensors Driver
3 * Copyright (c) 2012, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 */
19#ifndef _HID_SENSOR_TRIGGER_H
20#define _HID_SENSOR_TRIGGER_H
21
22int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
23 struct hid_sensor_iio_common *attrb);
24void hid_sensor_remove_trigger(struct iio_dev *indio_dev);
25
26#endif
drivers/iio/dac/Kconfig+16−4
@@ -57,11 +57,12 @@ config AD5624R_SPI · 56 unmodified lines
57 57
58config AD544658config AD5446
59 tristate "Analog Devices AD5446 and similar single channel DACs driver"59 tristate "Analog Devices AD5446 and similar single channel DACs driver"
60 depends on SPI60 depends on (SPI_MASTER || I2C)
61 help61 help
62 Say yes here to build support for Analog Devices AD5444, AD5446, AD5450,62 Say yes here to build support for Analog Devices AD5300, AD5301, AD5310,
63 AD5451, AD5452, AD5453, AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601,63 AD5311, AD5320, AD5321, AD5444, AD5446, AD5450, AD5451, AD5452, AD5453,
64 AD5611, AD5620, AD5621, AD5640, AD5660, AD5662 DACs.64 AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, AD5602, AD5611, AD5612,
65 AD5620, AD5621, AD5622, AD5640, AD5660, AD5662 DACs.
65 66
66 To compile this driver as a module, choose M here: the67 To compile this driver as a module, choose M here: the
67 module will be called ad5446.68 module will be called ad5446.
@@ -76,6 +77,17 @@ config AD5504 · 8 unmodified lines
76 To compile this driver as a module, choose M here: the77 To compile this driver as a module, choose M here: the
77 module will be called ad5504.78 module will be called ad5504.
78 79
80config AD5755
81 tristate "Analog Devices AD5755/AD5755-1/AD5757/AD5735/AD5737 DAC driver"
82 depends on SPI_MASTER
83 help
84 Say yes here to build support for Analog Devices AD5755, AD5755-1,
85 AD5757, AD5735, AD5737 quad channel Digital to
86 Analog Converter.
87
88 To compile this driver as a module, choose M here: the
89 module will be called ad5755.
90
79config AD576491config AD5764
80 tristate "Analog Devices AD5764/64R/44/44R DAC driver"92 tristate "Analog Devices AD5764/64R/44/44R DAC driver"
81 depends on SPI_MASTER93 depends on SPI_MASTER
drivers/iio/dac/Makefile+1−0
@@ -9,6 +9,7 @@ obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o · 8 unmodified lines
9obj-$(CONFIG_AD5064) += ad5064.o9obj-$(CONFIG_AD5064) += ad5064.o
10obj-$(CONFIG_AD5504) += ad5504.o10obj-$(CONFIG_AD5504) += ad5504.o
11obj-$(CONFIG_AD5446) += ad5446.o11obj-$(CONFIG_AD5446) += ad5446.o
12obj-$(CONFIG_AD5755) += ad5755.o
12obj-$(CONFIG_AD5764) += ad5764.o13obj-$(CONFIG_AD5764) += ad5764.o
13obj-$(CONFIG_AD5791) += ad5791.o14obj-$(CONFIG_AD5791) += ad5791.o
14obj-$(CONFIG_AD5686) += ad5686.o15obj-$(CONFIG_AD5686) += ad5686.o
drivers/iio/dac/ad5446.c+338−112
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <linux/sysfs.h>14#include <linux/sysfs.h>
15#include <linux/list.h>15#include <linux/list.h>
16#include <linux/spi/spi.h>16#include <linux/spi/spi.h>
17#include <linux/i2c.h>
17#include <linux/regulator/consumer.h>18#include <linux/regulator/consumer.h>
18#include <linux/err.h>19#include <linux/err.h>
19#include <linux/module.h>20#include <linux/module.h>
@@ -21,24 +22,40 @@ · 1 unmodified line
21#include <linux/iio/iio.h>22#include <linux/iio/iio.h>
22#include <linux/iio/sysfs.h>23#include <linux/iio/sysfs.h>
23 24
24#include "ad5446.h"25#define MODE_PWRDWN_1k 0x1
26#define MODE_PWRDWN_100k 0x2
27#define MODE_PWRDWN_TRISTATE 0x3
25 28
26static int ad5446_write(struct ad5446_state *st, unsigned val)29/**
27{30 * struct ad5446_state - driver instance specific data
28 __be16 data = cpu_to_be16(val);31 * @spi: spi_device
29 return spi_write(st->spi, &data, sizeof(data));32 * @chip_info: chip model specific constants, available modes etc
30}33 * @reg: supply regulator
34 * @vref_mv: actual reference voltage used
35 */
31 36
32static int ad5660_write(struct ad5446_state *st, unsigned val)37struct ad5446_state {
33{38 struct device *dev;
34 uint8_t data[3];39 const struct ad5446_chip_info *chip_info;
40 struct regulator *reg;
41 unsigned short vref_mv;
42 unsigned cached_val;
43 unsigned pwr_down_mode;
44 unsigned pwr_down;
45};
35 46
36 data[0] = (val >> 16) & 0xFF;47/**
37 data[1] = (val >> 8) & 0xFF;48 * struct ad5446_chip_info - chip specific information
38 data[2] = val & 0xFF;49 * @channel: channel spec for the DAC
50 * @int_vref_mv: AD5620/40/60: the internal reference voltage
51 * @write: chip specific helper function to write to the register
52 */
39 53
40 return spi_write(st->spi, data, sizeof(data));54struct ad5446_chip_info {
41}55 struct iio_chan_spec channel;
56 u16 int_vref_mv;
57 int (*write)(struct ad5446_state *st, unsigned val);
58};
42 59
43static const char * const ad5446_powerdown_modes[] = {60static const char * const ad5446_powerdown_modes[] = {
44 "1kohm_to_gnd", "100kohm_to_gnd", "three_state"61 "1kohm_to_gnd", "100kohm_to_gnd", "three_state"
@@ -110,7 +127,7 @@ static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev, · 65 unmodified lines
110 return ret ? ret : len;127 return ret ? ret : len;
111}128}
112 129
113static const struct iio_chan_spec_ext_info ad5064_ext_info_powerdown[] = {130static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = {
114 {131 {
115 .name = "powerdown",132 .name = "powerdown",
116 .read = ad5446_read_dac_powerdown,133 .read = ad5446_read_dac_powerdown,
@@ -136,84 +153,7 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info_powerdown[] = { · 19 unmodified lines
136 _AD5446_CHANNEL(bits, storage, shift, NULL)153 _AD5446_CHANNEL(bits, storage, shift, NULL)
137 154
138#define AD5446_CHANNEL_POWERDOWN(bits, storage, shift) \155#define AD5446_CHANNEL_POWERDOWN(bits, storage, shift) \
139 _AD5446_CHANNEL(bits, storage, shift, ad5064_ext_info_powerdown)156 _AD5446_CHANNEL(bits, storage, shift, ad5446_ext_info_powerdown)
140
141static const struct ad5446_chip_info ad5446_chip_info_tbl[] = {
142 [ID_AD5444] = {
143 .channel = AD5446_CHANNEL(12, 16, 2),
144 .write = ad5446_write,
145 },
146 [ID_AD5446] = {
147 .channel = AD5446_CHANNEL(14, 16, 0),
148 .write = ad5446_write,
149 },
150 [ID_AD5450] = {
151 .channel = AD5446_CHANNEL(8, 16, 6),
152 .write = ad5446_write,
153 },
154 [ID_AD5451] = {
155 .channel = AD5446_CHANNEL(10, 16, 4),
156 .write = ad5446_write,
157 },
158 [ID_AD5541A] = {
159 .channel = AD5446_CHANNEL(16, 16, 0),
160 .write = ad5446_write,
161 },
162 [ID_AD5512A] = {
163 .channel = AD5446_CHANNEL(12, 16, 4),
164 .write = ad5446_write,
165 },
166 [ID_AD5553] = {
167 .channel = AD5446_CHANNEL(14, 16, 0),
168 .write = ad5446_write,
169 },
170 [ID_AD5601] = {
171 .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6),
172 .write = ad5446_write,
173 },
174 [ID_AD5611] = {
175 .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4),
176 .write = ad5446_write,
177 },
178 [ID_AD5621] = {
179 .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
180 .write = ad5446_write,
181 },
182 [ID_AD5620_2500] = {
183 .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
184 .int_vref_mv = 2500,
185 .write = ad5446_write,
186 },
187 [ID_AD5620_1250] = {
188 .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
189 .int_vref_mv = 1250,
190 .write = ad5446_write,
191 },
192 [ID_AD5640_2500] = {
193 .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0),
194 .int_vref_mv = 2500,
195 .write = ad5446_write,
196 },
197 [ID_AD5640_1250] = {
198 .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0),
199 .int_vref_mv = 1250,
200 .write = ad5446_write,
201 },
202 [ID_AD5660_2500] = {
203 .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0),
204 .int_vref_mv = 2500,
205 .write = ad5660_write,
206 },
207 [ID_AD5660_1250] = {
208 .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0),
209 .int_vref_mv = 1250,
210 .write = ad5660_write,
211 },
212 [ID_AD5662] = {
213 .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0),
214 .write = ad5660_write,
215 },
216};
217 157
218static int ad5446_read_raw(struct iio_dev *indio_dev,158static int ad5446_read_raw(struct iio_dev *indio_dev,
219 struct iio_chan_spec const *chan,159 struct iio_chan_spec const *chan,
@@ -272,14 +212,15 @@ static const struct iio_info ad5446_info = { · 52 unmodified lines
272 .driver_module = THIS_MODULE,212 .driver_module = THIS_MODULE,
273};213};
274 214
275static int __devinit ad5446_probe(struct spi_device *spi)215static int __devinit ad5446_probe(struct device *dev, const char *name,
216 const struct ad5446_chip_info *chip_info)
276{217{
277 struct ad5446_state *st;218 struct ad5446_state *st;
278 struct iio_dev *indio_dev;219 struct iio_dev *indio_dev;
279 struct regulator *reg;220 struct regulator *reg;
280 int ret, voltage_uv = 0;221 int ret, voltage_uv = 0;
281 222
282 reg = regulator_get(&spi->dev, "vcc");223 reg = regulator_get(dev, "vcc");
283 if (!IS_ERR(reg)) {224 if (!IS_ERR(reg)) {
284 ret = regulator_enable(reg);225 ret = regulator_enable(reg);
285 if (ret)226 if (ret)
@@ -294,16 +235,15 @@ static int __devinit ad5446_probe(struct spi_device *spi) · 8 unmodified lines
294 goto error_disable_reg;235 goto error_disable_reg;
295 }236 }
296 st = iio_priv(indio_dev);237 st = iio_priv(indio_dev);
297 st->chip_info =238 st->chip_info = chip_info;
298 &ad5446_chip_info_tbl[spi_get_device_id(spi)->driver_data];
299 239
300 spi_set_drvdata(spi, indio_dev);240 dev_set_drvdata(dev, indio_dev);
301 st->reg = reg;241 st->reg = reg;
302 st->spi = spi;242 st->dev = dev;
303 243
304 /* Establish that the iio_dev is a child of the spi device */244 /* Establish that the iio_dev is a child of the device */
305 indio_dev->dev.parent = &spi->dev;245 indio_dev->dev.parent = dev;
306 indio_dev->name = spi_get_device_id(spi)->name;246 indio_dev->name = name;
307 indio_dev->info = &ad5446_info;247 indio_dev->info = &ad5446_info;
308 indio_dev->modes = INDIO_DIRECT_MODE;248 indio_dev->modes = INDIO_DIRECT_MODE;
309 indio_dev->channels = &st->chip_info->channel;249 indio_dev->channels = &st->chip_info->channel;
@@ -316,7 +256,7 @@ static int __devinit ad5446_probe(struct spi_device *spi) · 6 unmodified lines
316 else if (voltage_uv)256 else if (voltage_uv)
317 st->vref_mv = voltage_uv / 1000;257 st->vref_mv = voltage_uv / 1000;
318 else258 else
319 dev_warn(&spi->dev, "reference voltage unspecified\n");259 dev_warn(dev, "reference voltage unspecified\n");
320 260
321 ret = iio_device_register(indio_dev);261 ret = iio_device_register(indio_dev);
322 if (ret)262 if (ret)
@@ -336,9 +276,9 @@ error_put_reg: · 13 unmodified lines
336 return ret;276 return ret;
337}277}
338 278
339static int ad5446_remove(struct spi_device *spi)279static int ad5446_remove(struct device *dev)
340{280{
341 struct iio_dev *indio_dev = spi_get_drvdata(spi);281 struct iio_dev *indio_dev = dev_get_drvdata(dev);
342 struct ad5446_state *st = iio_priv(indio_dev);282 struct ad5446_state *st = iio_priv(indio_dev);
343 283
344 iio_device_unregister(indio_dev);284 iio_device_unregister(indio_dev);
@@ -351,7 +291,151 @@ static int ad5446_remove(struct spi_device *spi) · 6 unmodified lines
351 return 0;291 return 0;
352}292}
353 293
354static const struct spi_device_id ad5446_id[] = {294#if IS_ENABLED(CONFIG_SPI_MASTER)
295
296static int ad5446_write(struct ad5446_state *st, unsigned val)
297{
298 struct spi_device *spi = to_spi_device(st->dev);
299 __be16 data = cpu_to_be16(val);
300
301 return spi_write(spi, &data, sizeof(data));
302}
303
304static int ad5660_write(struct ad5446_state *st, unsigned val)
305{
306 struct spi_device *spi = to_spi_device(st->dev);
307 uint8_t data[3];
308
309 data[0] = (val >> 16) & 0xFF;
310 data[1] = (val >> 8) & 0xFF;
311 data[2] = val & 0xFF;
312
313 return spi_write(spi, data, sizeof(data));
314}
315
316/**
317 * ad5446_supported_spi_device_ids:
318 * The AD5620/40/60 parts are available in different fixed internal reference
319 * voltage options. The actual part numbers may look differently
320 * (and a bit cryptic), however this style is used to make clear which
321 * parts are supported here.
322 */
323enum ad5446_supported_spi_device_ids {
324 ID_AD5300,
325 ID_AD5310,
326 ID_AD5320,
327 ID_AD5444,
328 ID_AD5446,
329 ID_AD5450,
330 ID_AD5451,
331 ID_AD5541A,
332 ID_AD5512A,
333 ID_AD5553,
334 ID_AD5601,
335 ID_AD5611,
336 ID_AD5621,
337 ID_AD5620_2500,
338 ID_AD5620_1250,
339 ID_AD5640_2500,
340 ID_AD5640_1250,
341 ID_AD5660_2500,
342 ID_AD5660_1250,
343 ID_AD5662,
344};
345
346static const struct ad5446_chip_info ad5446_spi_chip_info[] = {
347 [ID_AD5300] = {
348 .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 4),
349 .write = ad5446_write,
350 },
351 [ID_AD5310] = {
352 .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 2),
353 .write = ad5446_write,
354 },
355 [ID_AD5320] = {
356 .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 0),
357 .write = ad5446_write,
358 },
359 [ID_AD5444] = {
360 .channel = AD5446_CHANNEL(12, 16, 2),
361 .write = ad5446_write,
362 },
363 [ID_AD5446] = {
364 .channel = AD5446_CHANNEL(14, 16, 0),
365 .write = ad5446_write,
366 },
367 [ID_AD5450] = {
368 .channel = AD5446_CHANNEL(8, 16, 6),
369 .write = ad5446_write,
370 },
371 [ID_AD5451] = {
372 .channel = AD5446_CHANNEL(10, 16, 4),
373 .write = ad5446_write,
374 },
375 [ID_AD5541A] = {
376 .channel = AD5446_CHANNEL(16, 16, 0),
377 .write = ad5446_write,
378 },
379 [ID_AD5512A] = {
380 .channel = AD5446_CHANNEL(12, 16, 4),
381 .write = ad5446_write,
382 },
383 [ID_AD5553] = {
384 .channel = AD5446_CHANNEL(14, 16, 0),
385 .write = ad5446_write,
386 },
387 [ID_AD5601] = {
388 .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6),
389 .write = ad5446_write,
390 },
391 [ID_AD5611] = {
392 .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4),
393 .write = ad5446_write,
394 },
395 [ID_AD5621] = {
396 .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
397 .write = ad5446_write,
398 },
399 [ID_AD5620_2500] = {
400 .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
401 .int_vref_mv = 2500,
402 .write = ad5446_write,
403 },
404 [ID_AD5620_1250] = {
405 .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
406 .int_vref_mv = 1250,
407 .write = ad5446_write,
408 },
409 [ID_AD5640_2500] = {
410 .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0),
411 .int_vref_mv = 2500,
412 .write = ad5446_write,
413 },
414 [ID_AD5640_1250] = {
415 .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0),
416 .int_vref_mv = 1250,
417 .write = ad5446_write,
418 },
419 [ID_AD5660_2500] = {
420 .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0),
421 .int_vref_mv = 2500,
422 .write = ad5660_write,
423 },
424 [ID_AD5660_1250] = {
425 .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0),
426 .int_vref_mv = 1250,
427 .write = ad5660_write,
428 },
429 [ID_AD5662] = {
430 .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0),
431 .write = ad5660_write,
432 },
433};
434
435static const struct spi_device_id ad5446_spi_ids[] = {
436 {"ad5300", ID_AD5300},
437 {"ad5310", ID_AD5310},
438 {"ad5320", ID_AD5320},
355 {"ad5444", ID_AD5444},439 {"ad5444", ID_AD5444},
356 {"ad5446", ID_AD5446},440 {"ad5446", ID_AD5446},
357 {"ad5450", ID_AD5450},441 {"ad5450", ID_AD5450},
@@ -375,18 +459,160 @@ static const struct spi_device_id ad5446_id[] = { · 17 unmodified lines
375 {"ad5662", ID_AD5662},459 {"ad5662", ID_AD5662},
376 {}460 {}
377};461};
378MODULE_DEVICE_TABLE(spi, ad5446_id);462MODULE_DEVICE_TABLE(spi, ad5446_spi_ids);
463
464static int __devinit ad5446_spi_probe(struct spi_device *spi)
465{
466 const struct spi_device_id *id = spi_get_device_id(spi);
379 467
380static struct spi_driver ad5446_driver = {468 return ad5446_probe(&spi->dev, id->name,
469 &ad5446_spi_chip_info[id->driver_data]);
470}
471
472static int __devexit ad5446_spi_remove(struct spi_device *spi)
473{
474 return ad5446_remove(&spi->dev);
475}
476
477static struct spi_driver ad5446_spi_driver = {
381 .driver = {478 .driver = {
382 .name = "ad5446",479 .name = "ad5446",
383 .owner = THIS_MODULE,480 .owner = THIS_MODULE,
384 },481 },
385 .probe = ad5446_probe,482 .probe = ad5446_spi_probe,
386 .remove = __devexit_p(ad5446_remove),483 .remove = __devexit_p(ad5446_spi_remove),
387 .id_table = ad5446_id,484 .id_table = ad5446_spi_ids,
388};485};
389module_spi_driver(ad5446_driver);486
487static int __init ad5446_spi_register_driver(void)
488{
489 return spi_register_driver(&ad5446_spi_driver);
490}
491
492static void ad5446_spi_unregister_driver(void)
493{
494 spi_unregister_driver(&ad5446_spi_driver);
495}
496
497#else
498
499static inline int ad5446_spi_register_driver(void) { return 0; }
500static inline void ad5446_spi_unregister_driver(void) { }
501
502#endif
503
504#if IS_ENABLED(CONFIG_I2C)
505
506static int ad5622_write(struct ad5446_state *st, unsigned val)
507{
508 struct i2c_client *client = to_i2c_client(st->dev);
509 __be16 data = cpu_to_be16(val);
510
511 return i2c_master_send(client, (char *)&data, sizeof(data));
512}
513
514/**
515 * ad5446_supported_i2c_device_ids:
516 * The AD5620/40/60 parts are available in different fixed internal reference
517 * voltage options. The actual part numbers may look differently
518 * (and a bit cryptic), however this style is used to make clear which
519 * parts are supported here.
520 */
521enum ad5446_supported_i2c_device_ids {
522 ID_AD5602,
523 ID_AD5612,
524 ID_AD5622,
525};
526
527static const struct ad5446_chip_info ad5446_i2c_chip_info[] = {
528 [ID_AD5602] = {
529 .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 4),
530 .write = ad5622_write,
531 },
532 [ID_AD5612] = {
533 .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 2),
534 .write = ad5622_write,
535 },
536 [ID_AD5622] = {
537 .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 0),
538 .write = ad5622_write,
539 },
540};
541
542static int __devinit ad5446_i2c_probe(struct i2c_client *i2c,
543 const struct i2c_device_id *id)
544{
545 return ad5446_probe(&i2c->dev, id->name,
546 &ad5446_i2c_chip_info[id->driver_data]);
547}
548
549static int __devexit ad5446_i2c_remove(struct i2c_client *i2c)
550{
551 return ad5446_remove(&i2c->dev);
552}
553
554static const struct i2c_device_id ad5446_i2c_ids[] = {
555 {"ad5301", ID_AD5602},
556 {"ad5311", ID_AD5612},
557 {"ad5321", ID_AD5622},
558 {"ad5602", ID_AD5602},
559 {"ad5612", ID_AD5612},
560 {"ad5622", ID_AD5622},
561 {}
562};
563MODULE_DEVICE_TABLE(i2c, ad5446_i2c_ids);
564
565static struct i2c_driver ad5446_i2c_driver = {
566 .driver = {
567 .name = "ad5446",
568 .owner = THIS_MODULE,
569 },
570 .probe = ad5446_i2c_probe,
571 .remove = __devexit_p(ad5446_i2c_remove),
572 .id_table = ad5446_i2c_ids,
573};
574
575static int __init ad5446_i2c_register_driver(void)
576{
577 return i2c_add_driver(&ad5446_i2c_driver);
578}
579
580static void __exit ad5446_i2c_unregister_driver(void)
581{
582 i2c_del_driver(&ad5446_i2c_driver);
583}
584
585#else
586
587static inline int ad5446_i2c_register_driver(void) { return 0; }
588static inline void ad5446_i2c_unregister_driver(void) { }
589
590#endif
591
592static int __init ad5446_init(void)
593{
594 int ret;
595
596 ret = ad5446_spi_register_driver();
597 if (ret)
598 return ret;
599
600 ret = ad5446_i2c_register_driver();
601 if (ret) {
602 ad5446_spi_unregister_driver();
603 return ret;
604 }
605
606 return 0;
607}
608module_init(ad5446_init);
609
610static void __exit ad5446_exit(void)
611{
612 ad5446_i2c_unregister_driver();
613 ad5446_spi_unregister_driver();
614}
615module_exit(ad5446_exit);
390 616
391MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");617MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
392MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC");618MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC");
drivers/iio/dac/ad5446.h+0−91
@@ -1,91 +0,0 @@
1/*
2 * AD5446 SPI DAC driver
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8#ifndef IIO_DAC_AD5446_H_
9#define IIO_DAC_AD5446_H_
10
11/* DAC Control Bits */
12
13#define AD5446_LOAD (0x0 << 14) /* Load and update */
14#define AD5446_SDO_DIS (0x1 << 14) /* Disable SDO */
15#define AD5446_NOP (0x2 << 14) /* No operation */
16#define AD5446_CLK_RISING (0x3 << 14) /* Clock data on rising edge */
17
18#define AD5620_LOAD (0x0 << 14) /* Load and update Norm Operation*/
19#define AD5620_PWRDWN_1k (0x1 << 14) /* Power-down: 1kOhm to GND */
20#define AD5620_PWRDWN_100k (0x2 << 14) /* Power-down: 100kOhm to GND */
21#define AD5620_PWRDWN_TRISTATE (0x3 << 14) /* Power-down: Three-state */
22
23#define AD5660_LOAD (0x0 << 16) /* Load and update Norm Operation*/
24#define AD5660_PWRDWN_1k (0x1 << 16) /* Power-down: 1kOhm to GND */
25#define AD5660_PWRDWN_100k (0x2 << 16) /* Power-down: 100kOhm to GND */
26#define AD5660_PWRDWN_TRISTATE (0x3 << 16) /* Power-down: Three-state */
27
28#define MODE_PWRDWN_1k 0x1
29#define MODE_PWRDWN_100k 0x2
30#define MODE_PWRDWN_TRISTATE 0x3
31
32/**
33 * struct ad5446_state - driver instance specific data
34 * @spi: spi_device
35 * @chip_info: chip model specific constants, available modes etc
36 * @reg: supply regulator
37 * @vref_mv: actual reference voltage used
38 */
39
40struct ad5446_state {
41 struct spi_device *spi;
42 const struct ad5446_chip_info *chip_info;
43 struct regulator *reg;
44 unsigned short vref_mv;
45 unsigned cached_val;
46 unsigned pwr_down_mode;
47 unsigned pwr_down;
48};
49
50/**
51 * struct ad5446_chip_info - chip specific information
52 * @channel: channel spec for the DAC
53 * @int_vref_mv: AD5620/40/60: the internal reference voltage
54 * @write: chip specific helper function to write to the register
55 */
56
57struct ad5446_chip_info {
58 struct iio_chan_spec channel;
59 u16 int_vref_mv;
60 int (*write)(struct ad5446_state *st, unsigned val);
61};
62
63/**
64 * ad5446_supported_device_ids:
65 * The AD5620/40/60 parts are available in different fixed internal reference
66 * voltage options. The actual part numbers may look differently
67 * (and a bit cryptic), however this style is used to make clear which
68 * parts are supported here.
69 */
70
71enum ad5446_supported_device_ids {
72 ID_AD5444,
73 ID_AD5446,
74 ID_AD5450,
75 ID_AD5451,
76 ID_AD5541A,
77 ID_AD5512A,
78 ID_AD5553,
79 ID_AD5601,
80 ID_AD5611,
81 ID_AD5621,
82 ID_AD5620_2500,
83 ID_AD5620_1250,
84 ID_AD5640_2500,
85 ID_AD5640_1250,
86 ID_AD5660_2500,
87 ID_AD5660_1250,
88 ID_AD5662,
89};
90
91#endif /* IIO_DAC_AD5446_H_ */
drivers/iio/dac/ad5755.c+650−0
@@ -0,0 +1,650 @@
1/*
2 * AD5755, AD5755-1, AD5757, AD5735, AD5737 Digital to analog converters driver
3 *
4 * Copyright 2012 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/device.h>
10#include <linux/err.h>
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/spi/spi.h>
14#include <linux/slab.h>
15#include <linux/sysfs.h>
16#include <linux/delay.h>
17#include <linux/iio/iio.h>
18#include <linux/iio/sysfs.h>
19#include <linux/platform_data/ad5755.h>
20
21#define AD5755_NUM_CHANNELS 4
22
23#define AD5755_ADDR(x) ((x) << 16)
24
25#define AD5755_WRITE_REG_DATA(chan) (chan)
26#define AD5755_WRITE_REG_GAIN(chan) (0x08 | (chan))
27#define AD5755_WRITE_REG_OFFSET(chan) (0x10 | (chan))
28#define AD5755_WRITE_REG_CTRL(chan) (0x1c | (chan))
29
30#define AD5755_READ_REG_DATA(chan) (chan)
31#define AD5755_READ_REG_CTRL(chan) (0x4 | (chan))
32#define AD5755_READ_REG_GAIN(chan) (0x8 | (chan))
33#define AD5755_READ_REG_OFFSET(chan) (0xc | (chan))
34#define AD5755_READ_REG_CLEAR(chan) (0x10 | (chan))
35#define AD5755_READ_REG_SLEW(chan) (0x14 | (chan))
36#define AD5755_READ_REG_STATUS 0x18
37#define AD5755_READ_REG_MAIN 0x19
38#define AD5755_READ_REG_DC_DC 0x1a
39
40#define AD5755_CTRL_REG_SLEW 0x0
41#define AD5755_CTRL_REG_MAIN 0x1
42#define AD5755_CTRL_REG_DAC 0x2
43#define AD5755_CTRL_REG_DC_DC 0x3
44#define AD5755_CTRL_REG_SW 0x4
45
46#define AD5755_READ_FLAG 0x800000
47
48#define AD5755_NOOP 0x1CE000
49
50#define AD5755_DAC_INT_EN BIT(8)
51#define AD5755_DAC_CLR_EN BIT(7)
52#define AD5755_DAC_OUT_EN BIT(6)
53#define AD5755_DAC_INT_CURRENT_SENSE_RESISTOR BIT(5)
54#define AD5755_DAC_DC_DC_EN BIT(4)
55#define AD5755_DAC_VOLTAGE_OVERRANGE_EN BIT(3)
56
57#define AD5755_DC_DC_MAXV 0
58#define AD5755_DC_DC_FREQ_SHIFT 2
59#define AD5755_DC_DC_PHASE_SHIFT 4
60#define AD5755_EXT_DC_DC_COMP_RES BIT(6)
61
62#define AD5755_SLEW_STEP_SIZE_SHIFT 0
63#define AD5755_SLEW_RATE_SHIFT 3
64#define AD5755_SLEW_ENABLE BIT(12)
65
66/**
67 * struct ad5755_chip_info - chip specific information
68 * @channel_template: channel specification
69 * @calib_shift: shift for the calibration data registers
70 * @has_voltage_out: whether the chip has voltage outputs
71 */
72struct ad5755_chip_info {
73 const struct iio_chan_spec channel_template;
74 unsigned int calib_shift;
75 bool has_voltage_out;
76};
77
78/**
79 * struct ad5755_state - driver instance specific data
80 * @spi: spi device the driver is attached to
81 * @chip_info: chip model specific constants, available modes etc
82 * @pwr_down: bitmask which contains hether a channel is powered down or not
83 * @ctrl: software shadow of the channel ctrl registers
84 * @channels: iio channel spec for the device
85 * @data: spi transfer buffers
86 */
87struct ad5755_state {
88 struct spi_device *spi;
89 const struct ad5755_chip_info *chip_info;
90 unsigned int pwr_down;
91 unsigned int ctrl[AD5755_NUM_CHANNELS];
92 struct iio_chan_spec channels[AD5755_NUM_CHANNELS];
93
94 /*
95 * DMA (thus cache coherency maintenance) requires the
96 * transfer buffers to live in their own cache lines.
97 */
98
99 union {
100 u32 d32;
101 u8 d8[4];
102 } data[2] ____cacheline_aligned;
103};
104
105enum ad5755_type {
106 ID_AD5755,
107 ID_AD5757,
108 ID_AD5735,
109 ID_AD5737,
110};
111
112static int ad5755_write_unlocked(struct iio_dev *indio_dev,
113 unsigned int reg, unsigned int val)
114{
115 struct ad5755_state *st = iio_priv(indio_dev);
116
117 st->data[0].d32 = cpu_to_be32((reg << 16) | val);
118
119 return spi_write(st->spi, &st->data[0].d8[1], 3);
120}
121
122static int ad5755_write_ctrl_unlocked(struct iio_dev *indio_dev,
123 unsigned int channel, unsigned int reg, unsigned int val)
124{
125 return ad5755_write_unlocked(indio_dev,
126 AD5755_WRITE_REG_CTRL(channel), (reg << 13) | val);
127}
128
129static int ad5755_write(struct iio_dev *indio_dev, unsigned int reg,
130 unsigned int val)
131{
132 int ret;
133
134 mutex_lock(&indio_dev->mlock);
135 ret = ad5755_write_unlocked(indio_dev, reg, val);
136 mutex_unlock(&indio_dev->mlock);
137
138 return ret;
139}
140
141static int ad5755_write_ctrl(struct iio_dev *indio_dev, unsigned int channel,
142 unsigned int reg, unsigned int val)
143{
144 int ret;
145
146 mutex_lock(&indio_dev->mlock);
147 ret = ad5755_write_ctrl_unlocked(indio_dev, channel, reg, val);
148 mutex_unlock(&indio_dev->mlock);
149
150 return ret;
151}
152
153static int ad5755_read(struct iio_dev *indio_dev, unsigned int addr)
154{
155 struct ad5755_state *st = iio_priv(indio_dev);
156 struct spi_message m;
157 int ret;
158 struct spi_transfer t[] = {
159 {
160 .tx_buf = &st->data[0].d8[1],
161 .len = 3,
162 .cs_change = 1,
163 }, {
164 .tx_buf = &st->data[1].d8[1],
165 .rx_buf = &st->data[1].d8[1],
166 .len = 3,
167 },
168 };
169
170 spi_message_init(&m);
171 spi_message_add_tail(&t[0], &m);
172 spi_message_add_tail(&t[1], &m);
173
174 mutex_lock(&indio_dev->mlock);
175
176 st->data[0].d32 = cpu_to_be32(AD5755_READ_FLAG | (addr << 16));
177 st->data[1].d32 = cpu_to_be32(AD5755_NOOP);
178
179 ret = spi_sync(st->spi, &m);
180 if (ret >= 0)
181 ret = be32_to_cpu(st->data[1].d32) & 0xffff;
182
183 mutex_unlock(&indio_dev->mlock);
184
185 return ret;
186}
187
188static int ad5755_update_dac_ctrl(struct iio_dev *indio_dev,
189 unsigned int channel, unsigned int set, unsigned int clr)
190{
191 struct ad5755_state *st = iio_priv(indio_dev);
192 int ret;
193
194 st->ctrl[channel] |= set;
195 st->ctrl[channel] &= ~clr;
196
197 ret = ad5755_write_ctrl_unlocked(indio_dev, channel,
198 AD5755_CTRL_REG_DAC, st->ctrl[channel]);
199
200 return ret;
201}
202
203static int ad5755_set_channel_pwr_down(struct iio_dev *indio_dev,
204 unsigned int channel, bool pwr_down)
205{
206 struct ad5755_state *st = iio_priv(indio_dev);
207 unsigned int mask = BIT(channel);
208
209 mutex_lock(&indio_dev->mlock);
210
211 if ((bool)(st->pwr_down & mask) == pwr_down)
212 goto out_unlock;
213
214 if (!pwr_down) {
215 st->pwr_down &= ~mask;
216 ad5755_update_dac_ctrl(indio_dev, channel,
217 AD5755_DAC_INT_EN | AD5755_DAC_DC_DC_EN, 0);
218 udelay(200);
219 ad5755_update_dac_ctrl(indio_dev, channel,
220 AD5755_DAC_OUT_EN, 0);
221 } else {
222 st->pwr_down |= mask;
223 ad5755_update_dac_ctrl(indio_dev, channel,
224 0, AD5755_DAC_INT_EN | AD5755_DAC_OUT_EN |
225 AD5755_DAC_DC_DC_EN);
226 }
227
228out_unlock:
229 mutex_unlock(&indio_dev->mlock);
230
231 return 0;
232}
233
234static const int ad5755_min_max_table[][2] = {
235 [AD5755_MODE_VOLTAGE_0V_5V] = { 0, 5000 },
236 [AD5755_MODE_VOLTAGE_0V_10V] = { 0, 10000 },
237 [AD5755_MODE_VOLTAGE_PLUSMINUS_5V] = { -5000, 5000 },
238 [AD5755_MODE_VOLTAGE_PLUSMINUS_10V] = { -10000, 10000 },
239 [AD5755_MODE_CURRENT_4mA_20mA] = { 4, 20 },
240 [AD5755_MODE_CURRENT_0mA_20mA] = { 0, 20 },
241 [AD5755_MODE_CURRENT_0mA_24mA] = { 0, 24 },
242};
243
244static void ad5755_get_min_max(struct ad5755_state *st,
245 struct iio_chan_spec const *chan, int *min, int *max)
246{
247 enum ad5755_mode mode = st->ctrl[chan->channel] & 7;
248 *min = ad5755_min_max_table[mode][0];
249 *max = ad5755_min_max_table[mode][1];
250}
251
252static inline int ad5755_get_offset(struct ad5755_state *st,
253 struct iio_chan_spec const *chan)
254{
255 int min, max;
256
257 ad5755_get_min_max(st, chan, &min, &max);
258 return (min * (1 << chan->scan_type.realbits)) / (max - min);
259}
260
261static inline int ad5755_get_scale(struct ad5755_state *st,
262 struct iio_chan_spec const *chan)
263{
264 int min, max;
265
266 ad5755_get_min_max(st, chan, &min, &max);
267 return ((max - min) * 1000000000ULL) >> chan->scan_type.realbits;
268}
269
270static int ad5755_chan_reg_info(struct ad5755_state *st,
271 struct iio_chan_spec const *chan, long info, bool write,
272 unsigned int *reg, unsigned int *shift, unsigned int *offset)
273{
274 switch (info) {
275 case IIO_CHAN_INFO_RAW:
276 if (write)
277 *reg = AD5755_WRITE_REG_DATA(chan->address);
278 else
279 *reg = AD5755_READ_REG_DATA(chan->address);
280 *shift = chan->scan_type.shift;
281 *offset = 0;
282 break;
283 case IIO_CHAN_INFO_CALIBBIAS:
284 if (write)
285 *reg = AD5755_WRITE_REG_OFFSET(chan->address);
286 else
287 *reg = AD5755_READ_REG_OFFSET(chan->address);
288 *shift = st->chip_info->calib_shift;
289 *offset = 32768;
290 break;
291 case IIO_CHAN_INFO_CALIBSCALE:
292 if (write)
293 *reg = AD5755_WRITE_REG_GAIN(chan->address);
294 else
295 *reg = AD5755_READ_REG_GAIN(chan->address);
296 *shift = st->chip_info->calib_shift;
297 *offset = 0;
298 break;
299 default:
300 return -EINVAL;
301 }
302
303 return 0;
304}
305
306static int ad5755_read_raw(struct iio_dev *indio_dev,
307 const struct iio_chan_spec *chan, int *val, int *val2, long info)
308{
309 struct ad5755_state *st = iio_priv(indio_dev);
310 unsigned int reg, shift, offset;
311 int ret;
312
313 switch (info) {
314 case IIO_CHAN_INFO_SCALE:
315 *val = 0;
316 *val2 = ad5755_get_scale(st, chan);
317 return IIO_VAL_INT_PLUS_NANO;
318 case IIO_CHAN_INFO_OFFSET:
319 *val = ad5755_get_offset(st, chan);
320 return IIO_VAL_INT;
321 default:
322 ret = ad5755_chan_reg_info(st, chan, info, false,
323 &reg, &shift, &offset);
324 if (ret)
325 return ret;
326
327 ret = ad5755_read(indio_dev, reg);
328 if (ret < 0)
329 return ret;
330
331 *val = (ret - offset) >> shift;
332
333 return IIO_VAL_INT;
334 }
335
336 return -EINVAL;
337}
338
339static int ad5755_write_raw(struct iio_dev *indio_dev,
340 const struct iio_chan_spec *chan, int val, int val2, long info)
341{
342 struct ad5755_state *st = iio_priv(indio_dev);
343 unsigned int shift, reg, offset;
344 int ret;
345
346 ret = ad5755_chan_reg_info(st, chan, info, true,
347 &reg, &shift, &offset);
348 if (ret)
349 return ret;
350
351 val <<= shift;
352 val += offset;
353
354 if (val < 0 || val > 0xffff)
355 return -EINVAL;
356
357 return ad5755_write(indio_dev, reg, val);
358}
359
360static ssize_t ad5755_read_powerdown(struct iio_dev *indio_dev, uintptr_t priv,
361 const struct iio_chan_spec *chan, char *buf)
362{
363 struct ad5755_state *st = iio_priv(indio_dev);
364
365 return sprintf(buf, "%d\n",
366 (bool)(st->pwr_down & (1 << chan->channel)));
367}
368
369static ssize_t ad5755_write_powerdown(struct iio_dev *indio_dev, uintptr_t priv,
370 struct iio_chan_spec const *chan, const char *buf, size_t len)
371{
372 bool pwr_down;
373 int ret;
374
375 ret = strtobool(buf, &pwr_down);
376 if (ret)
377 return ret;
378
379 ret = ad5755_set_channel_pwr_down(indio_dev, chan->channel, pwr_down);
380 return ret ? ret : len;
381}
382
383static const struct iio_info ad5755_info = {
384 .read_raw = ad5755_read_raw,
385 .write_raw = ad5755_write_raw,
386 .driver_module = THIS_MODULE,
387};
388
389static const struct iio_chan_spec_ext_info ad5755_ext_info[] = {
390 {
391 .name = "powerdown",
392 .read = ad5755_read_powerdown,
393 .write = ad5755_write_powerdown,
394 },
395 { },
396};
397
398#define AD5755_CHANNEL(_bits) { \
399 .indexed = 1, \
400 .output = 1, \
401 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
402 IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \
403 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \
404 IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \
405 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \
406 .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \
407 .ext_info = ad5755_ext_info, \
408}
409
410static const struct ad5755_chip_info ad5755_chip_info_tbl[] = {
411 [ID_AD5735] = {
412 .channel_template = AD5755_CHANNEL(14),
413 .has_voltage_out = true,
414 .calib_shift = 4,
415 },
416 [ID_AD5737] = {
417 .channel_template = AD5755_CHANNEL(14),
418 .has_voltage_out = false,
419 .calib_shift = 4,
420 },
421 [ID_AD5755] = {
422 .channel_template = AD5755_CHANNEL(16),
423 .has_voltage_out = true,
424 .calib_shift = 0,
425 },
426 [ID_AD5757] = {
427 .channel_template = AD5755_CHANNEL(16),
428 .has_voltage_out = false,
429 .calib_shift = 0,
430 },
431};
432
433static bool ad5755_is_valid_mode(struct ad5755_state *st, enum ad5755_mode mode)
434{
435 switch (mode) {
436 case AD5755_MODE_VOLTAGE_0V_5V:
437 case AD5755_MODE_VOLTAGE_0V_10V:
438 case AD5755_MODE_VOLTAGE_PLUSMINUS_5V:
439 case AD5755_MODE_VOLTAGE_PLUSMINUS_10V:
440 return st->chip_info->has_voltage_out;
441 case AD5755_MODE_CURRENT_4mA_20mA:
442 case AD5755_MODE_CURRENT_0mA_20mA:
443 case AD5755_MODE_CURRENT_0mA_24mA:
444 return true;
445 default:
446 return false;
447 }
448}
449
450static int __devinit ad5755_setup_pdata(struct iio_dev *indio_dev,
451 const struct ad5755_platform_data *pdata)
452{
453 struct ad5755_state *st = iio_priv(indio_dev);
454 unsigned int val;
455 unsigned int i;
456 int ret;
457
458 if (pdata->dc_dc_phase > AD5755_DC_DC_PHASE_90_DEGREE ||
459 pdata->dc_dc_freq > AD5755_DC_DC_FREQ_650kHZ ||
460 pdata->dc_dc_maxv > AD5755_DC_DC_MAXV_29V5)
461 return -EINVAL;
462
463 val = pdata->dc_dc_maxv << AD5755_DC_DC_MAXV;
464 val |= pdata->dc_dc_freq << AD5755_DC_DC_FREQ_SHIFT;
465 val |= pdata->dc_dc_phase << AD5755_DC_DC_PHASE_SHIFT;
466 if (pdata->ext_dc_dc_compenstation_resistor)
467 val |= AD5755_EXT_DC_DC_COMP_RES;
468
469 ret = ad5755_write_ctrl(indio_dev, 0, AD5755_CTRL_REG_DC_DC, val);
470 if (ret < 0)
471 return ret;
472
473 for (i = 0; i < ARRAY_SIZE(pdata->dac); ++i) {
474 val = pdata->dac[i].slew.step_size <<
475 AD5755_SLEW_STEP_SIZE_SHIFT;
476 val |= pdata->dac[i].slew.rate <<
477 AD5755_SLEW_RATE_SHIFT;
478 if (pdata->dac[i].slew.enable)
479 val |= AD5755_SLEW_ENABLE;
480
481 ret = ad5755_write_ctrl(indio_dev, i,
482 AD5755_CTRL_REG_SLEW, val);
483 if (ret < 0)
484 return ret;
485 }
486
487 for (i = 0; i < ARRAY_SIZE(pdata->dac); ++i) {
488 if (!ad5755_is_valid_mode(st, pdata->dac[i].mode))
489 return -EINVAL;
490
491 val = 0;
492 if (!pdata->dac[i].ext_current_sense_resistor)
493 val |= AD5755_DAC_INT_CURRENT_SENSE_RESISTOR;
494 if (pdata->dac[i].enable_voltage_overrange)
495 val |= AD5755_DAC_VOLTAGE_OVERRANGE_EN;
496 val |= pdata->dac[i].mode;
497
498 ret = ad5755_update_dac_ctrl(indio_dev, i, val, 0);
499 if (ret < 0)
500 return ret;
501 }
502
503 return 0;
504}
505
506static bool __devinit ad5755_is_voltage_mode(enum ad5755_mode mode)
507{
508 switch (mode) {
509 case AD5755_MODE_VOLTAGE_0V_5V:
510 case AD5755_MODE_VOLTAGE_0V_10V:
511 case AD5755_MODE_VOLTAGE_PLUSMINUS_5V:
512 case AD5755_MODE_VOLTAGE_PLUSMINUS_10V:
513 return true;
514 default:
515 return false;
516 }
517}
518
519static int __devinit ad5755_init_channels(struct iio_dev *indio_dev,
520 const struct ad5755_platform_data *pdata)
521{
522 struct ad5755_state *st = iio_priv(indio_dev);
523 struct iio_chan_spec *channels = st->channels;
524 unsigned int i;
525
526 for (i = 0; i < AD5755_NUM_CHANNELS; ++i) {
527 channels[i] = st->chip_info->channel_template;
528 channels[i].channel = i;
529 channels[i].address = i;
530 if (pdata && ad5755_is_voltage_mode(pdata->dac[i].mode))
531 channels[i].type = IIO_VOLTAGE;
532 else
533 channels[i].type = IIO_CURRENT;
534 }
535
536 indio_dev->channels = channels;
537
538 return 0;
539}
540
541#define AD5755_DEFAULT_DAC_PDATA { \
542 .mode = AD5755_MODE_CURRENT_4mA_20mA, \
543 .ext_current_sense_resistor = true, \
544 .enable_voltage_overrange = false, \
545 .slew = { \
546 .enable = false, \
547 .rate = AD5755_SLEW_RATE_64k, \
548 .step_size = AD5755_SLEW_STEP_SIZE_1, \
549 }, \
550 }
551
552static const struct ad5755_platform_data ad5755_default_pdata = {
553 .ext_dc_dc_compenstation_resistor = false,
554 .dc_dc_phase = AD5755_DC_DC_PHASE_ALL_SAME_EDGE,
555 .dc_dc_freq = AD5755_DC_DC_FREQ_410kHZ,
556 .dc_dc_maxv = AD5755_DC_DC_MAXV_23V,
557 .dac = {
558 [0] = AD5755_DEFAULT_DAC_PDATA,
559 [1] = AD5755_DEFAULT_DAC_PDATA,
560 [2] = AD5755_DEFAULT_DAC_PDATA,
561 [3] = AD5755_DEFAULT_DAC_PDATA,
562 },
563};
564
565static int __devinit ad5755_probe(struct spi_device *spi)
566{
567 enum ad5755_type type = spi_get_device_id(spi)->driver_data;
568 const struct ad5755_platform_data *pdata = dev_get_platdata(&spi->dev);
569 struct iio_dev *indio_dev;
570 struct ad5755_state *st;
571 int ret;
572
573 indio_dev = iio_device_alloc(sizeof(*st));
574 if (indio_dev == NULL) {
575 dev_err(&spi->dev, "Failed to allocate iio device\n");
576 return -ENOMEM;
577 }
578
579 st = iio_priv(indio_dev);
580 spi_set_drvdata(spi, indio_dev);
581
582 st->chip_info = &ad5755_chip_info_tbl[type];
583 st->spi = spi;
584 st->pwr_down = 0xf;
585
586 indio_dev->dev.parent = &spi->dev;
587 indio_dev->name = spi_get_device_id(spi)->name;
588 indio_dev->info = &ad5755_info;
589 indio_dev->modes = INDIO_DIRECT_MODE;
590 indio_dev->num_channels = AD5755_NUM_CHANNELS;
591
592 if (!pdata)
593 pdata = &ad5755_default_pdata;
594
595 ret = ad5755_init_channels(indio_dev, pdata);
596 if (ret)
597 goto error_free;
598
599 ret = ad5755_setup_pdata(indio_dev, pdata);
600 if (ret)
601 goto error_free;
602
603 ret = iio_device_register(indio_dev);
604 if (ret) {
605 dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
606 goto error_free;
607 }
608
609 return 0;
610
611error_free:
612 iio_device_free(indio_dev);
613
614 return ret;
615}
616
617static int __devexit ad5755_remove(struct spi_device *spi)
618{
619 struct iio_dev *indio_dev = spi_get_drvdata(spi);
620
621 iio_device_unregister(indio_dev);
622 iio_device_free(indio_dev);
623
624 return 0;
625}
626
627static const struct spi_device_id ad5755_id[] = {
628 { "ad5755", ID_AD5755 },
629 { "ad5755-1", ID_AD5755 },
630 { "ad5757", ID_AD5757 },
631 { "ad5735", ID_AD5735 },
632 { "ad5737", ID_AD5737 },
633 {}
634};
635MODULE_DEVICE_TABLE(spi, ad5755_id);
636
637static struct spi_driver ad5755_driver = {
638 .driver = {
639 .name = "ad5755",
640 .owner = THIS_MODULE,
641 },
642 .probe = ad5755_probe,
643 .remove = __devexit_p(ad5755_remove),
644 .id_table = ad5755_id,
645};
646module_spi_driver(ad5755_driver);
647
648MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
649MODULE_DESCRIPTION("Analog Devices AD5755/55-1/57/35/37 DAC");
650MODULE_LICENSE("GPL v2");
drivers/iio/gyro/Kconfig+16−0
@@ -0,0 +1,16 @@
1#
2# IIO Digital Gyroscope Sensor drivers configuration
3#
4menu "Digital gyroscope sensors"
5
6config HID_SENSOR_GYRO_3D
7 depends on HID_SENSOR_HUB
8 select IIO_BUFFER
9 select IIO_TRIGGERED_BUFFER
10 select HID_SENSOR_IIO_COMMON
11 tristate "HID Gyroscope 3D"
12 help
13 Say yes here to build support for the HID SENSOR
14 Gyroscope 3D.
15
16endmenu
drivers/iio/gyro/Makefile+5−0
@@ -0,0 +1,5 @@
1#
2# Makefile for industrial I/O gyroscope sensor drivers
3#
4
5obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o
drivers/iio/gyro/hid-sensor-gyro-3d.c+418−0
@@ -0,0 +1,418 @@
1/*
2 * HID Sensors Driver
3 * Copyright (c) 2012, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 */
19#include <linux/device.h>
20#include <linux/platform_device.h>
21#include <linux/module.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/slab.h>
25#include <linux/hid-sensor-hub.h>
26#include <linux/iio/iio.h>
27#include <linux/iio/sysfs.h>
28#include <linux/iio/buffer.h>
29#include <linux/iio/trigger_consumer.h>
30#include <linux/iio/triggered_buffer.h>
31#include "../common/hid-sensors/hid-sensor-attributes.h"
32#include "../common/hid-sensors/hid-sensor-trigger.h"
33
34/*Format: HID-SENSOR-usage_id_in_hex*/
35/*Usage ID from spec for Gyro-3D: 0x200076*/
36#define DRIVER_NAME "HID-SENSOR-200076"
37
38enum gyro_3d_channel {
39 CHANNEL_SCAN_INDEX_X,
40 CHANNEL_SCAN_INDEX_Y,
41 CHANNEL_SCAN_INDEX_Z,
42 GYRO_3D_CHANNEL_MAX,
43};
44
45struct gyro_3d_state {
46 struct hid_sensor_hub_callbacks callbacks;
47 struct hid_sensor_iio_common common_attributes;
48 struct hid_sensor_hub_attribute_info gyro[GYRO_3D_CHANNEL_MAX];
49 u32 gyro_val[GYRO_3D_CHANNEL_MAX];
50};
51
52static const u32 gyro_3d_addresses[GYRO_3D_CHANNEL_MAX] = {
53 HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS,
54 HID_USAGE_SENSOR_ANGL_VELOCITY_Y_AXIS,
55 HID_USAGE_SENSOR_ANGL_VELOCITY_Z_AXIS
56};
57
58/* Channel definitions */
59static const struct iio_chan_spec gyro_3d_channels[] = {
60 {
61 .type = IIO_ANGL_VEL,
62 .modified = 1,
63 .channel2 = IIO_MOD_X,
64 .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
65 IIO_CHAN_INFO_SCALE_SHARED_BIT |
66 IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
67 IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
68 .scan_index = CHANNEL_SCAN_INDEX_X,
69 }, {
70 .type = IIO_ANGL_VEL,
71 .modified = 1,
72 .channel2 = IIO_MOD_Y,
73 .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
74 IIO_CHAN_INFO_SCALE_SHARED_BIT |
75 IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
76 IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
77 .scan_index = CHANNEL_SCAN_INDEX_Y,
78 }, {
79 .type = IIO_ANGL_VEL,
80 .modified = 1,
81 .channel2 = IIO_MOD_Z,
82 .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
83 IIO_CHAN_INFO_SCALE_SHARED_BIT |
84 IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
85 IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
86 .scan_index = CHANNEL_SCAN_INDEX_Z,
87 }
88};
89
90/* Adjust channel real bits based on report descriptor */
91static void gyro_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels,
92 int channel, int size)
93{
94 channels[channel].scan_type.sign = 's';
95 /* Real storage bits will change based on the report desc. */
96 channels[channel].scan_type.realbits = size * 8;
97 /* Maximum size of a sample to capture is u32 */
98 channels[channel].scan_type.storagebits = sizeof(u32) * 8;
99}
100
101/* Channel read_raw handler */
102static int gyro_3d_read_raw(struct iio_dev *indio_dev,
103 struct iio_chan_spec const *chan,
104 int *val, int *val2,
105 long mask)
106{
107 struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
108 int report_id = -1;
109 u32 address;
110 int ret;
111 int ret_type;
112
113 *val = 0;
114 *val2 = 0;
115 switch (mask) {
116 case 0:
117 report_id = gyro_state->gyro[chan->scan_index].report_id;
118 address = gyro_3d_addresses[chan->scan_index];
119 if (report_id >= 0)
120 *val = sensor_hub_input_attr_get_raw_value(
121 gyro_state->common_attributes.hsdev,
122 HID_USAGE_SENSOR_GYRO_3D, address,
123 report_id);
124 else {
125 *val = 0;
126 return -EINVAL;
127 }
128 ret_type = IIO_VAL_INT;
129 break;
130 case IIO_CHAN_INFO_SCALE:
131 *val = gyro_state->gyro[CHANNEL_SCAN_INDEX_X].units;
132 ret_type = IIO_VAL_INT;
133 break;
134 case IIO_CHAN_INFO_OFFSET:
135 *val = hid_sensor_convert_exponent(
136 gyro_state->gyro[CHANNEL_SCAN_INDEX_X].unit_expo);
137 ret_type = IIO_VAL_INT;
138 break;
139 case IIO_CHAN_INFO_SAMP_FREQ:
140 ret = hid_sensor_read_samp_freq_value(
141 &gyro_state->common_attributes, val, val2);
142 ret_type = IIO_VAL_INT_PLUS_MICRO;
143 break;
144 case IIO_CHAN_INFO_HYSTERESIS:
145 ret = hid_sensor_read_raw_hyst_value(
146 &gyro_state->common_attributes, val, val2);
147 ret_type = IIO_VAL_INT_PLUS_MICRO;
148 break;
149 default:
150 ret_type = -EINVAL;
151 break;
152 }
153
154 return ret_type;
155}
156
157/* Channel write_raw handler */
158static int gyro_3d_write_raw(struct iio_dev *indio_dev,
159 struct iio_chan_spec const *chan,
160 int val,
161 int val2,
162 long mask)
163{
164 struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
165 int ret = 0;
166
167 switch (mask) {
168 case IIO_CHAN_INFO_SAMP_FREQ:
169 ret = hid_sensor_write_samp_freq_value(
170 &gyro_state->common_attributes, val, val2);
171 break;
172 case IIO_CHAN_INFO_HYSTERESIS:
173 ret = hid_sensor_write_raw_hyst_value(
174 &gyro_state->common_attributes, val, val2);
175 break;
176 default:
177 ret = -EINVAL;
178 }
179
180 return ret;
181}
182
183static int gyro_3d_write_raw_get_fmt(struct iio_dev *indio_dev,
184 struct iio_chan_spec const *chan,
185 long mask)
186{
187 return IIO_VAL_INT_PLUS_MICRO;
188}
189
190static const struct iio_info gyro_3d_info = {
191 .driver_module = THIS_MODULE,
192 .read_raw = &gyro_3d_read_raw,
193 .write_raw = &gyro_3d_write_raw,
194 .write_raw_get_fmt = &gyro_3d_write_raw_get_fmt,
195};
196
197/* Function to push data to buffer */
198static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
199{
200 struct iio_buffer *buffer = indio_dev->buffer;
201 int datum_sz;
202
203 dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
204 if (!buffer) {
205 dev_err(&indio_dev->dev, "Buffer == NULL\n");
206 return;
207 }
208 datum_sz = buffer->access->get_bytes_per_datum(buffer);
209 if (len > datum_sz) {
210 dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
211 datum_sz);
212 return;
213 }
214 iio_push_to_buffer(buffer, (u8 *)data);
215}
216
217/* Callback handler to send event after all samples are received and captured */
218static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev,
219 unsigned usage_id,
220 void *priv)
221{
222 struct iio_dev *indio_dev = platform_get_drvdata(priv);
223 struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
224
225 dev_dbg(&indio_dev->dev, "gyro_3d_proc_event [%d]\n",
226 gyro_state->common_attributes.data_ready);
227 if (gyro_state->common_attributes.data_ready)
228 hid_sensor_push_data(indio_dev,
229 (u8 *)gyro_state->gyro_val,
230 sizeof(gyro_state->gyro_val));
231
232 return 0;
233}
234
235/* Capture samples in local storage */
236static int gyro_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
237 unsigned usage_id,
238 size_t raw_len, char *raw_data,
239 void *priv)
240{
241 struct iio_dev *indio_dev = platform_get_drvdata(priv);
242 struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
243 int offset;
244 int ret = -EINVAL;
245
246 switch (usage_id) {
247 case HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS:
248 case HID_USAGE_SENSOR_ANGL_VELOCITY_Y_AXIS:
249 case HID_USAGE_SENSOR_ANGL_VELOCITY_Z_AXIS:
250 offset = usage_id - HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS;
251 gyro_state->gyro_val[CHANNEL_SCAN_INDEX_X + offset] =
252 *(u32 *)raw_data;
253 ret = 0;
254 break;
255 default:
256 break;
257 }
258
259 return ret;
260}
261
262/* Parse report which is specific to an usage id*/
263static int gyro_3d_parse_report(struct platform_device *pdev,
264 struct hid_sensor_hub_device *hsdev,
265 struct iio_chan_spec *channels,
266 unsigned usage_id,
267 struct gyro_3d_state *st)
268{
269 int ret;
270 int i;
271
272 for (i = 0; i <= CHANNEL_SCAN_INDEX_Z; ++i) {
273 ret = sensor_hub_input_get_attribute_info(hsdev,
274 HID_INPUT_REPORT,
275 usage_id,
276 HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS + i,
277 &st->gyro[CHANNEL_SCAN_INDEX_X + i]);
278 if (ret < 0)
279 break;
280 gyro_3d_adjust_channel_bit_mask(channels,
281 CHANNEL_SCAN_INDEX_X + i,
282 st->gyro[CHANNEL_SCAN_INDEX_X + i].size);
283 }
284 dev_dbg(&pdev->dev, "gyro_3d %x:%x, %x:%x, %x:%x\n",
285 st->gyro[0].index,
286 st->gyro[0].report_id,
287 st->gyro[1].index, st->gyro[1].report_id,
288 st->gyro[2].index, st->gyro[2].report_id);
289
290 return ret;
291}
292
293/* Function to initialize the processing for usage id */
294static int __devinit hid_gyro_3d_probe(struct platform_device *pdev)
295{
296 int ret = 0;
297 static const char *name = "gyro_3d";
298 struct iio_dev *indio_dev;
299 struct gyro_3d_state *gyro_state;
300 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
301 struct iio_chan_spec *channels;
302
303 indio_dev = iio_device_alloc(sizeof(struct gyro_3d_state));
304 if (indio_dev == NULL) {
305 ret = -ENOMEM;
306 goto error_ret;
307 }
308 platform_set_drvdata(pdev, indio_dev);
309
310 gyro_state = iio_priv(indio_dev);
311 gyro_state->common_attributes.hsdev = hsdev;
312 gyro_state->common_attributes.pdev = pdev;
313
314 ret = hid_sensor_parse_common_attributes(hsdev,
315 HID_USAGE_SENSOR_GYRO_3D,
316 &gyro_state->common_attributes);
317 if (ret) {
318 dev_err(&pdev->dev, "failed to setup common attributes\n");
319 goto error_free_dev;
320 }
321
322 channels = kmemdup(gyro_3d_channels,
323 sizeof(gyro_3d_channels),
324 GFP_KERNEL);
325 if (!channels) {
326 dev_err(&pdev->dev, "failed to duplicate channels\n");
327 goto error_free_dev;
328 }
329
330 ret = gyro_3d_parse_report(pdev, hsdev, channels,
331 HID_USAGE_SENSOR_GYRO_3D, gyro_state);
332 if (ret) {
333 dev_err(&pdev->dev, "failed to setup attributes\n");
334 goto error_free_dev_mem;
335 }
336
337 indio_dev->channels = channels;
338 indio_dev->num_channels = ARRAY_SIZE(gyro_3d_channels);
339 indio_dev->dev.parent = &pdev->dev;
340 indio_dev->info = &gyro_3d_info;
341 indio_dev->name = name;
342 indio_dev->modes = INDIO_DIRECT_MODE;
343
344 ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
345 NULL, NULL);
346 if (ret) {
347 dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
348 goto error_free_dev_mem;
349 }
350 gyro_state->common_attributes.data_ready = false;
351 ret = hid_sensor_setup_trigger(indio_dev, name,
352 &gyro_state->common_attributes);
353 if (ret < 0) {
354 dev_err(&pdev->dev, "trigger setup failed\n");
355 goto error_unreg_buffer_funcs;
356 }
357
358 ret = iio_device_register(indio_dev);
359 if (ret) {
360 dev_err(&pdev->dev, "device register failed\n");
361 goto error_remove_trigger;
362 }
363
364 gyro_state->callbacks.send_event = gyro_3d_proc_event;
365 gyro_state->callbacks.capture_sample = gyro_3d_capture_sample;
366 gyro_state->callbacks.pdev = pdev;
367 ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D,
368 &gyro_state->callbacks);
369 if (ret < 0) {
370 dev_err(&pdev->dev, "callback reg failed\n");
371 goto error_iio_unreg;
372 }
373
374 return ret;
375
376error_iio_unreg:
377 iio_device_unregister(indio_dev);
378error_remove_trigger:
379 hid_sensor_remove_trigger(indio_dev);
380error_unreg_buffer_funcs:
381 iio_triggered_buffer_cleanup(indio_dev);
382error_free_dev_mem:
383 kfree(indio_dev->channels);
384error_free_dev:
385 iio_device_free(indio_dev);
386error_ret:
387 return ret;
388}
389
390/* Function to deinitialize the processing for usage id */
391static int __devinit hid_gyro_3d_remove(struct platform_device *pdev)
392{
393 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
394 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
395
396 sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
397 iio_device_unregister(indio_dev);
398 hid_sensor_remove_trigger(indio_dev);
399 iio_triggered_buffer_cleanup(indio_dev);
400 kfree(indio_dev->channels);
401 iio_device_free(indio_dev);
402
403 return 0;
404}
405
406static struct platform_driver hid_gyro_3d_platform_driver = {
407 .driver = {
408 .name = DRIVER_NAME,
409 .owner = THIS_MODULE,
410 },
411 .probe = hid_gyro_3d_probe,
412 .remove = hid_gyro_3d_remove,
413};
414module_platform_driver(hid_gyro_3d_platform_driver);
415
416MODULE_DESCRIPTION("HID Sensor Gyroscope 3D");
417MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
418MODULE_LICENSE("GPL");
drivers/iio/industrialio-buffer.c+7−8
@@ -422,7 +422,7 @@ ssize_t iio_buffer_store_enable(struct device *dev, · 421 unmodified lines
422 ret = indio_dev->setup_ops->preenable(indio_dev);422 ret = indio_dev->setup_ops->preenable(indio_dev);
423 if (ret) {423 if (ret) {
424 printk(KERN_ERR424 printk(KERN_ERR
425 "Buffer not started:"425 "Buffer not started: "
426 "buffer preenable failed\n");426 "buffer preenable failed\n");
427 goto error_ret;427 goto error_ret;
428 }428 }
@@ -431,12 +431,12 @@ ssize_t iio_buffer_store_enable(struct device *dev, · 2 unmodified lines
431 ret = buffer->access->request_update(buffer);431 ret = buffer->access->request_update(buffer);
432 if (ret) {432 if (ret) {
433 printk(KERN_INFO433 printk(KERN_INFO
434 "Buffer not started:"434 "Buffer not started: "
435 "buffer parameter update failed\n");435 "buffer parameter update failed\n");
436 goto error_ret;436 goto error_ret;
437 }437 }
438 }438 }
439 /* Definitely possible for devices to support both of these.*/439 /* Definitely possible for devices to support both of these. */
440 if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {440 if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
441 if (!indio_dev->trig) {441 if (!indio_dev->trig) {
442 printk(KERN_INFO442 printk(KERN_INFO
@@ -456,7 +456,7 @@ ssize_t iio_buffer_store_enable(struct device *dev, · 13 unmodified lines
456 ret = indio_dev->setup_ops->postenable(indio_dev);456 ret = indio_dev->setup_ops->postenable(indio_dev);
457 if (ret) {457 if (ret) {
458 printk(KERN_INFO458 printk(KERN_INFO
459 "Buffer not started:"459 "Buffer not started: "
460 "postenable failed\n");460 "postenable failed\n");
461 indio_dev->currentmode = previous_mode;461 indio_dev->currentmode = previous_mode;
462 if (indio_dev->setup_ops->postdisable)462 if (indio_dev->setup_ops->postdisable)
@@ -657,7 +657,7 @@ EXPORT_SYMBOL_GPL(iio_scan_mask_query); · 194 unmodified lines
657/**657/**
658 * struct iio_demux_table() - table describing demux memcpy ops658 * struct iio_demux_table() - table describing demux memcpy ops
659 * @from: index to copy from659 * @from: index to copy from
660 * @to: index to copy to660 * @to: index to copy to
661 * @length: how many bytes to copy661 * @length: how many bytes to copy
662 * @l: list head used for management662 * @l: list head used for management
663 */663 */
@@ -682,12 +682,11 @@ static unsigned char *iio_demux(struct iio_buffer *buffer, · 18 unmodified lines
682 return buffer->demux_bounce;682 return buffer->demux_bounce;
683}683}
684 684
685int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data,685int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data)
686 s64 timestamp)
687{686{
688 unsigned char *dataout = iio_demux(buffer, data);687 unsigned char *dataout = iio_demux(buffer, data);
689 688
690 return buffer->access->store_to(buffer, dataout, timestamp);689 return buffer->access->store_to(buffer, dataout);
691}690}
692EXPORT_SYMBOL_GPL(iio_push_to_buffer);691EXPORT_SYMBOL_GPL(iio_push_to_buffer);
693 692
drivers/iio/industrialio-core.c+10−3
@@ -29,7 +29,7 @@ · 28 unmodified lines
29#include <linux/iio/sysfs.h>29#include <linux/iio/sysfs.h>
30#include <linux/iio/events.h>30#include <linux/iio/events.h>
31 31
32/* IDA to assign each registered device a unique id*/32/* IDA to assign each registered device a unique id */
33static DEFINE_IDA(iio_ida);33static DEFINE_IDA(iio_ida);
34 34
35static dev_t iio_devt;35static dev_t iio_devt;
@@ -99,6 +99,7 @@ static const char * const iio_chan_info_postfix[] = { · 63 unmodified lines
99 [IIO_CHAN_INFO_FREQUENCY] = "frequency",99 [IIO_CHAN_INFO_FREQUENCY] = "frequency",
100 [IIO_CHAN_INFO_PHASE] = "phase",100 [IIO_CHAN_INFO_PHASE] = "phase",
101 [IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain",101 [IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain",
102 [IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
102};103};
103 104
104const struct iio_chan_spec105const struct iio_chan_spec
@@ -365,6 +366,7 @@ static ssize_t iio_read_channel_info(struct device *dev, · 260 unmodified lines
365{366{
366 struct iio_dev *indio_dev = dev_to_iio_dev(dev);367 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
367 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);368 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
369 unsigned long long tmp;
368 int val, val2;370 int val, val2;
369 bool scale_db = false;371 bool scale_db = false;
370 int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,372 int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
@@ -390,6 +392,11 @@ static ssize_t iio_read_channel_info(struct device *dev, · 19 unmodified lines
390 return sprintf(buf, "-%d.%09u\n", val, -val2);392 return sprintf(buf, "-%d.%09u\n", val, -val2);
391 else393 else
392 return sprintf(buf, "%d.%09u\n", val, val2);394 return sprintf(buf, "%d.%09u\n", val, val2);
395 case IIO_VAL_FRACTIONAL:
396 tmp = div_s64((s64)val * 1000000000LL, val2);
397 val2 = do_div(tmp, 1000000000LL);
398 val = tmp;
399 return sprintf(buf, "%d.%09u\n", val, val2);
393 default:400 default:
394 return 0;401 return 0;
395 }402 }
@@ -729,7 +736,7 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev) · 333 unmodified lines
729 attrcount = attrcount_orig;736 attrcount = attrcount_orig;
730 /*737 /*
731 * New channel registration method - relies on the fact a group does738 * New channel registration method - relies on the fact a group does
732 * not need to be initialized if it is name is NULL.739 * not need to be initialized if its name is NULL.
733 */740 */
734 if (indio_dev->channels)741 if (indio_dev->channels)
735 for (i = 0; i < indio_dev->num_channels; i++) {742 for (i = 0; i < indio_dev->num_channels; i++) {
@@ -980,6 +987,6 @@ EXPORT_SYMBOL(iio_device_unregister); · 244 unmodified lines
980subsys_initcall(iio_init);987subsys_initcall(iio_init);
981module_exit(iio_exit);988module_exit(iio_exit);
982 989
983MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");990MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
984MODULE_DESCRIPTION("Industrial I/O core");991MODULE_DESCRIPTION("Industrial I/O core");
985MODULE_LICENSE("GPL");992MODULE_LICENSE("GPL");
drivers/iio/inkern.c+128−11
@@ -111,6 +111,7 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name) · 110 unmodified lines
111{111{
112 struct iio_map_internal *c_i = NULL, *c = NULL;112 struct iio_map_internal *c_i = NULL, *c = NULL;
113 struct iio_channel *channel;113 struct iio_channel *channel;
114 int err;
114 115
115 if (name == NULL && channel_name == NULL)116 if (name == NULL && channel_name == NULL)
116 return ERR_PTR(-ENODEV);117 return ERR_PTR(-ENODEV);
@@ -130,18 +131,32 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name) · 13 unmodified lines
130 if (c == NULL)131 if (c == NULL)
131 return ERR_PTR(-ENODEV);132 return ERR_PTR(-ENODEV);
132 133
133 channel = kmalloc(sizeof(*channel), GFP_KERNEL);134 channel = kzalloc(sizeof(*channel), GFP_KERNEL);
134 if (channel == NULL)135 if (channel == NULL) {
135 return ERR_PTR(-ENOMEM);136 err = -ENOMEM;
137 goto error_no_mem;
138 }
136 139
137 channel->indio_dev = c->indio_dev;140 channel->indio_dev = c->indio_dev;
138 141
139 if (c->map->adc_channel_label)142 if (c->map->adc_channel_label) {
140 channel->channel =143 channel->channel =
141 iio_chan_spec_from_name(channel->indio_dev,144 iio_chan_spec_from_name(channel->indio_dev,
142 c->map->adc_channel_label);145 c->map->adc_channel_label);
143 146
147 if (channel->channel == NULL) {
148 err = -EINVAL;
149 goto error_no_chan;
150 }
151 }
152
144 return channel;153 return channel;
154
155error_no_chan:
156 kfree(channel);
157error_no_mem:
158 iio_device_put(c->indio_dev);
159 return ERR_PTR(err);
145}160}
146EXPORT_SYMBOL_GPL(iio_channel_get);161EXPORT_SYMBOL_GPL(iio_channel_get);
147 162
@@ -229,9 +244,21 @@ void iio_channel_release_all(struct iio_channel *channels) · 81 unmodified lines
229}244}
230EXPORT_SYMBOL_GPL(iio_channel_release_all);245EXPORT_SYMBOL_GPL(iio_channel_release_all);
231 246
247static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
248 enum iio_chan_info_enum info)
249{
250 int unused;
251
252 if (val2 == NULL)
253 val2 = &unused;
254
255 return chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel,
256 val, val2, info);
257}
258
232int iio_read_channel_raw(struct iio_channel *chan, int *val)259int iio_read_channel_raw(struct iio_channel *chan, int *val)
233{260{
234 int val2, ret;261 int ret;
235 262
236 mutex_lock(&chan->indio_dev->info_exist_lock);263 mutex_lock(&chan->indio_dev->info_exist_lock);
237 if (chan->indio_dev->info == NULL) {264 if (chan->indio_dev->info == NULL) {
@@ -239,8 +266,7 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val) · 1 unmodified line
239 goto err_unlock;266 goto err_unlock;
240 }267 }
241 268
242 ret = chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel,269 ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
243 val, &val2, 0);
244err_unlock:270err_unlock:
245 mutex_unlock(&chan->indio_dev->info_exist_lock);271 mutex_unlock(&chan->indio_dev->info_exist_lock);
246 272
@@ -248,6 +274,100 @@ err_unlock: · 1 unmodified line
248}274}
249EXPORT_SYMBOL_GPL(iio_read_channel_raw);275EXPORT_SYMBOL_GPL(iio_read_channel_raw);
250 276
277static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
278 int raw, int *processed, unsigned int scale)
279{
280 int scale_type, scale_val, scale_val2, offset;
281 s64 raw64 = raw;
282 int ret;
283
284 ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_SCALE);
285 if (ret == 0)
286 raw64 += offset;
287
288 scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
289 IIO_CHAN_INFO_SCALE);
290 if (scale_type < 0)
291 return scale_type;
292
293 switch (scale_type) {
294 case IIO_VAL_INT:
295 *processed = raw64 * scale_val;
296 break;
297 case IIO_VAL_INT_PLUS_MICRO:
298 if (scale_val2 < 0)
299 *processed = -raw64 * scale_val;
300 else
301 *processed = raw64 * scale_val;
302 *processed += div_s64(raw64 * (s64)scale_val2 * scale,
303 1000000LL);
304 break;
305 case IIO_VAL_INT_PLUS_NANO:
306 if (scale_val2 < 0)
307 *processed = -raw64 * scale_val;
308 else
309 *processed = raw64 * scale_val;
310 *processed += div_s64(raw64 * (s64)scale_val2 * scale,
311 1000000000LL);
312 break;
313 case IIO_VAL_FRACTIONAL:
314 *processed = div_s64(raw64 * (s64)scale_val * scale,
315 scale_val2);
316 break;
317 default:
318 return -EINVAL;
319 }
320
321 return 0;
322}
323
324int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
325 int *processed, unsigned int scale)
326{
327 int ret;
328
329 mutex_lock(&chan->indio_dev->info_exist_lock);
330 if (chan->indio_dev->info == NULL) {
331 ret = -ENODEV;
332 goto err_unlock;
333 }
334
335 ret = iio_convert_raw_to_processed_unlocked(chan, raw, processed,
336 scale);
337err_unlock:
338 mutex_unlock(&chan->indio_dev->info_exist_lock);
339
340 return ret;
341}
342EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed);
343
344int iio_read_channel_processed(struct iio_channel *chan, int *val)
345{
346 int ret;
347
348 mutex_lock(&chan->indio_dev->info_exist_lock);
349 if (chan->indio_dev->info == NULL) {
350 ret = -ENODEV;
351 goto err_unlock;
352 }
353
354 if (iio_channel_has_info(chan->channel, IIO_CHAN_INFO_PROCESSED)) {
355 ret = iio_channel_read(chan, val, NULL,
356 IIO_CHAN_INFO_PROCESSED);
357 } else {
358 ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
359 if (ret < 0)
360 goto err_unlock;
361 ret = iio_convert_raw_to_processed_unlocked(chan, *val, val, 1);
362 }
363
364err_unlock:
365 mutex_unlock(&chan->indio_dev->info_exist_lock);
366
367 return ret;
368}
369EXPORT_SYMBOL_GPL(iio_read_channel_processed);
370
251int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)371int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
252{372{
253 int ret;373 int ret;
@@ -258,10 +378,7 @@ int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2) · 4 unmodified lines
258 goto err_unlock;378 goto err_unlock;
259 }379 }
260 380
261 ret = chan->indio_dev->info->read_raw(chan->indio_dev,381 ret = iio_channel_read(chan, val, val2, IIO_CHAN_INFO_SCALE);
262 chan->channel,
263 val, val2,
264 IIO_CHAN_INFO_SCALE);
265err_unlock:382err_unlock:
266 mutex_unlock(&chan->indio_dev->info_exist_lock);383 mutex_unlock(&chan->indio_dev->info_exist_lock);
267 384
drivers/iio/kfifo_buf.c+23−8
@@ -6,6 +6,7 @@ · 5 unmodified lines
6#include <linux/kfifo.h>6#include <linux/kfifo.h>
7#include <linux/mutex.h>7#include <linux/mutex.h>
8#include <linux/iio/kfifo_buf.h>8#include <linux/iio/kfifo_buf.h>
9#include <linux/sched.h>
9 10
10struct iio_kfifo {11struct iio_kfifo {
11 struct iio_buffer buffer;12 struct iio_buffer buffer;
@@ -22,7 +23,8 @@ static inline int __iio_allocate_kfifo(struct iio_kfifo *buf, · 10 unmodified lines
22 return -EINVAL;23 return -EINVAL;
23 24
24 __iio_update_buffer(&buf->buffer, bytes_per_datum, length);25 __iio_update_buffer(&buf->buffer, bytes_per_datum, length);
25 return kfifo_alloc(&buf->kf, bytes_per_datum*length, GFP_KERNEL);26 return __kfifo_alloc((struct __kfifo *)&buf->kf, length,
27 bytes_per_datum, GFP_KERNEL);
26}28}
27 29
28static int iio_request_update_kfifo(struct iio_buffer *r)30static int iio_request_update_kfifo(struct iio_buffer *r)
@@ -35,6 +37,7 @@ static int iio_request_update_kfifo(struct iio_buffer *r) · 6 unmodified lines
35 kfifo_free(&buf->kf);37 kfifo_free(&buf->kf);
36 ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum,38 ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum,
37 buf->buffer.length);39 buf->buffer.length);
40 r->stufftoread = false;
38error_ret:41error_ret:
39 return ret;42 return ret;
40}43}
@@ -81,6 +84,9 @@ static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd) · 40 unmodified lines
81 84
82static int iio_set_length_kfifo(struct iio_buffer *r, int length)85static int iio_set_length_kfifo(struct iio_buffer *r, int length)
83{86{
87 /* Avoid an invalid state */
88 if (length < 2)
89 length = 2;
84 if (r->length != length) {90 if (r->length != length) {
85 r->length = length;91 r->length = length;
86 iio_mark_update_needed_kfifo(r);92 iio_mark_update_needed_kfifo(r);
@@ -89,14 +95,16 @@ static int iio_set_length_kfifo(struct iio_buffer *r, int length) · 2 unmodified lines
89}95}
90 96
91static int iio_store_to_kfifo(struct iio_buffer *r,97static int iio_store_to_kfifo(struct iio_buffer *r,
92 u8 *data,98 u8 *data)
93 s64 timestamp)
94{99{
95 int ret;100 int ret;
96 struct iio_kfifo *kf = iio_to_kfifo(r);101 struct iio_kfifo *kf = iio_to_kfifo(r);
97 ret = kfifo_in(&kf->kf, data, r->bytes_per_datum);102 ret = kfifo_in(&kf->kf, data, 1);
98 if (ret != r->bytes_per_datum)103 if (ret != 1)
99 return -EBUSY;104 return -EBUSY;
105 r->stufftoread = true;
106 wake_up_interruptible(&r->pollq);
107
100 return 0;108 return 0;
101}109}
102 110
@@ -106,11 +114,18 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r, · 3 unmodified lines
106 int ret, copied;114 int ret, copied;
107 struct iio_kfifo *kf = iio_to_kfifo(r);115 struct iio_kfifo *kf = iio_to_kfifo(r);
108 116
109 if (n < r->bytes_per_datum)117 if (n < r->bytes_per_datum || r->bytes_per_datum == 0)
110 return -EINVAL;118 return -EINVAL;
111 119
112 n = rounddown(n, r->bytes_per_datum);
113 ret = kfifo_to_user(&kf->kf, buf, n, &copied);120 ret = kfifo_to_user(&kf->kf, buf, n, &copied);
121 if (ret < 0)
122 return ret;
123
124 if (kfifo_is_empty(&kf->kf))
125 r->stufftoread = false;
126 /* verify it is still empty to avoid race */
127 if (!kfifo_is_empty(&kf->kf))
128 r->stufftoread = true;
114 129
115 return copied;130 return copied;
116}131}
@@ -136,7 +151,7 @@ struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) · 19 unmodified lines
136 iio_buffer_init(&kf->buffer);151 iio_buffer_init(&kf->buffer);
137 kf->buffer.attrs = &iio_kfifo_attribute_group;152 kf->buffer.attrs = &iio_kfifo_attribute_group;
138 kf->buffer.access = &kfifo_access_funcs;153 kf->buffer.access = &kfifo_access_funcs;
139 154 kf->buffer.length = 2;
140 return &kf->buffer;155 return &kf->buffer;
141}156}
142EXPORT_SYMBOL(iio_kfifo_allocate);157EXPORT_SYMBOL(iio_kfifo_allocate);
drivers/iio/light/Kconfig+10−0
@@ -42,4 +42,14 @@ config VCNL4000 · 41 unmodified lines
42 To compile this driver as a module, choose M here: the42 To compile this driver as a module, choose M here: the
43 module will be called vcnl4000.43 module will be called vcnl4000.
44 44
45config HID_SENSOR_ALS
46 depends on HID_SENSOR_HUB
47 select IIO_BUFFER
48 select IIO_TRIGGERED_BUFFER
49 select HID_SENSOR_IIO_COMMON
50 tristate "HID ALS"
51 help
52 Say yes here to build support for the HID SENSOR
53 Ambient light sensor.
54
45endmenu55endmenu
drivers/iio/light/Makefile+1−0
@@ -5,3 +5,4 @@ · 4 unmodified lines
5obj-$(CONFIG_ADJD_S311) += adjd_s311.o5obj-$(CONFIG_ADJD_S311) += adjd_s311.o
6obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o6obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
7obj-$(CONFIG_VCNL4000) += vcnl4000.o7obj-$(CONFIG_VCNL4000) += vcnl4000.o
8obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
drivers/iio/light/adjd_s311.c+1−1
@@ -187,7 +187,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p) · 186 unmodified lines
187 if (indio_dev->scan_timestamp)187 if (indio_dev->scan_timestamp)
188 *(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64)))188 *(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64)))
189 = time_ns;189 = time_ns;
190 iio_push_to_buffer(buffer, (u8 *)data->buffer, time_ns);190 iio_push_to_buffer(buffer, (u8 *)data->buffer);
191 191
192done:192done:
193 iio_trigger_notify_done(indio_dev->trig);193 iio_trigger_notify_done(indio_dev->trig);
drivers/iio/light/hid-sensor-als.c+385−0
@@ -0,0 +1,385 @@
1/*
2 * HID Sensors Driver
3 * Copyright (c) 2012, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 */
19#include <linux/device.h>
20#include <linux/platform_device.h>
21#include <linux/module.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/slab.h>
25#include <linux/hid-sensor-hub.h>
26#include <linux/iio/iio.h>
27#include <linux/iio/sysfs.h>
28#include <linux/iio/buffer.h>
29#include <linux/iio/trigger_consumer.h>
30#include <linux/iio/triggered_buffer.h>
31#include "../common/hid-sensors/hid-sensor-attributes.h"
32#include "../common/hid-sensors/hid-sensor-trigger.h"
33
34/*Format: HID-SENSOR-usage_id_in_hex*/
35/*Usage ID from spec for Accelerometer-3D: 0x200041*/
36#define DRIVER_NAME "HID-SENSOR-200041"
37
38#define CHANNEL_SCAN_INDEX_ILLUM 0
39
40struct als_state {
41 struct hid_sensor_hub_callbacks callbacks;
42 struct hid_sensor_iio_common common_attributes;
43 struct hid_sensor_hub_attribute_info als_illum;
44 u32 illum;
45};
46
47/* Channel definitions */
48static const struct iio_chan_spec als_channels[] = {
49 {
50 .type = IIO_INTENSITY,
51 .modified = 1,
52 .channel2 = IIO_MOD_LIGHT_BOTH,
53 .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
54 IIO_CHAN_INFO_SCALE_SHARED_BIT |
55 IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
56 IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
57 .scan_index = CHANNEL_SCAN_INDEX_ILLUM,
58 }
59};
60
61/* Adjust channel real bits based on report descriptor */
62static void als_adjust_channel_bit_mask(struct iio_chan_spec *channels,
63 int channel, int size)
64{
65 channels[channel].scan_type.sign = 's';
66 /* Real storage bits will change based on the report desc. */
67 channels[channel].scan_type.realbits = size * 8;
68 /* Maximum size of a sample to capture is u32 */
69 channels[channel].scan_type.storagebits = sizeof(u32) * 8;
70}
71
72/* Channel read_raw handler */
73static int als_read_raw(struct iio_dev *indio_dev,
74 struct iio_chan_spec const *chan,
75 int *val, int *val2,
76 long mask)
77{
78 struct als_state *als_state = iio_priv(indio_dev);
79 int report_id = -1;
80 u32 address;
81 int ret;
82 int ret_type;
83
84 *val = 0;
85 *val2 = 0;
86 switch (mask) {
87 case 0:
88 switch (chan->scan_index) {
89 case CHANNEL_SCAN_INDEX_ILLUM:
90 report_id = als_state->als_illum.report_id;
91 address =
92 HID_USAGE_SENSOR_LIGHT_ILLUM;
93 break;
94 default:
95 report_id = -1;
96 break;
97 }
98 if (report_id >= 0)
99 *val = sensor_hub_input_attr_get_raw_value(
100 als_state->common_attributes.hsdev,
101 HID_USAGE_SENSOR_ALS, address,
102 report_id);
103 else {
104 *val = 0;
105 return -EINVAL;
106 }
107 ret_type = IIO_VAL_INT;
108 break;
109 case IIO_CHAN_INFO_SCALE:
110 *val = als_state->als_illum.units;
111 ret_type = IIO_VAL_INT;
112 break;
113 case IIO_CHAN_INFO_OFFSET:
114 *val = hid_sensor_convert_exponent(
115 als_state->als_illum.unit_expo);
116 ret_type = IIO_VAL_INT;
117 break;
118 case IIO_CHAN_INFO_SAMP_FREQ:
119 ret = hid_sensor_read_samp_freq_value(
120 &als_state->common_attributes, val, val2);
121 ret_type = IIO_VAL_INT_PLUS_MICRO;
122 break;
123 case IIO_CHAN_INFO_HYSTERESIS:
124 ret = hid_sensor_read_raw_hyst_value(
125 &als_state->common_attributes, val, val2);
126 ret_type = IIO_VAL_INT_PLUS_MICRO;
127 break;
128 default:
129 ret_type = -EINVAL;
130 break;
131 }
132
133 return ret_type;
134}
135
136/* Channel write_raw handler */
137static int als_write_raw(struct iio_dev *indio_dev,
138 struct iio_chan_spec const *chan,
139 int val,
140 int val2,
141 long mask)
142{
143 struct als_state *als_state = iio_priv(indio_dev);
144 int ret = 0;
145
146 switch (mask) {
147 case IIO_CHAN_INFO_SAMP_FREQ:
148 ret = hid_sensor_write_samp_freq_value(
149 &als_state->common_attributes, val, val2);
150 break;
151 case IIO_CHAN_INFO_HYSTERESIS:
152 ret = hid_sensor_write_raw_hyst_value(
153 &als_state->common_attributes, val, val2);
154 break;
155 default:
156 ret = -EINVAL;
157 }
158
159 return ret;
160}
161
162static int als_write_raw_get_fmt(struct iio_dev *indio_dev,
163 struct iio_chan_spec const *chan,
164 long mask)
165{
166 return IIO_VAL_INT_PLUS_MICRO;
167}
168
169static const struct iio_info als_info = {
170 .driver_module = THIS_MODULE,
171 .read_raw = &als_read_raw,
172 .write_raw = &als_write_raw,
173 .write_raw_get_fmt = &als_write_raw_get_fmt,
174};
175
176/* Function to push data to buffer */
177static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
178{
179 struct iio_buffer *buffer = indio_dev->buffer;
180 int datum_sz;
181
182 dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
183 if (!buffer) {
184 dev_err(&indio_dev->dev, "Buffer == NULL\n");
185 return;
186 }
187 datum_sz = buffer->access->get_bytes_per_datum(buffer);
188 if (len > datum_sz) {
189 dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
190 datum_sz);
191 return;
192 }
193 iio_push_to_buffer(buffer, (u8 *)data);
194}
195
196/* Callback handler to send event after all samples are received and captured */
197static int als_proc_event(struct hid_sensor_hub_device *hsdev,
198 unsigned usage_id,
199 void *priv)
200{
201 struct iio_dev *indio_dev = platform_get_drvdata(priv);
202 struct als_state *als_state = iio_priv(indio_dev);
203
204 dev_dbg(&indio_dev->dev, "als_proc_event [%d]\n",
205 als_state->common_attributes.data_ready);
206 if (als_state->common_attributes.data_ready)
207 hid_sensor_push_data(indio_dev,
208 (u8 *)&als_state->illum,
209 sizeof(als_state->illum));
210
211 return 0;
212}
213
214/* Capture samples in local storage */
215static int als_capture_sample(struct hid_sensor_hub_device *hsdev,
216 unsigned usage_id,
217 size_t raw_len, char *raw_data,
218 void *priv)
219{
220 struct iio_dev *indio_dev = platform_get_drvdata(priv);
221 struct als_state *als_state = iio_priv(indio_dev);
222 int ret = -EINVAL;
223
224 switch (usage_id) {
225 case HID_USAGE_SENSOR_LIGHT_ILLUM:
226 als_state->illum = *(u32 *)raw_data;
227 ret = 0;
228 break;
229 default:
230 break;
231 }
232
233 return ret;
234}
235
236/* Parse report which is specific to an usage id*/
237static int als_parse_report(struct platform_device *pdev,
238 struct hid_sensor_hub_device *hsdev,
239 struct iio_chan_spec *channels,
240 unsigned usage_id,
241 struct als_state *st)
242{
243 int ret;
244
245 ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT,
246 usage_id,
247 HID_USAGE_SENSOR_LIGHT_ILLUM,
248 &st->als_illum);
249 if (ret < 0)
250 return ret;
251 als_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_ILLUM,
252 st->als_illum.size);
253
254 dev_dbg(&pdev->dev, "als %x:%x\n", st->als_illum.index,
255 st->als_illum.report_id);
256
257 return ret;
258}
259
260/* Function to initialize the processing for usage id */
261static int __devinit hid_als_probe(struct platform_device *pdev)
262{
263 int ret = 0;
264 static const char *name = "als";
265 struct iio_dev *indio_dev;
266 struct als_state *als_state;
267 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
268 struct iio_chan_spec *channels;
269
270 indio_dev = iio_device_alloc(sizeof(struct als_state));
271 if (indio_dev == NULL) {
272 ret = -ENOMEM;
273 goto error_ret;
274 }
275 platform_set_drvdata(pdev, indio_dev);
276
277 als_state = iio_priv(indio_dev);
278 als_state->common_attributes.hsdev = hsdev;
279 als_state->common_attributes.pdev = pdev;
280
281 ret = hid_sensor_parse_common_attributes(hsdev, HID_USAGE_SENSOR_ALS,
282 &als_state->common_attributes);
283 if (ret) {
284 dev_err(&pdev->dev, "failed to setup common attributes\n");
285 goto error_free_dev;
286 }
287
288 channels = kmemdup(als_channels,
289 sizeof(als_channels),
290 GFP_KERNEL);
291 if (!channels) {
292 dev_err(&pdev->dev, "failed to duplicate channels\n");
293 goto error_free_dev;
294 }
295
296 ret = als_parse_report(pdev, hsdev, channels,
297 HID_USAGE_SENSOR_ALS, als_state);
298 if (ret) {
299 dev_err(&pdev->dev, "failed to setup attributes\n");
300 goto error_free_dev_mem;
301 }
302
303 indio_dev->channels = channels;
304 indio_dev->num_channels =
305 ARRAY_SIZE(als_channels);
306 indio_dev->dev.parent = &pdev->dev;
307 indio_dev->info = &als_info;
308 indio_dev->name = name;
309 indio_dev->modes = INDIO_DIRECT_MODE;
310
311 ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
312 NULL, NULL);
313 if (ret) {
314 dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
315 goto error_free_dev_mem;
316 }
317 als_state->common_attributes.data_ready = false;
318 ret = hid_sensor_setup_trigger(indio_dev, name,
319 &als_state->common_attributes);
320 if (ret < 0) {
321 dev_err(&pdev->dev, "trigger setup failed\n");
322 goto error_unreg_buffer_funcs;
323 }
324
325 ret = iio_device_register(indio_dev);
326 if (ret) {
327 dev_err(&pdev->dev, "device register failed\n");
328 goto error_remove_trigger;
329 }
330
331 als_state->callbacks.send_event = als_proc_event;
332 als_state->callbacks.capture_sample = als_capture_sample;
333 als_state->callbacks.pdev = pdev;
334 ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_ALS,
335 &als_state->callbacks);
336 if (ret < 0) {
337 dev_err(&pdev->dev, "callback reg failed\n");
338 goto error_iio_unreg;
339 }
340
341 return ret;
342
343error_iio_unreg:
344 iio_device_unregister(indio_dev);
345error_remove_trigger:
346 hid_sensor_remove_trigger(indio_dev);
347error_unreg_buffer_funcs:
348 iio_triggered_buffer_cleanup(indio_dev);
349error_free_dev_mem:
350 kfree(indio_dev->channels);
351error_free_dev:
352 iio_device_free(indio_dev);
353error_ret:
354 return ret;
355}
356
357/* Function to deinitialize the processing for usage id */
358static int __devinit hid_als_remove(struct platform_device *pdev)
359{
360 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
361 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
362
363 sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ALS);
364 iio_device_unregister(indio_dev);
365 hid_sensor_remove_trigger(indio_dev);
366 iio_triggered_buffer_cleanup(indio_dev);
367 kfree(indio_dev->channels);
368 iio_device_free(indio_dev);
369
370 return 0;
371}
372
373static struct platform_driver hid_als_platform_driver = {
374 .driver = {
375 .name = DRIVER_NAME,
376 .owner = THIS_MODULE,
377 },
378 .probe = hid_als_probe,
379 .remove = hid_als_remove,
380};
381module_platform_driver(hid_als_platform_driver);
382
383MODULE_DESCRIPTION("HID Sensor ALS");
384MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
385MODULE_LICENSE("GPL");
drivers/iio/magnetometer/Kconfig+16−0
@@ -0,0 +1,16 @@
1#
2# Magnetometer sensors
3#
4menu "Magnetometer sensors"
5
6config HID_SENSOR_MAGNETOMETER_3D
7 depends on HID_SENSOR_HUB
8 select IIO_BUFFER
9 select IIO_TRIGGERED_BUFFER
10 select HID_SENSOR_IIO_COMMON
11 tristate "HID Magenetometer 3D"
12 help
13 Say yes here to build support for the HID SENSOR
14 Magnetometer 3D.
15
16endmenu
drivers/iio/magnetometer/Makefile+5−0
@@ -0,0 +1,5 @@
1#
2# Makefile for industrial I/O Magnetometer sensor drivers
3#
4
5obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o
drivers/iio/magnetometer/hid-sensor-magn-3d.c+419−0
@@ -0,0 +1,419 @@
1/*
2 * HID Sensors Driver
3 * Copyright (c) 2012, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 */
19#include <linux/device.h>
20#include <linux/platform_device.h>
21#include <linux/module.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/slab.h>
25#include <linux/hid-sensor-hub.h>
26#include <linux/iio/iio.h>
27#include <linux/iio/sysfs.h>
28#include <linux/iio/buffer.h>
29#include <linux/iio/trigger_consumer.h>
30#include <linux/iio/triggered_buffer.h>
31#include "../common/hid-sensors/hid-sensor-attributes.h"
32#include "../common/hid-sensors/hid-sensor-trigger.h"
33
34/*Format: HID-SENSOR-usage_id_in_hex*/
35/*Usage ID from spec for Magnetometer-3D: 0x200083*/
36#define DRIVER_NAME "HID-SENSOR-200083"
37
38enum magn_3d_channel {
39 CHANNEL_SCAN_INDEX_X,
40 CHANNEL_SCAN_INDEX_Y,
41 CHANNEL_SCAN_INDEX_Z,
42 MAGN_3D_CHANNEL_MAX,
43};
44
45struct magn_3d_state {
46 struct hid_sensor_hub_callbacks callbacks;
47 struct hid_sensor_iio_common common_attributes;
48 struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
49 u32 magn_val[MAGN_3D_CHANNEL_MAX];
50};
51
52static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
53 HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
54 HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
55 HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
56};
57
58/* Channel definitions */
59static const struct iio_chan_spec magn_3d_channels[] = {
60 {
61 .type = IIO_MAGN,
62 .modified = 1,
63 .channel2 = IIO_MOD_X,
64 .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
65 IIO_CHAN_INFO_SCALE_SHARED_BIT |
66 IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
67 IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
68 .scan_index = CHANNEL_SCAN_INDEX_X,
69 }, {
70 .type = IIO_MAGN,
71 .modified = 1,
72 .channel2 = IIO_MOD_Y,
73 .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
74 IIO_CHAN_INFO_SCALE_SHARED_BIT |
75 IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
76 IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
77 .scan_index = CHANNEL_SCAN_INDEX_Y,
78 }, {
79 .type = IIO_MAGN,
80 .modified = 1,
81 .channel2 = IIO_MOD_Z,
82 .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
83 IIO_CHAN_INFO_SCALE_SHARED_BIT |
84 IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
85 IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
86 .scan_index = CHANNEL_SCAN_INDEX_Z,
87 }
88};
89
90/* Adjust channel real bits based on report descriptor */
91static void magn_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels,
92 int channel, int size)
93{
94 channels[channel].scan_type.sign = 's';
95 /* Real storage bits will change based on the report desc. */
96 channels[channel].scan_type.realbits = size * 8;
97 /* Maximum size of a sample to capture is u32 */
98 channels[channel].scan_type.storagebits = sizeof(u32) * 8;
99}
100
101/* Channel read_raw handler */
102static int magn_3d_read_raw(struct iio_dev *indio_dev,
103 struct iio_chan_spec const *chan,
104 int *val, int *val2,
105 long mask)
106{
107 struct magn_3d_state *magn_state = iio_priv(indio_dev);
108 int report_id = -1;
109 u32 address;
110 int ret;
111 int ret_type;
112
113 *val = 0;
114 *val2 = 0;
115 switch (mask) {
116 case 0:
117 report_id =
118 magn_state->magn[chan->scan_index].report_id;
119 address = magn_3d_addresses[chan->scan_index];
120 if (report_id >= 0)
121 *val = sensor_hub_input_attr_get_raw_value(
122 magn_state->common_attributes.hsdev,
123 HID_USAGE_SENSOR_COMPASS_3D, address,
124 report_id);
125 else {
126 *val = 0;
127 return -EINVAL;
128 }
129 ret_type = IIO_VAL_INT;
130 break;
131 case IIO_CHAN_INFO_SCALE:
132 *val = magn_state->magn[CHANNEL_SCAN_INDEX_X].units;
133 ret_type = IIO_VAL_INT;
134 break;
135 case IIO_CHAN_INFO_OFFSET:
136 *val = hid_sensor_convert_exponent(
137 magn_state->magn[CHANNEL_SCAN_INDEX_X].unit_expo);
138 ret_type = IIO_VAL_INT;
139 break;
140 case IIO_CHAN_INFO_SAMP_FREQ:
141 ret = hid_sensor_read_samp_freq_value(
142 &magn_state->common_attributes, val, val2);
143 ret_type = IIO_VAL_INT_PLUS_MICRO;
144 break;
145 case IIO_CHAN_INFO_HYSTERESIS:
146 ret = hid_sensor_read_raw_hyst_value(
147 &magn_state->common_attributes, val, val2);
148 ret_type = IIO_VAL_INT_PLUS_MICRO;
149 break;
150 default:
151 ret_type = -EINVAL;
152 break;
153 }
154
155 return ret_type;
156}
157
158/* Channel write_raw handler */
159static int magn_3d_write_raw(struct iio_dev *indio_dev,
160 struct iio_chan_spec const *chan,
161 int val,
162 int val2,
163 long mask)
164{
165 struct magn_3d_state *magn_state = iio_priv(indio_dev);
166 int ret = 0;
167
168 switch (mask) {
169 case IIO_CHAN_INFO_SAMP_FREQ:
170 ret = hid_sensor_write_samp_freq_value(
171 &magn_state->common_attributes, val, val2);
172 break;
173 case IIO_CHAN_INFO_HYSTERESIS:
174 ret = hid_sensor_write_raw_hyst_value(
175 &magn_state->common_attributes, val, val2);
176 break;
177 default:
178 ret = -EINVAL;
179 }
180
181 return ret;
182}
183
184static int magn_3d_write_raw_get_fmt(struct iio_dev *indio_dev,
185 struct iio_chan_spec const *chan,
186 long mask)
187{
188 return IIO_VAL_INT_PLUS_MICRO;
189}
190
191static const struct iio_info magn_3d_info = {
192 .driver_module = THIS_MODULE,
193 .read_raw = &magn_3d_read_raw,
194 .write_raw = &magn_3d_write_raw,
195 .write_raw_get_fmt = &magn_3d_write_raw_get_fmt,
196};
197
198/* Function to push data to buffer */
199static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
200{
201 struct iio_buffer *buffer = indio_dev->buffer;
202 int datum_sz;
203
204 dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
205 if (!buffer) {
206 dev_err(&indio_dev->dev, "Buffer == NULL\n");
207 return;
208 }
209 datum_sz = buffer->access->get_bytes_per_datum(buffer);
210 if (len > datum_sz) {
211 dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
212 datum_sz);
213 return;
214 }
215 iio_push_to_buffer(buffer, (u8 *)data);
216}
217
218/* Callback handler to send event after all samples are received and captured */
219static int magn_3d_proc_event(struct hid_sensor_hub_device *hsdev,
220 unsigned usage_id,
221 void *priv)
222{
223 struct iio_dev *indio_dev = platform_get_drvdata(priv);
224 struct magn_3d_state *magn_state = iio_priv(indio_dev);
225
226 dev_dbg(&indio_dev->dev, "magn_3d_proc_event [%d]\n",
227 magn_state->common_attributes.data_ready);
228 if (magn_state->common_attributes.data_ready)
229 hid_sensor_push_data(indio_dev,
230 (u8 *)magn_state->magn_val,
231 sizeof(magn_state->magn_val));
232
233 return 0;
234}
235
236/* Capture samples in local storage */
237static int magn_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
238 unsigned usage_id,
239 size_t raw_len, char *raw_data,
240 void *priv)
241{
242 struct iio_dev *indio_dev = platform_get_drvdata(priv);
243 struct magn_3d_state *magn_state = iio_priv(indio_dev);
244 int offset;
245 int ret = -EINVAL;
246
247 switch (usage_id) {
248 case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
249 case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
250 case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
251 offset = usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
252 magn_state->magn_val[CHANNEL_SCAN_INDEX_X + offset] =
253 *(u32 *)raw_data;
254 ret = 0;
255 break;
256 default:
257 break;
258 }
259
260 return ret;
261}
262
263/* Parse report which is specific to an usage id*/
264static int magn_3d_parse_report(struct platform_device *pdev,
265 struct hid_sensor_hub_device *hsdev,
266 struct iio_chan_spec *channels,
267 unsigned usage_id,
268 struct magn_3d_state *st)
269{
270 int ret;
271 int i;
272
273 for (i = 0; i <= CHANNEL_SCAN_INDEX_Z; ++i) {
274 ret = sensor_hub_input_get_attribute_info(hsdev,
275 HID_INPUT_REPORT,
276 usage_id,
277 HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS + i,
278 &st->magn[CHANNEL_SCAN_INDEX_X + i]);
279 if (ret < 0)
280 break;
281 magn_3d_adjust_channel_bit_mask(channels,
282 CHANNEL_SCAN_INDEX_X + i,
283 st->magn[CHANNEL_SCAN_INDEX_X + i].size);
284 }
285 dev_dbg(&pdev->dev, "magn_3d %x:%x, %x:%x, %x:%x\n",
286 st->magn[0].index,
287 st->magn[0].report_id,
288 st->magn[1].index, st->magn[1].report_id,
289 st->magn[2].index, st->magn[2].report_id);
290
291 return ret;
292}
293
294/* Function to initialize the processing for usage id */
295static int __devinit hid_magn_3d_probe(struct platform_device *pdev)
296{
297 int ret = 0;
298 static char *name = "magn_3d";
299 struct iio_dev *indio_dev;
300 struct magn_3d_state *magn_state;
301 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
302 struct iio_chan_spec *channels;
303
304 indio_dev = iio_device_alloc(sizeof(struct magn_3d_state));
305 if (indio_dev == NULL) {
306 ret = -ENOMEM;
307 goto error_ret;
308 }
309 platform_set_drvdata(pdev, indio_dev);
310
311 magn_state = iio_priv(indio_dev);
312 magn_state->common_attributes.hsdev = hsdev;
313 magn_state->common_attributes.pdev = pdev;
314
315 ret = hid_sensor_parse_common_attributes(hsdev,
316 HID_USAGE_SENSOR_COMPASS_3D,
317 &magn_state->common_attributes);
318 if (ret) {
319 dev_err(&pdev->dev, "failed to setup common attributes\n");
320 goto error_free_dev;
321 }
322
323 channels = kmemdup(magn_3d_channels,
324 sizeof(magn_3d_channels),
325 GFP_KERNEL);
326 if (!channels) {
327 dev_err(&pdev->dev, "failed to duplicate channels\n");
328 goto error_free_dev;
329 }
330
331 ret = magn_3d_parse_report(pdev, hsdev, channels,
332 HID_USAGE_SENSOR_COMPASS_3D, magn_state);
333 if (ret) {
334 dev_err(&pdev->dev, "failed to setup attributes\n");
335 goto error_free_dev_mem;
336 }
337
338 indio_dev->channels = channels;
339 indio_dev->num_channels = ARRAY_SIZE(magn_3d_channels);
340 indio_dev->dev.parent = &pdev->dev;
341 indio_dev->info = &magn_3d_info;
342 indio_dev->name = name;
343 indio_dev->modes = INDIO_DIRECT_MODE;
344
345 ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
346 NULL, NULL);
347 if (ret) {
348 dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
349 goto error_free_dev_mem;
350 }
351 magn_state->common_attributes.data_ready = false;
352 ret = hid_sensor_setup_trigger(indio_dev, name,
353 &magn_state->common_attributes);
354 if (ret < 0) {
355 dev_err(&pdev->dev, "trigger setup failed\n");
356 goto error_unreg_buffer_funcs;
357 }
358
359 ret = iio_device_register(indio_dev);
360 if (ret) {
361 dev_err(&pdev->dev, "device register failed\n");
362 goto error_remove_trigger;
363 }
364
365 magn_state->callbacks.send_event = magn_3d_proc_event;
366 magn_state->callbacks.capture_sample = magn_3d_capture_sample;
367 magn_state->callbacks.pdev = pdev;
368 ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D,
369 &magn_state->callbacks);
370 if (ret < 0) {
371 dev_err(&pdev->dev, "callback reg failed\n");
372 goto error_iio_unreg;
373 }
374
375 return ret;
376
377error_iio_unreg:
378 iio_device_unregister(indio_dev);
379error_remove_trigger:
380 hid_sensor_remove_trigger(indio_dev);
381error_unreg_buffer_funcs:
382 iio_triggered_buffer_cleanup(indio_dev);
383error_free_dev_mem:
384 kfree(indio_dev->channels);
385error_free_dev:
386 iio_device_free(indio_dev);
387error_ret:
388 return ret;
389}
390
391/* Function to deinitialize the processing for usage id */
392static int __devinit hid_magn_3d_remove(struct platform_device *pdev)
393{
394 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
395 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
396
397 sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D);
398 iio_device_unregister(indio_dev);
399 hid_sensor_remove_trigger(indio_dev);
400 iio_triggered_buffer_cleanup(indio_dev);
401 kfree(indio_dev->channels);
402 iio_device_free(indio_dev);
403
404 return 0;
405}
406
407static struct platform_driver hid_magn_3d_platform_driver = {
408 .driver = {
409 .name = DRIVER_NAME,
410 .owner = THIS_MODULE,
411 },
412 .probe = hid_magn_3d_probe,
413 .remove = hid_magn_3d_remove,
414};
415module_platform_driver(hid_magn_3d_platform_driver);
416
417MODULE_DESCRIPTION("HID Sensor Magnetometer 3D");
418MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
419MODULE_LICENSE("GPL");
drivers/power/Kconfig+7−0
@@ -29,6 +29,13 @@ config APM_POWER · 28 unmodified lines
29 Say Y here to enable support APM status emulation using29 Say Y here to enable support APM status emulation using
30 battery class devices.30 battery class devices.
31 31
32config GENERIC_ADC_BATTERY
33 tristate "Generic battery support using IIO"
34 depends on IIO
35 help
36 Say Y here to enable support for the generic battery driver
37 which uses IIO framework to read adc.
38
32config MAX8925_POWER39config MAX8925_POWER
33 tristate "MAX8925 battery charger support"40 tristate "MAX8925 battery charger support"
34 depends on MFD_MAX892541 depends on MFD_MAX8925
drivers/power/Makefile+1−0
@@ -5,6 +5,7 @@ power_supply-$(CONFIG_SYSFS) += power_supply_sysfs.o · 4 unmodified lines
5power_supply-$(CONFIG_LEDS_TRIGGERS) += power_supply_leds.o5power_supply-$(CONFIG_LEDS_TRIGGERS) += power_supply_leds.o
6 6
7obj-$(CONFIG_POWER_SUPPLY) += power_supply.o7obj-$(CONFIG_POWER_SUPPLY) += power_supply.o
8obj-$(CONFIG_GENERIC_ADC_BATTERY) += generic-adc-battery.o
8 9
9obj-$(CONFIG_PDA_POWER) += pda_power.o10obj-$(CONFIG_PDA_POWER) += pda_power.o
10obj-$(CONFIG_APM_POWER) += apm_power.o11obj-$(CONFIG_APM_POWER) += apm_power.o
drivers/power/generic-adc-battery.c+422−0
@@ -0,0 +1,422 @@
1/*
2 * Generic battery driver code using IIO
3 * Copyright (C) 2012, Anish Kumar <anish198519851985@gmail.com>
4 * based on jz4740-battery.c
5 * based on s3c_adc_battery.c
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for
9 * more details.
10 *
11 */
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14#include <linux/power_supply.h>
15#include <linux/gpio.h>
16#include <linux/err.h>
17#include <linux/timer.h>
18#include <linux/jiffies.h>
19#include <linux/errno.h>
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <linux/iio/consumer.h>
24#include <linux/iio/types.h>
25#include <linux/power/generic-adc-battery.h>
26
27#define JITTER_DEFAULT 10 /* hope 10ms is enough */
28
29enum gab_chan_type {
30 GAB_VOLTAGE = 0,
31 GAB_CURRENT,
32 GAB_POWER,
33 GAB_MAX_CHAN_TYPE
34};
35
36/*
37 * gab_chan_name suggests the standard channel names for commonly used
38 * channel types.
39 */
40static const char *const gab_chan_name[] = {
41 [GAB_VOLTAGE] = "voltage",
42 [GAB_CURRENT] = "current",
43 [GAB_POWER] = "power",
44};
45
46struct gab {
47 struct power_supply psy;
48 struct iio_channel *channel[GAB_MAX_CHAN_TYPE];
49 struct gab_platform_data *pdata;
50 struct delayed_work bat_work;
51 int level;
52 int status;
53 bool cable_plugged;
54};
55
56static struct gab *to_generic_bat(struct power_supply *psy)
57{
58 return container_of(psy, struct gab, psy);
59}
60
61static void gab_ext_power_changed(struct power_supply *psy)
62{
63 struct gab *adc_bat = to_generic_bat(psy);
64
65 schedule_delayed_work(&adc_bat->bat_work, msecs_to_jiffies(0));
66}
67
68static const enum power_supply_property gab_props[] = {
69 POWER_SUPPLY_PROP_STATUS,
70 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
71 POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
72 POWER_SUPPLY_PROP_CHARGE_NOW,
73 POWER_SUPPLY_PROP_VOLTAGE_NOW,
74 POWER_SUPPLY_PROP_CURRENT_NOW,
75 POWER_SUPPLY_PROP_TECHNOLOGY,
76 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
77 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
78 POWER_SUPPLY_PROP_MODEL_NAME,
79};
80
81/*
82 * This properties are set based on the received platform data and this
83 * should correspond one-to-one with enum chan_type.
84 */
85static const enum power_supply_property gab_dyn_props[] = {
86 POWER_SUPPLY_PROP_VOLTAGE_NOW,
87 POWER_SUPPLY_PROP_CURRENT_NOW,
88 POWER_SUPPLY_PROP_POWER_NOW,
89};
90
91static bool gab_charge_finished(struct gab *adc_bat)
92{
93 struct gab_platform_data *pdata = adc_bat->pdata;
94 bool ret = gpio_get_value(pdata->gpio_charge_finished);
95 bool inv = pdata->gpio_inverted;
96
97 if (!gpio_is_valid(pdata->gpio_charge_finished))
98 return false;
99 return ret ^ inv;
100}
101
102static int gab_get_status(struct gab *adc_bat)
103{
104 struct gab_platform_data *pdata = adc_bat->pdata;
105 struct power_supply_info *bat_info;
106
107 bat_info = &pdata->battery_info;
108 if (adc_bat->level == bat_info->charge_full_design)
109 return POWER_SUPPLY_STATUS_FULL;
110 return adc_bat->status;
111}
112
113static enum gab_chan_type gab_prop_to_chan(enum power_supply_property psp)
114{
115 switch (psp) {
116 case POWER_SUPPLY_PROP_POWER_NOW:
117 return GAB_POWER;
118 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
119 return GAB_VOLTAGE;
120 case POWER_SUPPLY_PROP_CURRENT_NOW:
121 return GAB_CURRENT;
122 default:
123 WARN_ON(1);
124 break;
125 }
126 return GAB_POWER;
127}
128
129static int read_channel(struct gab *adc_bat, enum power_supply_property psp,
130 int *result)
131{
132 int ret;
133 int chan_index;
134
135 chan_index = gab_prop_to_chan(psp);
136 ret = iio_read_channel_processed(adc_bat->channel[chan_index],
137 result);
138 if (ret < 0)
139 pr_err("read channel error\n");
140 return ret;
141}
142
143static int gab_get_property(struct power_supply *psy,
144 enum power_supply_property psp, union power_supply_propval *val)
145{
146 struct gab *adc_bat;
147 struct gab_platform_data *pdata;
148 struct power_supply_info *bat_info;
149 int result = 0;
150 int ret = 0;
151
152 adc_bat = to_generic_bat(psy);
153 if (!adc_bat) {
154 dev_err(psy->dev, "no battery infos ?!\n");
155 return -EINVAL;
156 }
157 pdata = adc_bat->pdata;
158 bat_info = &pdata->battery_info;
159
160 switch (psp) {
161 case POWER_SUPPLY_PROP_STATUS:
162 gab_get_status(adc_bat);
163 break;
164 case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN:
165 val->intval = 0;
166 break;
167 case POWER_SUPPLY_PROP_CHARGE_NOW:
168 val->intval = pdata->cal_charge(result);
169 break;
170 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
171 case POWER_SUPPLY_PROP_CURRENT_NOW:
172 case POWER_SUPPLY_PROP_POWER_NOW:
173 ret = read_channel(adc_bat, psp, &result);
174 if (ret < 0)
175 goto err;
176 val->intval = result;
177 break;
178 case POWER_SUPPLY_PROP_TECHNOLOGY:
179 val->intval = bat_info->technology;
180 break;
181 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
182 val->intval = bat_info->voltage_min_design;
183 break;
184 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
185 val->intval = bat_info->voltage_max_design;
186 break;
187 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
188 val->intval = bat_info->charge_full_design;
189 break;
190 case POWER_SUPPLY_PROP_MODEL_NAME:
191 val->strval = bat_info->name;
192 break;
193 default:
194 return -EINVAL;
195 }
196err:
197 return ret;
198}
199
200static void gab_work(struct work_struct *work)
201{
202 struct gab *adc_bat;
203 struct gab_platform_data *pdata;
204 struct delayed_work *delayed_work;
205 bool is_plugged;
206 int status;
207
208 delayed_work = container_of(work, struct delayed_work, work);
209 adc_bat = container_of(delayed_work, struct gab, bat_work);
210 pdata = adc_bat->pdata;
211 status = adc_bat->status;
212
213 is_plugged = power_supply_am_i_supplied(&adc_bat->psy);
214 adc_bat->cable_plugged = is_plugged;
215
216 if (!is_plugged)
217 adc_bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
218 else if (gab_charge_finished(adc_bat))
219 adc_bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
220 else
221 adc_bat->status = POWER_SUPPLY_STATUS_CHARGING;
222
223 if (status != adc_bat->status)
224 power_supply_changed(&adc_bat->psy);
225}
226
227static irqreturn_t gab_charged(int irq, void *dev_id)
228{
229 struct gab *adc_bat = dev_id;
230 struct gab_platform_data *pdata = adc_bat->pdata;
231 int delay;
232
233 delay = pdata->jitter_delay ? pdata->jitter_delay : JITTER_DEFAULT;
234 schedule_delayed_work(&adc_bat->bat_work,
235 msecs_to_jiffies(delay));
236 return IRQ_HANDLED;
237}
238
239static int __devinit gab_probe(struct platform_device *pdev)
240{
241 struct gab *adc_bat;
242 struct power_supply *psy;
243 struct gab_platform_data *pdata = pdev->dev.platform_data;
244 enum power_supply_property *properties;
245 int ret = 0;
246 int chan;
247 int index = 0;
248
249 adc_bat = devm_kzalloc(&pdev->dev, sizeof(*adc_bat), GFP_KERNEL);
250 if (!adc_bat) {
251 dev_err(&pdev->dev, "failed to allocate memory\n");
252 return -ENOMEM;
253 }
254
255 psy = &adc_bat->psy;
256 psy->name = pdata->battery_info.name;
257
258 /* bootup default values for the battery */
259 adc_bat->cable_plugged = false;
260 adc_bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
261 psy->type = POWER_SUPPLY_TYPE_BATTERY;
262 psy->get_property = gab_get_property;
263 psy->external_power_changed = gab_ext_power_changed;
264 adc_bat->pdata = pdata;
265
266 /* calculate the total number of channels */
267 chan = ARRAY_SIZE(gab_chan_name);
268
269 /*
270 * copying the static properties and allocating extra memory for holding
271 * the extra configurable properties received from platform data.
272 */
273 psy->properties = kcalloc(ARRAY_SIZE(gab_props) +
274 ARRAY_SIZE(gab_chan_name),
275 sizeof(*psy->properties), GFP_KERNEL);
276 if (!psy->properties) {
277 ret = -ENOMEM;
278 goto first_mem_fail;
279 }
280
281 memcpy(psy->properties, gab_props, sizeof(gab_props));
282 properties = psy->properties + sizeof(gab_props);
283
284 /*
285 * getting channel from iio and copying the battery properties
286 * based on the channel supported by consumer device.
287 */
288 for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) {
289 adc_bat->channel[chan] = iio_channel_get(dev_name(&pdev->dev),
290 gab_chan_name[chan]);
291 if (IS_ERR(adc_bat->channel[chan])) {
292 ret = PTR_ERR(adc_bat->channel[chan]);
293 } else {
294 /* copying properties for supported channels only */
295 memcpy(properties + sizeof(*(psy->properties)) * index,
296 &gab_dyn_props[chan],
297 sizeof(gab_dyn_props[chan]));
298 index++;
299 }
300 }
301
302 /* none of the channels are supported so let's bail out */
303 if (index == ARRAY_SIZE(gab_chan_name))
304 goto second_mem_fail;
305
306 /*
307 * Total number of properties is equal to static properties
308 * plus the dynamic properties.Some properties may not be set
309 * as come channels may be not be supported by the device.So
310 * we need to take care of that.
311 */
312 psy->num_properties = ARRAY_SIZE(gab_props) + index;
313
314 ret = power_supply_register(&pdev->dev, psy);
315 if (ret)
316 goto err_reg_fail;
317
318 INIT_DELAYED_WORK(&adc_bat->bat_work, gab_work);
319
320 if (gpio_is_valid(pdata->gpio_charge_finished)) {
321 int irq;
322 ret = gpio_request(pdata->gpio_charge_finished, "charged");
323 if (ret)
324 goto gpio_req_fail;
325
326 irq = gpio_to_irq(pdata->gpio_charge_finished);
327 ret = request_any_context_irq(irq, gab_charged,
328 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
329 "battery charged", adc_bat);
330 if (ret)
331 goto err_gpio;
332 }
333
334 platform_set_drvdata(pdev, adc_bat);
335
336 /* Schedule timer to check current status */
337 schedule_delayed_work(&adc_bat->bat_work,
338 msecs_to_jiffies(0));
339 return 0;
340
341err_gpio:
342 gpio_free(pdata->gpio_charge_finished);
343gpio_req_fail:
344 power_supply_unregister(psy);
345err_reg_fail:
346 for (chan = 0; ARRAY_SIZE(gab_chan_name); chan++)
347 iio_channel_release(adc_bat->channel[chan]);
348second_mem_fail:
349 kfree(psy->properties);
350first_mem_fail:
351 return ret;
352}
353
354static int __devexit gab_remove(struct platform_device *pdev)
355{
356 int chan;
357 struct gab *adc_bat = platform_get_drvdata(pdev);
358 struct gab_platform_data *pdata = adc_bat->pdata;
359
360 power_supply_unregister(&adc_bat->psy);
361
362 if (gpio_is_valid(pdata->gpio_charge_finished)) {
363 free_irq(gpio_to_irq(pdata->gpio_charge_finished), adc_bat);
364 gpio_free(pdata->gpio_charge_finished);
365 }
366
367 for (chan = 0; ARRAY_SIZE(gab_chan_name); chan++)
368 iio_channel_release(adc_bat->channel[chan]);
369
370 kfree(adc_bat->psy.properties);
371 cancel_delayed_work(&adc_bat->bat_work);
372 return 0;
373}
374
375#ifdef CONFIG_PM
376static int gab_suspend(struct device *dev)
377{
378 struct gab *adc_bat = dev_get_drvdata(dev);
379
380 cancel_delayed_work_sync(&adc_bat->bat_work);
381 adc_bat->status = POWER_SUPPLY_STATUS_UNKNOWN;
382 return 0;
383}
384
385static int gab_resume(struct device *dev)
386{
387 struct gab *adc_bat = dev_get_drvdata(dev);
388 struct gab_platform_data *pdata = adc_bat->pdata;
389 int delay;
390
391 delay = pdata->jitter_delay ? pdata->jitter_delay : JITTER_DEFAULT;
392
393 /* Schedule timer to check current status */
394 schedule_delayed_work(&adc_bat->bat_work,
395 msecs_to_jiffies(delay));
396 return 0;
397}
398
399static const struct dev_pm_ops gab_pm_ops = {
400 .suspend = gab_suspend,
401 .resume = gab_resume,
402};
403
404#define GAB_PM_OPS (&gab_pm_ops)
405#else
406#define GAB_PM_OPS (NULL)
407#endif
408
409static struct platform_driver gab_driver = {
410 .driver = {
411 .name = "generic-adc-battery",
412 .owner = THIS_MODULE,
413 .pm = GAB_PM_OPS
414 },
415 .probe = gab_probe,
416 .remove = __devexit_p(gab_remove),
417};
418module_platform_driver(gab_driver);
419
420MODULE_AUTHOR("anish kumar <anish198519851985@gmail.com>");
421MODULE_DESCRIPTION("generic battery driver using IIO");
422MODULE_LICENSE("GPL");
drivers/staging/Kconfig+8−2
@@ -122,8 +122,6 @@ source "drivers/staging/android/Kconfig" · 121 unmodified lines
122 122
123source "drivers/staging/telephony/Kconfig"123source "drivers/staging/telephony/Kconfig"
124 124
125source "drivers/staging/ramster/Kconfig"
126
127source "drivers/staging/ozwpan/Kconfig"125source "drivers/staging/ozwpan/Kconfig"
128 126
129source "drivers/staging/ccg/Kconfig"127source "drivers/staging/ccg/Kconfig"
@@ -136,4 +134,12 @@ source "drivers/staging/csr/Kconfig" · 6 unmodified lines
136 134
137source "drivers/staging/omap-thermal/Kconfig"135source "drivers/staging/omap-thermal/Kconfig"
138 136
137source "drivers/staging/ramster/Kconfig"
138
139source "drivers/staging/silicom/Kconfig"
140
141source "drivers/staging/ced1401/Kconfig"
142
143source "drivers/staging/imx-drm/Kconfig"
144
139endif # STAGING145endif # STAGING
drivers/staging/Makefile+4−1
@@ -54,9 +54,12 @@ obj-$(CONFIG_MFD_NVEC) += nvec/ · 53 unmodified lines
54obj-$(CONFIG_DRM_OMAP) += omapdrm/54obj-$(CONFIG_DRM_OMAP) += omapdrm/
55obj-$(CONFIG_ANDROID) += android/55obj-$(CONFIG_ANDROID) += android/
56obj-$(CONFIG_PHONE) += telephony/56obj-$(CONFIG_PHONE) += telephony/
57obj-$(CONFIG_RAMSTER) += ramster/
58obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/57obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/
59obj-$(CONFIG_USB_G_CCG) += ccg/58obj-$(CONFIG_USB_G_CCG) += ccg/
60obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/59obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/
61obj-$(CONFIG_CSR_WIFI) += csr/60obj-$(CONFIG_CSR_WIFI) += csr/
62obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal/61obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal/
62obj-$(CONFIG_ZCACHE2) += ramster/
63obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/
64obj-$(CONFIG_CED1401) += ced1401/
65obj-$(CONFIG_DRM_IMX) += imx-drm/
drivers/staging/android/alarm-dev.c+7−10
@@ -67,10 +67,8 @@ static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT]; · 66 unmodified lines
67 67
68static int is_wakeup(enum android_alarm_type type)68static int is_wakeup(enum android_alarm_type type)
69{69{
70 if (type == ANDROID_ALARM_RTC_WAKEUP ||70 return (type == ANDROID_ALARM_RTC_WAKEUP ||
71 type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP)71 type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP);
72 return 1;
73 return 0;
74}72}
75 73
76 74
@@ -85,12 +83,9 @@ static void devalarm_start(struct devalarm *alrm, ktime_t exp) · 8 unmodified lines
85 83
86static int devalarm_try_to_cancel(struct devalarm *alrm)84static int devalarm_try_to_cancel(struct devalarm *alrm)
87{85{
88 int ret;
89 if (is_wakeup(alrm->type))86 if (is_wakeup(alrm->type))
90 ret = alarm_try_to_cancel(&alrm->u.alrm);87 return alarm_try_to_cancel(&alrm->u.alrm);
91 else88 return hrtimer_try_to_cancel(&alrm->u.hrt);
92 ret = hrtimer_try_to_cancel(&alrm->u.hrt);
93 return ret;
94}89}
95 90
96static void devalarm_cancel(struct devalarm *alrm)91static void devalarm_cancel(struct devalarm *alrm)
@@ -223,10 +218,12 @@ from_old_alarm_set: · 126 unmodified lines
223 case ANDROID_ALARM_ELAPSED_REALTIME:218 case ANDROID_ALARM_ELAPSED_REALTIME:
224 get_monotonic_boottime(&tmp_time);219 get_monotonic_boottime(&tmp_time);
225 break;220 break;
226 case ANDROID_ALARM_TYPE_COUNT:
227 case ANDROID_ALARM_SYSTEMTIME:221 case ANDROID_ALARM_SYSTEMTIME:
228 ktime_get_ts(&tmp_time);222 ktime_get_ts(&tmp_time);
229 break;223 break;
224 default:
225 rv = -EINVAL;
226 goto err1;
230 }227 }
231 if (copy_to_user((void __user *)arg, &tmp_time,228 if (copy_to_user((void __user *)arg, &tmp_time,
232 sizeof(tmp_time))) {229 sizeof(tmp_time))) {
drivers/staging/android/ashmem.c+16−16
@@ -1,20 +1,20 @@
1/* mm/ashmem.c1/* mm/ashmem.c
2**2 *
3** Anonymous Shared Memory Subsystem, ashmem3 * Anonymous Shared Memory Subsystem, ashmem
4**4 *
5** Copyright (C) 2008 Google, Inc.5 * Copyright (C) 2008 Google, Inc.
6**6 *
7** Robert Love <rlove@google.com>7 * Robert Love <rlove@google.com>
8**8 *
9** This software is licensed under the terms of the GNU General Public9 * This software is licensed under the terms of the GNU General Public
10** License version 2, as published by the Free Software Foundation, and10 * License version 2, as published by the Free Software Foundation, and
11** may be copied, distributed, and modified under those terms.11 * may be copied, distributed, and modified under those terms.
12**12 *
13** This program is distributed in the hope that it will be useful,13 * This program is distributed in the hope that it will be useful,
14** but WITHOUT ANY WARRANTY; without even the implied warranty of14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16** GNU General Public License for more details.16 * GNU General Public License for more details.
17*/17 */
18 18
19#define pr_fmt(fmt) "ashmem: " fmt19#define pr_fmt(fmt) "ashmem: " fmt
20 20
drivers/staging/android/binder.c+3−3
@@ -365,7 +365,7 @@ binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer); · 364 unmodified lines
365/*365/*
366 * copied from get_unused_fd_flags366 * copied from get_unused_fd_flags
367 */367 */
368int task_get_unused_fd_flags(struct binder_proc *proc, int flags)368static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
369{369{
370 struct files_struct *files = proc->files;370 struct files_struct *files = proc->files;
371 int fd, error;371 int fd, error;
@@ -415,13 +415,13 @@ repeat: · 43 unmodified lines
415 else415 else
416 __clear_close_on_exec(fd, fdt);416 __clear_close_on_exec(fd, fdt);
417 files->next_fd = fd + 1;417 files->next_fd = fd + 1;
418#if 1418
419 /* Sanity check */419 /* Sanity check */
420 if (fdt->fd[fd] != NULL) {420 if (fdt->fd[fd] != NULL) {
421 pr_warn("get_unused_fd: slot %d not NULL!\n", fd);421 pr_warn("get_unused_fd: slot %d not NULL!\n", fd);
422 fdt->fd[fd] = NULL;422 fdt->fd[fd] = NULL;
423 }423 }
424#endif424
425 error = fd;425 error = fd;
426 426
427out:427out:
drivers/staging/android/logger.c+26−14
@@ -32,38 +32,50 @@ · 31 unmodified lines
32 32
33#include <asm/ioctls.h>33#include <asm/ioctls.h>
34 34
35/*35/**
36 * struct logger_log - represents a specific log, such as 'main' or 'radio'36 * struct logger_log - represents a specific log, such as 'main' or 'radio'
37 * @buffer: The actual ring buffer
38 * @misc: The "misc" device representing the log
39 * @wq: The wait queue for @readers
40 * @readers: This log's readers
41 * @mutex: The mutex that protects the @buffer
42 * @w_off: The current write head offset
43 * @head: The head, or location that readers start reading at.
44 * @size: The size of the log
45 * @logs: The list of log channels
37 *46 *
38 * This structure lives from module insertion until module removal, so it does47 * This structure lives from module insertion until module removal, so it does
39 * not need additional reference counting. The structure is protected by the48 * not need additional reference counting. The structure is protected by the
40 * mutex 'mutex'.49 * mutex 'mutex'.
41 */50 */
42struct logger_log {51struct logger_log {
43 unsigned char *buffer;/* the ring buffer itself */52 unsigned char *buffer;
44 struct miscdevice misc; /* misc device representing the log */53 struct miscdevice misc;
45 wait_queue_head_t wq; /* wait queue for readers */54 wait_queue_head_t wq;
46 struct list_head readers; /* this log's readers */55 struct list_head readers;
47 struct mutex mutex; /* mutex protecting buffer */56 struct mutex mutex;
48 size_t w_off; /* current write head offset */57 size_t w_off;
49 size_t head; /* new readers start here */58 size_t head;
50 size_t size; /* size of the log */59 size_t size;
51 struct list_head logs; /* list of log channels (myself)*/60 struct list_head logs;
52};61};
53 62
54static LIST_HEAD(log_list);63static LIST_HEAD(log_list);
55 64
56 65
57/*66/**
58 * struct logger_reader - a logging device open for reading67 * struct logger_reader - a logging device open for reading
68 * @log: The associated log
69 * @list: The associated entry in @logger_log's list
70 * @r_off: The current read head offset.
59 *71 *
60 * This object lives from open to release, so we don't need additional72 * This object lives from open to release, so we don't need additional
61 * reference counting. The structure is protected by log->mutex.73 * reference counting. The structure is protected by log->mutex.
62 */74 */
63struct logger_reader {75struct logger_reader {
64 struct logger_log *log; /* associated log */76 struct logger_log *log;
65 struct list_head list; /* entry in logger_log's list */77 struct list_head list;
66 size_t r_off; /* current read head offset */78 size_t r_off;
67};79};
68 80
69/* logger_offset - returns index 'n' into the log via (optimized) modulus */81/* logger_offset - returns index 'n' into the log via (optimized) modulus */
drivers/staging/android/logger.h+17−7
@@ -20,14 +20,24 @@ · 19 unmodified lines
20#include <linux/types.h>20#include <linux/types.h>
21#include <linux/ioctl.h>21#include <linux/ioctl.h>
22 22
23/**
24 * struct logger_entry - defines a single entry that is given to a logger
25 * @len: The length of the payload
26 * @__pad: Two bytes of padding that appear to be required
27 * @pid: The generating process' process ID
28 * @tid: The generating process' thread ID
29 * @sec: The number of seconds that have elapsed since the Epoch
30 * @nsec: The number of nanoseconds that have elapsed since @sec
31 * @msg: The message that is to be logged
32 */
23struct logger_entry {33struct logger_entry {
24 __u16 len; /* length of the payload */34 __u16 len;
25 __u16 __pad; /* no matter what, we get 2 bytes of padding */35 __u16 __pad;
26 __s32 pid; /* generating process's pid */36 __s32 pid;
27 __s32 tid; /* generating process's tid */37 __s32 tid;
28 __s32 sec; /* seconds since Epoch */38 __s32 sec;
29 __s32 nsec; /* nanoseconds */39 __s32 nsec;
30 char msg[0]; /* the entry's payload */40 char msg[0];
31};41};
32 42
33#define LOGGER_LOG_RADIO "log_radio" /* radio-related messages */43#define LOGGER_LOG_RADIO "log_radio" /* radio-related messages */
drivers/staging/android/timed_gpio.c+1−12
@@ -161,18 +161,7 @@ static struct platform_driver timed_gpio_driver = { · 160 unmodified lines
161 },161 },
162};162};
163 163
164static int __init timed_gpio_init(void)164module_platform_driver(timed_gpio_driver);
165{
166 return platform_driver_register(&timed_gpio_driver);
167}
168
169static void __exit timed_gpio_exit(void)
170{
171 platform_driver_unregister(&timed_gpio_driver);
172}
173
174module_init(timed_gpio_init);
175module_exit(timed_gpio_exit);
176 165
177MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");166MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
178MODULE_DESCRIPTION("timed gpio driver");167MODULE_DESCRIPTION("timed gpio driver");
drivers/staging/asus_oled/asus_oled.c+45−11
@@ -42,8 +42,6 @@ · 41 unmodified lines
42#define ASUS_OLED_NAME "asus-oled"42#define ASUS_OLED_NAME "asus-oled"
43#define ASUS_OLED_UNDERSCORE_NAME "asus_oled"43#define ASUS_OLED_UNDERSCORE_NAME "asus_oled"
44 44
45#define ASUS_OLED_ERROR "Asus OLED Display Error: "
46
47#define ASUS_OLED_STATIC 's'45#define ASUS_OLED_STATIC 's'
48#define ASUS_OLED_ROLL 'r'46#define ASUS_OLED_ROLL 'r'
49#define ASUS_OLED_FLASH 'f'47#define ASUS_OLED_FLASH 'f'
@@ -57,8 +55,9 @@ · 7 unmodified lines
57#define USB_DEVICE_ID_ASUS_LCM2 0x175b55#define USB_DEVICE_ID_ASUS_LCM2 0x175b
58 56
59MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com");57MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com");
60MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION);58MODULE_DESCRIPTION("Asus OLED Driver");
61MODULE_LICENSE("GPL");59MODULE_LICENSE("GPL");
60MODULE_VERSION(ASUS_OLED_VERSION);
62 61
63static struct class *oled_class;62static struct class *oled_class;
64static int oled_num;63static int oled_num;
@@ -138,6 +137,7 @@ struct asus_oled_dev { · 73 unmodified lines
138 size_t buf_size;137 size_t buf_size;
139 char *buf;138 char *buf;
140 uint8_t enabled;139 uint8_t enabled;
140 uint8_t enabled_post_resume;
141 struct device *dev;141 struct device *dev;
142};142};
143 143
@@ -383,13 +383,13 @@ static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count) · 239 unmodified lines
383 383
384 default:384 default:
385 i = 0;385 i = 0;
386 printk(ASUS_OLED_ERROR "Unknown OLED Pack Mode: %d!\n",386 dev_err(odev->dev, "Unknown OLED Pack Mode: %d!\n",
387 odev->pack_mode);387 odev->pack_mode);
388 break;388 break;
389 }389 }
390 390
391 if (i >= odev->buf_size) {391 if (i >= odev->buf_size) {
392 printk(ASUS_OLED_ERROR "Buffer overflow! Report a bug:"392 dev_err(odev->dev, "Buffer overflow! Report a bug:"
393 "offs: %d >= %d i: %d (x: %d y: %d)\n",393 "offs: %d >= %d i: %d (x: %d y: %d)\n",
394 (int) odev->buf_offs, (int) odev->buf_size,394 (int) odev->buf_offs, (int) odev->buf_size,
395 (int) i, (int) x, (int) y);395 (int) i, (int) x, (int) y);
@@ -435,7 +435,7 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, · 39 unmodified lines
435 odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);435 odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
436 if (odev->buf == NULL) {436 if (odev->buf == NULL) {
437 odev->buf_size = 0;437 odev->buf_size = 0;
438 printk(ASUS_OLED_ERROR "Out of memory!\n");438 dev_err(odev->dev, "Out of memory!\n");
439 return -ENOMEM;439 return -ENOMEM;
440 }440 }
441 441
@@ -473,7 +473,7 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, · 31 unmodified lines
473 odev->pic_mode = buf[1];473 odev->pic_mode = buf[1];
474 break;474 break;
475 default:475 default:
476 printk(ASUS_OLED_ERROR "Wrong picture mode: '%c'.\n",476 dev_err(odev->dev, "Wrong picture mode: '%c'.\n",
477 buf[1]);477 buf[1]);
478 return -EIO;478 return -EIO;
479 break;479 break;
@@ -533,7 +533,7 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, · 53 unmodified lines
533 533
534 if (odev->buf == NULL) {534 if (odev->buf == NULL) {
535 odev->buf_size = 0;535 odev->buf_size = 0;
536 printk(ASUS_OLED_ERROR "Out of memory!\n");536 dev_err(odev->dev, "Out of memory!\n");
537 return -ENOMEM;537 return -ENOMEM;
538 }538 }
539 539
@@ -593,15 +593,15 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, · 53 unmodified lines
593 return count;593 return count;
594 594
595error_width:595error_width:
596 printk(ASUS_OLED_ERROR "Wrong picture width specified.\n");596 dev_err(odev->dev, "Wrong picture width specified.\n");
597 return -EIO;597 return -EIO;
598 598
599error_height:599error_height:
600 printk(ASUS_OLED_ERROR "Wrong picture height specified.\n");600 dev_err(odev->dev, "Wrong picture height specified.\n");
601 return -EIO;601 return -EIO;
602 602
603error_header:603error_header:
604 printk(ASUS_OLED_ERROR "Wrong picture header.\n");604 dev_err(odev->dev, "Wrong picture header.\n");
605 return -EIO;605 return -EIO;
606}606}
607 607
@@ -766,11 +766,45 @@ static void asus_oled_disconnect(struct usb_interface *interface) · 158 unmodified lines
766 dev_info(&interface->dev, "Disconnected Asus OLED device\n");766 dev_info(&interface->dev, "Disconnected Asus OLED device\n");
767}767}
768 768
769#ifdef CONFIG_PM
770static int asus_oled_suspend(struct usb_interface *intf, pm_message_t message)
771{
772 struct asus_oled_dev *odev;
773
774 odev = usb_get_intfdata(intf);
775 if (!odev)
776 return -ENODEV;
777
778 odev->enabled_post_resume = odev->enabled;
779 enable_oled(odev, 0);
780
781 return 0;
782}
783
784static int asus_oled_resume(struct usb_interface *intf)
785{
786 struct asus_oled_dev *odev;
787
788 odev = usb_get_intfdata(intf);
789 if (!odev)
790 return -ENODEV;
791
792 enable_oled(odev, odev->enabled_post_resume);
793
794 return 0;
795}
796#else
797#define asus_oled_suspend NULL
798#define asus_oled_resume NULL
799#endif
800
769static struct usb_driver oled_driver = {801static struct usb_driver oled_driver = {
770 .name = ASUS_OLED_NAME,802 .name = ASUS_OLED_NAME,
771 .probe = asus_oled_probe,803 .probe = asus_oled_probe,
772 .disconnect = asus_oled_disconnect,804 .disconnect = asus_oled_disconnect,
773 .id_table = id_table,805 .id_table = id_table,
806 .suspend = asus_oled_suspend,
807 .resume = asus_oled_resume,
774};808};
775 809
776static CLASS_ATTR_STRING(version, S_IRUGO,810static CLASS_ATTR_STRING(version, S_IRUGO,
drivers/staging/bcm/Bcmchar.c+2−0
@@ -820,6 +820,7 @@ cntrlEnd: · 819 unmodified lines
820 820
821 if (copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength)) {821 if (copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength)) {
822 up(&Adapter->fw_download_sema);822 up(&Adapter->fw_download_sema);
823 kfree(psFwInfo);
823 return -EFAULT;824 return -EFAULT;
824 }825 }
825 826
@@ -829,6 +830,7 @@ cntrlEnd: · 3 unmodified lines
829 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n",830 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n",
830 psFwInfo->u32FirmwareLength);831 psFwInfo->u32FirmwareLength);
831 up(&Adapter->fw_download_sema);832 up(&Adapter->fw_download_sema);
833 kfree(psFwInfo);
832 Status = -EINVAL;834 Status = -EINVAL;
833 return Status;835 return Status;
834 }836 }
drivers/staging/bcm/CmHost.c+68−82
@@ -235,7 +235,7 @@ void ClearTargetDSXBuffer(struct bcm_mini_adapter *Adapter, B_UINT16 TID, BOOLEA · 234 unmodified lines
235 * @ingroup ctrl_pkt_functions235 * @ingroup ctrl_pkt_functions
236 * copy classifier rule into the specified SF index236 * copy classifier rule into the specified SF index
237 */237 */
238static inline VOID CopyClassifierRuleToSF(struct bcm_mini_adapter *Adapter, stConvergenceSLTypes *psfCSType, UINT uiSearchRuleIndex, UINT nClassifierIndex)238static inline VOID CopyClassifierRuleToSF(struct bcm_mini_adapter *Adapter, struct bcm_convergence_types *psfCSType, UINT uiSearchRuleIndex, UINT nClassifierIndex)
239{239{
240 struct bcm_classifier_rule *pstClassifierEntry = NULL;240 struct bcm_classifier_rule *pstClassifierEntry = NULL;
241 /* VOID *pvPhsContext = NULL; */241 /* VOID *pvPhsContext = NULL; */
@@ -428,7 +428,7 @@ VOID DeleteAllClassifiersForSF(struct bcm_mini_adapter *Adapter, UINT uiSearchRu · 186 unmodified lines
428 * @ingroup ctrl_pkt_functions428 * @ingroup ctrl_pkt_functions
429 */429 */
430static VOID CopyToAdapter(register struct bcm_mini_adapter *Adapter, /* <Pointer to the Adapter structure */430static VOID CopyToAdapter(register struct bcm_mini_adapter *Adapter, /* <Pointer to the Adapter structure */
431 register pstServiceFlowParamSI psfLocalSet, /* <Pointer to the ServiceFlowParamSI structure */431 register struct bcm_connect_mgr_params *psfLocalSet, /* Pointer to the connection manager parameters structure */
432 register UINT uiSearchRuleIndex, /* <Index of Queue, to which this data belongs */432 register UINT uiSearchRuleIndex, /* <Index of Queue, to which this data belongs */
433 register UCHAR ucDsxType,433 register UCHAR ucDsxType,
434 stLocalSFAddIndicationAlt *pstAddIndication) {434 stLocalSFAddIndicationAlt *pstAddIndication) {
@@ -439,7 +439,7 @@ static VOID CopyToAdapter(register struct bcm_mini_adapter *Adapter, /* <Pointer · 4 unmodified lines
439 enum E_CLASSIFIER_ACTION eClassifierAction = eInvalidClassifierAction;439 enum E_CLASSIFIER_ACTION eClassifierAction = eInvalidClassifierAction;
440 B_UINT16 u16PacketClassificationRuleIndex = 0;440 B_UINT16 u16PacketClassificationRuleIndex = 0;
441 int i;441 int i;
442 stConvergenceSLTypes *psfCSType = NULL;442 struct bcm_convergence_types *psfCSType = NULL;
443 S_PHS_RULE sPhsRule;443 S_PHS_RULE sPhsRule;
444 USHORT uVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value;444 USHORT uVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value;
445 UINT UGIValue = 0;445 UINT UGIValue = 0;
@@ -915,7 +915,7 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) · 469 unmodified lines
915 if (!pstAddIndication->sfAuthorizedSet.bValid)915 if (!pstAddIndication->sfAuthorizedSet.bValid)
916 pstAddIndication->sfAuthorizedSet.bValid = 1;916 pstAddIndication->sfAuthorizedSet.bValid = 1;
917 for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) {917 for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) {
918 stConvergenceSLTypes *psfCSType = NULL;918 struct bcm_convergence_types *psfCSType = NULL;
919 psfCSType = &pstAddIndication->sfAuthorizedSet.cConvergenceSLTypes[nIndex];919 psfCSType = &pstAddIndication->sfAuthorizedSet.cConvergenceSLTypes[nIndex];
920 920
921 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "psfCSType = %p", psfCSType);921 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "psfCSType = %p", psfCSType);
@@ -999,13 +999,10 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) · 77 unmodified lines
999#ifdef VERSION_D5999#ifdef VERSION_D5
1000 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ",1000 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ",
1001 psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);1001 psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);
1002 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x %02X %02X %02X %02X %02X %02X ",1002 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL,
1003 psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0],1003 DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x%*ph ",
1004 psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1],1004 6, psfCSType->cCPacketClassificationRule.
1005 psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2],1005 u8IPv6FlowLable);
1006 psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3],
1007 psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4],
1008 psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]);
1009#endif1006#endif
1010 }1007 }
1011 1008
@@ -1015,13 +1012,9 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) · 3 unmodified lines
1015 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfAdmittedSet.u16CID);1012 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfAdmittedSet.u16CID);
1016 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X",1013 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X",
1017 pstAddIndication->sfAdmittedSet.u8ServiceClassNameLength);1014 pstAddIndication->sfAdmittedSet.u8ServiceClassNameLength);
1018 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName: 0x %02X %02X %02X %02X %02X %02X",1015 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,
1019 pstAddIndication->sfAdmittedSet.u8ServiceClassName[0],1016 "u8ServiceClassName: 0x%*ph",
1020 pstAddIndication->sfAdmittedSet.u8ServiceClassName[1],1017 6, pstAddIndication->sfAdmittedSet.u8ServiceClassName);
1021 pstAddIndication->sfAdmittedSet.u8ServiceClassName[2],
1022 pstAddIndication->sfAdmittedSet.u8ServiceClassName[3],
1023 pstAddIndication->sfAdmittedSet.u8ServiceClassName[4],
1024 pstAddIndication->sfAdmittedSet.u8ServiceClassName[5]);
1025 1018
1026 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfAdmittedSet.u8MBSService);1019 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfAdmittedSet.u8MBSService);
1027 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfAdmittedSet.u8QosParamSet);1020 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfAdmittedSet.u8QosParamSet);
@@ -1066,7 +1059,7 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) · 38 unmodified lines
1066 nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF;1059 nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF;
1067 1060
1068 for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) {1061 for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) {
1069 stConvergenceSLTypes *psfCSType = NULL;1062 struct bcm_convergence_types *psfCSType = NULL;
1070 1063
1071 psfCSType = &pstAddIndication->sfAdmittedSet.cConvergenceSLTypes[nIndex];1064 psfCSType = &pstAddIndication->sfAdmittedSet.cConvergenceSLTypes[nIndex];
1072 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>");1065 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>");
@@ -1074,10 +1067,10 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) · 1 unmodified line
1074 psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority);1067 psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority);
1075 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength: 0x%02X",1068 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength: 0x%02X",
1076 psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);1069 psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
1077 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3]: 0x%02X %02X %02X",1070 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL,
1078 psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],1071 DBG_LVL_ALL, "u8IPTypeOfService[3]: 0x%*ph",
1079 psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],1072 3, psfCSType->cCPacketClassificationRule.
1080 psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);1073 u8IPTypeOfService);
1081 for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++)1074 for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++)
1082 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", psfCSType->cCPacketClassificationRule.u8Protocol);1075 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", psfCSType->cCPacketClassificationRule.u8Protocol);
1083 1076
@@ -1098,20 +1091,20 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) · 14 unmodified lines
1098 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength: 0x%02X ",1091 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength: 0x%02X ",
1099 psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);1092 psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
1100 1093
1101 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x %02X %02X %02X %02X ",1094 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL,
1102 psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0],1095 DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: "
1103 psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1],1096 "0x%*ph ", 4, psfCSType->
1104 psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2],1097 cCPacketClassificationRule.
1105 psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]);1098 u8ProtocolSourcePortRange);
1106 1099
1107 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength: 0x%02X ",1100 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength: 0x%02X ",
1108 psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength);1101 psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength);
1109 1102
1110 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x %02X %02X %02X %02X ",1103 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL,
1111 psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0],1104 DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: "
1112 psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1],1105 "0x%*ph ", 4, psfCSType->
1113 psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2],1106 cCPacketClassificationRule.
1114 psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]);1107 u8ProtocolDestPortRange);
1115 1108
1116 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength: 0x%02X ",1109 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength: 0x%02X ",
1117 psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);1110 psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
@@ -1130,10 +1123,10 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) · 12 unmodified lines
1130 u8EthernetSourceMACAddress);1123 u8EthernetSourceMACAddress);
1131 1124
1132 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ", psfCSType->cCPacketClassificationRule.u8EthertypeLength);1125 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ", psfCSType->cCPacketClassificationRule.u8EthertypeLength);
1133 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3]: 0x%02X %02X %02X",1126 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL,
1134 psfCSType->cCPacketClassificationRule.u8Ethertype[0],1127 DBG_LVL_ALL, "u8Ethertype[3]: 0x%*ph",
1135 psfCSType->cCPacketClassificationRule.u8Ethertype[1],1128 3, psfCSType->cCPacketClassificationRule.
1136 psfCSType->cCPacketClassificationRule.u8Ethertype[2]);1129 u8Ethertype);
1137 1130
1138 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority: 0x%X ", psfCSType->cCPacketClassificationRule.u16UserPriority);1131 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority: 0x%X ", psfCSType->cCPacketClassificationRule.u16UserPriority);
1139 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID);1132 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID);
@@ -1147,13 +1140,10 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) · 7 unmodified lines
1147#ifdef VERSION_D51140#ifdef VERSION_D5
1148 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ",1141 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ",
1149 psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);1142 psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);
1150 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x %02X %02X %02X %02X %02X %02X ",1143 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL,
1151 psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0],1144 DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x%*ph ",
1152 psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1],1145 6, psfCSType->cCPacketClassificationRule.
1153 psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2],1146 u8IPv6FlowLable);
1154 psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3],
1155 psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4],
1156 psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]);
1157#endif1147#endif
1158 }1148 }
1159 1149
@@ -1162,13 +1152,9 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) · 2 unmodified lines
1162 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", pstAddIndication->sfActiveSet.u32SFID);1152 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", pstAddIndication->sfActiveSet.u32SFID);
1163 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfActiveSet.u16CID);1153 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfActiveSet.u16CID);
1164 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", pstAddIndication->sfActiveSet.u8ServiceClassNameLength);1154 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", pstAddIndication->sfActiveSet.u8ServiceClassNameLength);
1165 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName: 0x %02X %02X %02X %02X %02X %02X",1155 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,
1166 pstAddIndication->sfActiveSet.u8ServiceClassName[0],1156 "u8ServiceClassName: 0x%*ph",
1167 pstAddIndication->sfActiveSet.u8ServiceClassName[1],1157 6, pstAddIndication->sfActiveSet.u8ServiceClassName);
1168 pstAddIndication->sfActiveSet.u8ServiceClassName[2],
1169 pstAddIndication->sfActiveSet.u8ServiceClassName[3],
1170 pstAddIndication->sfActiveSet.u8ServiceClassName[4],
1171 pstAddIndication->sfActiveSet.u8ServiceClassName[5]);
1172 1158
1173 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfActiveSet.u8MBSService);1159 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfActiveSet.u8MBSService);
1174 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfActiveSet.u8QosParamSet);1160 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfActiveSet.u8QosParamSet);
@@ -1212,7 +1198,7 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) · 37 unmodified lines
1212 nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF;1198 nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF;
1213 1199
1214 for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) {1200 for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) {
1215 stConvergenceSLTypes *psfCSType = NULL;1201 struct bcm_convergence_types *psfCSType = NULL;
1216 1202
1217 psfCSType = &pstAddIndication->sfActiveSet.cConvergenceSLTypes[nIndex];1203 psfCSType = &pstAddIndication->sfActiveSet.cConvergenceSLTypes[nIndex];
1218 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>");1204 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>");
@@ -1314,7 +1300,7 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) · 95 unmodified lines
1314 1300
1315static inline ULONG RestoreSFParam(struct bcm_mini_adapter *Adapter, ULONG ulAddrSFParamSet, PUCHAR pucDestBuffer)1301static inline ULONG RestoreSFParam(struct bcm_mini_adapter *Adapter, ULONG ulAddrSFParamSet, PUCHAR pucDestBuffer)
1316{1302{
1317 UINT nBytesToRead = sizeof(stServiceFlowParamSI);1303 UINT nBytesToRead = sizeof(struct bcm_connect_mgr_params);
1318 1304
1319 if (ulAddrSFParamSet == 0 || NULL == pucDestBuffer) {1305 if (ulAddrSFParamSet == 0 || NULL == pucDestBuffer) {
1320 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Got Param address as 0!!");1306 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Got Param address as 0!!");
@@ -1331,7 +1317,7 @@ static inline ULONG RestoreSFParam(struct bcm_mini_adapter *Adapter, ULONG ulAdd · 10 unmodified lines
1331 1317
1332static ULONG StoreSFParam(struct bcm_mini_adapter *Adapter, PUCHAR pucSrcBuffer, ULONG ulAddrSFParamSet)1318static ULONG StoreSFParam(struct bcm_mini_adapter *Adapter, PUCHAR pucSrcBuffer, ULONG ulAddrSFParamSet)
1333{1319{
1334 UINT nBytesToWrite = sizeof(stServiceFlowParamSI);1320 UINT nBytesToWrite = sizeof(struct bcm_connect_mgr_params);
1335 int ret = 0;1321 int ret = 0;
1336 1322
1337 if (ulAddrSFParamSet == 0 || NULL == pucSrcBuffer)1323 if (ulAddrSFParamSet == 0 || NULL == pucSrcBuffer)
@@ -1348,8 +1334,8 @@ static ULONG StoreSFParam(struct bcm_mini_adapter *Adapter, PUCHAR pucSrcBuffer, · 10 unmodified lines
1348ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength)1334ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength)
1349{1335{
1350 stLocalSFAddIndicationAlt *pstAddIndicationAlt = NULL;1336 stLocalSFAddIndicationAlt *pstAddIndicationAlt = NULL;
1351 stLocalSFAddIndication *pstAddIndication = NULL;1337 struct bcm_add_indication *pstAddIndication = NULL;
1352 stLocalSFDeleteRequest *pstDeletionRequest;1338 struct bcm_del_request *pstDeletionRequest;
1353 UINT uiSearchRuleIndex;1339 UINT uiSearchRuleIndex;
1354 ULONG ulSFID;1340 ULONG ulSFID;
1355 1341
@@ -1360,7 +1346,7 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu · 4 unmodified lines
1360 * we can stop the further classifying the pkt for this SF.1346 * we can stop the further classifying the pkt for this SF.
1361 */1347 */
1362 if (pstAddIndicationAlt->u8Type == DSD_REQ) {1348 if (pstAddIndicationAlt->u8Type == DSD_REQ) {
1363 pstDeletionRequest = (stLocalSFDeleteRequest *)pvBuffer;1349 pstDeletionRequest = (struct bcm_del_request *)pvBuffer;
1364 1350
1365 ulSFID = ntohl(pstDeletionRequest->u32SFID);1351 ulSFID = ntohl(pstDeletionRequest->u32SFID);
1366 uiSearchRuleIndex = SearchSfid(Adapter, ulSFID);1352 uiSearchRuleIndex = SearchSfid(Adapter, ulSFID);
@@ -1379,12 +1365,12 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu · 12 unmodified lines
1379 }1365 }
1380 /* For DSA_REQ, only up to "psfAuthorizedSet" parameter should be accessed by driver! */1366 /* For DSA_REQ, only up to "psfAuthorizedSet" parameter should be accessed by driver! */
1381 1367
1382 pstAddIndication = kmalloc(sizeof(*pstAddIndication), GFP_KERNEL);1368 pstAddIndication = kmalloc(sizeof(struct bcm_add_indication), GFP_KERNEL);
1383 if (pstAddIndication == NULL)1369 if (pstAddIndication == NULL)
1384 return 0;1370 return 0;
1385 1371
1386 /* AUTHORIZED SET */1372 /* AUTHORIZED SET */
1387 pstAddIndication->psfAuthorizedSet = (stServiceFlowParamSI *)1373 pstAddIndication->psfAuthorizedSet = (struct bcm_connect_mgr_params *)
1388 GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID);1374 GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID);
1389 if (!pstAddIndication->psfAuthorizedSet) {1375 if (!pstAddIndication->psfAuthorizedSet) {
1390 kfree(pstAddIndication);1376 kfree(pstAddIndication);
@@ -1398,10 +1384,10 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu · 7 unmodified lines
1398 }1384 }
1399 1385
1400 /* this can't possibly be right */1386 /* this can't possibly be right */
1401 pstAddIndication->psfAuthorizedSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfAuthorizedSet);1387 pstAddIndication->psfAuthorizedSet = (struct bcm_connect_mgr_params *)ntohl((ULONG)pstAddIndication->psfAuthorizedSet);
1402 1388
1403 if (pstAddIndicationAlt->u8Type == DSA_REQ) {1389 if (pstAddIndicationAlt->u8Type == DSA_REQ) {
1404 stLocalSFAddRequest AddRequest;1390 struct bcm_add_request AddRequest;
1405 1391
1406 AddRequest.u8Type = pstAddIndicationAlt->u8Type;1392 AddRequest.u8Type = pstAddIndicationAlt->u8Type;
1407 AddRequest.eConnectionDir = pstAddIndicationAlt->u8Direction;1393 AddRequest.eConnectionDir = pstAddIndicationAlt->u8Direction;
@@ -1409,8 +1395,8 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu · 1 unmodified line
1409 AddRequest.u16CID = pstAddIndicationAlt->u16CID;1395 AddRequest.u16CID = pstAddIndicationAlt->u16CID;
1410 AddRequest.u16VCID = pstAddIndicationAlt->u16VCID;1396 AddRequest.u16VCID = pstAddIndicationAlt->u16VCID;
1411 AddRequest.psfParameterSet = pstAddIndication->psfAuthorizedSet;1397 AddRequest.psfParameterSet = pstAddIndication->psfAuthorizedSet;
1412 (*puBufferLength) = sizeof(stLocalSFAddRequest);1398 (*puBufferLength) = sizeof(struct bcm_add_request);
1413 memcpy(pvBuffer, &AddRequest, sizeof(stLocalSFAddRequest));1399 memcpy(pvBuffer, &AddRequest, sizeof(struct bcm_add_request));
1414 kfree(pstAddIndication);1400 kfree(pstAddIndication);
1415 return 1;1401 return 1;
1416 }1402 }
@@ -1426,7 +1412,7 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu · 9 unmodified lines
1426 pstAddIndication->u8CC = pstAddIndicationAlt->u8CC;1412 pstAddIndication->u8CC = pstAddIndicationAlt->u8CC;
1427 1413
1428 /* ADMITTED SET */1414 /* ADMITTED SET */
1429 pstAddIndication->psfAdmittedSet = (stServiceFlowParamSI *)1415 pstAddIndication->psfAdmittedSet = (struct bcm_connect_mgr_params *)
1430 GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID);1416 GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID);
1431 if (!pstAddIndication->psfAdmittedSet) {1417 if (!pstAddIndication->psfAdmittedSet) {
1432 kfree(pstAddIndication);1418 kfree(pstAddIndication);
@@ -1437,10 +1423,10 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu · 4 unmodified lines
1437 return 0;1423 return 0;
1438 }1424 }
1439 1425
1440 pstAddIndication->psfAdmittedSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfAdmittedSet);1426 pstAddIndication->psfAdmittedSet = (struct bcm_connect_mgr_params *)ntohl((ULONG)pstAddIndication->psfAdmittedSet);
1441 1427
1442 /* ACTIVE SET */1428 /* ACTIVE SET */
1443 pstAddIndication->psfActiveSet = (stServiceFlowParamSI *)1429 pstAddIndication->psfActiveSet = (struct bcm_connect_mgr_params *)
1444 GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID);1430 GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID);
1445 if (!pstAddIndication->psfActiveSet) {1431 if (!pstAddIndication->psfActiveSet) {
1446 kfree(pstAddIndication);1432 kfree(pstAddIndication);
@@ -1451,10 +1437,10 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu · 4 unmodified lines
1451 return 0;1437 return 0;
1452 }1438 }
1453 1439
1454 pstAddIndication->psfActiveSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfActiveSet);1440 pstAddIndication->psfActiveSet = (struct bcm_connect_mgr_params *)ntohl((ULONG)pstAddIndication->psfActiveSet);
1455 1441
1456 (*puBufferLength) = sizeof(stLocalSFAddIndication);1442 (*puBufferLength) = sizeof(struct bcm_add_indication);
1457 *(stLocalSFAddIndication *)pvBuffer = *pstAddIndication;1443 *(struct bcm_add_indication *)pvBuffer = *pstAddIndication;
1458 kfree(pstAddIndication);1444 kfree(pstAddIndication);
1459 return 1;1445 return 1;
1460}1446}
@@ -1463,10 +1449,10 @@ static inline stLocalSFAddIndicationAlt · 2 unmodified lines
1463*RestoreCmControlResponseMessage(register struct bcm_mini_adapter *Adapter, register PVOID pvBuffer)1449*RestoreCmControlResponseMessage(register struct bcm_mini_adapter *Adapter, register PVOID pvBuffer)
1464{1450{
1465 ULONG ulStatus = 0;1451 ULONG ulStatus = 0;
1466 stLocalSFAddIndication *pstAddIndication = NULL;1452 struct bcm_add_indication *pstAddIndication = NULL;
1467 stLocalSFAddIndicationAlt *pstAddIndicationDest = NULL;1453 stLocalSFAddIndicationAlt *pstAddIndicationDest = NULL;
1468 1454
1469 pstAddIndication = (stLocalSFAddIndication *)(pvBuffer);1455 pstAddIndication = (struct bcm_add_indication *)(pvBuffer);
1470 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "=====>");1456 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "=====>");
1471 if ((pstAddIndication->u8Type == DSD_REQ) ||1457 if ((pstAddIndication->u8Type == DSD_REQ) ||
1472 (pstAddIndication->u8Type == DSD_RSP) ||1458 (pstAddIndication->u8Type == DSD_RSP) ||
@@ -1553,7 +1539,7 @@ ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter) · 80 unmodified lines
1553 if (Adapter->astTargetDsxBuffer[0].ulTargetDsxBuffer)1539 if (Adapter->astTargetDsxBuffer[0].ulTargetDsxBuffer)
1554 return 1;1540 return 1;
1555 1541
1556 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Size of Each DSX Buffer(Also size of ServiceFlowParamSI): %zx ", sizeof(stServiceFlowParamSI));1542 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Size of Each DSX Buffer(Also size of connection manager parameters): %zx ", sizeof(struct bcm_connect_mgr_params));
1557 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Reading DSX buffer From Target location %x ", DSX_MESSAGE_EXCHANGE_BUFFER);1543 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Reading DSX buffer From Target location %x ", DSX_MESSAGE_EXCHANGE_BUFFER);
1558 1544
1559 Status = rdmalt(Adapter, DSX_MESSAGE_EXCHANGE_BUFFER, (PUINT)&ulTargetDsxBuffersBase, sizeof(UINT));1545 Status = rdmalt(Adapter, DSX_MESSAGE_EXCHANGE_BUFFER, (PUINT)&ulTargetDsxBuffersBase, sizeof(UINT));
@@ -1564,7 +1550,7 @@ ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter) · 4 unmodified lines
1564 1550
1565 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Base Address Of DSX Target Buffer : 0x%lx", ulTargetDsxBuffersBase);1551 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Base Address Of DSX Target Buffer : 0x%lx", ulTargetDsxBuffersBase);
1566 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Tgt Buffer is Now %lx :", ulTargetDsxBuffersBase);1552 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Tgt Buffer is Now %lx :", ulTargetDsxBuffersBase);
1567 ulCntTargetBuffers = DSX_MESSAGE_EXCHANGE_BUFFER_SIZE / sizeof(stServiceFlowParamSI);1553 ulCntTargetBuffers = DSX_MESSAGE_EXCHANGE_BUFFER_SIZE / sizeof(struct bcm_connect_mgr_params);
1568 1554
1569 Adapter->ulTotalTargetBuffersAvailable =1555 Adapter->ulTotalTargetBuffersAvailable =
1570 ulCntTargetBuffers > MAX_TARGET_DSX_BUFFERS ?1556 ulCntTargetBuffers > MAX_TARGET_DSX_BUFFERS ?
@@ -1576,7 +1562,7 @@ ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter) · 5 unmodified lines
1576 Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer = ulTargetDsxBuffersBase;1562 Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer = ulTargetDsxBuffersBase;
1577 Adapter->astTargetDsxBuffer[i].valid = 1;1563 Adapter->astTargetDsxBuffer[i].valid = 1;
1578 Adapter->astTargetDsxBuffer[i].tid = 0;1564 Adapter->astTargetDsxBuffer[i].tid = 0;
1579 ulTargetDsxBuffersBase += sizeof(stServiceFlowParamSI);1565 ulTargetDsxBuffersBase += sizeof(struct bcm_connect_mgr_params);
1580 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Target DSX Buffer %lx setup at 0x%lx",1566 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Target DSX Buffer %lx setup at 0x%lx",
1581 i, Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer);1567 i, Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer);
1582 }1568 }
@@ -1647,7 +1633,7 @@ int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter) · 64 unmodified lines
1647BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer to the Adapter structure */1633BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer to the Adapter structure */
1648 PVOID pvBuffer /* Starting Address of the Buffer, that contains the AddIndication Data */)1634 PVOID pvBuffer /* Starting Address of the Buffer, that contains the AddIndication Data */)
1649{1635{
1650 stServiceFlowParamSI *psfLocalSet = NULL;1636 struct bcm_connect_mgr_params *psfLocalSet = NULL;
1651 stLocalSFAddIndicationAlt *pstAddIndication = NULL;1637 stLocalSFAddIndicationAlt *pstAddIndication = NULL;
1652 stLocalSFChangeIndicationAlt *pstChangeIndication = NULL;1638 stLocalSFChangeIndicationAlt *pstChangeIndication = NULL;
1653 struct bcm_leader *pLeader = NULL;1639 struct bcm_leader *pLeader = NULL;
@@ -1658,7 +1644,7 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer · 4 unmodified lines
1658 */1644 */
1659 pstAddIndication = RestoreCmControlResponseMessage(Adapter, pvBuffer);1645 pstAddIndication = RestoreCmControlResponseMessage(Adapter, pvBuffer);
1660 if (pstAddIndication == NULL) {1646 if (pstAddIndication == NULL) {
1661 ClearTargetDSXBuffer(Adapter, ((stLocalSFAddIndication *)pvBuffer)->u16TID, FALSE);1647 ClearTargetDSXBuffer(Adapter, ((struct bcm_add_indication *)pvBuffer)->u16TID, FALSE);
1662 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message");1648 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message");
1663 return FALSE;1649 return FALSE;
1664 }1650 }
@@ -1870,10 +1856,10 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer · 205 unmodified lines
1870 UINT uiSearchRuleIndex;1856 UINT uiSearchRuleIndex;
1871 ULONG ulSFID;1857 ULONG ulSFID;
1872 1858
1873 pLeader->PLength = sizeof(stLocalSFDeleteIndication);1859 pLeader->PLength = sizeof(struct bcm_del_indication);
1874 *((stLocalSFDeleteIndication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((stLocalSFDeleteIndication *)pstAddIndication);1860 *((struct bcm_del_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((struct bcm_del_indication *)pstAddIndication);
1875 1861
1876 ulSFID = ntohl(((stLocalSFDeleteIndication *)pstAddIndication)->u32SFID);1862 ulSFID = ntohl(((struct bcm_del_indication *)pstAddIndication)->u32SFID);
1877 uiSearchRuleIndex = SearchSfid(Adapter, ulSFID);1863 uiSearchRuleIndex = SearchSfid(Adapter, ulSFID);
1878 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD - Removing connection %x", uiSearchRuleIndex);1864 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD - Removing connection %x", uiSearchRuleIndex);
1879 1865
@@ -1884,7 +1870,7 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer · 4 unmodified lines
1884 }1870 }
1885 1871
1886 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSD RESPONSE TO MAC");1872 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSD RESPONSE TO MAC");
1887 ((stLocalSFDeleteIndication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP;1873 ((struct bcm_del_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP;
1888 CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp);1874 CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp);
1889 }1875 }
1890 case DSD_RSP:1876 case DSD_RSP:
@@ -1927,7 +1913,7 @@ int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, UINT uiSFId · 36 unmodified lines
1927VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter, PUINT puiBuffer)1913VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter, PUINT puiBuffer)
1928{1914{
1929 B_UINT32 u32NumofSFsinMsg = ntohl(*(puiBuffer + 1));1915 B_UINT32 u32NumofSFsinMsg = ntohl(*(puiBuffer + 1));
1930 stIM_SFHostNotify *pHostInfo = NULL;1916 struct bcm_stim_sfhostnotify *pHostInfo = NULL;
1931 UINT uiSearchRuleIndex = 0;1917 UINT uiSearchRuleIndex = 0;
1932 ULONG ulSFID = 0;1918 ULONG ulSFID = 0;
1933 1919
@@ -1936,7 +1922,7 @@ VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter, PUINT puiBuffer · 2 unmodified lines
1936 1922
1937 while (u32NumofSFsinMsg != 0 && u32NumofSFsinMsg < NO_OF_QUEUES) {1923 while (u32NumofSFsinMsg != 0 && u32NumofSFsinMsg < NO_OF_QUEUES) {
1938 u32NumofSFsinMsg--;1924 u32NumofSFsinMsg--;
1939 pHostInfo = (stIM_SFHostNotify *)puiBuffer;1925 pHostInfo = (struct bcm_stim_sfhostnotify *)puiBuffer;
1940 puiBuffer = (PUINT)(pHostInfo + 1);1926 puiBuffer = (PUINT)(pHostInfo + 1);
1941 1927
1942 ulSFID = ntohl(pHostInfo->SFID);1928 ulSFID = ntohl(pHostInfo->SFID);
drivers/staging/bcm/CmHost.h+19−35
@@ -35,8 +35,7 @@ typedef struct stLocalSFAddRequestAlt{ · 34 unmodified lines
35 B_UINT16 u16VCID;35 B_UINT16 u16VCID;
36 36
37 37
38 /// \brief structure ParameterSet38 struct bcm_connect_mgr_params sfParameterSet;
39 stServiceFlowParamSI sfParameterSet;
40 39
41 //USE_MEMORY_MANAGER();40 //USE_MEMORY_MANAGER();
42}stLocalSFAddRequestAlt;41}stLocalSFAddRequestAlt;
@@ -50,12 +49,9 @@ typedef struct stLocalSFAddIndicationAlt{ · 7 unmodified lines
50 B_UINT16 u16CID;49 B_UINT16 u16CID;
51 /// \brief 16bitVCID50 /// \brief 16bitVCID
52 B_UINT16 u16VCID;51 B_UINT16 u16VCID;
53 /// \brief structure AuthorizedSet52 struct bcm_connect_mgr_params sfAuthorizedSet;
54 stServiceFlowParamSI sfAuthorizedSet;53 struct bcm_connect_mgr_params sfAdmittedSet;
55 /// \brief structure AdmittedSet54 struct bcm_connect_mgr_params sfActiveSet;
56 stServiceFlowParamSI sfAdmittedSet;
57 /// \brief structure ActiveSet
58 stServiceFlowParamSI sfActiveSet;
59 55
60 B_UINT8 u8CC; /**< Confirmation Code*/56 B_UINT8 u8CC; /**< Confirmation Code*/
61 B_UINT8 u8Padd; /**< 8-bit Padding */57 B_UINT8 u8Padd; /**< 8-bit Padding */
@@ -72,12 +68,9 @@ typedef struct stLocalSFAddConfirmationAlt{ · 10 unmodified lines
72 B_UINT16 u16CID;68 B_UINT16 u16CID;
73 /// \brief 16bitVCID69 /// \brief 16bitVCID
74 B_UINT16 u16VCID;70 B_UINT16 u16VCID;
75 /// \brief structure AuthorizedSet71 struct bcm_connect_mgr_params sfAuthorizedSet;
76 stServiceFlowParamSI sfAuthorizedSet;72 struct bcm_connect_mgr_params sfAdmittedSet;
77 /// \brief structure AdmittedSet73 struct bcm_connect_mgr_params sfActiveSet;
78 stServiceFlowParamSI sfAdmittedSet;
79 /// \brief structure ActiveSet
80 stServiceFlowParamSI sfActiveSet;
81}stLocalSFAddConfirmationAlt;74}stLocalSFAddConfirmationAlt;
82 75
83 76
@@ -91,16 +84,13 @@ typedef struct stLocalSFChangeRequestAlt{ · 7 unmodified lines
91 /// \brief 16bitVCID84 /// \brief 16bitVCID
92 B_UINT16 u16VCID;85 B_UINT16 u16VCID;
93 /*86 /*
94 //Pointer location at which following Service Flow param Structure can be read87 //Pointer location at which following connection manager param Structure can be read
95 //from the target. We get only the address location and we need to read out the88 //from the target. We only get the address location and we need to read out the
96 //entire SF param structure at the given location on target89 //entire connection manager param structure at the given location on target
97 */90 */
98 /// \brief structure AuthorizedSet91 struct bcm_connect_mgr_params sfAuthorizedSet;
99 stServiceFlowParamSI sfAuthorizedSet;92 struct bcm_connect_mgr_params sfAdmittedSet;
100 /// \brief structure AdmittedSet93 struct bcm_connect_mgr_params sfActiveSet;
101 stServiceFlowParamSI sfAdmittedSet;
102 /// \brief structure ParameterSet
103 stServiceFlowParamSI sfActiveSet;
104 94
105 B_UINT8 u8CC; /**< Confirmation Code*/95 B_UINT8 u8CC; /**< Confirmation Code*/
106 B_UINT8 u8Padd; /**< 8-bit Padding */96 B_UINT8 u8Padd; /**< 8-bit Padding */
@@ -117,12 +107,9 @@ typedef struct stLocalSFChangeConfirmationAlt{ · 10 unmodified lines
117 B_UINT16 u16CID;107 B_UINT16 u16CID;
118 /// \brief 16bitVCID108 /// \brief 16bitVCID
119 B_UINT16 u16VCID;109 B_UINT16 u16VCID;
120 /// \brief structure AuthorizedSet110 struct bcm_connect_mgr_params sfAuthorizedSet;
121 stServiceFlowParamSI sfAuthorizedSet;111 struct bcm_connect_mgr_params sfAdmittedSet;
122 /// \brief structure AdmittedSet112 struct bcm_connect_mgr_params sfActiveSet;
123 stServiceFlowParamSI sfAdmittedSet;
124 /// \brief structure ActiveSet
125 stServiceFlowParamSI sfActiveSet;
126 113
127}stLocalSFChangeConfirmationAlt;114}stLocalSFChangeConfirmationAlt;
128 115
@@ -135,12 +122,9 @@ typedef struct stLocalSFChangeIndicationAlt{ · 6 unmodified lines
135 B_UINT16 u16CID;122 B_UINT16 u16CID;
136 /// \brief 16bitVCID123 /// \brief 16bitVCID
137 B_UINT16 u16VCID;124 B_UINT16 u16VCID;
138 /// \brief structure AuthorizedSet125 struct bcm_connect_mgr_params sfAuthorizedSet;
139 stServiceFlowParamSI sfAuthorizedSet;126 struct bcm_connect_mgr_params sfAdmittedSet;
140 /// \brief structure AdmittedSet127 struct bcm_connect_mgr_params sfActiveSet;
141 stServiceFlowParamSI sfAdmittedSet;
142 /// \brief structure ActiveSet
143 stServiceFlowParamSI sfActiveSet;
144 128
145 B_UINT8 u8CC; /**< Confirmation Code*/129 B_UINT8 u8CC; /**< Confirmation Code*/
146 B_UINT8 u8Padd; /**< 8-bit Padding */130 B_UINT8 u8Padd; /**< 8-bit Padding */
drivers/staging/bcm/InterfaceInit.c+13−4
@@ -8,6 +8,7 @@ static struct usb_device_id InterfaceUsbtable[] = { · 7 unmodified lines
8 { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) },8 { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) },
9 { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) },9 { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) },
10 { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) },10 { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) },
11 { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_226) },
11 { }12 { }
12};13};
13MODULE_DEVICE_TABLE(usb, InterfaceUsbtable);14MODULE_DEVICE_TABLE(usb, InterfaceUsbtable);
@@ -669,16 +670,24 @@ struct class *bcm_class; · 655 unmodified lines
669 670
670static __init int bcm_init(void)671static __init int bcm_init(void)
671{672{
672 printk(KERN_INFO "%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION);673 int retval;
673 printk(KERN_INFO "%s\n", DRV_COPYRIGHT);674
675 pr_info("%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION);
676 pr_info("%s\n", DRV_COPYRIGHT);
674 677
675 bcm_class = class_create(THIS_MODULE, DRV_NAME);678 bcm_class = class_create(THIS_MODULE, DRV_NAME);
676 if (IS_ERR(bcm_class)) {679 if (IS_ERR(bcm_class)) {
677 printk(KERN_ERR DRV_NAME ": could not create class\n");680 pr_err(DRV_NAME ": could not create class\n");
678 return PTR_ERR(bcm_class);681 return PTR_ERR(bcm_class);
679 }682 }
680 683
681 return usb_register(&usbbcm_driver);684 retval = usb_register(&usbbcm_driver);
685 if (retval < 0) {
686 pr_err(DRV_NAME ": could not register usb driver\n");
687 class_destroy(bcm_class);
688 return retval;
689 }
690 return 0;
682}691}
683 692
684static __exit void bcm_exit(void)693static __exit void bcm_exit(void)
drivers/staging/bcm/InterfaceInit.h+16−17
@@ -1,27 +1,26 @@
1#ifndef _INTERFACE_INIT_H1#ifndef _INTERFACE_INIT_H
2#define _INTERFACE_INIT_H2#define _INTERFACE_INIT_H
3 3
4#define BCM_USB_VENDOR_ID_T3 0x198f4#define BCM_USB_VENDOR_ID_T3 0x198f
5#define BCM_USB_VENDOR_ID_FOXCONN 0x04895#define BCM_USB_VENDOR_ID_FOXCONN 0x0489
6#define BCM_USB_VENDOR_ID_ZTE 0x19d26#define BCM_USB_VENDOR_ID_ZTE 0x19d2
7 7
8#define BCM_USB_PRODUCT_ID_T3 0x03008#define BCM_USB_PRODUCT_ID_T3 0x0300
9#define BCM_USB_PRODUCT_ID_T3B 0x02109#define BCM_USB_PRODUCT_ID_T3B 0x0210
10#define BCM_USB_PRODUCT_ID_T3L 0x022010#define BCM_USB_PRODUCT_ID_T3L 0x0220
11#define BCM_USB_PRODUCT_ID_SM250 0xbccd11#define BCM_USB_PRODUCT_ID_SM250 0xbccd
12#define BCM_USB_PRODUCT_ID_SYM 0x15E12#define BCM_USB_PRODUCT_ID_SYM 0x15E
13#define BCM_USB_PRODUCT_ID_1901 0xe01713#define BCM_USB_PRODUCT_ID_1901 0xe017
14#define BCM_USB_PRODUCT_ID_226 0x013214#define BCM_USB_PRODUCT_ID_226 0x0132 /* not sure if this is valid */
15#define BCM_USB_PRODUCT_ID_ZTE_TU25 0x000715#define BCM_USB_PRODUCT_ID_ZTE_226 0x172
16#define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007
16 17
17#define BCM_USB_MINOR_BASE 19218#define BCM_USB_MINOR_BASE 192
18 19
20int InterfaceInitialize(void);
19 21
20INT InterfaceInitialize(void);22int InterfaceExit(void);
21 23
22INT InterfaceExit(void);24int usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter);
23
24INT usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter);
25 25
26#endif26#endif
27
drivers/staging/bcm/Kconfig+1−1
@@ -1,6 +1,6 @@
1config BCM_WIMAX1config BCM_WIMAX
2 tristate "Beceem BCS200/BCS220-3 and BCSM250 wimax support"2 tristate "Beceem BCS200/BCS220-3 and BCSM250 wimax support"
3 depends on USB && NET && EXPERIMENTAL3 depends on USB && NET
4 default N4 default N
5 help5 help
6 This is an experimental driver for the Beceem WIMAX chipset used6 This is an experimental driver for the Beceem WIMAX chipset used
drivers/staging/bcm/Misc.c+4−1
@@ -752,7 +752,10 @@ VOID DumpPackInfo(struct bcm_mini_adapter *Adapter) · 751 unmodified lines
752 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AuthzSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAuthorizedSet);752 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AuthzSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAuthorizedSet);
753 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ClassifyPrority: %x\n", Adapter->PackInfo[uiLoopIndex].bClassifierPriority);753 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ClassifyPrority: %x\n", Adapter->PackInfo[uiLoopIndex].bClassifierPriority);
754 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxLatency: %x\n", Adapter->PackInfo[uiLoopIndex].uiMaxLatency);754 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxLatency: %x\n", Adapter->PackInfo[uiLoopIndex].uiMaxLatency);
755 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ServiceClassName: %x %x %x %x\n", Adapter->PackInfo[uiLoopIndex].ucServiceClassName[0], Adapter->PackInfo[uiLoopIndex].ucServiceClassName[1], Adapter->PackInfo[uiLoopIndex].ucServiceClassName[2], Adapter->PackInfo[uiLoopIndex].ucServiceClassName[3]);755 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO,
756 DBG_LVL_ALL, "ServiceClassName: %*ph\n",
757 4, Adapter->PackInfo[uiLoopIndex].
758 ucServiceClassName);
756/* BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bHeaderSuppressionEnabled :%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled);759/* BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bHeaderSuppressionEnabled :%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled);
757 * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalTxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalTxBytes);760 * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalTxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalTxBytes);
758 * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalRxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalRxBytes);761 * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalRxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalRxBytes);
drivers/staging/bcm/PHSModule.c+2−2
@@ -66,7 +66,7 @@ Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapte · 65 unmodified lines
66 BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF.66 BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF.
67 67
68Return: STATUS_SUCCESS - If the send was successful.68Return: STATUS_SUCCESS - If the send was successful.
69 Other - If an error occured.69 Other - If an error occurred.
70*/70*/
71 71
72int PHSTransmit(struct bcm_mini_adapter *Adapter,72int PHSTransmit(struct bcm_mini_adapter *Adapter,
@@ -346,7 +346,7 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension, struct bcm_mini_adapter · 273 unmodified lines
346 346
347 347
348 348
349 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successfull");349 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successful");
350 return STATUS_SUCCESS;350 return STATUS_SUCCESS;
351}351}
352 352
drivers/staging/bcm/Prototypes.h+1−1
@@ -95,7 +95,7 @@ void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter); · 94 unmodified lines
95int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo);95int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo);
96 96
97void CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter,97void CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter,
98 CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex);98 struct bcm_connect_mgr_params *psfLocalSet, UINT uiSearchRuleIndex);
99 99
100VOID ResetCounters(struct bcm_mini_adapter *Adapter);100VOID ResetCounters(struct bcm_mini_adapter *Adapter);
101 101
drivers/staging/bcm/Transmit.c+106−128
@@ -1,162 +1,149 @@
1/**1/**
2@file Transmit.c2 * @file Transmit.c
3@defgroup tx_functions Transmission3 * @defgroup tx_functions Transmission
4@section Queueing4 * @section Queueing
5@dot5 * @dot
6digraph transmit1 {6 * digraph transmit1 {
7node[shape=box]7 * node[shape=box]
8edge[weight=5;color=red]8 * edge[weight=5;color=red]
9 9 *
10bcm_transmit->GetPacketQueueIndex[label="IP Packet"]10 * bcm_transmit->GetPacketQueueIndex[label="IP Packet"]
11GetPacketQueueIndex->IpVersion4[label="IPV4"]11 * GetPacketQueueIndex->IpVersion4[label="IPV4"]
12GetPacketQueueIndex->IpVersion6[label="IPV6"]12 * GetPacketQueueIndex->IpVersion6[label="IPV6"]
13}13 * }
14 14 *
15@enddot15 * @enddot
16 16 *
17@section De-Queueing17 * @section De-Queueing
18@dot18 * @dot
19digraph transmit2 {19 * digraph transmit2 {
20node[shape=box]20 * node[shape=box]
21edge[weight=5;color=red]21 * edge[weight=5;color=red]
22interrupt_service_thread->transmit_packets22 * interrupt_service_thread->transmit_packets
23tx_pkt_hdler->transmit_packets23 * tx_pkt_hdler->transmit_packets
24transmit_packets->CheckAndSendPacketFromIndex24 * transmit_packets->CheckAndSendPacketFromIndex
25transmit_packets->UpdateTokenCount25 * transmit_packets->UpdateTokenCount
26CheckAndSendPacketFromIndex->PruneQueue26 * CheckAndSendPacketFromIndex->PruneQueue
27CheckAndSendPacketFromIndex->IsPacketAllowedForFlow27 * CheckAndSendPacketFromIndex->IsPacketAllowedForFlow
28CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"]28 * CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"]
29SendControlPacket->bcm_cmd5329 * SendControlPacket->bcm_cmd53
30CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"]30 * CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"]
31SendPacketFromQueue->SetupNextSend->bcm_cmd5331 * SendPacketFromQueue->SetupNextSend->bcm_cmd53
32}32 * }
33@enddot33 * @enddot
34*/34 */
35 35
36#include "headers.h"36#include "headers.h"
37 37
38
39/**38/**
40@ingroup ctrl_pkt_functions39 * @ingroup ctrl_pkt_functions
41This function dispatches control packet to the h/w interface40 * This function dispatches control packet to the h/w interface
42@return zero(success) or -ve value(failure)41 * @return zero(success) or -ve value(failure)
43*/42 */
44INT SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket)43int SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket)
45{44{
46 struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket;45 struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket;
47 46
48 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx");47 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx");
49 if(!pControlPacket || !Adapter)48 if (!pControlPacket || !Adapter) {
50 {49 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter");
51 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter");50 return STATUS_FAILURE;
51 }
52 if ((atomic_read(&Adapter->CurrNumFreeTxDesc) <
53 ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1)) {
54 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET");
52 return STATUS_FAILURE;55 return STATUS_FAILURE;
53 }56 }
54 if((atomic_read( &Adapter->CurrNumFreeTxDesc ) <
55 ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1))
56 {
57 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET");
58 return STATUS_FAILURE;
59 }
60 57
61 /* Update the netdevice statistics */58 /* Update the netdevice statistics */
62 /* Dump Packet */59 /* Dump Packet */
63 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status);60 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status);
64 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x",PLeader->Vcid);61 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x", PLeader->Vcid);
65 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength);62 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x", PLeader->PLength);
66 if(Adapter->device_removed)63 if (Adapter->device_removed)
67 return 0;64 return 0;
68 65
69 if (netif_msg_pktdata(Adapter))66 if (netif_msg_pktdata(Adapter))
70 print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE,67 print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE,
71 16, 1, pControlPacket, PLeader->PLength + LEADER_SIZE, 0);68 16, 1, pControlPacket, PLeader->PLength + LEADER_SIZE, 0);
72 69
73 Adapter->interface_transmit(Adapter->pvInterfaceAdapter,70 Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
74 pControlPacket, (PLeader->PLength + LEADER_SIZE));71 pControlPacket, (PLeader->PLength + LEADER_SIZE));
75 72
76 atomic_dec(&Adapter->CurrNumFreeTxDesc);73 atomic_dec(&Adapter->CurrNumFreeTxDesc);
77 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");74 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
78 return STATUS_SUCCESS;75 return STATUS_SUCCESS;
79}76}
80 77
81/**78/**
82@ingroup tx_functions79 * @ingroup tx_functions
83This function despatches the IP packets with the given vcid80 * This function despatches the IP packets with the given vcid
84to the target via the host h/w interface.81 * to the target via the host h/w interface.
85@return zero(success) or -ve value(failure)82 * @return zero(success) or -ve value(failure)
86*/83 */
87INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USHORT Vcid)84int SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USHORT Vcid)
88{85{
89 int status=0;86 int status = 0;
90 BOOLEAN bHeaderSupressionEnabled = FALSE;87 BOOLEAN bHeaderSupressionEnabled = FALSE;
91 B_UINT16 uiClassifierRuleID;88 B_UINT16 uiClassifierRuleID;
92 u16 QueueIndex = skb_get_queue_mapping(Packet);89 u16 QueueIndex = skb_get_queue_mapping(Packet);
93 struct bcm_leader Leader={0};90 struct bcm_leader Leader = {0};
94 91
95 if(Packet->len > MAX_DEVICE_DESC_SIZE)92 if (Packet->len > MAX_DEVICE_DESC_SIZE) {
96 {
97 status = STATUS_FAILURE;93 status = STATUS_FAILURE;
98 goto errExit;94 goto errExit;
99 }95 }
100 96
101 /* Get the Classifier Rule ID */97 /* Get the Classifier Rule ID */
102 uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET);98 uiClassifierRuleID = *((UINT32 *) (Packet->cb) + SKB_CB_CLASSIFICATION_OFFSET);
103 99
104 bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled100 bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled
105 & Adapter->bPHSEnabled;101 & Adapter->bPHSEnabled;
106 102
107 if(Adapter->device_removed)103 if (Adapter->device_removed) {
108 {
109 status = STATUS_FAILURE;104 status = STATUS_FAILURE;
110 goto errExit;105 goto errExit;
111 }106 }
112 107
113 status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled,108 status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled,
114 (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport);109 (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport);
115 110
116 if(status != STATUS_SUCCESS)111 if (status != STATUS_SUCCESS) {
117 {112 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n");
118 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n");
119 goto errExit;113 goto errExit;
120 }114 }
121 115
122 Leader.Vcid = Vcid;116 Leader.Vcid = Vcid;
123 117
124 if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET ))118 if (TCP_ACK == *((UINT32 *) (Packet->cb) + SKB_CB_TCPACK_OFFSET))
125 Leader.Status = LEADER_STATUS_TCP_ACK;119 Leader.Status = LEADER_STATUS_TCP_ACK;
126 else120 else
127 Leader.Status = LEADER_STATUS;121 Leader.Status = LEADER_STATUS;
128 122
129 if(Adapter->PackInfo[QueueIndex].bEthCSSupport)123 if (Adapter->PackInfo[QueueIndex].bEthCSSupport) {
130 {
131 Leader.PLength = Packet->len;124 Leader.PLength = Packet->len;
132 if(skb_headroom(Packet) < LEADER_SIZE)125 if (skb_headroom(Packet) < LEADER_SIZE) {
133 {126 status = skb_cow(Packet, LEADER_SIZE);
134 if((status = skb_cow(Packet,LEADER_SIZE)))127 if (status) {
135 {128 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit : Failed To Increase headRoom\n");
136 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"bcm_transmit : Failed To Increase headRoom\n");
137 goto errExit;129 goto errExit;
138 }130 }
139 }131 }
140 skb_push(Packet, LEADER_SIZE);132 skb_push(Packet, LEADER_SIZE);
141 memcpy(Packet->data, &Leader, LEADER_SIZE);133 memcpy(Packet->data, &Leader, LEADER_SIZE);
142 }134 } else {
143 else
144 {
145 Leader.PLength = Packet->len - ETH_HLEN;135 Leader.PLength = Packet->len - ETH_HLEN;
146 memcpy((struct bcm_leader *)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);136 memcpy((struct bcm_leader *)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);
147 }137 }
148 138
149 status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,139 status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
150 Packet->data, (Leader.PLength + LEADER_SIZE));140 Packet->data, (Leader.PLength + LEADER_SIZE));
151 if(status)141 if (status) {
152 {
153 ++Adapter->dev->stats.tx_errors;142 ++Adapter->dev->stats.tx_errors;
154 if (netif_msg_tx_err(Adapter))143 if (netif_msg_tx_err(Adapter))
155 pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name,144 pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name,
156 status);145 status);
157 }146 } else {
158 else
159 {
160 struct net_device_stats *netstats = &Adapter->dev->stats;147 struct net_device_stats *netstats = &Adapter->dev->stats;
161 Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;148 Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;
162 149
@@ -175,7 +162,6 @@ INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USH · 12 unmodified lines
175 atomic_dec(&Adapter->CurrNumFreeTxDesc);162 atomic_dec(&Adapter->CurrNumFreeTxDesc);
176 163
177errExit:164errExit:
178
179 dev_kfree_skb(Packet);165 dev_kfree_skb(Packet);
180 return status;166 return status;
181}167}
@@ -188,73 +174,65 @@ static int tx_pending(struct bcm_mini_adapter *Adapter) · 6 unmodified lines
188}174}
189 175
190/**176/**
191@ingroup tx_functions177 * @ingroup tx_functions
192Transmit thread178 * Transmit thread
193*/179 */
194int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter object*/180int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter object*/)
195 )
196{181{
197 int status = 0;182 int status = 0;
198 183
199 while(! kthread_should_stop()) {184 while (!kthread_should_stop()) {
200 /* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */185 /* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */
201 if(Adapter->LinkUpStatus)186 if (Adapter->LinkUpStatus)
202 wait_event_timeout(Adapter->tx_packet_wait_queue,187 wait_event_timeout(Adapter->tx_packet_wait_queue,
203 tx_pending(Adapter), msecs_to_jiffies(10));188 tx_pending(Adapter), msecs_to_jiffies(10));
204 else189 else
205 wait_event_interruptible(Adapter->tx_packet_wait_queue,190 wait_event_interruptible(Adapter->tx_packet_wait_queue,
206 tx_pending(Adapter));191 tx_pending(Adapter));
207 192
208 if (Adapter->device_removed)193 if (Adapter->device_removed)
209 break;194 break;
210 195
211 if(Adapter->downloadDDR == 1)196 if (Adapter->downloadDDR == 1) {
212 {197 Adapter->downloadDDR += 1;
213 Adapter->downloadDDR +=1;
214 status = download_ddr_settings(Adapter);198 status = download_ddr_settings(Adapter);
215 if(status)199 if (status)
216 pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status);200 pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status);
217 continue;201 continue;
218 }202 }
219 203
220 //Check end point for halt/stall.204 /* Check end point for halt/stall. */
221 if(Adapter->bEndPointHalted == TRUE)205 if (Adapter->bEndPointHalted == TRUE) {
222 {
223 Bcm_clear_halt_of_endpoints(Adapter);206 Bcm_clear_halt_of_endpoints(Adapter);
224 Adapter->bEndPointHalted = FALSE;207 Adapter->bEndPointHalted = FALSE;
225 StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));208 StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
226 }209 }
227 210
228 if(Adapter->LinkUpStatus && !Adapter->IdleMode)211 if (Adapter->LinkUpStatus && !Adapter->IdleMode) {
229 {212 if (atomic_read(&Adapter->TotalPacketCount))
230 if(atomic_read(&Adapter->TotalPacketCount))
231 {
232 update_per_sf_desc_cnts(Adapter);213 update_per_sf_desc_cnts(Adapter);
233 }
234 }214 }
235 215
236 if( atomic_read(&Adapter->CurrNumFreeTxDesc) &&216 if (atomic_read(&Adapter->CurrNumFreeTxDesc) &&
237 Adapter->LinkStatus == SYNC_UP_REQUEST &&217 Adapter->LinkStatus == SYNC_UP_REQUEST &&
238 !Adapter->bSyncUpRequestSent)218 !Adapter->bSyncUpRequestSent) {
239 {219
240 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage");220 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage");
241 LinkMessage(Adapter);221 LinkMessage(Adapter);
242 }222 }
243 223
244 if((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount))224 if ((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount)) {
245 {225 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up");
246 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up");226 Adapter->usIdleModePattern = ABORT_IDLE_MODE;
247 Adapter->usIdleModePattern = ABORT_IDLE_MODE;227 Adapter->bWakeUpDevice = TRUE;
248 Adapter->bWakeUpDevice = TRUE;228 wake_up(&Adapter->process_rx_cntrlpkt);
249 wake_up(&Adapter->process_rx_cntrlpkt);
250 }229 }
251 230
252 transmit_packets(Adapter);231 transmit_packets(Adapter);
253
254 atomic_set(&Adapter->TxPktAvail, 0);232 atomic_set(&Adapter->TxPktAvail, 0);
255 }233 }
256 234
257 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");235 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");
258 Adapter->transmit_packet_thread = NULL;236 Adapter->transmit_packet_thread = NULL;
259 return 0;237 return 0;
260}238}
drivers/staging/bcm/cntrl_SignalingInterface.h+296−408
@@ -1,423 +1,311 @@
1#ifndef CNTRL_SIGNALING_INTERFACE_1#ifndef CNTRL_SIGNALING_INTERFACE_
2#define CNTRL_SIGNALING_INTERFACE_2#define CNTRL_SIGNALING_INTERFACE_
3 3
4 4#define DSA_REQ 11
5 5#define DSA_RSP 12
6 6#define DSA_ACK 13
7#define DSA_REQ 117#define DSC_REQ 14
8#define DSA_RSP 128#define DSC_RSP 15
9#define DSA_ACK 139#define DSC_ACK 16
10#define DSC_REQ 1410#define DSD_REQ 17
11#define DSC_RSP 1511#define DSD_RSP 18
12#define DSC_ACK 1612#define DSD_ACK 19
13#define DSD_REQ 1713#define MAX_CLASSIFIERS_IN_SF 4
14#define DSD_RSP 1814
15#define DSD_ACK 1915#define MAX_STRING_LEN 20
16#define MAX_CLASSIFIERS_IN_SF 416#define MAX_PHS_LENGTHS 255
17 17#define VENDOR_PHS_PARAM_LENGTH 10
18 18#define MAX_NUM_ACTIVE_BS 10
19#define MAX_STRING_LEN 2019#define AUTH_TOKEN_LENGTH 10
20#define MAX_PHS_LENGTHS 25520#define NUM_HARQ_CHANNELS 16 /* Changed from 10 to 16 to accommodate all HARQ channels */
21#define VENDOR_PHS_PARAM_LENGTH 1021#define VENDOR_CLASSIFIER_PARAM_LENGTH 1 /* Changed the size to 1 byte since we dnt use it */
22#define MAX_NUM_ACTIVE_BS 1022#define VENDOR_SPECIF_QOS_PARAM 1
23#define AUTH_TOKEN_LENGTH 1023#define VENDOR_PHS_PARAM_LENGTH 10
24#define NUM_HARQ_CHANNELS 16 //Changed from 10 to 16 to accommodate all HARQ channels24#define MBS_CONTENTS_ID_LENGTH 10
25#define VENDOR_CLASSIFIER_PARAM_LENGTH 1 //Changed the size to 1 byte since we dnt use it25#define GLOBAL_SF_CLASSNAME_LENGTH 6
26#define VENDOR_SPECIF_QOS_PARAM 126
27#define VENDOR_PHS_PARAM_LENGTH 1027#define TYPE_OF_SERVICE_LENGTH 3
28#define MBS_CONTENTS_ID_LENGTH 1028#define IP_MASKED_SRC_ADDRESS_LENGTH 32
29#define GLOBAL_SF_CLASSNAME_LENGTH 629#define IP_MASKED_DEST_ADDRESS_LENGTH 32
30 30#define PROTOCOL_SRC_PORT_RANGE_LENGTH 4
31#define TYPE_OF_SERVICE_LENGTH 331#define PROTOCOL_DEST_PORT_RANGE_LENGTH 4
32#define IP_MASKED_SRC_ADDRESS_LENGTH 3232#define ETHERNET_DEST_MAC_ADDR_LENGTH 12
33#define IP_MASKED_DEST_ADDRESS_LENGTH 3233#define ETHERNET_SRC_MAC_ADDR_LENGTH 12
34#define PROTOCOL_SRC_PORT_RANGE_LENGTH 434#define NUM_ETHERTYPE_BYTES 3
35#define PROTOCOL_DEST_PORT_RANGE_LENGTH 435#define NUM_IPV6_FLOWLABLE_BYTES 3
36#define ETHERNET_DEST_MAC_ADDR_LENGTH 1236
37#define ETHERNET_SRC_MAC_ADDR_LENGTH 1237struct bcm_packet_class_rules {
38#define NUM_ETHERTYPE_BYTES 338 /* 16bit UserPriority Of The Service Flow */
39#define NUM_IPV6_FLOWLABLE_BYTES 339 B_UINT16 u16UserPriority;
40 40 /* 16bit VLANID Of The Service Flow */
41 41 B_UINT16 u16VLANID;
42////////////////////////////////////////////////////////////////////////////////42 /* 16bit Packet Classification RuleIndex Of The Service Flow */
43////////////////////////structure Definitions///////////////////////////////////43 B_UINT16 u16PacketClassificationRuleIndex;
44////////////////////////////////////////////////////////////////////////////////44 /* 8bit Classifier Rule Priority Of The Service Flow */
45/// \brief class cCPacketClassificationRule45 B_UINT8 u8ClassifierRulePriority;
46struct _stCPacketClassificationRuleSI{46 /* Length of IP TypeOfService field */
47 47 B_UINT8 u8IPTypeOfServiceLength;
48 /** 16bit UserPriority Of The Service Flow*/48 /* 3bytes IP TypeOfService */
49 B_UINT16 u16UserPriority;49 B_UINT8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH];
50 /** 16bit VLANID Of The Service Flow*/50 /* Protocol used in classification of Service Flow */
51 B_UINT16 u16VLANID;51 B_UINT8 u8Protocol;
52 /** 16bit Packet Classification RuleIndex Of The Service Flow*/52 /* Length of IP Masked Source Address */
53 B_UINT16 u16PacketClassificationRuleIndex;53 B_UINT8 u8IPMaskedSourceAddressLength;
54 /** 8bit Classifier Rule Priority Of The Service Flow*/54 /* IP Masked Source Address used in classification for the Service Flow */
55 B_UINT8 u8ClassifierRulePriority;55 B_UINT8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH];
56 /** Length of IP TypeOfService field*/56 /* Length of IP Destination Address */
57 B_UINT8 u8IPTypeOfServiceLength;57 B_UINT8 u8IPDestinationAddressLength;
58 /** 3bytes IP TypeOfService */58 /* IP Destination Address used in classification for the Service Flow */
59 B_UINT8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH];59 B_UINT8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH];
60 /** Protocol used in classification of Service Flow*/60 /* Length of Protocol Source Port Range */
61 B_UINT8 u8Protocol;61 B_UINT8 u8ProtocolSourcePortRangeLength;
62 /** Length of IP Masked Source Address */62 /* Protocol Source Port Range used in the Service Flow */
63 B_UINT8 u8IPMaskedSourceAddressLength;63 B_UINT8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH];
64 /** IP Masked Source Address used in classification for the Service Flow*/64 /* Length of Protocol Dest Port Range */
65 B_UINT8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH];65 B_UINT8 u8ProtocolDestPortRangeLength;
66 /** Length of IP Destination Address */66 /* Protocol Dest Port Range used in the Service Flow */
67 B_UINT8 u8IPDestinationAddressLength;67 B_UINT8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH];
68 /** IP Destination Address used in classification for the Service Flow*/68 /* Length of Ethernet Destination MAC Address */
69 B_UINT8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH];69 B_UINT8 u8EthernetDestMacAddressLength;
70 /** Length of Protocol Source Port Range */70 /* Ethernet Destination MAC Address used in classification of the Service Flow */
71 B_UINT8 u8ProtocolSourcePortRangeLength;71 B_UINT8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH];
72 /** Protocol Source Port Range used in the Service Flow*/72 /* Length of Ethernet Source MAC Address */
73 B_UINT8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH];73 B_UINT8 u8EthernetSourceMACAddressLength;
74 /** Length of Protocol Dest Port Range */74 /* Ethernet Source MAC Address used in classification of the Service Flow */
75 B_UINT8 u8ProtocolDestPortRangeLength;75 B_UINT8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH];
76 /** Protocol Dest Port Range used in the Service Flow*/76 /* Length of Ethertype */
77 B_UINT8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH];77 B_UINT8 u8EthertypeLength;
78 /** Length of Ethernet Destination MAC Address */78 /* 3bytes Ethertype Of The Service Flow */
79 B_UINT8 u8EthernetDestMacAddressLength;79 B_UINT8 u8Ethertype[NUM_ETHERTYPE_BYTES];
80 /** Ethernet Destination MAC Address used in classification of the Service Flow*/80 /* 8bit Associated PHSI Of The Service Flow */
81 B_UINT8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH];81 B_UINT8 u8AssociatedPHSI;
82 /** Length of Ethernet Source MAC Address */82 /* Length of Vendor Specific Classifier Param length Of The Service Flow */
83 B_UINT8 u8EthernetSourceMACAddressLength;83 B_UINT8 u8VendorSpecificClassifierParamLength;
84 /** Ethernet Source MAC Address used in classification of the Service Flow*/84 /* Vendor Specific Classifier Param Of The Service Flow */
85 B_UINT8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH];85 B_UINT8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH];
86 /** Length of Ethertype */86 /* Length Of IPv6 Flow Lable of the Service Flow */
87 B_UINT8 u8EthertypeLength;87 B_UINT8 u8IPv6FlowLableLength;
88 /** 3bytes Ethertype Of The Service Flow*/88 /* IPv6 Flow Lable Of The Service Flow */
89 B_UINT8 u8Ethertype[NUM_ETHERTYPE_BYTES];89 B_UINT8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES];
90 /** 8bit Associated PHSI Of The Service Flow*/90 /* Action associated with the classifier rule */
91 B_UINT8 u8AssociatedPHSI;91 B_UINT8 u8ClassifierActionRule;
92 /** Length of Vendor Specific Classifier Param length Of The Service Flow*/92 B_UINT16 u16ValidityBitMap;
93 B_UINT8 u8VendorSpecificClassifierParamLength;
94 /** Vendor Specific Classifier Param Of The Service Flow*/
95 B_UINT8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH];
96 /** Length Of IPv6 Flow Lable of the Service Flow*/
97 B_UINT8 u8IPv6FlowLableLength;
98 /** IPv6 Flow Lable Of The Service Flow*/
99 B_UINT8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES];
100 /** Action associated with the classifier rule*/
101 B_UINT8 u8ClassifierActionRule;
102 B_UINT16 u16ValidityBitMap;
103};93};
104typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI,stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI;
105
106/// \brief class CPhsRuleSI
107typedef struct _stPhsRuleSI {
108 /** 8bit PHS Index Of The Service Flow*/
109 B_UINT8 u8PHSI;
110 /** PHSF Length Of The Service Flow*/
111 B_UINT8 u8PHSFLength;
112 /** String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS*/
113 B_UINT8 u8PHSF[MAX_PHS_LENGTHS];
114 /** PHSM Length Of The Service Flow*/
115 B_UINT8 u8PHSMLength;
116 /** PHS Mask for the SF*/
117 B_UINT8 u8PHSM[MAX_PHS_LENGTHS];
118 /** 8bit Total number of bytes to be suppressed for the Service Flow*/
119 B_UINT8 u8PHSS;
120 /** 8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */
121 B_UINT8 u8PHSV;
122 /** Vendor Specific PHS param Length Of The Service Flow*/
123 B_UINT8 u8VendorSpecificPHSParamsLength;
124 /** Vendor Specific PHS param Of The Service Flow*/
125 B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
126
127 B_UINT8 u8Padding[2];
128}stPhsRuleSI,*pstPhsRuleSI;
129typedef stPhsRuleSI CPhsRuleSI;
130 94
131/// \brief structure cConvergenceSLTypes95struct bcm_phs_rules {
132struct _stConvergenceSLTypes{96 /* 8bit PHS Index Of The Service Flow */
133 /** 8bit Phs Classfier Action Of The Service Flow*/97 B_UINT8 u8PHSI;
134 B_UINT8 u8ClassfierDSCAction;98 /* PHSF Length Of The Service Flow */
135 /** 8bit Phs DSC Action Of The Service Flow*/99 B_UINT8 u8PHSFLength;
136 B_UINT8 u8PhsDSCAction;100 /* String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS */
137 /** 16bit Padding */101 B_UINT8 u8PHSF[MAX_PHS_LENGTHS];
138 B_UINT8 u8Padding[2];102 /* PHSM Length Of The Service Flow */
139 /// \brief class cCPacketClassificationRule103 B_UINT8 u8PHSMLength;
140 stCPacketClassificationRuleSI cCPacketClassificationRule;104 /* PHS Mask for the SF */
141 /// \brief class CPhsRuleSI105 B_UINT8 u8PHSM[MAX_PHS_LENGTHS];
142 struct _stPhsRuleSI cPhsRule;106 /* 8bit Total number of bytes to be suppressed for the Service Flow */
107 B_UINT8 u8PHSS;
108 /* 8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */
109 B_UINT8 u8PHSV;
110 /* Vendor Specific PHS param Length Of The Service Flow */
111 B_UINT8 u8VendorSpecificPHSParamsLength;
112 /* Vendor Specific PHS param Of The Service Flow */
113 B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
114 B_UINT8 u8Padding[2];
143};115};
144typedef struct _stConvergenceSLTypes stConvergenceSLTypes,CConvergenceSLTypes, *pstConvergenceSLTypes;
145
146
147/// \brief structure CServiceFlowParamSI
148typedef struct _stServiceFlowParamSI{
149
150 /** 32bitSFID Of The Service Flow*/
151 B_UINT32 u32SFID;
152
153 /** 32bit Maximum Sustained Traffic Rate of the Service Flow*/
154 B_UINT32 u32MaxSustainedTrafficRate;
155
156 /** 32bit Maximum Traffic Burst allowed for the Service Flow*/
157 B_UINT32 u32MaxTrafficBurst;
158
159 /** 32bit Minimum Reserved Traffic Rate of the Service Flow*/
160 B_UINT32 u32MinReservedTrafficRate;
161
162 /** 32bit Tolerated Jitter of the Service Flow*/
163 B_UINT32 u32ToleratedJitter;
164
165 /** 32bit Maximum Latency of the Service Flow*/
166 B_UINT32 u32MaximumLatency;
167
168 /** 16bitCID Of The Service Flow*/
169 B_UINT16 u16CID;
170
171 /** 16bit SAID on which the service flow being set up shall be mapped*/
172 B_UINT16 u16TargetSAID;
173
174 /** 16bit ARQ window size negotiated*/
175 B_UINT16 u16ARQWindowSize;
176
177 /** 16bit Total Tx delay incl sending, receiving & processing delays */
178 B_UINT16 u16ARQRetryTxTimeOut;
179
180 /** 16bit Total Rx delay incl sending, receiving & processing delays */
181 B_UINT16 u16ARQRetryRxTimeOut;
182
183 /** 16bit ARQ block lifetime */
184 B_UINT16 u16ARQBlockLifeTime;
185
186 /** 16bit ARQ Sync loss timeout*/
187 B_UINT16 u16ARQSyncLossTimeOut;
188
189 /** 16bit ARQ Purge timeout */
190 B_UINT16 u16ARQRxPurgeTimeOut;
191//TODO::Remove this once we move to a new CORR2 driver
192 /// \brief Size of an ARQ block
193 B_UINT16 u16ARQBlockSize;
194
195//#endif
196 /** 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP*/
197 B_UINT16 u16SDUInterArrivalTime;
198
199 /** 16bit Specifies the time base for rate measurement */
200 B_UINT16 u16TimeBase;
201
202 /** 16bit Interval b/w Successive Grant oppurtunities*/
203 B_UINT16 u16UnsolicitedGrantInterval;
204
205 /** 16bit Interval b/w Successive Polling grant oppurtunities*/
206 B_UINT16 u16UnsolicitedPollingInterval;
207
208 /** internal var to get the overhead */
209 B_UINT16 u16MacOverhead;
210
211 /** MBS contents Identifier*/
212 B_UINT16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH];
213
214 /** MBS contents Identifier length*/
215 B_UINT8 u8MBSContentsIDLength;
216
217 /** ServiceClassName Length Of The Service Flow*/
218 B_UINT8 u8ServiceClassNameLength;
219
220 /** 32bytes ServiceClassName Of The Service Flow*/
221 B_UINT8 u8ServiceClassName[32];
222
223 /** 8bit Indicates whether or not MBS service is requested for this Serivce Flow*/
224 B_UINT8 u8MBSService;
225
226 /** 8bit QOS Parameter Set specifies proper application of QoS paramters to Provisioned, Admitted and Active sets*/
227 B_UINT8 u8QosParamSet;
228
229 /** 8bit Traffic Priority Of the Service Flow */
230 B_UINT8 u8TrafficPriority;
231
232 /** 8bit Uplink Grant Scheduling Type of The Service Flow */
233 B_UINT8 u8ServiceFlowSchedulingType;
234
235 /** 8bit Request transmission Policy of the Service Flow*/
236 B_UINT8 u8RequesttransmissionPolicy;
237
238 /** 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */
239 B_UINT8 u8FixedLengthVSVariableLengthSDUIndicator;
240
241 /** 8bit Length of the SDU for a fixed length SDU service flow*/
242 B_UINT8 u8SDUSize;
243 116
244 /** 8bit Indicates whether or not ARQ is requested for this connection*/117struct bcm_convergence_types {
245 B_UINT8 u8ARQEnable;118 /* 8bit Phs Classfier Action Of The Service Flow */
246 119 B_UINT8 u8ClassfierDSCAction;
247 /**< 8bit Indicates whether or not data has tobe delivered in order to higher layer*/120 /* 8bit Phs DSC Action Of The Service Flow */
248 B_UINT8 u8ARQDeliverInOrder;121 B_UINT8 u8PhsDSCAction;
249 122 /* 16bit Padding */
250 /** 8bit Receiver ARQ ACK processing time */123 B_UINT8 u8Padding[2];
251 B_UINT8 u8RxARQAckProcessingTime;124 /* Packet classification rules structure */
252 125 struct bcm_packet_class_rules cCPacketClassificationRule;
253 /** 8bit Convergence Sublayer Specification Of The Service Flow*/126 /* Payload header suppression rules structure */
254 B_UINT8 u8CSSpecification;127 struct bcm_phs_rules cPhsRule;
255 128};
256 /** 8 bit Type of data delivery service*/
257 B_UINT8 u8TypeOfDataDeliveryService;
258
259 /** 8bit Specifies whether a service flow may generate Paging */
260 B_UINT8 u8PagingPreference;
261
262 /** 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */
263 B_UINT8 u8MBSZoneIdentifierassignment;
264
265 /** 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode*/
266 B_UINT8 u8TrafficIndicationPreference;
267
268 /** 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */
269 B_UINT8 u8GlobalServicesClassNameLength;
270
271 /** 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */
272 B_UINT8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH];
273
274 /** 8bit Indicates whether or not SN feedback is enabled for the conn */
275 B_UINT8 u8SNFeedbackEnabled;
276
277 /** Indicates the size of the Fragment Sequence Number for the connection */
278 B_UINT8 u8FSNSize;
279
280 /** 8bit Number of CIDs in active BS list */
281 B_UINT8 u8CIDAllocation4activeBSsLength;
282
283 /** CIDs of BS in the active list */
284 B_UINT8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS];
285
286 /** Specifies if PDU extended subheader should be applied on every PDU on this conn*/
287 B_UINT8 u8PDUSNExtendedSubheader4HarqReordering;
288
289 /** 8bit Specifies whether the connection uses HARQ or not */
290 B_UINT8 u8HARQServiceFlows;
291
292 /** Specifies the length of Authorization token*/
293 B_UINT8 u8AuthTokenLength;
294
295 /** Specifies the Authorization token*/
296 B_UINT8 u8AuthToken[AUTH_TOKEN_LENGTH];
297
298 /** specifes Number of HARQ channels used to carry data length*/
299 B_UINT8 u8HarqChannelMappingLength;
300
301 /** specifes HARQ channels used to carry data*/
302 B_UINT8 u8HARQChannelMapping[NUM_HARQ_CHANNELS];
303
304 /** 8bit Length of Vendor Specific QoS Params */
305 B_UINT8 u8VendorSpecificQoSParamLength;
306
307 /** 1byte Vendor Specific QoS Param Of The Service Flow*/
308 B_UINT8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM];
309
310 // indicates total classifiers in the SF
311 B_UINT8 u8TotalClassifiers; /**< Total number of valid classifiers*/
312 B_UINT8 bValid; /**< Validity flag */
313 B_UINT8 u8Padding; /**< Padding byte*/
314
315/**
316Structure for Convergence SubLayer Types with a maximum of 4 classifiers
317*/
318 stConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF];
319
320} stServiceFlowParamSI, *pstServiceFlowParamSI;
321typedef stServiceFlowParamSI CServiceFlowParamSI;
322
323/**
324structure stLocalSFAddRequest
325*/
326typedef struct _stLocalSFAddRequest{
327
328 B_UINT8 u8Type; /**< Type*/
329 B_UINT8 eConnectionDir; /**< Connection direction*/
330 /// \brief 16 bit TID
331 B_UINT16 u16TID; /**< 16bit TID*/
332 /// \brief 16bitCID
333 B_UINT16 u16CID; /**< 16bit CID*/
334 /// \brief 16bitVCID
335 B_UINT16 u16VCID; /**< 16bit VCID*/
336 /// \brief structure ParameterSet
337
338 stServiceFlowParamSI *psfParameterSet; /**< structure ParameterSet*/
339
340}stLocalSFAddRequest, *pstLocalSFAddRequest;
341
342
343/**
344structure stLocalSFAddIndication
345*/
346typedef struct _stLocalSFAddIndication{
347
348 B_UINT8 u8Type; /**< Type*/
349 B_UINT8 eConnectionDir; /**< Connection Direction*/
350 /// \brief 16 bit TID
351 B_UINT16 u16TID; /**< TID*/
352 /// \brief 16bitCID
353 B_UINT16 u16CID; /**< 16bitCID*/
354 /// \brief 16bitVCID
355 B_UINT16 u16VCID; /**< 16bitVCID*/
356
357
358 /// \brief structure AuthorizedSet
359 /// \brief structure AuthorizedSet
360 stServiceFlowParamSI *psfAuthorizedSet; /**< AuthorizedSet of type stServiceFlowParamSI*/
361 /// \brief structure AdmittedSet
362 stServiceFlowParamSI *psfAdmittedSet; /**< AdmittedSet of type stServiceFlowParamSI*/
363 /// \brief structure ActiveSet
364 stServiceFlowParamSI *psfActiveSet; /**< sfActiveSet of type stServiceFlowParamSI*/
365 B_UINT8 u8CC; /**< Confirmation Code*/
366 B_UINT8 u8Padd; /**< 8-bit Padding */
367
368 B_UINT16 u16Padd; /**< 16 bit Padding */
369
370}stLocalSFAddIndication;
371 129
130struct bcm_connect_mgr_params {
131 /* 32bitSFID Of The Service Flow */
132 B_UINT32 u32SFID;
133 /* 32bit Maximum Sustained Traffic Rate of the Service Flow */
134 B_UINT32 u32MaxSustainedTrafficRate;
135 /* 32bit Maximum Traffic Burst allowed for the Service Flow */
136 B_UINT32 u32MaxTrafficBurst;
137 /* 32bit Minimum Reserved Traffic Rate of the Service Flow */
138 B_UINT32 u32MinReservedTrafficRate;
139 /* 32bit Tolerated Jitter of the Service Flow */
140 B_UINT32 u32ToleratedJitter;
141 /* 32bit Maximum Latency of the Service Flow */
142 B_UINT32 u32MaximumLatency;
143 /* 16bitCID Of The Service Flow */
144 B_UINT16 u16CID;
145 /* 16bit SAID on which the service flow being set up shall be mapped */
146 B_UINT16 u16TargetSAID;
147 /* 16bit ARQ window size negotiated */
148 B_UINT16 u16ARQWindowSize;
149 /* 16bit Total Tx delay incl sending, receiving & processing delays */
150 B_UINT16 u16ARQRetryTxTimeOut;
151 /* 16bit Total Rx delay incl sending, receiving & processing delays */
152 B_UINT16 u16ARQRetryRxTimeOut;
153 /* 16bit ARQ block lifetime */
154 B_UINT16 u16ARQBlockLifeTime;
155 /* 16bit ARQ Sync loss timeout */
156 B_UINT16 u16ARQSyncLossTimeOut;
157 /* 16bit ARQ Purge timeout */
158 B_UINT16 u16ARQRxPurgeTimeOut;
159 /* TODO::Remove this once we move to a new CORR2 driver
160 * brief Size of an ARQ block
161 */
162 B_UINT16 u16ARQBlockSize;
163 /* #endif */
164 /* 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP */
165 B_UINT16 u16SDUInterArrivalTime;
166 /* 16bit Specifies the time base for rate measurement */
167 B_UINT16 u16TimeBase;
168 /* 16bit Interval b/w Successive Grant oppurtunities */
169 B_UINT16 u16UnsolicitedGrantInterval;
170 /* 16bit Interval b/w Successive Polling grant oppurtunities */
171 B_UINT16 u16UnsolicitedPollingInterval;
172 /* internal var to get the overhead */
173 B_UINT16 u16MacOverhead;
174 /* MBS contents Identifier */
175 B_UINT16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH];
176 /* MBS contents Identifier length */
177 B_UINT8 u8MBSContentsIDLength;
178 /* ServiceClassName Length Of The Service Flow */
179 B_UINT8 u8ServiceClassNameLength;
180 /* 32bytes ServiceClassName Of The Service Flow */
181 B_UINT8 u8ServiceClassName[32];
182 /* 8bit Indicates whether or not MBS service is requested for this Serivce Flow */
183 B_UINT8 u8MBSService;
184 /* 8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets */
185 B_UINT8 u8QosParamSet;
186 /* 8bit Traffic Priority Of the Service Flow */
187 B_UINT8 u8TrafficPriority;
188 /* 8bit Uplink Grant Scheduling Type of The Service Flow */
189 B_UINT8 u8ServiceFlowSchedulingType;
190 /* 8bit Request transmission Policy of the Service Flow */
191 B_UINT8 u8RequesttransmissionPolicy;
192 /* 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */
193 B_UINT8 u8FixedLengthVSVariableLengthSDUIndicator;
194 /* 8bit Length of the SDU for a fixed length SDU service flow */
195 B_UINT8 u8SDUSize;
196 /* 8bit Indicates whether or not ARQ is requested for this connection */
197 B_UINT8 u8ARQEnable;
198 /* < 8bit Indicates whether or not data has tobe delivered in order to higher layer */
199 B_UINT8 u8ARQDeliverInOrder;
200 /* 8bit Receiver ARQ ACK processing time */
201 B_UINT8 u8RxARQAckProcessingTime;
202 /* 8bit Convergence Sublayer Specification Of The Service Flow */
203 B_UINT8 u8CSSpecification;
204 /* 8 bit Type of data delivery service */
205 B_UINT8 u8TypeOfDataDeliveryService;
206 /* 8bit Specifies whether a service flow may generate Paging */
207 B_UINT8 u8PagingPreference;
208 /* 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */
209 B_UINT8 u8MBSZoneIdentifierassignment;
210 /* 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode */
211 B_UINT8 u8TrafficIndicationPreference;
212 /* 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */
213 B_UINT8 u8GlobalServicesClassNameLength;
214 /* 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */
215 B_UINT8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH];
216 /* 8bit Indicates whether or not SN feedback is enabled for the conn */
217 B_UINT8 u8SNFeedbackEnabled;
218 /* Indicates the size of the Fragment Sequence Number for the connection */
219 B_UINT8 u8FSNSize;
220 /* 8bit Number of CIDs in active BS list */
221 B_UINT8 u8CIDAllocation4activeBSsLength;
222 /* CIDs of BS in the active list */
223 B_UINT8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS];
224 /* Specifies if PDU extended subheader should be applied on every PDU on this conn */
225 B_UINT8 u8PDUSNExtendedSubheader4HarqReordering;
226 /* 8bit Specifies whether the connection uses HARQ or not */
227 B_UINT8 u8HARQServiceFlows;
228 /* Specifies the length of Authorization token */
229 B_UINT8 u8AuthTokenLength;
230 /* Specifies the Authorization token */
231 B_UINT8 u8AuthToken[AUTH_TOKEN_LENGTH];
232 /* specifes Number of HARQ channels used to carry data length */
233 B_UINT8 u8HarqChannelMappingLength;
234 /* specifes HARQ channels used to carry data */
235 B_UINT8 u8HARQChannelMapping[NUM_HARQ_CHANNELS];
236 /* 8bit Length of Vendor Specific QoS Params */
237 B_UINT8 u8VendorSpecificQoSParamLength;
238 /* 1byte Vendor Specific QoS Param Of The Service Flow */
239 B_UINT8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM];
240 /* indicates total classifiers in the SF */
241 B_UINT8 u8TotalClassifiers; /* < Total number of valid classifiers */
242 B_UINT8 bValid; /* < Validity flag */
243 B_UINT8 u8Padding; /* < Padding byte */
244 /*
245 * Structure for Convergence SubLayer Types with a maximum of 4 classifiers
246 */
247 struct bcm_convergence_types cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF];
248};
372 249
373typedef struct _stLocalSFAddIndication *pstLocalSFAddIndication;250struct bcm_add_request {
374/**251 B_UINT8 u8Type; /* < Type */
375structure stLocalSFChangeRequest is same as structure stLocalSFAddIndication252 B_UINT8 eConnectionDir; /* < Connection direction */
376*/253 /* brief 16 bit TID */
377typedef struct _stLocalSFAddIndication stLocalSFChangeRequest, *pstLocalSFChangeRequest;254 B_UINT16 u16TID; /* < 16bit TID */
378/**255 /* brief 16bitCID */
379structure stLocalSFChangeIndication is same as structure stLocalSFAddIndication256 B_UINT16 u16CID; /* < 16bit CID */
380*/257 /* brief 16bitVCID */
381typedef struct _stLocalSFAddIndication stLocalSFChangeIndication, *pstLocalSFChangeIndication;258 B_UINT16 u16VCID; /* < 16bit VCID */
259 struct bcm_connect_mgr_params *psfParameterSet; /* < connection manager parameters */
260};
382 261
383/**262struct bcm_add_indication {
384structure stLocalSFDeleteRequest263 B_UINT8 u8Type; /* < Type */
385*/264 B_UINT8 eConnectionDir; /* < Connection Direction */
386typedef struct _stLocalSFDeleteRequest{265 /* brief 16 bit TID */
387 B_UINT8 u8Type; /**< Type*/266 B_UINT16 u16TID; /* < TID */
388 B_UINT8 u8Padding; /**< Padding byte*/267 /* brief 16bitCID */
389 B_UINT16 u16TID; /**< TID*/268 B_UINT16 u16CID; /* < 16bitCID */
390 /// \brief 32bitSFID269 /* brief 16bitVCID */
391 B_UINT32 u32SFID; /**< SFID*/270 B_UINT16 u16VCID; /* < 16bitVCID */
392}stLocalSFDeleteRequest, *pstLocalSFDeleteRequest;271 struct bcm_connect_mgr_params *psfAuthorizedSet; /* Authorized set of connection manager parameters */
272 struct bcm_connect_mgr_params *psfAdmittedSet; /* Admitted set of connection manager parameters */
273 struct bcm_connect_mgr_params *psfActiveSet; /* Activeset of connection manager parameters */
274 B_UINT8 u8CC; /* <Confirmation Code */
275 B_UINT8 u8Padd; /* < 8-bit Padding */
276 B_UINT16 u16Padd; /* < 16 bit Padding */
277};
393 278
394/**279struct bcm_del_request {
395structure stLocalSFDeleteIndication280 B_UINT8 u8Type; /* < Type */
396*/281 B_UINT8 u8Padding; /* < Padding byte */
397typedef struct stLocalSFDeleteIndication{282 B_UINT16 u16TID; /* < TID */
398 B_UINT8 u8Type; /**< Type */283 /* brief 32bitSFID */
399 B_UINT8 u8Padding; /**< Padding */284 B_UINT32 u32SFID; /* < SFID */
400 B_UINT16 u16TID; /**< TID */285};
401 /// \brief 16bitCID
402 B_UINT16 u16CID; /**< CID */
403 /// \brief 16bitVCID
404 B_UINT16 u16VCID; /**< VCID */
405 /// \brief 32bitSFID
406 B_UINT32 u32SFID; /**< SFID */
407 /// \brief 8bit Confirmation code
408 B_UINT8 u8ConfirmationCode; /**< Confirmation code */
409 B_UINT8 u8Padding1[3]; /**< 3 byte Padding */
410}stLocalSFDeleteIndication;
411 286
412typedef struct _stIM_SFHostNotify287struct bcm_del_indication {
413{288 B_UINT8 u8Type; /* < Type */
414 B_UINT32 SFID; //SFID of the service flow289 B_UINT8 u8Padding; /* < Padding */
415 B_UINT16 newCID; //the new/changed CID290 B_UINT16 u16TID; /* < TID */
416 B_UINT16 VCID; //Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid291 /* brief 16bitCID */
417 B_UINT8 RetainSF; //Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete292 B_UINT16 u16CID; /* < CID */
418 B_UINT8 QoSParamSet; //QoS paramset of the retained SF293 /* brief 16bitVCID */
419 B_UINT16 u16reserved; //For byte alignment294 B_UINT16 u16VCID; /* < VCID */
295 /* brief 32bitSFID */
296 B_UINT32 u32SFID; /* < SFID */
297 /* brief 8bit Confirmation code */
298 B_UINT8 u8ConfirmationCode; /* < Confirmation code */
299 B_UINT8 u8Padding1[3]; /* < 3 byte Padding */
300};
420 301
421} stIM_SFHostNotify;302struct bcm_stim_sfhostnotify {
303 B_UINT32 SFID; /* SFID of the service flow */
304 B_UINT16 newCID; /* the new/changed CID */
305 B_UINT16 VCID; /* Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid */
306 B_UINT8 RetainSF; /* Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete */
307 B_UINT8 QoSParamSet; /* QoS paramset of the retained SF */
308 B_UINT16 u16reserved; /* For byte alignment */
309};
422 310
423#endif311#endif
drivers/staging/bcm/hostmibs.c+1−1
@@ -101,7 +101,7 @@ VOID GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *pstHostMibs, struct bcm_t · 100 unmodified lines
101 sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));101 sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
102}102}
103 103
104VOID CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter, CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex)104VOID CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter, struct bcm_connect_mgr_params *psfLocalSet, UINT uiSearchRuleIndex)
105{105{
106 S_MIBS_EXTSERVICEFLOW_PARAMETERS *t = &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable;106 S_MIBS_EXTSERVICEFLOW_PARAMETERS *t = &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable;
107 107
drivers/staging/bcm/nvm.c+2−2
@@ -577,7 +577,7 @@ static int FlashSectorErase(struct bcm_mini_adapter *Adapter, · 576 unmodified lines
577 * the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms577 * the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms
578 * won't hamper performance in any case.578 * won't hamper performance in any case.
579 */579 */
580 udelay(10000);580 mdelay(10);
581 } while ((uiStatus & 0x1) && (iRetries < 400));581 } while ((uiStatus & 0x1) && (iRetries < 400));
582 582
583 if (uiStatus & 0x1) {583 if (uiStatus & 0x1) {
@@ -3932,7 +3932,7 @@ int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRIT · 3348 unmodified lines
3932 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3);3932 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3);
3933 }3933 }
3934 3934
3935 /* since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset3935 /* since this uiSectEndoffset is the size of iso Image. hence for calculating the virtual endoffset
3936 * it should be added in startoffset. so that check done in last of this function can be valued.3936 * it should be added in startoffset. so that check done in last of this function can be valued.
3937 */3937 */
3938 uiSectEndOffset = uiSectStartOffset + uiSectEndOffset;3938 uiSectEndOffset = uiSectStartOffset + uiSectEndOffset;
drivers/staging/bcm/target_params.h+1−1
@@ -32,7 +32,7 @@ typedef struct _TARGET_PARAMS · 31 unmodified lines
32 B_UINT32 m_u32PowerSavingModesEnable; //bit 1: 1 Idlemode enable; bit2: 1 Sleepmode Enable32 B_UINT32 m_u32PowerSavingModesEnable; //bit 1: 1 Idlemode enable; bit2: 1 Sleepmode Enable
33 /* PowerSaving Mode Options:33 /* PowerSaving Mode Options:
34 bit 0 = 1: CPE mode - to keep pcmcia if alive;34 bit 0 = 1: CPE mode - to keep pcmcia if alive;
35 bit 1 = 1: CINR reporing in Idlemode Msg35 bit 1 = 1: CINR reporting in Idlemode Msg
36 bit 2 = 1: Default PSC Enable in sleepmode*/36 bit 2 = 1: Default PSC Enable in sleepmode*/
37 B_UINT32 m_u32PowerSavingModeOptions;37 B_UINT32 m_u32PowerSavingModeOptions;
38 38
drivers/staging/ccg/Kconfig+1−1
@@ -2,7 +2,7 @@ if USB_GADGET · 1 unmodified line
2 2
3config USB_G_CCG3config USB_G_CCG
4 tristate "Configurable Composite Gadget (STAGING)"4 tristate "Configurable Composite Gadget (STAGING)"
5 depends on STAGING && BLOCK && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM5 depends on STAGING && BLOCK && NET && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM
6 help6 help
7 The Configurable Composite Gadget supports multiple USB7 The Configurable Composite Gadget supports multiple USB
8 functions: acm, mass storage, rndis and FunctionFS.8 functions: acm, mass storage, rndis and FunctionFS.
drivers/staging/ccg/ccg.c+5−9
@@ -728,7 +728,7 @@ static int mass_storage_function_init(struct ccg_usb_function *f, · 727 unmodified lines
728 struct fsg_common *common;728 struct fsg_common *common;
729 int err;729 int err;
730 730
731 memset(&fsg, 0, sizeof fsg);731 memset(&fsg, 0, sizeof(fsg));
732 fsg.nluns = 1;732 fsg.nluns = 1;
733 fsg.luns[0].removable = 1;733 fsg.luns[0].removable = 1;
734 fsg.vendor_name = iManufacturer;734 fsg.vendor_name = iManufacturer;
@@ -1101,13 +1101,7 @@ static struct device_attribute *ccg_usb_attributes[] = { · 366 unmodified lines
1101static int ccg_bind_config(struct usb_configuration *c)1101static int ccg_bind_config(struct usb_configuration *c)
1102{1102{
1103 struct ccg_dev *dev = _ccg_dev;1103 struct ccg_dev *dev = _ccg_dev;
1104 int ret = 0;1104 return ccg_bind_enabled_functions(dev, c);
1105
1106 ret = ccg_bind_enabled_functions(dev, c);
1107 if (ret)
1108 return ret;
1109
1110 return 0;
1111}1105}
1112 1106
1113static void ccg_unbind_config(struct usb_configuration *c)1107static void ccg_unbind_config(struct usb_configuration *c)
@@ -1254,8 +1248,10 @@ static int __init init(void) · 140 unmodified lines
1254 return PTR_ERR(ccg_class);1248 return PTR_ERR(ccg_class);
1255 1249
1256 dev = kzalloc(sizeof(*dev), GFP_KERNEL);1250 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1257 if (!dev)1251 if (!dev) {
1252 class_destroy(ccg_class);
1258 return -ENOMEM;1253 return -ENOMEM;
1254 }
1259 1255
1260 dev->functions = supported_functions;1256 dev->functions = supported_functions;
1261 INIT_LIST_HEAD(&dev->enabled_functions);1257 INIT_LIST_HEAD(&dev->enabled_functions);
drivers/staging/ced1401/Kconfig+6−0
@@ -0,0 +1,6 @@
1config CED1401
2 tristate "Cambridge Electronic Design 1401 USB support"
3 depends on USB
4 help
5 This driver supports the Cambridge Electronic Design 1401 USB device
6 (whatever that is.)
drivers/staging/ced1401/Makefile+3−0
@@ -0,0 +1,3 @@
1
2obj-$(CONFIG_CED1401) := cedusb.o
3cedusb-objs := usb1401.o ced_ioc.o
drivers/staging/ced1401/TODO+10−0
@@ -0,0 +1,10 @@
1TODO:
2 - coding syle fixes
3 - build warning fixups
4 - ioctl auditing
5 - usb api auditing
6 - proper USB minor number (it's stomping on an existing one right now.)
7
8Please send patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org> and Cc:
9Alois Schlögl <alois.schloegl@ist.ac.at>
10
drivers/staging/ced1401/ced_ioc.c+1515−0
@@ -0,0 +1,1515 @@
1/* ced_ioc.c
2 ioctl part of the 1401 usb device driver for linux.
3 Copyright (C) 2010 Cambridge Electronic Design Ltd
4 Author Greg P Smith (greg@ced.co.uk)
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19*/
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/module.h>
25#include <linux/kref.h>
26#include <linux/uaccess.h>
27#include <linux/usb.h>
28#include <linux/mutex.h>
29#include <linux/page-flags.h>
30#include <linux/pagemap.h>
31#include <linux/jiffies.h>
32
33#include "usb1401.h"
34
35/****************************************************************************
36** FlushOutBuff
37**
38** Empties the Output buffer and sets int lines. Used from user level only
39****************************************************************************/
40void FlushOutBuff(DEVICE_EXTENSION * pdx)
41{
42 dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__,
43 pdx->sCurrentState);
44 if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */
45 return;
46// CharSend_Cancel(pdx); /* Kill off any pending I/O */
47 spin_lock_irq(&pdx->charOutLock);
48 pdx->dwNumOutput = 0;
49 pdx->dwOutBuffGet = 0;
50 pdx->dwOutBuffPut = 0;
51 spin_unlock_irq(&pdx->charOutLock);
52}
53
54/****************************************************************************
55**
56** FlushInBuff
57**
58** Empties the input buffer and sets int lines
59****************************************************************************/
60void FlushInBuff(DEVICE_EXTENSION * pdx)
61{
62 dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__,
63 pdx->sCurrentState);
64 if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */
65 return;
66// CharRead_Cancel(pDevObject); /* Kill off any pending I/O */
67 spin_lock_irq(&pdx->charInLock);
68 pdx->dwNumInput = 0;
69 pdx->dwInBuffGet = 0;
70 pdx->dwInBuffPut = 0;
71 spin_unlock_irq(&pdx->charInLock);
72}
73
74/****************************************************************************
75** PutChars
76**
77** Utility routine to copy chars into the output buffer and fire them off.
78** called from user mode, holds charOutLock.
79****************************************************************************/
80static int PutChars(DEVICE_EXTENSION * pdx, const char *pCh,
81 unsigned int uCount)
82{
83 int iReturn;
84 spin_lock_irq(&pdx->charOutLock); // get the output spin lock
85 if ((OUTBUF_SZ - pdx->dwNumOutput) >= uCount) {
86 unsigned int u;
87 for (u = 0; u < uCount; u++) {
88 pdx->outputBuffer[pdx->dwOutBuffPut++] = pCh[u];
89 if (pdx->dwOutBuffPut >= OUTBUF_SZ)
90 pdx->dwOutBuffPut = 0;
91 }
92 pdx->dwNumOutput += uCount;
93 spin_unlock_irq(&pdx->charOutLock);
94 iReturn = SendChars(pdx); // ...give a chance to transmit data
95 } else {
96 iReturn = U14ERR_NOOUT; // no room at the out (ha-ha)
97 spin_unlock_irq(&pdx->charOutLock);
98 }
99 return iReturn;
100}
101
102/*****************************************************************************
103** Add the data in pData (local pointer) of length n to the output buffer, and
104** trigger an output transfer if this is appropriate. User mode.
105** Holds the io_mutex
106*****************************************************************************/
107int SendString(DEVICE_EXTENSION * pdx, const char __user * pData,
108 unsigned int n)
109{
110 int iReturn = U14ERR_NOERROR; // assume all will be well
111 char buffer[OUTBUF_SZ + 1]; // space in our address space for characters
112 if (n > OUTBUF_SZ) // check space in local buffer...
113 return U14ERR_NOOUT; // ...too many characters
114 if (copy_from_user(buffer, pData, n))
115 return -EFAULT;
116 buffer[n] = 0; // terminate for debug purposes
117
118 mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
119 if (n > 0) // do nothing if nowt to do!
120 {
121 dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, n,
122 buffer);
123 iReturn = PutChars(pdx, buffer, n);
124 }
125
126 Allowi(pdx, false); // make sure we have input int
127 mutex_unlock(&pdx->io_mutex);
128
129 return iReturn;
130}
131
132/****************************************************************************
133** SendChar
134**
135** Sends a single character to the 1401. User mode, holds io_mutex.
136****************************************************************************/
137int SendChar(DEVICE_EXTENSION * pdx, char c)
138{
139 int iReturn;
140 mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
141 iReturn = PutChars(pdx, &c, 1);
142 dev_dbg(&pdx->interface->dev, "SendChar >%c< (0x%02x)", c, c);
143 Allowi(pdx, false); // Make sure char reads are running
144 mutex_unlock(&pdx->io_mutex);
145 return iReturn;
146}
147
148/***************************************************************************
149**
150** Get1401State
151**
152** Retrieves state information from the 1401, adjusts the 1401 state held
153** in the device extension to indicate the current 1401 type.
154**
155** *state is updated with information about the 1401 state as returned by the
156** 1401. The low byte is a code for what 1401 is doing:
157**
158** 0 normal 1401 operation
159** 1 sending chars to host
160** 2 sending block data to host
161** 3 reading block data from host
162** 4 sending an escape sequence to the host
163** 0x80 1401 is executing self-test, in which case the upper word
164** is the last error code seen (or zero for no new error).
165**
166** *error is updated with error information if a self-test error code
167** is returned in the upper word of state.
168**
169** both state and error are set to -1 if there are comms problems, and
170** to zero if there is a simple failure.
171**
172** return error code (U14ERR_NOERROR for OK)
173*/
174int Get1401State(DEVICE_EXTENSION * pdx, __u32 * state, __u32 * error)
175{
176 int nGot;
177 dev_dbg(&pdx->interface->dev, "Get1401State() entry");
178
179 *state = 0xFFFFFFFF; // Start off with invalid state
180 nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
181 GET_STATUS, (D_TO_H | VENDOR | DEVREQ), 0, 0,
182 pdx->statBuf, sizeof(pdx->statBuf), HZ);
183 if (nGot != sizeof(pdx->statBuf)) {
184 dev_err(&pdx->interface->dev,
185 "Get1401State() FAILED, return code %d", nGot);
186 pdx->sCurrentState = U14ERR_TIME; // Indicate that things are very wrong indeed
187 *state = 0; // Force status values to a known state
188 *error = 0;
189 } else {
190 int nDevice;
191 dev_dbg(&pdx->interface->dev,
192 "Get1401State() Success, state: 0x%x, 0x%x",
193 pdx->statBuf[0], pdx->statBuf[1]);
194
195 *state = pdx->statBuf[0]; // Return the state values to the calling code
196 *error = pdx->statBuf[1];
197
198 nDevice = pdx->udev->descriptor.bcdDevice >> 8; // 1401 type code value
199 switch (nDevice) // so we can clean up current state
200 {
201 case 0:
202 pdx->sCurrentState = U14ERR_U1401;
203 break;
204
205 default: // allow lots of device codes for future 1401s
206 if ((nDevice >= 1) && (nDevice <= 23))
207 pdx->sCurrentState = (short)(nDevice + 6);
208 else
209 pdx->sCurrentState = U14ERR_ILL;
210 break;
211 }
212 }
213
214 return pdx->sCurrentState >= 0 ? U14ERR_NOERROR : pdx->sCurrentState;
215}
216
217/****************************************************************************
218** ReadWrite_Cancel
219**
220** Kills off staged read\write request from the USB if one is pending.
221****************************************************************************/
222int ReadWrite_Cancel(DEVICE_EXTENSION * pdx)
223{
224 dev_dbg(&pdx->interface->dev, "ReadWrite_Cancel entry %d",
225 pdx->bStagedUrbPending);
226#ifdef NOT_WRITTEN_YET
227 int ntStatus = STATUS_SUCCESS;
228 bool bResult = false;
229 unsigned int i;
230 // We can fill this in when we know how we will implement the staged transfer stuff
231 spin_lock_irq(&pdx->stagedLock);
232
233 if (pdx->bStagedUrbPending) // anything to be cancelled? May need more...
234 {
235 dev_info(&pdx->interface - dev,
236 "ReadWrite_Cancel about to cancel Urb");
237
238 // KeClearEvent(&pdx->StagingDoneEvent); // Clear the staging done flag
239 USB_ASSERT(pdx->pStagedIrp != NULL);
240
241 // Release the spinlock first otherwise the completion routine may hang
242 // on the spinlock while this function hands waiting for the event.
243 spin_unlock_irq(&pdx->stagedLock);
244 bResult = IoCancelIrp(pdx->pStagedIrp); // Actually do the cancel
245 if (bResult) {
246 LARGE_INTEGER timeout;
247 timeout.QuadPart = -10000000; // Use a timeout of 1 second
248 dev_info(&pdx->interface - dev,
249 "ReadWrite_Cancel about to wait till done");
250 ntStatus =
251 KeWaitForSingleObject(&pdx->StagingDoneEvent,
252 Executive, KernelMode, FALSE,
253 &timeout);
254 } else {
255 dev_info(&pdx->interface - dev,
256 "ReadWrite_Cancel, cancellation failed");
257 ntStatus = U14ERR_FAIL;
258 }
259 USB_KdPrint(DBGLVL_DEFAULT,
260 ("ReadWrite_Cancel ntStatus = 0x%x decimal %d\n",
261 ntStatus, ntStatus));
262 } else
263 spin_unlock_irq(&pdx->stagedLock);
264
265 dev_info(&pdx->interface - dev, "ReadWrite_Cancel done");
266 return ntStatus;
267#else
268 return U14ERR_NOERROR;
269#endif
270
271}
272
273/***************************************************************************
274** InSelfTest - utility to check in self test. Return 1 for ST, 0 for not or
275** a -ve error code if we failed for some reason.
276***************************************************************************/
277static int InSelfTest(DEVICE_EXTENSION * pdx, unsigned int *pState)
278{
279 unsigned int state, error;
280 int iReturn = Get1401State(pdx, &state, &error); // see if in self-test
281 if (iReturn == U14ERR_NOERROR) // if all still OK
282 iReturn = (state == (unsigned int)-1) || // TX problem or...
283 ((state & 0xff) == 0x80); // ...self test
284 *pState = state; // return actual state
285 return iReturn;
286}
287
288/***************************************************************************
289** Is1401 - ALWAYS CALLED HOLDING THE io_mutex
290**
291** Tests for the current state of the 1401. Sets sCurrentState:
292**
293** U14ERR_NOIF 1401 i/f card not installed (not done here)
294** U14ERR_OFF 1401 apparently not switched on
295** U14ERR_NC 1401 appears to be not connected
296** U14ERR_ILL 1401 if it is there its not very well at all
297** U14ERR_TIME 1401 appears OK, but doesn't communicate - very bad
298** U14ERR_STD 1401 OK and ready for use
299** U14ERR_PLUS 1401+ OK and ready for use
300** U14ERR_U1401 Micro1401 OK and ready for use
301** U14ERR_POWER Power1401 OK and ready for use
302** U14ERR_U14012 Micro1401 mkII OK and ready for use
303**
304** Returns TRUE if a 1401 detected and OK, else FALSE
305****************************************************************************/
306bool Is1401(DEVICE_EXTENSION * pdx)
307{
308 int iReturn;
309 dev_dbg(&pdx->interface->dev, "%s", __func__);
310
311 ced_draw_down(pdx); // wait for, then kill outstanding Urbs
312 FlushInBuff(pdx); // Clear out input buffer & pipe
313 FlushOutBuff(pdx); // Clear output buffer & pipe
314
315 // The next call returns 0 if OK, but has returned 1 in the past, meaning that
316 // usb_unlock_device() is needed... now it always is
317 iReturn = usb_lock_device_for_reset(pdx->udev, pdx->interface);
318
319 // release the io_mutex because if we don't, we will deadlock due to system
320 // calls back into the driver.
321 mutex_unlock(&pdx->io_mutex); // locked, so we will not get system calls
322 if (iReturn >= 0) // if we failed
323 {
324 iReturn = usb_reset_device(pdx->udev); // try to do the reset
325 usb_unlock_device(pdx->udev); // undo the lock
326 }
327
328 mutex_lock(&pdx->io_mutex); // hold stuff off while we wait
329 pdx->dwDMAFlag = MODE_CHAR; // Clear DMA mode flag regardless!
330 if (iReturn == 0) // if all is OK still
331 {
332 unsigned int state;
333 iReturn = InSelfTest(pdx, &state); // see if likely in self test
334 if (iReturn > 0) // do we need to wait for self-test?
335 {
336 unsigned long ulTimeOut = jiffies + 30 * HZ; // when to give up
337 while ((iReturn > 0) && time_before(jiffies, ulTimeOut)) {
338 schedule(); // let other stuff run
339 iReturn = InSelfTest(pdx, &state); // see if done yet
340 }
341 }
342
343 if (iReturn == 0) // if all is OK...
344 iReturn = state == 0; // then sucess is that the state is 0
345 } else
346 iReturn = 0; // we failed
347 pdx->bForceReset = false; // Clear forced reset flag now
348
349 return iReturn > 0;
350}
351
352/****************************************************************************
353** QuickCheck - ALWAYS CALLED HOLDING THE io_mutex
354** This is used to test for a 1401. It will try to do a quick check if all is
355** OK, that is the 1401 was OK the last time it was asked, and there is no DMA
356** in progress, and if the bTestBuff flag is set, the character buffers must be
357** empty too. If the quick check shows that the state is still the same, then
358** all is OK.
359**
360** If any of the above conditions are not met, or if the state or type of the
361** 1401 has changed since the previous test, the full Is1401 test is done, but
362** only if bCanReset is also TRUE.
363**
364** The return value is TRUE if a useable 1401 is found, FALSE if not
365*/
366bool QuickCheck(DEVICE_EXTENSION * pdx, bool bTestBuff, bool bCanReset)
367{
368 bool bRet = false; // assume it will fail and we will reset
369 bool bShortTest;
370
371 bShortTest = ((pdx->dwDMAFlag == MODE_CHAR) && // no DMA running
372 (!pdx->bForceReset) && // Not had a real reset forced
373 (pdx->sCurrentState >= U14ERR_STD)); // No 1401 errors stored
374
375 dev_dbg(&pdx->interface->dev,
376 "%s DMAFlag:%d, state:%d, force:%d, testBuff:%d, short:%d",
377 __func__, pdx->dwDMAFlag, pdx->sCurrentState, pdx->bForceReset,
378 bTestBuff, bShortTest);
379
380 if ((bTestBuff) && // Buffer check requested, and...
381 (pdx->dwNumInput || pdx->dwNumOutput)) // ...characters were in the buffer?
382 {
383 bShortTest = false; // Then do the full test
384 dev_dbg(&pdx->interface->dev,
385 "%s will reset as buffers not empty", __func__);
386 }
387
388 if (bShortTest || !bCanReset) // Still OK to try the short test?
389 { // Always test if no reset - we want state update
390 unsigned int state, error;
391 dev_dbg(&pdx->interface->dev, "%s->Get1401State", __func__);
392 if (Get1401State(pdx, &state, &error) == U14ERR_NOERROR) // Check on the 1401 state
393 {
394 if ((state & 0xFF) == 0) // If call worked, check the status value
395 bRet = true; // If that was zero, all is OK, no reset needed
396 }
397 }
398
399 if (!bRet && bCanReset) // If all not OK, then
400 {
401 dev_info(&pdx->interface->dev, "%s->Is1401 %d %d %d %d",
402 __func__, bShortTest, pdx->sCurrentState, bTestBuff,
403 pdx->bForceReset);
404 bRet = Is1401(pdx); // do full test
405 }
406
407 return bRet;
408}
409
410/****************************************************************************
411** Reset1401
412**
413** Resets the 1401 and empties the i/o buffers
414*****************************************************************************/
415int Reset1401(DEVICE_EXTENSION * pdx)
416{
417 mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
418 dev_dbg(&pdx->interface->dev, "ABout to call QuickCheck");
419 QuickCheck(pdx, true, true); // Check 1401, reset if not OK
420 mutex_unlock(&pdx->io_mutex);
421 return U14ERR_NOERROR;
422}
423
424/****************************************************************************
425** GetChar
426**
427** Gets a single character from the 1401
428****************************************************************************/
429int GetChar(DEVICE_EXTENSION * pdx)
430{
431 int iReturn = U14ERR_NOIN; // assume we will get nothing
432 mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
433
434 dev_dbg(&pdx->interface->dev, "GetChar");
435
436 Allowi(pdx, false); // Make sure char reads are running
437 SendChars(pdx); // and send any buffered chars
438
439 spin_lock_irq(&pdx->charInLock);
440 if (pdx->dwNumInput > 0) // worth looking
441 {
442 iReturn = pdx->inputBuffer[pdx->dwInBuffGet++];
443 if (pdx->dwInBuffGet >= INBUF_SZ)
444 pdx->dwInBuffGet = 0;
445 pdx->dwNumInput--;
446 } else
447 iReturn = U14ERR_NOIN; // no input data to read
448 spin_unlock_irq(&pdx->charInLock);
449
450 Allowi(pdx, false); // Make sure char reads are running
451
452 mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o
453 return iReturn;
454}
455
456/****************************************************************************
457** GetString
458**
459** Gets a string from the 1401. Returns chars up to the next CR or when
460** there are no more to read or nowhere to put them. CR is translated to
461** 0 and counted as a character. If the string does not end in a 0, we will
462** add one, if there is room, but it is not counted as a character.
463**
464** returns the count of characters (including the terminator, or 0 if none
465** or a negative error code.
466****************************************************************************/
467int GetString(DEVICE_EXTENSION * pdx, char __user * pUser, int n)
468{
469 int nAvailable; // character in the buffer
470 int iReturn = U14ERR_NOIN;
471 if (n <= 0)
472 return -ENOMEM;
473
474 mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
475 Allowi(pdx, false); // Make sure char reads are running
476 SendChars(pdx); // and send any buffered chars
477
478 spin_lock_irq(&pdx->charInLock);
479 nAvailable = pdx->dwNumInput; // characters available now
480 if (nAvailable > n) // read max of space in pUser...
481 nAvailable = n; // ...or input characters
482
483 if (nAvailable > 0) // worth looking?
484 {
485 char buffer[INBUF_SZ + 1]; // space for a linear copy of data
486 int nGot = 0;
487 int nCopyToUser; // number to copy to user
488 char cData;
489 do {
490 cData = pdx->inputBuffer[pdx->dwInBuffGet++];
491 if (cData == CR_CHAR) // replace CR with zero
492 cData = (char)0;
493
494 if (pdx->dwInBuffGet >= INBUF_SZ)
495 pdx->dwInBuffGet = 0; // wrap buffer pointer
496
497 buffer[nGot++] = cData; // save the output
498 }
499 while ((nGot < nAvailable) && cData);
500
501 nCopyToUser = nGot; // what to copy...
502 if (cData) // do we need null
503 {
504 buffer[nGot] = (char)0; // make it tidy
505 if (nGot < n) // if space in user buffer...
506 ++nCopyToUser; // ...copy the 0 as well.
507 }
508
509 pdx->dwNumInput -= nGot;
510 spin_unlock_irq(&pdx->charInLock);
511
512 dev_dbg(&pdx->interface->dev,
513 "GetString read %d characters >%s<", nGot, buffer);
514 if (copy_to_user(pUser, buffer, nCopyToUser))
515 iReturn = -EFAULT;
516 else
517 iReturn = nGot; // report characters read
518 } else
519 spin_unlock_irq(&pdx->charInLock);
520
521 Allowi(pdx, false); // Make sure char reads are running
522 mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o
523
524 return iReturn;
525}
526
527/*******************************************************************************
528** Get count of characters in the inout buffer.
529*******************************************************************************/
530int Stat1401(DEVICE_EXTENSION * pdx)
531{
532 int iReturn;
533 mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
534 Allowi(pdx, false); // make sure we allow pending chars
535 SendChars(pdx); // in both directions
536 iReturn = pdx->dwNumInput; // no lock as single read
537 mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o
538 return iReturn;
539}
540
541/****************************************************************************
542** LineCount
543**
544** Returns the number of newline chars in the buffer. There is no need for
545** any fancy interlocks as we only read the interrupt routine data, and the
546** system is arranged so nothing can be destroyed.
547****************************************************************************/
548int LineCount(DEVICE_EXTENSION * pdx)
549{
550 int iReturn = 0; // will be count of line ends
551
552 mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
553 Allowi(pdx, false); // Make sure char reads are running
554 SendChars(pdx); // and send any buffered chars
555 spin_lock_irq(&pdx->charInLock); // Get protection
556
557 if (pdx->dwNumInput > 0) // worth looking?
558 {
559 unsigned int dwIndex = pdx->dwInBuffGet; // start at first available
560 unsigned int dwEnd = pdx->dwInBuffPut; // Position for search end
561 do {
562 if (pdx->inputBuffer[dwIndex++] == CR_CHAR)
563 ++iReturn; // inc count if CR
564
565 if (dwIndex >= INBUF_SZ) // see if we fall off buff
566 dwIndex = 0;
567 }
568 while (dwIndex != dwEnd); // go to last avaliable
569 }
570
571 spin_unlock_irq(&pdx->charInLock);
572 dev_dbg(&pdx->interface->dev, "LineCount returned %d", iReturn);
573 mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o
574 return iReturn;
575}
576
577/****************************************************************************
578** GetOutBufSpace
579**
580** Gets the space in the output buffer. Called from user code.
581*****************************************************************************/
582int GetOutBufSpace(DEVICE_EXTENSION * pdx)
583{
584 int iReturn;
585 mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
586 SendChars(pdx); // send any buffered chars
587 iReturn = (int)(OUTBUF_SZ - pdx->dwNumOutput); // no lock needed for single read
588 dev_dbg(&pdx->interface->dev, "OutBufSpace %d", iReturn);
589 mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o
590 return iReturn;
591}
592
593/****************************************************************************
594**
595** ClearArea
596**
597** Clears up a transfer area. This is always called in the context of a user
598** request, never from a call-back.
599****************************************************************************/
600int ClearArea(DEVICE_EXTENSION * pdx, int nArea)
601{
602 int iReturn = U14ERR_NOERROR;
603
604 if ((nArea < 0) || (nArea >= MAX_TRANSAREAS)) {
605 iReturn = U14ERR_BADAREA;
606 dev_err(&pdx->interface->dev, "%s Attempt to clear area %d",
607 __func__, nArea);
608 } else {
609 TRANSAREA *pTA = &pdx->rTransDef[nArea]; // to save typing
610 if (!pTA->bUsed) // if not used...
611 iReturn = U14ERR_NOTSET; // ...nothing to be done
612 else {
613 // We must save the memory we return as we shouldn't mess with memory while
614 // holding a spin lock.
615 struct page **pPages = 0; // save page address list
616 int nPages = 0; // and number of pages
617 int np;
618
619 dev_dbg(&pdx->interface->dev, "%s area %d", __func__,
620 nArea);
621 spin_lock_irq(&pdx->stagedLock);
622 if ((pdx->StagedId == nArea)
623 && (pdx->dwDMAFlag > MODE_CHAR)) {
624 iReturn = U14ERR_UNLOCKFAIL; // cannot delete as in use
625 dev_err(&pdx->interface->dev,
626 "%s call on area %d while active",
627 __func__, nArea);
628 } else {
629 pPages = pTA->pPages; // save page address list
630 nPages = pTA->nPages; // and page count
631 if (pTA->dwEventSz) // if events flagging in use
632 wake_up_interruptible(&pTA->wqEvent); // release anything that was waiting
633
634 if (pdx->bXFerWaiting
635 && (pdx->rDMAInfo.wIdent == nArea))
636 pdx->bXFerWaiting = false; // Cannot have pending xfer if area cleared
637
638 // Clean out the TRANSAREA except for the wait queue, which is at the end
639 // This sets bUsed to false and dwEventSz to 0 to say area not used and no events.
640 memset(pTA, 0,
641 sizeof(TRANSAREA) -
642 sizeof(wait_queue_head_t));
643 }
644 spin_unlock_irq(&pdx->stagedLock);
645
646 if (pPages) // if we decided to release the memory
647 {
648 // Now we must undo the pinning down of the pages. We will assume the worst and mark
649 // all the pages as dirty. Don't be tempted to move this up above as you must not be
650 // holding a spin lock to do this stuff as it is not atomic.
651 dev_dbg(&pdx->interface->dev, "%s nPages=%d",
652 __func__, nPages);
653
654 for (np = 0; np < nPages; ++np) {
655 if (pPages[np]) {
656 SetPageDirty(pPages[np]);
657 page_cache_release(pPages[np]);
658 }
659 }
660
661 kfree(pPages);
662 dev_dbg(&pdx->interface->dev,
663 "%s kfree(pPages) done", __func__);
664 }
665 }
666 }
667
668 return iReturn;
669}
670
671/****************************************************************************
672** SetArea
673**
674** Sets up a transfer area - the functional part. Called by both
675** SetTransfer and SetCircular.
676****************************************************************************/
677static int SetArea(DEVICE_EXTENSION * pdx, int nArea, char __user * puBuf,
678 unsigned int dwLength, bool bCircular, bool bCircToHost)
679{
680 // Start by working out the page aligned start of the area and the size
681 // of the area in pages, allowing for the start not being aligned and the
682 // end needing to be rounded up to a page boundary.
683 unsigned long ulStart = ((unsigned long)puBuf) & PAGE_MASK;
684 unsigned int ulOffset = ((unsigned long)puBuf) & (PAGE_SIZE - 1);
685 int len = (dwLength + ulOffset + PAGE_SIZE - 1) >> PAGE_SHIFT;
686
687 TRANSAREA *pTA = &pdx->rTransDef[nArea]; // to save typing
688 struct page **pPages = 0; // space for page tables
689 int nPages = 0; // and number of pages
690
691 int iReturn = ClearArea(pdx, nArea); // see if OK to use this area
692 if ((iReturn != U14ERR_NOTSET) && // if not area unused and...
693 (iReturn != U14ERR_NOERROR)) // ...not all OK, then...
694 return iReturn; // ...we cannot use this area
695
696 if (!access_ok(VERIFY_WRITE, puBuf, dwLength)) // if we cannot access the memory...
697 return -EFAULT; // ...then we are done
698
699 // Now allocate space to hold the page pointer and virtual address pointer tables
700 pPages =
701 (struct page **)kmalloc(len * sizeof(struct page *), GFP_KERNEL);
702 if (!pPages) {
703 iReturn = U14ERR_NOMEMORY;
704 goto error;
705 }
706 dev_dbg(&pdx->interface->dev, "%s %p, length=%06x, circular %d",
707 __func__, puBuf, dwLength, bCircular);
708
709 // To pin down user pages we must first acquire the mapping semaphore.
710 down_read(&current->mm->mmap_sem); // get memory map semaphore
711 nPages =
712 get_user_pages(current, current->mm, ulStart, len, 1, 0, pPages, 0);
713 up_read(&current->mm->mmap_sem); // release the semaphore
714 dev_dbg(&pdx->interface->dev, "%s nPages = %d", __func__, nPages);
715
716 if (nPages > 0) // if we succeeded
717 {
718 // If you are tempted to use page_address (form LDD3), forget it. You MUST use
719 // kmap() or kmap_atomic() to get a virtual address. page_address will give you
720 // (null) or at least it does in this context with an x86 machine.
721 spin_lock_irq(&pdx->stagedLock);
722 pTA->lpvBuff = puBuf; // keep start of region (user address)
723 pTA->dwBaseOffset = ulOffset; // save offset in first page to start of xfer
724 pTA->dwLength = dwLength; // Size if the region in bytes
725 pTA->pPages = pPages; // list of pages that are used by buffer
726 pTA->nPages = nPages; // number of pages
727
728 pTA->bCircular = bCircular;
729 pTA->bCircToHost = bCircToHost;
730
731 pTA->aBlocks[0].dwOffset = 0;
732 pTA->aBlocks[0].dwSize = 0;
733 pTA->aBlocks[1].dwOffset = 0;
734 pTA->aBlocks[1].dwSize = 0;
735 pTA->bUsed = true; // This is now a used block
736
737 spin_unlock_irq(&pdx->stagedLock);
738 iReturn = U14ERR_NOERROR; // say all was well
739 } else {
740 iReturn = U14ERR_LOCKFAIL;
741 goto error;
742 }
743
744 return iReturn;
745
746error:
747 kfree(pPages);
748 return iReturn;
749}
750
751/****************************************************************************
752** SetTransfer
753**
754** Sets up a transfer area record. If the area is already set, we attempt to
755** unset it. Unsetting will fail if the area is booked, and a transfer to that
756** area is in progress. Otherwise, we will release the area and re-assign it.
757****************************************************************************/
758int SetTransfer(DEVICE_EXTENSION * pdx, TRANSFERDESC __user * pTD)
759{
760 int iReturn;
761 TRANSFERDESC td;
762
763 if (copy_from_user(&td, pTD, sizeof(td)))
764 return -EFAULT;
765
766 mutex_lock(&pdx->io_mutex);
767 dev_dbg(&pdx->interface->dev, "%s area:%d, size:%08x", __func__,
768 td.wAreaNum, td.dwLength);
769 // The strange cast is done so that we don't get warnings in 32-bit linux about the size of the
770 // pointer. The pointer is always passed as a 64-bit object so that we don't have problems using
771 // a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system.
772 iReturn =
773 SetArea(pdx, td.wAreaNum,
774 (char __user *)((unsigned long)td.lpvBuff), td.dwLength,
775 false, false);
776 mutex_unlock(&pdx->io_mutex);
777 return iReturn;
778}
779
780/****************************************************************************
781** UnSetTransfer
782** Erases a transfer area record
783****************************************************************************/
784int UnsetTransfer(DEVICE_EXTENSION * pdx, int nArea)
785{
786 int iReturn;
787 mutex_lock(&pdx->io_mutex);
788 iReturn = ClearArea(pdx, nArea);
789 mutex_unlock(&pdx->io_mutex);
790 return iReturn;
791}
792
793/****************************************************************************
794** SetEvent
795** Creates an event that we can test for based on a transfer to/from an area.
796** The area must be setup for a transfer. We attempt to simulate the Windows
797** driver behavior for events (as we don't actually use them), which is to
798** pretend that whatever the user asked for was achieved, so we return 1 if
799** try to create one, and 0 if they ask to remove (assuming all else was OK).
800****************************************************************************/
801int SetEvent(DEVICE_EXTENSION * pdx, TRANSFEREVENT __user * pTE)
802{
803 int iReturn = U14ERR_NOERROR;
804 TRANSFEREVENT te;
805
806 // get a local copy of the data
807 if (copy_from_user(&te, pTE, sizeof(te)))
808 return -EFAULT;
809
810 if (te.wAreaNum >= MAX_TRANSAREAS) // the area must exist
811 return U14ERR_BADAREA;
812 else {
813 TRANSAREA *pTA = &pdx->rTransDef[te.wAreaNum];
814 mutex_lock(&pdx->io_mutex); // make sure we have no competitor
815 spin_lock_irq(&pdx->stagedLock);
816 if (pTA->bUsed) // area must be in use
817 {
818 pTA->dwEventSt = te.dwStart; // set area regions
819 pTA->dwEventSz = te.dwLength; // set size (0 cancels it)
820 pTA->bEventToHost = te.wFlags & 1; // set the direction
821 pTA->iWakeUp = 0; // zero the wake up count
822 } else
823 iReturn = U14ERR_NOTSET;
824 spin_unlock_irq(&pdx->stagedLock);
825 mutex_unlock(&pdx->io_mutex);
826 }
827 return iReturn ==
828 U14ERR_NOERROR ? (te.iSetEvent ? 1 : U14ERR_NOERROR) : iReturn;
829}
830
831/****************************************************************************
832** WaitEvent
833** Sleep the process with a timeout waiting for an event. Returns the number
834** of times that a block met the event condition since we last cleared it or
835** 0 if timed out, or -ve error (bad area or not set, or signal).
836****************************************************************************/
837int WaitEvent(DEVICE_EXTENSION * pdx, int nArea, int msTimeOut)
838{
839 int iReturn;
840 if ((unsigned)nArea >= MAX_TRANSAREAS)
841 return U14ERR_BADAREA;
842 else {
843 int iWait;
844 TRANSAREA *pTA = &pdx->rTransDef[nArea];
845 msTimeOut = (msTimeOut * HZ + 999) / 1000; // convert timeout to jiffies
846
847 // We cannot wait holding the mutex, but we check the flags while holding
848 // it. This may well be pointless as another thread could get in between
849 // releasing it and the wait call. However, this would have to clear the
850 // iWakeUp flag. However, the !pTA-bUsed may help us in this case.
851 mutex_lock(&pdx->io_mutex); // make sure we have no competitor
852 if (!pTA->bUsed || !pTA->dwEventSz) // check something to wait for...
853 return U14ERR_NOTSET; // ...else we do nothing
854 mutex_unlock(&pdx->io_mutex);
855
856 if (msTimeOut)
857 iWait =
858 wait_event_interruptible_timeout(pTA->wqEvent,
859 pTA->iWakeUp
860 || !pTA->bUsed,
861 msTimeOut);
862 else
863 iWait =
864 wait_event_interruptible(pTA->wqEvent, pTA->iWakeUp
865 || !pTA->bUsed);
866 if (iWait)
867 iReturn = -ERESTARTSYS; // oops - we have had a SIGNAL
868 else
869 iReturn = pTA->iWakeUp; // else the wakeup count
870
871 spin_lock_irq(&pdx->stagedLock);
872 pTA->iWakeUp = 0; // clear the flag
873 spin_unlock_irq(&pdx->stagedLock);
874 }
875 return iReturn;
876}
877
878/****************************************************************************
879** TestEvent
880** Test the event to see if a WaitEvent would return immediately. Returns the
881** number of times a block completed since the last call, or 0 if none or a
882** negative error.
883****************************************************************************/
884int TestEvent(DEVICE_EXTENSION * pdx, int nArea)
885{
886 int iReturn;
887 if ((unsigned)nArea >= MAX_TRANSAREAS)
888 iReturn = U14ERR_BADAREA;
889 else {
890 TRANSAREA *pTA = &pdx->rTransDef[nArea];
891 mutex_lock(&pdx->io_mutex); // make sure we have no competitor
892 spin_lock_irq(&pdx->stagedLock);
893 iReturn = pTA->iWakeUp; // get wakeup count since last call
894 pTA->iWakeUp = 0; // clear the count
895 spin_unlock_irq(&pdx->stagedLock);
896 mutex_unlock(&pdx->io_mutex);
897 }
898 return iReturn;
899}
900
901/****************************************************************************
902** GetTransferInfo
903** Puts the current state of the 1401 in a TGET_TX_BLOCK.
904*****************************************************************************/
905int GetTransfer(DEVICE_EXTENSION * pdx, TGET_TX_BLOCK __user * pTX)
906{
907 int iReturn = U14ERR_NOERROR;
908 unsigned int dwIdent;
909
910 mutex_lock(&pdx->io_mutex);
911 dwIdent = pdx->StagedId; // area ident for last xfer
912 if (dwIdent >= MAX_TRANSAREAS)
913 iReturn = U14ERR_BADAREA;
914 else {
915 // Return the best information we have - we don't have physical addresses
916 TGET_TX_BLOCK tx;
917 memset(&tx, 0, sizeof(tx)); // clean out local work structure
918 tx.size = pdx->rTransDef[dwIdent].dwLength;
919 tx.linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff);
920 tx.avail = GET_TX_MAXENTRIES; // how many blocks we could return
921 tx.used = 1; // number we actually return
922 tx.entries[0].physical =
923 (long long)(tx.linear + pdx->StagedOffset);
924 tx.entries[0].size = tx.size;
925
926 if (copy_to_user(pTX, &tx, sizeof(tx)))
927 iReturn = -EFAULT;
928 }
929 mutex_unlock(&pdx->io_mutex);
930 return iReturn;
931}
932
933/****************************************************************************
934** KillIO1401
935**
936** Empties the host i/o buffers
937****************************************************************************/
938int KillIO1401(DEVICE_EXTENSION * pdx)
939{
940 dev_dbg(&pdx->interface->dev, "%s", __func__);
941 mutex_lock(&pdx->io_mutex);
942 FlushOutBuff(pdx);
943 FlushInBuff(pdx);
944 mutex_unlock(&pdx->io_mutex);
945 return U14ERR_NOERROR;
946}
947
948/****************************************************************************
949** BlkTransState
950** Returns a 0 or a 1 for whether DMA is happening. No point holding a mutex
951** for this as it only does one read.
952*****************************************************************************/
953int BlkTransState(DEVICE_EXTENSION * pdx)
954{
955 int iReturn = pdx->dwDMAFlag != MODE_CHAR;
956 dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn);
957 return iReturn;
958}
959
960/****************************************************************************
961** StateOf1401
962**
963** Puts the current state of the 1401 in the Irp return buffer.
964*****************************************************************************/
965int StateOf1401(DEVICE_EXTENSION * pdx)
966{
967 int iReturn;
968 mutex_lock(&pdx->io_mutex);
969
970 QuickCheck(pdx, false, false); // get state up to date, no reset
971 iReturn = pdx->sCurrentState;
972
973 mutex_unlock(&pdx->io_mutex);
974 dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn);
975
976 return iReturn;
977}
978
979/****************************************************************************
980** StartSelfTest
981**
982** Initiates a self-test cycle. The assumption is that we have no interrupts
983** active, so we should make sure that this is the case.
984*****************************************************************************/
985int StartSelfTest(DEVICE_EXTENSION * pdx)
986{
987 int nGot;
988 mutex_lock(&pdx->io_mutex);
989 dev_dbg(&pdx->interface->dev, "%s", __func__);
990
991 ced_draw_down(pdx); // wait for, then kill outstanding Urbs
992 FlushInBuff(pdx); // Clear out input buffer & pipe
993 FlushOutBuff(pdx); // Clear output buffer & pipe
994// ReadWrite_Cancel(pDeviceObject); /* so things stay tidy */
995 pdx->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flags here */
996
997 nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), DB_SELFTEST, (H_TO_D | VENDOR | DEVREQ), 0, 0, 0, 0, HZ); // allow 1 second timeout
998 pdx->ulSelfTestTime = jiffies + HZ * 30; // 30 seconds into the future
999
1000 mutex_unlock(&pdx->io_mutex);
1001 if (nGot < 0)
1002 dev_err(&pdx->interface->dev, "%s err=%d", __func__, nGot);
1003 return nGot < 0 ? U14ERR_FAIL : U14ERR_NOERROR;
1004}
1005
1006/****************************************************************************
1007** CheckSelfTest
1008**
1009** Check progress of a self-test cycle
1010****************************************************************************/
1011int CheckSelfTest(DEVICE_EXTENSION * pdx, TGET_SELFTEST __user * pGST)
1012{
1013 unsigned int state, error;
1014 int iReturn;
1015 TGET_SELFTEST gst; // local work space
1016 memset(&gst, 0, sizeof(gst)); // clear out the space (sets code 0)
1017
1018 mutex_lock(&pdx->io_mutex);
1019
1020 dev_dbg(&pdx->interface->dev, "%s", __func__);
1021 iReturn = Get1401State(pdx, &state, &error);
1022 if (iReturn == U14ERR_NOERROR) // Only accept zero if it happens twice
1023 iReturn = Get1401State(pdx, &state, &error);
1024
1025 if (iReturn != U14ERR_NOERROR) // Self-test can cause comms errors
1026 { // so we assume still testing
1027 dev_err(&pdx->interface->dev,
1028 "%s Get1401State=%d, assuming still testing", __func__,
1029 iReturn);
1030 state = 0x80; // Force still-testing, no error
1031 error = 0;
1032 iReturn = U14ERR_NOERROR;
1033 }
1034
1035 if ((state == -1) && (error == -1)) // If Get1401State had problems
1036 {
1037 dev_err(&pdx->interface->dev,
1038 "%s Get1401State failed, assuming still testing",
1039 __func__);
1040 state = 0x80; // Force still-testing, no error
1041 error = 0;
1042 }
1043
1044 if ((state & 0xFF) == 0x80) // If we are still in self-test
1045 {
1046 if (state & 0x00FF0000) // Have we got an error?
1047 {
1048 gst.code = (state & 0x00FF0000) >> 16; // read the error code
1049 gst.x = error & 0x0000FFFF; // Error data X
1050 gst.y = (error & 0xFFFF0000) >> 16; // and data Y
1051 dev_dbg(&pdx->interface->dev, "Self-test error code %d",
1052 gst.code);
1053 } else // No error, check for timeout
1054 {
1055 unsigned long ulNow = jiffies; // get current time
1056 if (time_after(ulNow, pdx->ulSelfTestTime)) {
1057 gst.code = -2; // Flag the timeout
1058 dev_dbg(&pdx->interface->dev,
1059 "Self-test timed-out");
1060 } else
1061 dev_dbg(&pdx->interface->dev,
1062 "Self-test on-going");
1063 }
1064 } else {
1065 gst.code = -1; // Flag the test is done
1066 dev_dbg(&pdx->interface->dev, "Self-test done");
1067 }
1068
1069 if (gst.code < 0) // If we have a problem or finished
1070 { // If using the 2890 we should reset properly
1071 if ((pdx->nPipes == 4) && (pdx->s1401Type <= TYPEPOWER))
1072 Is1401(pdx); // Get 1401 reset and OK
1073 else
1074 QuickCheck(pdx, true, true); // Otherwise check without reset unless problems
1075 }
1076 mutex_unlock(&pdx->io_mutex);
1077
1078 if (copy_to_user(pGST, &gst, sizeof(gst)))
1079 return -EFAULT;
1080
1081 return iReturn;
1082}
1083
1084/****************************************************************************
1085** TypeOf1401
1086**
1087** Returns code for standard, plus, micro1401, power1401 or none
1088****************************************************************************/
1089int TypeOf1401(DEVICE_EXTENSION * pdx)
1090{
1091 int iReturn = TYPEUNKNOWN;
1092 mutex_lock(&pdx->io_mutex);
1093 dev_dbg(&pdx->interface->dev, "%s", __func__);
1094
1095 switch (pdx->s1401Type) {
1096 case TYPE1401:
1097 iReturn = U14ERR_STD;
1098 break; // Handle these types directly
1099 case TYPEPLUS:
1100 iReturn = U14ERR_PLUS;
1101 break;
1102 case TYPEU1401:
1103 iReturn = U14ERR_U1401;
1104 break;
1105 default:
1106 if ((pdx->s1401Type >= TYPEPOWER) && (pdx->s1401Type <= 25))
1107 iReturn = pdx->s1401Type + 4; // We can calculate types
1108 else // for up-coming 1401 designs
1109 iReturn = TYPEUNKNOWN; // Don't know or not there
1110 }
1111 dev_dbg(&pdx->interface->dev, "%s %d", __func__, iReturn);
1112 mutex_unlock(&pdx->io_mutex);
1113
1114 return iReturn;
1115}
1116
1117/****************************************************************************
1118** TransferFlags
1119**
1120** Returns flags on block transfer abilities
1121****************************************************************************/
1122int TransferFlags(DEVICE_EXTENSION * pdx)
1123{
1124 int iReturn = U14TF_MULTIA | U14TF_DIAG | // we always have multiple DMA area
1125 U14TF_NOTIFY | U14TF_CIRCTH; // diagnostics, notify and circular
1126 dev_dbg(&pdx->interface->dev, "%s", __func__);
1127 mutex_lock(&pdx->io_mutex);
1128 if (pdx->bIsUSB2) // Set flag for USB2 if appropriate
1129 iReturn |= U14TF_USB2;
1130 mutex_unlock(&pdx->io_mutex);
1131
1132 return iReturn;
1133}
1134
1135/***************************************************************************
1136** DbgCmd1401
1137** Issues a debug\diagnostic command to the 1401 along with a 32-bit datum
1138** This is a utility command used for dbg operations.
1139*/
1140static int DbgCmd1401(DEVICE_EXTENSION * pdx, unsigned char cmd,
1141 unsigned int data)
1142{
1143 int iReturn;
1144 dev_dbg(&pdx->interface->dev, "%s entry", __func__);
1145 iReturn = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), cmd, (H_TO_D | VENDOR | DEVREQ), (unsigned short)data, (unsigned short)(data >> 16), 0, 0, HZ); // allow 1 second timeout
1146 if (iReturn < 0)
1147 dev_err(&pdx->interface->dev, "%s fail code=%d", __func__,
1148 iReturn);
1149
1150 return iReturn;
1151}
1152
1153/****************************************************************************
1154** DbgPeek
1155**
1156** Execute the diagnostic peek operation. Uses address, width and repeats.
1157****************************************************************************/
1158int DbgPeek(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
1159{
1160 int iReturn;
1161 TDBGBLOCK db;
1162
1163 if (copy_from_user(&db, pDB, sizeof(db)))
1164 return -EFAULT;
1165
1166 mutex_lock(&pdx->io_mutex);
1167 dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr);
1168
1169 iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr);
1170 if (iReturn == U14ERR_NOERROR)
1171 iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth);
1172 if (iReturn == U14ERR_NOERROR)
1173 iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats);
1174 if (iReturn == U14ERR_NOERROR)
1175 iReturn = DbgCmd1401(pdx, DB_PEEK, 0);
1176 mutex_unlock(&pdx->io_mutex);
1177
1178 return iReturn;
1179}
1180
1181/****************************************************************************
1182** DbgPoke
1183**
1184** Execute the diagnostic poke operation. Parameters are in the CSBLOCK struct
1185** in order address, size, repeats and value to poke.
1186****************************************************************************/
1187int DbgPoke(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
1188{
1189 int iReturn;
1190 TDBGBLOCK db;
1191
1192 if (copy_from_user(&db, pDB, sizeof(db)))
1193 return -EFAULT;
1194
1195 mutex_lock(&pdx->io_mutex);
1196 dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr);
1197
1198 iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr);
1199 if (iReturn == U14ERR_NOERROR)
1200 iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth);
1201 if (iReturn == U14ERR_NOERROR)
1202 iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats);
1203 if (iReturn == U14ERR_NOERROR)
1204 iReturn = DbgCmd1401(pdx, DB_POKE, db.iData);
1205 mutex_unlock(&pdx->io_mutex);
1206
1207 return iReturn;
1208}
1209
1210/****************************************************************************
1211** DbgRampData
1212**
1213** Execute the diagnostic ramp data operation. Parameters are in the CSBLOCK struct
1214** in order address, default, enable mask, size and repeats.
1215****************************************************************************/
1216int DbgRampData(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
1217{
1218 int iReturn;
1219 TDBGBLOCK db;
1220
1221 if (copy_from_user(&db, pDB, sizeof(db)))
1222 return -EFAULT;
1223
1224 mutex_lock(&pdx->io_mutex);
1225 dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr);
1226
1227 iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr);
1228 if (iReturn == U14ERR_NOERROR)
1229 iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault);
1230 if (iReturn == U14ERR_NOERROR)
1231 iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask);
1232 if (iReturn == U14ERR_NOERROR)
1233 iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth);
1234 if (iReturn == U14ERR_NOERROR)
1235 iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats);
1236 if (iReturn == U14ERR_NOERROR)
1237 iReturn = DbgCmd1401(pdx, DB_RAMPD, 0);
1238 mutex_unlock(&pdx->io_mutex);
1239
1240 return iReturn;
1241}
1242
1243/****************************************************************************
1244** DbgRampAddr
1245**
1246** Execute the diagnostic ramp address operation
1247****************************************************************************/
1248int DbgRampAddr(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
1249{
1250 int iReturn;
1251 TDBGBLOCK db;
1252
1253 if (copy_from_user(&db, pDB, sizeof(db)))
1254 return -EFAULT;
1255
1256 mutex_lock(&pdx->io_mutex);
1257 dev_dbg(&pdx->interface->dev, "%s", __func__);
1258
1259 iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault);
1260 if (iReturn == U14ERR_NOERROR)
1261 iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask);
1262 if (iReturn == U14ERR_NOERROR)
1263 iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth);
1264 if (iReturn == U14ERR_NOERROR)
1265 iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats);
1266 if (iReturn == U14ERR_NOERROR)
1267 iReturn = DbgCmd1401(pdx, DB_RAMPA, 0);
1268 mutex_unlock(&pdx->io_mutex);
1269
1270 return iReturn;
1271}
1272
1273/****************************************************************************
1274** DbgGetData
1275**
1276** Retrieve the data resulting from the last debug Peek operation
1277****************************************************************************/
1278int DbgGetData(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
1279{
1280 int iReturn;
1281 TDBGBLOCK db;
1282 memset(&db, 0, sizeof(db)); // fill returned block with 0s
1283
1284 mutex_lock(&pdx->io_mutex);
1285 dev_dbg(&pdx->interface->dev, "%s", __func__);
1286
1287 // Read back the last peeked value from the 1401.
1288 iReturn = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
1289 DB_DATA, (D_TO_H | VENDOR | DEVREQ), 0, 0,
1290 &db.iData, sizeof(db.iData), HZ);
1291 if (iReturn == sizeof(db.iData)) {
1292 if (copy_to_user(pDB, &db, sizeof(db)))
1293 iReturn = -EFAULT;
1294 else
1295 iReturn = U14ERR_NOERROR;
1296 } else
1297 dev_err(&pdx->interface->dev, "%s failed, code %d", __func__,
1298 iReturn);
1299
1300 mutex_unlock(&pdx->io_mutex);
1301
1302 return iReturn;
1303}
1304
1305/****************************************************************************
1306** DbgStopLoop
1307**
1308** Stop any never-ending debug loop, we just call Get1401State for USB
1309**
1310****************************************************************************/
1311int DbgStopLoop(DEVICE_EXTENSION * pdx)
1312{
1313 int iReturn;
1314 unsigned int uState, uErr;
1315
1316 mutex_lock(&pdx->io_mutex);
1317 dev_dbg(&pdx->interface->dev, "%s", __func__);
1318 iReturn = Get1401State(pdx, &uState, &uErr);
1319 mutex_unlock(&pdx->io_mutex);
1320
1321 return iReturn;
1322}
1323
1324/****************************************************************************
1325** SetCircular
1326**
1327** Sets up a transfer area record for circular transfers. If the area is
1328** already set, we attempt to unset it. Unsetting will fail if the area is
1329** booked and a transfer to that area is in progress. Otherwise, we will
1330** release the area and re-assign it.
1331****************************************************************************/
1332int SetCircular(DEVICE_EXTENSION * pdx, TRANSFERDESC __user * pTD)
1333{
1334 int iReturn;
1335 bool bToHost;
1336 TRANSFERDESC td;
1337
1338 if (copy_from_user(&td, pTD, sizeof(td)))
1339 return -EFAULT;
1340
1341 mutex_lock(&pdx->io_mutex);
1342 dev_dbg(&pdx->interface->dev, "%s area:%d, size:%08x", __func__,
1343 td.wAreaNum, td.dwLength);
1344 bToHost = td.eSize != 0; // this is used as the tohost flag
1345
1346 // The strange cast is done so that we don't get warnings in 32-bit linux about the size of the
1347 // pointer. The pointer is always passed as a 64-bit object so that we don't have problems using
1348 // a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system.
1349 iReturn =
1350 SetArea(pdx, td.wAreaNum,
1351 (char __user *)((unsigned long)td.lpvBuff), td.dwLength,
1352 true, bToHost);
1353 mutex_unlock(&pdx->io_mutex);
1354 return iReturn;
1355}
1356
1357/****************************************************************************
1358** GetCircBlock
1359**
1360** Return the next available block of circularly-transferred data.
1361****************************************************************************/
1362int GetCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB)
1363{
1364 int iReturn = U14ERR_NOERROR;
1365 unsigned int nArea;
1366 TCIRCBLOCK cb;
1367
1368 dev_dbg(&pdx->interface->dev, "%s", __func__);
1369
1370 if (copy_from_user(&cb, pCB, sizeof(cb)))
1371 return -EFAULT;
1372
1373 mutex_lock(&pdx->io_mutex);
1374
1375 nArea = cb.nArea; // Retrieve parameters first
1376 cb.dwOffset = 0; // set default result (nothing)
1377 cb.dwSize = 0;
1378
1379 if (nArea < MAX_TRANSAREAS) // The area number must be OK
1380 {
1381 TRANSAREA *pArea = &pdx->rTransDef[nArea]; // Pointer to relevant info
1382 spin_lock_irq(&pdx->stagedLock); // Lock others out
1383
1384 if ((pArea->bUsed) && (pArea->bCircular) && // Must be circular area
1385 (pArea->bCircToHost)) // For now at least must be to host
1386 {
1387 if (pArea->aBlocks[0].dwSize > 0) // Got anything?
1388 {
1389 cb.dwOffset = pArea->aBlocks[0].dwOffset;
1390 cb.dwSize = pArea->aBlocks[0].dwSize;
1391 dev_dbg(&pdx->interface->dev,
1392 "%s return block 0: %d bytes at %d",
1393 __func__, cb.dwSize, cb.dwOffset);
1394 }
1395 } else
1396 iReturn = U14ERR_NOTSET;
1397
1398 spin_unlock_irq(&pdx->stagedLock);
1399 } else
1400 iReturn = U14ERR_BADAREA;
1401
1402 if (copy_to_user(pCB, &cb, sizeof(cb)))
1403 iReturn = -EFAULT;
1404
1405 mutex_unlock(&pdx->io_mutex);
1406 return iReturn;
1407}
1408
1409/****************************************************************************
1410** FreeCircBlock
1411**
1412** Frees a block of circularly-transferred data and returns the next one.
1413****************************************************************************/
1414int FreeCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB)
1415{
1416 int iReturn = U14ERR_NOERROR;
1417 unsigned int nArea, uStart, uSize;
1418 TCIRCBLOCK cb;
1419
1420 dev_dbg(&pdx->interface->dev, "%s", __func__);
1421
1422 if (copy_from_user(&cb, pCB, sizeof(cb)))
1423 return -EFAULT;
1424
1425 mutex_lock(&pdx->io_mutex);
1426
1427 nArea = cb.nArea; // Retrieve parameters first
1428 uStart = cb.dwOffset;
1429 uSize = cb.dwSize;
1430 cb.dwOffset = 0; // then set default result (nothing)
1431 cb.dwSize = 0;
1432
1433 if (nArea < MAX_TRANSAREAS) // The area number must be OK
1434 {
1435 TRANSAREA *pArea = &pdx->rTransDef[nArea]; // Pointer to relevant info
1436 spin_lock_irq(&pdx->stagedLock); // Lock others out
1437
1438 if ((pArea->bUsed) && (pArea->bCircular) && // Must be circular area
1439 (pArea->bCircToHost)) // For now at least must be to host
1440 {
1441 bool bWaiting = false;
1442
1443 if ((pArea->aBlocks[0].dwSize >= uSize) && // Got anything?
1444 (pArea->aBlocks[0].dwOffset == uStart)) // Must be legal data
1445 {
1446 pArea->aBlocks[0].dwSize -= uSize;
1447 pArea->aBlocks[0].dwOffset += uSize;
1448 if (pArea->aBlocks[0].dwSize == 0) // Have we emptied this block?
1449 {
1450 if (pArea->aBlocks[1].dwSize) // Is there a second block?
1451 {
1452 pArea->aBlocks[0] = pArea->aBlocks[1]; // Copy down block 2 data
1453 pArea->aBlocks[1].dwSize = 0; // and mark the second block as unused
1454 pArea->aBlocks[1].dwOffset = 0;
1455 } else
1456 pArea->aBlocks[0].dwOffset = 0;
1457 }
1458
1459 dev_dbg(&pdx->interface->dev,
1460 "%s free %d bytes at %d, return %d bytes at %d, wait=%d",
1461 __func__, uSize, uStart,
1462 pArea->aBlocks[0].dwSize,
1463 pArea->aBlocks[0].dwOffset,
1464 pdx->bXFerWaiting);
1465
1466 // Return the next available block of memory as well
1467 if (pArea->aBlocks[0].dwSize > 0) // Got anything?
1468 {
1469 cb.dwOffset =
1470 pArea->aBlocks[0].dwOffset;
1471 cb.dwSize = pArea->aBlocks[0].dwSize;
1472 }
1473
1474 bWaiting = pdx->bXFerWaiting;
1475 if (bWaiting && pdx->bStagedUrbPending) {
1476 dev_err(&pdx->interface->dev,
1477 "%s ERROR: waiting xfer and staged Urb pending!",
1478 __func__);
1479 bWaiting = false;
1480 }
1481 } else {
1482 dev_err(&pdx->interface->dev,
1483 "%s ERROR: freeing %d bytes at %d, block 0 is %d bytes at %d",
1484 __func__, uSize, uStart,
1485 pArea->aBlocks[0].dwSize,
1486 pArea->aBlocks[0].dwOffset);
1487 iReturn = U14ERR_NOMEMORY;
1488 }
1489
1490 // If we have one, kick off pending transfer
1491 if (bWaiting) // Got a block xfer waiting?
1492 {
1493 int RWMStat =
1494 ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard,
1495 pdx->rDMAInfo.wIdent,
1496 pdx->rDMAInfo.dwOffset,
1497 pdx->rDMAInfo.dwSize);
1498 if (RWMStat != U14ERR_NOERROR)
1499 dev_err(&pdx->interface->dev,
1500 "%s rw setup failed %d",
1501 __func__, RWMStat);
1502 }
1503 } else
1504 iReturn = U14ERR_NOTSET;
1505
1506 spin_unlock_irq(&pdx->stagedLock);
1507 } else
1508 iReturn = U14ERR_BADAREA;
1509
1510 if (copy_to_user(pCB, &cb, sizeof(cb)))
1511 return -EFAULT;
1512
1513 mutex_unlock(&pdx->io_mutex);
1514 return iReturn;
1515}
drivers/staging/ced1401/ced_ioctl.h+345−0
@@ -0,0 +1,345 @@
1/*
2 * IOCTL calls for the CED1401 driver
3 * Copyright (C) 2010 Cambridge Electronic Design Ltd
4 * Author Greg P Smith (greg@ced.co.uk)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifndef __CED_IOCTL_H__
17#define __CED_IOCTL_H__
18
19#include <linux/ioctl.h>
20
21/* dma modes, only MODE_CHAR and MODE_LINEAR are used in this driver */
22#define MODE_CHAR 0
23#define MODE_LINEAR 1
24
25/****************************************************************************
26** TypeDefs
27*****************************************************************************/
28
29typedef unsigned short TBLOCKENTRY; /* index the blk transfer table 0-7 */
30
31typedef struct TransferDesc {
32 long long lpvBuff; /* address of transfer area (for 64 or 32 bit) */
33 unsigned int dwLength; /* length of the area */
34 TBLOCKENTRY wAreaNum; /* number of transfer area to set up */
35 short eSize; /* element size - is tohost flag for circular */
36} TRANSFERDESC;
37
38typedef TRANSFERDESC * LPTRANSFERDESC;
39
40typedef struct TransferEvent {
41 unsigned int dwStart; /* offset into the area */
42 unsigned int dwLength; /* length of the region */
43 unsigned short wAreaNum; /* the area number */
44 unsigned short wFlags; /* bit 0 set for toHost */
45 int iSetEvent; /* could be dummy in LINUX */
46} TRANSFEREVENT;
47
48#define MAX_TRANSFER_SIZE 0x4000 /* Maximum data bytes per IRP */
49#define MAX_AREA_LENGTH 0x100000 /* Maximum size of transfer area */
50#define MAX_TRANSAREAS 8 /* definitions for dma set up */
51
52typedef struct TGetSelfTest {
53 int code; /* self-test error code */
54 int x, y; /* additional information */
55} TGET_SELFTEST;
56
57/* Debug block used for several commands. Not all fields are used for all commands. */
58typedef struct TDbgBlock {
59 int iAddr; /* the address in the 1401 */
60 int iRepeats; /* number of repeats */
61 int iWidth; /* width in bytes 1, 2, 4 */
62 int iDefault; /* default value */
63 int iMask; /* mask to apply */
64 int iData; /* data for poke, result for peek */
65} TDBGBLOCK;
66
67/* Used to collect information about a circular block from the device driver */
68typedef struct TCircBlock {
69 unsigned int nArea; /* the area to collect information from */
70 unsigned int dwOffset; /* offset into the area to the available block */
71 unsigned int dwSize; /* size of the area */
72} TCIRCBLOCK;
73
74/* Used to clollect the 1401 status */
75typedef struct TCSBlock {
76 unsigned int uiState;
77 unsigned int uiError;
78} TCSBLOCK;
79
80/*
81 * As seen by the user, an ioctl call looks like: int ioctl(int fd, unsigned
82 * long cmd, char* argp); We will then have all sorts of variants on this that
83 * can be used to pass stuff to our driver. We will generate macros for each
84 * type of call so as to provide some sort of type safety in the calling:
85 */
86#define CED_MAGIC_IOC 0xce
87
88/* NBNB: READ and WRITE are from the point of view of the device, not user. */
89typedef struct ced_ioc_string {
90 int nChars;
91 char buffer[256];
92} CED_IOC_STRING;
93
94#define IOCTL_CED_SENDSTRING(n) _IOC(_IOC_WRITE, CED_MAGIC_IOC, 2, n)
95
96#define IOCTL_CED_RESET1401 _IO(CED_MAGIC_IOC, 3)
97#define IOCTL_CED_GETCHAR _IO(CED_MAGIC_IOC, 4)
98#define IOCTL_CED_SENDCHAR _IO(CED_MAGIC_IOC, 5)
99#define IOCTL_CED_STAT1401 _IO(CED_MAGIC_IOC, 6)
100#define IOCTL_CED_LINECOUNT _IO(CED_MAGIC_IOC, 7)
101#define IOCTL_CED_GETSTRING(nMax) _IOC(_IOC_READ, CED_MAGIC_IOC, 8, nMax)
102
103#define IOCTL_CED_SETTRANSFER _IOW(CED_MAGIC_IOC, 11, TRANSFERDESC)
104#define IOCTL_CED_UNSETTRANSFER _IO(CED_MAGIC_IOC, 12)
105#define IOCTL_CED_SETEVENT _IOW(CED_MAGIC_IOC, 13, TRANSFEREVENT)
106#define IOCTL_CED_GETOUTBUFSPACE _IO(CED_MAGIC_IOC, 14)
107#define IOCTL_CED_GETBASEADDRESS _IO(CED_MAGIC_IOC, 15)
108#define IOCTL_CED_GETDRIVERREVISION _IO(CED_MAGIC_IOC, 16)
109
110#define IOCTL_CED_GETTRANSFER _IOR(CED_MAGIC_IOC, 17, TGET_TX_BLOCK)
111#define IOCTL_CED_KILLIO1401 _IO(CED_MAGIC_IOC, 18)
112#define IOCTL_CED_BLKTRANSSTATE _IO(CED_MAGIC_IOC, 19)
113
114#define IOCTL_CED_STATEOF1401 _IO(CED_MAGIC_IOC, 23)
115#define IOCTL_CED_GRAB1401 _IO(CED_MAGIC_IOC, 25)
116#define IOCTL_CED_FREE1401 _IO(CED_MAGIC_IOC, 26)
117#define IOCTL_CED_STARTSELFTEST _IO(CED_MAGIC_IOC, 31)
118#define IOCTL_CED_CHECKSELFTEST _IOR(CED_MAGIC_IOC, 32, TGET_SELFTEST)
119#define IOCTL_CED_TYPEOF1401 _IO(CED_MAGIC_IOC, 33)
120#define IOCTL_CED_TRANSFERFLAGS _IO(CED_MAGIC_IOC, 34)
121
122#define IOCTL_CED_DBGPEEK _IOW(CED_MAGIC_IOC, 35, TDBGBLOCK)
123#define IOCTL_CED_DBGPOKE _IOW(CED_MAGIC_IOC, 36, TDBGBLOCK)
124#define IOCTL_CED_DBGRAMPDATA _IOW(CED_MAGIC_IOC, 37, TDBGBLOCK)
125#define IOCTL_CED_DBGRAMPADDR _IOW(CED_MAGIC_IOC, 38, TDBGBLOCK)
126#define IOCTL_CED_DBGGETDATA _IOR(CED_MAGIC_IOC, 39, TDBGBLOCK)
127#define IOCTL_CED_DBGSTOPLOOP _IO(CED_MAGIC_IOC, 40)
128#define IOCTL_CED_FULLRESET _IO(CED_MAGIC_IOC, 41)
129#define IOCTL_CED_SETCIRCULAR _IOW(CED_MAGIC_IOC, 42, TRANSFERDESC)
130#define IOCTL_CED_GETCIRCBLOCK _IOWR(CED_MAGIC_IOC, 43, TCIRCBLOCK)
131#define IOCTL_CED_FREECIRCBLOCK _IOWR(CED_MAGIC_IOC, 44, TCIRCBLOCK)
132#define IOCTL_CED_WAITEVENT _IO(CED_MAGIC_IOC, 45)
133#define IOCTL_CED_TESTEVENT _IO(CED_MAGIC_IOC, 46)
134
135#ifndef __KERNEL__
136/*
137 * If nothing said about return value, it is a U14ERR_... error code
138 * (U14ERR_NOERROR for none)
139 */
140inline int CED_SendString(int fh, const char *szText, int n)
141{
142 return ioctl(fh, IOCTL_CED_SENDSTRING(n), szText);
143}
144
145inline int CED_Reset1401(int fh)
146{
147 return ioctl(fh, IOCTL_CED_RESET1401);
148}
149
150/* Return the singe character or a -ve error code. */
151inline int CED_GetChar(int fh)
152{
153 return ioctl(fh, IOCTL_CED_GETCHAR);
154}
155
156/* Return character count in input buffer */
157inline int CED_Stat1401(int fh)
158{
159 return ioctl(fh, IOCTL_CED_STAT1401);
160}
161
162inline int CED_SendChar(int fh, char c)
163{
164 return ioctl(fh, IOCTL_CED_SENDCHAR, c);
165}
166
167inline int CED_LineCount(int fh)
168{
169 return ioctl(fh, IOCTL_CED_LINECOUNT);
170}
171
172/*
173 * return the count of characters returned. If the string was terminated by CR
174 * or 0, then the 0 is part of the count. Otherwise, we will add a zero if
175 * there is room, but it is not included in the count. The return value is 0
176 * if there was nothing to read.
177 */
178inline int CED_GetString(int fh, char *szText, int nMax)
179{
180 return ioctl(fh, IOCTL_CED_GETSTRING(nMax), szText);
181}
182
183/* returns space in the output buffer. */
184inline int CED_GetOutBufSpace(int fh)
185{
186 return ioctl(fh, IOCTL_CED_GETOUTBUFSPACE);
187}
188
189/* This always returns -1 as not implemented. */
190inline int CED_GetBaseAddress(int fh)
191{
192 return ioctl(fh, IOCTL_CED_GETBASEADDRESS);
193}
194
195/* returns the major revision <<16 | minor revision. */
196inline int CED_GetDriverRevision(int fh)
197{
198 return ioctl(fh, IOCTL_CED_GETDRIVERREVISION);
199}
200
201inline int CED_SetTransfer(int fh, TRANSFERDESC *pTD)
202{
203 return ioctl(fh, IOCTL_CED_SETTRANSFER, pTD);
204}
205
206inline int CED_UnsetTransfer(int fh, int nArea)
207{
208 return ioctl(fh, IOCTL_CED_UNSETTRANSFER, nArea);
209}
210
211inline int CED_SetEvent(int fh, TRANSFEREVENT *pTE)
212{
213 return ioctl(fh, IOCTL_CED_SETEVENT, pTE);
214}
215
216inline int CED_GetTransfer(int fh, TGET_TX_BLOCK *pTX)
217{
218 return ioctl(fh, IOCTL_CED_GETTRANSFER, pTX);
219}
220
221inline int CED_KillIO1401(int fh)
222{
223 return ioctl(fh, IOCTL_CED_KILLIO1401);
224}
225
226/* returns 0 if no active DMA, 1 if active */
227inline int CED_BlkTransState(int fh)
228{
229 return ioctl(fh, IOCTL_CED_BLKTRANSSTATE);
230}
231
232inline int CED_StateOf1401(int fh)
233{
234 return ioctl(fh, IOCTL_CED_STATEOF1401);
235}
236
237inline int CED_Grab1401(int fh)
238{
239 return ioctl(fh, IOCTL_CED_GRAB1401);
240}
241
242inline int CED_Free1401(int fh)
243{
244 return ioctl(fh, IOCTL_CED_FREE1401);
245}
246
247inline int CED_StartSelfTest(int fh)
248{
249 return ioctl(fh, IOCTL_CED_STARTSELFTEST);
250}
251
252inline int CED_CheckSelfTest(int fh, TGET_SELFTEST *pGST)
253{
254 return ioctl(fh, IOCTL_CED_CHECKSELFTEST, pGST);
255}
256
257inline int CED_TypeOf1401(int fh)
258{
259 return ioctl(fh, IOCTL_CED_TYPEOF1401);
260}
261
262inline int CED_TransferFlags(int fh)
263{
264 return ioctl(fh, IOCTL_CED_TRANSFERFLAGS);
265}
266
267inline int CED_DbgPeek(int fh, TDBGBLOCK *pDB)
268{
269 return ioctl(fh, IOCTL_CED_DBGPEEK, pDB);
270}
271
272inline int CED_DbgPoke(int fh, TDBGBLOCK *pDB)
273{
274 return ioctl(fh, IOCTL_CED_DBGPOKE, pDB);
275}
276
277inline int CED_DbgRampData(int fh, TDBGBLOCK *pDB)
278{
279 return ioctl(fh, IOCTL_CED_DBGRAMPDATA, pDB);
280}
281
282inline int CED_DbgRampAddr(int fh, TDBGBLOCK *pDB)
283{
284 return ioctl(fh, IOCTL_CED_DBGRAMPADDR, pDB);
285}
286
287inline int CED_DbgGetData(int fh, TDBGBLOCK *pDB)
288{
289 return ioctl(fh, IOCTL_CED_DBGGETDATA, pDB);
290}
291
292inline int CED_DbgStopLoop(int fh)
293{
294 return ioctl(fh, IOCTL_CED_DBGSTOPLOOP);
295}
296
297inline int CED_FullReset(int fh)
298{
299 return ioctl(fh, IOCTL_CED_FULLRESET);
300}
301
302inline int CED_SetCircular(int fh, TRANSFERDESC *pTD)
303{
304 return ioctl(fh, IOCTL_CED_SETCIRCULAR, pTD);
305}
306
307inline int CED_GetCircBlock(int fh, TCIRCBLOCK *pCB)
308{
309 return ioctl(fh, IOCTL_CED_GETCIRCBLOCK, pCB);
310}
311
312inline int CED_FreeCircBlock(int fh, TCIRCBLOCK *pCB)
313{
314 return ioctl(fh, IOCTL_CED_FREECIRCBLOCK, pCB);
315}
316
317inline int CED_WaitEvent(int fh, int nArea, int msTimeOut)
318{
319 return ioctl(fh, IOCTL_CED_WAITEVENT, (nArea & 0xff)|(msTimeOut << 8));
320}
321
322inline int CED_TestEvent(int fh, int nArea)
323{
324 return ioctl(fh, IOCTL_CED_TESTEVENT, nArea);
325}
326#endif
327
328#ifdef NOTWANTEDYET
329#define IOCTL_CED_REGCALLBACK _IO(CED_MAGIC_IOC, 9) /* Not used */
330#define IOCTL_CED_GETMONITORBUF _IO(CED_MAGIC_IOC, 10) /* Not used */
331
332#define IOCTL_CED_BYTECOUNT _IO(CED_MAGIC_IOC, 20) /* Not used */
333#define IOCTL_CED_ZEROBLOCKCOUNT _IO(CED_MAGIC_IOC, 21) /* Not used */
334#define IOCTL_CED_STOPCIRCULAR _IO(CED_MAGIC_IOC, 22) /* Not used */
335
336#define IOCTL_CED_REGISTERS1401 _IO(CED_MAGIC_IOC, 24) /* Not used */
337#define IOCTL_CED_STEP1401 _IO(CED_MAGIC_IOC, 27) /* Not used */
338#define IOCTL_CED_SET1401REGISTERS _IO(CED_MAGIC_IOC, 28) /* Not used */
339#define IOCTL_CED_STEPTILL1401 _IO(CED_MAGIC_IOC, 29) /* Not used */
340#define IOCTL_CED_SETORIN _IO(CED_MAGIC_IOC, 30) /* Not used */
341
342#endif
343
344/* __CED_IOCTL_H__ */
345#endif
drivers/staging/ced1401/machine.h+127−0
@@ -0,0 +1,127 @@
1/*****************************************************************************
2**
3** machine.h
4**
5** Copyright (c) Cambridge Electronic Design Limited 1991,1992,2010
6**
7** This program is free software; you can redistribute it and/or
8** modify it under the terms of the GNU General Public License
9** as published by the Free Software Foundation; either version 2
10** of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20**
21** Contact CED: Cambridge Electronic Design Limited, Science Park, Milton Road
22** Cambridge, CB6 0FE.
23** www.ced.co.uk
24** greg@ced.co.uk
25**
26** This file is included at the start of 'C' or 'C++' source file to define
27** things for cross-platform/compiler interoperability. This used to deal with
28** MSDOS/16-bit stuff, but this was all removed in Decemeber 2010. There are
29** three things to consider: Windows, LINUX, mac OSX (BSD Unix) and 32 vs 64
30** bit. At the time of writing (DEC 2010) there is a consensus on the following
31** and their unsigned equivalents:
32**
33** type bits
34** char 8
35** short 16
36** int 32
37** long long 64
38**
39** long is a problem as it is always 64 bits on linux/unix and is always 32 bits
40** on windows.
41** On windows, we define _IS_WINDOWS_ and one of WIN32 or WIN64.
42** On linux we define LINUX
43** On Max OSX we define MACOSX
44**
45*/
46
47#ifndef __MACHINE_H__
48#define __MACHINE_H__
49#ifndef __KERNEL__
50#include <float.h>
51#include <limits.h>
52#endif
53
54/*
55** The initial section is to identify the operating system
56*/
57#if (defined(__linux__) || defined(_linux) || defined(__linux)) && !defined(LINUX)
58#define LINUX 1
59#endif
60
61#if (defined(__WIN32__) || defined(_WIN32)) && !defined(WIN32)
62#define WIN32 1
63#endif
64
65#if defined(__APPLE__)
66#define MACOSX
67#endif
68
69#if defined(_WIN64)
70#undef WIN32
71#undef WIN64
72#define WIN64 1
73#endif
74
75#if defined(WIN32) || defined(WIN64)
76#define _IS_WINDOWS_ 1
77#endif
78
79#if defined(LINUX) || defined(MAXOSX)
80 #define FAR
81
82 typedef int BOOL; // To match Windows
83 typedef char * LPSTR;
84 typedef const char * LPCSTR;
85 typedef unsigned short WORD;
86 typedef unsigned int DWORD;
87 typedef unsigned char BYTE;
88 typedef BYTE BOOLEAN;
89 typedef unsigned char UCHAR;
90 #define __packed __attribute__((packed))
91 typedef BYTE * LPBYTE;
92 #define HIWORD(x) (WORD)(((x)>>16) & 0xffff)
93 #define LOWORD(x) (WORD)((x) & 0xffff)
94#endif
95
96#ifdef _IS_WINDOWS_
97#include <windows.h>
98#define __packed
99#endif
100
101/*
102** Sort out the DllExport and DllImport macros. The GCC compiler has its own
103** syntax for this, though it also supports the MS specific __declspec() as
104** a synonym.
105*/
106#ifdef GNUC
107 #define DllExport __attribute__((dllexport))
108 #define DllImport __attribute__((dllimport))
109#endif
110
111#ifndef DllExport
112#ifdef _IS_WINDOWS_
113 #define DllExport __declspec(dllexport)
114 #define DllImport __declspec(dllimport)
115#else
116 #define DllExport
117 #define DllImport
118#endif
119#endif /* _IS_WINDOWS_ */
120
121
122#ifndef TRUE
123 #define TRUE 1
124 #define FALSE 0
125#endif
126
127#endif
drivers/staging/ced1401/usb1401.c+1637−0
@@ -0,0 +1,1637 @@
1/***********************************************************************************
2 CED1401 usb driver. This basic loading is based on the usb-skeleton.c code that is:
3 Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
4 Copyright (C) 2012 Alois Schloegl <alois.schloegl@ist.ac.at>
5 There is not a great deal of the skeleton left.
6
7 All the remainder dealing specifically with the CED1401 is based on drivers written
8 by CED for other systems (mainly Windows) and is:
9 Copyright (C) 2010 Cambridge Electronic Design Ltd
10 Author Greg P Smith (greg@ced.co.uk)
11
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 as published by the Free Software Foundation; either version 2
15 of the License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25
26Endpoints
27*********
28There are 4 endpoints plus the control endpoint in the standard interface
29provided by most 1401s. The control endpoint is used for standard USB requests,
30plus various CED-specific transactions such as start self test, debug and get
31the 1401 status. The other endpoints are:
32
33 1 Characters to the 1401
34 2 Characters from the 1401
35 3 Block data to the 1401
36 4 Block data to the host.
37
38inside the driver these are indexed as an array from 0 to 3, transactions
39over the control endpoint are carried out using a separate mechanism. The
40use of the endpoints is mostly straightforward, with the driver issuing
41IO request packets (IRPs) as required to transfer data to and from the 1401.
42The handling of endpoint 2 is different because it is used for characters
43from the 1401, which can appear spontaneously and without any other driver
44activity - for example to repeatedly request DMA transfers in Spike2. The
45desired effect is achieved by using an interrupt endpoint which can be
46polled to see if it has data available, and writing the driver so that it
47always maintains a pending read IRP from that endpoint which will read the
48character data and terminate as soon as the 1401 makes data available. This
49works very well, some care is taken with when you kick off this character
50read IRP to avoid it being active when it is not wanted but generally it
51is running all the time.
52
53In the 2270, there are only three endpoints plus the control endpoint. In
54addition to the transactions mentioned above, the control endpoint is used
55to transfer character data to the 1401. The other endpoints are used as:
56
57 1 Characters from the 1401
58 2 Block data to the 1401
59 3 Block data to the host.
60
61The type of interface available is specified by the interface subclass field
62in the interface descriptor provided by the 1401. See the USB_INT_ constants
63for the values that this field can hold.
64
65****************************************************************************
66Linux implementation
67
68Although Linux Device Drivers (3rd Edition) was a major source of information,
69it is very out of date. A lot of information was gleaned from the latest
70usb_skeleton.c code (you need to download the kernel sources to get this).
71
72To match the Windows version, everything is done using ioctl calls. All the
73device state is held in the DEVICE_EXTENSION (named to match Windows use).
74Block transfers are done by using get_user_pages() to pin down a list of
75pages that we hold a pointer to in the device driver. We also allocate a
76coherent transfer buffer of size STAGED_SZ (this must be a multiple of the
77bulk endpoint size so that the 1401 does not realise that we break large
78transfers down into smaller pieces). We use kmap_atomic() to get a kernel
79va for each page, as it is required, for copying; see CopyUserSpace().
80
81All character and data transfers are done using asynchronous IO. All Urbs are
82tracked by anchoring them. Status and debug ioctls are implemented with the
83synchronous non-Urb based transfers.
84*/
85
86#include <linux/kernel.h>
87#include <linux/errno.h>
88#include <linux/usb.h>
89#include <linux/mutex.h>
90#include <linux/mm.h>
91#include <linux/highmem.h>
92#include <linux/version.h>
93#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) )
94#include <linux/init.h>
95#include <linux/slab.h>
96#include <linux/module.h>
97#include <linux/kref.h>
98#include <linux/uaccess.h>
99#endif
100
101#include "usb1401.h"
102
103/* Define these values to match your devices */
104#define USB_CED_VENDOR_ID 0x0525
105#define USB_CED_PRODUCT_ID 0xa0f0
106
107/* table of devices that work with this driver */
108static const struct usb_device_id ced_table[] = {
109 {USB_DEVICE(USB_CED_VENDOR_ID, USB_CED_PRODUCT_ID)},
110 {} /* Terminating entry */
111};
112
113MODULE_DEVICE_TABLE(usb, ced_table);
114
115/* Get a minor range for your devices from the usb maintainer */
116#define USB_CED_MINOR_BASE 192
117
118/* our private defines. if this grows any larger, use your own .h file */
119#define MAX_TRANSFER (PAGE_SIZE - 512)
120/* MAX_TRANSFER is chosen so that the VM is not stressed by
121 allocations > PAGE_SIZE and the number of packets in a page
122 is an integer 512 is the largest possible packet on EHCI */
123#define WRITES_IN_FLIGHT 8
124/* arbitrarily chosen */
125
126/*
127The cause for these errors is that the driver makes use of the functions usb_buffer_alloc() and usb_buffer_free() which got renamed in kernel 2.6.35. This is stated in the Changelog: USB: rename usb_buffer_alloc() and usb_buffer_free() users
128 For more clearance what the functions actually do,
129 usb_buffer_alloc() is renamed to usb_alloc_coherent()
130 usb_buffer_free() is renamed to usb_free_coherent()
131 This is needed on Debian 2.6.32-5-amd64
132*/
133#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) )
134#define usb_alloc_coherent usb_buffer_alloc
135#define usb_free_coherent usb_buffer_free
136#define noop_llseek NULL
137#endif
138
139static struct usb_driver ced_driver;
140
141static void ced_delete(struct kref *kref)
142{
143 DEVICE_EXTENSION *pdx = to_DEVICE_EXTENSION(kref);
144
145 // Free up the output buffer, then free the output urb. Note that the interface member
146 // of pdx will probably be NULL, so cannot be used to get to dev.
147 usb_free_coherent(pdx->udev, OUTBUF_SZ, pdx->pCoherCharOut,
148 pdx->pUrbCharOut->transfer_dma);
149 usb_free_urb(pdx->pUrbCharOut);
150
151 // Do the same for chan input
152 usb_free_coherent(pdx->udev, INBUF_SZ, pdx->pCoherCharIn,
153 pdx->pUrbCharIn->transfer_dma);
154 usb_free_urb(pdx->pUrbCharIn);
155
156 // Do the same for the block transfers
157 usb_free_coherent(pdx->udev, STAGED_SZ, pdx->pCoherStagedIO,
158 pdx->pStagedUrb->transfer_dma);
159 usb_free_urb(pdx->pStagedUrb);
160
161 usb_put_dev(pdx->udev);
162 kfree(pdx);
163}
164
165// This is the driver end of the open() call from user space.
166static int ced_open(struct inode *inode, struct file *file)
167{
168 DEVICE_EXTENSION *pdx;
169 int retval = 0;
170 int subminor = iminor(inode);
171 struct usb_interface *interface =
172 usb_find_interface(&ced_driver, subminor);
173 if (!interface) {
174 pr_err("%s - error, can't find device for minor %d", __func__,
175 subminor);
176 retval = -ENODEV;
177 goto exit;
178 }
179
180 pdx = usb_get_intfdata(interface);
181 if (!pdx) {
182 retval = -ENODEV;
183 goto exit;
184 }
185
186 dev_dbg(&interface->dev, "%s got pdx", __func__);
187
188 /* increment our usage count for the device */
189 kref_get(&pdx->kref);
190
191 /* lock the device to allow correctly handling errors
192 * in resumption */
193 mutex_lock(&pdx->io_mutex);
194
195 if (!pdx->open_count++) {
196 retval = usb_autopm_get_interface(interface);
197 if (retval) {
198 pdx->open_count--;
199 mutex_unlock(&pdx->io_mutex);
200 kref_put(&pdx->kref, ced_delete);
201 goto exit;
202 }
203 } else { //uncomment this block if you want exclusive open
204 dev_err(&interface->dev, "%s fail: already open", __func__);
205 retval = -EBUSY;
206 pdx->open_count--;
207 mutex_unlock(&pdx->io_mutex);
208 kref_put(&pdx->kref, ced_delete);
209 goto exit;
210 }
211 /* prevent the device from being autosuspended */
212
213 /* save our object in the file's private structure */
214 file->private_data = pdx;
215 mutex_unlock(&pdx->io_mutex);
216
217exit:
218 return retval;
219}
220
221static int ced_release(struct inode *inode, struct file *file)
222{
223 DEVICE_EXTENSION *pdx = file->private_data;
224 if (pdx == NULL)
225 return -ENODEV;
226
227 dev_dbg(&pdx->interface->dev, "%s called", __func__);
228 mutex_lock(&pdx->io_mutex);
229 if (!--pdx->open_count && pdx->interface) // Allow autosuspend
230 usb_autopm_put_interface(pdx->interface);
231 mutex_unlock(&pdx->io_mutex);
232
233 kref_put(&pdx->kref, ced_delete); // decrement the count on our device
234 return 0;
235}
236
237static int ced_flush(struct file *file, fl_owner_t id)
238{
239 int res;
240 DEVICE_EXTENSION *pdx = file->private_data;
241 if (pdx == NULL)
242 return -ENODEV;
243
244 dev_dbg(&pdx->interface->dev, "%s char in pend=%d", __func__,
245 pdx->bReadCharsPending);
246
247 /* wait for io to stop */
248 mutex_lock(&pdx->io_mutex);
249 dev_dbg(&pdx->interface->dev, "%s got io_mutex", __func__);
250 ced_draw_down(pdx);
251
252 /* read out errors, leave subsequent opens a clean slate */
253 spin_lock_irq(&pdx->err_lock);
254 res = pdx->errors ? (pdx->errors == -EPIPE ? -EPIPE : -EIO) : 0;
255 pdx->errors = 0;
256 spin_unlock_irq(&pdx->err_lock);
257
258 mutex_unlock(&pdx->io_mutex);
259 dev_dbg(&pdx->interface->dev, "%s exit reached", __func__);
260
261 return res;
262}
263
264/***************************************************************************
265** CanAcceptIoRequests
266** If the device is removed, interface is set NULL. We also clear our pointer
267** from the interface, so we should make sure that pdx is not NULL. This will
268** not help with a device extension held by a file.
269** return true if can accept new io requests, else false
270*/
271static bool CanAcceptIoRequests(DEVICE_EXTENSION * pdx)
272{
273 return pdx && pdx->interface; // Can we accept IO requests
274}
275
276/****************************************************************************
277** Callback routine to complete writes. This may need to fire off another
278** urb to complete the transfer.
279****************************************************************************/
280static void ced_writechar_callback(struct urb *pUrb)
281{
282 DEVICE_EXTENSION *pdx = pUrb->context;
283 int nGot = pUrb->actual_length; // what we transferred
284
285 if (pUrb->status) { // sync/async unlink faults aren't errors
286 if (!
287 (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
288 || pUrb->status == -ESHUTDOWN)) {
289 dev_err(&pdx->interface->dev,
290 "%s - nonzero write bulk status received: %d",
291 __func__, pUrb->status);
292 }
293
294 spin_lock(&pdx->err_lock);
295 pdx->errors = pUrb->status;
296 spin_unlock(&pdx->err_lock);
297 nGot = 0; // and tidy up again if so
298
299 spin_lock(&pdx->charOutLock); // already at irq level
300 pdx->dwOutBuffGet = 0; // Reset the output buffer
301 pdx->dwOutBuffPut = 0;
302 pdx->dwNumOutput = 0; // Clear the char count
303 pdx->bPipeError[0] = 1; // Flag an error for later
304 pdx->bSendCharsPending = false; // Allow other threads again
305 spin_unlock(&pdx->charOutLock); // already at irq level
306 dev_dbg(&pdx->interface->dev,
307 "%s - char out done, 0 chars sent", __func__);
308 } else {
309 dev_dbg(&pdx->interface->dev,
310 "%s - char out done, %d chars sent", __func__, nGot);
311 spin_lock(&pdx->charOutLock); // already at irq level
312 pdx->dwNumOutput -= nGot; // Now adjust the char send buffer
313 pdx->dwOutBuffGet += nGot; // to match what we did
314 if (pdx->dwOutBuffGet >= OUTBUF_SZ) // Can't do this any earlier as data could be overwritten
315 pdx->dwOutBuffGet = 0;
316
317 if (pdx->dwNumOutput > 0) // if more to be done...
318 {
319 int nPipe = 0; // The pipe number to use
320 int iReturn;
321 char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet];
322 unsigned int dwCount = pdx->dwNumOutput; // maximum to send
323 if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ) // does it cross buffer end?
324 dwCount = OUTBUF_SZ - pdx->dwOutBuffGet;
325 spin_unlock(&pdx->charOutLock); // we are done with stuff that changes
326 memcpy(pdx->pCoherCharOut, pDat, dwCount); // copy output data to the buffer
327 usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev,
328 usb_sndbulkpipe(pdx->udev,
329 pdx->epAddr[0]),
330 pdx->pCoherCharOut, dwCount,
331 ced_writechar_callback, pdx);
332 pdx->pUrbCharOut->transfer_flags |=
333 URB_NO_TRANSFER_DMA_MAP;
334 usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); // in case we need to kill it
335 iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_ATOMIC);
336 dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__,
337 dwCount, pDat);
338 spin_lock(&pdx->charOutLock); // grab lock for errors
339 if (iReturn) {
340 pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later
341 pdx->bSendCharsPending = false; // Allow other threads again
342 usb_unanchor_urb(pdx->pUrbCharOut);
343 dev_err(&pdx->interface->dev,
344 "%s usb_submit_urb() returned %d",
345 __func__, iReturn);
346 }
347 } else
348 pdx->bSendCharsPending = false; // Allow other threads again
349 spin_unlock(&pdx->charOutLock); // already at irq level
350 }
351}
352
353/****************************************************************************
354** SendChars
355** Transmit the characters in the output buffer to the 1401. This may need
356** breaking down into multiple transfers.
357****************************************************************************/
358int SendChars(DEVICE_EXTENSION * pdx)
359{
360 int iReturn = U14ERR_NOERROR;
361
362 spin_lock_irq(&pdx->charOutLock); // Protect ourselves
363
364 if ((!pdx->bSendCharsPending) && // Not currently sending
365 (pdx->dwNumOutput > 0) && // has characters to output
366 (CanAcceptIoRequests(pdx))) // and current activity is OK
367 {
368 unsigned int dwCount = pdx->dwNumOutput; // Get a copy of the character count
369 pdx->bSendCharsPending = true; // Set flag to lock out other threads
370
371 dev_dbg(&pdx->interface->dev,
372 "Send %d chars to 1401, EP0 flag %d\n", dwCount,
373 pdx->nPipes == 3);
374 // If we have only 3 end points we must send the characters to the 1401 using EP0.
375 if (pdx->nPipes == 3) {
376 // For EP0 character transmissions to the 1401, we have to hang about until they
377 // are gone, as otherwise without more character IO activity they will never go.
378 unsigned int count = dwCount; // Local char counter
379 unsigned int index = 0; // The index into the char buffer
380
381 spin_unlock_irq(&pdx->charOutLock); // Free spinlock as we call USBD
382
383 while ((count > 0) && (iReturn == U14ERR_NOERROR)) {
384 // We have to break the transfer up into 64-byte chunks because of a 2270 problem
385 int n = count > 64 ? 64 : count; // Chars for this xfer, max of 64
386 int nSent = usb_control_msg(pdx->udev,
387 usb_sndctrlpipe(pdx->udev, 0), // use end point 0
388 DB_CHARS, // bRequest
389 (H_TO_D | VENDOR | DEVREQ), // to the device, vendor request to the device
390 0, 0, // value and index are both 0
391 &pdx->outputBuffer[index], // where to send from
392 n, // how much to send
393 1000); // timeout in jiffies
394 if (nSent <= 0) {
395 iReturn = nSent ? nSent : -ETIMEDOUT; // if 0 chars says we timed out
396 dev_err(&pdx->interface->dev,
397 "Send %d chars by EP0 failed: %d",
398 n, iReturn);
399 } else {
400 dev_dbg(&pdx->interface->dev,
401 "Sent %d chars by EP0", n);
402 count -= nSent;
403 index += nSent;
404 }
405 }
406
407 spin_lock_irq(&pdx->charOutLock); // Protect pdx changes, released by general code
408 pdx->dwOutBuffGet = 0; // so reset the output buffer
409 pdx->dwOutBuffPut = 0;
410 pdx->dwNumOutput = 0; // and clear the buffer count
411 pdx->bSendCharsPending = false; // Allow other threads again
412 } else { // Here for sending chars normally - we hold the spin lock
413 int nPipe = 0; // The pipe number to use
414 char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet];
415
416 if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ) // does it cross buffer end?
417 dwCount = OUTBUF_SZ - pdx->dwOutBuffGet;
418 spin_unlock_irq(&pdx->charOutLock); // we are done with stuff that changes
419 memcpy(pdx->pCoherCharOut, pDat, dwCount); // copy output data to the buffer
420 usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev,
421 usb_sndbulkpipe(pdx->udev,
422 pdx->epAddr[0]),
423 pdx->pCoherCharOut, dwCount,
424 ced_writechar_callback, pdx);
425 pdx->pUrbCharOut->transfer_flags |=
426 URB_NO_TRANSFER_DMA_MAP;
427 usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted);
428 iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_KERNEL);
429 spin_lock_irq(&pdx->charOutLock); // grab lock for errors
430 if (iReturn) {
431 pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later
432 pdx->bSendCharsPending = false; // Allow other threads again
433 usb_unanchor_urb(pdx->pUrbCharOut); // remove from list of active urbs
434 }
435 }
436 } else if (pdx->bSendCharsPending && (pdx->dwNumOutput > 0))
437 dev_dbg(&pdx->interface->dev,
438 "SendChars bSendCharsPending:true");
439
440 dev_dbg(&pdx->interface->dev, "SendChars exit code: %d", iReturn);
441 spin_unlock_irq(&pdx->charOutLock); // Now let go of the spinlock
442 return iReturn;
443}
444
445/***************************************************************************
446** CopyUserSpace
447** This moves memory between pinned down user space and the pCoherStagedIO
448** memory buffer we use for transfers. Copy n bytes in the directions that
449** is defined by pdx->StagedRead. The user space is determined by the area
450** in pdx->StagedId and the offset in pdx->StagedDone. The user
451** area may well not start on a page boundary, so allow for that.
452**
453** We have a table of physical pages that describe the area, so we can use
454** this to get a virtual address that the kernel can use.
455**
456** pdx Is our device extension which holds all we know about the transfer.
457** n The number of bytes to move one way or the other.
458***************************************************************************/
459static void CopyUserSpace(DEVICE_EXTENSION * pdx, int n)
460{
461 unsigned int nArea = pdx->StagedId;
462 if (nArea < MAX_TRANSAREAS) {
463 TRANSAREA *pArea = &pdx->rTransDef[nArea]; // area to be used
464 unsigned int dwOffset =
465 pdx->StagedDone + pdx->StagedOffset + pArea->dwBaseOffset;
466 char *pCoherBuf = pdx->pCoherStagedIO; // coherent buffer
467 if (!pArea->bUsed) {
468 dev_err(&pdx->interface->dev, "%s area %d unused",
469 __func__, nArea);
470 return;
471 }
472
473 while (n) {
474 int nPage = dwOffset >> PAGE_SHIFT; // page number in table
475 if (nPage < pArea->nPages) {
476 char *pvAddress =
477 (char *)kmap_atomic(pArea->pPages[nPage]);
478 if (pvAddress) {
479 unsigned int uiPageOff = dwOffset & (PAGE_SIZE - 1); // offset into the page
480 size_t uiXfer = PAGE_SIZE - uiPageOff; // max to transfer on this page
481 if (uiXfer > n) // limit byte count if too much
482 uiXfer = n; // for the page
483 if (pdx->StagedRead)
484 memcpy(pvAddress + uiPageOff,
485 pCoherBuf, uiXfer);
486 else
487 memcpy(pCoherBuf,
488 pvAddress + uiPageOff,
489 uiXfer);
490 kunmap_atomic(pvAddress);
491 dwOffset += uiXfer;
492 pCoherBuf += uiXfer;
493 n -= uiXfer;
494 } else {
495 dev_err(&pdx->interface->dev,
496 "%s did not map page %d",
497 __func__, nPage);
498 return;
499 }
500
501 } else {
502 dev_err(&pdx->interface->dev,
503 "%s exceeded pages %d", __func__,
504 nPage);
505 return;
506 }
507 }
508 } else
509 dev_err(&pdx->interface->dev, "%s bad area %d", __func__,
510 nArea);
511}
512
513// Forward declarations for stuff used circularly
514static int StageChunk(DEVICE_EXTENSION * pdx);
515/***************************************************************************
516** ReadWrite_Complete
517**
518** Completion routine for our staged read/write Irps
519*/
520static void staged_callback(struct urb *pUrb)
521{
522 DEVICE_EXTENSION *pdx = pUrb->context;
523 unsigned int nGot = pUrb->actual_length; // what we transferred
524 bool bCancel = false;
525 bool bRestartCharInput; // used at the end
526
527 spin_lock(&pdx->stagedLock); // stop ReadWriteMem() action while this routine is running
528 pdx->bStagedUrbPending = false; // clear the flag for staged IRP pending
529
530 if (pUrb->status) { // sync/async unlink faults aren't errors
531 if (!
532 (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
533 || pUrb->status == -ESHUTDOWN)) {
534 dev_err(&pdx->interface->dev,
535 "%s - nonzero write bulk status received: %d",
536 __func__, pUrb->status);
537 } else
538 dev_info(&pdx->interface->dev,
539 "%s - staged xfer cancelled", __func__);
540
541 spin_lock(&pdx->err_lock);
542 pdx->errors = pUrb->status;
543 spin_unlock(&pdx->err_lock);
544 nGot = 0; // and tidy up again if so
545 bCancel = true;
546 } else {
547 dev_dbg(&pdx->interface->dev, "%s %d chars xferred", __func__,
548 nGot);
549 if (pdx->StagedRead) // if reading, save to user space
550 CopyUserSpace(pdx, nGot); // copy from buffer to user
551 if (nGot == 0)
552 dev_dbg(&pdx->interface->dev, "%s ZLP", __func__);
553 }
554
555 // Update the transfer length based on the TransferBufferLength value in the URB
556 pdx->StagedDone += nGot;
557
558 dev_dbg(&pdx->interface->dev, "%s, done %d bytes of %d", __func__,
559 pdx->StagedDone, pdx->StagedLength);
560
561 if ((pdx->StagedDone == pdx->StagedLength) || // If no more to do
562 (bCancel)) // or this IRP was cancelled
563 {
564 TRANSAREA *pArea = &pdx->rTransDef[pdx->StagedId]; // Transfer area info
565 dev_dbg(&pdx->interface->dev,
566 "%s transfer done, bytes %d, cancel %d", __func__,
567 pdx->StagedDone, bCancel);
568
569 // Here is where we sort out what to do with this transfer if using a circular buffer. We have
570 // a completed transfer that can be assumed to fit into the transfer area. We should be able to
571 // add this to the end of a growing block or to use it to start a new block unless the code
572 // that calculates the offset to use (in ReadWriteMem) is totally duff.
573 if ((pArea->bCircular) && (pArea->bCircToHost) && (!bCancel) && // Time to sort out circular buffer info?
574 (pdx->StagedRead)) // Only for tohost transfers for now
575 {
576 if (pArea->aBlocks[1].dwSize > 0) // If block 1 is in use we must append to it
577 {
578 if (pdx->StagedOffset ==
579 (pArea->aBlocks[1].dwOffset +
580 pArea->aBlocks[1].dwSize)) {
581 pArea->aBlocks[1].dwSize +=
582 pdx->StagedLength;
583 dev_dbg(&pdx->interface->dev,
584 "RWM_Complete, circ block 1 now %d bytes at %d",
585 pArea->aBlocks[1].dwSize,
586 pArea->aBlocks[1].dwOffset);
587 } else {
588 // Here things have gone very, very, wrong, but I cannot see how this can actually be achieved
589 pArea->aBlocks[1].dwOffset =
590 pdx->StagedOffset;
591 pArea->aBlocks[1].dwSize =
592 pdx->StagedLength;
593 dev_err(&pdx->interface->dev,
594 "%s ERROR, circ block 1 re-started %d bytes at %d",
595 __func__,
596 pArea->aBlocks[1].dwSize,
597 pArea->aBlocks[1].dwOffset);
598 }
599 } else // If block 1 is not used, we try to add to block 0
600 {
601 if (pArea->aBlocks[0].dwSize > 0) // Got stored block 0 information?
602 { // Must append onto the existing block 0
603 if (pdx->StagedOffset ==
604 (pArea->aBlocks[0].dwOffset +
605 pArea->aBlocks[0].dwSize)) {
606 pArea->aBlocks[0].dwSize += pdx->StagedLength; // Just add this transfer in
607 dev_dbg(&pdx->interface->dev,
608 "RWM_Complete, circ block 0 now %d bytes at %d",
609 pArea->aBlocks[0].
610 dwSize,
611 pArea->aBlocks[0].
612 dwOffset);
613 } else // If it doesn't append, put into new block 1
614 {
615 pArea->aBlocks[1].dwOffset =
616 pdx->StagedOffset;
617 pArea->aBlocks[1].dwSize =
618 pdx->StagedLength;
619 dev_dbg(&pdx->interface->dev,
620 "RWM_Complete, circ block 1 started %d bytes at %d",
621 pArea->aBlocks[1].
622 dwSize,
623 pArea->aBlocks[1].
624 dwOffset);
625 }
626 } else // No info stored yet, just save in block 0
627 {
628 pArea->aBlocks[0].dwOffset =
629 pdx->StagedOffset;
630 pArea->aBlocks[0].dwSize =
631 pdx->StagedLength;
632 dev_dbg(&pdx->interface->dev,
633 "RWM_Complete, circ block 0 started %d bytes at %d",
634 pArea->aBlocks[0].dwSize,
635 pArea->aBlocks[0].dwOffset);
636 }
637 }
638 }
639
640 if (!bCancel) // Don't generate an event if cancelled
641 {
642 dev_dbg(&pdx->interface->dev,
643 "RWM_Complete, bCircular %d, bToHost %d, eStart %d, eSize %d",
644 pArea->bCircular, pArea->bEventToHost,
645 pArea->dwEventSt, pArea->dwEventSz);
646 if ((pArea->dwEventSz) && // Set a user-mode event...
647 (pdx->StagedRead == pArea->bEventToHost)) // ...on transfers in this direction?
648 {
649 int iWakeUp = 0; // assume
650 // If we have completed the right sort of DMA transfer then set the event to notify
651 // the user code to wake up anyone that is waiting.
652 if ((pArea->bCircular) && // Circular areas use a simpler test
653 (pArea->bCircToHost)) // only in supported direction
654 { // Is total data waiting up to size limit?
655 unsigned int dwTotal =
656 pArea->aBlocks[0].dwSize +
657 pArea->aBlocks[1].dwSize;
658 iWakeUp = (dwTotal >= pArea->dwEventSz);
659 } else {
660 unsigned int transEnd =
661 pdx->StagedOffset +
662 pdx->StagedLength;
663 unsigned int eventEnd =
664 pArea->dwEventSt + pArea->dwEventSz;
665 iWakeUp = (pdx->StagedOffset < eventEnd)
666 && (transEnd > pArea->dwEventSt);
667 }
668
669 if (iWakeUp) {
670 dev_dbg(&pdx->interface->dev,
671 "About to set event to notify app");
672 wake_up_interruptible(&pArea->wqEvent); // wake up waiting processes
673 ++pArea->iWakeUp; // increment wakeup count
674 }
675 }
676 }
677
678 pdx->dwDMAFlag = MODE_CHAR; // Switch back to char mode before ReadWriteMem call
679
680 if (!bCancel) // Don't look for waiting transfer if cancelled
681 {
682 // If we have a transfer waiting, kick it off
683 if (pdx->bXFerWaiting) // Got a block xfer waiting?
684 {
685 int iReturn;
686 dev_info(&pdx->interface->dev,
687 "*** RWM_Complete *** pending transfer will now be set up!!!");
688 iReturn =
689 ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard,
690 pdx->rDMAInfo.wIdent,
691 pdx->rDMAInfo.dwOffset,
692 pdx->rDMAInfo.dwSize);
693
694 if (iReturn)
695 dev_err(&pdx->interface->dev,
696 "RWM_Complete rw setup failed %d",
697 iReturn);
698 }
699 }
700
701 } else // Here for more to do
702 StageChunk(pdx); // fire off the next bit
703
704 // While we hold the stagedLock, see if we should reallow character input ints
705 // Don't allow if cancelled, or if a new block has started or if there is a waiting block.
706 // This feels wrong as we should ask which spin lock protects dwDMAFlag.
707 bRestartCharInput = !bCancel && (pdx->dwDMAFlag == MODE_CHAR)
708 && !pdx->bXFerWaiting;
709
710 spin_unlock(&pdx->stagedLock); // Finally release the lock again
711
712 // This is not correct as dwDMAFlag is protected by the staged lock, but it is treated
713 // in Allowi as if it were protected by the char lock. In any case, most systems will
714 // not be upset by char input during DMA... sigh. Needs sorting out.
715 if (bRestartCharInput) // may be out of date, but...
716 Allowi(pdx, true); // ...Allowi tests a lock too.
717 dev_dbg(&pdx->interface->dev, "%s done", __func__);
718}
719
720/****************************************************************************
721** StageChunk
722**
723** Generates the next chunk of data making up a staged transfer.
724**
725** The calling code must have acquired the staging spinlock before calling
726** this function, and is responsible for releasing it. We are at callback level.
727****************************************************************************/
728static int StageChunk(DEVICE_EXTENSION * pdx)
729{
730 int iReturn = U14ERR_NOERROR;
731 unsigned int ChunkSize;
732 int nPipe = pdx->StagedRead ? 3 : 2; // The pipe number to use for reads or writes
733 if (pdx->nPipes == 3)
734 nPipe--; // Adjust for the 3-pipe case
735 if (nPipe < 0) // and trap case that should never happen
736 return U14ERR_FAIL;
737
738 if (!CanAcceptIoRequests(pdx)) // got sudden remove?
739 {
740 dev_info(&pdx->interface->dev, "%s sudden remove, giving up",
741 __func__);
742 return U14ERR_FAIL; // could do with a better error
743 }
744
745 ChunkSize = (pdx->StagedLength - pdx->StagedDone); // transfer length remaining
746 if (ChunkSize > STAGED_SZ) // make sure to keep legal
747 ChunkSize = STAGED_SZ; // limit to max allowed
748
749 if (!pdx->StagedRead) // if writing...
750 CopyUserSpace(pdx, ChunkSize); // ...copy data into the buffer
751
752 usb_fill_bulk_urb(pdx->pStagedUrb, pdx->udev,
753 pdx->StagedRead ? usb_rcvbulkpipe(pdx->udev,
754 pdx->
755 epAddr[nPipe]) :
756 usb_sndbulkpipe(pdx->udev, pdx->epAddr[nPipe]),
757 pdx->pCoherStagedIO, ChunkSize, staged_callback, pdx);
758 pdx->pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
759 usb_anchor_urb(pdx->pStagedUrb, &pdx->submitted); // in case we need to kill it
760 iReturn = usb_submit_urb(pdx->pStagedUrb, GFP_ATOMIC);
761 if (iReturn) {
762 usb_unanchor_urb(pdx->pStagedUrb); // kill it
763 pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later
764 dev_err(&pdx->interface->dev, "%s submit urb failed, code %d",
765 __func__, iReturn);
766 } else
767 pdx->bStagedUrbPending = true; // Set the flag for staged URB pending
768 dev_dbg(&pdx->interface->dev, "%s done so far:%d, this size:%d",
769 __func__, pdx->StagedDone, ChunkSize);
770
771 return iReturn;
772}
773
774/***************************************************************************
775** ReadWriteMem
776**
777** This routine is used generally for block read and write operations.
778** Breaks up a read or write in to specified sized chunks, as specified by pipe
779** information on maximum transfer size.
780**
781** Any code that calls this must be holding the stagedLock
782**
783** Arguments:
784** DeviceObject - pointer to our FDO (Functional Device Object)
785** Read - TRUE for read, FALSE for write. This is from POV of the driver
786** wIdent - the transfer area number - defines memory area and more.
787** dwOffs - the start offset within the transfer area of the start of this
788** transfer.
789** dwLen - the number of bytes to transfer.
790*/
791int ReadWriteMem(DEVICE_EXTENSION * pdx, bool Read, unsigned short wIdent,
792 unsigned int dwOffs, unsigned int dwLen)
793{
794 TRANSAREA *pArea = &pdx->rTransDef[wIdent]; // Transfer area info
795
796 if (!CanAcceptIoRequests(pdx)) // Are we in a state to accept new requests?
797 {
798 dev_err(&pdx->interface->dev, "%s can't accept requests",
799 __func__);
800 return U14ERR_FAIL;
801 }
802
803 dev_dbg(&pdx->interface->dev,
804 "%s xfer %d bytes to %s, offset %d, area %d", __func__, dwLen,
805 Read ? "host" : "1401", dwOffs, wIdent);
806
807 // Amazingly, we can get an escape sequence back before the current staged Urb is done, so we
808 // have to check for this situation and, if so, wait until all is OK.
809 if (pdx->bStagedUrbPending) {
810 pdx->bXFerWaiting = true; // Flag we are waiting
811 dev_info(&pdx->interface->dev,
812 "%s xfer is waiting, as previous staged pending",
813 __func__);
814 return U14ERR_NOERROR;
815 }
816
817 if (dwLen == 0) // allow 0-len read or write; just return success
818 {
819 dev_dbg(&pdx->interface->dev,
820 "%s OK; zero-len read/write request", __func__);
821 return U14ERR_NOERROR;
822 }
823
824 if ((pArea->bCircular) && // Circular transfer?
825 (pArea->bCircToHost) && (Read)) // In a supported direction
826 { // If so, we sort out offset ourself
827 bool bWait = false; // Flag for transfer having to wait
828
829 dev_dbg(&pdx->interface->dev,
830 "Circular buffers are %d at %d and %d at %d",
831 pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset,
832 pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset);
833 if (pArea->aBlocks[1].dwSize > 0) // Using the second block already?
834 {
835 dwOffs = pArea->aBlocks[1].dwOffset + pArea->aBlocks[1].dwSize; // take offset from that
836 bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; // Wait if will overwrite block 0?
837 bWait |= (dwOffs + dwLen) > pArea->dwLength; // or if it overflows the buffer
838 } else // Area 1 not in use, try to use area 0
839 {
840 if (pArea->aBlocks[0].dwSize == 0) // Reset block 0 if not in use
841 pArea->aBlocks[0].dwOffset = 0;
842 dwOffs =
843 pArea->aBlocks[0].dwOffset +
844 pArea->aBlocks[0].dwSize;
845 if ((dwOffs + dwLen) > pArea->dwLength) // Off the end of the buffer?
846 {
847 pArea->aBlocks[1].dwOffset = 0; // Set up to use second block
848 dwOffs = 0;
849 bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; // Wait if will overwrite block 0?
850 bWait |= (dwOffs + dwLen) > pArea->dwLength; // or if it overflows the buffer
851 }
852 }
853
854 if (bWait) // This transfer will have to wait?
855 {
856 pdx->bXFerWaiting = true; // Flag we are waiting
857 dev_dbg(&pdx->interface->dev,
858 "%s xfer waiting for circular buffer space",
859 __func__);
860 return U14ERR_NOERROR;
861 }
862
863 dev_dbg(&pdx->interface->dev,
864 "%s circular xfer, %d bytes starting at %d", __func__,
865 dwLen, dwOffs);
866 }
867 // Save the parameters for the read\write transfer
868 pdx->StagedRead = Read; // Save the parameters for this read
869 pdx->StagedId = wIdent; // ID allows us to get transfer area info
870 pdx->StagedOffset = dwOffs; // The area within the transfer area
871 pdx->StagedLength = dwLen;
872 pdx->StagedDone = 0; // Initialise the byte count
873 pdx->dwDMAFlag = MODE_LINEAR; // Set DMA mode flag at this point
874 pdx->bXFerWaiting = false; // Clearly not a transfer waiting now
875
876// KeClearEvent(&pdx->StagingDoneEvent); // Clear the transfer done event
877 StageChunk(pdx); // fire off the first chunk
878
879 return U14ERR_NOERROR;
880}
881
882/****************************************************************************
883**
884** ReadChar
885**
886** Reads a character a buffer. If there is no more
887** data we return FALSE. Used as part of decoding a DMA request.
888**
889****************************************************************************/
890static bool ReadChar(unsigned char *pChar, char *pBuf, unsigned int *pdDone,
891 unsigned int dGot)
892{
893 bool bRead = false;
894 unsigned int dDone = *pdDone;
895
896 if (dDone < dGot) // If there is more data
897 {
898 *pChar = (unsigned char)pBuf[dDone]; // Extract the next char
899 dDone++; // Increment the done count
900 *pdDone = dDone;
901 bRead = true; // and flag success
902 }
903
904 return bRead;
905}
906
907#ifdef NOTUSED
908/****************************************************************************
909**
910** ReadWord
911**
912** Reads a word from the 1401, just uses ReadChar twice; passes on any error
913**
914*****************************************************************************/
915static bool ReadWord(unsigned short *pWord, char *pBuf, unsigned int *pdDone,
916 unsigned int dGot)
917{
918 if (ReadChar((unsigned char *)pWord, pBuf, pdDone, dGot))
919 return ReadChar(((unsigned char *)pWord) + 1, pBuf, pdDone,
920 dGot);
921 else
922 return false;
923}
924#endif
925
926/****************************************************************************
927** ReadHuff
928**
929** Reads a coded number in and returns it, Code is:
930** If data is in range 0..127 we recieve 1 byte. If data in range 128-16383
931** we recieve two bytes, top bit of first indicates another on its way. If
932** data in range 16383-4194303 we get three bytes, top two bits of first set
933** to indicate three byte total.
934**
935*****************************************************************************/
936static bool ReadHuff(volatile unsigned int *pDWord, char *pBuf,
937 unsigned int *pdDone, unsigned int dGot)
938{
939 unsigned char ucData; /* for each read to ReadChar */
940 bool bReturn = true; /* assume we will succeed */
941 unsigned int dwData = 0; /* Accumulator for the data */
942
943 if (ReadChar(&ucData, pBuf, pdDone, dGot)) {
944 dwData = ucData; /* copy the data */
945 if ((dwData & 0x00000080) != 0) { /* Bit set for more data ? */
946 dwData &= 0x0000007F; /* Clear the relevant bit */
947 if (ReadChar(&ucData, pBuf, pdDone, dGot)) {
948 dwData = (dwData << 8) | ucData;
949 if ((dwData & 0x00004000) != 0) { /* three byte sequence ? */
950 dwData &= 0x00003FFF; /* Clear the relevant bit */
951 if (ReadChar
952 (&ucData, pBuf, pdDone, dGot))
953 dwData = (dwData << 8) | ucData;
954 else
955 bReturn = false;
956 }
957 } else
958 bReturn = false; /* couldn't read data */
959 }
960 } else
961 bReturn = false;
962
963 *pDWord = dwData; /* return the data */
964 return bReturn;
965}
966
967/***************************************************************************
968**
969** ReadDMAInfo
970**
971** Tries to read info about the dma request from the 1401 and decode it into
972** the dma descriptor block. We have at this point had the escape character
973** from the 1401 and now we must read in the rest of the information about
974** the transfer request. Returns FALSE if 1401 fails to respond or obselete
975** code from 1401 or bad parameters.
976**
977** The pBuf char pointer does not include the initial escape character, so
978** we start handling the data at offset zero.
979**
980*****************************************************************************/
981static bool ReadDMAInfo(volatile DMADESC * pDmaDesc, DEVICE_EXTENSION * pdx,
982 char *pBuf, unsigned int dwCount)
983{
984 bool bResult = false; // assume we won't succeed
985 unsigned char ucData;
986 unsigned int dDone = 0; // We haven't parsed anything so far
987
988 dev_dbg(&pdx->interface->dev, "%s", __func__);
989
990 if (ReadChar(&ucData, pBuf, &dDone, dwCount)) {
991 unsigned char ucTransCode = (ucData & 0x0F); // get code for transfer type
992 unsigned short wIdent = ((ucData >> 4) & 0x07); // and area identifier
993
994 // fill in the structure we were given
995 pDmaDesc->wTransType = ucTransCode; // type of transfer
996 pDmaDesc->wIdent = wIdent; // area to use
997 pDmaDesc->dwSize = 0; // initialise other bits
998 pDmaDesc->dwOffset = 0;
999
1000 dev_dbg(&pdx->interface->dev, "%s type: %d ident: %d", __func__,
1001 pDmaDesc->wTransType, pDmaDesc->wIdent);
1002
1003 pDmaDesc->bOutWard = (ucTransCode != TM_EXTTOHOST); // set transfer direction
1004
1005 switch (ucTransCode) {
1006 case TM_EXTTOHOST: // Extended linear transfer modes (the only ones!)
1007 case TM_EXTTO1401:
1008 {
1009 bResult =
1010 ReadHuff(&(pDmaDesc->dwOffset), pBuf,
1011 &dDone, dwCount)
1012 && ReadHuff(&(pDmaDesc->dwSize), pBuf,
1013 &dDone, dwCount);
1014 if (bResult) {
1015 dev_dbg(&pdx->interface->dev,
1016 "%s xfer offset & size %d %d",
1017 __func__, pDmaDesc->dwOffset,
1018 pDmaDesc->dwSize);
1019
1020 if ((wIdent >= MAX_TRANSAREAS) || // Illegal area number, or...
1021 (!pdx->rTransDef[wIdent].bUsed) || // area not set up, or...
1022 (pDmaDesc->dwOffset > pdx->rTransDef[wIdent].dwLength) || // range/size
1023 ((pDmaDesc->dwOffset +
1024 pDmaDesc->dwSize) >
1025 (pdx->rTransDef[wIdent].
1026 dwLength))) {
1027 bResult = false; // bad parameter(s)
1028 dev_dbg(&pdx->interface->dev,
1029 "%s bad param - id %d, bUsed %d, offset %d, size %d, area length %d",
1030 __func__, wIdent,
1031 pdx->rTransDef[wIdent].
1032 bUsed,
1033 pDmaDesc->dwOffset,
1034 pDmaDesc->dwSize,
1035 pdx->rTransDef[wIdent].
1036 dwLength);
1037 }
1038 }
1039 break;
1040 }
1041 default:
1042 break;
1043 }
1044 } else
1045 bResult = false;
1046
1047 if (!bResult) // now check parameters for validity
1048 dev_err(&pdx->interface->dev, "%s error reading Esc sequence",
1049 __func__);
1050
1051 return bResult;
1052}
1053
1054/****************************************************************************
1055**
1056** Handle1401Esc
1057**
1058** Deals with an escape sequence coming from the 1401. This can either be
1059** a DMA transfer request of various types or a response to an escape sequence
1060** sent to the 1401. This is called from a callback.
1061**
1062** Parameters are
1063**
1064** dwCount - the number of characters in the device extension char in buffer,
1065** this is known to be at least 2 or we will not be called.
1066**
1067****************************************************************************/
1068static int Handle1401Esc(DEVICE_EXTENSION * pdx, char *pCh,
1069 unsigned int dwCount)
1070{
1071 int iReturn = U14ERR_FAIL;
1072
1073 // I have no idea what this next test is about. '?' is 0x3f, which is area 3, code
1074 // 15. At the moment, this is not used, so it does no harm, but unless someone can
1075 // tell me what this is for, it should be removed from this and the Windows driver.
1076 if (pCh[0] == '?') // Is this an information response
1077 { // Parse and save the information
1078 } else {
1079 spin_lock(&pdx->stagedLock); // Lock others out
1080
1081 if (ReadDMAInfo(&pdx->rDMAInfo, pdx, pCh, dwCount)) // Get DMA parameters
1082 {
1083 unsigned short wTransType = pdx->rDMAInfo.wTransType; // check transfer type
1084
1085 dev_dbg(&pdx->interface->dev,
1086 "%s xfer to %s, offset %d, length %d", __func__,
1087 pdx->rDMAInfo.bOutWard ? "1401" : "host",
1088 pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize);
1089
1090 if (pdx->bXFerWaiting) // Check here for badly out of kilter...
1091 { // This can never happen, really
1092 dev_err(&pdx->interface->dev,
1093 "ERROR: DMA setup while transfer still waiting");
1094 spin_unlock(&pdx->stagedLock);
1095 } else {
1096 if ((wTransType == TM_EXTTOHOST)
1097 || (wTransType == TM_EXTTO1401)) {
1098 iReturn =
1099 ReadWriteMem(pdx,
1100 !pdx->rDMAInfo.
1101 bOutWard,
1102 pdx->rDMAInfo.wIdent,
1103 pdx->rDMAInfo.dwOffset,
1104 pdx->rDMAInfo.dwSize);
1105 if (iReturn != U14ERR_NOERROR)
1106 dev_err(&pdx->interface->dev,
1107 "%s ReadWriteMem() failed %d",
1108 __func__, iReturn);
1109 } else // This covers non-linear transfer setup
1110 dev_err(&pdx->interface->dev,
1111 "%s Unknown block xfer type %d",
1112 __func__, wTransType);
1113 }
1114 } else // Failed to read parameters
1115 dev_err(&pdx->interface->dev, "%s ReadDMAInfo() fail",
1116 __func__);
1117
1118 spin_unlock(&pdx->stagedLock); // OK here
1119 }
1120
1121 dev_dbg(&pdx->interface->dev, "%s returns %d", __func__, iReturn);
1122
1123 return iReturn;
1124}
1125
1126/****************************************************************************
1127** Callback for the character read complete or error
1128****************************************************************************/
1129static void ced_readchar_callback(struct urb *pUrb)
1130{
1131 DEVICE_EXTENSION *pdx = pUrb->context;
1132 int nGot = pUrb->actual_length; // what we transferred
1133
1134 if (pUrb->status) // Do we have a problem to handle?
1135 {
1136 int nPipe = pdx->nPipes == 4 ? 1 : 0; // The pipe number to use for error
1137 // sync/async unlink faults aren't errors... just saying device removed or stopped
1138 if (!
1139 (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
1140 || pUrb->status == -ESHUTDOWN)) {
1141 dev_err(&pdx->interface->dev,
1142 "%s - nonzero write bulk status received: %d",
1143 __func__, pUrb->status);
1144 } else
1145 dev_dbg(&pdx->interface->dev,
1146 "%s - 0 chars pUrb->status=%d (shutdown?)",
1147 __func__, pUrb->status);
1148
1149 spin_lock(&pdx->err_lock);
1150 pdx->errors = pUrb->status;
1151 spin_unlock(&pdx->err_lock);
1152 nGot = 0; // and tidy up again if so
1153
1154 spin_lock(&pdx->charInLock); // already at irq level
1155 pdx->bPipeError[nPipe] = 1; // Flag an error for later
1156 } else {
1157 if ((nGot > 1) && ((pdx->pCoherCharIn[0] & 0x7f) == 0x1b)) // Esc sequence?
1158 {
1159 Handle1401Esc(pdx, &pdx->pCoherCharIn[1], nGot - 1); // handle it
1160 spin_lock(&pdx->charInLock); // already at irq level
1161 } else {
1162 spin_lock(&pdx->charInLock); // already at irq level
1163 if (nGot > 0) {
1164 unsigned int i;
1165 if (nGot < INBUF_SZ) {
1166 pdx->pCoherCharIn[nGot] = 0; // tidy the string
1167 dev_dbg(&pdx->interface->dev,
1168 "%s got %d chars >%s<",
1169 __func__, nGot,
1170 pdx->pCoherCharIn);
1171 }
1172 // We know that whatever we read must fit in the input buffer
1173 for (i = 0; i < nGot; i++) {
1174 pdx->inputBuffer[pdx->dwInBuffPut++] =
1175 pdx->pCoherCharIn[i] & 0x7F;
1176 if (pdx->dwInBuffPut >= INBUF_SZ)
1177 pdx->dwInBuffPut = 0;
1178 }
1179
1180 if ((pdx->dwNumInput + nGot) <= INBUF_SZ)
1181 pdx->dwNumInput += nGot; // Adjust the buffer count accordingly
1182 } else
1183 dev_dbg(&pdx->interface->dev, "%s read ZLP",
1184 __func__);
1185 }
1186 }
1187
1188 pdx->bReadCharsPending = false; // No longer have a pending read
1189 spin_unlock(&pdx->charInLock); // already at irq level
1190
1191 Allowi(pdx, true); // see if we can do the next one
1192}
1193
1194/****************************************************************************
1195** Allowi
1196**
1197** This is used to make sure that there is always a pending input transfer so
1198** we can pick up any inward transfers. This can be called in multiple contexts
1199** so we use the irqsave version of the spinlock.
1200****************************************************************************/
1201int Allowi(DEVICE_EXTENSION * pdx, bool bInCallback)
1202{
1203 int iReturn = U14ERR_NOERROR;
1204 unsigned long flags;
1205 spin_lock_irqsave(&pdx->charInLock, flags); // can be called in multiple contexts
1206
1207 // We don't want char input running while DMA is in progress as we know that this
1208 // can cause sequencing problems for the 2270. So don't. It will also allow the
1209 // ERR response to get back to the host code too early on some PCs, even if there
1210 // is no actual driver failure, so we don't allow this at all.
1211 if (!pdx->bInDrawDown && // stop input if
1212 !pdx->bReadCharsPending && // If no read request outstanding
1213 (pdx->dwNumInput < (INBUF_SZ / 2)) && // and there is some space
1214 (pdx->dwDMAFlag == MODE_CHAR) && // not doing any DMA
1215 (!pdx->bXFerWaiting) && // no xfer waiting to start
1216 (CanAcceptIoRequests(pdx))) // and activity is generally OK
1217 { // then off we go
1218 unsigned int nMax = INBUF_SZ - pdx->dwNumInput; // max we could read
1219 int nPipe = pdx->nPipes == 4 ? 1 : 0; // The pipe number to use
1220
1221 dev_dbg(&pdx->interface->dev, "%s %d chars in input buffer",
1222 __func__, pdx->dwNumInput);
1223
1224 usb_fill_int_urb(pdx->pUrbCharIn, pdx->udev,
1225 usb_rcvintpipe(pdx->udev, pdx->epAddr[nPipe]),
1226 pdx->pCoherCharIn, nMax, ced_readchar_callback,
1227 pdx, pdx->bInterval);
1228 pdx->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; // short xfers are OK by default
1229 usb_anchor_urb(pdx->pUrbCharIn, &pdx->submitted); // in case we need to kill it
1230 iReturn =
1231 usb_submit_urb(pdx->pUrbCharIn,
1232 bInCallback ? GFP_ATOMIC : GFP_KERNEL);
1233 if (iReturn) {
1234 usb_unanchor_urb(pdx->pUrbCharIn); // remove from list of active Urbs
1235 pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later
1236 dev_err(&pdx->interface->dev,
1237 "%s submit urb failed: %d", __func__, iReturn);
1238 } else
1239 pdx->bReadCharsPending = true; // Flag that we are active here
1240 }
1241
1242 spin_unlock_irqrestore(&pdx->charInLock, flags);
1243
1244 return iReturn;
1245
1246}
1247
1248/*****************************************************************************
1249** The ioctl entry point to the driver that is used by us to talk to it.
1250** inode The device node (no longer in 3.0.0 kernels)
1251** file The file that is open, which holds our pdx pointer
1252** ulArg The argument passed in. Note that long is 64-bits in 64-bit system, i.e. it is big
1253** enough for a 64-bit pointer.
1254*****************************************************************************/
1255#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
1256static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg)
1257#else
1258static int ced_ioctl(struct inode *node, struct file *file, unsigned int cmd,
1259 unsigned long ulArg)
1260#endif
1261{
1262 int err = 0;
1263 DEVICE_EXTENSION *pdx = file->private_data;
1264 if (!CanAcceptIoRequests(pdx)) // check we still exist
1265 return -ENODEV;
1266
1267 // Check that access is allowed, where is is needed. Anything that would have an indeterminate
1268 // size will be checked by the specific command.
1269 if (_IOC_DIR(cmd) & _IOC_READ) // read from point of view of user...
1270 err = !access_ok(VERIFY_WRITE, (void __user *)ulArg, _IOC_SIZE(cmd)); // is kernel write
1271 else if (_IOC_DIR(cmd) & _IOC_WRITE) // and write from point of view of user...
1272 err = !access_ok(VERIFY_READ, (void __user *)ulArg, _IOC_SIZE(cmd)); // is kernel read
1273 if (err)
1274 return -EFAULT;
1275
1276 switch (_IOC_NR(cmd)) {
1277 case _IOC_NR(IOCTL_CED_SENDSTRING(0)):
1278 return SendString(pdx, (const char __user *)ulArg,
1279 _IOC_SIZE(cmd));
1280
1281 case _IOC_NR(IOCTL_CED_RESET1401):
1282 return Reset1401(pdx);
1283
1284 case _IOC_NR(IOCTL_CED_GETCHAR):
1285 return GetChar(pdx);
1286
1287 case _IOC_NR(IOCTL_CED_SENDCHAR):
1288 return SendChar(pdx, (char)ulArg);
1289
1290 case _IOC_NR(IOCTL_CED_STAT1401):
1291 return Stat1401(pdx);
1292
1293 case _IOC_NR(IOCTL_CED_LINECOUNT):
1294 return LineCount(pdx);
1295
1296 case _IOC_NR(IOCTL_CED_GETSTRING(0)):
1297 return GetString(pdx, (char __user *)ulArg, _IOC_SIZE(cmd));
1298
1299 case _IOC_NR(IOCTL_CED_SETTRANSFER):
1300 return SetTransfer(pdx, (TRANSFERDESC __user *) ulArg);
1301
1302 case _IOC_NR(IOCTL_CED_UNSETTRANSFER):
1303 return UnsetTransfer(pdx, (int)ulArg);
1304
1305 case _IOC_NR(IOCTL_CED_SETEVENT):
1306 return SetEvent(pdx, (TRANSFEREVENT __user *) ulArg);
1307
1308 case _IOC_NR(IOCTL_CED_GETOUTBUFSPACE):
1309 return GetOutBufSpace(pdx);
1310
1311 case _IOC_NR(IOCTL_CED_GETBASEADDRESS):
1312 return -1;
1313
1314 case _IOC_NR(IOCTL_CED_GETDRIVERREVISION):
1315 return (2 << 24) | (DRIVERMAJREV << 16) | DRIVERMINREV; // USB | MAJOR | MINOR
1316
1317 case _IOC_NR(IOCTL_CED_GETTRANSFER):
1318 return GetTransfer(pdx, (TGET_TX_BLOCK __user *) ulArg);
1319
1320 case _IOC_NR(IOCTL_CED_KILLIO1401):
1321 return KillIO1401(pdx);
1322
1323 case _IOC_NR(IOCTL_CED_STATEOF1401):
1324 return StateOf1401(pdx);
1325
1326 case _IOC_NR(IOCTL_CED_GRAB1401):
1327 case _IOC_NR(IOCTL_CED_FREE1401):
1328 return U14ERR_NOERROR;
1329
1330 case _IOC_NR(IOCTL_CED_STARTSELFTEST):
1331 return StartSelfTest(pdx);
1332
1333 case _IOC_NR(IOCTL_CED_CHECKSELFTEST):
1334 return CheckSelfTest(pdx, (TGET_SELFTEST __user *) ulArg);
1335
1336 case _IOC_NR(IOCTL_CED_TYPEOF1401):
1337 return TypeOf1401(pdx);
1338
1339 case _IOC_NR(IOCTL_CED_TRANSFERFLAGS):
1340 return TransferFlags(pdx);
1341
1342 case _IOC_NR(IOCTL_CED_DBGPEEK):
1343 return DbgPeek(pdx, (TDBGBLOCK __user *) ulArg);
1344
1345 case _IOC_NR(IOCTL_CED_DBGPOKE):
1346 return DbgPoke(pdx, (TDBGBLOCK __user *) ulArg);
1347
1348 case _IOC_NR(IOCTL_CED_DBGRAMPDATA):
1349 return DbgRampData(pdx, (TDBGBLOCK __user *) ulArg);
1350
1351 case _IOC_NR(IOCTL_CED_DBGRAMPADDR):
1352 return DbgRampAddr(pdx, (TDBGBLOCK __user *) ulArg);
1353
1354 case _IOC_NR(IOCTL_CED_DBGGETDATA):
1355 return DbgGetData(pdx, (TDBGBLOCK __user *) ulArg);
1356
1357 case _IOC_NR(IOCTL_CED_DBGSTOPLOOP):
1358 return DbgStopLoop(pdx);
1359
1360 case _IOC_NR(IOCTL_CED_FULLRESET):
1361 pdx->bForceReset = true; // Set a flag for a full reset
1362 break;
1363
1364 case _IOC_NR(IOCTL_CED_SETCIRCULAR):
1365 return SetCircular(pdx, (TRANSFERDESC __user *) ulArg);
1366
1367 case _IOC_NR(IOCTL_CED_GETCIRCBLOCK):
1368 return GetCircBlock(pdx, (TCIRCBLOCK __user *) ulArg);
1369
1370 case _IOC_NR(IOCTL_CED_FREECIRCBLOCK):
1371 return FreeCircBlock(pdx, (TCIRCBLOCK __user *) ulArg);
1372
1373 case _IOC_NR(IOCTL_CED_WAITEVENT):
1374 return WaitEvent(pdx, (int)(ulArg & 0xff), (int)(ulArg >> 8));
1375
1376 case _IOC_NR(IOCTL_CED_TESTEVENT):
1377 return TestEvent(pdx, (int)ulArg);
1378
1379 default:
1380 return U14ERR_NO_SUCH_FN;
1381 }
1382 return U14ERR_NOERROR;
1383}
1384
1385static const struct file_operations ced_fops = {
1386 .owner = THIS_MODULE,
1387 .open = ced_open,
1388 .release = ced_release,
1389 .flush = ced_flush,
1390 .llseek = noop_llseek,
1391#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
1392 .unlocked_ioctl = ced_ioctl,
1393#else
1394 .ioctl = ced_ioctl,
1395#endif
1396};
1397
1398/*
1399 * usb class driver info in order to get a minor number from the usb core,
1400 * and to have the device registered with the driver core
1401 */
1402static struct usb_class_driver ced_class = {
1403 .name = "cedusb%d",
1404 .fops = &ced_fops,
1405 .minor_base = USB_CED_MINOR_BASE,
1406};
1407
1408// Check that the device that matches a 1401 vendor and product ID is OK to use and
1409// initialise our DEVICE_EXTENSION.
1410static int ced_probe(struct usb_interface *interface,
1411 const struct usb_device_id *id)
1412{
1413 DEVICE_EXTENSION *pdx;
1414 struct usb_host_interface *iface_desc;
1415 struct usb_endpoint_descriptor *endpoint;
1416 int i, bcdDevice;
1417 int retval = -ENOMEM;
1418
1419 // allocate memory for our device extension and initialize it
1420 pdx = kzalloc(sizeof(*pdx), GFP_KERNEL);
1421 if (!pdx) {
1422 dev_err(&interface->dev, "Out of memory\n");
1423 goto error;
1424 }
1425
1426 for (i = 0; i < MAX_TRANSAREAS; ++i) // Initialise the wait queues
1427 {
1428 init_waitqueue_head(&pdx->rTransDef[i].wqEvent);
1429 }
1430
1431 // Put initialises for our stuff here. Note that all of *pdx is zero, so
1432 // no need to explicitly zero it.
1433 spin_lock_init(&pdx->charOutLock);
1434 spin_lock_init(&pdx->charInLock);
1435 spin_lock_init(&pdx->stagedLock);
1436
1437 // Initialises from the skeleton stuff
1438 kref_init(&pdx->kref);
1439 mutex_init(&pdx->io_mutex);
1440 spin_lock_init(&pdx->err_lock);
1441 init_usb_anchor(&pdx->submitted);
1442
1443 pdx->udev = usb_get_dev(interface_to_usbdev(interface));
1444 pdx->interface = interface;
1445
1446 // Attempt to identify the device
1447 bcdDevice = pdx->udev->descriptor.bcdDevice;
1448 i = (bcdDevice >> 8);
1449 if (i == 0)
1450 pdx->s1401Type = TYPEU1401;
1451 else if ((i >= 1) && (i <= 23))
1452 pdx->s1401Type = i + 2;
1453 else {
1454 dev_err(&interface->dev, "%s Unknown device. bcdDevice = %d",
1455 __func__, bcdDevice);
1456 goto error;
1457 }
1458 // set up the endpoint information. We only care about the number of EP as
1459 // we know that we are dealing with a 1401 device.
1460 iface_desc = interface->cur_altsetting;
1461 pdx->nPipes = iface_desc->desc.bNumEndpoints;
1462 dev_info(&interface->dev, "1401Type=%d with %d End Points",
1463 pdx->s1401Type, pdx->nPipes);
1464 if ((pdx->nPipes < 3) || (pdx->nPipes > 4))
1465 goto error;
1466
1467 // Allocate the URBs we hold for performing transfers
1468 pdx->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL); // character output URB
1469 pdx->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL); // character input URB
1470 pdx->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL); // block transfer URB
1471 if (!pdx->pUrbCharOut || !pdx->pUrbCharIn || !pdx->pStagedUrb) {
1472 dev_err(&interface->dev, "%s URB alloc failed", __func__);
1473 goto error;
1474 }
1475
1476 pdx->pCoherStagedIO =
1477 usb_alloc_coherent(pdx->udev, STAGED_SZ, GFP_KERNEL,
1478 &pdx->pStagedUrb->transfer_dma);
1479 pdx->pCoherCharOut =
1480 usb_alloc_coherent(pdx->udev, OUTBUF_SZ, GFP_KERNEL,
1481 &pdx->pUrbCharOut->transfer_dma);
1482 pdx->pCoherCharIn =
1483 usb_alloc_coherent(pdx->udev, INBUF_SZ, GFP_KERNEL,
1484 &pdx->pUrbCharIn->transfer_dma);
1485 if (!pdx->pCoherCharOut || !pdx->pCoherCharIn || !pdx->pCoherStagedIO) {
1486 dev_err(&interface->dev, "%s Coherent buffer alloc failed",
1487 __func__);
1488 goto error;
1489 }
1490
1491 for (i = 0; i < pdx->nPipes; ++i) {
1492 endpoint = &iface_desc->endpoint[i].desc;
1493 pdx->epAddr[i] = endpoint->bEndpointAddress;
1494 dev_info(&interface->dev, "Pipe %d, ep address %02x", i,
1495 pdx->epAddr[i]);
1496 if (((pdx->nPipes == 3) && (i == 0)) || // if char input end point
1497 ((pdx->nPipes == 4) && (i == 1))) {
1498 pdx->bInterval = endpoint->bInterval; // save the endpoint interrupt interval
1499 dev_info(&interface->dev, "Pipe %d, bInterval = %d", i,
1500 pdx->bInterval);
1501 }
1502 // Detect USB2 by checking last ep size (64 if USB1)
1503 if (i == pdx->nPipes - 1) // if this is the last ep (bulk)
1504 {
1505 pdx->bIsUSB2 =
1506 le16_to_cpu(endpoint->wMaxPacketSize) > 64;
1507 dev_info(&pdx->interface->dev, "USB%d",
1508 pdx->bIsUSB2 + 1);
1509 }
1510 }
1511
1512 /* save our data pointer in this interface device */
1513 usb_set_intfdata(interface, pdx);
1514
1515 /* we can register the device now, as it is ready */
1516 retval = usb_register_dev(interface, &ced_class);
1517 if (retval) {
1518 /* something prevented us from registering this driver */
1519 dev_err(&interface->dev,
1520 "Not able to get a minor for this device.\n");
1521 usb_set_intfdata(interface, NULL);
1522 goto error;
1523 }
1524
1525 /* let the user know what node this device is now attached to */
1526 dev_info(&interface->dev,
1527 "USB CEDUSB device now attached to cedusb #%d",
1528 interface->minor);
1529 return 0;
1530
1531error:
1532 if (pdx)
1533 kref_put(&pdx->kref, ced_delete); // frees allocated memory
1534 return retval;
1535}
1536
1537static void ced_disconnect(struct usb_interface *interface)
1538{
1539 DEVICE_EXTENSION *pdx = usb_get_intfdata(interface);
1540 int minor = interface->minor; // save for message at the end
1541 int i;
1542
1543 usb_set_intfdata(interface, NULL); // remove the pdx from the interface
1544 usb_deregister_dev(interface, &ced_class); // give back our minor device number
1545
1546 mutex_lock(&pdx->io_mutex); // stop more I/O starting while...
1547 ced_draw_down(pdx); // ...wait for then kill any io
1548 for (i = 0; i < MAX_TRANSAREAS; ++i) {
1549 int iErr = ClearArea(pdx, i); // ...release any used memory
1550 if (iErr == U14ERR_UNLOCKFAIL)
1551 dev_err(&pdx->interface->dev, "%s Area %d was in used",
1552 __func__, i);
1553 }
1554 pdx->interface = NULL; // ...we kill off link to interface
1555 mutex_unlock(&pdx->io_mutex);
1556
1557 usb_kill_anchored_urbs(&pdx->submitted);
1558
1559 kref_put(&pdx->kref, ced_delete); // decrement our usage count
1560
1561 dev_info(&interface->dev, "USB cedusb #%d now disconnected", minor);
1562}
1563
1564// Wait for all the urbs we know of to be done with, then kill off any that
1565// are left. NBNB we will need to have a mechanism to stop circular xfers
1566// from trying to fire off more urbs. We will wait up to 3 seconds for Urbs
1567// to be done.
1568void ced_draw_down(DEVICE_EXTENSION * pdx)
1569{
1570 int time;
1571 dev_dbg(&pdx->interface->dev, "%s called", __func__);
1572
1573 pdx->bInDrawDown = true;
1574 time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000);
1575 if (!time) // if we timed out we kill the urbs
1576 {
1577 usb_kill_anchored_urbs(&pdx->submitted);
1578 dev_err(&pdx->interface->dev, "%s timed out", __func__);
1579 }
1580 pdx->bInDrawDown = false;
1581}
1582
1583static int ced_suspend(struct usb_interface *intf, pm_message_t message)
1584{
1585 DEVICE_EXTENSION *pdx = usb_get_intfdata(intf);
1586 if (!pdx)
1587 return 0;
1588 ced_draw_down(pdx);
1589
1590 dev_dbg(&pdx->interface->dev, "%s called", __func__);
1591 return 0;
1592}
1593
1594static int ced_resume(struct usb_interface *intf)
1595{
1596 DEVICE_EXTENSION *pdx = usb_get_intfdata(intf);
1597 if (!pdx)
1598 return 0;
1599 dev_dbg(&pdx->interface->dev, "%s called", __func__);
1600 return 0;
1601}
1602
1603static int ced_pre_reset(struct usb_interface *intf)
1604{
1605 DEVICE_EXTENSION *pdx = usb_get_intfdata(intf);
1606 dev_dbg(&pdx->interface->dev, "%s", __func__);
1607 mutex_lock(&pdx->io_mutex);
1608 ced_draw_down(pdx);
1609 return 0;
1610}
1611
1612static int ced_post_reset(struct usb_interface *intf)
1613{
1614 DEVICE_EXTENSION *pdx = usb_get_intfdata(intf);
1615 dev_dbg(&pdx->interface->dev, "%s", __func__);
1616
1617 /* we are sure no URBs are active - no locking needed */
1618 pdx->errors = -EPIPE;
1619 mutex_unlock(&pdx->io_mutex);
1620
1621 return 0;
1622}
1623
1624static struct usb_driver ced_driver = {
1625 .name = "cedusb",
1626 .probe = ced_probe,
1627 .disconnect = ced_disconnect,
1628 .suspend = ced_suspend,
1629 .resume = ced_resume,
1630 .pre_reset = ced_pre_reset,
1631 .post_reset = ced_post_reset,
1632 .id_table = ced_table,
1633 .supports_autosuspend = 1,
1634};
1635
1636module_usb_driver(ced_driver);
1637MODULE_LICENSE("GPL");
drivers/staging/ced1401/usb1401.h+249−0
@@ -0,0 +1,249 @@
1/* usb1401.h
2 Header file for the CED 1401 USB device driver for Linux
3 Copyright (C) 2010 Cambridge Electronic Design Ltd
4 Author Greg P Smith (greg@ced.co.uk)
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19*/
20#ifndef __USB1401_H__
21#define __USB1401_H__
22#include "use1401.h"
23#include "ced_ioctl.h"
24
25#ifndef UINT
26#define UINT unsigned int
27#endif
28
29/// Device type codes, but these don't need to be extended - a succession is assumed
30/// These are set for usb from the bcdDevice field (suitably mangled). Future devices
31/// will be added in order of device creation to the list, so the names here are just
32/// to help use remember which device is which. The U14ERR_... values follow the same
33/// pattern for modern devices.
34#define TYPEUNKNOWN -1 // dont know
35#define TYPE1401 0 // standard 1401
36#define TYPEPLUS 1 // 1401 plus
37#define TYPEU1401 2 // u1401
38#define TYPEPOWER 3 // Power1401
39#define TYPEU14012 4 // u1401 mkII
40#define TYPEPOWER2 5 // Power1401 mk II
41#define TYPEMICRO3 6 // Micro1401-3
42#define TYPEPOWER3 7 // Power1401-3
43
44/// Some useful defines of constants. DONT FORGET to change the version in the
45/// resources whenever you change it here!.
46#define DRIVERMAJREV 2 // driver revision level major (match windows)
47#define DRIVERMINREV 0 // driver revision level minor
48
49/// Definitions of the various block transfer command codes
50#define TM_EXTTOHOST 8 // extended tohost
51#define TM_EXTTO1401 9 // extended to1401
52
53/// Definitions of values in usbReqtype. Used in sorting out setup actions
54#define H_TO_D 0x00
55#define D_TO_H 0x80
56#define VENDOR 0x40
57#define DEVREQ 0x00
58#define INTREQ 0x01
59#define ENDREQ 0x02
60
61/// Definition of values in usbRequest, again used to sort out setup
62#define GET_STATUS 0x00
63#define CLEAR_FEATURE 0x01
64#define SET_FEATURE 0x03
65#define SET_ADDRESS 0x05
66#define GET_DESC 0x06
67#define SET_DESC 0x07
68#define GET_CONF 0x08
69#define SET_CONF 0x09
70#define GET_INTERFACE 0x0a
71#define SET_INTERFACE 0x0b
72#define SYNCH_FRAME 0x0c
73
74/// Definitions of the various debug command codes understood by the 1401. These
75/// are used in various vendor-specific commands to achieve the desired effect
76#define DB_GRAB 0x50 /* Grab is a NOP for USB */
77#define DB_FREE 0x51 /* Free is a NOP for the USB */
78#define DB_SETADD 0x52 /* Set debug address (double) */
79#define DB_SELFTEST 0x53 /* Start self test */
80#define DB_SETMASK 0x54 /* Set enable mask (double) */
81#define DB_SETDEF 0x55 /* Set default mask (double) */
82#define DB_PEEK 0x56 /* Peek address, save result */
83#define DB_POKE 0x57 /* Poke address with data (double) */
84#define DB_RAMPD 0x58 /* Ramp data at debug address */
85#define DB_RAMPA 0x59 /* Ramp address bus */
86#define DB_REPEATS 0x5A /* Set repeats for operations (double) */
87#define DB_WIDTH 0x5B /* Set width for operations (byte) */
88#define DB_DATA 0x5C /* Get 4-byte data read by PEEK */
89#define DB_CHARS 0x5D /* Send chars via EP0 control write */
90
91#define CR_CHAR 0x0D /* The carriage return character */
92#define CR_CHAR_80 0x8d /* and with bit 7 set */
93
94/// A structure holding information about a block of memory for use in circular transfers
95typedef struct circBlk
96{
97 volatile UINT dwOffset; /* Offset within area of block start */
98 volatile UINT dwSize; /* Size of the block, in bytes (0 = unused) */
99} CIRCBLK;
100
101/// A structure holding all of the information about a transfer area - an area of
102/// memory set up for use either as a source or destination in DMA transfers.
103typedef struct transarea
104{
105 void* lpvBuff; // User address of xfer area saved for completeness
106 UINT dwBaseOffset; // offset to start of xfer area in first page
107 UINT dwLength; // Length of xfer area, in bytes
108 struct page **pPages; // Points at array of locked down pages
109 int nPages; // number of pages that are locked down
110 bool bUsed; // Is this structure in use?
111 bool bCircular; // Is this area for circular transfers?
112 bool bCircToHost; // Flag for direction of circular transfer
113 bool bEventToHost; // Set event on transfer to host?
114 int iWakeUp; // Set 1 on event, cleared by TestEvent()
115 UINT dwEventSt; // Defines section within xfer area for...
116 UINT dwEventSz; // ...notification by the event SZ is 0 if unset
117 CIRCBLK aBlocks[2]; // Info on a pair of circular blocks
118 wait_queue_head_t wqEvent; // The wait queue for events in this area MUST BE LAST
119} TRANSAREA;
120
121/// The DMADESC structure is used to hold information on the transfer in progress. It
122/// is set up by ReadDMAInfo, using information sent by the 1401 in an escape sequence.
123typedef struct dmadesc
124{
125 unsigned short wTransType; /* transfer type as TM_xxx above */
126 unsigned short wIdent; /* identifier word */
127 unsigned int dwSize; /* bytes to transfer */
128 unsigned int dwOffset; /* offset into transfer area for trans */
129 bool bOutWard; /* true when data is going TO 1401 */
130} DMADESC;
131
132#define INBUF_SZ 256 /* input buffer size */
133#define OUTBUF_SZ 256 /* output buffer size */
134#define STAGED_SZ 0x10000 // size of coherent buffer for staged transfers
135
136/// Structure to hold all of our device specific stuff. We are making this as similar as we
137/// can to the Windows driver to help in our understanding of what is going on.
138typedef struct _DEVICE_EXTENSION
139{
140 char inputBuffer[INBUF_SZ]; /* The two buffers */
141 char outputBuffer[OUTBUF_SZ]; /* accessed by the host functions */
142 volatile unsigned int dwNumInput; /* num of chars in input buffer */
143 volatile unsigned int dwInBuffGet; /* where to get from input buffer */
144 volatile unsigned int dwInBuffPut; /* where to put into input buffer */
145 volatile unsigned int dwNumOutput; /* num of chars in output buffer */
146 volatile unsigned int dwOutBuffGet; /* where to get from output buffer*/
147 volatile unsigned int dwOutBuffPut; /* where to put into output buffer*/
148
149 volatile bool bSendCharsPending; /* Flag to indicate sendchar active */
150 volatile bool bReadCharsPending; /* Flag to indicate a read is primed */
151 char* pCoherCharOut; /* special aligned buffer for chars to 1401 */
152 struct urb* pUrbCharOut; /* urb used for chars to 1401 */
153 char* pCoherCharIn; /* special aligned buffer for chars to host */
154 struct urb* pUrbCharIn; /* urb used for chars to host */
155
156 spinlock_t charOutLock; /* to protect the outputBuffer and outputting */
157 spinlock_t charInLock; /* to protect the inputBuffer and char reads */
158 __u8 bInterval; /* Interrupt end point interval */
159
160 volatile unsigned int dwDMAFlag; /* state of DMA */
161 TRANSAREA rTransDef[MAX_TRANSAREAS];/* transfer area info */
162 volatile DMADESC rDMAInfo; // info on current DMA transfer
163 volatile bool bXFerWaiting; // Flag set if DMA transfer stalled
164 volatile bool bInDrawDown; // Flag that we want to halt transfers
165
166 // Parameters relating to a block read\write that is in progress. Some of these values
167 // are equivalent to values in rDMAInfo. The values here are those in use, while those
168 // in rDMAInfo are those recieved from the 1401 via an escape sequence. If another
169 // escape sequence arrives before the previous xfer ends, rDMAInfo values are updated while these
170 // are used to finish off the current transfer.
171 volatile short StagedId; // The transfer area id for this transfer
172 volatile bool StagedRead; // Flag TRUE for read from 1401, FALSE for write
173 volatile unsigned int StagedLength; // Total length of this transfer
174 volatile unsigned int StagedOffset; // Offset within memory area for transfer start
175 volatile unsigned int StagedDone; // Bytes transferred so far
176 volatile bool bStagedUrbPending; // Flag to indicate active
177 char* pCoherStagedIO; // buffer used for block transfers
178 struct urb* pStagedUrb; // The URB to use
179 spinlock_t stagedLock; // protects ReadWriteMem() and circular buffer stuff
180
181 short s1401Type; // type of 1401 attached
182 short sCurrentState; // current error state
183 bool bIsUSB2; // type of the interface we connect to
184 bool bForceReset; // Flag to make sure we get a real reset
185 __u32 statBuf[2]; // buffer for 1401 state info
186
187 unsigned long ulSelfTestTime; // used to timeout self test
188
189 int nPipes; // Should be 3 or 4 depending on 1401 usb chip
190 int bPipeError[4]; // set non-zero if an error on one of the pipe
191 __u8 epAddr[4]; // addresses of the 3/4 end points
192
193 struct usb_device *udev; // the usb device for this device
194 struct usb_interface *interface; // the interface for this device, NULL if removed
195 struct usb_anchor submitted; // in case we need to retract our submissions
196 struct mutex io_mutex; // synchronize I/O with disconnect, one user-mode caller at a time
197
198 int errors; // the last request tanked
199 int open_count; // count the number of openers
200 spinlock_t err_lock; // lock for errors
201 struct kref kref;
202}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
203#define to_DEVICE_EXTENSION(d) container_of(d, DEVICE_EXTENSION, kref)
204
205/// Definitions of routimes used between compilation object files
206// in usb1401.c
207extern int Allowi(DEVICE_EXTENSION* pdx, bool bInCallback);
208extern int SendChars(DEVICE_EXTENSION* pdx);
209extern void ced_draw_down(DEVICE_EXTENSION *pdx);
210extern int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent,
211 unsigned int dwOffs, unsigned int dwLen);
212
213// in ced_ioc.c
214extern int ClearArea(DEVICE_EXTENSION *pdx, int nArea);
215extern int SendString(DEVICE_EXTENSION* pdx, const char __user* pData, unsigned int n);
216extern int SendChar(DEVICE_EXTENSION *pdx, char c);
217extern int Get1401State(DEVICE_EXTENSION* pdx, __u32* state, __u32* error);
218extern int ReadWrite_Cancel(DEVICE_EXTENSION *pdx);
219extern bool Is1401(DEVICE_EXTENSION* pdx);
220extern bool QuickCheck(DEVICE_EXTENSION* pdx, bool bTestBuff, bool bCanReset);
221extern int Reset1401(DEVICE_EXTENSION *pdx);
222extern int GetChar(DEVICE_EXTENSION *pdx);
223extern int GetString(DEVICE_EXTENSION *pdx, char __user* pUser, int n);
224extern int SetTransfer(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD);
225extern int UnsetTransfer(DEVICE_EXTENSION *pdx, int nArea);
226extern int SetEvent(DEVICE_EXTENSION *pdx, TRANSFEREVENT __user*pTE);
227extern int Stat1401(DEVICE_EXTENSION *pdx);
228extern int LineCount(DEVICE_EXTENSION *pdx);
229extern int GetOutBufSpace(DEVICE_EXTENSION *pdx);
230extern int GetTransfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pGTB);
231extern int KillIO1401(DEVICE_EXTENSION *pdx);
232extern int BlkTransState(DEVICE_EXTENSION *pdx);
233extern int StateOf1401(DEVICE_EXTENSION *pdx);
234extern int StartSelfTest(DEVICE_EXTENSION *pdx);
235extern int CheckSelfTest(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST);
236extern int TypeOf1401(DEVICE_EXTENSION *pdx);
237extern int TransferFlags(DEVICE_EXTENSION *pdx);
238extern int DbgPeek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user* pDB);
239extern int DbgPoke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
240extern int DbgRampData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
241extern int DbgRampAddr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
242extern int DbgGetData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
243extern int DbgStopLoop(DEVICE_EXTENSION *pdx);
244extern int SetCircular(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD);
245extern int GetCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB);
246extern int FreeCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB);
247extern int WaitEvent(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut);
248extern int TestEvent(DEVICE_EXTENSION *pdx, int nArea);
249#endif
drivers/staging/ced1401/use1401.h+287−0
@@ -0,0 +1,287 @@
1/****************************************************************************
2** use1401.h
3** Copyright (C) Cambridge Electronic Design Ltd, 1992-2010
4** Authors: Paul Cox, Tim Bergel, Greg Smith
5** See CVS for revisions.
6**
7** Because the size of a long is different between 32-bit and 64-bit on some
8** systems, we avoid this in this interface.
9****************************************************************************/
10#ifndef __USE1401_H__
11#define __USE1401_H__
12#include "machine.h"
13
14// Some definitions to make things compatible. If you want to use Use1401 directly
15// from a Windows program you should define U14_NOT_DLL, in which case you also
16// MUST make sure that your application startup code calls U14InitLib().
17// DLL_USE1401 is defined when you are building the Use1401 dll, not otherwise.
18#ifdef _IS_WINDOWS_
19#ifndef U14_NOT_DLL
20#ifdef DLL_USE1401
21#define U14API(retType) retType DllExport __stdcall
22#else
23#define U14API(retType) retType DllImport __stdcall
24#endif
25#endif
26
27#define U14ERRBASE -500
28#define U14LONG long
29#endif
30
31#ifdef LINUX
32#define U14ERRBASE -1000
33#define U14LONG int
34#endif
35
36#ifdef _QT
37#ifndef U14_NOT_DLL
38#undef U14API
39#define U14API(retType) retType __declspec(dllimport) __stdcall
40#endif
41#undef U14LONG
42#define U14LONG int
43#endif
44
45#ifndef U14API
46#define U14API(retType) retType
47#endif
48
49#ifndef U14LONG
50#define U14LONG long
51#endif
52
53/// Error codes: We need them here as user space can see them.
54#define U14ERR_NOERROR 0 // no problems
55
56/// Device error codes, but these don't need to be extended - a succession is assumed
57#define U14ERR_STD 4 // standard 1401 connected
58#define U14ERR_U1401 5 // u1401 connected
59#define U14ERR_PLUS 6 // 1401 plus connected
60#define U14ERR_POWER 7 // Power1401 connected
61#define U14ERR_U14012 8 // u1401 mkII connected
62#define U14ERR_POWER2 9
63#define U14ERR_U14013 10
64#define U14ERR_POWER3 11
65
66/// NBNB Error numbers need shifting as some linux error codes start at 512
67#define U14ERR(n) (n+U14ERRBASE)
68#define U14ERR_OFF U14ERR(0) /* 1401 there but switched off */
69#define U14ERR_NC U14ERR(-1) /* 1401 not connected */
70#define U14ERR_ILL U14ERR(-2) /* if present it is ill */
71#define U14ERR_NOIF U14ERR(-3) /* I/F card missing */
72#define U14ERR_TIME U14ERR(-4) /* 1401 failed to come ready */
73#define U14ERR_BADSW U14ERR(-5) /* I/F card bad switches */
74#define U14ERR_PTIME U14ERR(-6) /* 1401plus failed to come ready */
75#define U14ERR_NOINT U14ERR(-7) /* couldn't grab the int vector */
76#define U14ERR_INUSE U14ERR(-8) /* 1401 is already in use */
77#define U14ERR_NODMA U14ERR(-9) /* couldn't get DMA channel */
78#define U14ERR_BADHAND U14ERR(-10) /* handle provided was bad */
79#define U14ERR_BAD1401NUM U14ERR(-11) /* 1401 number provided was bad */
80
81#define U14ERR_NO_SUCH_FN U14ERR(-20) /* no such function */
82#define U14ERR_NO_SUCH_SUBFN U14ERR(-21) /* no such sub function */
83#define U14ERR_NOOUT U14ERR(-22) /* no room in output buffer */
84#define U14ERR_NOIN U14ERR(-23) /* no input in buffer */
85#define U14ERR_STRLEN U14ERR(-24) /* string longer than buffer */
86#define U14ERR_ERR_STRLEN U14ERR(-24) /* string longer than buffer */
87#define U14ERR_LOCKFAIL U14ERR(-25) /* failed to lock memory */
88#define U14ERR_UNLOCKFAIL U14ERR(-26) /* failed to unlock memory */
89#define U14ERR_ALREADYSET U14ERR(-27) /* area already set up */
90#define U14ERR_NOTSET U14ERR(-28) /* area not set up */
91#define U14ERR_BADAREA U14ERR(-29) /* illegal area number */
92#define U14ERR_FAIL U14ERR(-30) /* we failed for some other reason*/
93
94#define U14ERR_NOFILE U14ERR(-40) /* command file not found */
95#define U14ERR_READERR U14ERR(-41) /* error reading command file */
96#define U14ERR_UNKNOWN U14ERR(-42) /* unknown command */
97#define U14ERR_HOSTSPACE U14ERR(-43) /* not enough host space to load */
98#define U14ERR_LOCKERR U14ERR(-44) /* could not lock resource/command*/
99#define U14ERR_CLOADERR U14ERR(-45) /* CLOAD command failed */
100
101#define U14ERR_TOXXXERR U14ERR(-60) /* tohost/1401 failed */
102#define U14ERR_NO386ENH U14ERR(-80) /* not 386 enhanced mode */
103#define U14ERR_NO1401DRIV U14ERR(-81) /* no device driver */
104#define U14ERR_DRIVTOOOLD U14ERR(-82) /* device driver too old */
105
106#define U14ERR_TIMEOUT U14ERR(-90) /* timeout occurred */
107
108#define U14ERR_BUFF_SMALL U14ERR(-100) /* buffer for getstring too small */
109#define U14ERR_CBALREADY U14ERR(-101) /* there is already a callback */
110#define U14ERR_BADDEREG U14ERR(-102) /* bad parameter to deregcallback */
111#define U14ERR_NOMEMORY U14ERR(-103) /* no memory for allocation */
112
113#define U14ERR_DRIVCOMMS U14ERR(-110) /* failed talking to driver */
114#define U14ERR_OUTOFMEMORY U14ERR(-111) /* needed memory and couldnt get it*/
115
116/// 1401 type codes.
117#define U14TYPE1401 0 /* standard 1401 */
118#define U14TYPEPLUS 1 /* 1401 plus */
119#define U14TYPEU1401 2 /* u1401 */
120#define U14TYPEPOWER 3 /* power1401 */
121#define U14TYPEU14012 4 /* u1401 mk II */
122#define U14TYPEPOWER2 5 /* power1401 mk II */
123#define U14TYPEU14013 6 /* u1401-3 */
124#define U14TYPEPOWER3 7 /* power1401-3 */
125#define U14TYPEUNKNOWN -1 /* dont know */
126
127/// Transfer flags to allow driver capabilities to be interrogated
128
129/// Constants for transfer flags
130#define U14TF_USEDMA 1 /* Transfer flag for use DMA */
131#define U14TF_MULTIA 2 /* Transfer flag for multi areas */
132#define U14TF_FIFO 4 /* for FIFO interface card */
133#define U14TF_USB2 8 /* for USB2 interface and 1401 */
134#define U14TF_NOTIFY 16 /* for event notifications */
135#define U14TF_SHORT 32 /* for PCI can short cycle */
136#define U14TF_PCI2 64 /* for new PCI card 1401-70 */
137#define U14TF_CIRCTH 128 /* Circular-mode to host */
138#define U14TF_DIAG 256 /* Diagnostics/debug functions */
139#define U14TF_CIRC14 512 /* Circular-mode to 1401 */
140
141/// Definitions of element sizes for DMA transfers - to allow byte-swapping
142#define ESZBYTES 0 /* BYTE element size value */
143#define ESZWORDS 1 /* WORD element size value */
144#define ESZLONGS 2 /* long element size value */
145#define ESZUNKNOWN 0 /* unknown element size value */
146
147/// These define required access types for the debug/diagnostics function
148#define BYTE_SIZE 1 /* 8-bit access */
149#define WORD_SIZE 2 /* 16-bit access */
150#define LONG_SIZE 3 /* 32-bit access */
151
152/// Stuff used by U14_GetTransfer
153#define GET_TX_MAXENTRIES 257 /* (max length / page size + 1) */
154
155#ifdef _IS_WINDOWS_
156#pragma pack(1)
157
158typedef struct /* used for U14_GetTransfer results */
159{ /* Info on a single mapped block */
160 U14LONG physical;
161 U14LONG size;
162} TXENTRY;
163
164typedef struct TGetTxBlock /* used for U14_GetTransfer results */
165{ /* matches structure in VXD */
166 U14LONG size;
167 U14LONG linear;
168 short seg;
169 short reserved;
170 short avail; /* number of available entries */
171 short used; /* number of used entries */
172 TXENTRY entries[GET_TX_MAXENTRIES]; /* Array of mapped block info */
173} TGET_TX_BLOCK;
174
175typedef TGET_TX_BLOCK *LPGET_TX_BLOCK;
176
177#pragma pack()
178#endif
179
180#ifdef LINUX
181typedef struct /* used for U14_GetTransfer results */
182{ /* Info on a single mapped block */
183 long long physical;
184 long size;
185} TXENTRY;
186
187typedef struct TGetTxBlock /* used for U14_GetTransfer results */
188{ /* matches structure in VXD */
189 long long linear; /* linear address */
190 long size; /* total size of the mapped area, holds id when called */
191 short seg; /* segment of the address for Win16 */
192 short reserved;
193 short avail; /* number of available entries */
194 short used; /* number of used entries */
195 TXENTRY entries[GET_TX_MAXENTRIES]; /* Array of mapped block info */
196} TGET_TX_BLOCK;
197#endif
198
199#ifdef __cplusplus
200extern "C" {
201#endif
202
203U14API(int) U14WhenToTimeOut(short hand); // when to timeout in ms
204U14API(short) U14PassedTime(int iTime); // non-zero if iTime passed
205
206U14API(short) U14LastErrCode(short hand);
207
208U14API(short) U14Open1401(short n1401);
209U14API(short) U14Close1401(short hand);
210U14API(short) U14Reset1401(short hand);
211U14API(short) U14ForceReset(short hand);
212U14API(short) U14TypeOf1401(short hand);
213U14API(short) U14NameOf1401(short hand, char* pBuf, WORD wMax);
214
215U14API(short) U14Stat1401(short hand);
216U14API(short) U14CharCount(short hand);
217U14API(short) U14LineCount(short hand);
218
219U14API(short) U14SendString(short hand, const char* pString);
220U14API(short) U14GetString(short hand, char* pBuffer, WORD wMaxLen);
221U14API(short) U14SendChar(short hand, char cChar);
222U14API(short) U14GetChar(short hand, char* pcChar);
223
224U14API(short) U14LdCmd(short hand, const char* command);
225U14API(DWORD) U14Ld(short hand, const char* vl, const char* str);
226
227U14API(short) U14SetTransArea(short hand, WORD wArea, void *pvBuff,
228 DWORD dwLength, short eSz);
229U14API(short) U14UnSetTransfer(short hand, WORD wArea);
230U14API(short) U14SetTransferEvent(short hand, WORD wArea, BOOL bEvent,
231 BOOL bToHost, DWORD dwStart, DWORD dwLength);
232U14API(int) U14TestTransferEvent(short hand, WORD wArea);
233U14API(int) U14WaitTransferEvent(short hand, WORD wArea, int msTimeOut);
234U14API(short) U14GetTransfer(short hand, TGET_TX_BLOCK *pTransBlock);
235
236U14API(short) U14ToHost(short hand, char* pAddrHost,DWORD dwSize,DWORD dw1401,
237 short eSz);
238U14API(short) U14To1401(short hand, const char* pAddrHost,DWORD dwSize,DWORD dw1401,
239 short eSz);
240
241U14API(short) U14SetCircular(short hand, WORD wArea, BOOL bToHost, void *pvBuff,
242 DWORD dwLength);
243
244U14API(int) U14GetCircBlk(short hand, WORD wArea, DWORD *pdwOffs);
245U14API(int) U14FreeCircBlk(short hand, WORD wArea, DWORD dwOffs, DWORD dwSize,
246 DWORD *pdwOffs);
247
248U14API(short) U14StrToLongs(const char* pszBuff, U14LONG *palNums, short sMaxLongs);
249U14API(short) U14LongsFrom1401(short hand, U14LONG *palBuff, short sMaxLongs);
250
251U14API(void) U14SetTimeout(short hand, int lTimeout);
252U14API(int) U14GetTimeout(short hand);
253U14API(short) U14OutBufSpace(short hand);
254U14API(int) U14BaseAddr1401(short hand);
255U14API(int) U14DriverVersion(short hand);
256U14API(int) U14DriverType(short hand);
257U14API(short) U14DriverName(short hand, char* pBuf, WORD wMax);
258U14API(short) U14GetUserMemorySize(short hand, DWORD *pMemorySize);
259U14API(short) U14KillIO1401(short hand);
260
261U14API(short) U14BlkTransState(short hand);
262U14API(short) U14StateOf1401(short hand);
263
264U14API(short) U14Grab1401(short hand);
265U14API(short) U14Free1401(short hand);
266U14API(short) U14Peek1401(short hand, DWORD dwAddr, int nSize, int nRepeats);
267U14API(short) U14Poke1401(short hand, DWORD dwAddr, DWORD dwValue, int nSize, int nRepeats);
268U14API(short) U14Ramp1401(short hand, DWORD dwAddr, DWORD dwDef, DWORD dwEnable, int nSize, int nRepeats);
269U14API(short) U14RampAddr(short hand, DWORD dwDef, DWORD dwEnable, int nSize, int nRepeats);
270U14API(short) U14StopDebugLoop(short hand);
271U14API(short) U14GetDebugData(short hand, U14LONG *plValue);
272
273U14API(short) U14StartSelfTest(short hand);
274U14API(short) U14CheckSelfTest(short hand, U14LONG *pData);
275U14API(short) U14TransferFlags(short hand);
276U14API(void) U14GetErrorString(short nErr, char* pStr, WORD wMax);
277U14API(int) U14MonitorRev(short hand);
278U14API(void) U14CloseAll(void);
279
280U14API(short) U14WorkingSet(DWORD dwMinKb, DWORD dwMaxKb);
281U14API(int) U14InitLib(void);
282
283#ifdef __cplusplus
284}
285#endif
286
287#endif /* End of ifndef __USE1401_H__ */
drivers/staging/ced1401/use14_ioc.h+301−0
@@ -0,0 +1,301 @@
1/* use14_ioc.h
2** definitions of use1401 module stuff that is shared between use1401 and the driver.
3** Copyright (C) Cambridge Electronic Design Limited 2010
4** Author Greg P Smith
5************************************************************************************/
6#ifndef __USE14_IOC_H__
7#define __USE14_IOC_H__
8
9#define MAX_TRANSAREAS 8 /* The number of transfer areas supported by driver */
10
11#define i386
12#include "winioctl.h" /* needed so we can access driver */
13
14/*
15** Defines for IOCTL functions to ask driver to perform. These must be matched
16** in both use1401 and in the driver. The IOCTL code contains a command
17** identifier, plus other information about the device, the type of access
18** with which the file must have been opened, and the type of buffering.
19** The IOCTL function codes from 0x80 to 0xFF are for developer use.
20*/
21#define FILE_DEVICE_CED1401 0x8001
22#define FNNUMBASE 0x800
23
24#define U14_OPEN1401 CTL_CODE( FILE_DEVICE_CED1401, \
25 FNNUMBASE, \
26 METHOD_BUFFERED, \
27 FILE_ANY_ACCESS)
28
29#define U14_CLOSE1401 CTL_CODE( FILE_DEVICE_CED1401, \
30 FNNUMBASE+1, \
31 METHOD_BUFFERED, \
32 FILE_ANY_ACCESS)
33
34#define U14_SENDSTRING CTL_CODE( FILE_DEVICE_CED1401, \
35 FNNUMBASE+2, \
36 METHOD_BUFFERED, \
37 FILE_ANY_ACCESS)
38
39#define U14_RESET1401 CTL_CODE( FILE_DEVICE_CED1401, \
40 FNNUMBASE+3, \
41 METHOD_BUFFERED, \
42 FILE_ANY_ACCESS)
43
44#define U14_GETCHAR CTL_CODE( FILE_DEVICE_CED1401, \
45 FNNUMBASE+4, \
46 METHOD_BUFFERED, \
47 FILE_ANY_ACCESS)
48
49#define U14_SENDCHAR CTL_CODE( FILE_DEVICE_CED1401, \
50 FNNUMBASE+5, \
51 METHOD_BUFFERED, \
52 FILE_ANY_ACCESS)
53
54#define U14_STAT1401 CTL_CODE( FILE_DEVICE_CED1401, \
55 FNNUMBASE+6, \
56 METHOD_BUFFERED, \
57 FILE_ANY_ACCESS)
58
59#define U14_LINECOUNT CTL_CODE( FILE_DEVICE_CED1401, \
60 FNNUMBASE+7, \
61 METHOD_BUFFERED, \
62 FILE_ANY_ACCESS)
63
64#define U14_GETSTRING CTL_CODE( FILE_DEVICE_CED1401, \
65 FNNUMBASE+8, \
66 METHOD_BUFFERED, \
67 FILE_ANY_ACCESS)
68
69#define U14_REGCALLBACK CTL_CODE( FILE_DEVICE_CED1401, \
70 FNNUMBASE+9, \
71 METHOD_BUFFERED, \
72 FILE_ANY_ACCESS)
73
74#define U14_GETMONITORBUF CTL_CODE( FILE_DEVICE_CED1401, \
75 FNNUMBASE+10, \
76 METHOD_BUFFERED, \
77 FILE_ANY_ACCESS)
78
79#define U14_SETTRANSFER CTL_CODE( FILE_DEVICE_CED1401, \
80 FNNUMBASE+11, \
81 METHOD_BUFFERED, \
82 FILE_ANY_ACCESS)
83
84#define U14_UNSETTRANSFER CTL_CODE( FILE_DEVICE_CED1401, \
85 FNNUMBASE+12, \
86 METHOD_BUFFERED, \
87 FILE_ANY_ACCESS)
88
89#define U14_SETTRANSEVENT CTL_CODE( FILE_DEVICE_CED1401, \
90 FNNUMBASE+13, \
91 METHOD_BUFFERED, \
92 FILE_ANY_ACCESS)
93
94#define U14_GETOUTBUFSPACE CTL_CODE( FILE_DEVICE_CED1401, \
95 FNNUMBASE+14, \
96 METHOD_BUFFERED, \
97 FILE_ANY_ACCESS)
98
99#define U14_GETBASEADDRESS CTL_CODE( FILE_DEVICE_CED1401, \
100 FNNUMBASE+15, \
101 METHOD_BUFFERED, \
102 FILE_ANY_ACCESS)
103
104#define U14_GETDRIVERREVISION CTL_CODE( FILE_DEVICE_CED1401, \
105 FNNUMBASE+16, \
106 METHOD_BUFFERED, \
107 FILE_ANY_ACCESS)
108
109#define U14_GETTRANSFER CTL_CODE( FILE_DEVICE_CED1401, \
110 FNNUMBASE+17, \
111 METHOD_BUFFERED, \
112 FILE_ANY_ACCESS)
113
114#define U14_KILLIO1401 CTL_CODE( FILE_DEVICE_CED1401, \
115 FNNUMBASE+18, \
116 METHOD_BUFFERED, \
117 FILE_ANY_ACCESS)
118
119#define U14_BLKTRANSSTATE CTL_CODE( FILE_DEVICE_CED1401, \
120 FNNUMBASE+19, \
121 METHOD_BUFFERED, \
122 FILE_ANY_ACCESS)
123
124#define U14_BYTECOUNT CTL_CODE( FILE_DEVICE_CED1401, \
125 FNNUMBASE+20, \
126 METHOD_BUFFERED, \
127 FILE_ANY_ACCESS)
128
129#define U14_ZEROBLOCKCOUNT CTL_CODE( FILE_DEVICE_CED1401, \
130 FNNUMBASE+21, \
131 METHOD_BUFFERED, \
132 FILE_ANY_ACCESS)
133
134#define U14_STOPCIRCULAR CTL_CODE( FILE_DEVICE_CED1401, \
135 FNNUMBASE+22, \
136 METHOD_BUFFERED, \
137 FILE_ANY_ACCESS)
138
139#define U14_STATEOF1401 CTL_CODE( FILE_DEVICE_CED1401, \
140 FNNUMBASE+23, \
141 METHOD_BUFFERED, \
142 FILE_ANY_ACCESS)
143
144#define U14_REGISTERS1401 CTL_CODE( FILE_DEVICE_CED1401, \
145 FNNUMBASE+24, \
146 METHOD_BUFFERED, \
147 FILE_ANY_ACCESS)
148
149#define U14_GRAB1401 CTL_CODE( FILE_DEVICE_CED1401, \
150 FNNUMBASE+25, \
151 METHOD_BUFFERED, \
152 FILE_ANY_ACCESS)
153
154#define U14_FREE1401 CTL_CODE( FILE_DEVICE_CED1401, \
155 FNNUMBASE+26, \
156 METHOD_BUFFERED, \
157 FILE_ANY_ACCESS)
158
159#define U14_STEP1401 CTL_CODE( FILE_DEVICE_CED1401, \
160 FNNUMBASE+27, \
161 METHOD_BUFFERED, \
162 FILE_ANY_ACCESS)
163
164#define U14_SET1401REGISTERS CTL_CODE( FILE_DEVICE_CED1401, \
165 FNNUMBASE+28, \
166 METHOD_BUFFERED, \
167 FILE_ANY_ACCESS)
168
169#define U14_STEPTILL1401 CTL_CODE( FILE_DEVICE_CED1401, \
170 FNNUMBASE+29, \
171 METHOD_BUFFERED, \
172 FILE_ANY_ACCESS)
173
174#define U14_SETORIN CTL_CODE( FILE_DEVICE_CED1401, \
175 FNNUMBASE+30, \
176 METHOD_BUFFERED, \
177 FILE_ANY_ACCESS)
178
179#define U14_STARTSELFTEST CTL_CODE( FILE_DEVICE_CED1401, \
180 FNNUMBASE+31, \
181 METHOD_BUFFERED, \
182 FILE_ANY_ACCESS)
183
184#define U14_CHECKSELFTEST CTL_CODE( FILE_DEVICE_CED1401, \
185 FNNUMBASE+32, \
186 METHOD_BUFFERED, \
187 FILE_ANY_ACCESS)
188
189#define U14_TYPEOF1401 CTL_CODE( FILE_DEVICE_CED1401, \
190 FNNUMBASE+33, \
191 METHOD_BUFFERED, \
192 FILE_ANY_ACCESS)
193
194#define U14_TRANSFERFLAGS CTL_CODE( FILE_DEVICE_CED1401, \
195 FNNUMBASE+34, \
196 METHOD_BUFFERED, \
197 FILE_ANY_ACCESS)
198
199#define U14_DBGPEEK CTL_CODE( FILE_DEVICE_CED1401, \
200 FNNUMBASE+35, \
201 METHOD_BUFFERED, \
202 FILE_ANY_ACCESS)
203
204#define U14_DBGPOKE CTL_CODE( FILE_DEVICE_CED1401, \
205 FNNUMBASE+36, \
206 METHOD_BUFFERED, \
207 FILE_ANY_ACCESS)
208
209#define U14_DBGRAMPDATA CTL_CODE( FILE_DEVICE_CED1401, \
210 FNNUMBASE+37, \
211 METHOD_BUFFERED, \
212 FILE_ANY_ACCESS)
213
214#define U14_DBGRAMPADDR CTL_CODE( FILE_DEVICE_CED1401, \
215 FNNUMBASE+38, \
216 METHOD_BUFFERED, \
217 FILE_ANY_ACCESS)
218
219#define U14_DBGGETDATA CTL_CODE( FILE_DEVICE_CED1401, \
220 FNNUMBASE+39, \
221 METHOD_BUFFERED, \
222 FILE_ANY_ACCESS)
223
224#define U14_DBGSTOPLOOP CTL_CODE( FILE_DEVICE_CED1401, \
225 FNNUMBASE+40, \
226 METHOD_BUFFERED, \
227 FILE_ANY_ACCESS)
228
229#define U14_FULLRESET CTL_CODE( FILE_DEVICE_CED1401, \
230 FNNUMBASE+41, \
231 METHOD_BUFFERED, \
232 FILE_ANY_ACCESS)
233
234#define U14_SETCIRCULAR CTL_CODE( FILE_DEVICE_CED1401, \
235 FNNUMBASE+42, \
236 METHOD_BUFFERED, \
237 FILE_ANY_ACCESS)
238
239#define U14_GETCIRCBLK CTL_CODE( FILE_DEVICE_CED1401, \
240 FNNUMBASE+43, \
241 METHOD_BUFFERED, \
242 FILE_ANY_ACCESS)
243
244#define U14_FREECIRCBLK CTL_CODE( FILE_DEVICE_CED1401, \
245 FNNUMBASE+44, \
246 METHOD_BUFFERED, \
247 FILE_ANY_ACCESS)
248
249//--------------- Structures that are shared with the driver -------------
250#pragma pack(1)
251
252typedef struct /* used for get/set standard 1401 registers */
253{
254 short sPC;
255 char A;
256 char X;
257 char Y;
258 char stat;
259 char rubbish;
260} T1401REGISTERS;
261
262typedef union /* to communicate with 1401 driver status & control funcs */
263{
264 char chrs[22];
265 short ints[11];
266 long longs[5];
267 T1401REGISTERS registers;
268} TCSBLOCK;
269
270typedef TCSBLOCK* LPTCSBLOCK;
271
272typedef struct paramBlk
273{
274 short sState;
275 TCSBLOCK csBlock;
276} PARAMBLK;
277
278typedef PARAMBLK* PPARAMBLK;
279
280typedef struct TransferDesc /* Structure and type for SetTransArea */
281{
282 WORD wArea; /* number of transfer area to set up */
283 void FAR * lpvBuff; /* address of transfer area */
284 DWORD dwLength; /* length of area to set up */
285 short eSize; /* size to move (for swapping on MAC) */
286} TRANSFERDESC;
287
288typedef TRANSFERDESC FAR * LPTRANSFERDESC;
289
290/* This is the structure used to set up a transfer area */
291typedef struct VXTransferDesc /* use1401.c and use1432x.x use only */
292{
293 WORD wArea; /* number of transfer area to set up */
294 WORD wAddrSel; /* 16 bit selector for area */
295 DWORD dwAddrOfs; /* 32 bit offset for area start */
296 DWORD dwLength; /* length of area to set up */
297} VXTRANSFERDESC;
298
299#pragma pack()
300
301#endif
drivers/staging/ced1401/userspace/use1401.c+3035−0
@@ -0,0 +1,3035 @@
1/****************************************************************************
2** use1401.c
3** Copyright (C) Cambridge Electronic Design Ltd, 1992-2010
4**
5** This program is free software; you can redistribute it and/or
6** modify it under the terms of the GNU General Public License
7** as published by the Free Software Foundation; either version 2
8** of the License, or (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18**
19** Contact CED: Cambridge Electronic Design Limited, Science Park, Milton Road
20** Cambridge, CB6 0FE.
21** www.ced.co.uk
22** greg@ced.co.uk
23**
24** Title: USE1401.C
25** Version: 4.00
26** Author: Paul Cox, Tim Bergel, Greg Smith
27**
28** The code was vigorously pruned in DEC 2010 to remove the macintosh options
29** and to get rid of the 16-bit support. It has also been aligned with the
30** Linux version. See CVS for revisions. This will work for Win 9x onwards.
31****************************************************************************
32**
33** Notes on Windows interface to driver
34** ************************************
35**
36** Under Windows 9x and NT, Use1401 uses DeviceIoControl to get access to
37** the 1401 driver. This has parameters for the device handle, the function
38** code, an input pointer and byte count, an output pointer and byte count
39** and a pointer to a DWORD to hold the output byte count. Note that input
40** and output are from the point-of-view of the driver, so the output stuff
41** is used to read values from the 1401, not send to the 1401. The use of
42** these parameters varies with the function in use and the operating
43** system; there are five separate DIOC calls SendString, GetString and
44** SetTransferArea all have their own specialised calls, the rest use the
45** Status1401 or Control1401 functions.
46**
47** There are two basic styles of DIOC call used, one for Win9x VxD drivers
48** and one for NT Kernel-mode and WDM drivers (see below for tables showing
49** the different parameters used. The array bUseNTDIOC[] selects between
50** these two calling styles.
51**
52** Function codes
53** In Win3.x, simple function codes from 0 to 40 were used, shifted left 8
54** bits with a sub-function code in the lower 8 bits. These were also used
55** in the Windows 95 driver, though we had to add 1 to the code value to
56** avoid problems (Open from CreateFile is zero), and the sub-function code
57** is now unused. We found that this gave some problems with Windows 98
58** as the function code values are reserved by microsoft, so we switched to
59** using the NT function codes instead. The NT codes are generated using the
60** CTL_CODE macro, essentially this gives 0x80012000 | (func << 2), where
61** func is the original 0 to 34 value. The driver will handle both types of
62** code and Use1432 only uses the NT codes if it knows the driver is new
63** enough. The array bUseNTCodes[] holds flags on the type of codes required.
64** GPS/TDB Dec 2010: we removed the bUseNTCodes array as this is always true
65** as we no longer support ancient versions.
66**
67** The CreateFile and CloseFile function calls are also handled
68** by DIOC, using the special function codes 0 and -1 respectively.
69**
70** Input pointer and buffer size
71** These are intended for data sent to the device driver. In nearly all cases
72** they are unused in calls to the Win95 driver, the NT driver uses them
73** for all information sent to the driver. The table below shows the pointer
74** and byte count used for the various calls:
75**
76** Win 95 Win NT
77** SendString NULL, 0 pStr, nStr
78** GetString NULL, 0 NULL, 0
79** SetTransferArea pBuf, nBuf (unused?) pDesc, nDesc
80** GetTransfer NULL, 0 NULL, 0
81** Status1401 NULL, 0 NULL, 0
82** Control1401 NULL, 0 pBlk, nBlk
83**
84** pStr and nStr are pointers to a char buffer and the buffer length for
85** string I/O, note that these are temporary buffers owned by the DLL, not
86** application memory, pBuf and nBuf are the transfer area buffer (I think
87** these are unused), pDesc and nDesc are the TRANSFERDESC structure, pBlk
88** and nBlk are the TCSBLOCK structure.
89**
90**
91** Output pointer and buffer size
92** These are intended for data read from the device driver. These are used
93** for almost all information sent to the Win95 driver, the NT driver uses
94** them for information read from the driver, chiefly the error code. The
95** table below shows the pointer and byte count used for the various calls:
96**
97** Win 95 Win NT
98** SendString pStr, nStr pPar, nPar
99** GetString pStr, nStr+2 pStr, nStr+2
100** SetTransferArea pDesc, nDesc pPar, nPar
101** GetTransfer pGet, nGet pGet, nGet
102** Status1401 pBlk, nBlk pPar, nPar
103** Control1401 pBlk, nBlk pPar, nPar
104**
105** pStr and nStr are pointers to a char buffer and the buffer length for
106** string I/O, the +2 for GetString refers to two spare bytes at the start
107** used to hold the string length and returning an error code for NT. Note
108** again that these are (and must be) DLL-owned temporary buffers. pPar
109** and nPar are a PARAM structure used in NT (it holds an error code and a
110** TCSBLOCK structure). pDesc and nDesc are the VXTRANSFERDESC structure,
111** pBlk and nBlk are the TCSBLOCK structure. pGet and nGet indicate the
112** TGET_TX_BLOCK structure used for GetTransfer.
113**
114**
115** The output byte count
116** Both drivers return the output buffer size here, regardless of the actual
117** bytes output. This is used to check that we did get through to the driver.
118**
119** Multiple 1401s
120** **************
121**
122** We have code that tries to support the use of multiple 1401s, but there
123** are problems: The lDriverVersion and lDriverType variables are global, not
124** per-1401 (a particular problem as the U14 functions that use them don't
125** have a hand parameter). In addition, the mechansim for finding a free
126** 1401 depends upon the 1401 device driver open operation failing if it's
127** already in use, which doesn't always happen, particularly with the VxDs.
128** The code in TryToOpen tries to fix this by relying on TYPEOF1401 to detect
129** the 1401-in-use state - the VxDs contain special code to help this. This is
130** working OK but multiple 1401 support works better with the Win2000 drivers.
131**
132** USB driver
133** **********
134**
135** The USB driver, which runs on both Win98 and NT2000, uses the NT-style
136** calling convention, both for the DIOC codes and the DIOC parameters. The
137** TryToOpen function has been altered to look for an NT driver first in
138** the appropriate circumstances, and to set the driver DIOC flags up in
139** the correct state.
140**
141** Adding a new 1401 type - now almost nothing to do
142** *************************************************
143**
144** The 1401 types are defined by a set of U14TYPExxxx codes in USE1401.H.
145** You should add a new one of these to keep things tidy for applications.
146**
147** DRIVERET_MAX (below) specifies the maximum allowed type code from the
148** 1401 driver; I have set this high to accomodate as yet undesigned 1401
149** types. Similarly, as long as the command file names follow the ARM,
150** ARN, ARO sequence, these are calculated by the ExtForType function, so
151** you don't need to do anything here either.
152**
153** Version number
154** **************
155** The new U14InitLib() function returns 0 if the OS is incapable of use,
156** otherwise is returns the version of the USE1401 library. This is done
157** in three parts: Major(31-24).Minor(23-16).Revision.(15-0) (brackets are
158** the bits used). The Major number starts at 2 for the first revision with
159** the U14InitLib() function. Changes to the Major version means that we
160** have broken backwards compatibility. Minor number changes mean that we
161** have added new functionality that does not break backwards compatibility.
162** we starts at 0. Revision changes mean we have fixed something. Each index
163** returns to 0 when a higer one changes.
164*/
165#define U14LIB_MAJOR 4
166#define U14LIB_MINOR 0
167#define U14LIB_REVISION 0
168#define U14LIB_VERSION ((U14LIB_MAJOR<<24) | (U14LIB_MINOR<<16) | U14LIB_REVISION)
169
170#include <stdlib.h>
171#include <string.h>
172#include <stdio.h>
173
174#include "USE1401.H"
175
176#ifdef _IS_WINDOWS_
177#include <io.h>
178#include <windows.h>
179#pragma warning(disable: 4100) /* Disable "Unused formal parameter" warning */
180#include <assert.h>
181#include "process.h"
182
183
184#define sprintf wsprintf
185#define PATHSEP '\\'
186#define PATHSEPSTR "\\"
187#define DEFCMDPATH "\\1401\\" // default command path if all else fails
188#define MINDRIVERMAJREV 1 // minimum driver revision level we need
189#define __packed // does nothing in Windows
190
191#include "use14_ioc.h" // links to device driver stuff
192#endif
193
194#ifdef LINUX
195#include <fcntl.h>
196#include <unistd.h>
197#include <sys/ioctl.h>
198#include <errno.h>
199#include <sys/time.h>
200#include <sched.h>
201#include <libgen.h>
202#define PATHSEP '/'
203#define PATHSEPSTR "/"
204#define DEFCMDPATH "/var/1401/" // default command path if all else fails
205#define MINDRIVERMAJREV 2 // minimum driver revision level we need
206
207#include "ced_ioctl.h" // links to device driver stuff
208#endif
209
210#define MAX1401 8 // The number of 1401s that can be supported
211
212/*
213** These are the 1401 type codes returned by the driver, they are a slightly
214** odd sequence & start for reasons of compatability with the DOS driver.
215** The maximum code value is the upper limit of 1401 device types.
216*/
217#define DRIVRET_STD 4 // Codes for 1401 types matching driver values
218#define DRIVRET_U1401 5 // This table does not need extending, as
219#define DRIVRET_PLUS 6 // we can calculate values now.
220#define DRIVRET_POWER 7 // but we need all of these values still
221#define DRIVRET_MAX 26 // Maximum tolerated code - future designs
222
223/*
224** These variables store data that will be used to generate the last
225** error string. For now, a string will hold the 1401 command file name.
226*/
227static char szLastName[20]; // additional text information
228
229/*
230** Information stored per handle. NBNB, driverType and DriverVersion used to be
231** only stored once for all handles... i.e. nonsensical. This change means that
232** three U14...() calls now include handles that were previously void. We have
233** set a constructor and a destructor call for the library (see the end) to
234** initialise important structures, or call use1401_load().
235*/
236static short asDriverType[MAX1401] = {0};
237static int lLastDriverVersion = U14ERR_NO1401DRIV;
238static int lLastDriverType = U14TYPEUNKNOWN;
239static int alDriverVersion[MAX1401]; // version/type of each driver
240static int alTimeOutPeriod[MAX1401]; // timeout time in milliseconds
241static short asLastRetCode[MAX1401]; // last code from a fn call
242static short asType1401[MAX1401] = {0}; // The type of the 1401
243static BOOL abGrabbed[MAX1401] = {0}; // Flag for grabbed, set true by grab1401
244static int iAttached = 0; // counts process attaches so can let go
245
246#ifdef _IS_WINDOWS_
247/****************************************************************************
248** Windows NT Specific Variables and internal types
249****************************************************************************/
250static HANDLE aHand1401[MAX1401] = {0}; // handles for 1401s
251static HANDLE aXferEvent[MAX1401] = {0}; // transfer events for the 1401s
252static LPVOID apAreas[MAX1401][MAX_TRANSAREAS]; // Locked areas
253static DWORD auAreas[MAX1401][MAX_TRANSAREAS]; // Size of locked areas
254static BOOL bWindows9x = FALSE; // if we are Windows 95 or better
255#ifdef _WIN64
256#define USE_NT_DIOC(ind) TRUE
257#else
258static BOOL abUseNTDIOC[MAX1401]; // Use NT-style DIOC parameters */
259#define USE_NT_DIOC(ind) abUseNTDIOC[ind]
260#endif
261
262#endif
263
264#ifdef LINUX
265static int aHand1401[MAX1401] = {0}; // handles for 1401s
266#define INVALID_HANDLE_VALUE 0 // to avoid code differences
267#endif
268
269
270/*
271** The CmdHead relates to backwards compatibility with ancient Microsoft (and Sperry!)
272** versions of BASIC, where this header was needed so we could load a command into
273** memory.
274*/
275#pragma pack(1) // pack our structure
276typedef struct CmdHead // defines header block on command
277{ // for PC commands
278 char acBasic[5]; // BASIC information - needed to align things
279 WORD wBasicSz; // size as seen by BASIC
280 WORD wCmdSize; // size of the following info
281} __packed CMDHEAD;
282#pragma pack() // back to normal
283
284/*
285** The rest of the header looks like this...
286** int iRelPnt; relocation pointer... actual start
287** char acName[8]; string holding the command name
288** BYTE bMonRev; monitor revision level
289** BYTE bCmdRev; command revision level
290*/
291
292typedef CMDHEAD *LPCMDHEAD; // pointer to a command header
293
294#define MAXSTRLEN 255 // maximum string length we use
295#define TOHOST FALSE
296#define TO1401 TRUE
297
298static short CheckHandle(short h)
299{
300 if ((h < 0) || (h >= MAX1401)) // must be legal range...
301 return U14ERR_BADHAND;
302 if (aHand1401[h] <= 0) // must be open
303 return U14ERR_BADHAND;
304 return U14ERR_NOERROR;
305}
306
307#ifdef _IS_WINDOWS_
308/****************************************************************************
309** U14Status1401 Used for functions which do not pass any data in but
310** get data back
311****************************************************************************/
312static short U14Status1401(short sHand, LONG lCode, TCSBLOCK* pBlk)
313{
314 DWORD dwBytes = 0;
315
316 if ((sHand < 0) || (sHand >= MAX1401)) /* Check parameters */
317 return U14ERR_BADHAND;
318#ifndef _WIN64
319 if (!USE_NT_DIOC(sHand))
320 { /* Windows 9x DIOC methods? */
321 if (DeviceIoControl(aHand1401[sHand], lCode, NULL, 0, pBlk,sizeof(TCSBLOCK),&dwBytes,NULL))
322 return (short)((dwBytes>=sizeof(TCSBLOCK)) ? U14ERR_NOERROR : U14ERR_DRIVCOMMS);
323 else
324 return (short)GetLastError();
325 }
326 else
327#endif
328 { /* Windows NT or USB driver */
329 PARAMBLK rWork;
330 rWork.sState = U14ERR_DRIVCOMMS;
331 if (DeviceIoControl(aHand1401[sHand], lCode, NULL, 0, &rWork,sizeof(PARAMBLK),&dwBytes,NULL) &&
332 (dwBytes >= sizeof(PARAMBLK)))
333 {
334 *pBlk = rWork.csBlock;
335 return rWork.sState;
336 }
337 }
338
339 return U14ERR_DRIVCOMMS;
340}
341
342/****************************************************************************
343** U14Control1401 Used for functions which pass data in and only expect
344** an error code back
345****************************************************************************/
346static short U14Control1401(short sHand, LONG lCode, TCSBLOCK* pBlk)
347{
348 DWORD dwBytes = 0;
349
350 if ((sHand < 0) || (sHand >= MAX1401)) /* Check parameters */
351 return U14ERR_BADHAND;
352
353#ifndef _WIN64
354 if (!USE_NT_DIOC(sHand))
355 { /* Windows 9x DIOC methods */
356 if (DeviceIoControl(aHand1401[sHand], lCode, NULL, 0, pBlk, sizeof(TCSBLOCK), &dwBytes, NULL))
357 return (short)(dwBytes >= sizeof(TCSBLOCK) ? U14ERR_NOERROR : U14ERR_DRIVCOMMS);
358 else
359 return (short)GetLastError();
360 }
361 else
362#endif
363 { /* Windows NT or later */
364 PARAMBLK rWork;
365 rWork.sState = U14ERR_DRIVCOMMS;
366 if (DeviceIoControl(aHand1401[sHand], lCode, pBlk, sizeof(TCSBLOCK), &rWork, sizeof(PARAMBLK), &dwBytes, NULL) &&
367 (dwBytes >= sizeof(PARAMBLK)))
368 return rWork.sState;
369 }
370
371 return U14ERR_DRIVCOMMS;
372}
373#endif
374
375/****************************************************************************
376** SafeTickCount
377** Gets time in approximately units of a millisecond.
378*****************************************************************************/
379static long SafeTickCount()
380{
381#ifdef _IS_WINDOWS_
382 return GetTickCount();
383#endif
384#ifdef LINUX
385 struct timeval tv;
386 gettimeofday(&tv, NULL);
387 return (tv.tv_sec*1000 + tv.tv_usec/1000);
388#endif
389}
390
391/****************************************************************************
392** A utility routine to get the command file extension for a given type
393** of 1401. We assume the type code is vaguely legal.
394****************************************************************************/
395static int ExtForType(short sType, char* szExt)
396{
397 szExt[0] = 0; /* Default return is a blank string */
398 switch (sType)
399 {
400 case U14TYPE1401: strcpy(szExt, ".CMD"); break; // Standard 1401
401 case U14TYPEPLUS: strcpy(szExt, ".GXC"); break; // 1401 plus
402 default: // All others are in a predictable sequence
403 strcpy(szExt, ".ARM");
404 szExt[3] = (char)('M' + sType - U14TYPEU1401);
405 if (szExt[3] > 'Z') // Wrap round to ARA after ARZ
406 szExt[3] = (char)(szExt[3] - 26);
407 }
408 return 0;
409}
410
411/****************************************************************************
412** U14WhenToTimeOut
413** Returns the time to time out in time units suitable for the machine
414** we are running on ie millsecs for pc/linux, or Mac/
415****************************************************************************/
416U14API(int) U14WhenToTimeOut(short hand)
417{
418 int iNow = SafeTickCount();
419 if ((hand >= 0) && (hand < MAX1401))
420 iNow += alTimeOutPeriod[hand];
421 return iNow;
422}
423
424/****************************************************************************
425** U14PassedTime
426** Returns non zero if the timed passed in has been passed 0 if not
427****************************************************************************/
428U14API(short) U14PassedTime(int lCheckTime)
429{
430 return (short)((SafeTickCount()-lCheckTime) > 0);
431}
432
433/****************************************************************************
434** TranslateString
435** Tidies up string that U14GetString returns. Converts all the commas in a
436** string to spaces. Removes terminating CR character. May do more in future.
437****************************************************************************/
438static void TranslateString(char* pStr)
439{
440 int i = 0;
441 while (pStr[i])
442 {
443 if (pStr[i] == ',')
444 pStr[i] = ' '; /* convert comma to space */
445 ++i;
446 }
447
448 if ((i > 0) && (pStr[i-1] == '\n')) /* kill terminating LF */
449 pStr[i-1] = (char)0;
450}
451
452/****************************************************************************
453** U14StrToLongs
454** Converts a string to an array of longs and returns the number of values
455****************************************************************************/
456U14API(short) U14StrToLongs(const char* pszBuff, U14LONG *palNums, short sMaxLongs)
457{
458 WORD wChInd = 0; // index into source
459 short sLgInd = 0; // index into result longs
460
461 while (pszBuff[wChInd] && // until we get to end of string...
462 (sLgInd < sMaxLongs)) // ...or filled the buffer
463 {
464 // Why not use a C Library converter?
465 switch (pszBuff[wChInd])
466 {
467 case '-':
468 case '0': case '1': case '2': case '3': case '4':
469 case '5': case '6': case '7': case '8': case '9':
470 {
471 BOOL bDone = FALSE; // true at end of number
472 int iSign = 1; // sign of number
473 long lValue = 0;
474
475 while ((!bDone) && pszBuff[wChInd])
476 {
477 switch (pszBuff[wChInd])
478 {
479 case '-':
480 iSign = -1; // swap sign
481 break;
482
483 case '0': case '1': case '2': case '3': case '4':
484 case '5': case '6': case '7': case '8': case '9':
485 lValue *= 10; // move to next digit base 10
486 lValue += ((int)pszBuff[wChInd]-(int)'0');
487 break;
488
489 default: // end of number
490 bDone = TRUE;
491 break;
492 }
493 wChInd++; // move onto next character
494 }
495 palNums[sLgInd] = lValue * iSign;
496 sLgInd++;
497 }
498 break;
499
500 default:
501 wChInd++; // look at next char
502 break;
503 }
504 }
505 return (sLgInd);
506}
507
508
509/****************************************************************************
510** U14LongsFrom1401
511** Gets the next waiting line from the 1401 and converts it longs
512** Returns the number of numbers read or an error.
513****************************************************************************/
514U14API(short) U14LongsFrom1401(short hand, U14LONG *palBuff, short sMaxLongs)
515{
516 char szWork[MAXSTRLEN];
517 short sResult = U14GetString(hand, szWork, MAXSTRLEN);/* get reply from 1401 */
518 if (sResult == U14ERR_NOERROR) /* if no error convert */
519 sResult = U14StrToLongs(szWork, palBuff, sMaxLongs);
520 return sResult;
521}
522
523/****************************************************************************
524** U14CheckErr
525** Sends the ERR command to the 1401 and gets the result. Returns 0, a
526** negative error code, or the first error value.
527****************************************************************************/
528U14API(short) U14CheckErr(short hand)
529{
530 short sResult = U14SendString(hand, ";ERR;");
531 if (sResult == U14ERR_NOERROR)
532 {
533 U14LONG er[3];
534 sResult = U14LongsFrom1401(hand, er, 3);
535 if (sResult > 0)
536 {
537 sResult = (short)er[0]; /* Either zero or an error value */
538#ifdef _DEBUG
539 if (er[0] != 0)
540 {
541 char szMsg[50];
542 sprintf(szMsg, "U14CheckErr returned %d,%d\n", er[0], er[1]);
543 OutputDebugString(szMsg);
544 }
545#endif
546 }
547 else
548 {
549 if (sResult == 0)
550 sResult = U14ERR_TIMEOUT; /* No numbers equals timeout */
551 }
552 }
553
554 return sResult;
555}
556
557/****************************************************************************
558** U14LastErrCode
559** Returns the last code from the driver. This is for Windows where all calls
560** go through the Control and Status routines, so we can save any error.
561****************************************************************************/
562U14API(short) U14LastErrCode(short hand)
563{
564 if ((hand < 0) || (hand >= MAX1401))
565 return U14ERR_BADHAND;
566 return asLastRetCode[hand];
567}
568
569/****************************************************************************
570** U14SetTimeout
571** Set the timeout period for 1401 comms in milliseconds
572****************************************************************************/
573U14API(void) U14SetTimeout(short hand, int lTimeOut)
574{
575 if ((hand < 0) || (hand >= MAX1401))
576 return;
577 alTimeOutPeriod[hand] = lTimeOut;
578}
579
580/****************************************************************************
581** U14GetTimeout
582** Get the timeout period for 1401 comms in milliseconds
583****************************************************************************/
584U14API(int) U14GetTimeout(short hand)
585{
586 if ((hand < 0) || (hand >= MAX1401))
587 return U14ERR_BADHAND;
588 return alTimeOutPeriod[hand];
589}
590
591/****************************************************************************
592** U14OutBufSpace
593** Return the space in the output buffer, or an error.
594****************************************************************************/
595U14API(short) U14OutBufSpace(short hand)
596{
597#ifdef _IS_WINDOWS_
598 TCSBLOCK csBlock;
599 short sErr = U14Status1401(hand, U14_GETOUTBUFSPACE,&csBlock);
600 if (sErr == U14ERR_NOERROR)
601 sErr = csBlock.ints[0];
602 return sErr;
603#endif
604#ifdef LINUX
605 short sErr = CheckHandle(hand);
606 return (sErr == U14ERR_NOERROR) ? CED_GetOutBufSpace(aHand1401[hand]) : sErr;
607#endif
608}
609
610
611/****************************************************************************
612** U14BaseAddr1401
613** Returns the 1401 base address or an error code. Meaningless nowadays
614****************************************************************************/
615U14API(int) U14BaseAddr1401(short hand)
616{
617#ifdef _IS_WINDOWS_
618 TCSBLOCK csBlock;
619 int iError = U14Status1401(hand, U14_GETBASEADDRESS,&csBlock);
620 if (iError == U14ERR_NOERROR)
621 iError = csBlock.longs[0];
622 return iError;
623#endif
624#ifdef LINUX
625 short sErr = CheckHandle(hand);
626 return (sErr == U14ERR_NOERROR) ? CED_GetBaseAddress(aHand1401[hand]) : sErr;
627#endif
628}
629
630/****************************************************************************
631** U14StateOf1401
632** Return error state, either NOERROR or a negative code.
633****************************************************************************/
634U14API(short) U14StateOf1401(short hand)
635{
636#ifdef _IS_WINDOWS_
637 TCSBLOCK csBlock;
638 short sErr = U14Status1401(hand, U14_STATEOF1401, &csBlock);
639 if (sErr == U14ERR_NOERROR)
640 {
641 sErr = csBlock.ints[0]; // returned 1401 state
642 if ((sErr >= DRIVRET_STD) && (sErr <= DRIVRET_MAX))
643 sErr = U14ERR_NOERROR;
644 }
645#endif
646#ifdef LINUX
647 short sErr = CheckHandle(hand);
648 if (sErr == U14ERR_NOERROR)
649 {
650 sErr = (short)CED_StateOf1401(aHand1401[hand]);
651 if ((sErr >= DRIVRET_STD) && (sErr <= DRIVRET_MAX))
652 sErr = U14ERR_NOERROR;
653 }
654#endif
655 return sErr;
656}
657
658/****************************************************************************
659** U14DriverVersion
660** Returns the driver version. Hi word is major revision, low word is minor.
661** If you pass in a silly handle (like -1), we return the version of the last
662** driver we know of (to cope with PCI and no 1401 attached).
663****************************************************************************/
664U14API(int) U14DriverVersion(short hand)
665{
666 return CheckHandle(hand) != U14ERR_NOERROR ? lLastDriverVersion : alDriverVersion[hand];
667}
668
669/****************************************************************************
670** U14DriverType
671** Returns the driver type. The type, 0=ISA/NU-Bus, 1=PCI, 2=USB, 3=HSS
672** If you pass in a silly handle (like -1), we return the type of the last
673** driver we know of (to cope with PCI and no 1401 attached).
674****************************************************************************/
675U14API(int) U14DriverType(short hand)
676{
677 return CheckHandle(hand) != U14ERR_NOERROR ? lLastDriverType : asDriverType[hand];
678}
679
680/****************************************************************************
681** U14DriverName
682** Returns the driver type as 3 character (ISA, PCI, USB or HSS))
683****************************************************************************/
684U14API(short) U14DriverName(short hand, char* pBuf, WORD wMax)
685{
686 char* pName;
687 *pBuf = 0; // Start off with a blank string
688 switch (U14DriverType(hand)) // Results according to type
689 {
690 case 0: pName = "ISA"; break;
691 case 1: pName = "PCI"; break;
692 case 2: pName = "USB"; break;
693 case 3: pName = "HSS"; break;
694 default: pName = "???"; break;
695 }
696 strncpy(pBuf, pName, wMax); // Copy the correct name to return
697
698 return U14ERR_NOERROR;
699}
700
701/****************************************************************************
702** U14BlkTransState
703** Returns 0 no transfer in progress, 1 transfer in progress or an error code
704****************************************************************************/
705U14API(short) U14BlkTransState(short hand)
706{
707#ifdef _IS_WINDOWS_
708 TCSBLOCK csBlock;
709 short sErr = U14Status1401(hand, U14_BLKTRANSSTATE, &csBlock);
710 if (sErr == U14ERR_NOERROR)
711 sErr = csBlock.ints[0];
712 return sErr;
713#endif
714#ifdef LINUX
715 short sErr = CheckHandle(hand);
716 return (sErr == U14ERR_NOERROR) ? CED_BlkTransState(aHand1401[hand]) : sErr;
717#endif
718}
719
720/****************************************************************************
721** U14Grab1401
722** Take control of the 1401 for diagnostics purposes. USB does nothing.
723****************************************************************************/
724U14API(short) U14Grab1401(short hand)
725{
726 short sErr = CheckHandle(hand);
727 if (sErr == U14ERR_NOERROR)
728 {
729#ifdef _IS_WINDOWS_
730 if (abGrabbed[hand]) // 1401 should not have been grabbed
731 sErr = U14ERR_ALREADYSET; // Error code defined for this
732 else
733 {
734 TCSBLOCK csBlock;
735 sErr = U14Control1401(hand, U14_GRAB1401, &csBlock);
736 }
737#endif
738#ifdef LINUX
739 // 1401 should not have been grabbed
740 sErr = abGrabbed[hand] ? U14ERR_ALREADYSET : CED_Grab1401(aHand1401[hand]);
741#endif
742 if (sErr == U14ERR_NOERROR)
743 abGrabbed[hand] = TRUE;
744 }
745 return sErr;
746}
747
748/****************************************************************************
749** U14Free1401
750****************************************************************************/
751U14API(short) U14Free1401(short hand)
752{
753 short sErr = CheckHandle(hand);
754 if (sErr == U14ERR_NOERROR)
755 {
756#ifdef _IS_WINDOWS_
757 if (abGrabbed[hand]) // 1401 should have been grabbed
758 {
759 TCSBLOCK csBlock;
760 sErr = U14Control1401(hand, U14_FREE1401, &csBlock);
761 }
762 else
763 sErr = U14ERR_NOTSET;
764#endif
765#ifdef LINUX
766 // 1401 should not have been grabbed
767 sErr = abGrabbed[hand] ? CED_Free1401(aHand1401[hand]) : U14ERR_NOTSET;
768#endif
769 if (sErr == U14ERR_NOERROR)
770 abGrabbed[hand] = FALSE;
771 }
772 return sErr;
773}
774
775/****************************************************************************
776** U14Peek1401
777** DESCRIPTION Cause the 1401 to do one or more peek operations.
778** If lRepeats is zero, the loop will continue until U14StopDebugLoop
779** is called. After the peek is done, use U14GetDebugData to retrieve
780** the results of the peek.
781****************************************************************************/
782U14API(short) U14Peek1401(short hand, DWORD dwAddr, int nSize, int nRepeats)
783{
784 short sErr = CheckHandle(hand);
785 if (sErr == U14ERR_NOERROR)
786 {
787 if (abGrabbed[hand]) // 1401 should have been grabbed
788 {
789#ifdef _IS_WINDOWS_
790 TCSBLOCK csBlock;
791 csBlock.longs[0] = (long)dwAddr;
792 csBlock.longs[1] = nSize;
793 csBlock.longs[2] = nRepeats;
794 sErr = U14Control1401(hand, U14_DBGPEEK, &csBlock);
795#endif
796#ifdef LINUX
797 TDBGBLOCK dbb;
798 dbb.iAddr = (int)dwAddr;
799 dbb.iWidth = nSize;
800 dbb.iRepeats = nRepeats;
801 sErr = CED_DbgPeek(aHand1401[hand], &dbb);
802#endif
803 }
804 else
805 sErr = U14ERR_NOTSET;
806 }
807 return sErr;
808}
809
810/****************************************************************************
811** U14Poke1401
812** DESCRIPTION Cause the 1401 to do one or more poke operations.
813** If lRepeats is zero, the loop will continue until U14StopDebugLoop
814** is called.
815****************************************************************************/
816U14API(short) U14Poke1401(short hand, DWORD dwAddr, DWORD dwValue,
817 int nSize, int nRepeats)
818{
819 short sErr = CheckHandle(hand);
820 if (sErr == U14ERR_NOERROR)
821 {
822 if (abGrabbed[hand]) // 1401 should have been grabbed
823 {
824#ifdef _IS_WINDOWS_
825 TCSBLOCK csBlock;
826 csBlock.longs[0] = (long)dwAddr;
827 csBlock.longs[1] = nSize;
828 csBlock.longs[2] = nRepeats;
829 csBlock.longs[3] = (long)dwValue;
830 sErr = U14Control1401(hand, U14_DBGPOKE, &csBlock);
831#endif
832#ifdef LINUX
833 TDBGBLOCK dbb;
834 dbb.iAddr = (int)dwAddr;
835 dbb.iWidth = nSize;
836 dbb.iRepeats= nRepeats;
837 dbb.iData = (int)dwValue;
838 sErr = CED_DbgPoke(aHand1401[hand], &dbb);
839#endif
840 }
841 else
842 sErr = U14ERR_NOTSET;
843 }
844 return sErr;
845}
846
847/****************************************************************************
848** U14Ramp1401
849** DESCRIPTION Cause the 1401 to loop, writing a ramp to a location.
850** If lRepeats is zero, the loop will continue until U14StopDebugLoop.
851****************************************************************************/
852U14API(short) U14Ramp1401(short hand, DWORD dwAddr, DWORD dwDef, DWORD dwEnable,
853 int nSize, int nRepeats)
854{
855 short sErr = CheckHandle(hand);
856 if (sErr == U14ERR_NOERROR)
857 {
858 if (abGrabbed[hand]) // 1401 should have been grabbed
859 {
860#ifdef _IS_WINDOWS_
861 TCSBLOCK csBlock;
862 csBlock.longs[0] = (long)dwAddr;
863 csBlock.longs[1] = (long)dwDef;
864 csBlock.longs[2] = (long)dwEnable;
865 csBlock.longs[3] = nSize;
866 csBlock.longs[4] = nRepeats;
867 sErr = U14Control1401(hand, U14_DBGRAMPDATA, &csBlock);
868#endif
869#ifdef LINUX
870 TDBGBLOCK dbb;
871 dbb.iAddr = (int)dwAddr;
872 dbb.iDefault = (int)dwDef;
873 dbb.iMask = (int)dwEnable;
874 dbb.iWidth = nSize;
875 dbb.iRepeats = nRepeats;
876 sErr = CED_DbgRampAddr(aHand1401[hand], &dbb);
877#endif
878 }
879 else
880 sErr = U14ERR_NOTSET;
881 }
882 return sErr;
883}
884
885/****************************************************************************
886** U14RampAddr
887** DESCRIPTION Cause the 1401 to loop, reading from a ramping location.
888** If lRepeats is zero, the loop will continue until U14StopDebugLoop
889****************************************************************************/
890U14API(short) U14RampAddr(short hand, DWORD dwDef, DWORD dwEnable,
891 int nSize, int nRepeats)
892{
893 short sErr = CheckHandle(hand);
894 if (sErr == U14ERR_NOERROR)
895 {
896 if (abGrabbed[hand]) // 1401 should have been grabbed
897 {
898#ifdef _IS_WINDOWS_
899 TCSBLOCK csBlock;
900 csBlock.longs[0] = (long)dwDef;
901 csBlock.longs[1] = (long)dwEnable;
902 csBlock.longs[2] = nSize;
903 csBlock.longs[3] = nRepeats;
904 sErr = U14Control1401(hand, U14_DBGRAMPADDR, &csBlock);
905#endif
906#ifdef LINUX
907 TDBGBLOCK dbb;
908 dbb.iDefault = (int)dwDef;
909 dbb.iMask = (int)dwEnable;
910 dbb.iWidth = nSize;
911 dbb.iRepeats = nRepeats;
912 sErr = CED_DbgRampAddr(aHand1401[hand], &dbb);
913#endif
914 }
915 else
916 sErr = U14ERR_NOTSET;
917 }
918 return sErr;
919}
920
921/****************************************************************************
922** U14StopDebugLoop
923** DESCRIPTION Stops a peek\poke\ramp that, with repeats set to zero,
924** will otherwise continue forever.
925****************************************************************************/
926U14API(short) U14StopDebugLoop(short hand)
927{
928 short sErr = CheckHandle(hand);
929 if (sErr == U14ERR_NOERROR)
930#ifdef _IS_WINDOWS_
931 {
932 if (abGrabbed[hand]) // 1401 should have been grabbed
933 {
934 TCSBLOCK csBlock;
935 sErr = U14Control1401(hand, U14_DBGSTOPLOOP, &csBlock);
936 }
937 else
938 sErr = U14ERR_NOTSET;
939 }
940#endif
941#ifdef LINUX
942 sErr = abGrabbed[hand] ? CED_DbgStopLoop(aHand1401[hand]) : U14ERR_NOTSET;
943#endif
944 return sErr;
945}
946
947/****************************************************************************
948** U14GetDebugData
949** DESCRIPTION Returns the result from a previous peek operation.
950****************************************************************************/
951U14API(short) U14GetDebugData(short hand, U14LONG* plValue)
952{
953 short sErr = CheckHandle(hand);
954 if (sErr == U14ERR_NOERROR)
955 {
956 if (abGrabbed[hand]) // 1401 should have been grabbed
957 {
958#ifdef _IS_WINDOWS_
959 TCSBLOCK csBlock;
960 sErr = U14Status1401(hand, U14_DBGGETDATA, &csBlock);
961 if (sErr == U14ERR_NOERROR)
962 *plValue = csBlock.longs[0]; // Return the data
963#endif
964#ifdef LINUX
965 TDBGBLOCK dbb;
966 sErr = CED_DbgGetData(aHand1401[hand], &dbb);
967 if (sErr == U14ERR_NOERROR)
968 *plValue = dbb.iData; /* Return the data */
969#endif
970 }
971 else
972 sErr = U14ERR_NOTSET;
973 }
974 return sErr;
975}
976
977/****************************************************************************
978** U14StartSelfTest
979****************************************************************************/
980U14API(short) U14StartSelfTest(short hand)
981{
982#ifdef _IS_WINDOWS_
983 TCSBLOCK csBlock;
984 return U14Control1401(hand, U14_STARTSELFTEST, &csBlock);
985#endif
986#ifdef LINUX
987 short sErr = CheckHandle(hand);
988 return (sErr == U14ERR_NOERROR) ? CED_StartSelfTest(aHand1401[hand]) : sErr;
989#endif
990}
991
992/****************************************************************************
993** U14CheckSelfTest
994****************************************************************************/
995U14API(short) U14CheckSelfTest(short hand, U14LONG *pData)
996{
997#ifdef _IS_WINDOWS_
998 TCSBLOCK csBlock;
999 short sErr = U14Status1401(hand, U14_CHECKSELFTEST, &csBlock);
1000 if (sErr == U14ERR_NOERROR)
1001 {
1002 pData[0] = csBlock.longs[0]; /* Return the results to user */
1003 pData[1] = csBlock.longs[1];
1004 pData[2] = csBlock.longs[2];
1005 }
1006#endif
1007#ifdef LINUX
1008 short sErr = CheckHandle(hand);
1009 if (sErr == U14ERR_NOERROR) /* Check parameters */
1010 {
1011 TGET_SELFTEST gst;
1012 sErr = CED_CheckSelfTest(aHand1401[hand], &gst);
1013 if (sErr == U14ERR_NOERROR)
1014 {
1015 pData[0] = gst.code; /* Return the results to user */
1016 pData[1] = gst.x;
1017 pData[2] = gst.y;
1018 }
1019 }
1020#endif
1021 return sErr;
1022}
1023
1024/****************************************************************************
1025** U14GetUserMemorySize
1026****************************************************************************/
1027U14API(short) U14GetUserMemorySize(short hand, DWORD *pMemorySize)
1028{
1029 // The original 1401 used a different command for getting the size
1030 short sErr = U14SendString(hand, (asType1401[hand] == U14TYPE1401) ? "MEMTOP;" : "MEMTOP,?;");
1031 *pMemorySize = 0; /* if we get error then leave size set at 0 */
1032 if (sErr == U14ERR_NOERROR)
1033 {
1034 U14LONG alLimits[4];
1035 sErr = U14LongsFrom1401(hand, alLimits, 4);
1036 if (sErr > 0) /* +ve sErr is the number of values read */
1037 {
1038 sErr = U14ERR_NOERROR; /* All OK, flag success */
1039 if (asType1401[hand] == U14TYPE1401) /* result for standard */
1040 *pMemorySize = alLimits[0] - alLimits[1]; /* memtop-membot */
1041 else
1042 *pMemorySize = alLimits[0]; /* result for plus or u1401 */
1043 }
1044 }
1045 return sErr;
1046}
1047
1048/****************************************************************************
1049** U14TypeOf1401
1050** Returns the type of the 1401, maybe unknown
1051****************************************************************************/
1052U14API(short) U14TypeOf1401(short hand)
1053{
1054 if ((hand < 0) || (hand >= MAX1401)) /* Check parameters */
1055 return U14ERR_BADHAND;
1056 else
1057 return asType1401[hand];
1058}
1059
1060/****************************************************************************
1061** U14NameOf1401
1062** Returns the type of the 1401 as a string, blank if unknown
1063****************************************************************************/
1064U14API(short) U14NameOf1401(short hand, char* pBuf, WORD wMax)
1065{
1066 short sErr = CheckHandle(hand);
1067 if (sErr == U14ERR_NOERROR)
1068 {
1069 char* pName;
1070 switch (asType1401[hand]) // Results according to type
1071 {
1072 case U14TYPE1401: pName = "Std 1401"; break;
1073 case U14TYPEPLUS: pName = "1401plus"; break;
1074 case U14TYPEU1401: pName = "micro1401"; break;
1075 case U14TYPEPOWER: pName = "Power1401"; break;
1076 case U14TYPEU14012:pName = "Micro1401 mk II"; break;
1077 case U14TYPEPOWER2:pName = "Power1401 mk II"; break;
1078 case U14TYPEU14013:pName = "Micro1401-3"; break;
1079 case U14TYPEPOWER3:pName = "Power1401-3"; break;
1080 default: pName = "Unknown";
1081 }
1082 strncpy(pBuf, pName, wMax);
1083 }
1084 return sErr;
1085}
1086
1087/****************************************************************************
1088** U14TransferFlags
1089** Returns the driver block transfer flags.
1090** Bits can be set - see U14TF_ constants in use1401.h
1091*****************************************************************************/
1092U14API(short) U14TransferFlags(short hand)
1093{
1094#ifdef _IS_WINDOWS_
1095 TCSBLOCK csBlock;
1096 short sErr = U14Status1401(hand, U14_TRANSFERFLAGS, &csBlock);
1097 return (sErr == U14ERR_NOERROR) ? (short)csBlock.ints[0] : sErr;
1098#endif
1099#ifdef LINUX
1100 short sErr = CheckHandle(hand);
1101 return (sErr == U14ERR_NOERROR) ? CED_TransferFlags(aHand1401[hand]) : sErr;
1102#endif
1103}
1104
1105/****************************************************************************
1106** GetDriverVersion
1107** Actually reads driver version from the device driver.
1108** Hi word is major revision, low word is minor revision.
1109** Assumes that hand has been checked. Also codes driver type in bits 24 up.
1110*****************************************************************************/
1111static int GetDriverVersion(short hand)
1112{
1113#ifdef _IS_WINDOWS_
1114 TCSBLOCK csBlock;
1115 int iErr = U14Status1401(hand, U14_GETDRIVERREVISION, &csBlock);
1116 if (iErr == U14ERR_NOERROR)
1117 iErr = csBlock.longs[0];
1118 return iErr;
1119#endif
1120#ifdef LINUX
1121 return CED_GetDriverRevision(aHand1401[hand]);
1122#endif
1123}
1124
1125/****************************************************************************
1126** U14MonitorRev
1127** Returns the 1401 monitor revision number.
1128** The number returned is the minor revision - the part after the
1129** decimal point - plus the major revision times 1000.
1130*****************************************************************************/
1131U14API(int) U14MonitorRev(short hand)
1132{
1133 int iRev = 0;
1134 int iErr = CheckHandle(hand);
1135 if (iErr != U14ERR_NOERROR) // Check open and in use
1136 return iErr;
1137
1138 if (asType1401[hand] >= U14TYPEPOWER2) // The Power2 onwards can give us the monitor
1139 { // revision directly for all versions
1140 iErr = U14SendString(hand, "INFO,S,28;");
1141 if (iErr == U14ERR_NOERROR)
1142 {
1143 U14LONG lVals[2]; // Read a single number being the revision
1144 iErr = U14LongsFrom1401(hand, lVals, 1);
1145 if (iErr > 0)
1146 {
1147 iErr = U14ERR_NOERROR;
1148 iRev = lVals[0]; // This is the minor part of the revision
1149 iRev += asType1401[hand] * 10000;
1150 }
1151 }
1152 }
1153 else
1154 { /* Do it the hard way for older hardware */
1155 iErr = U14SendString(hand, ";CLIST;"); /* ask for command levels */
1156 if (iErr == U14ERR_NOERROR)
1157 {
1158 while (iErr == U14ERR_NOERROR)
1159 {
1160 char wstr[50];
1161 iErr = U14GetString(hand, wstr, 45);
1162 if (iErr == U14ERR_NOERROR)
1163 {
1164 char *pstr = strstr(wstr,"RESET"); /* Is this the RESET command? */
1165 if ((pstr == wstr) && (wstr[5] == ' '))
1166 {
1167 char *pstr2;
1168 size_t l;
1169 pstr += 6; /* Move past RESET and followinmg char */
1170 l = strlen(pstr); /* The length of text remaining */
1171 while (((pstr[l-1] == ' ') || (pstr[l-1] == 13)) && (l > 0))
1172 {
1173 pstr[l-1] = 0; /* Tidy up string at the end */
1174 l--; /* by removing spaces and CRs */
1175 }
1176 pstr2 = strchr(pstr, '.'); /* Find the decimal point */
1177 if (pstr2 != NULL) /* If we found the DP */
1178 {
1179 *pstr2 = 0; /* End pstr string at DP */
1180 pstr2++; /* Now past the decimal point */
1181 iRev = atoi(pstr2); /* Get the number after point */
1182 }
1183 iRev += (atoi(pstr) * 1000); /* Add first bit * 1000 */
1184 }
1185 if ((strlen(wstr) < 3) && (wstr[0] == ' '))
1186 break; /* Spot the last line of results */
1187 }
1188 }
1189 }
1190 }
1191 if (iErr == U14ERR_NOERROR) /* Return revision if no error */
1192 iErr = iRev;
1193
1194 return iErr;
1195}
1196
1197/****************************************************************************
1198** U14TryToOpen Tries to open the 1401 number passed
1199** Note : This will succeed with NT driver even if no I/F card or
1200** 1401 switched off, so we check state and close the driver
1201** if the state is unsatisfactory in U14Open1401.
1202****************************************************************************/
1203#ifdef _IS_WINDOWS_
1204#define U14NAMEOLD "\\\\.\\CED_140%d"
1205#define U14NAMENEW "\\\\.\\CED%d"
1206static short U14TryToOpen(int n1401, long* plRetVal, short* psHandle)
1207{
1208 short sErr = U14ERR_NOERROR;
1209 HANDLE hDevice = INVALID_HANDLE_VALUE;
1210 DWORD dwErr = 0;
1211 int nFirst, nLast, nDev = 0; /* Used for the search for a 1401 */
1212 BOOL bOldName = FALSE; /* start by looking for a modern driver */
1213
1214 if (n1401 == 0) /* If we need to look for a 1401 */
1215 {
1216 nFirst = 1; /* Set the search range */
1217 nLast = MAX1401; /* through all the possible 1401s */
1218 }
1219 else
1220 nFirst = nLast = n1401; /* Otherwise just one 1401 */
1221
1222 while (hDevice == INVALID_HANDLE_VALUE) /* Loop to try for a 1401 */
1223 {
1224 for (nDev = nFirst; nDev <= nLast; nDev++)
1225 {
1226 char szDevName[40]; /* name of the device to open */
1227 sprintf(szDevName, bOldName ? U14NAMEOLD : U14NAMENEW, nDev);
1228 hDevice = CreateFile(szDevName, GENERIC_WRITE | GENERIC_READ,
1229 0, 0, /* Unshared mode does nothing as this is a device */
1230 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1231
1232 if (hDevice != INVALID_HANDLE_VALUE)/* Check 1401 if opened */
1233 {
1234 TCSBLOCK csBlock;
1235 assert(aHand1401[nDev-1] == INVALID_HANDLE_VALUE); // assert if already open
1236 aHand1401[nDev-1] = hDevice; /* Save handle for now */
1237
1238#ifndef _WIN64
1239 // Use DIOC method if not windows 9x or if using new device name
1240 abUseNTDIOC[nDev-1] = (BOOL)(!bWindows9x || !bOldName);
1241#endif
1242 sErr = U14Status1401((short)(nDev-1), U14_TYPEOF1401, &csBlock);
1243 if (sErr == U14ERR_NOERROR)
1244 {
1245 *plRetVal = csBlock.ints[0];
1246 if (csBlock.ints[0] == U14ERR_INUSE)/* Prevent multi opens */
1247 {
1248 CloseHandle(hDevice); /* treat as open failure */
1249 hDevice = INVALID_HANDLE_VALUE;
1250 aHand1401[nDev-1] = INVALID_HANDLE_VALUE;
1251 sErr = U14ERR_INUSE;
1252 }
1253 else
1254 break; /* Exit from for loop on success */
1255 }
1256 else
1257 {
1258 CloseHandle(hDevice); /* Give up if func fails */
1259 hDevice = INVALID_HANDLE_VALUE;
1260 aHand1401[nDev-1] = INVALID_HANDLE_VALUE;
1261 }
1262 }
1263 else
1264 {
1265 DWORD dwe = GetLastError(); /* Get error code otherwise */
1266 if ((dwe != ERROR_FILE_NOT_FOUND) || (dwErr == 0))
1267 dwErr = dwe; /* Ignore repeats of 'not found' */
1268 }
1269 }
1270
1271 if ((hDevice == INVALID_HANDLE_VALUE) &&/* No device found, and... */
1272 (bWindows9x) && /* ...old names are allowed, and... */
1273 (bOldName == FALSE)) /* ...not tried old names yet */
1274 bOldName = TRUE; /* Set flag and go round again */
1275 else
1276 break; /* otherwise that's all folks */
1277 }
1278
1279 if (hDevice != INVALID_HANDLE_VALUE) /* If we got our device open */
1280 *psHandle = (short)(nDev-1); /* return 1401 number opened */
1281 else
1282 {
1283 if (dwErr == ERROR_FILE_NOT_FOUND) /* Sort out the error codes */
1284 sErr = U14ERR_NO1401DRIV; /* if file not found */
1285 else if (dwErr == ERROR_NOT_SUPPORTED)
1286 sErr = U14ERR_DRIVTOOOLD; /* if DIOC not supported */
1287 else if (dwErr == ERROR_ACCESS_DENIED)
1288 sErr = U14ERR_INUSE;
1289 else
1290 sErr = U14ERR_DRIVCOMMS; /* otherwise assume comms problem */
1291 }
1292 return sErr;
1293}
1294#endif
1295#ifdef LINUX
1296static short U14TryToOpen(int n1401, long* plRetVal, short* psHandle)
1297{
1298 short sErr = U14ERR_NOERROR;
1299 int fh = 0; // will be 1401 handle
1300 int iErr = 0;
1301 int nFirst, nLast, nDev = 0; // Used for the search for a 1401
1302
1303 if (n1401 == 0) // If we need to look for a 1401
1304 {
1305 nFirst = 1; /* Set the search range */
1306 nLast = MAX1401; /* through all the possible 1401s */
1307 }
1308 else
1309 nFirst = nLast = n1401; /* Otherwise just one 1401 */
1310
1311 for (nDev = nFirst; nDev <= nLast; nDev++)
1312 {
1313 char szDevName[40]; // name of the device to open
1314 sprintf(szDevName,"/dev/cedusb/%d", nDev-1);
1315 fh = open(szDevName, O_RDWR); // can only be opened once at a time
1316 if (fh > 0) // Check 1401 if opened
1317 {
1318 int iType1401 = CED_TypeOf1401(fh); // get 1401 type
1319 aHand1401[nDev-1] = fh; // Save handle for now
1320 if (iType1401 >= 0)
1321 {
1322 *plRetVal = iType1401;
1323 break; // Exit from for loop on success
1324 }
1325 else
1326 {
1327 close(fh); // Give up if func fails
1328 fh = 0;
1329 aHand1401[nDev-1] = 0;
1330 }
1331 }
1332 else
1333 {
1334 if (((errno != ENODEV) && (errno != ENOENT)) || (iErr == 0))
1335 iErr = errno; // Ignore repeats of 'not found'
1336 }
1337 }
1338
1339
1340 if (fh) // If we got our device open
1341 *psHandle = (short)(nDev-1); // return 1401 number opened
1342 else
1343 {
1344 if ((iErr == ENODEV) || (iErr == ENOENT)) // Sort out the error codes
1345 sErr = U14ERR_NO1401DRIV; // if file not found
1346 else if (iErr == EBUSY)
1347 sErr = U14ERR_INUSE;
1348 else
1349 sErr = U14ERR_DRIVCOMMS; // otherwise assume comms problem
1350 }
1351
1352 return sErr;
1353}
1354#endif
1355/****************************************************************************
1356** U14Open1401
1357** Tries to get the 1401 for use by this application
1358*****************************************************************************/
1359U14API(short) U14Open1401(short n1401)
1360{
1361 long lRetVal = -1;
1362 short sErr;
1363 short hand = 0;
1364
1365 if ((n1401 < 0) || (n1401 > MAX1401)) // must check the 1401 number
1366 return U14ERR_BAD1401NUM;
1367
1368 szLastName[0] = 0; /* initialise the error info string */
1369
1370 sErr = U14TryToOpen(n1401, &lRetVal, &hand);
1371 if (sErr == U14ERR_NOERROR)
1372 {
1373 long lDriverVersion = GetDriverVersion(hand); /* get driver revision */
1374 long lDriverRev = -1;
1375 if (lDriverVersion >= 0) /* can use it if all OK */
1376 {
1377 lLastDriverType = (lDriverVersion >> 24) & 0x000000FF;
1378 asDriverType[hand] = (short)lLastDriverType; /* Drv type */
1379 lLastDriverVersion = lDriverVersion & 0x00FFFFFF;
1380 alDriverVersion[hand] = lLastDriverVersion; /* Actual version */
1381 lDriverRev = ((lDriverVersion>>16) & 0x00FF); /* use hi word */
1382 }
1383 else
1384 {
1385 U14Close1401(hand); /* If there is a problem we should close */
1386 return (short)lDriverVersion; /* and return the error code */
1387 }
1388
1389 if (lDriverRev < MINDRIVERMAJREV) /* late enough version? */
1390 {
1391 U14Close1401(hand); /* If there is a problem we should close */
1392 return U14ERR_DRIVTOOOLD; /* too old */
1393 }
1394
1395 asLastRetCode[hand] = U14ERR_NOERROR; /* Initialise this 1401s info */
1396 abGrabbed[hand] = FALSE; /* we are not in single step mode */
1397 U14SetTimeout(hand, 3000); /* set 3 seconds as default timeout */
1398
1399 switch (lRetVal)
1400 {
1401 case DRIVRET_STD: asType1401[hand] = U14TYPE1401; break; /* Some we do by hand */
1402 case DRIVRET_U1401:asType1401[hand] = U14TYPEU1401; break;
1403 case DRIVRET_PLUS: asType1401[hand] = U14TYPEPLUS; break;
1404 default: // For the power upwards, we can calculate the codes
1405 if ((lRetVal >= DRIVRET_POWER) && (lRetVal <= DRIVRET_MAX))
1406 asType1401[hand] = (short)(lRetVal - (DRIVRET_POWER - U14TYPEPOWER));
1407 else
1408 asType1401[hand] = U14TYPEUNKNOWN;
1409 break;
1410 }
1411 U14KillIO1401(hand); /* resets the 1401 buffers */
1412
1413 if (asType1401[hand] != U14TYPEUNKNOWN) /* If all seems OK so far */
1414 {
1415 sErr = U14CheckErr(hand); /* we can check 1401 comms now */
1416 if (sErr != 0) /* If this failed to go OK */
1417 U14Reset1401(hand); /* Reset the 1401 to try to sort it out */
1418 }
1419
1420 sErr = U14StateOf1401(hand);/* Get the state of the 1401 for return */
1421 if (sErr == U14ERR_NOERROR)
1422 sErr = hand; /* return the handle if no problem */
1423 else
1424 U14Close1401(hand); /* If there is a problem we should close */
1425 }
1426
1427 return sErr;
1428}
1429
1430
1431/****************************************************************************
1432** U14Close1401
1433** Closes the 1401 so someone else can use it.
1434****************************************************************************/
1435U14API(short) U14Close1401(short hand)
1436{
1437 int j;
1438 int iAreaMask = 0; // Mask for active areas
1439 short sErr = CheckHandle(hand);
1440 if (sErr != U14ERR_NOERROR) // Check open and in use
1441 return sErr;
1442
1443 for (j = 0; j<MAX_TRANSAREAS; ++j)
1444 {
1445 TGET_TX_BLOCK gtb;
1446 int iReturn = U14GetTransfer(hand, &gtb); // get area information
1447 if (iReturn == U14ERR_NOERROR) // ignore if any problem
1448 if (gtb.used)
1449 iAreaMask |= (1 << j); // set a bit for each used area
1450 }
1451
1452 if (iAreaMask) // if any areas are in use
1453 {
1454 U14Reset1401(hand); // in case an active transfer running
1455 for (j = 0; j < MAX_TRANSAREAS; ++j) // Locate locked areas
1456 if (iAreaMask & (1 << j)) // And kill off any transfers
1457 U14UnSetTransfer(hand, (WORD)j);
1458 }
1459
1460#ifdef _IS_WINDOWS_
1461 if (aXferEvent[hand]) // if this 1401 has an open event handle
1462 {
1463 CloseHandle(aXferEvent[hand]); // close down the handle
1464 aXferEvent[hand] = NULL; // and mark it as gone
1465 }
1466
1467 if (CloseHandle(aHand1401[hand]))
1468#endif
1469#ifdef LINUX
1470 if (close(aHand1401[hand]) == 0) // make sure that close works
1471#endif
1472 {
1473 aHand1401[hand] = INVALID_HANDLE_VALUE;
1474 asType1401[hand] = U14TYPEUNKNOWN;
1475 return U14ERR_NOERROR;
1476 }
1477 else
1478 return U14ERR_BADHAND; /* BUGBUG GetLastError() ? */
1479}
1480
1481/**************************************************************************
1482**
1483** Look for open 1401s and attempt to close them down. 32-bit windows only.
1484**************************************************************************/
1485U14API(void) U14CloseAll(void)
1486{
1487 int i;
1488 for (i = 0; i < MAX1401; i++) // Tidy up and make safe
1489 if (aHand1401[i] != INVALID_HANDLE_VALUE)
1490 U14Close1401((short)i); // Last ditch close 1401
1491}
1492
1493/****************************************************************************
1494** U14Reset1401
1495** Resets the 1401
1496****************************************************************************/
1497U14API(short) U14Reset1401(short hand)
1498{
1499#ifdef _IS_WINDOWS_
1500 TCSBLOCK csBlock;
1501 return U14Control1401(hand, U14_RESET1401, &csBlock);
1502#endif
1503#ifdef LINUX
1504 short sErr = CheckHandle(hand);
1505 return (sErr == U14ERR_NOERROR) ? CED_Reset1401(aHand1401[hand]) : sErr;
1506#endif
1507}
1508
1509/****************************************************************************
1510** U14ForceReset
1511** Sets the 1401 full reset flag, so that next call to Reset1401 will
1512** always cause a genuine reset.
1513*****************************************************************************/
1514U14API(short) U14ForceReset(short hand)
1515{
1516#ifdef _IS_WINDOWS_
1517 TCSBLOCK csBlock;
1518 return U14Control1401(hand, U14_FULLRESET, &csBlock);
1519#endif
1520#ifdef LINUX
1521 short sErr = CheckHandle(hand);
1522 return (sErr == U14ERR_NOERROR) ? CED_FullReset(aHand1401[hand]) : sErr;
1523#endif
1524}
1525
1526/****************************************************************************
1527** U14KillIO1401
1528** Removes any pending IO from the buffers.
1529*****************************************************************************/
1530U14API(short) U14KillIO1401(short hand)
1531{
1532#ifdef _IS_WINDOWS_
1533 TCSBLOCK csBlock;
1534 return U14Control1401(hand, U14_KILLIO1401, &csBlock);
1535#endif
1536#ifdef LINUX
1537 short sErr = CheckHandle(hand);
1538 return (sErr == U14ERR_NOERROR) ? CED_KillIO1401(aHand1401[hand]) : sErr;
1539#endif
1540}
1541
1542
1543/****************************************************************************
1544** U14SendString
1545** Send characters to the 1401
1546*****************************************************************************/
1547U14API(short) U14SendString(short hand, const char* pString)
1548{
1549 int nChars; // length we are sending
1550 long lTimeOutTicks; // when to time out
1551 BOOL bSpaceToSend; // space to send yet
1552 short sErr = CheckHandle(hand);
1553 if (sErr != U14ERR_NOERROR)
1554 return sErr;
1555
1556 nChars = (int)strlen(pString); // get string length we want to send
1557 if (nChars > MAXSTRLEN)
1558 return U14ERR_STRLEN; // String too long
1559
1560#ifdef _IS_WINDOWS_
1561 // To get here we must wait for the buffer to have some space
1562 lTimeOutTicks = U14WhenToTimeOut(hand);
1563 do
1564 {
1565 bSpaceToSend = (BOOL)((long)U14OutBufSpace(hand) >= nChars);
1566 }
1567 while (!bSpaceToSend && !U14PassedTime(lTimeOutTicks));
1568
1569 if (!bSpaceToSend) /* Last-ditch attempt to avoid timeout */
1570 { /* This can happen with anti-virus or network activity! */
1571 int i;
1572 for (i = 0; (i < 4) && (!bSpaceToSend); ++i)
1573 {
1574 Sleep(25); /* Give other threads a chance for a while */
1575 bSpaceToSend = (BOOL)((long)U14OutBufSpace(hand) >= nChars);
1576 }
1577 }
1578
1579 if (asLastRetCode[hand] == U14ERR_NOERROR) /* no errors? */
1580 {
1581 if (bSpaceToSend)
1582 {
1583 PARAMBLK rData;
1584 DWORD dwBytes;
1585 char tstr[MAXSTRLEN+5]; /* Buffer for chars */
1586
1587 if ((hand < 0) || (hand >= MAX1401))
1588 sErr = U14ERR_BADHAND;
1589 else
1590 {
1591 strcpy(tstr, pString); /* Into local buf */
1592#ifndef _WIN64
1593 if (!USE_NT_DIOC(hand)) /* Using WIN 95 driver access? */
1594 {
1595 int iOK = DeviceIoControl(aHand1401[hand], (DWORD)U14_SENDSTRING,
1596 NULL, 0, tstr, nChars,
1597 &dwBytes, NULL);
1598 if (iOK)
1599 sErr = (dwBytes >= (DWORD)nChars) ? U14ERR_NOERROR : U14ERR_DRIVCOMMS;
1600 else
1601 sErr = (short)GetLastError();
1602 }
1603 else
1604#endif
1605 {
1606 int iOK = DeviceIoControl(aHand1401[hand],(DWORD)U14_SENDSTRING,
1607 tstr, nChars,
1608 &rData,sizeof(PARAMBLK),&dwBytes,NULL);
1609 if (iOK && (dwBytes >= sizeof(PARAMBLK)))
1610 sErr = rData.sState;
1611 else
1612 sErr = U14ERR_DRIVCOMMS;
1613 }
1614
1615 if (sErr != U14ERR_NOERROR) // If we have had a comms error
1616 U14ForceReset(hand); // make sure we get real reset
1617 }
1618
1619 return sErr;
1620
1621 }
1622 else
1623 {
1624 U14ForceReset(hand); // make sure we get real reset
1625 return U14ERR_TIMEOUT;
1626 }
1627 }
1628 else
1629 return asLastRetCode[hand];
1630#endif
1631#ifdef LINUX
1632 // Just try to send it and see what happens!
1633 sErr = CED_SendString(aHand1401[hand], pString, nChars);
1634 if (sErr != U14ERR_NOOUT) // if any result except "no room in output"...
1635 {
1636 if (sErr != U14ERR_NOERROR) // if a problem...
1637 U14ForceReset(hand); // ...make sure we get real reset next time
1638 return sErr; // ... we are done as nothing we can do
1639 }
1640
1641 // To get here we must wait for the buffer to have some space
1642 lTimeOutTicks = U14WhenToTimeOut(hand);
1643 do
1644 {
1645 bSpaceToSend = (BOOL)((long)U14OutBufSpace(hand) >= nChars);
1646 if (!bSpaceToSend)
1647 sched_yield(); // let others have fun while we wait
1648 }
1649 while (!bSpaceToSend && !U14PassedTime(lTimeOutTicks));
1650
1651 if (asLastRetCode[hand] == U14ERR_NOERROR) /* no errors? */
1652 {
1653 if (bSpaceToSend)
1654 {
1655 sErr = CED_SendString(aHand1401[hand], pString, nChars);
1656 if (sErr != U14ERR_NOERROR) // If we have had a comms error
1657 U14ForceReset(hand); // make sure we get real reset
1658 return sErr;
1659 }
1660 else
1661 {
1662 U14ForceReset(hand); // make sure we get real reset
1663 return U14ERR_TIMEOUT;
1664 }
1665 }
1666 else
1667 return asLastRetCode[hand];
1668#endif
1669}
1670
1671/****************************************************************************
1672** U14SendChar
1673** Send character to the 1401
1674*****************************************************************************/
1675U14API(short) U14SendChar(short hand, char cChar)
1676{
1677#ifdef _IS_WINDOWS_
1678 char sz[2]=" "; // convert to a string and send
1679 sz[0] = cChar;
1680 sz[1] = 0;
1681 return(U14SendString(hand, sz)); // String routines are better
1682#endif
1683#ifdef LINUX
1684 short sErr = CheckHandle(hand);
1685 return (sErr == U14ERR_NOERROR) ? CED_SendChar(aHand1401[hand], cChar) : sErr;
1686#endif
1687}
1688
1689/****************************************************************************
1690** U14GetString
1691** Get a string from the 1401. Returns a null terminated string.
1692** The string is all the characters up to the next CR in the buffer
1693** or the end of the buffer if that comes first. This only returns text
1694** if there is a CR in the buffer. The terminating CR character is removed.
1695** wMaxLen Is the size of the buffer and must be at least 2 or an error.
1696** Returns U14ERR_NOERR if OK with the result in the string or a negative
1697** error code. Any error from the device causes us to set up for
1698** a full reset.
1699****************************************************************************/
1700U14API(short) U14GetString(short hand, char* pBuffer, WORD wMaxLen)
1701{
1702 short sErr = CheckHandle(hand);
1703 if (sErr != U14ERR_NOERROR) // If an error...
1704 return sErr; // ...bail out!
1705
1706#ifdef _IS_WINDOWS_
1707 if (wMaxLen>1) // we need space for terminating 0
1708 {
1709 BOOL bLineToGet; // true when a line to get
1710 long lTimeOutTicks = U14WhenToTimeOut(hand);
1711 do
1712 bLineToGet = (BOOL)(U14LineCount(hand) != 0);
1713 while (!bLineToGet && !U14PassedTime(lTimeOutTicks));
1714
1715 if (!bLineToGet) /* Last-ditch attempt to avoid timeout */
1716 { /* This can happen with anti-virus or network activity! */
1717 int i;
1718 for (i = 0; (i < 4) && (!bLineToGet); ++i)
1719 {
1720 Sleep(25); /* Give other threads a chance for a while */
1721 bLineToGet = (BOOL)(U14LineCount(hand) != 0);
1722 }
1723 }
1724
1725 if (bLineToGet)
1726 {
1727 if (asLastRetCode[hand] == U14ERR_NOERROR) /* all ok so far */
1728 {
1729 DWORD dwBytes = 0;
1730 *((WORD *)pBuffer) = wMaxLen; /* set up length */
1731#ifndef _WIN64
1732 if (!USE_NT_DIOC(hand)) /* Win 95 DIOC here ? */
1733 {
1734 char tstr[MAXSTRLEN+5]; /* Buffer for Win95 chars */
1735 int iOK;
1736
1737 if (wMaxLen > MAXSTRLEN) /* Truncate length */
1738 wMaxLen = MAXSTRLEN;
1739
1740 *((WORD *)tstr) = wMaxLen; /* set len */
1741
1742 iOK = DeviceIoControl(aHand1401[hand],(DWORD)U14_GETSTRING,
1743 NULL, 0, tstr, wMaxLen+sizeof(short),
1744 &dwBytes, NULL);
1745 if (iOK) /* Device IO control OK ? */
1746 {
1747 if (dwBytes >= 0) /* If driver OK */
1748 {
1749 strcpy(pBuffer, tstr);
1750 sErr = U14ERR_NOERROR;
1751 }
1752 else
1753 sErr = U14ERR_DRIVCOMMS;
1754 }
1755 else
1756 {
1757 sErr = (short)GetLastError();
1758 if (sErr > 0) /* Errors are -ve */
1759 sErr = (short)-sErr;
1760 }
1761 }
1762 else
1763#endif
1764 { /* Here for NT, the DLL must own the buffer */
1765 HANDLE hMem = GlobalAlloc(GMEM_MOVEABLE,wMaxLen+sizeof(short));
1766 if (hMem)
1767 {
1768 char* pMem = (char*)GlobalLock(hMem);
1769 if (pMem)
1770 {
1771 int iOK = DeviceIoControl(aHand1401[hand],(DWORD)U14_GETSTRING,
1772 NULL, 0, pMem, wMaxLen+sizeof(short),
1773 &dwBytes, NULL);
1774 if (iOK) /* Device IO control OK ? */
1775 {
1776 if (dwBytes >= wMaxLen)
1777 {
1778 strcpy(pBuffer, pMem+sizeof(short));
1779 sErr = *((SHORT*)pMem);
1780 }
1781 else
1782 sErr = U14ERR_DRIVCOMMS;
1783 }
1784 else
1785 sErr = U14ERR_DRIVCOMMS;
1786
1787 GlobalUnlock(hMem);
1788 }
1789 else
1790 sErr = U14ERR_OUTOFMEMORY;
1791
1792 GlobalFree(hMem);
1793 }
1794 else
1795 sErr = U14ERR_OUTOFMEMORY;
1796 }
1797
1798 if (sErr == U14ERR_NOERROR) // If all OK...
1799 TranslateString(pBuffer); // ...convert any commas to spaces
1800 else // If we have had a comms error...
1801 U14ForceReset(hand); // ...make sure we get real reset
1802
1803 }
1804 else
1805 sErr = asLastRetCode[hand];
1806 }
1807 else
1808 {
1809 sErr = U14ERR_TIMEOUT;
1810 U14ForceReset(hand); // make sure we get real reset
1811 }
1812 }
1813 else
1814 sErr = U14ERR_BUFF_SMALL;
1815 return sErr;
1816#endif
1817#ifdef LINUX
1818 if (wMaxLen>1) // we need space for terminating 0
1819 {
1820 BOOL bLineToGet; // true when a line to get
1821 long lTimeOutTicks = U14WhenToTimeOut(hand);
1822 do
1823 {
1824 bLineToGet = (BOOL)(U14LineCount(hand) != 0);
1825 if (!bLineToGet)
1826 sched_yield();
1827
1828 }
1829 while (!bLineToGet && !U14PassedTime(lTimeOutTicks));
1830
1831 if (bLineToGet)
1832 {
1833 sErr = CED_GetString(aHand1401[hand], pBuffer, wMaxLen-1); // space for terminator
1834 if (sErr >=0) // if we were OK...
1835 {
1836 if (sErr >= wMaxLen) // this should NOT happen unless
1837 sErr = U14ERR_DRIVCOMMS; // ...driver Comms are very bad
1838 else
1839 {
1840 pBuffer[sErr] = 0; // OK, so terminate the string...
1841 TranslateString(pBuffer); // ...and convert commas to spaces.
1842 }
1843 }
1844
1845 if (sErr < U14ERR_NOERROR) // If we have had a comms error
1846 U14ForceReset(hand); // make sure we get real reset
1847 }
1848 else
1849 {
1850 sErr = U14ERR_TIMEOUT;
1851 U14ForceReset(hand); // make sure we get real reset
1852 }
1853 }
1854 else
1855 sErr = U14ERR_BUFF_SMALL;
1856
1857 return sErr >= U14ERR_NOERROR ? U14ERR_NOERROR : sErr;
1858#endif
1859}
1860
1861/****************************************************************************
1862** U14GetChar
1863** Get a character from the 1401. CR returned as CR.
1864*****************************************************************************/
1865U14API(short) U14GetChar(short hand, char* pcChar)
1866{
1867#ifdef _IS_WINDOWS_
1868 char sz[2]; // read a very short string
1869 short sErr = U14GetString(hand, sz, 2); // read one char and nul terminate it
1870 *pcChar = sz[0]; // copy to result, NB char translate done by GetString
1871 if (sErr == U14ERR_NOERROR)
1872 { // undo translate of CR to zero
1873 if (*pcChar == '\0') // by converting back
1874 *pcChar = '\n'; // What a nasty thing to have to do
1875 }
1876 return sErr;
1877#endif
1878#ifdef LINUX
1879 short sErr = CheckHandle(hand);
1880 if (sErr != U14ERR_NOERROR) // Check parameters
1881 return sErr;
1882 sErr = CED_GetChar(aHand1401[hand]); // get one char, if available
1883 if (sErr >= 0)
1884 {
1885 *pcChar = (char)sErr; // return if it we have one
1886 return U14ERR_NOERROR; // say all OK
1887 }
1888 else
1889 return sErr;
1890#endif
1891}
1892
1893/****************************************************************************
1894** U14Stat1401
1895** Returns 0 for no lines or error or non zero for something waiting
1896****************************************************************************/
1897U14API(short) U14Stat1401(short hand)
1898{
1899 return ((short)(U14LineCount(hand) > 0));
1900}
1901
1902/****************************************************************************
1903** U14CharCount
1904** Returns the number of characters in the input buffer
1905*****************************************************************************/
1906U14API(short) U14CharCount(short hand)
1907{
1908#ifdef _IS_WINDOWS_
1909 TCSBLOCK csBlock;
1910 short sErr = U14Status1401(hand, U14_STAT1401, &csBlock);
1911 if (sErr == U14ERR_NOERROR)
1912 sErr = csBlock.ints[0];
1913 return sErr;
1914#endif
1915#ifdef LINUX
1916 short sErr = CheckHandle(hand);
1917 return (sErr == U14ERR_NOERROR) ? CED_Stat1401(aHand1401[hand]) : sErr;
1918#endif
1919}
1920
1921/****************************************************************************
1922** U14LineCount
1923** Returns the number of CR characters in the input buffer
1924*****************************************************************************/
1925U14API(short) U14LineCount(short hand)
1926{
1927#ifdef _IS_WINDOWS_
1928 TCSBLOCK csBlock;
1929 short sErr = U14Status1401(hand, U14_LINECOUNT, &csBlock);
1930 if (sErr == U14ERR_NOERROR)
1931 sErr = csBlock.ints[0];
1932 return sErr;
1933#endif
1934#ifdef LINUX
1935 short sErr = CheckHandle(hand);
1936 return (sErr == U14ERR_NOERROR) ? CED_LineCount(aHand1401[hand]) : sErr;
1937#endif
1938}
1939
1940/****************************************************************************
1941** U14GetErrorString
1942** Converts error code supplied to a decent descriptive string.
1943** NOTE: This function may use some extra information stored
1944** internally in the DLL. This information is stored on a
1945** per-process basis, but it might be altered if you call
1946** other functions after getting an error and before using
1947** this function.
1948****************************************************************************/
1949U14API(void) U14GetErrorString(short nErr, char* pStr, WORD wMax)
1950{
1951 char wstr[150];
1952
1953 switch (nErr) /* Basically, we do this with a switch block */
1954 {
1955 case U14ERR_OFF:
1956 sprintf(wstr, "The 1401 is apparently switched off (code %d)", nErr);
1957 break;
1958
1959 case U14ERR_NC:
1960 sprintf(wstr, "The 1401 is not connected to the interface card (code %d)", nErr);
1961 break;
1962
1963 case U14ERR_ILL:
1964 sprintf(wstr, "The 1401 is not working correctly (code %d)", nErr);
1965 break;
1966
1967 case U14ERR_NOIF:
1968 sprintf(wstr, "The 1401 interface card was not detected (code %d)", nErr);
1969 break;
1970
1971 case U14ERR_TIME:
1972 sprintf(wstr, "The 1401 fails to become ready for use (code %d)", nErr);
1973 break;
1974
1975 case U14ERR_BADSW:
1976 sprintf(wstr, "The 1401 interface card jumpers are incorrect (code %d)", nErr);
1977 break;
1978
1979 case U14ERR_NOINT:
1980 sprintf(wstr, "The 1401 interrupt is not available for use (code %d)", nErr);
1981 break;
1982
1983 case U14ERR_INUSE:
1984 sprintf(wstr, "The 1401 is already in use by another program (code %d)", nErr);
1985 break;
1986
1987 case U14ERR_NODMA:
1988 sprintf(wstr, "The 1401 DMA channel is not available for use (code %d)", nErr);
1989 break;
1990
1991 case U14ERR_BADHAND:
1992 sprintf(wstr, "The application supplied an incorrect 1401 handle (code %d)", nErr);
1993 break;
1994
1995 case U14ERR_BAD1401NUM:
1996 sprintf(wstr, "The application used an incorrect 1401 number (code %d)", nErr);
1997 break;
1998
1999 case U14ERR_NO_SUCH_FN:
2000 sprintf(wstr, "The code passed to the 1401 driver is invalid (code %d)", nErr);
2001 break;
2002
2003 case U14ERR_NO_SUCH_SUBFN:
2004 sprintf(wstr, "The sub-code passed to the 1401 driver is invalid (code %d)", nErr);
2005 break;
2006
2007 case U14ERR_NOOUT:
2008 sprintf(wstr, "No room in buffer for characters for the 1401 (code %d)", nErr);
2009 break;
2010
2011 case U14ERR_NOIN:
2012 sprintf(wstr, "No characters from the 1401 are available (code %d)", nErr);
2013 break;
2014
2015 case U14ERR_STRLEN:
2016 sprintf(wstr, "A string sent to or read from the 1401 was too long (code %d)", nErr);
2017 break;
2018
2019 case U14ERR_LOCKFAIL:
2020 sprintf(wstr, "Failed to lock host memory for data transfer (code %d)", nErr);
2021 break;
2022
2023 case U14ERR_UNLOCKFAIL:
2024 sprintf(wstr, "Failed to unlock host memory after data transfer (code %d)", nErr);
2025 break;
2026
2027 case U14ERR_ALREADYSET:
2028 sprintf(wstr, "The transfer area used is already set up (code %d)", nErr);
2029 break;
2030
2031 case U14ERR_NOTSET:
2032 sprintf(wstr, "The transfer area used has not been set up (code %d)", nErr);
2033 break;
2034
2035 case U14ERR_BADAREA:
2036 sprintf(wstr, "The transfer area number is incorrect (code %d)", nErr);
2037 break;
2038
2039 case U14ERR_NOFILE:
2040 sprintf(wstr, "The command file %s could not be opened (code %d)", szLastName, nErr);
2041 break;
2042
2043 case U14ERR_READERR:
2044 sprintf(wstr, "The command file %s could not be read (code %d)", szLastName, nErr);
2045 break;
2046
2047 case U14ERR_UNKNOWN:
2048 sprintf(wstr, "The %s command resource could not be found (code %d)", szLastName, nErr);
2049 break;
2050
2051 case U14ERR_HOSTSPACE:
2052 sprintf(wstr, "Unable to allocate memory for loading command %s (code %d)", szLastName, nErr);
2053 break;
2054
2055 case U14ERR_LOCKERR:
2056 sprintf(wstr, "Unable to lock memory for loading command %s (code %d)", szLastName, nErr);
2057 break;
2058
2059 case U14ERR_CLOADERR:
2060 sprintf(wstr, "Error in loading command %s, bad command format (code %d)", szLastName, nErr);
2061 break;
2062
2063 case U14ERR_TOXXXERR:
2064 sprintf(wstr, "Error detected after data transfer to or from the 1401 (code %d)", nErr);
2065 break;
2066
2067 case U14ERR_NO386ENH:
2068 sprintf(wstr, "Windows 3.1 is not running in 386 enhanced mode (code %d)", nErr);
2069 break;
2070
2071 case U14ERR_NO1401DRIV:
2072 sprintf(wstr, "The 1401 device driver cannot be found (code %d)\nUSB: check plugged in and powered\nOther: not installed?", nErr);
2073 break;
2074
2075 case U14ERR_DRIVTOOOLD:
2076 sprintf(wstr, "The 1401 device driver is too old for use (code %d)", nErr);
2077 break;
2078
2079 case U14ERR_TIMEOUT:
2080 sprintf(wstr, "Character transmissions to the 1401 timed-out (code %d)", nErr);
2081 break;
2082
2083 case U14ERR_BUFF_SMALL:
2084 sprintf(wstr, "Buffer for text from the 1401 was too small (code %d)", nErr);
2085 break;
2086
2087 case U14ERR_CBALREADY:
2088 sprintf(wstr, "1401 monitor callback already set up (code %d)", nErr);
2089 break;
2090
2091 case U14ERR_BADDEREG:
2092 sprintf(wstr, "1401 monitor callback deregister invalid (code %d)", nErr);
2093 break;
2094
2095 case U14ERR_DRIVCOMMS:
2096 sprintf(wstr, "1401 device driver communications failed (code %d)", nErr);
2097 break;
2098
2099 case U14ERR_OUTOFMEMORY:
2100 sprintf(wstr, "Failed to allocate or lock memory for text from the 1401 (code %d)", nErr);
2101 break;
2102
2103 default:
2104 sprintf(wstr, "1401 error code %d returned; this code is unknown", nErr);
2105 break;
2106
2107 }
2108 if ((WORD)strlen(wstr) >= wMax-1) /* Check for string being too long */
2109 wstr[wMax-1] = 0; /* and truncate it if so */
2110 strcpy(pStr, wstr); /* Return the error string */
2111}
2112
2113/***************************************************************************
2114** U14GetTransfer
2115** Get a TGET_TX_BLOCK describing a transfer area (held in the block)
2116***************************************************************************/
2117U14API(short) U14GetTransfer(short hand, TGET_TX_BLOCK *pTransBlock)
2118{
2119 short sErr = CheckHandle(hand);
2120#ifdef _IS_WINDOWS_
2121 if (sErr == U14ERR_NOERROR)
2122 {
2123 DWORD dwBytes = 0;
2124 BOOL bOK = DeviceIoControl(aHand1401[hand], (DWORD)U14_GETTRANSFER, NULL, 0, pTransBlock,
2125 sizeof(TGET_TX_BLOCK), &dwBytes, NULL);
2126
2127 if (bOK && (dwBytes >= sizeof(TGET_TX_BLOCK)))
2128 sErr = U14ERR_NOERROR;
2129 else
2130 sErr = U14ERR_DRIVCOMMS;
2131 }
2132 return sErr;
2133#endif
2134#ifdef LINUX
2135 return (sErr == U14ERR_NOERROR) ? CED_GetTransfer(aHand1401[hand], pTransBlock) : sErr;
2136#endif
2137}
2138/////////////////////////////////////////////////////////////////////////////
2139// U14WorkingSet
2140// For Win32 only, adjusts process working set so that minimum is at least
2141// dwMinKb and maximum is at least dwMaxKb.
2142// Return value is zero if all went OK, or a code from 1 to 3 indicating the
2143// cause of the failure:
2144//
2145// 1 unable to access process (insufficient rights?)
2146// 2 unable to read process working set
2147// 3 unable to set process working set - bad parameters?
2148U14API(short) U14WorkingSet(DWORD dwMinKb, DWORD dwMaxKb)
2149{
2150#ifdef _IS_WINDOWS_
2151 short sRetVal = 0; // 0 means all is OK
2152 HANDLE hProcess;
2153 DWORD dwVer = GetVersion();
2154 if (dwVer & 0x80000000) // is this not NT?
2155 return 0; // then give up right now
2156
2157 // Now attempt to get information on working set size
2158 hProcess = OpenProcess(STANDARD_RIGHTS_REQUIRED |
2159 PROCESS_QUERY_INFORMATION |
2160 PROCESS_SET_QUOTA,
2161 FALSE, _getpid());
2162 if (hProcess)
2163 {
2164 SIZE_T dwMinSize,dwMaxSize;
2165 if (GetProcessWorkingSetSize(hProcess, &dwMinSize, &dwMaxSize))
2166 {
2167 DWORD dwMin = dwMinKb << 10; // convert from kb to bytes
2168 DWORD dwMax = dwMaxKb << 10;
2169
2170 // if we get here, we have managed to read the current size
2171 if (dwMin > dwMinSize) // need to change sizes?
2172 dwMinSize = dwMin;
2173
2174 if (dwMax > dwMaxSize)
2175 dwMaxSize = dwMax;
2176
2177 if (!SetProcessWorkingSetSize(hProcess, dwMinSize, dwMaxSize))
2178 sRetVal = 3; // failed to change size
2179 }
2180 else
2181 sRetVal = 2; // failed to read original size
2182
2183 CloseHandle(hProcess);
2184 }
2185 else
2186 sRetVal = 1; // failed to get handle
2187
2188 return sRetVal;
2189#endif
2190#ifdef LINUX
2191 if (dwMinKb | dwMaxKb)
2192 {
2193 // to stop compiler moaning
2194 }
2195 return U14ERR_NOERROR;
2196#endif
2197}
2198
2199/****************************************************************************
2200** U14UnSetTransfer Cancels a transfer area
2201** wArea The index of a block previously used in by SetTransfer
2202*****************************************************************************/
2203U14API(short) U14UnSetTransfer(short hand, WORD wArea)
2204{
2205 short sErr = CheckHandle(hand);
2206#ifdef _IS_WINDOWS_
2207 if (sErr == U14ERR_NOERROR)
2208 {
2209 TCSBLOCK csBlock;
2210 csBlock.ints[0] = (short)wArea; /* Area number into control block */
2211 sErr = U14Control1401(hand, U14_UNSETTRANSFER, &csBlock); /* Free area */
2212
2213 VirtualUnlock(apAreas[hand][wArea], auAreas[hand][wArea]);/* Unlock */
2214 apAreas[hand][wArea] = NULL; /* Clear locations */
2215 auAreas[hand][wArea] = 0;
2216 }
2217 return sErr;
2218#endif
2219#ifdef LINUX
2220 return (sErr == U14ERR_NOERROR) ? CED_UnsetTransfer(aHand1401[hand], wArea) : sErr;
2221#endif
2222}
2223
2224/****************************************************************************
2225** U14SetTransArea Sets an area up to be used for transfers
2226** WORD wArea The area number to set up
2227** void *pvBuff The address of the buffer for the data.
2228** DWORD dwLength The length of the buffer for the data
2229** short eSz The element size (used for byte swapping on the Mac)
2230****************************************************************************/
2231U14API(short) U14SetTransArea(short hand, WORD wArea, void *pvBuff,
2232 DWORD dwLength, short eSz)
2233{
2234 TRANSFERDESC td;
2235 short sErr = CheckHandle(hand);
2236 if (sErr != U14ERR_NOERROR)
2237 return sErr;
2238 if (wArea >= MAX_TRANSAREAS) // Is this a valid area number
2239 return U14ERR_BADAREA;
2240
2241#ifdef _IS_WINDOWS_
2242 assert(apAreas[hand][wArea] == NULL);
2243 assert(auAreas[hand][wArea] == 0);
2244
2245 apAreas[hand][wArea] = pvBuff; /* Save data for later */
2246 auAreas[hand][wArea] = dwLength;
2247
2248 if (!VirtualLock(pvBuff, dwLength)) /* Lock using WIN32 calls */
2249 {
2250 apAreas[hand][wArea] = NULL; /* Clear locations */
2251 auAreas[hand][wArea] = 0;
2252 return U14ERR_LOCKERR; /* VirtualLock failed */
2253 }
2254#ifndef _WIN64
2255 if (!USE_NT_DIOC(hand)) /* Use Win 9x DIOC? */
2256 {
2257 DWORD dwBytes;
2258 VXTRANSFERDESC vxDesc; /* Structure to pass to VXD */
2259 vxDesc.wArea = wArea; /* Copy across simple params */
2260 vxDesc.dwLength = dwLength;
2261
2262 // Check we are not asking an old driver for more than area 0
2263 if ((wArea != 0) && (U14DriverVersion(hand) < 0x00010002L))
2264 sErr = U14ERR_DRIVTOOOLD;
2265 else
2266 {
2267 vxDesc.dwAddrOfs = (DWORD)pvBuff; /* 32 bit offset */
2268 vxDesc.wAddrSel = 0;
2269
2270 if (DeviceIoControl(aHand1401[hand], (DWORD)U14_SETTRANSFER,
2271 pvBuff,dwLength, /* Will translate pointer */
2272 &vxDesc,sizeof(VXTRANSFERDESC),
2273 &dwBytes,NULL))
2274 {
2275 if (dwBytes >= sizeof(VXTRANSFERDESC)) /* Driver OK ? */
2276 sErr = U14ERR_NOERROR;
2277 else
2278 sErr = U14ERR_DRIVCOMMS; /* Else never got there */
2279 }
2280 else
2281 sErr = (short)GetLastError();
2282 }
2283 }
2284 else
2285#endif
2286 {
2287 PARAMBLK rWork;
2288 DWORD dwBytes;
2289 td.wArea = wArea; /* Pure NT - put data into struct */
2290 td.lpvBuff = pvBuff;
2291 td.dwLength = dwLength;
2292 td.eSize = 0; // Dummy element size
2293
2294 if (DeviceIoControl(aHand1401[hand],(DWORD)U14_SETTRANSFER,
2295 &td,sizeof(TRANSFERDESC),
2296 &rWork,sizeof(PARAMBLK),&dwBytes,NULL))
2297 {
2298 if (dwBytes >= sizeof(PARAMBLK)) // maybe error from driver?
2299 sErr = rWork.sState; // will report any error
2300 else
2301 sErr = U14ERR_DRIVCOMMS; // Else never got there
2302 }
2303 else
2304 sErr = U14ERR_DRIVCOMMS;
2305 }
2306
2307 if (sErr != U14ERR_NOERROR)
2308 {
2309 if (sErr != U14ERR_LOCKERR) // unless lock failed...
2310 VirtualUnlock(pvBuff, dwLength); // ...release the lock
2311 apAreas[hand][wArea] = NULL; // Clear locations
2312 auAreas[hand][wArea] = 0;
2313 }
2314
2315 return sErr;
2316#endif
2317#ifdef LINUX
2318 // The strange cast is so that it works in 64 and 32-bit linux as long is 64-bits
2319 // in the 64 bit version.
2320 td.lpvBuff = (long long)((unsigned long)pvBuff);
2321 td.wAreaNum = wArea;
2322 td.dwLength = dwLength;
2323 td.eSize = eSz; // Dummy element size
2324 return CED_SetTransfer(aHand1401[hand], &td);
2325#endif
2326}
2327
2328/****************************************************************************
2329** U14SetTransferEvent Sets an event for notification of application
2330** wArea The tranfer area index, from 0 to MAXAREAS-1
2331** bEvent True to create an event, false to remove it
2332** bToHost Set 0 for notification on to1401 tranfers, 1 for
2333** notification of transfers to the host PC
2334** dwStart The offset of the sub-area of interest
2335** dwLength The size of the sub-area of interest
2336**
2337** The device driver will set the event supplied to the signalled state
2338** whenever a DMA transfer to/from the specified area is completed. The
2339** transfer has to be in the direction specified by bToHost, and overlap
2340** that part of the whole transfer area specified by dwStart and dwLength.
2341** It is important that this function is called with bEvent false to release
2342** the event once 1401 activity is finished.
2343**
2344** Returns 1 if an event handle exists, 0 if all OK and no event handle or
2345** a negative code for an error.
2346****************************************************************************/
2347U14API(short) U14SetTransferEvent(short hand, WORD wArea, BOOL bEvent,
2348 BOOL bToHost, DWORD dwStart, DWORD dwLength)
2349{
2350#ifdef _IS_WINDOWS_
2351 TCSBLOCK csBlock;
2352 short sErr = U14TransferFlags(hand); // see if we can handle events
2353 if (sErr >= U14ERR_NOERROR) // check handle is OK
2354 {
2355 bEvent = bEvent && ((sErr & U14TF_NOTIFY) != 0); // remove request if we cannot do events
2356 if (wArea >= MAX_TRANSAREAS) // Check a valid area...
2357 return U14ERR_BADAREA; // ...and bail of not
2358
2359 // We can hold an event for each area, so see if we need to change the
2360 // state of the event.
2361 if ((bEvent != 0) != (aXferEvent[hand] != 0)) // change of event state?
2362 {
2363 if (bEvent) // want one and none present
2364 aXferEvent[hand] = CreateEvent(NULL, FALSE, FALSE, NULL);
2365 else
2366 {
2367 CloseHandle(aXferEvent[hand]); // clear the existing event
2368 aXferEvent[hand] = NULL; // and clear handle
2369 }
2370 }
2371
2372 // We have to store the parameters differently for 64-bit operations
2373 // because a handle is 64 bits long. The drivers know of this and
2374 // handle the information appropriately.
2375#ifdef _WIN64
2376 csBlock.longs[0] = wArea; // Pass paramaters into the driver...
2377 if (bToHost != 0) // The direction flag is held in the
2378 csBlock.longs[0] |= 0x10000; // upper word of the transfer area value
2379 *((HANDLE*)&csBlock.longs[1]) = aXferEvent[hand]; // The event handle is 64-bits
2380 csBlock.longs[3] = dwStart; // Thankfully these two remain
2381 csBlock.longs[4] = dwLength; // as unsigned 32-bit values
2382#else
2383 csBlock.longs[0] = wArea; // pass paramaters into the driver...
2384 csBlock.longs[1] = (long)aXferEvent[hand]; // ...especially the event handle
2385 csBlock.longs[2] = bToHost;
2386 csBlock.longs[3] = dwStart;
2387 csBlock.longs[4] = dwLength;
2388#endif
2389 sErr = U14Control1401(hand, U14_SETTRANSEVENT, &csBlock);
2390 if (sErr == U14ERR_NOERROR)
2391 sErr = (short)(aXferEvent[hand] != NULL); // report if we have a flag
2392 }
2393
2394 return sErr;
2395#endif
2396#ifdef LINUX
2397 TRANSFEREVENT te;
2398 short sErr = CheckHandle(hand);
2399 if (sErr != U14ERR_NOERROR)
2400 return sErr;
2401
2402 if (wArea >= MAX_TRANSAREAS) // Is this a valid area number
2403 return U14ERR_BADAREA;
2404
2405 te.wAreaNum = wArea; // copy parameters to the control block
2406 te.wFlags = bToHost ? 1 : 0; // bit 0 sets the direction
2407 te.dwStart = dwStart; // start offset of the event area
2408 te.dwLength = dwLength; // size of the event area
2409 te.iSetEvent = bEvent; // in Windows, this creates/destroys the event
2410 return CED_SetEvent(aHand1401[hand], &te);
2411#endif
2412}
2413
2414/****************************************************************************
2415** U14TestTransferEvent
2416** Would a U14WaitTransferEvent() call return immediately? return 1 if so,
2417** 0 if not or a negative code if a problem.
2418****************************************************************************/
2419U14API(int) U14TestTransferEvent(short hand, WORD wArea)
2420{
2421#ifdef _IS_WINDOWS_
2422 int iErr = CheckHandle(hand);
2423 if (iErr == U14ERR_NOERROR)
2424 {
2425 if (aXferEvent[hand]) // if a handle is set...
2426 iErr = WaitForSingleObject(aXferEvent[hand], 0) == WAIT_OBJECT_0;
2427 }
2428 return iErr;
2429#endif
2430#ifdef LINUX
2431 short sErr = CheckHandle(hand);
2432 return (sErr == U14ERR_NOERROR) ? CED_TestEvent(aHand1401[hand], wArea) : sErr;
2433#endif
2434}
2435
2436/****************************************************************************
2437** U14WaitTransferEvent
2438** Wait for a transfer event with a timeout.
2439** msTimeOut is 0 for an infinite wait, else it is the maximum time to wait
2440** in milliseconds in range 0-0x00ffffff.
2441** Returns If no event handle then return immediately. Else return 1 if
2442** timed out or 0=event, and a negative code if a problem.
2443****************************************************************************/
2444U14API(int) U14WaitTransferEvent(short hand, WORD wArea, int msTimeOut)
2445{
2446#ifdef _IS_WINDOWS_
2447 int iErr = CheckHandle(hand);
2448 if (iErr == U14ERR_NOERROR)
2449 {
2450 if (aXferEvent[hand])
2451 {
2452 if (msTimeOut == 0)
2453 msTimeOut = INFINITE;
2454 iErr = WaitForSingleObject(aXferEvent[hand], msTimeOut) != WAIT_OBJECT_0;
2455 }
2456 else
2457 iErr = TRUE; // say we timed out if no event
2458 }
2459 return iErr;
2460#endif
2461#ifdef LINUX
2462 short sErr = CheckHandle(hand);
2463 return (sErr == U14ERR_NOERROR) ? CED_WaitEvent(aHand1401[hand], wArea, msTimeOut) : sErr;
2464#endif
2465}
2466
2467/****************************************************************************
2468** U14SetCircular Sets an area up for circular DMA transfers
2469** WORD wArea The area number to set up
2470** BOOL bToHost Sets the direction of data transfer
2471** void *pvBuff The address of the buffer for the data
2472** DWORD dwLength The length of the buffer for the data
2473****************************************************************************/
2474U14API(short) U14SetCircular(short hand, WORD wArea, BOOL bToHost,
2475 void *pvBuff, DWORD dwLength)
2476{
2477 short sErr = CheckHandle(hand);
2478 if (sErr != U14ERR_NOERROR)
2479 return sErr;
2480
2481 if (wArea >= MAX_TRANSAREAS) /* Is this a valid area number */
2482 return U14ERR_BADAREA;
2483
2484 if (!bToHost) /* For now, support tohost transfers only */
2485 return U14ERR_BADAREA; /* best error code I can find */
2486#ifdef _IS_WINDOWS_
2487 assert(apAreas[hand][wArea] == NULL);
2488 assert(auAreas[hand][wArea] == 0);
2489
2490 apAreas[hand][wArea] = pvBuff; /* Save data for later */
2491 auAreas[hand][wArea] = dwLength;
2492
2493 if (!VirtualLock(pvBuff, dwLength)) /* Lock using WIN32 calls */
2494 sErr = U14ERR_LOCKERR; /* VirtualLock failed */
2495 else
2496 {
2497 PARAMBLK rWork;
2498 DWORD dwBytes;
2499 TRANSFERDESC txDesc;
2500 txDesc.wArea = wArea; /* Pure NT - put data into struct */
2501 txDesc.lpvBuff = pvBuff;
2502 txDesc.dwLength = dwLength;
2503 txDesc.eSize = (short)bToHost; /* Use this for direction flag */
2504
2505 if (DeviceIoControl(aHand1401[hand],(DWORD)U14_SETCIRCULAR,
2506 &txDesc, sizeof(TRANSFERDESC),
2507 &rWork, sizeof(PARAMBLK),&dwBytes,NULL))
2508 {
2509 if (dwBytes >= sizeof(PARAMBLK)) /* error from driver? */
2510 sErr = rWork.sState; /* No, just return driver data */
2511 else
2512 sErr = U14ERR_DRIVCOMMS; /* Else never got there */
2513 }
2514 else
2515 sErr = U14ERR_DRIVCOMMS;
2516 }
2517
2518 if (sErr != U14ERR_NOERROR)
2519 {
2520 if (sErr != U14ERR_LOCKERR)
2521 VirtualUnlock(pvBuff, dwLength); /* Release NT lock */
2522 apAreas[hand][wArea] = NULL; /* Clear locations */
2523 auAreas[hand][wArea] = 0;
2524 }
2525
2526 return sErr;
2527#endif
2528#ifdef LINUX
2529 else
2530 {
2531 TRANSFERDESC td;
2532 td.lpvBuff = (long long)((unsigned long)pvBuff);
2533 td.wAreaNum = wArea;
2534 td.dwLength = dwLength;
2535 td.eSize = (short)bToHost; /* Use this for direction flag */
2536 return CED_SetCircular(aHand1401[hand], &td);
2537 }
2538#endif
2539}
2540
2541/****************************************************************************
2542** Function GetCircBlk returns the size (& start offset) of the next
2543** available block of circular data.
2544****************************************************************************/
2545U14API(int) U14GetCircBlk(short hand, WORD wArea, DWORD *pdwOffs)
2546{
2547 int lErr = CheckHandle(hand);
2548 if (lErr != U14ERR_NOERROR)
2549 return lErr;
2550
2551 if (wArea >= MAX_TRANSAREAS) // Is this a valid area number?
2552 return U14ERR_BADAREA;
2553 else
2554 {
2555#ifdef _IS_WINDOWS_
2556 PARAMBLK rWork;
2557 TCSBLOCK csBlock;
2558 DWORD dwBytes;
2559 csBlock.longs[0] = wArea; // Area number into control block
2560 rWork.sState = U14ERR_DRIVCOMMS;
2561 if (DeviceIoControl(aHand1401[hand], (DWORD)U14_GETCIRCBLK, &csBlock, sizeof(TCSBLOCK), &rWork, sizeof(PARAMBLK), &dwBytes, NULL) &&
2562 (dwBytes >= sizeof(PARAMBLK)))
2563 lErr = rWork.sState;
2564 else
2565 lErr = U14ERR_DRIVCOMMS;
2566
2567 if (lErr == U14ERR_NOERROR) // Did everything go OK?
2568 { // Yes, we can pass the results back
2569 lErr = rWork.csBlock.longs[1]; // Return the block information
2570 *pdwOffs = rWork.csBlock.longs[0]; // Offset is first in array
2571 }
2572#endif
2573#ifdef LINUX
2574 TCIRCBLOCK cb;
2575 cb.nArea = wArea; // Area number into control block
2576 cb.dwOffset = 0;
2577 cb.dwSize = 0;
2578 lErr = CED_GetCircBlock(aHand1401[hand], &cb);
2579 if (lErr == U14ERR_NOERROR) // Did everything go OK?
2580 { // Yes, we can pass the results back
2581 lErr = cb.dwSize; // return the size
2582 *pdwOffs = cb.dwOffset; // and the offset
2583 }
2584#endif
2585 }
2586 return lErr;
2587}
2588
2589/****************************************************************************
2590** Function FreeCircBlk marks the specified area of memory as free for
2591** resuse for circular transfers and returns the size (& start
2592** offset) of the next available block of circular data.
2593****************************************************************************/
2594U14API(int) U14FreeCircBlk(short hand, WORD wArea, DWORD dwOffs, DWORD dwSize,
2595 DWORD *pdwOffs)
2596{
2597 int lErr = CheckHandle(hand);
2598 if (lErr != U14ERR_NOERROR)
2599 return lErr;
2600
2601 if (wArea < MAX_TRANSAREAS) // Is this a valid area number
2602 {
2603#ifdef _IS_WINDOWS_
2604 PARAMBLK rWork;
2605 TCSBLOCK csBlock;
2606 DWORD dwBytes;
2607 csBlock.longs[0] = wArea; // Area number into control block
2608 csBlock.longs[1] = dwOffs;
2609 csBlock.longs[2] = dwSize;
2610 rWork.sState = U14ERR_DRIVCOMMS;
2611 if (DeviceIoControl(aHand1401[hand], (DWORD)U14_FREECIRCBLK, &csBlock, sizeof(TCSBLOCK),
2612 &rWork, sizeof(PARAMBLK), &dwBytes, NULL) &&
2613 (dwBytes >= sizeof(PARAMBLK)))
2614 lErr = rWork.sState;
2615 else
2616 lErr = U14ERR_DRIVCOMMS;
2617 if (lErr == U14ERR_NOERROR) // Did everything work OK?
2618 { // Yes, we can pass the results back
2619 lErr = rWork.csBlock.longs[1]; // Return the block information
2620 *pdwOffs = rWork.csBlock.longs[0]; // Offset is first in array
2621 }
2622#endif
2623#ifdef LINUX
2624 TCIRCBLOCK cb;
2625 cb.nArea = wArea; // Area number into control block
2626 cb.dwOffset = dwOffs;
2627 cb.dwSize = dwSize;
2628
2629 lErr = CED_FreeCircBlock(aHand1401[hand], &cb);
2630 if (lErr == U14ERR_NOERROR) // Did everything work OK?
2631 { // Yes, we can pass the results back
2632 lErr = cb.dwSize; // Return the block information
2633 *pdwOffs = cb.dwOffset; // Offset is first in array
2634 }
2635#endif
2636 }
2637 else
2638 lErr = U14ERR_BADAREA;
2639
2640 return lErr;
2641}
2642
2643/****************************************************************************
2644** Transfer
2645** Transfer moves data to 1401 or to host
2646** Assumes memory is allocated and locked,
2647** which it should be to get a pointer
2648*****************************************************************************/
2649static short Transfer(short hand, BOOL bTo1401, char* pData,
2650 DWORD dwSize, DWORD dw1401, short eSz)
2651{
2652 char strcopy[MAXSTRLEN+1]; // to hold copy of work string
2653 short sResult = U14SetTransArea(hand, 0, (void *)pData, dwSize, eSz);
2654 if (sResult == U14ERR_NOERROR) // no error
2655 {
2656 sprintf(strcopy, // data offset is always 0
2657 "TO%s,$%X,$%X,0;", bTo1401 ? "1401" : "HOST", dw1401, dwSize);
2658
2659 U14SendString(hand, strcopy); // send transfer string
2660
2661 sResult = U14CheckErr(hand); // Use ERR command to check for done
2662 if (sResult > 0)
2663 sResult = U14ERR_TOXXXERR; // If a 1401 error, use this code
2664
2665 U14UnSetTransfer(hand, 0);
2666 }
2667 return sResult;
2668}
2669
2670/****************************************************************************
2671** Function ToHost transfers data into the host from the 1401
2672****************************************************************************/
2673U14API(short) U14ToHost(short hand, char* pAddrHost, DWORD dwSize,
2674 DWORD dw1401, short eSz)
2675{
2676 short sErr = CheckHandle(hand);
2677 if ((sErr == U14ERR_NOERROR) && dwSize) // TOHOST is a constant
2678 sErr = Transfer(hand, TOHOST, pAddrHost, dwSize, dw1401, eSz);
2679 return sErr;
2680}
2681
2682/****************************************************************************
2683** Function To1401 transfers data into the 1401 from the host
2684****************************************************************************/
2685U14API(short) U14To1401(short hand, const char* pAddrHost,DWORD dwSize,
2686 DWORD dw1401, short eSz)
2687{
2688 short sErr = CheckHandle(hand);
2689 if ((sErr == U14ERR_NOERROR) && dwSize) // TO1401 is a constant
2690 sErr = Transfer(hand, TO1401, (char*)pAddrHost, dwSize, dw1401, eSz);
2691 return sErr;
2692}
2693
2694/****************************************************************************
2695** Function LdCmd Loads a command from a full path or just a file
2696*****************************************************************************/
2697#ifdef _IS_WINDOWS_
2698#define file_exist(name) (_access(name, 0) != -1)
2699#define file_open(name) _lopen(name, OF_READ)
2700#define file_close(h) _lclose(h)
2701#define file_seek(h, pos) _llseek(h, pos, FILE_BEGIN)
2702#define file_read(h, buffer, size) (_lread(h, buffer, size) == size)
2703#endif
2704#ifdef LINUX
2705#define file_exist(name) (access(name, F_OK) != -1)
2706#define file_open(name) open(name, O_RDONLY)
2707#define file_close(h) close(h)
2708#define file_seek(h, pos) lseek(h, pos, SEEK_SET)
2709#define file_read(h, buffer, size) (read(h, buffer, size) == (ssize_t)size)
2710static DWORD GetModuleFileName(void* dummy, char* buffer, int max)
2711{
2712 // The following works for Linux systems with a /proc file system.
2713 char szProcPath[32];
2714 sprintf(szProcPath, "/proc/%d/exe", getpid()); // attempt to read link
2715 if (readlink(szProcPath, buffer, max) != -1)
2716 {
2717 dirname (buffer);
2718 strcat (buffer, "/");
2719 return strlen(buffer);
2720 }
2721 return 0;
2722}
2723#endif
2724
2725U14API(short) U14LdCmd(short hand, const char* command)
2726{
2727 char strcopy[MAXSTRLEN+1]; // to hold copy of work string
2728 BOOL bGotIt = FALSE; // have we found the command file?
2729 int iFHandle; // file handle of command
2730#define FNSZ 260
2731 char filnam[FNSZ]; // space to build name in
2732 char szCmd[25]; // just the command name with extension
2733
2734 short sErr = CheckHandle(hand);
2735 if (sErr != U14ERR_NOERROR)
2736 return sErr;
2737
2738 if (strchr(command, '.') != NULL) // see if we have full name
2739 {
2740 if (file_exist(command)) // If the file exists
2741 {
2742 strcpy(filnam, command); // use name as is
2743 bGotIt = TRUE; // Flag no more searching
2744 }
2745 else // not found, get file name for search
2746 {
2747 char* pStr = strrchr(command, PATHSEP); // Point to last separator
2748 if (pStr != NULL) // Check we got it
2749 {
2750 pStr++; // move past the backslash
2751 strcpy(szCmd, pStr); // copy file name as is
2752 }
2753 else
2754 strcpy(szCmd, command); // use as is
2755 }
2756 }
2757 else // File extension not supplied, so build the command file name
2758 {
2759 char szExt[8];
2760 strcpy(szCmd, command); // Build command file name
2761 ExtForType(asType1401[hand], szExt);// File extension string
2762 strcat(szCmd, szExt); // add it to the end
2763 }
2764
2765 // Next place to look is in the 1401 folder in the same place as the
2766 // application was run from.
2767 if (!bGotIt) // Still not got it?
2768 {
2769 DWORD dwLen = GetModuleFileName(NULL, filnam, FNSZ); // Get app path
2770 if (dwLen > 0) // and use it as path if found
2771 {
2772 char* pStr = strrchr(filnam, PATHSEP); // Point to last separator
2773 if (pStr != NULL)
2774 {
2775 *(++pStr) = 0; // Terminate string there
2776 if (strlen(filnam) < FNSZ-6) // make sure we have space
2777 {
2778 strcat(filnam, "1401" PATHSEPSTR); // add in 1401 subdir
2779 strcat(filnam,szCmd);
2780 bGotIt = (BOOL)file_exist(filnam); // See if file exists
2781 }
2782 }
2783 }
2784 }
2785
2786 // Next place to look is in whatever path is set by the 1401DIR environment
2787 // variable, if it exists.
2788 if (!bGotIt) // Need to do more searches?/
2789 {
2790 char* pStr = getenv("1401DIR"); // Try to find environment var
2791 if (pStr != NULL) // and use it as path if found
2792 {
2793 strcpy(filnam, pStr); // Use path in environment
2794 if (filnam[strlen(filnam)-1] != PATHSEP)// We need separator
2795 strcat(filnam, PATHSEPSTR);
2796 strcat(filnam, szCmd);
2797 bGotIt = (BOOL)file_exist(filnam); // Got this one?
2798 }
2799 }
2800
2801 // Last place to look is the default location.
2802 if (!bGotIt) // Need to do more searches?
2803 {
2804 strcpy(filnam, DEFCMDPATH); // Use default path
2805 strcat(filnam, szCmd);
2806 bGotIt = file_exist(filnam); // Got this one?
2807 }
2808
2809 iFHandle = file_open(filnam);
2810 if (iFHandle == -1)
2811 sErr = U14ERR_NOFILE;
2812 else
2813 { // first read in the header block
2814 CMDHEAD rCmdHead; // to hold the command header
2815 if (file_read(iFHandle, &rCmdHead, sizeof(CMDHEAD)))
2816 {
2817 size_t nComSize = rCmdHead.wCmdSize;
2818 char* pMem = malloc(nComSize);
2819 if (pMem != NULL)
2820 {
2821 file_seek(iFHandle, sizeof(CMDHEAD));
2822 if (file_read(iFHandle, pMem, (UINT)nComSize))
2823 {
2824 sErr = U14SetTransArea(hand, 0, (void *)pMem, (DWORD)nComSize, ESZBYTES);
2825 if (sErr == U14ERR_NOERROR)
2826 {
2827 sprintf(strcopy, "CLOAD,0,$%X;", (int)nComSize);
2828 sErr = U14SendString(hand, strcopy);
2829 if (sErr == U14ERR_NOERROR)
2830 {
2831 sErr = U14CheckErr(hand); // Use ERR to check for done
2832 if (sErr > 0)
2833 sErr = U14ERR_CLOADERR; // If an error, this code
2834 }
2835 U14UnSetTransfer(hand, 0); // release transfer area
2836 }
2837 }
2838 else
2839 sErr = U14ERR_READERR;
2840 free(pMem);
2841 }
2842 else
2843 sErr = U14ERR_HOSTSPACE; // memory allocate failed
2844 }
2845 else
2846 sErr = U14ERR_READERR;
2847
2848 file_close(iFHandle); // close the file
2849 }
2850
2851 return sErr;
2852}
2853
2854
2855/****************************************************************************
2856** Ld
2857** Loads a command into the 1401
2858** Returns NOERROR code or a long with error in lo word and index of
2859** command that failed in high word
2860****************************************************************************/
2861U14API(DWORD) U14Ld(short hand, const char* vl, const char* str)
2862{
2863 DWORD dwIndex = 0; // index to current command
2864 long lErr = U14ERR_NOERROR; // what the error was that went wrong
2865 char strcopy[MAXSTRLEN+1]; // stores unmodified str parameter
2866 char szFExt[8]; // The command file extension
2867 short sErr = CheckHandle(hand);
2868 if (sErr != U14ERR_NOERROR)
2869 return sErr;
2870
2871 ExtForType(asType1401[hand], szFExt); // File extension string
2872 strcpy(strcopy, str); // to avoid changing original
2873
2874 // now break out one command at a time and see if loaded
2875 if (*str) // if anything there
2876 {
2877 BOOL bDone = FALSE; // true when finished all commands
2878 int iLoop1 = 0; // Point at start of string for command name
2879 int iLoop2 = 0; // and at start of str parameter
2880 do // repeat until end of str
2881 {
2882 char filnam[MAXSTRLEN+1]; // filename to use
2883 char szFName[MAXSTRLEN+1]; // filename work string
2884
2885 if (!strcopy[iLoop1]) // at the end of the string?
2886 bDone = TRUE; // set the finish flag
2887
2888 if (bDone || (strcopy[iLoop1] == ',')) // end of cmd?
2889 {
2890 U14LONG er[5]; // Used to read back error results
2891 ++dwIndex; // Keep count of command number, first is 1
2892 szFName[iLoop2]=(char)0; // null terminate name of command
2893
2894 strncpy(szLastName, szFName, sizeof(szLastName)); // Save for error info
2895 szLastName[sizeof(szLastName)-1] = 0;
2896 strncat(szLastName, szFExt, sizeof(szLastName)); // with extension included
2897 szLastName[sizeof(szLastName)-1] = 0;
2898
2899 U14SendString(hand, szFName); // ask if loaded
2900 U14SendString(hand, ";ERR;"); // add err return
2901
2902 lErr = U14LongsFrom1401(hand, er, 5);
2903 if (lErr > 0)
2904 {
2905 lErr = U14ERR_NOERROR;
2906 if (er[0] == 255) // if command not loaded at all
2907 {
2908 if (vl && *vl) // if we have a path name
2909 {
2910 strcpy(filnam, vl);
2911 if (strchr("\\/:", filnam[strlen(filnam)-1]) == NULL)
2912 strcat(filnam, PATHSEPSTR); // add separator if none found
2913 strcat(filnam, szFName); // add the file name
2914 strcat(filnam, szFExt); // and extension
2915 }
2916 else
2917 strcpy(filnam, szFName); // simple name
2918
2919 lErr = U14LdCmd(hand, filnam); // load cmd
2920 if (lErr != U14ERR_NOERROR) // spot any errors
2921 bDone = TRUE; // give up if an error
2922 }
2923 }
2924 else
2925 bDone = TRUE; // give up if an error
2926
2927 iLoop2 = 0; // Reset pointer to command name string
2928 ++iLoop1; // and move on through str parameter
2929 }
2930 else
2931 szFName[iLoop2++] = strcopy[iLoop1++]; // no command end, so copy 1 char
2932 }
2933 while (!bDone);
2934 }
2935
2936 if (lErr == U14ERR_NOERROR)
2937 {
2938 szLastName[0] = 0; // No error, so clean out command name here
2939 return lErr;
2940 }
2941 else
2942 return ((dwIndex<<16) | ((DWORD)lErr & 0x0000FFFF));
2943}
2944
2945// Initialise the library (if not initialised) and return the library version
2946U14API(int) U14InitLib(void)
2947{
2948 int iRetVal = U14LIB_VERSION;
2949 if (iAttached == 0) // only do this the first time please
2950 {
2951 int i;
2952#ifdef _IS_WINDOWS_
2953 int j;
2954 DWORD dwVersion = GetVersion();
2955 bWindows9x = FALSE; // Assume not Win9x
2956
2957 if (dwVersion & 0x80000000) // if not windows NT
2958 {
2959 if ((LOBYTE(LOWORD(dwVersion)) < 4) && // if Win32s or...
2960 (HIBYTE(LOWORD(dwVersion)) < 95)) // ...below Windows 95
2961 iRetVal = 0; // We do not support this
2962 else
2963 bWindows9x = TRUE; // Flag we have Win9x
2964 }
2965#endif
2966
2967 for (i = 0; i < MAX1401; i++) // initialise the device area
2968 {
2969 aHand1401[i] = INVALID_HANDLE_VALUE; // Clear handle values
2970 asType1401[i] = U14TYPEUNKNOWN; // and 1401 type codes
2971 alTimeOutPeriod[i] = 3000; // 3 second timeouts
2972#ifdef _IS_WINDOWS_
2973#ifndef _WIN64
2974 abUseNTDIOC[i] = (BOOL)!bWindows9x;
2975#endif
2976 aXferEvent[i] = NULL; // there are no Xfer events
2977 for (j = 0; j < MAX_TRANSAREAS; j++) // Clear out locked area info
2978 {
2979 apAreas[i][j] = NULL;
2980 auAreas[i][j] = 0;
2981 }
2982#endif
2983 }
2984 }
2985 return iRetVal;
2986}
2987
2988///--------------------------------------------------------------------------------
2989/// Functions called when the library is loaded and unloaded to give us a chance to
2990/// setup the library.
2991
2992
2993#ifdef _IS_WINDOWS_
2994#ifndef U14_NOT_DLL
2995/****************************************************************************
2996** FUNCTION: DllMain(HANDLE, DWORD, LPVOID)
2997** LibMain is called by Windows when the DLL is initialized, Thread Attached,
2998** and other times. Refer to SDK documentation, as to the different ways this
2999** may be called.
3000****************************************************************************/
3001INT APIENTRY DllMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReserved)
3002{
3003 int iRetVal = 1;
3004
3005 switch (ul_reason_being_called)
3006 {
3007 case DLL_PROCESS_ATTACH:
3008 iRetVal = U14InitLib() > 0; // does nothing if iAttached != 0
3009 ++iAttached; // count times attached
3010 break;
3011
3012 case DLL_PROCESS_DETACH:
3013 if (--iAttached == 0) // last man out?
3014 U14CloseAll(); // release all open handles
3015 break;
3016 }
3017 return iRetVal;
3018
3019 UNREFERENCED_PARAMETER(lpReserved);
3020}
3021#endif
3022#endif
3023#ifdef LINUX
3024void __attribute__((constructor)) use1401_load(void)
3025{
3026 U14InitLib();
3027 ++iAttached;
3028}
3029
3030void __attribute__((destructor)) use1401_unload(void)
3031{
3032 if (--iAttached == 0) // last man out?
3033 U14CloseAll(); // release all open handles
3034}
3035#endif
drivers/staging/comedi/Kconfig+28−38
@@ -549,6 +549,23 @@ menuconfig COMEDI_PCI_DRIVERS · 548 unmodified lines
549 549
550if COMEDI_PCI_DRIVERS550if COMEDI_PCI_DRIVERS
551 551
552config COMEDI_8255_PCI
553 tristate "Generic PCI based 8255 digital i/o board support"
554 select COMEDI_8255
555 ---help---
556 Enable support for PCI based 8255 digital i/o boards. This driver
557 provides a PCI wrapper around the generic 8255 driver.
558
559 Supported boards:
560 ADlink - PCI-7224, PCI-7248, and PCI-7296
561 Measurement Computing - PCI-DIO24, PCI-DIO24H, PCI-DIO48H and
562 PCI-DIO96H
563 National Instruments - PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503,
564 PCI-6503B, PCI-6503X, and PXI-6503
565
566 To compile this driver as a module, choose M here: the module will
567 be called 8255_pci.
568
552config COMEDI_ADDI_APCI_035569config COMEDI_ADDI_APCI_035
553 tristate "ADDI-DATA APCI_035 support"570 tristate "ADDI-DATA APCI_035 support"
554 depends on VIRT_TO_BUS571 depends on VIRT_TO_BUS
@@ -676,30 +693,16 @@ config COMEDI_ADL_PCI6208 · 121 unmodified lines
676 To compile this driver as a module, choose M here: the module will be693 To compile this driver as a module, choose M here: the module will be
677 called adl_pci6208.694 called adl_pci6208.
678 695
679config COMEDI_ADL_PCI7230696config COMEDI_ADL_PCI7X3X
680 tristate "ADLink PCI-7230 digital io board support"697 tristate "ADLink PCI-723X/743X isolated digital i/o board support"
681 ---help---
682 Enable support for ADlink PCI-7230 digital io board support
683
684 To compile this driver as a module, choose M here: the module will be
685 called adl_pci7230.
686
687config COMEDI_ADL_PCI7296
688 tristate "ADLink PCI-7296 96 ch. digital io board support"
689 select COMEDI_8255
690 ---help---698 ---help---
691 Enable support for ADlink PCI-7296 96 ch. digital io board support699 Enable support for ADlink PCI-723X/743X isolated digital i/o boards.
700 Supported boards include the 32-channel PCI-7230 (16 in/16 out),
701 PCI-7233 (32 in), and PCI-7234 (32 out) as well as the 64-channel
702 PCI-7432 (32 in/32 out), PCI-7433 (64 in), and PCI-7434 (64 out).
692 703
693 To compile this driver as a module, choose M here: the module will be704 To compile this driver as a module, choose M here: the module will be
694 called adl_pci7296.705 called adl_pci7x3x.
695
696config COMEDI_ADL_PCI7432
697 tristate "ADLink PCI-7432 64 ch. isolated digital io board support"
698 ---help---
699 Enable support for ADlink PCI-7432 64 ch. isolated digital io board
700
701 To compile this driver as a module, choose M here: the module will be
702 called adl_pci7432.
703 706
704config COMEDI_ADL_PCI8164707config COMEDI_ADL_PCI8164
705 tristate "ADLink PCI-8164 4 Axes Motion Control board support"708 tristate "ADLink PCI-8164 4 Axes Motion Control board support"
@@ -935,16 +938,6 @@ config COMEDI_CB_PCIDDA · 229 unmodified lines
935 To compile this driver as a module, choose M here: the module will be938 To compile this driver as a module, choose M here: the module will be
936 called cb_pcidda.939 called cb_pcidda.
937 940
938config COMEDI_CB_PCIDIO
939 tristate "MeasurementComputing PCI-DIO series support"
940 select COMEDI_8255
941 ---help---
942 Enable support for ComputerBoards/MeasurementComputing PCI-DIO series
943 PCI-DIO24, PCI-DIO24H and PCI-DIO48H
944
945 To compile this driver as a module, choose M here: the module will be
946 called cb_pcidio.
947
948config COMEDI_CB_PCIMDAS941config COMEDI_CB_PCIMDAS
949 tristate "MeasurementComputing PCIM-DAS1602/16 support"942 tristate "MeasurementComputing PCIM-DAS1602/16 support"
950 select COMEDI_8255943 select COMEDI_8255
@@ -1039,15 +1032,12 @@ config COMEDI_NI_LABPC · 88 unmodified lines
1039 called ni_labpc.1032 called ni_labpc.
1040 1033
1041config COMEDI_NI_PCIDIO1034config COMEDI_NI_PCIDIO
1042 tristate "NI PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503 support"1035 tristate "NI PCI-DIO32HS, PCI-6533, PCI-6534 support"
1043 select COMEDI_MITE1036 select COMEDI_MITE
1044 select COMEDI_82551037 select COMEDI_8255
1045 ---help---1038 ---help---
1046 Enable support for National Instruments PCI-DIO-32HS, PXI-6533,1039 Enable support for National Instruments PCI-DIO-32HS, PXI-6533,
1047 PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X,1040 PCI-6533 and PCI-6534
1048 PXI-6503, PCI-6533 and PCI-6534
1049 The DIO-96 appears as four 8255 subdevices. See the 8255
1050 driver notes for details.
1051 1041
1052 To compile this driver as a module, choose M here: the module will be1042 To compile this driver as a module, choose M here: the module will be
1053 called ni_pcidio.1043 called ni_pcidio.
@@ -1262,8 +1252,8 @@ config COMEDI_8255 · 208 unmodified lines
1262 that has an 8255 chip. For multifunction boards, the main driver will1252 that has an 8255 chip. For multifunction boards, the main driver will
1263 configure the 8255 subdevice automatically.1253 configure the 8255 subdevice automatically.
1264 1254
1265 Note that most PCI 8255 boards do NOT work with this driver, and1255 Note that most PCI based 8255 boards use the 8255_pci driver as a
1266 need a separate driver as a wrapper.1256 wrapper around this driver.
1267 1257
1268 To compile this driver as a module, choose M here: the module will be1258 To compile this driver as a module, choose M here: the module will be
1269 called 8255.1259 called 8255.
drivers/staging/comedi/comedi.h+554−555
@@ -208,92 +208,92 @@ · 207 unmodified lines
208 208
209/* subdevice types */209/* subdevice types */
210 210
211 enum comedi_subdevice_type {211enum comedi_subdevice_type {
212 COMEDI_SUBD_UNUSED, /* unused by driver */212 COMEDI_SUBD_UNUSED, /* unused by driver */
213 COMEDI_SUBD_AI, /* analog input */213 COMEDI_SUBD_AI, /* analog input */
214 COMEDI_SUBD_AO, /* analog output */214 COMEDI_SUBD_AO, /* analog output */
215 COMEDI_SUBD_DI, /* digital input */215 COMEDI_SUBD_DI, /* digital input */
216 COMEDI_SUBD_DO, /* digital output */216 COMEDI_SUBD_DO, /* digital output */
217 COMEDI_SUBD_DIO, /* digital input/output */217 COMEDI_SUBD_DIO, /* digital input/output */
218 COMEDI_SUBD_COUNTER, /* counter */218 COMEDI_SUBD_COUNTER, /* counter */
219 COMEDI_SUBD_TIMER, /* timer */219 COMEDI_SUBD_TIMER, /* timer */
220 COMEDI_SUBD_MEMORY, /* memory, EEPROM, DPRAM */220 COMEDI_SUBD_MEMORY, /* memory, EEPROM, DPRAM */
221 COMEDI_SUBD_CALIB, /* calibration DACs */221 COMEDI_SUBD_CALIB, /* calibration DACs */
222 COMEDI_SUBD_PROC, /* processor, DSP */222 COMEDI_SUBD_PROC, /* processor, DSP */
223 COMEDI_SUBD_SERIAL, /* serial IO */223 COMEDI_SUBD_SERIAL, /* serial IO */
224 COMEDI_SUBD_PWM /* PWM */224 COMEDI_SUBD_PWM /* PWM */
225 };225};
226 226
227/* configuration instructions */227/* configuration instructions */
228 228
229 enum configuration_ids {229enum configuration_ids {
230 INSN_CONFIG_DIO_INPUT = 0,230 INSN_CONFIG_DIO_INPUT = 0,
231 INSN_CONFIG_DIO_OUTPUT = 1,231 INSN_CONFIG_DIO_OUTPUT = 1,
232 INSN_CONFIG_DIO_OPENDRAIN = 2,232 INSN_CONFIG_DIO_OPENDRAIN = 2,
233 INSN_CONFIG_ANALOG_TRIG = 16,233 INSN_CONFIG_ANALOG_TRIG = 16,
234/* INSN_CONFIG_WAVEFORM = 17, */234/* INSN_CONFIG_WAVEFORM = 17, */
235/* INSN_CONFIG_TRIG = 18, */235/* INSN_CONFIG_TRIG = 18, */
236/* INSN_CONFIG_COUNTER = 19, */236/* INSN_CONFIG_COUNTER = 19, */
237 INSN_CONFIG_ALT_SOURCE = 20,237 INSN_CONFIG_ALT_SOURCE = 20,
238 INSN_CONFIG_DIGITAL_TRIG = 21,238 INSN_CONFIG_DIGITAL_TRIG = 21,
239 INSN_CONFIG_BLOCK_SIZE = 22,239 INSN_CONFIG_BLOCK_SIZE = 22,
240 INSN_CONFIG_TIMER_1 = 23,240 INSN_CONFIG_TIMER_1 = 23,
241 INSN_CONFIG_FILTER = 24,241 INSN_CONFIG_FILTER = 24,
242 INSN_CONFIG_CHANGE_NOTIFY = 25,242 INSN_CONFIG_CHANGE_NOTIFY = 25,
243 243
244 /*ALPHA*/ INSN_CONFIG_SERIAL_CLOCK = 26,244 INSN_CONFIG_SERIAL_CLOCK = 26, /*ALPHA*/
245 INSN_CONFIG_BIDIRECTIONAL_DATA = 27,245 INSN_CONFIG_BIDIRECTIONAL_DATA = 27,
246 INSN_CONFIG_DIO_QUERY = 28,246 INSN_CONFIG_DIO_QUERY = 28,
247 INSN_CONFIG_PWM_OUTPUT = 29,247 INSN_CONFIG_PWM_OUTPUT = 29,
248 INSN_CONFIG_GET_PWM_OUTPUT = 30,248 INSN_CONFIG_GET_PWM_OUTPUT = 30,
249 INSN_CONFIG_ARM = 31,249 INSN_CONFIG_ARM = 31,
250 INSN_CONFIG_DISARM = 32,250 INSN_CONFIG_DISARM = 32,
251 INSN_CONFIG_GET_COUNTER_STATUS = 33,251 INSN_CONFIG_GET_COUNTER_STATUS = 33,
252 INSN_CONFIG_RESET = 34,252 INSN_CONFIG_RESET = 34,
253 /* Use CTR as single pulsegenerator */253 /* Use CTR as single pulsegenerator */
254 INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001,254 INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001,
255 /* Use CTR as pulsetraingenerator */255 /* Use CTR as pulsetraingenerator */
256 INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002,256 INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002,
257 /* Use the counter as encoder */257 /* Use the counter as encoder */
258 INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003,258 INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003,
259 INSN_CONFIG_SET_GATE_SRC = 2001, /* Set gate source */259 INSN_CONFIG_SET_GATE_SRC = 2001, /* Set gate source */
260 INSN_CONFIG_GET_GATE_SRC = 2002, /* Get gate source */260 INSN_CONFIG_GET_GATE_SRC = 2002, /* Get gate source */
261 /* Set master clock source */261 /* Set master clock source */
262 INSN_CONFIG_SET_CLOCK_SRC = 2003,262 INSN_CONFIG_SET_CLOCK_SRC = 2003,
263 INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */263 INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */
264 INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */264 INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */
265 /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */265 /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */
266 /* Get size in bytes of subdevice's on-board fifos used during266 /* Get size in bytes of subdevice's on-board fifos used during
267 * streaming input/output */267 * streaming input/output */
268 INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006,268 INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006,
269 INSN_CONFIG_SET_COUNTER_MODE = 4097,269 INSN_CONFIG_SET_COUNTER_MODE = 4097,
270 /* INSN_CONFIG_8254_SET_MODE is deprecated */270 /* INSN_CONFIG_8254_SET_MODE is deprecated */
271 INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE,271 INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE,
272 INSN_CONFIG_8254_READ_STATUS = 4098,272 INSN_CONFIG_8254_READ_STATUS = 4098,
273 INSN_CONFIG_SET_ROUTING = 4099,273 INSN_CONFIG_SET_ROUTING = 4099,
274 INSN_CONFIG_GET_ROUTING = 4109,274 INSN_CONFIG_GET_ROUTING = 4109,
275/* PWM */275 /* PWM */
276 INSN_CONFIG_PWM_SET_PERIOD = 5000, /* sets frequency */276 INSN_CONFIG_PWM_SET_PERIOD = 5000, /* sets frequency */
277 INSN_CONFIG_PWM_GET_PERIOD = 5001, /* gets frequency */277 INSN_CONFIG_PWM_GET_PERIOD = 5001, /* gets frequency */
278 INSN_CONFIG_GET_PWM_STATUS = 5002, /* is it running? */278 INSN_CONFIG_GET_PWM_STATUS = 5002, /* is it running? */
279 /* sets H bridge: duty cycle and sign bit for a relay at the279 /* sets H bridge: duty cycle and sign bit for a relay at the
280 * same time */280 * same time */
281 INSN_CONFIG_PWM_SET_H_BRIDGE = 5003,281 INSN_CONFIG_PWM_SET_H_BRIDGE = 5003,
282 /* gets H bridge data: duty cycle and the sign bit */282 /* gets H bridge data: duty cycle and the sign bit */
283 INSN_CONFIG_PWM_GET_H_BRIDGE = 5004283 INSN_CONFIG_PWM_GET_H_BRIDGE = 5004
284 };284};
285 285
286 enum comedi_io_direction {286enum comedi_io_direction {
287 COMEDI_INPUT = 0,287 COMEDI_INPUT = 0,
288 COMEDI_OUTPUT = 1,288 COMEDI_OUTPUT = 1,
289 COMEDI_OPENDRAIN = 2289 COMEDI_OPENDRAIN = 2
290 };290};
291 291
292 enum comedi_support_level {292enum comedi_support_level {
293 COMEDI_UNKNOWN_SUPPORT = 0,293 COMEDI_UNKNOWN_SUPPORT = 0,
294 COMEDI_SUPPORTED,294 COMEDI_SUPPORTED,
295 COMEDI_UNSUPPORTED295 COMEDI_UNSUPPORTED
296 };296};
297 297
298/* ioctls */298/* ioctls */
299 299
@@ -317,133 +317,133 @@ · 17 unmodified lines
317 317
318/* structures */318/* structures */
319 319
320 struct comedi_trig {320struct comedi_trig {
321 unsigned int subdev; /* subdevice */321 unsigned int subdev; /* subdevice */
322 unsigned int mode; /* mode */322 unsigned int mode; /* mode */
323 unsigned int flags;323 unsigned int flags;
324 unsigned int n_chan; /* number of channels */324 unsigned int n_chan; /* number of channels */
325 unsigned int *chanlist; /* channel/range list */325 unsigned int *chanlist; /* channel/range list */
326 short *data; /* data list, size depends on subd flags */326 short *data; /* data list, size depends on subd flags */
327 unsigned int n; /* number of scans */327 unsigned int n; /* number of scans */
328 unsigned int trigsrc;328 unsigned int trigsrc;
329 unsigned int trigvar;329 unsigned int trigvar;
330 unsigned int trigvar1;330 unsigned int trigvar1;
331 unsigned int data_len;331 unsigned int data_len;
332 unsigned int unused[3];332 unsigned int unused[3];
333 };333};
334 334
335 struct comedi_insn {335struct comedi_insn {
336 unsigned int insn;336 unsigned int insn;
337 unsigned int n;337 unsigned int n;
338 unsigned int __user *data;338 unsigned int __user *data;
339 unsigned int subdev;339 unsigned int subdev;
340 unsigned int chanspec;340 unsigned int chanspec;
341 unsigned int unused[3];341 unsigned int unused[3];
342 };342};
343 343
344 struct comedi_insnlist {344struct comedi_insnlist {
345 unsigned int n_insns;345 unsigned int n_insns;
346 struct comedi_insn __user *insns;346 struct comedi_insn __user *insns;
347 };347};
348 348
349 struct comedi_cmd {349struct comedi_cmd {
350 unsigned int subdev;350 unsigned int subdev;
351 unsigned int flags;351 unsigned int flags;
352 352
353 unsigned int start_src;353 unsigned int start_src;
354 unsigned int start_arg;354 unsigned int start_arg;
355 355
356 unsigned int scan_begin_src;356 unsigned int scan_begin_src;
357 unsigned int scan_begin_arg;357 unsigned int scan_begin_arg;
358 358
359 unsigned int convert_src;359 unsigned int convert_src;
360 unsigned int convert_arg;360 unsigned int convert_arg;
361 361
362 unsigned int scan_end_src;362 unsigned int scan_end_src;
363 unsigned int scan_end_arg;363 unsigned int scan_end_arg;
364 364
365 unsigned int stop_src;365 unsigned int stop_src;
366 unsigned int stop_arg;366 unsigned int stop_arg;
367 367
368 unsigned int __user *chanlist; /* channel/range list */368 unsigned int *chanlist; /* channel/range list */
369 unsigned int chanlist_len;369 unsigned int chanlist_len;
370 370
371 short __user *data; /* data list, size depends on subd flags */371 short __user *data; /* data list, size depends on subd flags */
372 unsigned int data_len;372 unsigned int data_len;
373 };373};
374 374
375 struct comedi_chaninfo {375struct comedi_chaninfo {
376 unsigned int subdev;376 unsigned int subdev;
377 unsigned int __user *maxdata_list;377 unsigned int __user *maxdata_list;
378 unsigned int __user *flaglist;378 unsigned int __user *flaglist;
379 unsigned int __user *rangelist;379 unsigned int __user *rangelist;
380 unsigned int unused[4];380 unsigned int unused[4];
381 };381};
382 382
383 struct comedi_rangeinfo {383struct comedi_rangeinfo {
384 unsigned int range_type;384 unsigned int range_type;
385 void __user *range_ptr;385 void __user *range_ptr;
386 };386};
387 387
388 struct comedi_krange {388struct comedi_krange {
389 int min; /* fixed point, multiply by 1e-6 */389 int min; /* fixed point, multiply by 1e-6 */
390 int max; /* fixed point, multiply by 1e-6 */390 int max; /* fixed point, multiply by 1e-6 */
391 unsigned int flags;391 unsigned int flags;
392 };392};
393 393
394 struct comedi_subdinfo {394struct comedi_subdinfo {
395 unsigned int type;395 unsigned int type;
396 unsigned int n_chan;396 unsigned int n_chan;
397 unsigned int subd_flags;397 unsigned int subd_flags;
398 unsigned int timer_type;398 unsigned int timer_type;
399 unsigned int len_chanlist;399 unsigned int len_chanlist;
400 unsigned int maxdata;400 unsigned int maxdata;
401 unsigned int flags; /* channel flags */401 unsigned int flags; /* channel flags */
402 unsigned int range_type; /* lookup in kernel */402 unsigned int range_type; /* lookup in kernel */
403 unsigned int settling_time_0;403 unsigned int settling_time_0;
404 /* see support_level enum for values */404 /* see support_level enum for values */
405 unsigned insn_bits_support;405 unsigned insn_bits_support;
406 unsigned int unused[8];406 unsigned int unused[8];
407 };407};
408 408
409 struct comedi_devinfo {409struct comedi_devinfo {
410 unsigned int version_code;410 unsigned int version_code;
411 unsigned int n_subdevs;411 unsigned int n_subdevs;
412 char driver_name[COMEDI_NAMELEN];412 char driver_name[COMEDI_NAMELEN];
413 char board_name[COMEDI_NAMELEN];413 char board_name[COMEDI_NAMELEN];
414 int read_subdevice;414 int read_subdevice;
415 int write_subdevice;415 int write_subdevice;
416 int unused[30];416 int unused[30];
417 };417};
418 418
419 struct comedi_devconfig {419struct comedi_devconfig {
420 char board_name[COMEDI_NAMELEN];420 char board_name[COMEDI_NAMELEN];
421 int options[COMEDI_NDEVCONFOPTS];421 int options[COMEDI_NDEVCONFOPTS];
422 };422};
423 423
424 struct comedi_bufconfig {424struct comedi_bufconfig {
425 unsigned int subdevice;425 unsigned int subdevice;
426 unsigned int flags;426 unsigned int flags;
427 427
428 unsigned int maximum_size;428 unsigned int maximum_size;
429 unsigned int size;429 unsigned int size;
430 430
431 unsigned int unused[4];431 unsigned int unused[4];
432 };432};
433 433
434 struct comedi_bufinfo {434struct comedi_bufinfo {
435 unsigned int subdevice;435 unsigned int subdevice;
436 unsigned int bytes_read;436 unsigned int bytes_read;
437 437
438 unsigned int buf_write_ptr;438 unsigned int buf_write_ptr;
439 unsigned int buf_read_ptr;439 unsigned int buf_read_ptr;
440 unsigned int buf_write_count;440 unsigned int buf_write_count;
441 unsigned int buf_read_count;441 unsigned int buf_read_count;
442 442
443 unsigned int bytes_written;443 unsigned int bytes_written;
444 444
445 unsigned int unused[4];445 unsigned int unused[4];
446 };446};
447 447
448/* range stuff */448/* range stuff */
449 449
@@ -495,306 +495,306 @@ · 45 unmodified lines
495 495
496*/496*/
497 497
498 enum i8254_mode {498enum i8254_mode {
499 I8254_MODE0 = (0 << 1), /* Interrupt on terminal count */499 I8254_MODE0 = (0 << 1), /* Interrupt on terminal count */
500 I8254_MODE1 = (1 << 1), /* Hardware retriggerable one-shot */500 I8254_MODE1 = (1 << 1), /* Hardware retriggerable one-shot */
501 I8254_MODE2 = (2 << 1), /* Rate generator */501 I8254_MODE2 = (2 << 1), /* Rate generator */
502 I8254_MODE3 = (3 << 1), /* Square wave mode */502 I8254_MODE3 = (3 << 1), /* Square wave mode */
503 I8254_MODE4 = (4 << 1), /* Software triggered strobe */503 I8254_MODE4 = (4 << 1), /* Software triggered strobe */
504 I8254_MODE5 = (5 << 1), /* Hardware triggered strobe504 I8254_MODE5 = (5 << 1), /* Hardware triggered strobe
505 * (retriggerable) */505 * (retriggerable) */
506 I8254_BCD = 1, /* use binary-coded decimal instead of binary506 I8254_BCD = 1, /* use binary-coded decimal instead of binary
507 * (pretty useless) */507 * (pretty useless) */
508 I8254_BINARY = 0508 I8254_BINARY = 0
509 };509};
510 510
511 static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel)511static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel)
512 {512{
513 if (pfi_channel < 10)513 if (pfi_channel < 10)
514 return 0x1 + pfi_channel;514 return 0x1 + pfi_channel;
515 else515 else
516 return 0xb + pfi_channel;516 return 0xb + pfi_channel;
517 }517}
518 518
519 static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel)519static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel)
520 {520{
521 if (rtsi_channel < 7)521 if (rtsi_channel < 7)
522 return 0xb + rtsi_channel;522 return 0xb + rtsi_channel;
523 else523 else
524 return 0x1b;524 return 0x1b;
525 }525}
526 526
527/* mode bits for NI general-purpose counters, set with527/* mode bits for NI general-purpose counters, set with
528 * INSN_CONFIG_SET_COUNTER_MODE */528 * INSN_CONFIG_SET_COUNTER_MODE */
529#define NI_GPCT_COUNTING_MODE_SHIFT 16529#define NI_GPCT_COUNTING_MODE_SHIFT 16
530#define NI_GPCT_INDEX_PHASE_BITSHIFT 20530#define NI_GPCT_INDEX_PHASE_BITSHIFT 20
531#define NI_GPCT_COUNTING_DIRECTION_SHIFT 24531#define NI_GPCT_COUNTING_DIRECTION_SHIFT 24
532 enum ni_gpct_mode_bits {532enum ni_gpct_mode_bits {
533 NI_GPCT_GATE_ON_BOTH_EDGES_BIT = 0x4,533 NI_GPCT_GATE_ON_BOTH_EDGES_BIT = 0x4,
534 NI_GPCT_EDGE_GATE_MODE_MASK = 0x18,534 NI_GPCT_EDGE_GATE_MODE_MASK = 0x18,
535 NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS = 0x0,535 NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS = 0x0,
536 NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS = 0x8,536 NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS = 0x8,
537 NI_GPCT_EDGE_GATE_STARTS_BITS = 0x10,537 NI_GPCT_EDGE_GATE_STARTS_BITS = 0x10,
538 NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS = 0x18,538 NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS = 0x18,
539 NI_GPCT_STOP_MODE_MASK = 0x60,539 NI_GPCT_STOP_MODE_MASK = 0x60,
540 NI_GPCT_STOP_ON_GATE_BITS = 0x00,540 NI_GPCT_STOP_ON_GATE_BITS = 0x00,
541 NI_GPCT_STOP_ON_GATE_OR_TC_BITS = 0x20,541 NI_GPCT_STOP_ON_GATE_OR_TC_BITS = 0x20,
542 NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS = 0x40,542 NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS = 0x40,
543 NI_GPCT_LOAD_B_SELECT_BIT = 0x80,543 NI_GPCT_LOAD_B_SELECT_BIT = 0x80,
544 NI_GPCT_OUTPUT_MODE_MASK = 0x300,544 NI_GPCT_OUTPUT_MODE_MASK = 0x300,
545 NI_GPCT_OUTPUT_TC_PULSE_BITS = 0x100,545 NI_GPCT_OUTPUT_TC_PULSE_BITS = 0x100,
546 NI_GPCT_OUTPUT_TC_TOGGLE_BITS = 0x200,546 NI_GPCT_OUTPUT_TC_TOGGLE_BITS = 0x200,
547 NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS = 0x300,547 NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS = 0x300,
548 NI_GPCT_HARDWARE_DISARM_MASK = 0xc00,548 NI_GPCT_HARDWARE_DISARM_MASK = 0xc00,
549 NI_GPCT_NO_HARDWARE_DISARM_BITS = 0x000,549 NI_GPCT_NO_HARDWARE_DISARM_BITS = 0x000,
550 NI_GPCT_DISARM_AT_TC_BITS = 0x400,550 NI_GPCT_DISARM_AT_TC_BITS = 0x400,
551 NI_GPCT_DISARM_AT_GATE_BITS = 0x800,551 NI_GPCT_DISARM_AT_GATE_BITS = 0x800,
552 NI_GPCT_DISARM_AT_TC_OR_GATE_BITS = 0xc00,552 NI_GPCT_DISARM_AT_TC_OR_GATE_BITS = 0xc00,
553 NI_GPCT_LOADING_ON_TC_BIT = 0x1000,553 NI_GPCT_LOADING_ON_TC_BIT = 0x1000,
554 NI_GPCT_LOADING_ON_GATE_BIT = 0x4000,554 NI_GPCT_LOADING_ON_GATE_BIT = 0x4000,
555 NI_GPCT_COUNTING_MODE_MASK = 0x7 << NI_GPCT_COUNTING_MODE_SHIFT,555 NI_GPCT_COUNTING_MODE_MASK = 0x7 << NI_GPCT_COUNTING_MODE_SHIFT,
556 NI_GPCT_COUNTING_MODE_NORMAL_BITS =556 NI_GPCT_COUNTING_MODE_NORMAL_BITS =
557 0x0 << NI_GPCT_COUNTING_MODE_SHIFT,557 0x0 << NI_GPCT_COUNTING_MODE_SHIFT,
558 NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS =558 NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS =
559 0x1 << NI_GPCT_COUNTING_MODE_SHIFT,559 0x1 << NI_GPCT_COUNTING_MODE_SHIFT,
560 NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS =560 NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS =
561 0x2 << NI_GPCT_COUNTING_MODE_SHIFT,561 0x2 << NI_GPCT_COUNTING_MODE_SHIFT,
562 NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS =562 NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS =
563 0x3 << NI_GPCT_COUNTING_MODE_SHIFT,563 0x3 << NI_GPCT_COUNTING_MODE_SHIFT,
564 NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS =564 NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS =
565 0x4 << NI_GPCT_COUNTING_MODE_SHIFT,565 0x4 << NI_GPCT_COUNTING_MODE_SHIFT,
566 NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS =566 NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS =
567 0x6 << NI_GPCT_COUNTING_MODE_SHIFT,567 0x6 << NI_GPCT_COUNTING_MODE_SHIFT,
568 NI_GPCT_INDEX_PHASE_MASK = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,568 NI_GPCT_INDEX_PHASE_MASK = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
569 NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS =569 NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS =
570 0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT,570 0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT,
571 NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS =571 NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS =
572 0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT,572 0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT,
573 NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS =573 NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS =
574 0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT,574 0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT,
575 NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS =575 NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS =
576 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,576 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
577 NI_GPCT_INDEX_ENABLE_BIT = 0x400000,577 NI_GPCT_INDEX_ENABLE_BIT = 0x400000,
578 NI_GPCT_COUNTING_DIRECTION_MASK =578 NI_GPCT_COUNTING_DIRECTION_MASK =
579 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,579 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
580 NI_GPCT_COUNTING_DIRECTION_DOWN_BITS =580 NI_GPCT_COUNTING_DIRECTION_DOWN_BITS =
581 0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT,581 0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
582 NI_GPCT_COUNTING_DIRECTION_UP_BITS =582 NI_GPCT_COUNTING_DIRECTION_UP_BITS =
583 0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT,583 0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
584 NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS =584 NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS =
585 0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT,585 0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
586 NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS =586 NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS =
587 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,587 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
588 NI_GPCT_RELOAD_SOURCE_MASK = 0xc000000,588 NI_GPCT_RELOAD_SOURCE_MASK = 0xc000000,
589 NI_GPCT_RELOAD_SOURCE_FIXED_BITS = 0x0,589 NI_GPCT_RELOAD_SOURCE_FIXED_BITS = 0x0,
590 NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS = 0x4000000,590 NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS = 0x4000000,
591 NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS = 0x8000000,591 NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS = 0x8000000,
592 NI_GPCT_OR_GATE_BIT = 0x10000000,592 NI_GPCT_OR_GATE_BIT = 0x10000000,
593 NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000593 NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000
594 };594};
595 595
596/* Bits for setting a clock source with596/* Bits for setting a clock source with
597 * INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters. */597 * INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters. */
598 enum ni_gpct_clock_source_bits {598enum ni_gpct_clock_source_bits {
599 NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f,599 NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f,
600 NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0,600 NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0,
601 NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1,601 NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1,
602 NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2,602 NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2,
603 NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3,603 NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3,
604 NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4,604 NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4,
605 NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5,605 NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5,
606 /* NI 660x-specific */606 /* NI 660x-specific */
607 NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6,607 NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6,
608 NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7,608 NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7,
609 NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8,609 NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8,
610 NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9,610 NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9,
611 NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000,611 NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000,
612 NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0,612 NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0,
613 /* divide source by 2 */613 /* divide source by 2 */
614 NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000,614 NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000,
615 /* divide source by 8 */615 /* divide source by 8 */
616 NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000,616 NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000,
617 NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000617 NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000
618 };618};
619 static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n)619static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n)
620 {620{
621 /* NI 660x-specific */621 /* NI 660x-specific */
622 return 0x10 + n;622 return 0x10 + n;
623 }623}
624 static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n)624static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n)
625 {625{
626 return 0x18 + n;626 return 0x18 + n;
627 }627}
628 static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n)628static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n)
629 {629{
630 /* no pfi on NI 660x */630 /* no pfi on NI 660x */
631 return 0x20 + n;631 return 0x20 + n;
632 }632}
633 633
634/* Possibilities for setting a gate source with634/* Possibilities for setting a gate source with
635INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters.635INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters.
636May be bitwise-or'd with CR_EDGE or CR_INVERT. */636May be bitwise-or'd with CR_EDGE or CR_INVERT. */
637 enum ni_gpct_gate_select {637enum ni_gpct_gate_select {
638 /* m-series gates */638 /* m-series gates */
639 NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0,639 NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0,
640 NI_GPCT_AI_START2_GATE_SELECT = 0x12,640 NI_GPCT_AI_START2_GATE_SELECT = 0x12,
641 NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT = 0x13,641 NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT = 0x13,
642 NI_GPCT_NEXT_OUT_GATE_SELECT = 0x14,642 NI_GPCT_NEXT_OUT_GATE_SELECT = 0x14,
643 NI_GPCT_AI_START1_GATE_SELECT = 0x1c,643 NI_GPCT_AI_START1_GATE_SELECT = 0x1c,
644 NI_GPCT_NEXT_SOURCE_GATE_SELECT = 0x1d,644 NI_GPCT_NEXT_SOURCE_GATE_SELECT = 0x1d,
645 NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT = 0x1e,645 NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT = 0x1e,
646 NI_GPCT_LOGIC_LOW_GATE_SELECT = 0x1f,646 NI_GPCT_LOGIC_LOW_GATE_SELECT = 0x1f,
647 /* more gates for 660x */647 /* more gates for 660x */
648 NI_GPCT_SOURCE_PIN_i_GATE_SELECT = 0x100,648 NI_GPCT_SOURCE_PIN_i_GATE_SELECT = 0x100,
649 NI_GPCT_GATE_PIN_i_GATE_SELECT = 0x101,649 NI_GPCT_GATE_PIN_i_GATE_SELECT = 0x101,
650 /* more gates for 660x "second gate" */650 /* more gates for 660x "second gate" */
651 NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201,651 NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201,
652 NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e,652 NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e,
653 /* m-series "second gate" sources are unknown,653 /* m-series "second gate" sources are unknown,
654 * we should add them here with an offset of 0x300 when654 * we should add them here with an offset of 0x300 when
655 * known. */655 * known. */
656 NI_GPCT_DISABLED_GATE_SELECT = 0x8000,656 NI_GPCT_DISABLED_GATE_SELECT = 0x8000,
657 };657};
658 static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n)658static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n)
659 {659{
660 return 0x102 + n;660 return 0x102 + n;
661 }661}
662 static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n)662static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n)
663 {663{
664 return NI_USUAL_RTSI_SELECT(n);664 return NI_USUAL_RTSI_SELECT(n);
665 }665}
666 static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n)666static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n)
667 {667{
668 return NI_USUAL_PFI_SELECT(n);668 return NI_USUAL_PFI_SELECT(n);
669 }669}
670 static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n)670static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n)
671 {671{
672 return 0x202 + n;672 return 0x202 + n;
673 }673}
674 674
675/* Possibilities for setting a source with675/* Possibilities for setting a source with
676INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */676INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */
677 enum ni_gpct_other_index {677enum ni_gpct_other_index {
678 NI_GPCT_SOURCE_ENCODER_A,678 NI_GPCT_SOURCE_ENCODER_A,
679 NI_GPCT_SOURCE_ENCODER_B,679 NI_GPCT_SOURCE_ENCODER_B,
680 NI_GPCT_SOURCE_ENCODER_Z680 NI_GPCT_SOURCE_ENCODER_Z
681 };681};
682 enum ni_gpct_other_select {682enum ni_gpct_other_select {
683 /* m-series gates */683 /* m-series gates */
684 /* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */684 /* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */
685 NI_GPCT_DISABLED_OTHER_SELECT = 0x8000,685 NI_GPCT_DISABLED_OTHER_SELECT = 0x8000,
686 };686};
687 static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n)687static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n)
688 {688{
689 return NI_USUAL_PFI_SELECT(n);689 return NI_USUAL_PFI_SELECT(n);
690 }690}
691 691
692/* start sources for ni general-purpose counters for use with692/* start sources for ni general-purpose counters for use with
693INSN_CONFIG_ARM */693INSN_CONFIG_ARM */
694 enum ni_gpct_arm_source {694enum ni_gpct_arm_source {
695 NI_GPCT_ARM_IMMEDIATE = 0x0,695 NI_GPCT_ARM_IMMEDIATE = 0x0,
696 NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, /* Start both the counter696 NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, /* Start both the counter
697 * and the adjacent paired697 * and the adjacent paired
698 * counter simultaneously */698 * counter simultaneously */
699 /* NI doesn't document bits for selecting hardware arm triggers.699 /* NI doesn't document bits for selecting hardware arm triggers.
700 * If the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least700 * If the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least
701 * significant bits (3 bits for 660x or 5 bits for m-series)701 * significant bits (3 bits for 660x or 5 bits for m-series)
702 * through to the hardware. This will at least allow someone to702 * through to the hardware. This will at least allow someone to
703 * figure out what the bits do later. */703 * figure out what the bits do later. */
704 NI_GPCT_ARM_UNKNOWN = 0x1000,704 NI_GPCT_ARM_UNKNOWN = 0x1000,
705 };705};
706 706
707/* digital filtering options for ni 660x for use with INSN_CONFIG_FILTER. */707/* digital filtering options for ni 660x for use with INSN_CONFIG_FILTER. */
708 enum ni_gpct_filter_select {708enum ni_gpct_filter_select {
709 NI_GPCT_FILTER_OFF = 0x0,709 NI_GPCT_FILTER_OFF = 0x0,
710 NI_GPCT_FILTER_TIMEBASE_3_SYNC = 0x1,710 NI_GPCT_FILTER_TIMEBASE_3_SYNC = 0x1,
711 NI_GPCT_FILTER_100x_TIMEBASE_1 = 0x2,711 NI_GPCT_FILTER_100x_TIMEBASE_1 = 0x2,
712 NI_GPCT_FILTER_20x_TIMEBASE_1 = 0x3,712 NI_GPCT_FILTER_20x_TIMEBASE_1 = 0x3,
713 NI_GPCT_FILTER_10x_TIMEBASE_1 = 0x4,713 NI_GPCT_FILTER_10x_TIMEBASE_1 = 0x4,
714 NI_GPCT_FILTER_2x_TIMEBASE_1 = 0x5,714 NI_GPCT_FILTER_2x_TIMEBASE_1 = 0x5,
715 NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6715 NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6
716 };716};
717 717
718/* PFI digital filtering options for ni m-series for use with718/* PFI digital filtering options for ni m-series for use with
719 * INSN_CONFIG_FILTER. */719 * INSN_CONFIG_FILTER. */
720 enum ni_pfi_filter_select {720enum ni_pfi_filter_select {
721 NI_PFI_FILTER_OFF = 0x0,721 NI_PFI_FILTER_OFF = 0x0,
722 NI_PFI_FILTER_125ns = 0x1,722 NI_PFI_FILTER_125ns = 0x1,
723 NI_PFI_FILTER_6425ns = 0x2,723 NI_PFI_FILTER_6425ns = 0x2,
724 NI_PFI_FILTER_2550us = 0x3724 NI_PFI_FILTER_2550us = 0x3
725 };725};
726 726
727/* master clock sources for ni mio boards and INSN_CONFIG_SET_CLOCK_SRC */727/* master clock sources for ni mio boards and INSN_CONFIG_SET_CLOCK_SRC */
728 enum ni_mio_clock_source {728enum ni_mio_clock_source {
729 NI_MIO_INTERNAL_CLOCK = 0,729 NI_MIO_INTERNAL_CLOCK = 0,
730 NI_MIO_RTSI_CLOCK = 1, /* doesn't work for m-series, use730 NI_MIO_RTSI_CLOCK = 1, /* doesn't work for m-series, use
731 NI_MIO_PLL_RTSI_CLOCK() */731 NI_MIO_PLL_RTSI_CLOCK() */
732 /* the NI_MIO_PLL_* sources are m-series only */732 /* the NI_MIO_PLL_* sources are m-series only */
733 NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2,733 NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2,
734 NI_MIO_PLL_PXI10_CLOCK = 3,734 NI_MIO_PLL_PXI10_CLOCK = 3,
735 NI_MIO_PLL_RTSI0_CLOCK = 4735 NI_MIO_PLL_RTSI0_CLOCK = 4
736 };736};
737 static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel)737static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel)
738 {738{
739 return NI_MIO_PLL_RTSI0_CLOCK + rtsi_channel;739 return NI_MIO_PLL_RTSI0_CLOCK + rtsi_channel;
740 }740}
741 741
742/* Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING.742/* Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING.
743 The numbers assigned are not arbitrary, they correspond to the bits required743 The numbers assigned are not arbitrary, they correspond to the bits required
744 to program the board. */744 to program the board. */
745 enum ni_rtsi_routing {745enum ni_rtsi_routing {
746 NI_RTSI_OUTPUT_ADR_START1 = 0,746 NI_RTSI_OUTPUT_ADR_START1 = 0,
747 NI_RTSI_OUTPUT_ADR_START2 = 1,747 NI_RTSI_OUTPUT_ADR_START2 = 1,
748 NI_RTSI_OUTPUT_SCLKG = 2,748 NI_RTSI_OUTPUT_SCLKG = 2,
749 NI_RTSI_OUTPUT_DACUPDN = 3,749 NI_RTSI_OUTPUT_DACUPDN = 3,
750 NI_RTSI_OUTPUT_DA_START1 = 4,750 NI_RTSI_OUTPUT_DA_START1 = 4,
751 NI_RTSI_OUTPUT_G_SRC0 = 5,751 NI_RTSI_OUTPUT_G_SRC0 = 5,
752 NI_RTSI_OUTPUT_G_GATE0 = 6,752 NI_RTSI_OUTPUT_G_GATE0 = 6,
753 NI_RTSI_OUTPUT_RGOUT0 = 7,753 NI_RTSI_OUTPUT_RGOUT0 = 7,
754 NI_RTSI_OUTPUT_RTSI_BRD_0 = 8,754 NI_RTSI_OUTPUT_RTSI_BRD_0 = 8,
755 NI_RTSI_OUTPUT_RTSI_OSC = 12 /* pre-m-series always have RTSI755 NI_RTSI_OUTPUT_RTSI_OSC = 12 /* pre-m-series always have RTSI
756 * clock on line 7 */756 * clock on line 7 */
757 };757};
758 static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n)758static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n)
759 {759{
760 return NI_RTSI_OUTPUT_RTSI_BRD_0 + n;760 return NI_RTSI_OUTPUT_RTSI_BRD_0 + n;
761 }761}
762 762
763/* Signals which can be routed to an NI PFI pin on an m-series board with763/* Signals which can be routed to an NI PFI pin on an m-series board with
764 * INSN_CONFIG_SET_ROUTING. These numbers are also returned by764 * INSN_CONFIG_SET_ROUTING. These numbers are also returned by
765 * INSN_CONFIG_GET_ROUTING on pre-m-series boards, even though their routing765 * INSN_CONFIG_GET_ROUTING on pre-m-series boards, even though their routing
766 * cannot be changed. The numbers assigned are not arbitrary, they correspond766 * cannot be changed. The numbers assigned are not arbitrary, they correspond
767 * to the bits required to program the board. */767 * to the bits required to program the board. */
768 enum ni_pfi_routing {768enum ni_pfi_routing {
769 NI_PFI_OUTPUT_PFI_DEFAULT = 0,769 NI_PFI_OUTPUT_PFI_DEFAULT = 0,
770 NI_PFI_OUTPUT_AI_START1 = 1,770 NI_PFI_OUTPUT_AI_START1 = 1,
771 NI_PFI_OUTPUT_AI_START2 = 2,771 NI_PFI_OUTPUT_AI_START2 = 2,
772 NI_PFI_OUTPUT_AI_CONVERT = 3,772 NI_PFI_OUTPUT_AI_CONVERT = 3,
773 NI_PFI_OUTPUT_G_SRC1 = 4,773 NI_PFI_OUTPUT_G_SRC1 = 4,
774 NI_PFI_OUTPUT_G_GATE1 = 5,774 NI_PFI_OUTPUT_G_GATE1 = 5,
775 NI_PFI_OUTPUT_AO_UPDATE_N = 6,775 NI_PFI_OUTPUT_AO_UPDATE_N = 6,
776 NI_PFI_OUTPUT_AO_START1 = 7,776 NI_PFI_OUTPUT_AO_START1 = 7,
777 NI_PFI_OUTPUT_AI_START_PULSE = 8,777 NI_PFI_OUTPUT_AI_START_PULSE = 8,
778 NI_PFI_OUTPUT_G_SRC0 = 9,778 NI_PFI_OUTPUT_G_SRC0 = 9,
779 NI_PFI_OUTPUT_G_GATE0 = 10,779 NI_PFI_OUTPUT_G_GATE0 = 10,
780 NI_PFI_OUTPUT_EXT_STROBE = 11,780 NI_PFI_OUTPUT_EXT_STROBE = 11,
781 NI_PFI_OUTPUT_AI_EXT_MUX_CLK = 12,781 NI_PFI_OUTPUT_AI_EXT_MUX_CLK = 12,
782 NI_PFI_OUTPUT_GOUT0 = 13,782 NI_PFI_OUTPUT_GOUT0 = 13,
783 NI_PFI_OUTPUT_GOUT1 = 14,783 NI_PFI_OUTPUT_GOUT1 = 14,
784 NI_PFI_OUTPUT_FREQ_OUT = 15,784 NI_PFI_OUTPUT_FREQ_OUT = 15,
785 NI_PFI_OUTPUT_PFI_DO = 16,785 NI_PFI_OUTPUT_PFI_DO = 16,
786 NI_PFI_OUTPUT_I_ATRIG = 17,786 NI_PFI_OUTPUT_I_ATRIG = 17,
787 NI_PFI_OUTPUT_RTSI0 = 18,787 NI_PFI_OUTPUT_RTSI0 = 18,
788 NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN = 26,788 NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN = 26,
789 NI_PFI_OUTPUT_SCXI_TRIG1 = 27,789 NI_PFI_OUTPUT_SCXI_TRIG1 = 27,
790 NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI = 28,790 NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI = 28,
791 NI_PFI_OUTPUT_CDI_SAMPLE = 29,791 NI_PFI_OUTPUT_CDI_SAMPLE = 29,
792 NI_PFI_OUTPUT_CDO_UPDATE = 30792 NI_PFI_OUTPUT_CDO_UPDATE = 30
793 };793};
794 static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel)794static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel)
795 {795{
796 return NI_PFI_OUTPUT_RTSI0 + rtsi_channel;796 return NI_PFI_OUTPUT_RTSI0 + rtsi_channel;
797 }797}
798 798
799/* Signals which can be routed to output on a NI PFI pin on a 660x board799/* Signals which can be routed to output on a NI PFI pin on a 660x board
800 with INSN_CONFIG_SET_ROUTING. The numbers assigned are800 with INSN_CONFIG_SET_ROUTING. The numbers assigned are
@@ -802,113 +802,112 @@ INSN_CONFIG_ARM */ · 1 unmodified line
802 to program the board. Lines 0 to 7 can only be set to802 to program the board. Lines 0 to 7 can only be set to
803 NI_660X_PFI_OUTPUT_DIO. Lines 32 to 39 can only be set to803 NI_660X_PFI_OUTPUT_DIO. Lines 32 to 39 can only be set to
804 NI_660X_PFI_OUTPUT_COUNTER. */804 NI_660X_PFI_OUTPUT_COUNTER. */
805 enum ni_660x_pfi_routing {805enum ni_660x_pfi_routing {
806 NI_660X_PFI_OUTPUT_COUNTER = 1, /* counter */806 NI_660X_PFI_OUTPUT_COUNTER = 1, /* counter */
807 NI_660X_PFI_OUTPUT_DIO = 2, /* static digital output */807 NI_660X_PFI_OUTPUT_DIO = 2, /* static digital output */
808 };808};
809 809
810/* NI External Trigger lines. These values are not arbitrary, but are related810/* NI External Trigger lines. These values are not arbitrary, but are related
811 * to the bits required to program the board (offset by 1 for historical811 * to the bits required to program the board (offset by 1 for historical
812 * reasons). */812 * reasons). */
813 static inline unsigned NI_EXT_PFI(unsigned pfi_channel)813static inline unsigned NI_EXT_PFI(unsigned pfi_channel)
814 {814{
815 return NI_USUAL_PFI_SELECT(pfi_channel) - 1;815 return NI_USUAL_PFI_SELECT(pfi_channel) - 1;
816 }816}
817 static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel)817static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel)
818 {818{
819 return NI_USUAL_RTSI_SELECT(rtsi_channel) - 1;819 return NI_USUAL_RTSI_SELECT(rtsi_channel) - 1;
820 }820}
821 821
822/* status bits for INSN_CONFIG_GET_COUNTER_STATUS */822/* status bits for INSN_CONFIG_GET_COUNTER_STATUS */
823 enum comedi_counter_status_flags {823enum comedi_counter_status_flags {
824 COMEDI_COUNTER_ARMED = 0x1,824 COMEDI_COUNTER_ARMED = 0x1,
825 COMEDI_COUNTER_COUNTING = 0x2,825 COMEDI_COUNTER_COUNTING = 0x2,
826 COMEDI_COUNTER_TERMINAL_COUNT = 0x4,826 COMEDI_COUNTER_TERMINAL_COUNT = 0x4,
827 };827};
828 828
829/* Clock sources for CDIO subdevice on NI m-series boards. Used as the829/* Clock sources for CDIO subdevice on NI m-series boards. Used as the
830 * scan_begin_arg for a comedi_command. These sources may also be bitwise-or'd830 * scan_begin_arg for a comedi_command. These sources may also be bitwise-or'd
831 * with CR_INVERT to change polarity. */831 * with CR_INVERT to change polarity. */
832 enum ni_m_series_cdio_scan_begin_src {832enum ni_m_series_cdio_scan_begin_src {
833 NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0,833 NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0,
834 NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18,834 NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18,
835 NI_CDIO_SCAN_BEGIN_SRC_AI_CONVERT = 19,835 NI_CDIO_SCAN_BEGIN_SRC_AI_CONVERT = 19,
836 NI_CDIO_SCAN_BEGIN_SRC_PXI_STAR_TRIGGER = 20,836 NI_CDIO_SCAN_BEGIN_SRC_PXI_STAR_TRIGGER = 20,
837 NI_CDIO_SCAN_BEGIN_SRC_G0_OUT = 28,837 NI_CDIO_SCAN_BEGIN_SRC_G0_OUT = 28,
838 NI_CDIO_SCAN_BEGIN_SRC_G1_OUT = 29,838 NI_CDIO_SCAN_BEGIN_SRC_G1_OUT = 29,
839 NI_CDIO_SCAN_BEGIN_SRC_ANALOG_TRIGGER = 30,839 NI_CDIO_SCAN_BEGIN_SRC_ANALOG_TRIGGER = 30,
840 NI_CDIO_SCAN_BEGIN_SRC_AO_UPDATE = 31,840 NI_CDIO_SCAN_BEGIN_SRC_AO_UPDATE = 31,
841 NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32,841 NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32,
842 NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33842 NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33
843 };843};
844 static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)844static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)
845 {845{
846 return NI_USUAL_PFI_SELECT(pfi_channel);846 return NI_USUAL_PFI_SELECT(pfi_channel);
847 }847}
848 static inline unsigned848static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)
849 NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)849{
850 {850 return NI_USUAL_RTSI_SELECT(rtsi_channel);
851 return NI_USUAL_RTSI_SELECT(rtsi_channel);851}
852 }
853 852
854/* scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI853/* scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI
855 * boards. These scan begin sources can also be bitwise-or'd with CR_INVERT to854 * boards. These scan begin sources can also be bitwise-or'd with CR_INVERT to
856 * change polarity. */855 * change polarity. */
857 static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)856static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)
858 {857{
859 return NI_USUAL_PFI_SELECT(pfi_channel);858 return NI_USUAL_PFI_SELECT(pfi_channel);
860 }859}
861 static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)860static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)
862 {861{
863 return NI_USUAL_RTSI_SELECT(rtsi_channel);862 return NI_USUAL_RTSI_SELECT(rtsi_channel);
864 }863}
865 864
866/* Bits for setting a clock source with865/* Bits for setting a clock source with
867 * INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice. */866 * INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice. */
868 enum ni_freq_out_clock_source_bits {867enum ni_freq_out_clock_source_bits {
869 NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC, /* 10 MHz */868 NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC, /* 10 MHz */
870 NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC /* 100 KHz */869 NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC /* 100 KHz */
871 };870};
872 871
873/* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for872/* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
874 * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */873 * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */
875 enum amplc_dio_clock_source {874enum amplc_dio_clock_source {
876 AMPLC_DIO_CLK_CLKN, /* per channel external clock875 AMPLC_DIO_CLK_CLKN, /* per channel external clock
877 input/output pin (pin is only an876 input/output pin (pin is only an
878 input when clock source set to this877 input when clock source set to this
879 value, otherwise it is an output) */878 value, otherwise it is an output) */
880 AMPLC_DIO_CLK_10MHZ, /* 10 MHz internal clock */879 AMPLC_DIO_CLK_10MHZ, /* 10 MHz internal clock */
881 AMPLC_DIO_CLK_1MHZ, /* 1 MHz internal clock */880 AMPLC_DIO_CLK_1MHZ, /* 1 MHz internal clock */
882 AMPLC_DIO_CLK_100KHZ, /* 100 kHz internal clock */881 AMPLC_DIO_CLK_100KHZ, /* 100 kHz internal clock */
883 AMPLC_DIO_CLK_10KHZ, /* 10 kHz internal clock */882 AMPLC_DIO_CLK_10KHZ, /* 10 kHz internal clock */
884 AMPLC_DIO_CLK_1KHZ, /* 1 kHz internal clock */883 AMPLC_DIO_CLK_1KHZ, /* 1 kHz internal clock */
885 AMPLC_DIO_CLK_OUTNM1, /* output of preceding counter channel884 AMPLC_DIO_CLK_OUTNM1, /* output of preceding counter channel
886 (for channel 0, preceding counter885 (for channel 0, preceding counter
887 channel is channel 2 on preceding886 channel is channel 2 on preceding
888 counter subdevice, for first counter887 counter subdevice, for first counter
889 subdevice, preceding counter888 subdevice, preceding counter
890 subdevice is the last counter889 subdevice is the last counter
891 subdevice) */890 subdevice) */
892 AMPLC_DIO_CLK_EXT /* per chip external input pin */891 AMPLC_DIO_CLK_EXT /* per chip external input pin */
893 };892};
894 893
895/* Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for894/* Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for
896 * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */895 * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */
897 enum amplc_dio_gate_source {896enum amplc_dio_gate_source {
898 AMPLC_DIO_GAT_VCC, /* internal high logic level */897 AMPLC_DIO_GAT_VCC, /* internal high logic level */
899 AMPLC_DIO_GAT_GND, /* internal low logic level */898 AMPLC_DIO_GAT_GND, /* internal low logic level */
900 AMPLC_DIO_GAT_GATN, /* per channel external gate input */899 AMPLC_DIO_GAT_GATN, /* per channel external gate input */
901 AMPLC_DIO_GAT_NOUTNM2, /* negated output of counter channel900 AMPLC_DIO_GAT_NOUTNM2, /* negated output of counter channel
902 minus 2 (for channels 0 or 1,901 minus 2 (for channels 0 or 1,
903 channel minus 2 is channel 1 or 2 on902 channel minus 2 is channel 1 or 2 on
904 the preceding counter subdevice, for903 the preceding counter subdevice, for
905 the first counter subdevice the904 the first counter subdevice the
906 preceding counter subdevice is the905 preceding counter subdevice is the
907 last counter subdevice) */906 last counter subdevice) */
908 AMPLC_DIO_GAT_RESERVED4,907 AMPLC_DIO_GAT_RESERVED4,
909 AMPLC_DIO_GAT_RESERVED5,908 AMPLC_DIO_GAT_RESERVED5,
910 AMPLC_DIO_GAT_RESERVED6,909 AMPLC_DIO_GAT_RESERVED6,
911 AMPLC_DIO_GAT_RESERVED7910 AMPLC_DIO_GAT_RESERVED7
912 };911};
913 912
914#endif /* _COMEDI_H */913#endif /* _COMEDI_H */
drivers/staging/comedi/comedi_fops.c+73−79
@@ -370,7 +370,8 @@ static int do_devconfig_ioctl(struct comedi_device *dev, · 369 unmodified lines
370 return -ENOMEM;370 return -ENOMEM;
371 371
372 if (copy_from_user(aux_data,372 if (copy_from_user(aux_data,
373 comedi_aux_data(it.options, 0), aux_len)) {373 (unsigned char __user *
374 )comedi_aux_data(it.options, 0), aux_len)) {
374 vfree(aux_data);375 vfree(aux_data);
375 return -EFAULT;376 return -EFAULT;
376 }377 }
@@ -426,7 +427,7 @@ static int do_bufconfig_ioctl(struct comedi_device *dev, · 49 unmodified lines
426 if (bc.subdevice >= dev->n_subdevices || bc.subdevice < 0)427 if (bc.subdevice >= dev->n_subdevices || bc.subdevice < 0)
427 return -EINVAL;428 return -EINVAL;
428 429
429 s = dev->subdevices + bc.subdevice;430 s = &dev->subdevices[bc.subdevice];
430 async = s->async;431 async = s->async;
431 432
432 if (!async) {433 if (!async) {
@@ -539,7 +540,7 @@ static int do_subdinfo_ioctl(struct comedi_device *dev, · 106 unmodified lines
539 540
540 /* fill subdinfo structs */541 /* fill subdinfo structs */
541 for (i = 0; i < dev->n_subdevices; i++) {542 for (i = 0; i < dev->n_subdevices; i++) {
542 s = dev->subdevices + i;543 s = &dev->subdevices[i];
543 us = tmp + i;544 us = tmp + i;
544 545
545 us->type = s->type;546 us->type = s->type;
@@ -617,7 +618,7 @@ static int do_chaninfo_ioctl(struct comedi_device *dev, · 71 unmodified lines
617 618
618 if (it.subdev >= dev->n_subdevices)619 if (it.subdev >= dev->n_subdevices)
619 return -EINVAL;620 return -EINVAL;
620 s = dev->subdevices + it.subdev;621 s = &dev->subdevices[it.subdev];
621 622
622 if (it.maxdata_list) {623 if (it.maxdata_list) {
623 if (s->maxdata || !s->maxdata_list)624 if (s->maxdata || !s->maxdata_list)
@@ -685,7 +686,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, · 61 unmodified lines
685 if (bi.subdevice >= dev->n_subdevices || bi.subdevice < 0)686 if (bi.subdevice >= dev->n_subdevices || bi.subdevice < 0)
686 return -EINVAL;687 return -EINVAL;
687 688
688 s = dev->subdevices + bi.subdevice;689 s = &dev->subdevices[bi.subdevice];
689 690
690 if (s->lock && s->lock != file)691 if (s->lock && s->lock != file)
691 return -EACCES;692 return -EACCES;
@@ -882,14 +883,12 @@ static int check_insn_config_length(struct comedi_insn *insn, · 190 unmodified lines
882 /* by default we allow the insn since we don't have checks for883 /* by default we allow the insn since we don't have checks for
883 * all possible cases yet */884 * all possible cases yet */
884 default:885 default:
885 printk(KERN_WARNING886 pr_warn("comedi: No check for data length of config insn id %i is implemented.\n",
886 "comedi: no check for data length of config insn id "887 data[0]);
887 "%i is implemented.\n"888 pr_warn("comedi: Add a check to %s in %s.\n",
888 " Add a check to %s in %s.\n"889 __func__, __FILE__);
889 " Assuming n=%i is correct.\n", data[0], __func__,890 pr_warn("comedi: Assuming n=%i is correct.\n", insn->n);
890 __FILE__, insn->n);
891 return 0;891 return 0;
892 break;
893 }892 }
894 return -EINVAL;893 return -EINVAL;
895}894}
@@ -940,7 +939,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, · 44 unmodified lines
940 ret = -EINVAL;939 ret = -EINVAL;
941 break;940 break;
942 }941 }
943 s = dev->subdevices + insn->subdev;942 s = &dev->subdevices[insn->subdev];
944 if (!s->async) {943 if (!s->async) {
945 DPRINTK("no async\n");944 DPRINTK("no async\n");
946 ret = -EINVAL;945 ret = -EINVAL;
@@ -951,7 +950,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, · 4 unmodified lines
951 ret = -EAGAIN;950 ret = -EAGAIN;
952 break;951 break;
953 }952 }
954 ret = s->async->inttrig(dev, s, insn->data[0]);953 ret = s->async->inttrig(dev, s, data[0]);
955 if (ret >= 0)954 if (ret >= 0)
956 ret = 1;955 ret = 1;
957 break;956 break;
@@ -969,7 +968,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, · 11 unmodified lines
969 ret = -EINVAL;968 ret = -EINVAL;
970 goto out;969 goto out;
971 }970 }
972 s = dev->subdevices + insn->subdev;971 s = &dev->subdevices[insn->subdev];
973 972
974 if (s->type == COMEDI_SUBD_UNUSED) {973 if (s->type == COMEDI_SUBD_UNUSED) {
975 DPRINTK("%d not usable subdevice\n", insn->subdev);974 DPRINTK("%d not usable subdevice\n", insn->subdev);
@@ -1133,37 +1132,37 @@ static void comedi_set_subdevice_runflags(struct comedi_subdevice *s, · 157 unmodified lines
1133}1132}
1134 1133
1135static int do_cmd_ioctl(struct comedi_device *dev,1134static int do_cmd_ioctl(struct comedi_device *dev,
1136 struct comedi_cmd __user *cmd, void *file)1135 struct comedi_cmd __user *arg, void *file)
1137{1136{
1138 struct comedi_cmd user_cmd;1137 struct comedi_cmd cmd;
1139 struct comedi_subdevice *s;1138 struct comedi_subdevice *s;
1140 struct comedi_async *async;1139 struct comedi_async *async;
1141 int ret = 0;1140 int ret = 0;
1142 unsigned int __user *chanlist_saver = NULL;1141 unsigned int __user *user_chanlist;
1143 1142
1144 if (copy_from_user(&user_cmd, cmd, sizeof(struct comedi_cmd))) {1143 if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) {
1145 DPRINTK("bad cmd address\n");1144 DPRINTK("bad cmd address\n");
1146 return -EFAULT;1145 return -EFAULT;
1147 }1146 }
1148 /* save user's chanlist pointer so it can be restored later */1147 /* save user's chanlist pointer so it can be restored later */
1149 chanlist_saver = user_cmd.chanlist;1148 user_chanlist = (unsigned int __user *)cmd.chanlist;
1150 1149
1151 if (user_cmd.subdev >= dev->n_subdevices) {1150 if (cmd.subdev >= dev->n_subdevices) {
1152 DPRINTK("%d no such subdevice\n", user_cmd.subdev);1151 DPRINTK("%d no such subdevice\n", cmd.subdev);
1153 return -ENODEV;1152 return -ENODEV;
1154 }1153 }
1155 1154
1156 s = dev->subdevices + user_cmd.subdev;1155 s = &dev->subdevices[cmd.subdev];
1157 async = s->async;1156 async = s->async;
1158 1157
1159 if (s->type == COMEDI_SUBD_UNUSED) {1158 if (s->type == COMEDI_SUBD_UNUSED) {
1160 DPRINTK("%d not valid subdevice\n", user_cmd.subdev);1159 DPRINTK("%d not valid subdevice\n", cmd.subdev);
1161 return -EIO;1160 return -EIO;
1162 }1161 }
1163 1162
1164 if (!s->do_cmd || !s->do_cmdtest || !s->async) {1163 if (!s->do_cmd || !s->do_cmdtest || !s->async) {
1165 DPRINTK("subdevice %i does not support commands\n",1164 DPRINTK("subdevice %i does not support commands\n",
1166 user_cmd.subdev);1165 cmd.subdev);
1167 return -EIO;1166 return -EIO;
1168 }1167 }
1169 1168
@@ -1181,23 +1180,22 @@ static int do_cmd_ioctl(struct comedi_device *dev, · 11 unmodified lines
1181 s->busy = file;1180 s->busy = file;
1182 1181
1183 /* make sure channel/gain list isn't too long */1182 /* make sure channel/gain list isn't too long */
1184 if (user_cmd.chanlist_len > s->len_chanlist) {1183 if (cmd.chanlist_len > s->len_chanlist) {
1185 DPRINTK("channel/gain list too long %u > %d\n",1184 DPRINTK("channel/gain list too long %u > %d\n",
1186 user_cmd.chanlist_len, s->len_chanlist);1185 cmd.chanlist_len, s->len_chanlist);
1187 ret = -EINVAL;1186 ret = -EINVAL;
1188 goto cleanup;1187 goto cleanup;
1189 }1188 }
1190 1189
1191 /* make sure channel/gain list isn't too short */1190 /* make sure channel/gain list isn't too short */
1192 if (user_cmd.chanlist_len < 1) {1191 if (cmd.chanlist_len < 1) {
1193 DPRINTK("channel/gain list too short %u < 1\n",1192 DPRINTK("channel/gain list too short %u < 1\n",
1194 user_cmd.chanlist_len);1193 cmd.chanlist_len);
1195 ret = -EINVAL;1194 ret = -EINVAL;
1196 goto cleanup;1195 goto cleanup;
1197 }1196 }
1198 1197
1199 kfree(async->cmd.chanlist);1198 async->cmd = cmd;
1200 async->cmd = user_cmd;
1201 async->cmd.data = NULL;1199 async->cmd.data = NULL;
1202 /* load channel/gain list */1200 /* load channel/gain list */
1203 async->cmd.chanlist =1201 async->cmd.chanlist =
@@ -1208,7 +1206,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, · 4 unmodified lines
1208 goto cleanup;1206 goto cleanup;
1209 }1207 }
1210 1208
1211 if (copy_from_user(async->cmd.chanlist, user_cmd.chanlist,1209 if (copy_from_user(async->cmd.chanlist, user_chanlist,
1212 async->cmd.chanlist_len * sizeof(int))) {1210 async->cmd.chanlist_len * sizeof(int))) {
1213 DPRINTK("fault reading chanlist\n");1211 DPRINTK("fault reading chanlist\n");
1214 ret = -EFAULT;1212 ret = -EFAULT;
@@ -1228,11 +1226,11 @@ static int do_cmd_ioctl(struct comedi_device *dev, · 13 unmodified lines
1228 1226
1229 if (async->cmd.flags & TRIG_BOGUS || ret) {1227 if (async->cmd.flags & TRIG_BOGUS || ret) {
1230 DPRINTK("test returned %d\n", ret);1228 DPRINTK("test returned %d\n", ret);
1231 user_cmd = async->cmd;1229 cmd = async->cmd;
1232 /* restore chanlist pointer before copying back */1230 /* restore chanlist pointer before copying back */
1233 user_cmd.chanlist = chanlist_saver;1231 cmd.chanlist = (unsigned int __force *)user_chanlist;
1234 user_cmd.data = NULL;1232 cmd.data = NULL;
1235 if (copy_to_user(cmd, &user_cmd, sizeof(struct comedi_cmd))) {1233 if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) {
1236 DPRINTK("fault writing cmd\n");1234 DPRINTK("fault writing cmd\n");
1237 ret = -EFAULT;1235 ret = -EFAULT;
1238 goto cleanup;1236 goto cleanup;
@@ -1285,77 +1283,77 @@ cleanup: · 46 unmodified lines
1285static int do_cmdtest_ioctl(struct comedi_device *dev,1283static int do_cmdtest_ioctl(struct comedi_device *dev,
1286 struct comedi_cmd __user *arg, void *file)1284 struct comedi_cmd __user *arg, void *file)
1287{1285{
1288 struct comedi_cmd user_cmd;1286 struct comedi_cmd cmd;
1289 struct comedi_subdevice *s;1287 struct comedi_subdevice *s;
1290 int ret = 0;1288 int ret = 0;
1291 unsigned int *chanlist = NULL;1289 unsigned int *chanlist = NULL;
1292 unsigned int __user *chanlist_saver = NULL;1290 unsigned int __user *user_chanlist;
1293 1291
1294 if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {1292 if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) {
1295 DPRINTK("bad cmd address\n");1293 DPRINTK("bad cmd address\n");
1296 return -EFAULT;1294 return -EFAULT;
1297 }1295 }
1298 /* save user's chanlist pointer so it can be restored later */1296 /* save user's chanlist pointer so it can be restored later */
1299 chanlist_saver = user_cmd.chanlist;1297 user_chanlist = (unsigned int __user *)cmd.chanlist;
1300 1298
1301 if (user_cmd.subdev >= dev->n_subdevices) {1299 if (cmd.subdev >= dev->n_subdevices) {
1302 DPRINTK("%d no such subdevice\n", user_cmd.subdev);1300 DPRINTK("%d no such subdevice\n", cmd.subdev);
1303 return -ENODEV;1301 return -ENODEV;
1304 }1302 }
1305 1303
1306 s = dev->subdevices + user_cmd.subdev;1304 s = &dev->subdevices[cmd.subdev];
1307 if (s->type == COMEDI_SUBD_UNUSED) {1305 if (s->type == COMEDI_SUBD_UNUSED) {
1308 DPRINTK("%d not valid subdevice\n", user_cmd.subdev);1306 DPRINTK("%d not valid subdevice\n", cmd.subdev);
1309 return -EIO;1307 return -EIO;
1310 }1308 }
1311 1309
1312 if (!s->do_cmd || !s->do_cmdtest) {1310 if (!s->do_cmd || !s->do_cmdtest) {
1313 DPRINTK("subdevice %i does not support commands\n",1311 DPRINTK("subdevice %i does not support commands\n",
1314 user_cmd.subdev);1312 cmd.subdev);
1315 return -EIO;1313 return -EIO;
1316 }1314 }
1317 1315
1318 /* make sure channel/gain list isn't too long */1316 /* make sure channel/gain list isn't too long */
1319 if (user_cmd.chanlist_len > s->len_chanlist) {1317 if (cmd.chanlist_len > s->len_chanlist) {
1320 DPRINTK("channel/gain list too long %d > %d\n",1318 DPRINTK("channel/gain list too long %d > %d\n",
1321 user_cmd.chanlist_len, s->len_chanlist);1319 cmd.chanlist_len, s->len_chanlist);
1322 ret = -EINVAL;1320 ret = -EINVAL;
1323 goto cleanup;1321 goto cleanup;
1324 }1322 }
1325 1323
1326 /* load channel/gain list */1324 /* load channel/gain list */
1327 if (user_cmd.chanlist) {1325 if (cmd.chanlist) {
1328 chanlist =1326 chanlist =
1329 kmalloc(user_cmd.chanlist_len * sizeof(int), GFP_KERNEL);1327 kmalloc(cmd.chanlist_len * sizeof(int), GFP_KERNEL);
1330 if (!chanlist) {1328 if (!chanlist) {
1331 DPRINTK("allocation failed\n");1329 DPRINTK("allocation failed\n");
1332 ret = -ENOMEM;1330 ret = -ENOMEM;
1333 goto cleanup;1331 goto cleanup;
1334 }1332 }
1335 1333
1336 if (copy_from_user(chanlist, user_cmd.chanlist,1334 if (copy_from_user(chanlist, user_chanlist,
1337 user_cmd.chanlist_len * sizeof(int))) {1335 cmd.chanlist_len * sizeof(int))) {
1338 DPRINTK("fault reading chanlist\n");1336 DPRINTK("fault reading chanlist\n");
1339 ret = -EFAULT;1337 ret = -EFAULT;
1340 goto cleanup;1338 goto cleanup;
1341 }1339 }
1342 1340
1343 /* make sure each element in channel/gain list is valid */1341 /* make sure each element in channel/gain list is valid */
1344 ret = comedi_check_chanlist(s, user_cmd.chanlist_len, chanlist);1342 ret = comedi_check_chanlist(s, cmd.chanlist_len, chanlist);
1345 if (ret < 0) {1343 if (ret < 0) {
1346 DPRINTK("bad chanlist\n");1344 DPRINTK("bad chanlist\n");
1347 goto cleanup;1345 goto cleanup;
1348 }1346 }
1349 1347
1350 user_cmd.chanlist = chanlist;1348 cmd.chanlist = chanlist;
1351 }1349 }
1352 1350
1353 ret = s->do_cmdtest(dev, s, &user_cmd);1351 ret = s->do_cmdtest(dev, s, &cmd);
1354 1352
1355 /* restore chanlist pointer before copying back */1353 /* restore chanlist pointer before copying back */
1356 user_cmd.chanlist = chanlist_saver;1354 cmd.chanlist = (unsigned int __force *)user_chanlist;
1357 1355
1358 if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {1356 if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) {
1359 DPRINTK("bad cmd address\n");1357 DPRINTK("bad cmd address\n");
1360 ret = -EFAULT;1358 ret = -EFAULT;
1361 goto cleanup;1359 goto cleanup;
@@ -1390,7 +1388,7 @@ static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, · 28 unmodified lines
1390 1388
1391 if (arg >= dev->n_subdevices)1389 if (arg >= dev->n_subdevices)
1392 return -EINVAL;1390 return -EINVAL;
1393 s = dev->subdevices + arg;1391 s = &dev->subdevices[arg];
1394 1392
1395 spin_lock_irqsave(&s->spin_lock, flags);1393 spin_lock_irqsave(&s->spin_lock, flags);
1396 if (s->busy || s->lock)1394 if (s->busy || s->lock)
@@ -1433,7 +1431,7 @@ static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, · 36 unmodified lines
1433 1431
1434 if (arg >= dev->n_subdevices)1432 if (arg >= dev->n_subdevices)
1435 return -EINVAL;1433 return -EINVAL;
1436 s = dev->subdevices + arg;1434 s = &dev->subdevices[arg];
1437 1435
1438 if (s->busy)1436 if (s->busy)
1439 return -EBUSY;1437 return -EBUSY;
@@ -1474,7 +1472,7 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, · 34 unmodified lines
1474 1472
1475 if (arg >= dev->n_subdevices)1473 if (arg >= dev->n_subdevices)
1476 return -EINVAL;1474 return -EINVAL;
1477 s = dev->subdevices + arg;1475 s = &dev->subdevices[arg];
1478 if (s->async == NULL)1476 if (s->async == NULL)
1479 return -EINVAL;1477 return -EINVAL;
1480 1478
@@ -1511,7 +1509,7 @@ static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg, · 30 unmodified lines
1511 1509
1512 if (arg >= dev->n_subdevices)1510 if (arg >= dev->n_subdevices)
1513 return -EINVAL;1511 return -EINVAL;
1514 s = dev->subdevices + arg;1512 s = &dev->subdevices[arg];
1515 1513
1516 if (s->lock && s->lock != file)1514 if (s->lock && s->lock != file)
1517 return -EACCES;1515 return -EACCES;
@@ -2025,7 +2023,8 @@ done: · 507 unmodified lines
2025/*2023/*
2026 This function restores a subdevice to an idle state.2024 This function restores a subdevice to an idle state.
2027 */2025 */
2028void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s)2026static void do_become_nonbusy(struct comedi_device *dev,
2027 struct comedi_subdevice *s)
2029{2028{
2030 struct comedi_async *async = s->async;2029 struct comedi_async *async = s->async;
2031 2030
@@ -2033,9 +2032,11 @@ void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s) · 1 unmodified line
2033 if (async) {2032 if (async) {
2034 comedi_reset_async_buf(async);2033 comedi_reset_async_buf(async);
2035 async->inttrig = NULL;2034 async->inttrig = NULL;
2035 kfree(async->cmd.chanlist);
2036 async->cmd.chanlist = NULL;
2036 } else {2037 } else {
2037 printk(KERN_ERR2038 dev_err(dev->class_dev,
2038 "BUG: (?) do_become_nonbusy called with async=0\n");2039 "BUG: (?) do_become_nonbusy called with async=NULL\n");
2039 }2040 }
2040 2041
2041 s->busy = NULL;2042 s->busy = NULL;
@@ -2140,7 +2141,7 @@ static int comedi_close(struct inode *inode, struct file *file) · 98 unmodified lines
2140 2141
2141 if (dev->subdevices) {2142 if (dev->subdevices) {
2142 for (i = 0; i < dev->n_subdevices; i++) {2143 for (i = 0; i < dev->n_subdevices; i++) {
2143 s = dev->subdevices + i;2144 s = &dev->subdevices[i];
2144 2145
2145 if (s->busy == file)2146 if (s->busy == file)
2146 do_cancel(dev, s);2147 do_cancel(dev, s);
@@ -2211,14 +2212,12 @@ static int __init comedi_init(void) · 64 unmodified lines
2211 int i;2212 int i;
2212 int retval;2213 int retval;
2213 2214
2214 printk(KERN_INFO "comedi: version " COMEDI_RELEASE2215 pr_info("comedi: version " COMEDI_RELEASE " - http://www.comedi.org\n");
2215 " - http://www.comedi.org\n");
2216 2216
2217 if (comedi_num_legacy_minors < 0 ||2217 if (comedi_num_legacy_minors < 0 ||
2218 comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) {2218 comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) {
2219 printk(KERN_ERR "comedi: error: invalid value for module "2219 pr_err("comedi: error: invalid value for module parameter \"comedi_num_legacy_minors\". Valid values are 0 through %i.\n",
2220 "parameter \"comedi_num_legacy_minors\". Valid values "2220 COMEDI_NUM_BOARD_MINORS);
2221 "are 0 through %i.\n", COMEDI_NUM_BOARD_MINORS);
2222 return -EINVAL;2221 return -EINVAL;
2223 }2222 }
2224 2223
@@ -2247,7 +2246,7 @@ static int __init comedi_init(void) · 22 unmodified lines
2247 }2246 }
2248 comedi_class = class_create(THIS_MODULE, "comedi");2247 comedi_class = class_create(THIS_MODULE, "comedi");
2249 if (IS_ERR(comedi_class)) {2248 if (IS_ERR(comedi_class)) {
2250 printk(KERN_ERR "comedi: failed to create class");2249 pr_err("comedi: failed to create class\n");
2251 cdev_del(&comedi_cdev);2250 cdev_del(&comedi_cdev);
2252 unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),2251 unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
2253 COMEDI_NUM_MINORS);2252 COMEDI_NUM_MINORS);
@@ -2295,8 +2294,7 @@ module_exit(comedi_cleanup); · 41 unmodified lines
2295 2294
2296void comedi_error(const struct comedi_device *dev, const char *s)2295void comedi_error(const struct comedi_device *dev, const char *s)
2297{2296{
2298 printk(KERN_ERR "comedi%d: %s: %s\n", dev->minor,2297 dev_err(dev->class_dev, "%s: %s\n", dev->driver->driver_name, s);
2299 dev->driver->driver_name, s);
2300}2298}
2301EXPORT_SYMBOL(comedi_error);2299EXPORT_SYMBOL(comedi_error);
2302 2300
@@ -2364,7 +2362,7 @@ static int is_device_busy(struct comedi_device *dev) · 61 unmodified lines
2364 return 0;2362 return 0;
2365 2363
2366 for (i = 0; i < dev->n_subdevices; i++) {2364 for (i = 0; i < dev->n_subdevices; i++) {
2367 s = dev->subdevices + i;2365 s = &dev->subdevices[i];
2368 if (s->busy)2366 if (s->busy)
2369 return 1;2367 return 1;
2370 if (s->async && s->async->mmap_count)2368 if (s->async && s->async->mmap_count)
@@ -2420,9 +2418,7 @@ int comedi_alloc_board_minor(struct device *hardware_device) · 49 unmodified lines
2420 comedi_device_cleanup(info->device);2418 comedi_device_cleanup(info->device);
2421 kfree(info->device);2419 kfree(info->device);
2422 kfree(info);2420 kfree(info);
2423 printk(KERN_ERR2421 pr_err("comedi: error: ran out of minor numbers for board device files.\n");
2424 "comedi: error: "
2425 "ran out of minor numbers for board device files.\n");
2426 return -EBUSY;2422 return -EBUSY;
2427 }2423 }
2428 info->device->minor = i;2424 info->device->minor = i;
@@ -2499,9 +2495,7 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, · 70 unmodified lines
2499 spin_unlock(&comedi_file_info_table_lock);2495 spin_unlock(&comedi_file_info_table_lock);
2500 if (i == COMEDI_NUM_MINORS) {2496 if (i == COMEDI_NUM_MINORS) {
2501 kfree(info);2497 kfree(info);
2502 printk(KERN_ERR2498 pr_err("comedi: error: ran out of minor numbers for board device files.\n");
2503 "comedi: error: "
2504 "ran out of minor numbers for board device files.\n");
2505 return -EBUSY;2499 return -EBUSY;
2506 }2500 }
2507 s->minor = i;2501 s->minor = i;
drivers/staging/comedi/comedidev.h+1−1
@@ -46,7 +46,7 @@ · 45 unmodified lines
46 46
47#define DPRINTK(format, args...) do { \47#define DPRINTK(format, args...) do { \
48 if (comedi_debug) \48 if (comedi_debug) \
49 printk(KERN_DEBUG "comedi: " format , ## args); \49 pr_debug("comedi: " format, ## args); \
50} while (0)50} while (0)
51 51
52#define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))52#define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
drivers/staging/comedi/drivers.c+45−37
@@ -71,7 +71,7 @@ int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices) · 70 unmodified lines
71 dev->n_subdevices = num_subdevices;71 dev->n_subdevices = num_subdevices;
72 72
73 for (i = 0; i < num_subdevices; ++i) {73 for (i = 0; i < num_subdevices; ++i) {
74 s = dev->subdevices + i;74 s = &dev->subdevices[i];
75 s->device = dev;75 s->device = dev;
76 s->async_dma_dir = DMA_NONE;76 s->async_dma_dir = DMA_NONE;
77 spin_lock_init(&s->spin_lock);77 spin_lock_init(&s->spin_lock);
@@ -88,7 +88,7 @@ static void cleanup_device(struct comedi_device *dev) · 10 unmodified lines
88 88
89 if (dev->subdevices) {89 if (dev->subdevices) {
90 for (i = 0; i < dev->n_subdevices; i++) {90 for (i = 0; i < dev->n_subdevices; i++) {
91 s = dev->subdevices + i;91 s = &dev->subdevices[i];
92 comedi_free_subdevice_minor(s);92 comedi_free_subdevice_minor(s);
93 if (s->async) {93 if (s->async) {
94 comedi_buf_alloc(dev, s, 0);94 comedi_buf_alloc(dev, s, 0);
@@ -119,8 +119,8 @@ static void __comedi_device_detach(struct comedi_device *dev) · 24 unmodified lines
119 if (dev->driver)119 if (dev->driver)
120 dev->driver->detach(dev);120 dev->driver->detach(dev);
121 else121 else
122 printk(KERN_WARNING122 dev_warn(dev->class_dev,
123 "BUG: dev->driver=NULL in comedi_device_detach()\n");123 "BUG: dev->driver=NULL in comedi_device_detach()\n");
124 cleanup_device(dev);124 cleanup_device(dev);
125}125}
126 126
@@ -142,8 +142,7 @@ static int comedi_device_postconfig(struct comedi_device *dev) · 15 unmodified lines
142 return ret;142 return ret;
143 }143 }
144 if (!dev->board_name) {144 if (!dev->board_name) {
145 printk(KERN_WARNING "BUG: dev->board_name=<%p>\n",145 dev_warn(dev->class_dev, "BUG: dev->board_name=NULL\n");
146 dev->board_name);
147 dev->board_name = "BUG";146 dev->board_name = "BUG";
148 }147 }
149 smp_wmb();148 smp_wmb();
@@ -160,10 +159,8 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) · 10 unmodified lines
160 return -EBUSY;159 return -EBUSY;
161 160
162 for (driv = comedi_drivers; driv; driv = driv->next) {161 for (driv = comedi_drivers; driv; driv = driv->next) {
163 if (!try_module_get(driv->module)) {162 if (!try_module_get(driv->module))
164 printk(KERN_INFO "comedi: failed to increment module count, skipping\n");
165 continue;163 continue;
166 }
167 if (driv->num_names) {164 if (driv->num_names) {
168 dev->board_ptr = comedi_recognize(driv, it->board_name);165 dev->board_ptr = comedi_recognize(driv, it->board_name);
169 if (dev->board_ptr)166 if (dev->board_ptr)
@@ -176,16 +173,21 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) · 6 unmodified lines
176 /* recognize has failed if we get here */173 /* recognize has failed if we get here */
177 /* report valid board names before returning error */174 /* report valid board names before returning error */
178 for (driv = comedi_drivers; driv; driv = driv->next) {175 for (driv = comedi_drivers; driv; driv = driv->next) {
179 if (!try_module_get(driv->module)) {176 if (!try_module_get(driv->module))
180 printk(KERN_INFO
181 "comedi: failed to increment module count\n");
182 continue;177 continue;
183 }
184 comedi_report_boards(driv);178 comedi_report_boards(driv);
185 module_put(driv->module);179 module_put(driv->module);
186 }180 }
187 return -EIO;181 return -EIO;
188 }182 }
183 if (driv->attach == NULL) {
184 /* driver does not support manual configuration */
185 dev_warn(dev->class_dev,
186 "driver '%s' does not support attach using comedi_config\n",
187 driv->driver_name);
188 module_put(driv->module);
189 return -ENOSYS;
190 }
189 /* initialize dev->driver here so191 /* initialize dev->driver here so
190 * comedi_error() can be called from attach */192 * comedi_error() can be called from attach */
191 dev->driver = driv;193 dev->driver = driv;
@@ -225,8 +227,9 @@ int comedi_driver_unregister(struct comedi_driver *driver) · 33 unmodified lines
225 mutex_lock(&dev->mutex);227 mutex_lock(&dev->mutex);
226 if (dev->attached && dev->driver == driver) {228 if (dev->attached && dev->driver == driver) {
227 if (dev->use_count)229 if (dev->use_count)
228 printk(KERN_WARNING "BUG! detaching device with use_count=%d\n",230 dev_warn(dev->class_dev,
229 dev->use_count);231 "BUG! detaching device with use_count=%d\n",
232 dev->use_count);
230 comedi_device_detach(dev);233 comedi_device_detach(dev);
231 }234 }
232 mutex_unlock(&dev->mutex);235 mutex_unlock(&dev->mutex);
@@ -255,7 +258,7 @@ static int postconfig(struct comedi_device *dev) · 22 unmodified lines
255 int ret;258 int ret;
256 259
257 for (i = 0; i < dev->n_subdevices; i++) {260 for (i = 0; i < dev->n_subdevices; i++) {
258 s = dev->subdevices + i;261 s = &dev->subdevices[i];
259 262
260 if (s->type == COMEDI_SUBD_UNUSED)263 if (s->type == COMEDI_SUBD_UNUSED)
261 continue;264 continue;
@@ -273,8 +276,8 @@ static int postconfig(struct comedi_device *dev) · 11 unmodified lines
273 async =276 async =
274 kzalloc(sizeof(struct comedi_async), GFP_KERNEL);277 kzalloc(sizeof(struct comedi_async), GFP_KERNEL);
275 if (async == NULL) {278 if (async == NULL) {
276 printk(KERN_INFO279 dev_warn(dev->class_dev,
277 "failed to allocate async struct\n");280 "failed to allocate async struct\n");
278 return -ENOMEM;281 return -ENOMEM;
279 }282 }
280 init_waitqueue_head(&async->wait_head);283 init_waitqueue_head(&async->wait_head);
@@ -290,7 +293,8 @@ static int postconfig(struct comedi_device *dev) · 9 unmodified lines
290 async->prealloc_buf = NULL;293 async->prealloc_buf = NULL;
291 async->prealloc_bufsz = 0;294 async->prealloc_bufsz = 0;
292 if (comedi_buf_alloc(dev, s, buf_size) < 0) {295 if (comedi_buf_alloc(dev, s, buf_size) < 0) {
293 printk(KERN_INFO "Buffer allocation failed\n");296 dev_warn(dev->class_dev,
297 "Buffer allocation failed\n");
294 return -ENOMEM;298 return -ENOMEM;
295 }299 }
296 if (s->buf_change) {300 if (s->buf_change) {
@@ -370,17 +374,17 @@ static void comedi_report_boards(struct comedi_driver *driv) · 73 unmodified lines
370 unsigned int i;374 unsigned int i;
371 const char *const *name_ptr;375 const char *const *name_ptr;
372 376
373 printk(KERN_INFO "comedi: valid board names for %s driver are:\n",377 pr_info("comedi: valid board names for %s driver are:\n",
374 driv->driver_name);378 driv->driver_name);
375 379
376 name_ptr = driv->board_name;380 name_ptr = driv->board_name;
377 for (i = 0; i < driv->num_names; i++) {381 for (i = 0; i < driv->num_names; i++) {
378 printk(KERN_INFO " %s\n", *name_ptr);382 pr_info(" %s\n", *name_ptr);
379 name_ptr = (const char **)((char *)name_ptr + driv->offset);383 name_ptr = (const char **)((char *)name_ptr + driv->offset);
380 }384 }
381 385
382 if (driv->num_names == 0)386 if (driv->num_names == 0)
383 printk(KERN_INFO " %s\n", driv->driver_name);387 pr_info(" %s\n", driv->driver_name);
384}388}
385 389
386static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)390static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -411,7 +415,6 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, · 24 unmodified lines
411 new_insn.insn = INSN_BITS;415 new_insn.insn = INSN_BITS;
412 new_insn.chanspec = base_bitfield_channel;416 new_insn.chanspec = base_bitfield_channel;
413 new_insn.n = 2;417 new_insn.n = 2;
414 new_insn.data = new_data;
415 new_insn.subdev = insn->subdev;418 new_insn.subdev = insn->subdev;
416 419
417 if (insn->insn == INSN_WRITE) {420 if (insn->insn == INSN_WRITE) {
@@ -584,9 +587,9 @@ static unsigned int comedi_buf_munge(struct comedi_async *async, · 166 unmodified lines
584 587
585 block_size = num_bytes - count;588 block_size = num_bytes - count;
586 if (block_size < 0) {589 if (block_size < 0) {
587 printk(KERN_WARNING590 dev_warn(s->device->class_dev,
588 "%s: %s: bug! block_size is negative\n",591 "%s: %s: bug! block_size is negative\n",
589 __FILE__, __func__);592 __FILE__, __func__);
590 break;593 break;
591 }594 }
592 if ((int)(async->munge_ptr + block_size -595 if ((int)(async->munge_ptr + block_size -
@@ -667,7 +670,8 @@ unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes) · 74 unmodified lines
667{670{
668 if ((int)(async->buf_write_count + nbytes -671 if ((int)(async->buf_write_count + nbytes -
669 async->buf_write_alloc_count) > 0) {672 async->buf_write_alloc_count) > 0) {
670 printk(KERN_INFO "comedi: attempted to write-free more bytes than have been write-allocated.\n");673 dev_info(async->subdevice->device->class_dev,
674 "attempted to write-free more bytes than have been write-allocated.\n");
671 nbytes = async->buf_write_alloc_count - async->buf_write_count;675 nbytes = async->buf_write_alloc_count - async->buf_write_count;
672 }676 }
673 async->buf_write_count += nbytes;677 async->buf_write_count += nbytes;
@@ -703,8 +707,8 @@ unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes) · 29 unmodified lines
703 smp_mb();707 smp_mb();
704 if ((int)(async->buf_read_count + nbytes -708 if ((int)(async->buf_read_count + nbytes -
705 async->buf_read_alloc_count) > 0) {709 async->buf_read_alloc_count) > 0) {
706 printk(KERN_INFO710 dev_info(async->subdevice->device->class_dev,
707 "comedi: attempted to read-free more bytes than have been read-allocated.\n");711 "attempted to read-free more bytes than have been read-allocated.\n");
708 nbytes = async->buf_read_alloc_count - async->buf_read_count;712 nbytes = async->buf_read_alloc_count - async->buf_read_count;
709 }713 }
710 async->buf_read_count += nbytes;714 async->buf_read_count += nbytes;
@@ -853,10 +857,9 @@ comedi_auto_config_helper(struct device *hardware_device, · 142 unmodified lines
853 mutex_lock(&comedi_dev->mutex);857 mutex_lock(&comedi_dev->mutex);
854 if (comedi_dev->attached)858 if (comedi_dev->attached)
855 ret = -EBUSY;859 ret = -EBUSY;
856 else if (!try_module_get(driver->module)) {860 else if (!try_module_get(driver->module))
857 printk(KERN_INFO "comedi: failed to increment module count\n");
858 ret = -EIO;861 ret = -EIO;
859 } else {862 else {
860 /* set comedi_dev->driver here for attach wrapper */863 /* set comedi_dev->driver here for attach wrapper */
861 comedi_dev->driver = driver;864 comedi_dev->driver = driver;
862 ret = (*attach_wrapper)(comedi_dev, context);865 ret = (*attach_wrapper)(comedi_dev, context);
@@ -884,14 +887,19 @@ static int comedi_auto_config_wrapper(struct comedi_device *dev, void *context) · 21 unmodified lines
884 * has already been copied to it->board_name */887 * has already been copied to it->board_name */
885 dev->board_ptr = comedi_recognize(driv, it->board_name);888 dev->board_ptr = comedi_recognize(driv, it->board_name);
886 if (dev->board_ptr == NULL) {889 if (dev->board_ptr == NULL) {
887 printk(KERN_WARNING890 dev_warn(dev->class_dev,
888 "comedi: auto config failed to find board entry"891 "auto config failed to find board entry '%s' for driver '%s'\n",
889 " '%s' for driver '%s'\n", it->board_name,892 it->board_name, driv->driver_name);
890 driv->driver_name);
891 comedi_report_boards(driv);893 comedi_report_boards(driv);
892 return -EINVAL;894 return -EINVAL;
893 }895 }
894 }896 }
897 if (!driv->attach) {
898 dev_warn(dev->class_dev,
899 "BUG! driver '%s' using old-style auto config but has no attach handler\n",
900 driv->driver_name);
901 return -EINVAL;
902 }
895 return driv->attach(dev, it);903 return driv->attach(dev, it);
896}904}
897 905
drivers/staging/comedi/drivers/8253.h+9−6
@@ -262,8 +262,10 @@ static inline int i8254_load(unsigned long base_address, unsigned int regshift, · 261 unmodified lines
262 return 0;262 return 0;
263}263}
264 264
265static inline int i8254_mm_load(void *base_address, unsigned int regshift,265static inline int i8254_mm_load(void __iomem *base_address,
266 unsigned int counter_number, unsigned int count,266 unsigned int regshift,
267 unsigned int counter_number,
268 unsigned int count,
267 unsigned int mode)269 unsigned int mode)
268{270{
269 unsigned int byte;271 unsigned int byte;
@@ -311,7 +313,8 @@ static inline int i8254_read(unsigned long base_address, unsigned int regshift, · 41 unmodified lines
311 return ret;313 return ret;
312}314}
313 315
314static inline int i8254_mm_read(void *base_address, unsigned int regshift,316static inline int i8254_mm_read(void __iomem *base_address,
317 unsigned int regshift,
315 unsigned int counter_number)318 unsigned int counter_number)
316{319{
317 unsigned int byte;320 unsigned int byte;
@@ -348,7 +351,7 @@ static inline void i8254_write(unsigned long base_address, · 30 unmodified lines
348 outb(byte, base_address + (counter_number << regshift));351 outb(byte, base_address + (counter_number << regshift));
349}352}
350 353
351static inline void i8254_mm_write(void *base_address,354static inline void i8254_mm_write(void __iomem *base_address,
352 unsigned int regshift,355 unsigned int regshift,
353 unsigned int counter_number,356 unsigned int counter_number,
354 unsigned int count)357 unsigned int count)
@@ -390,7 +393,7 @@ static inline int i8254_set_mode(unsigned long base_address, · 35 unmodified lines
390 return 0;393 return 0;
391}394}
392 395
393static inline int i8254_mm_set_mode(void *base_address,396static inline int i8254_mm_set_mode(void __iomem *base_address,
394 unsigned int regshift,397 unsigned int regshift,
395 unsigned int counter_number,398 unsigned int counter_number,
396 unsigned int mode)399 unsigned int mode)
@@ -419,7 +422,7 @@ static inline int i8254_status(unsigned long base_address, · 22 unmodified lines
419 return inb(base_address + (counter_number << regshift));422 return inb(base_address + (counter_number << regshift));
420}423}
421 424
422static inline int i8254_mm_status(void *base_address,425static inline int i8254_mm_status(void __iomem *base_address,
423 unsigned int regshift,426 unsigned int regshift,
424 unsigned int counter_number)427 unsigned int counter_number)
425{428{
drivers/staging/comedi/drivers/8255.c+12−29
@@ -82,6 +82,8 @@ I/O port base address can be found in the output of 'lspci -v'. · 81 unmodified lines
82 82
83#include <linux/ioport.h>83#include <linux/ioport.h>
84#include <linux/slab.h>84#include <linux/slab.h>
85
86#include "comedi_fc.h"
85#include "8255.h"87#include "8255.h"
86 88
87#define _8255_SIZE 489#define _8255_SIZE 4
@@ -229,39 +231,20 @@ static int subdev_8255_cmdtest(struct comedi_device *dev, · 141 unmodified lines
229 struct comedi_cmd *cmd)231 struct comedi_cmd *cmd)
230{232{
231 int err = 0;233 int err = 0;
232 unsigned int tmp;
233
234 /* step 1 */
235
236 tmp = cmd->start_src;
237 cmd->start_src &= TRIG_NOW;
238 if (!cmd->start_src || tmp != cmd->start_src)
239 err++;
240
241 tmp = cmd->scan_begin_src;
242 cmd->scan_begin_src &= TRIG_EXT;
243 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
244 err++;
245 234
246 tmp = cmd->convert_src;235 /* Step 1 : check if triggers are trivially valid */
247 cmd->convert_src &= TRIG_FOLLOW;
248 if (!cmd->convert_src || tmp != cmd->convert_src)
249 err++;
250 236
251 tmp = cmd->scan_end_src;237 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
252 cmd->scan_end_src &= TRIG_COUNT;238 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
253 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)239 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
254 err++;240 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
255 241 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
256 tmp = cmd->stop_src;
257 cmd->stop_src &= TRIG_NONE;
258 if (!cmd->stop_src || tmp != cmd->stop_src)
259 err++;
260 242
261 if (err)243 if (err)
262 return 1;244 return 1;
263 245
264 /* step 2 */246 /* Step 2a : make sure trigger sources are unique */
247 /* Step 2b : and mutually compatible */
265 248
266 if (err)249 if (err)
267 return 2;250 return 2;
@@ -403,7 +386,7 @@ static int dev_8255_attach(struct comedi_device *dev, · 135 unmodified lines
403 return ret;386 return ret;
404 387
405 for (i = 0; i < dev->n_subdevices; i++) {388 for (i = 0; i < dev->n_subdevices; i++) {
406 s = dev->subdevices + i;389 s = &dev->subdevices[i];
407 iobase = it->options[i];390 iobase = it->options[i];
408 391
409 if (!request_region(iobase, _8255_SIZE, "8255")) {392 if (!request_region(iobase, _8255_SIZE, "8255")) {
@@ -429,7 +412,7 @@ static void dev_8255_detach(struct comedi_device *dev) · 19 unmodified lines
429 int i;412 int i;
430 413
431 for (i = 0; i < dev->n_subdevices; i++) {414 for (i = 0; i < dev->n_subdevices; i++) {
432 s = dev->subdevices + i;415 s = &dev->subdevices[i];
433 if (s->type != COMEDI_SUBD_UNUSED) {416 if (s->type != COMEDI_SUBD_UNUSED) {
434 spriv = s->private;417 spriv = s->private;
435 release_region(spriv->iobase, _8255_SIZE);418 release_region(spriv->iobase, _8255_SIZE);
drivers/staging/comedi/drivers/8255_pci.c+353−0
@@ -0,0 +1,353 @@
1/*
2 * COMEDI driver for generic PCI based 8255 digital i/o boards
3 * Copyright (C) 2012 H Hartley Sweeten <hsweeten@visionengravers.com>
4 *
5 * Based on the tested adl_pci7296 driver written by:
6 * Jon Grierson <jd@renko.co.uk>
7 * and the experimental cb_pcidio driver written by:
8 * Yoshiya Matsuzaka
9 *
10 * COMEDI - Linux Control and Measurement Device Interface
11 * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28/*
29Driver: 8255_pci
30Description: Generic PCI based 8255 Digital I/O boards
31Devices: (ADLink) PCI-7224 [adl_pci-7224] - 24 channels
32 (ADLink) PCI-7248 [adl_pci-7248] - 48 channels
33 (ADLink) PCI-7296 [adl_pci-7296] - 96 channels
34 (Measurement Computing) PCI-DIO24 [cb_pci-dio24] - 24 channels
35 (Measurement Computing) PCI-DIO24H [cb_pci-dio24h] - 24 channels
36 (Measurement Computing) PCI-DIO48H [cb_pci-dio48h] - 48 channels
37 (Measurement Computing) PCI-DIO96H [cb_pci-dio96h] - 96 channels
38 (National Instruments) PCI-DIO-96 [ni_pci-dio-96] - 96 channels
39 (National Instruments) PCI-DIO-96B [ni_pci-dio-96b] - 96 channels
40 (National Instruments) PXI-6508 [ni_pxi-6508] - 96 channels
41 (National Instruments) PCI-6503 [ni_pci-6503] - 24 channels
42 (National Instruments) PCI-6503B [ni_pci-6503b] - 24 channels
43 (National Instruments) PCI-6503X [ni_pci-6503x] - 24 channels
44 (National Instruments) PXI-6503 [ni_pxi-6503] - 24 channels
45Author: H Hartley Sweeten <hsweeten@visionengravers.com>
46Updated: Wed, 12 Sep 2012 11:52:01 -0700
47Status: untested
48
49Some of these boards also have an 8254 programmable timer/counter
50chip. This chip is not currently supported by this driver.
51
52Interrupt support for these boards is also not currently supported.
53
54Configuration Options: not applicable, uses PCI auto config
55*/
56
57#include "../comedidev.h"
58
59#include "8255.h"
60
61/*
62 * PCI Device ID's supported by this driver
63 */
64#define PCI_DEVICE_ID_ADLINK_PCI7224 0x7224
65#define PCI_DEVICE_ID_ADLINK_PCI7248 0x7248
66#define PCI_DEVICE_ID_ADLINK_PCI7296 0x7296
67
68/* ComputerBoards is now known as Measurement Computing */
69#define PCI_VENDOR_ID_CB 0x1307
70
71#define PCI_DEVICE_ID_CB_PCIDIO48H 0x000b
72#define PCI_DEVICE_ID_CB_PCIDIO24H 0x0014
73#define PCI_DEVICE_ID_CB_PCIDIO96H 0x0017
74#define PCI_DEVICE_ID_CB_PCIDIO24 0x0028
75
76#define PCI_DEVICE_ID_NI_PCIDIO96 0x0160
77#define PCI_DEVICE_ID_NI_PCI6503 0x0400
78#define PCI_DEVICE_ID_NI_PCI6503B 0x1250
79#define PCI_DEVICE_ID_NI_PXI6508 0x13c0
80#define PCI_DEVICE_ID_NI_PCIDIO96B 0x1630
81#define PCI_DEVICE_ID_NI_PCI6503X 0x17d0
82#define PCI_DEVICE_ID_NI_PXI_6503 0x1800
83
84struct pci_8255_boardinfo {
85 const char *name;
86 unsigned short vendor;
87 unsigned short device;
88 int dio_badr;
89 int is_mmio;
90 int n_8255;
91};
92
93static const struct pci_8255_boardinfo pci_8255_boards[] = {
94 {
95 .name = "adl_pci-7224",
96 .vendor = PCI_VENDOR_ID_ADLINK,
97 .device = PCI_DEVICE_ID_ADLINK_PCI7224,
98 .dio_badr = 2,
99 .n_8255 = 1,
100 }, {
101 .name = "adl_pci-7248",
102 .vendor = PCI_VENDOR_ID_ADLINK,
103 .device = PCI_DEVICE_ID_ADLINK_PCI7248,
104 .dio_badr = 2,
105 .n_8255 = 2,
106 }, {
107 .name = "adl_pci-7296",
108 .vendor = PCI_VENDOR_ID_ADLINK,
109 .device = PCI_DEVICE_ID_ADLINK_PCI7296,
110 .dio_badr = 2,
111 .n_8255 = 4,
112 }, {
113 .name = "cb_pci-dio24",
114 .vendor = PCI_VENDOR_ID_CB,
115 .device = PCI_DEVICE_ID_CB_PCIDIO24,
116 .dio_badr = 2,
117 .n_8255 = 1,
118 }, {
119 .name = "cb_pci-dio24h",
120 .vendor = PCI_VENDOR_ID_CB,
121 .device = PCI_DEVICE_ID_CB_PCIDIO24H,
122 .dio_badr = 2,
123 .n_8255 = 1,
124 }, {
125 .name = "cb_pci-dio48h",
126 .vendor = PCI_VENDOR_ID_CB,
127 .device = PCI_DEVICE_ID_CB_PCIDIO48H,
128 .dio_badr = 1,
129 .n_8255 = 2,
130 }, {
131 .name = "cb_pci-dio96h",
132 .vendor = PCI_VENDOR_ID_CB,
133 .device = PCI_DEVICE_ID_CB_PCIDIO96H,
134 .dio_badr = 2,
135 .n_8255 = 4,
136 }, {
137 .name = "ni_pci-dio-96",
138 .vendor = PCI_VENDOR_ID_NI,
139 .device = PCI_DEVICE_ID_NI_PCIDIO96,
140 .dio_badr = 1,
141 .is_mmio = 1,
142 .n_8255 = 4,
143 }, {
144 .name = "ni_pci-dio-96b",
145 .vendor = PCI_VENDOR_ID_NI,
146 .device = PCI_DEVICE_ID_NI_PCIDIO96B,
147 .dio_badr = 1,
148 .is_mmio = 1,
149 .n_8255 = 4,
150 }, {
151 .name = "ni_pxi-6508",
152 .vendor = PCI_VENDOR_ID_NI,
153 .device = PCI_DEVICE_ID_NI_PXI6508,
154 .dio_badr = 1,
155 .is_mmio = 1,
156 .n_8255 = 4,
157 }, {
158 .name = "ni_pci-6503",
159 .vendor = PCI_VENDOR_ID_NI,
160 .device = PCI_DEVICE_ID_NI_PCI6503,
161 .dio_badr = 1,
162 .is_mmio = 1,
163 .n_8255 = 1,
164 }, {
165 .name = "ni_pci-6503b",
166 .vendor = PCI_VENDOR_ID_NI,
167 .device = PCI_DEVICE_ID_NI_PCI6503B,
168 .dio_badr = 1,
169 .is_mmio = 1,
170 .n_8255 = 1,
171 }, {
172 .name = "ni_pci-6503x",
173 .vendor = PCI_VENDOR_ID_NI,
174 .device = PCI_DEVICE_ID_NI_PCI6503X,
175 .dio_badr = 1,
176 .is_mmio = 1,
177 .n_8255 = 1,
178 }, {
179 .name = "ni_pxi-6503",
180 .vendor = PCI_VENDOR_ID_NI,
181 .device = PCI_DEVICE_ID_NI_PXI_6503,
182 .dio_badr = 1,
183 .is_mmio = 1,
184 .n_8255 = 1,
185 },
186};
187
188struct pci_8255_private {
189 void __iomem *mmio_base;
190};
191
192static int pci_8255_mmio(int dir, int port, int data, unsigned long iobase)
193{
194 void __iomem *mmio_base = (void __iomem *)iobase;
195
196 if (dir) {
197 writeb(data, mmio_base + port);
198 return 0;
199 } else {
200 return readb(mmio_base + port);
201 }
202}
203
204static const void *pci_8255_find_boardinfo(struct comedi_device *dev,
205 struct pci_dev *pcidev)
206{
207 const struct pci_8255_boardinfo *board;
208 int i;
209
210 for (i = 0; i < ARRAY_SIZE(pci_8255_boards); i++) {
211 board = &pci_8255_boards[i];
212 if (pcidev->vendor == board->vendor &&
213 pcidev->device == board->device)
214 return board;
215 }
216 return NULL;
217}
218
219static int pci_8255_attach_pci(struct comedi_device *dev,
220 struct pci_dev *pcidev)
221{
222 const struct pci_8255_boardinfo *board;
223 struct pci_8255_private *devpriv;
224 struct comedi_subdevice *s;
225 resource_size_t iobase;
226 unsigned long len;
227 int ret;
228 int i;
229
230 comedi_set_hw_dev(dev, &pcidev->dev);
231
232 board = pci_8255_find_boardinfo(dev, pcidev);
233 if (!board)
234 return -ENODEV;
235 dev->board_ptr = board;
236 dev->board_name = board->name;
237
238 ret = alloc_private(dev, sizeof(*devpriv));
239 if (ret < 0)
240 return ret;
241 devpriv = dev->private;
242
243 ret = comedi_pci_enable(pcidev, dev->board_name);
244 if (ret)
245 return ret;
246 iobase = pci_resource_start(pcidev, board->dio_badr);
247 len = pci_resource_len(pcidev, board->dio_badr);
248
249 if (board->is_mmio) {
250 devpriv->mmio_base = ioremap(iobase, len);
251 if (!devpriv->mmio_base)
252 return -ENOMEM;
253 }
254 dev->iobase = iobase;
255
256 /*
257 * One, two, or four subdevices are setup by this driver depending
258 * on the number of channels provided by the board. Each subdevice
259 * has 24 channels supported by the 8255 module.
260 */
261 ret = comedi_alloc_subdevices(dev, board->n_8255);
262 if (ret)
263 return ret;
264
265 for (i = 0; i < board->n_8255; i++) {
266 s = &dev->subdevices[i];
267 if (board->is_mmio) {
268 iobase = (unsigned long)(devpriv->mmio_base + (i * 4));
269 ret = subdev_8255_init(dev, s, pci_8255_mmio, iobase);
270 } else {
271 iobase = dev->iobase + (i * 4);
272 ret = subdev_8255_init(dev, s, NULL, iobase);
273 }
274 if (ret)
275 return ret;
276 }
277
278 dev_info(dev->class_dev, "%s attached (%d digital i/o channels)\n",
279 dev->board_name, board->n_8255 * 24);
280
281 return 0;
282}
283
284static void pci_8255_detach(struct comedi_device *dev)
285{
286 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
287 const struct pci_8255_boardinfo *board = comedi_board(dev);
288 struct pci_8255_private *devpriv = dev->private;
289 struct comedi_subdevice *s;
290 int i;
291
292 if (dev->subdevices) {
293 for (i = 0; i < board->n_8255; i++) {
294 s = &dev->subdevices[i];
295 subdev_8255_cleanup(dev, s);
296 }
297 }
298 if (pcidev) {
299 if (devpriv->mmio_base)
300 iounmap(devpriv->mmio_base);
301 if (dev->iobase)
302 comedi_pci_disable(pcidev);
303 }
304}
305
306static struct comedi_driver pci_8255_driver = {
307 .driver_name = "8255_pci",
308 .module = THIS_MODULE,
309 .attach_pci = pci_8255_attach_pci,
310 .detach = pci_8255_detach,
311};
312
313static int __devinit pci_8255_pci_probe(struct pci_dev *dev,
314 const struct pci_device_id *ent)
315{
316 return comedi_pci_auto_config(dev, &pci_8255_driver);
317}
318
319static void __devexit pci_8255_pci_remove(struct pci_dev *dev)
320{
321 comedi_pci_auto_unconfig(dev);
322}
323
324static DEFINE_PCI_DEVICE_TABLE(pci_8255_pci_table) = {
325 { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7224) },
326 { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7248) },
327 { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7296) },
328 { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO24) },
329 { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO24H) },
330 { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO48H) },
331 { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO96H) },
332 { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCIDIO96) },
333 { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCIDIO96B) },
334 { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI6508) },
335 { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI6503) },
336 { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI6503B) },
337 { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI6503X) },
338 { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI_6503) },
339 { 0 }
340};
341MODULE_DEVICE_TABLE(pci, pci_8255_pci_table);
342
343static struct pci_driver pci_8255_pci_driver = {
344 .name = "8255_pci",
345 .id_table = pci_8255_pci_table,
346 .probe = pci_8255_pci_probe,
347 .remove = __devexit_p(pci_8255_pci_remove),
348};
349module_comedi_pci_driver(pci_8255_driver, pci_8255_pci_driver);
350
351MODULE_DESCRIPTION("COMEDI - Generic PCI based 8255 Digital I/O boards");
352MODULE_AUTHOR("Comedi http://www.comedi.org");
353MODULE_LICENSE("GPL");
drivers/staging/comedi/drivers/Makefile+2−4
@@ -55,6 +55,7 @@ obj-$(CONFIG_COMEDI_MULTIQ3) += multiq3.o · 54 unmodified lines
55obj-$(CONFIG_COMEDI_POC) += poc.o55obj-$(CONFIG_COMEDI_POC) += poc.o
56 56
57# Comedi PCI drivers57# Comedi PCI drivers
58obj-$(CONFIG_COMEDI_8255_PCI) += 8255_pci.o
58obj-$(CONFIG_COMEDI_ADDI_APCI_035) += addi_apci_035.o59obj-$(CONFIG_COMEDI_ADDI_APCI_035) += addi_apci_035.o
59obj-$(CONFIG_COMEDI_ADDI_APCI_1032) += addi_apci_1032.o60obj-$(CONFIG_COMEDI_ADDI_APCI_1032) += addi_apci_1032.o
60obj-$(CONFIG_COMEDI_ADDI_APCI_1500) += addi_apci_1500.o61obj-$(CONFIG_COMEDI_ADDI_APCI_1500) += addi_apci_1500.o
@@ -69,9 +70,7 @@ obj-$(CONFIG_COMEDI_ADDI_APCI_3120) += addi_apci_3120.o · 8 unmodified lines
69obj-$(CONFIG_COMEDI_ADDI_APCI_3501) += addi_apci_3501.o70obj-$(CONFIG_COMEDI_ADDI_APCI_3501) += addi_apci_3501.o
70obj-$(CONFIG_COMEDI_ADDI_APCI_3XXX) += addi_apci_3xxx.o71obj-$(CONFIG_COMEDI_ADDI_APCI_3XXX) += addi_apci_3xxx.o
71obj-$(CONFIG_COMEDI_ADL_PCI6208) += adl_pci6208.o72obj-$(CONFIG_COMEDI_ADL_PCI6208) += adl_pci6208.o
72obj-$(CONFIG_COMEDI_ADL_PCI7230) += adl_pci7230.o73obj-$(CONFIG_COMEDI_ADL_PCI7X3X) += adl_pci7x3x.o
73obj-$(CONFIG_COMEDI_ADL_PCI7296) += adl_pci7296.o
74obj-$(CONFIG_COMEDI_ADL_PCI7432) += adl_pci7432.o
75obj-$(CONFIG_COMEDI_ADL_PCI8164) += adl_pci8164.o74obj-$(CONFIG_COMEDI_ADL_PCI8164) += adl_pci8164.o
76obj-$(CONFIG_COMEDI_ADL_PCI9111) += adl_pci9111.o75obj-$(CONFIG_COMEDI_ADL_PCI9111) += adl_pci9111.o
77obj-$(CONFIG_COMEDI_ADL_PCI9118) += adl_pci9118.o76obj-$(CONFIG_COMEDI_ADL_PCI9118) += adl_pci9118.o
@@ -96,7 +95,6 @@ obj-$(CONFIG_COMEDI_KE_COUNTER) += ke_counter.o · 18 unmodified lines
96obj-$(CONFIG_COMEDI_CB_PCIDAS64) += cb_pcidas64.o95obj-$(CONFIG_COMEDI_CB_PCIDAS64) += cb_pcidas64.o
97obj-$(CONFIG_COMEDI_CB_PCIDAS) += cb_pcidas.o96obj-$(CONFIG_COMEDI_CB_PCIDAS) += cb_pcidas.o
98obj-$(CONFIG_COMEDI_CB_PCIDDA) += cb_pcidda.o97obj-$(CONFIG_COMEDI_CB_PCIDDA) += cb_pcidda.o
99obj-$(CONFIG_COMEDI_CB_PCIDIO) += cb_pcidio.o
100obj-$(CONFIG_COMEDI_CB_PCIMDAS) += cb_pcimdas.o98obj-$(CONFIG_COMEDI_CB_PCIMDAS) += cb_pcimdas.o
101obj-$(CONFIG_COMEDI_CB_PCIMDDA) += cb_pcimdda.o99obj-$(CONFIG_COMEDI_CB_PCIMDDA) += cb_pcimdda.o
102obj-$(CONFIG_COMEDI_ME4000) += me4000.o100obj-$(CONFIG_COMEDI_ME4000) += me4000.o
drivers/staging/comedi/drivers/acl7225b.c+3−3
@@ -81,7 +81,7 @@ static int acl7225b_attach(struct comedi_device *dev, · 80 unmodified lines
81 if (ret)81 if (ret)
82 return ret;82 return ret;
83 83
84 s = dev->subdevices + 0;84 s = &dev->subdevices[0];
85 /* Relays outputs */85 /* Relays outputs */
86 s->type = COMEDI_SUBD_DO;86 s->type = COMEDI_SUBD_DO;
87 s->subdev_flags = SDF_WRITABLE;87 s->subdev_flags = SDF_WRITABLE;
@@ -91,7 +91,7 @@ static int acl7225b_attach(struct comedi_device *dev, · 3 unmodified lines
91 s->range_table = &range_digital;91 s->range_table = &range_digital;
92 s->private = (void *)ACL7225_RIO_LO;92 s->private = (void *)ACL7225_RIO_LO;
93 93
94 s = dev->subdevices + 1;94 s = &dev->subdevices[1];
95 /* Relays status */95 /* Relays status */
96 s->type = COMEDI_SUBD_DI;96 s->type = COMEDI_SUBD_DI;
97 s->subdev_flags = SDF_READABLE;97 s->subdev_flags = SDF_READABLE;
@@ -101,7 +101,7 @@ static int acl7225b_attach(struct comedi_device *dev, · 3 unmodified lines
101 s->range_table = &range_digital;101 s->range_table = &range_digital;
102 s->private = (void *)ACL7225_RIO_LO;102 s->private = (void *)ACL7225_RIO_LO;
103 103
104 s = dev->subdevices + 2;104 s = &dev->subdevices[2];
105 /* Isolated digital inputs */105 /* Isolated digital inputs */
106 s->type = COMEDI_SUBD_DI;106 s->type = COMEDI_SUBD_DI;
107 s->subdev_flags = SDF_READABLE;107 s->subdev_flags = SDF_READABLE;
drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c+0−195
@@ -1,195 +0,0 @@
1/**
2@verbatim
3
4Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
5
6 ADDI-DATA GmbH
7 Dieselstrasse 3
8 D-77833 Ottersweier
9 Tel: +19(0)7223/9493-0
10 Fax: +49(0)7223/9493-92
11 http://www.addi-data.com
12 info@addi-data.com
13
14This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
15
16This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20You should also find the complete GPL in the COPYING file accompanying this source code.
21
22@endverbatim
23*/
24/*
25 +-----------------------------------------------------------------------+
26 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
27 +-----------------------------------------------------------------------+
28 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
29 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
30 +-------------------------------+---------------------------------------+
31 | Project : ADDI HEADER READ WRITER | Compiler : Visual C++ |
32 | Module name : S5920.cpp | Version : 6.0 |
33 +-------------------------------+---------------------------------------+
34 | Author : E. LIBS Date : 02/05/2002 |
35 +-----------------------------------------------------------------------+
36 | Description : DLL with the S5920 PCI Controller functions |
37 +-----------------------------------------------------------------------+
38 | UPDATE'S |
39 +-----------------------------------------------------------------------+
40 | Date | Author | Description of updates |
41 +----------+-----------+------------------------------------------------+
42 | 28/08/02 | LIBS Eric | Add return codes each time a function of the |
43 | | | Addi Library is called |
44 +-----------------------------------------------------------------------+
45 | 31/07/03 | KRAUTH J. | Changes for the MSX-Box |
46 +-----------------------------------------------------------------------+
47*/
48
49#include "addi_amcc_S5920.h"
50
51/*+----------------------------------------------------------------------------+*/
52/*| Function Name : int i_AddiHeaderRW_ReadEeprom |*/
53/*| (int i_NbOfWordsToRead, |*/
54/*| unsigned int dw_PCIBoardEepromAddress, |*/
55/*| unsigned short w_EepromStartAddress, |*/
56/*| unsigned short * pw_DataRead) |*/
57/*+----------------------------------------------------------------------------+*/
58/*| Task : Read word from the 5920 eeprom. |*/
59/*+----------------------------------------------------------------------------+*/
60/*| Input Parameters : int i_NbOfWordsToRead : Nbr. of word to read |*/
61/*| unsigned int dw_PCIBoardEepromAddress : Address of the eeprom |*/
62/*| unsigned short w_EepromStartAddress : Eeprom start address |*/
63/*+----------------------------------------------------------------------------+*/
64/*| Output Parameters : unsigned short * pw_DataRead : Read data |*/
65/*+----------------------------------------------------------------------------+*/
66/*| Return Value : - |*/
67/*+----------------------------------------------------------------------------+*/
68
69int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
70 unsigned int dw_PCIBoardEepromAddress,
71 unsigned short w_EepromStartAddress, unsigned short *pw_DataRead)
72{
73 unsigned int dw_eeprom_busy = 0;
74 int i_Counter = 0;
75 int i_WordCounter;
76 int i;
77 unsigned char pb_ReadByte[1];
78 unsigned char b_ReadLowByte = 0;
79 unsigned char b_ReadHighByte = 0;
80 unsigned char b_SelectedAddressLow = 0;
81 unsigned char b_SelectedAddressHigh = 0;
82 unsigned short w_ReadWord = 0;
83
84 for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
85 i_WordCounter++) {
86 do {
87 dw_eeprom_busy =
88 inl(dw_PCIBoardEepromAddress +
89 AMCC_OP_REG_MCSR);
90 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
91 } while (dw_eeprom_busy == EEPROM_BUSY);
92
93 for (i_Counter = 0; i_Counter < 2; i_Counter++) {
94 b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256; /* Read the low 8 bit part */
95 b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256; /* Read the high 8 bit part */
96
97 /* Select the load low address mode */
98 outb(NVCMD_LOAD_LOW,
99 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
100 3);
101
102 /* Wait on busy */
103 do {
104 dw_eeprom_busy =
105 inl(dw_PCIBoardEepromAddress +
106 AMCC_OP_REG_MCSR);
107 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
108 } while (dw_eeprom_busy == EEPROM_BUSY);
109
110 /* Load the low address */
111 outb(b_SelectedAddressLow,
112 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
113 2);
114
115 /* Wait on busy */
116 do {
117 dw_eeprom_busy =
118 inl(dw_PCIBoardEepromAddress +
119 AMCC_OP_REG_MCSR);
120 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
121 } while (dw_eeprom_busy == EEPROM_BUSY);
122
123 /* Select the load high address mode */
124 outb(NVCMD_LOAD_HIGH,
125 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
126 3);
127
128 /* Wait on busy */
129 do {
130 dw_eeprom_busy =
131 inl(dw_PCIBoardEepromAddress +
132 AMCC_OP_REG_MCSR);
133 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
134 } while (dw_eeprom_busy == EEPROM_BUSY);
135
136 /* Load the high address */
137 outb(b_SelectedAddressHigh,
138 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
139 2);
140
141 /* Wait on busy */
142 do {
143 dw_eeprom_busy =
144 inl(dw_PCIBoardEepromAddress +
145 AMCC_OP_REG_MCSR);
146 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
147 } while (dw_eeprom_busy == EEPROM_BUSY);
148
149 /* Select the READ mode */
150 outb(NVCMD_BEGIN_READ,
151 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
152 3);
153
154 /* Wait on busy */
155 do {
156 dw_eeprom_busy =
157 inl(dw_PCIBoardEepromAddress +
158 AMCC_OP_REG_MCSR);
159 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
160 } while (dw_eeprom_busy == EEPROM_BUSY);
161
162 /* Read data into the EEPROM */
163 *pb_ReadByte =
164 inb(dw_PCIBoardEepromAddress +
165 AMCC_OP_REG_MCSR + 2);
166
167 /* Wait on busy */
168 do {
169 dw_eeprom_busy =
170 inl(dw_PCIBoardEepromAddress +
171 AMCC_OP_REG_MCSR);
172 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
173 } while (dw_eeprom_busy == EEPROM_BUSY);
174
175 /* Select the upper address part */
176 if (i_Counter == 0)
177 b_ReadLowByte = pb_ReadByte[0];
178 else
179 b_ReadHighByte = pb_ReadByte[0];
180
181 /* Sleep */
182 msleep(1);
183
184 }
185 w_ReadWord =
186 (b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
187 256));
188
189 pw_DataRead[i_WordCounter] = w_ReadWord;
190
191 w_EepromStartAddress += 2; /* to read the next word */
192
193 } /* for (...) i_NbOfWordsToRead */
194 return 0;
195}
drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h+0−27
@@ -1,27 +0,0 @@
1/*
2 * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
3 *
4 * ADDI-DATA GmbH
5 * Dieselstrasse 3
6 * D-77833 Ottersweier
7 * Tel: +19(0)7223/9493-0
8 * Fax: +49(0)7223/9493-92
9 * http://www.addi-data.com
10 * info@addi-data.com
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the Free
14 * Software Foundation; either version 2 of the License, or (at your option)
15 * any later version.
16 */
17
18#define AMCC_OP_REG_MCSR 0x3c
19#define EEPROM_BUSY 0x80000000
20#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */
21#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */
22#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */
23#define NVCMD_BEGIN_WRITE (0x6 << 5) /* EEPROM begin write command */
24
25int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
26 unsigned int dw_PCIBoardEepromAddress,
27 unsigned short w_EepromStartAddress, unsigned short *pw_DataRead);
drivers/staging/comedi/drivers/addi-data/addi_common.c+7−7
@@ -1669,7 +1669,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) · 1668 unmodified lines
1669 return ret;1669 return ret;
1670 1670
1671 /* Allocate and Initialise AI Subdevice Structures */1671 /* Allocate and Initialise AI Subdevice Structures */
1672 s = dev->subdevices + 0;1672 s = &dev->subdevices[0];
1673 if ((devpriv->s_EeParameters.i_NbrAiChannel)1673 if ((devpriv->s_EeParameters.i_NbrAiChannel)
1674 || (this_board->i_NbrAiChannelDiff)) {1674 || (this_board->i_NbrAiChannelDiff)) {
1675 dev->read_subdev = s;1675 dev->read_subdev = s;
@@ -1705,7 +1705,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) · 29 unmodified lines
1705 }1705 }
1706 1706
1707 /* Allocate and Initialise AO Subdevice Structures */1707 /* Allocate and Initialise AO Subdevice Structures */
1708 s = dev->subdevices + 1;1708 s = &dev->subdevices[1];
1709 if (devpriv->s_EeParameters.i_NbrAoChannel) {1709 if (devpriv->s_EeParameters.i_NbrAoChannel) {
1710 s->type = COMEDI_SUBD_AO;1710 s->type = COMEDI_SUBD_AO;
1711 s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;1711 s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
@@ -1720,7 +1720,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) · 8 unmodified lines
1720 s->type = COMEDI_SUBD_UNUSED;1720 s->type = COMEDI_SUBD_UNUSED;
1721 }1721 }
1722 /* Allocate and Initialise DI Subdevice Structures */1722 /* Allocate and Initialise DI Subdevice Structures */
1723 s = dev->subdevices + 2;1723 s = &dev->subdevices[2];
1724 if (devpriv->s_EeParameters.i_NbrDiChannel) {1724 if (devpriv->s_EeParameters.i_NbrDiChannel) {
1725 s->type = COMEDI_SUBD_DI;1725 s->type = COMEDI_SUBD_DI;
1726 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;1726 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
@@ -1738,7 +1738,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) · 11 unmodified lines
1738 s->type = COMEDI_SUBD_UNUSED;1738 s->type = COMEDI_SUBD_UNUSED;
1739 }1739 }
1740 /* Allocate and Initialise DO Subdevice Structures */1740 /* Allocate and Initialise DO Subdevice Structures */
1741 s = dev->subdevices + 3;1741 s = &dev->subdevices[3];
1742 if (devpriv->s_EeParameters.i_NbrDoChannel) {1742 if (devpriv->s_EeParameters.i_NbrDoChannel) {
1743 s->type = COMEDI_SUBD_DO;1743 s->type = COMEDI_SUBD_DO;
1744 s->subdev_flags =1744 s->subdev_flags =
@@ -1760,7 +1760,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) · 15 unmodified lines
1760 }1760 }
1761 1761
1762 /* Allocate and Initialise Timer Subdevice Structures */1762 /* Allocate and Initialise Timer Subdevice Structures */
1763 s = dev->subdevices + 4;1763 s = &dev->subdevices[4];
1764 if (devpriv->s_EeParameters.i_Timer) {1764 if (devpriv->s_EeParameters.i_Timer) {
1765 s->type = COMEDI_SUBD_TIMER;1765 s->type = COMEDI_SUBD_TIMER;
1766 s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;1766 s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
@@ -1778,7 +1778,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) · 11 unmodified lines
1778 }1778 }
1779 1779
1780 /* Allocate and Initialise TTL */1780 /* Allocate and Initialise TTL */
1781 s = dev->subdevices + 5;1781 s = &dev->subdevices[5];
1782 if (this_board->i_NbrTTLChannel) {1782 if (this_board->i_NbrTTLChannel) {
1783 s->type = COMEDI_SUBD_TTLIO;1783 s->type = COMEDI_SUBD_TTLIO;
1784 s->subdev_flags =1784 s->subdev_flags =
@@ -1797,7 +1797,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) · 12 unmodified lines
1797 }1797 }
1798 1798
1799 /* EEPROM */1799 /* EEPROM */
1800 s = dev->subdevices + 6;1800 s = &dev->subdevices[6];
1801 if (this_board->i_PCIEeprom) {1801 if (this_board->i_PCIEeprom) {
1802 s->type = COMEDI_SUBD_MEMORY;1802 s->type = COMEDI_SUBD_MEMORY;
1803 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;1803 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h+0−453
@@ -1,453 +0,0 @@
1/*
2 Modified by umesh on 16th may 2001
3 Modified by sarath on 22nd may 2001
4*/
5
6/*
7 comedi/drivers/amcc_s5933_v_58.h
8
9 Stuff for AMCC S5933 PCI Controller
10
11 Author: Michal Dobes <majkl@tesnet.cz>
12
13 Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
14 made by Andrea Cisternino <acister@pcape1.pi.infn.it>
15 and as result of espionage from MITE code made by David A. Schleef.
16 Thanks to AMCC for their on-line documentation and bus master DMA
17 example.
18*/
19
20#ifndef _AMCC_S5933_H_
21#define _AMCC_S5933_H_
22
23#include <linux/pci.h>
24#include "../../comedidev.h"
25
26/***********Added by sarath for compatibility with APCI3120
27
28*************************/
29
30#define FIFO_ADVANCE_ON_BYTE_2 0x20000000 /* written on base0 */
31
32#define AMWEN_ENABLE 0x02 /* added for step 6 dma written on base2 */
33#define A2P_FIFO_WRITE_ENABLE 0x01
34
35#define AGCSTS_TC_ENABLE 0x10000000 /* Added for transfer count enable bit */
36
37/* ADDON RELATED ADDITIONS */
38/* Constant */
39#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
40#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
41#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
42#define APCI3120_AMWEN_ENABLE 0x02
43#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
44#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
45#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
46#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
47#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
48#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
49#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
50
51 /* ADD_ON ::: this needed since apci supports 16 bit interface to add on */
52#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
53#define APCI3120_ADD_ON_AGCSTS_HIGH APCI3120_ADD_ON_AGCSTS_LOW + 2
54#define APCI3120_ADD_ON_MWAR_LOW 0x24
55#define APCI3120_ADD_ON_MWAR_HIGH APCI3120_ADD_ON_MWAR_LOW + 2
56#define APCI3120_ADD_ON_MWTC_LOW 0x058
57#define APCI3120_ADD_ON_MWTC_HIGH APCI3120_ADD_ON_MWTC_LOW + 2
58
59/* AMCC */
60#define APCI3120_AMCC_OP_MCSR 0x3C
61#define APCI3120_AMCC_OP_REG_INTCSR 0x38
62
63/*******from here all upward definitions are added by sarath */
64
65/****************************************************************************/
66/* AMCC Operation Register Offsets - PCI */
67/****************************************************************************/
68
69#define AMCC_OP_REG_OMB1 0x00
70#define AMCC_OP_REG_OMB2 0x04
71#define AMCC_OP_REG_OMB3 0x08
72#define AMCC_OP_REG_OMB4 0x0c
73#define AMCC_OP_REG_IMB1 0x10
74#define AMCC_OP_REG_IMB2 0x14
75#define AMCC_OP_REG_IMB3 0x18
76#define AMCC_OP_REG_IMB4 0x1c
77#define AMCC_OP_REG_FIFO 0x20
78#define AMCC_OP_REG_MWAR 0x24
79#define AMCC_OP_REG_MWTC 0x28
80#define AMCC_OP_REG_MRAR 0x2c
81#define AMCC_OP_REG_MRTC 0x30
82#define AMCC_OP_REG_MBEF 0x34
83#define AMCC_OP_REG_INTCSR 0x38
84#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) /* int source */
85#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) /* FIFO ctrl */
86#define AMCC_OP_REG_MCSR 0x3c
87#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) /* Data in byte 2 */
88#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
89
90#define AMCC_FIFO_DEPTH_DWORD 8
91#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32))
92
93/****************************************************************************/
94/* AMCC Operation Registers Size - PCI */
95/****************************************************************************/
96
97#define AMCC_OP_REG_SIZE 64 /* in bytes */
98
99/****************************************************************************/
100/* AMCC Operation Register Offsets - Add-on */
101/****************************************************************************/
102
103#define AMCC_OP_REG_AIMB1 0x00
104#define AMCC_OP_REG_AIMB2 0x04
105#define AMCC_OP_REG_AIMB3 0x08
106#define AMCC_OP_REG_AIMB4 0x0c
107#define AMCC_OP_REG_AOMB1 0x10
108#define AMCC_OP_REG_AOMB2 0x14
109#define AMCC_OP_REG_AOMB3 0x18
110#define AMCC_OP_REG_AOMB4 0x1c
111#define AMCC_OP_REG_AFIFO 0x20
112#define AMCC_OP_REG_AMWAR 0x24
113#define AMCC_OP_REG_APTA 0x28
114#define AMCC_OP_REG_APTD 0x2c
115#define AMCC_OP_REG_AMRAR 0x30
116#define AMCC_OP_REG_AMBEF 0x34
117#define AMCC_OP_REG_AINT 0x38
118#define AMCC_OP_REG_AGCSTS 0x3c
119#define AMCC_OP_REG_AMWTC 0x58
120#define AMCC_OP_REG_AMRTC 0x5c
121
122/****************************************************************************/
123/* AMCC - Add-on General Control/Status Register */
124/****************************************************************************/
125
126#define AGCSTS_CONTROL_MASK 0xfffff000
127#define AGCSTS_NV_ACC_MASK 0xe0000000
128#define AGCSTS_RESET_MASK 0x0e000000
129#define AGCSTS_NV_DA_MASK 0x00ff0000
130#define AGCSTS_BIST_MASK 0x0000f000
131#define AGCSTS_STATUS_MASK 0x000000ff
132#define AGCSTS_TCZERO_MASK 0x000000c0
133#define AGCSTS_FIFO_ST_MASK 0x0000003f
134
135#define AGCSTS_RESET_MBFLAGS 0x08000000
136#define AGCSTS_RESET_P2A_FIFO 0x04000000
137#define AGCSTS_RESET_A2P_FIFO 0x02000000
138#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
139
140#define AGCSTS_A2P_TCOUNT 0x00000080
141#define AGCSTS_P2A_TCOUNT 0x00000040
142
143#define AGCSTS_FS_P2A_EMPTY 0x00000020
144#define AGCSTS_FS_P2A_HALF 0x00000010
145#define AGCSTS_FS_P2A_FULL 0x00000008
146
147#define AGCSTS_FS_A2P_EMPTY 0x00000004
148#define AGCSTS_FS_A2P_HALF 0x00000002
149#define AGCSTS_FS_A2P_FULL 0x00000001
150
151/****************************************************************************/
152/* AMCC - Add-on Interrupt Control/Status Register */
153/****************************************************************************/
154
155#define AINT_INT_MASK 0x00ff0000
156#define AINT_SEL_MASK 0x0000ffff
157#define AINT_IS_ENSEL_MASK 0x00001f1f
158
159#define AINT_INT_ASSERTED 0x00800000
160#define AINT_BM_ERROR 0x00200000
161#define AINT_BIST_INT 0x00100000
162
163#define AINT_RT_COMPLETE 0x00080000
164#define AINT_WT_COMPLETE 0x00040000
165
166#define AINT_OUT_MB_INT 0x00020000
167#define AINT_IN_MB_INT 0x00010000
168
169#define AINT_READ_COMPL 0x00008000
170#define AINT_WRITE_COMPL 0x00004000
171
172#define AINT_OMB_ENABLE 0x00001000
173#define AINT_OMB_SELECT 0x00000c00
174#define AINT_OMB_BYTE 0x00000300
175
176#define AINT_IMB_ENABLE 0x00000010
177#define AINT_IMB_SELECT 0x0000000c
178#define AINT_IMB_BYTE 0x00000003
179
180/* Enable Bus Mastering */
181#define EN_A2P_TRANSFERS 0x00000400
182/* FIFO Flag Reset */
183#define RESET_A2P_FLAGS 0x04000000L
184/* FIFO Relative Priority */
185#define A2P_HI_PRIORITY 0x00000100L
186/* Identify Interrupt Sources */
187#define ANY_S593X_INT 0x00800000L
188#define READ_TC_INT 0x00080000L
189#define WRITE_TC_INT 0x00040000L
190#define IN_MB_INT 0x00020000L
191#define MASTER_ABORT_INT 0x00100000L
192#define TARGET_ABORT_INT 0x00200000L
193#define BUS_MASTER_INT 0x00200000L
194
195/****************************************************************************/
196
197struct pcilst_struct {
198 struct pcilst_struct *next;
199 int used;
200 struct pci_dev *pcidev;
201 unsigned short vendor;
202 unsigned short device;
203 unsigned int master;
204 unsigned char pci_bus;
205 unsigned char pci_slot;
206 unsigned char pci_func;
207 unsigned int io_addr[5];
208 unsigned int irq;
209};
210
211struct pcilst_struct *amcc_devices; /* ptr to root list of all amcc devices */
212
213/****************************************************************************/
214
215void v_pci_card_list_init(unsigned short pci_vendor, char display);
216void v_pci_card_list_cleanup(unsigned short pci_vendor);
217struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
218 unsigned short
219 device_id);
220int i_find_free_pci_card_by_position(unsigned short vendor_id,
221 unsigned short device_id,
222 unsigned short pci_bus,
223 unsigned short pci_slot,
224 struct pcilst_struct **card);
225struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
226 unsigned short device_id,
227 unsigned short pci_bus,
228 unsigned short pci_slot);
229
230int i_pci_card_alloc(struct pcilst_struct *amcc);
231int i_pci_card_free(struct pcilst_struct *amcc);
232void v_pci_card_list_display(void);
233int i_pci_card_data(struct pcilst_struct *amcc,
234 unsigned char *pci_bus, unsigned char *pci_slot,
235 unsigned char *pci_func, unsigned short *io_addr,
236 unsigned short *irq, unsigned short *master);
237
238/****************************************************************************/
239
240/* build list of amcc cards in this system */
241void v_pci_card_list_init(unsigned short pci_vendor, char display)
242{
243 struct pci_dev *pcidev;
244 struct pcilst_struct *amcc, *last;
245 int i;
246
247 amcc_devices = NULL;
248 last = NULL;
249
250 pci_for_each_dev(pcidev) {
251 if (pcidev->vendor == pci_vendor) {
252 amcc = kzalloc(sizeof(*amcc), GFP_KERNEL);
253 if (amcc == NULL)
254 continue;
255
256 amcc->pcidev = pcidev;
257 if (last) {
258 last->next = amcc;
259 } else {
260 amcc_devices = amcc;
261 }
262 last = amcc;
263
264 amcc->vendor = pcidev->vendor;
265 amcc->device = pcidev->device;
266#if 0
267 amcc->master = pcidev->master; /* how get this information under 2.4 kernels? */
268#endif
269 amcc->pci_bus = pcidev->bus->number;
270 amcc->pci_slot = PCI_SLOT(pcidev->devfn);
271 amcc->pci_func = PCI_FUNC(pcidev->devfn);
272 for (i = 0; i < 5; i++)
273 amcc->io_addr[i] =
274 pcidev->resource[i].start & ~3UL;
275 amcc->irq = pcidev->irq;

178 more lines aren’t shown here.

drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c+9−9

This diff is large: its 81 lines aren’t shown here.

drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c+15−46

This diff is large: its 97 lines aren’t shown here.

drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c+29−52

This diff is large: its 129 lines aren’t shown here.

drivers/staging/comedi/drivers/addi_apci_all.c+0−18

This diff is large: its 19 lines aren’t shown here.

drivers/staging/comedi/drivers/adl_pci6208.c+87−96

This diff is large: its 292 lines aren’t shown here.

drivers/staging/comedi/drivers/adl_pci7230.c+0−190

This diff is large: its 191 lines aren’t shown here.

drivers/staging/comedi/drivers/adl_pci7296.c+0−183

This diff is large: its 184 lines aren’t shown here.

drivers/staging/comedi/drivers/adl_pci7432.c+0−200

This diff is large: its 201 lines aren’t shown here.

drivers/staging/comedi/drivers/adl_pci7x3x.c+332−0

This diff is large: its 333 lines aren’t shown here.

drivers/staging/comedi/drivers/adl_pci8164.c+17−56

This diff is large: its 138 lines aren’t shown here.

drivers/staging/comedi/drivers/adl_pci9111.c+278−695

This diff is large: its 1371 lines aren’t shown here.

drivers/staging/comedi/drivers/adl_pci9118.c+410−649

This diff is large: its 1492 lines aren’t shown here.

drivers/staging/comedi/drivers/adq12b.c+14−15

This diff is large: its 96 lines aren’t shown here.

drivers/staging/comedi/drivers/adv_pci1710.c+316−450

This diff is large: its 1205 lines aren’t shown here.

drivers/staging/comedi/drivers/adv_pci1723.c+58−164

This diff is large: its 312 lines aren’t shown here.

drivers/staging/comedi/drivers/adv_pci_dio.c+225−248

This diff is large: its 671 lines aren’t shown here.

drivers/staging/comedi/drivers/aio_aio12_8.c+137−81

This diff is large: its 311 lines aren’t shown here.

drivers/staging/comedi/drivers/aio_iiro_16.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/comedi/drivers/amplc_dio200.c+49−65

This diff is large: its 259 lines aren’t shown here.

drivers/staging/comedi/drivers/amplc_pc236.c+53−55

This diff is large: its 272 lines aren’t shown here.

drivers/staging/comedi/drivers/amplc_pc263.c+34−20

This diff is large: its 139 lines aren’t shown here.

drivers/staging/comedi/drivers/amplc_pci224.c+21−43

This diff is large: its 99 lines aren’t shown here.

drivers/staging/comedi/drivers/amplc_pci230.c+45−109

This diff is large: its 231 lines aren’t shown here.

drivers/staging/comedi/drivers/c6xdigio.c+3−3

This diff is large: its 27 lines aren’t shown here.

drivers/staging/comedi/drivers/cb_das16_cs.c+18−38

This diff is large: its 97 lines aren’t shown here.

drivers/staging/comedi/drivers/cb_pcidas.c+66−136

This diff is large: its 339 lines aren’t shown here.

drivers/staging/comedi/drivers/cb_pcidas64.c+41−87

This diff is large: its 260 lines aren’t shown here.

drivers/staging/comedi/drivers/cb_pcidda.c+175−266

This diff is large: its 530 lines aren’t shown here.

drivers/staging/comedi/drivers/cb_pcidio.c+0−211

This diff is large: its 212 lines aren’t shown here.

drivers/staging/comedi/drivers/cb_pcimdas.c+119−160

This diff is large: its 324 lines aren’t shown here.

drivers/staging/comedi/drivers/cb_pcimdda.c+92−301

This diff is large: its 443 lines aren’t shown here.

drivers/staging/comedi/drivers/comedi_bond.c+31−79

This diff is large: its 249 lines aren’t shown here.

drivers/staging/comedi/drivers/comedi_fc.h+32−0

This diff is large: its 37 lines aren’t shown here.

drivers/staging/comedi/drivers/comedi_parport.c+39−47

This diff is large: its 215 lines aren’t shown here.

drivers/staging/comedi/drivers/comedi_test.c+40−68

This diff is large: its 239 lines aren’t shown here.

drivers/staging/comedi/drivers/contec_pci_dio.c+45−101

This diff is large: its 209 lines aren’t shown here.

drivers/staging/comedi/drivers/daqboard2000.c+202−264

This diff is large: its 782 lines aren’t shown here.

drivers/staging/comedi/drivers/das08.c+149−333

This diff is large: its 854 lines aren’t shown here.

drivers/staging/comedi/drivers/das08.h+4−11

This diff is large: its 42 lines aren’t shown here.

drivers/staging/comedi/drivers/das08_cs.c+26−0

This diff is large: its 33 lines aren’t shown here.

drivers/staging/comedi/drivers/das16.c+31−51

This diff is large: its 183 lines aren’t shown here.

drivers/staging/comedi/drivers/das16m1.c+18−36

This diff is large: its 101 lines aren’t shown here.

drivers/staging/comedi/drivers/das1800.c+63−82

This diff is large: its 332 lines aren’t shown here.

drivers/staging/comedi/drivers/das6402.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/comedi/drivers/das800.c+16−36

This diff is large: its 93 lines aren’t shown here.

drivers/staging/comedi/drivers/dmm32at.c+19−38

This diff is large: its 98 lines aren’t shown here.

drivers/staging/comedi/drivers/dt2801.c+6−6

This diff is large: its 54 lines aren’t shown here.

drivers/staging/comedi/drivers/dt2811.c+4−4

This diff is large: its 36 lines aren’t shown here.

drivers/staging/comedi/drivers/dt2814.c+14−32

This diff is large: its 80 lines aren’t shown here.

drivers/staging/comedi/drivers/dt2815.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/comedi/drivers/dt2817.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/comedi/drivers/dt282x.c+29−74

This diff is large: its 171 lines aren’t shown here.

drivers/staging/comedi/drivers/dt3000.c+16−32

This diff is large: its 109 lines aren’t shown here.

drivers/staging/comedi/drivers/dt9812.c+4−4

This diff is large: its 36 lines aren’t shown here.

drivers/staging/comedi/drivers/dyna_pci10xx.c+36−125

This diff is large: its 288 lines aren’t shown here.

drivers/staging/comedi/drivers/fl512.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/comedi/drivers/gsc_hpdi.c+11−32

This diff is large: its 65 lines aren’t shown here.

drivers/staging/comedi/drivers/icp_multi.c+140−552

This diff is large: its 982 lines aren’t shown here.

drivers/staging/comedi/drivers/icp_multi.h+0−297

This diff is large: its 298 lines aren’t shown here.

drivers/staging/comedi/drivers/ii_pci20kc.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/comedi/drivers/jr3_pci.c+5−4

This diff is large: its 32 lines aren’t shown here.

drivers/staging/comedi/drivers/jr3_pci.h+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/comedi/drivers/ke_counter.c+35−68

This diff is large: its 154 lines aren’t shown here.

drivers/staging/comedi/drivers/me4000.c+618−1018

This diff is large: its 2388 lines aren’t shown here.

drivers/staging/comedi/drivers/me4000.h+0−409

This diff is large: its 410 lines aren’t shown here.

drivers/staging/comedi/drivers/me_daq.c+99−122

This diff is large: its 383 lines aren’t shown here.

drivers/staging/comedi/drivers/mite.c+135−150

This diff is large: its 450 lines aren’t shown here.

drivers/staging/comedi/drivers/mite.h+16−50

This diff is large: its 125 lines aren’t shown here.

drivers/staging/comedi/drivers/mpc624.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/comedi/drivers/mpc8260cpm.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/comedi/drivers/multiq3.c+8−6

This diff is large: its 57 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_6527.c+61−110

This diff is large: its 290 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_65xx.c+63−118

This diff is large: its 317 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_660x.c+46−87

This diff is large: its 271 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_670x.c+24−38

This diff is large: its 116 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_at_a2150.c+12−34

This diff is large: its 66 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_at_ao.c+4−4

This diff is large: its 36 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_atmio.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_atmio16d.c+26−41

This diff is large: its 137 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_daq_700.c+164−48

This diff is large: its 344 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_daq_dio24.c+8−4

This diff is large: its 33 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_labpc.c+198−269

This diff is large: its 925 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_labpc_cs.c+3−3

This diff is large: its 27 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_mio_common.c+88−152

This diff is large: its 539 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_mio_cs.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_pcidio.c+169−303

This diff is large: its 707 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_pcimio.c+30−40

This diff is large: its 131 lines aren’t shown here.

drivers/staging/comedi/drivers/ni_tiocmd.c+18−43

This diff is large: its 87 lines aren’t shown here.

drivers/staging/comedi/drivers/pcl711.c+18−35

This diff is large: its 108 lines aren’t shown here.

drivers/staging/comedi/drivers/pcl724.c+9−6

This diff is large: its 42 lines aren’t shown here.

drivers/staging/comedi/drivers/pcl725.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/comedi/drivers/pcl726.c+3−3

This diff is large: its 27 lines aren’t shown here.

drivers/staging/comedi/drivers/pcl730.c+4−4

This diff is large: its 36 lines aren’t shown here.

drivers/staging/comedi/drivers/pcl812.c+20−37

This diff is large: its 125 lines aren’t shown here.

drivers/staging/comedi/drivers/pcl816.c+14−38

This diff is large: its 94 lines aren’t shown here.

drivers/staging/comedi/drivers/pcl818.c+20−39

This diff is large: its 143 lines aren’t shown here.

drivers/staging/comedi/drivers/pcm3724.c+17−9

This diff is large: its 81 lines aren’t shown here.

drivers/staging/comedi/drivers/pcm3730.c+6−6

This diff is large: its 54 lines aren’t shown here.

drivers/staging/comedi/drivers/pcm_common.c+13−43

This diff is large: its 74 lines aren’t shown here.

drivers/staging/comedi/drivers/pcmad.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/comedi/drivers/pcmda12.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/comedi/drivers/pcmmio.c+10−22

This diff is large: its 78 lines aren’t shown here.

drivers/staging/comedi/drivers/pcmuio.c+7−7

This diff is large: its 49 lines aren’t shown here.

drivers/staging/comedi/drivers/poc.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/comedi/drivers/quatech_daqp_cs.c+20−43

This diff is large: its 111 lines aren’t shown here.

drivers/staging/comedi/drivers/rtd520.c+21−46

This diff is large: its 129 lines aren’t shown here.

drivers/staging/comedi/drivers/rti800.c+5−5

This diff is large: its 45 lines aren’t shown here.

drivers/staging/comedi/drivers/rti802.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/comedi/drivers/s526.c+153−449

This diff is large: its 923 lines aren’t shown here.

drivers/staging/comedi/drivers/s626.c+303−452

This diff is large: its 910 lines aren’t shown here.

drivers/staging/comedi/drivers/s626.h+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/comedi/drivers/serial2002.c+8−6

This diff is large: its 56 lines aren’t shown here.

drivers/staging/comedi/drivers/skel.c+28−46

This diff is large: its 120 lines aren’t shown here.

drivers/staging/comedi/drivers/ssv_dnp.c+2−5

This diff is large: its 34 lines aren’t shown here.

drivers/staging/comedi/drivers/usbdux.c+52−149

This diff is large: its 353 lines aren’t shown here.

drivers/staging/comedi/drivers/usbduxfast.c+23−97

This diff is large: its 196 lines aren’t shown here.

drivers/staging/comedi/drivers/usbduxsigma.c+45−147

This diff is large: its 323 lines aren’t shown here.

drivers/staging/comedi/drivers/vmk80xx.c+8−6

This diff is large: its 70 lines aren’t shown here.

drivers/staging/comedi/kcomedilib/kcomedilib_main.c+13−10

This diff is large: its 87 lines aren’t shown here.

drivers/staging/comedi/range.c+10−8

This diff is large: its 50 lines aren’t shown here.

drivers/staging/cptm1217/clearpad_tm1217.c+1−12

This diff is large: its 20 lines aren’t shown here.

drivers/staging/crystalhd/crystalhd_lnx.c+5−1

This diff is large: its 26 lines aren’t shown here.

drivers/staging/csr/Makefile+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/csr/bh.c+90−83

This diff is large: its 219 lines aren’t shown here.

drivers/staging/csr/csr_formatted_io.c+0−27

This diff is large: its 28 lines aren’t shown here.

drivers/staging/csr/csr_formatted_io.h+0−25

This diff is large: its 26 lines aren’t shown here.

drivers/staging/csr/csr_framework_ext.c+1−12

This diff is large: its 22 lines aren’t shown here.

drivers/staging/csr/csr_panic.c+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/csr/csr_time.c+9−18

This diff is large: its 44 lines aren’t shown here.

drivers/staging/csr/csr_wifi_hip_card_sdio.c+4−4

This diff is large: its 32 lines aren’t shown here.

drivers/staging/csr/csr_wifi_hip_download.c+2−0

This diff is large: its 16 lines aren’t shown here.

drivers/staging/csr/csr_wifi_hip_send.c+2−7

This diff is large: its 16 lines aren’t shown here.

drivers/staging/csr/csr_wifi_hip_udi.c+47−47

This diff is large: its 246 lines aren’t shown here.

drivers/staging/csr/csr_wifi_hip_unifi.h+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/csr/drv.c+9−37

This diff is large: its 100 lines aren’t shown here.

drivers/staging/csr/firmware.c+2−4

This diff is large: its 20 lines aren’t shown here.

drivers/staging/csr/io.c+17−36

This diff is large: its 137 lines aren’t shown here.

drivers/staging/csr/monitor.c+1−6

This diff is large: its 29 lines aren’t shown here.

drivers/staging/csr/netdev.c+6−624

This diff is large: its 874 lines aren’t shown here.

drivers/staging/csr/sdio_events.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/csr/sdio_mmc.c+21−44

This diff is large: its 208 lines aren’t shown here.

drivers/staging/csr/sme_blocking.c+2−2

This diff is large: its 13 lines aren’t shown here.

drivers/staging/csr/sme_native.c+1−5

This diff is large: its 21 lines aren’t shown here.

drivers/staging/csr/sme_sys.c+8−14

This diff is large: its 111 lines aren’t shown here.

drivers/staging/csr/sme_wext.c+3−5

This diff is large: its 29 lines aren’t shown here.

drivers/staging/csr/ul_int.c+1−4

This diff is large: its 20 lines aren’t shown here.

drivers/staging/csr/unifi_pdu_processing.c+1−4

This diff is large: its 19 lines aren’t shown here.

drivers/staging/csr/unifi_priv.h+0−40

This diff is large: its 80 lines aren’t shown here.

drivers/staging/csr/unifi_wext.h+6−21

This diff is large: its 59 lines aren’t shown here.

drivers/staging/csr/wext_events.c+3−5

This diff is large: its 15 lines aren’t shown here.

drivers/staging/cxt1e1/linux.c+6−6

This diff is large: its 26 lines aren’t shown here.

drivers/staging/cxt1e1/musycc.c+5−5

This diff is large: its 29 lines aren’t shown here.

drivers/staging/et131x/et131x.c+1−6

This diff is large: its 14 lines aren’t shown here.

drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c+17−17

This diff is large: its 45 lines aren’t shown here.

drivers/staging/ft1000/ft1000-usb/ft1000_hw.c+7−7

This diff is large: its 63 lines aren’t shown here.

drivers/staging/ft1000/ft1000-usb/ft1000_usb.h+0−2

This diff is large: its 9 lines aren’t shown here.

drivers/staging/gdm72xx/gdm_qos.c+59−59

This diff is large: its 208 lines aren’t shown here.

drivers/staging/gdm72xx/gdm_qos.h+29−29

This diff is large: its 85 lines aren’t shown here.

drivers/staging/gdm72xx/gdm_sdio.c+11−26

This diff is large: its 68 lines aren’t shown here.

drivers/staging/gdm72xx/gdm_usb.c+24−38

This diff is large: its 129 lines aren’t shown here.

drivers/staging/gdm72xx/gdm_usb.h+8−8

This diff is large: its 57 lines aren’t shown here.

drivers/staging/gdm72xx/gdm_wimax.c+10−6

This diff is large: its 23 lines aren’t shown here.

drivers/staging/gdm72xx/usb_boot.c+100−120

This diff is large: its 377 lines aren’t shown here.

drivers/staging/iio/Documentation/generic_buffer.c+10−0

This diff is large: its 17 lines aren’t shown here.

drivers/staging/iio/Documentation/inkernel.txt+3−3

This diff is large: its 15 lines aren’t shown here.

drivers/staging/iio/Kconfig+1−1

This diff is large: its 7 lines aren’t shown here.

drivers/staging/iio/TODO+1−1

This diff is large: its 7 lines aren’t shown here.

drivers/staging/iio/accel/adis16201_core.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/iio/accel/adis16201_ring.c+1−2

This diff is large: its 17 lines aren’t shown here.

drivers/staging/iio/accel/adis16203_core.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/iio/accel/adis16203_ring.c+1−4

This diff is large: its 19 lines aren’t shown here.

drivers/staging/iio/accel/adis16204_core.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/iio/accel/adis16204_ring.c+1−2

This diff is large: its 17 lines aren’t shown here.

drivers/staging/iio/accel/adis16209_core.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/iio/accel/adis16209_ring.c+1−2

This diff is large: its 17 lines aren’t shown here.

drivers/staging/iio/accel/adis16220_core.c+4−7

This diff is large: its 39 lines aren’t shown here.

drivers/staging/iio/accel/adis16240_core.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/iio/accel/adis16240_ring.c+1−2

This diff is large: its 17 lines aren’t shown here.

drivers/staging/iio/accel/kxsd9.c+3−3

This diff is large: its 26 lines aren’t shown here.

drivers/staging/iio/accel/lis3l02dq.h+7−7

This diff is large: its 62 lines aren’t shown here.

drivers/staging/iio/accel/lis3l02dq_core.c+10−16

This diff is large: its 81 lines aren’t shown here.

drivers/staging/iio/accel/lis3l02dq_ring.c+15−16

This diff is large: its 106 lines aren’t shown here.

drivers/staging/iio/accel/sca3000.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/accel/sca3000_core.c+6−8

This diff is large: its 45 lines aren’t shown here.

drivers/staging/iio/accel/sca3000_ring.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/adc/Kconfig+20−23

This diff is large: its 83 lines aren’t shown here.

drivers/staging/iio/adc/Makefile+1−4

This diff is large: its 17 lines aren’t shown here.

drivers/staging/iio/adc/ad7192.c+67−456

This diff is large: its 744 lines aren’t shown here.

drivers/staging/iio/adc/ad7298_core.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/adc/ad7298_ring.c+1−2

This diff is large: its 17 lines aren’t shown here.

drivers/staging/iio/adc/ad7476.h+0−66

This diff is large: its 67 lines aren’t shown here.

drivers/staging/iio/adc/ad7476_ring.c+0−64

This diff is large: its 65 lines aren’t shown here.

drivers/staging/iio/adc/ad7606.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/adc/ad7606_core.c+3−3

This diff is large: its 27 lines aren’t shown here.

drivers/staging/iio/adc/ad7606_ring.c+1−2

This diff is large: its 17 lines aren’t shown here.

drivers/staging/iio/adc/ad7780.c+109−128

This diff is large: its 369 lines aren’t shown here.

drivers/staging/iio/adc/ad7793.c+121−567

This diff is large: its 911 lines aren’t shown here.

drivers/staging/iio/adc/ad7793.h+9−1

This diff is large: its 34 lines aren’t shown here.

drivers/staging/iio/adc/ad7887_core.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/adc/ad7887_ring.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/adc/ad799x_ring.c+1−2

This diff is large: its 17 lines aren’t shown here.

drivers/staging/iio/adc/lpc32xx_adc.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/adc/max1363.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/adc/max1363_core.c+16−16

This diff is large: its 78 lines aren’t shown here.

drivers/staging/iio/adc/max1363_ring.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/adc/mxs-lradc.c+590−0

This diff is large: its 591 lines aren’t shown here.

drivers/staging/iio/adc/spear_adc.c+9−18

This diff is large: its 80 lines aren’t shown here.

drivers/staging/iio/gyro/adis16060_core.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/iio/gyro/adis16080_core.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/gyro/adis16130_core.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/gyro/adis16260_core.c+3−9

This diff is large: its 28 lines aren’t shown here.

drivers/staging/iio/gyro/adis16260_ring.c+1−2

This diff is large: its 17 lines aren’t shown here.

drivers/staging/iio/gyro/adxrs450_core.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/iio_dummy_evgen.c+1−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/iio/iio_hwmon.c+7−40

This diff is large: its 67 lines aren’t shown here.

drivers/staging/iio/iio_simple_dummy.c+9−15

This diff is large: its 66 lines aren’t shown here.

drivers/staging/iio/iio_simple_dummy.h+4−2

This diff is large: its 15 lines aren’t shown here.

drivers/staging/iio/iio_simple_dummy_buffer.c+11−2

This diff is large: its 43 lines aren’t shown here.

drivers/staging/iio/impedance-analyzer/ad5933.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/iio/imu/adis16400.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/imu/adis16400_core.c+6−12

This diff is large: its 64 lines aren’t shown here.

drivers/staging/iio/imu/adis16400_ring.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/light/isl29018.c+15−2

This diff is large: its 51 lines aren’t shown here.

drivers/staging/iio/light/tsl2563.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/magnetometer/hmc5843.c+1−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/iio/meter/ade7753.c+4−9

This diff is large: its 25 lines aren’t shown here.

drivers/staging/iio/meter/ade7754.c+3−9

This diff is large: its 25 lines aren’t shown here.

drivers/staging/iio/meter/ade7758.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/meter/ade7758_core.c+4−9

This diff is large: its 39 lines aren’t shown here.

drivers/staging/iio/meter/ade7758_ring.c+1−2

This diff is large: its 17 lines aren’t shown here.

drivers/staging/iio/meter/ade7759.c+3−8

This diff is large: its 24 lines aren’t shown here.

drivers/staging/iio/meter/ade7854-spi.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/resolver/ad2s1210.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/ring_hw.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/ring_sw.c+3−4

This diff is large: its 23 lines aren’t shown here.

drivers/staging/iio/trigger/Kconfig+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/staging/iio/trigger/iio-trig-bfin-timer.c+88−21

This diff is large: its 214 lines aren’t shown here.

drivers/staging/iio/trigger/iio-trig-bfin-timer.h+24−0

This diff is large: its 25 lines aren’t shown here.

drivers/staging/iio/trigger/iio-trig-gpio.c+4−4

This diff is large: its 35 lines aren’t shown here.

drivers/staging/iio/trigger/iio-trig-periodic-rtc.c+4−4

This diff is large: its 35 lines aren’t shown here.

drivers/staging/iio/trigger/iio-trig-sysfs.c+16−1

This diff is large: its 48 lines aren’t shown here.

drivers/staging/imx-drm/Kconfig+35−0

This diff is large: its 36 lines aren’t shown here.

drivers/staging/imx-drm/Makefile+9−0

This diff is large: its 10 lines aren’t shown here.

drivers/staging/imx-drm/TODO+22−0

This diff is large: its 23 lines aren’t shown here.

drivers/staging/imx-drm/imx-drm-core.c+884−0

This diff is large: its 885 lines aren’t shown here.

drivers/staging/imx-drm/imx-drm.h+58−0

This diff is large: its 59 lines aren’t shown here.

drivers/staging/imx-drm/imx-fb.c+47−0

This diff is large: its 48 lines aren’t shown here.

drivers/staging/imx-drm/imx-fbdev.c+74−0

This diff is large: its 75 lines aren’t shown here.

drivers/staging/imx-drm/ipu-v3/Makefile+3−0

This diff is large: its 4 lines aren’t shown here.

drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h+318−0

This diff is large: its 319 lines aren’t shown here.

drivers/staging/imx-drm/ipu-v3/ipu-common.c+1143−0

This diff is large: its 1144 lines aren’t shown here.

drivers/staging/imx-drm/ipu-v3/ipu-dc.c+372−0

This diff is large: its 373 lines aren’t shown here.

drivers/staging/imx-drm/ipu-v3/ipu-di.c+700−0

This diff is large: its 701 lines aren’t shown here.

drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c+408−0

This diff is large: its 409 lines aren’t shown here.

drivers/staging/imx-drm/ipu-v3/ipu-dp.c+336−0

This diff is large: its 337 lines aren’t shown here.

drivers/staging/imx-drm/ipu-v3/ipu-prv.h+206−0

This diff is large: its 207 lines aren’t shown here.

drivers/staging/imx-drm/ipuv3-crtc.c+579−0

This diff is large: its 580 lines aren’t shown here.

drivers/staging/imx-drm/parallel-display.c+261−0

This diff is large: its 262 lines aren’t shown here.

drivers/staging/ipack/Kconfig+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/staging/ipack/TODO+2−23

This diff is large: its 32 lines aren’t shown here.

drivers/staging/ipack/bridges/tpci200.c+306−429

This diff is large: its 978 lines aren’t shown here.

drivers/staging/ipack/bridges/tpci200.h+27−12

This diff is large: its 120 lines aren’t shown here.

drivers/staging/ipack/devices/ipoctal.c+321−417

This diff is large: its 1032 lines aren’t shown here.

drivers/staging/ipack/devices/scc2698.h+58−59

This diff is large: its 142 lines aren’t shown here.

drivers/staging/ipack/ipack.c+350−22

This diff is large: its 453 lines aren’t shown here.

drivers/staging/ipack/ipack.h+61−27

This diff is large: its 181 lines aren’t shown here.

drivers/staging/ipack/ipack_ids.h+32−0

This diff is large: its 33 lines aren’t shown here.

drivers/staging/keucr/smcommon.h+0−2

This diff is large: its 8 lines aren’t shown here.

drivers/staging/line6/pcm.c+7−1

This diff is large: its 15 lines aren’t shown here.

drivers/staging/line6/variax.c+4−4

This diff is large: its 26 lines aren’t shown here.

drivers/staging/nvec/Kconfig+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/nvec/nvec.c+13−12

This diff is large: its 98 lines aren’t shown here.

drivers/staging/olpc_dcon/olpc_dcon.c+24−29

This diff is large: its 199 lines aren’t shown here.

drivers/staging/olpc_dcon/olpc_dcon_xo_1.c+9−6

This diff is large: its 48 lines aren’t shown here.

drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c+4−2

This diff is large: its 27 lines aren’t shown here.

drivers/staging/omap-thermal/omap-bandgap.c+12−11

This diff is large: its 63 lines aren’t shown here.

drivers/staging/omap-thermal/omap-thermal-common.c+36−6

This diff is large: its 88 lines aren’t shown here.

drivers/staging/omap-thermal/omap4-thermal.c+27−27

This diff is large: its 75 lines aren’t shown here.

drivers/staging/omap-thermal/omap5-thermal.c+19−19

This diff is large: its 49 lines aren’t shown here.

drivers/staging/omapdrm/omap_crtc.c+31−2

This diff is large: its 76 lines aren’t shown here.

drivers/staging/omapdrm/omap_dmm_tiler.c+43−8

This diff is large: its 101 lines aren’t shown here.

drivers/staging/omapdrm/omap_dmm_tiler.h+15−2

This diff is large: its 31 lines aren’t shown here.

drivers/staging/omapdrm/omap_drv.c+18−3

This diff is large: its 49 lines aren’t shown here.

drivers/staging/omapdrm/omap_drv.h+31−2

This diff is large: its 63 lines aren’t shown here.

drivers/staging/omapdrm/omap_fb.c+85−14

This diff is large: its 131 lines aren’t shown here.

drivers/staging/omapdrm/omap_gem.c+58−2

This diff is large: its 107 lines aren’t shown here.

drivers/staging/omapdrm/omap_plane.c+90−21

This diff is large: its 182 lines aren’t shown here.

drivers/staging/ozwpan/ozcdev.c+7−7

This diff is large: its 54 lines aren’t shown here.

drivers/staging/ozwpan/ozevent.c+3−3

This diff is large: its 20 lines aren’t shown here.

drivers/staging/ozwpan/ozhcd.c+80−24

This diff is large: its 206 lines aren’t shown here.

drivers/staging/ozwpan/ozmain.c+1−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/ozwpan/ozpd.c+2−9

This diff is large: its 32 lines aren’t shown here.

drivers/staging/ozwpan/ozpd.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/staging/ozwpan/ozproto.c+13−0

This diff is large: its 20 lines aren’t shown here.

drivers/staging/ozwpan/ozproto.h+7−1

This diff is large: its 22 lines aren’t shown here.

drivers/staging/ozwpan/ozprotocol.h+5−1

This diff is large: its 20 lines aren’t shown here.

drivers/staging/panel/panel.c+26−26

This diff is large: its 190 lines aren’t shown here.

drivers/staging/ramster/Kconfig+21−4

This diff is large: its 35 lines aren’t shown here.

drivers/staging/ramster/Makefile+6−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/ramster/TODO+0−13

This diff is large: its 14 lines aren’t shown here.

drivers/staging/ramster/cluster/Makefile+0−3

This diff is large: its 4 lines aren’t shown here.

drivers/staging/ramster/ramster.h+27−86

This diff is large: its 146 lines aren’t shown here.

drivers/staging/ramster/ramster/heartbeat.crenamed from drivers/staging/ramster/cluster/heartbeat.c+2−4

This diff is large: its 20 lines aren’t shown here.

drivers/staging/ramster/ramster/heartbeat.hrenamed from drivers/staging/ramster/cluster/heartbeat.h+0−0

File renamed without changes.

drivers/staging/ramster/ramster/masklog.crenamed from drivers/staging/ramster/cluster/masklog.c+0−0

File renamed without changes.

drivers/staging/ramster/ramster/masklog.hrenamed from drivers/staging/ramster/cluster/masklog.h+0−0

File renamed without changes.

drivers/staging/ramster/ramster/nodemanager.crenamed from drivers/staging/ramster/cluster/nodemanager.c+9−6

This diff is large: its 47 lines aren’t shown here.

drivers/staging/ramster/ramster/nodemanager.hrenamed from drivers/staging/ramster/cluster/nodemanager.h+0−0

File renamed without changes.

drivers/staging/ramster/ramster/r2net.crenamed from drivers/staging/ramster/r2net.c+46−33

This diff is large: its 208 lines aren’t shown here.

drivers/staging/ramster/ramster/ramster.c+985−0

This diff is large: its 986 lines aren’t shown here.

drivers/staging/ramster/ramster/ramster.h+161−0

This diff is large: its 162 lines aren’t shown here.

drivers/staging/ramster/ramster/ramster_nodemanager.hrenamed from drivers/staging/ramster/cluster/ramster_nodemanager.h+0−0

File renamed without changes.

drivers/staging/ramster/ramster/tcp.crenamed from drivers/staging/ramster/cluster/tcp.c+25−28

This diff is large: its 210 lines aren’t shown here.

drivers/staging/ramster/ramster/tcp.hrenamed from drivers/staging/ramster/cluster/tcp.h+0−0

File renamed without changes.

drivers/staging/ramster/ramster/tcp_internal.hrenamed from drivers/staging/ramster/cluster/tcp_internal.h+0−0

File renamed without changes.

drivers/staging/ramster/tmem.c+178−135

This diff is large: its 552 lines aren’t shown here.

drivers/staging/ramster/tmem.h+62−47

This diff is large: its 199 lines aren’t shown here.

drivers/staging/ramster/xvmalloc.c+0−509

This diff is large: its 510 lines aren’t shown here.

drivers/staging/ramster/xvmalloc.h+0−30

This diff is large: its 31 lines aren’t shown here.

drivers/staging/ramster/xvmalloc_int.h+0−95

This diff is large: its 96 lines aren’t shown here.

drivers/staging/ramster/zbud.c+1060−0

This diff is large: its 1061 lines aren’t shown here.

drivers/staging/ramster/zbud.h+33−0

This diff is large: its 34 lines aren’t shown here.

drivers/staging/ramster/zcache-main.c+1033−2533

This diff is large: its 4199 lines aren’t shown here.

drivers/staging/ramster/zcache.h+43−12

This diff is large: its 66 lines aren’t shown here.

drivers/staging/rtl8187se/ieee80211/ieee80211.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c+3−10

This diff is large: its 34 lines aren’t shown here.

drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c+3−2

This diff is large: its 26 lines aren’t shown here.

drivers/staging/rtl8187se/r8180_core.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/rtl8187se/r8180_hw.h+7−2

This diff is large: its 19 lines aren’t shown here.

drivers/staging/rtl8187se/r8185b_init.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c+5−4

This diff is large: its 16 lines aren’t shown here.

drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h+4−0

This diff is large: its 11 lines aren’t shown here.

drivers/staging/rtl8192e/rtl8192e/rtl_core.c+4−2

This diff is large: its 20 lines aren’t shown here.

drivers/staging/rtl8192e/rtl8192e/rtl_dm.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/rtl8192e/rtllib.h+4−4

This diff is large: its 27 lines aren’t shown here.

drivers/staging/rtl8192e/rtllib_softmac.c+8−16

This diff is large: its 80 lines aren’t shown here.

drivers/staging/rtl8192e/rtllib_softmac_wx.c+4−3

This diff is large: its 35 lines aren’t shown here.

drivers/staging/rtl8192u/ieee80211/ieee80211.h+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c+7−13

This diff is large: its 62 lines aren’t shown here.

drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c+3−2

This diff is large: its 26 lines aren’t shown here.

drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c+1−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/rtl8192u/r8192U_core.c+8−19

This diff is large: its 43 lines aren’t shown here.

drivers/staging/rtl8192u/r819xU_HTType.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/rtl8192u/r819xU_phyreg.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/rtl8712/drv_types.h+0−9

This diff is large: its 24 lines aren’t shown here.

drivers/staging/rtl8712/ethernet.h+0−8

This diff is large: its 15 lines aren’t shown here.

drivers/staging/rtl8712/os_intfs.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/rtl8712/rtl8712_recv.c+8−1

This diff is large: its 29 lines aren’t shown here.

drivers/staging/rtl8712/rtl8712_recv.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/rtl8712/rtl8712_xmit.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/rtl8712/rtl871x_ioctl_linux.c+1−3

This diff is large: its 11 lines aren’t shown here.

drivers/staging/rtl8712/rtl871x_ioctl_set.c+1−4

This diff is large: its 12 lines aren’t shown here.

drivers/staging/rtl8712/rtl871x_mlme.c+3−2

This diff is large: its 20 lines aren’t shown here.

drivers/staging/rtl8712/rtl871x_pwrctrl.h+0−20

This diff is large: its 35 lines aren’t shown here.

drivers/staging/rtl8712/rtl871x_recv.c+5−4

This diff is large: its 30 lines aren’t shown here.

drivers/staging/rtl8712/rtl871x_security.c+4−4

This diff is large: its 36 lines aren’t shown here.

drivers/staging/rtl8712/usb_intf.c+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/rtl8712/usb_osintf.h+0−3

This diff is large: its 10 lines aren’t shown here.

drivers/staging/rtl8712/usb_vendor_req.h+0−58

This diff is large: its 59 lines aren’t shown here.

drivers/staging/rts5139/rts51x_fop.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/rts5139/trace.h+3−29

This diff is large: its 39 lines aren’t shown here.

drivers/staging/rts_pstor/ms.c+340−532

This diff is large: its 2330 lines aren’t shown here.

drivers/staging/rts_pstor/rtsx.c+54−58

This diff is large: its 374 lines aren’t shown here.

drivers/staging/rts_pstor/rtsx_card.c+81−105

This diff is large: its 439 lines aren’t shown here.

drivers/staging/rts_pstor/rtsx_chip.c+246−317

This diff is large: its 1377 lines aren’t shown here.

drivers/staging/rts_pstor/rtsx_scsi.c+169−236

This diff is large: its 1057 lines aren’t shown here.

drivers/staging/rts_pstor/rtsx_transport.c+45−55

This diff is large: its 231 lines aren’t shown here.

drivers/staging/rts_pstor/sd.c+415−640

This diff is large: its 2761 lines aren’t shown here.

drivers/staging/rts_pstor/trace.h+3−27

This diff is large: its 37 lines aren’t shown here.

drivers/staging/sbe-2t3e3/2t3e3.h+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/sbe-2t3e3/dc.c+6−4

This diff is large: its 45 lines aren’t shown here.

drivers/staging/sbe-2t3e3/module.c+11−4

This diff is large: its 42 lines aren’t shown here.

drivers/staging/sbe-2t3e3/netdev.c+4−4

This diff is large: its 34 lines aren’t shown here.

drivers/staging/sep/sep_main.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/serqt_usb2/serqt_usb2.c+3−8

This diff is large: its 60 lines aren’t shown here.

drivers/staging/silicom/Kconfig+46−0

This diff is large: its 47 lines aren’t shown here.

drivers/staging/silicom/Makefile+9−0

This diff is large: its 10 lines aren’t shown here.

drivers/staging/silicom/README+14−0

This diff is large: its 15 lines aren’t shown here.

drivers/staging/silicom/TODO+8−0

This diff is large: its 9 lines aren’t shown here.

drivers/staging/silicom/bits.h+56−0

This diff is large: its 57 lines aren’t shown here.

drivers/staging/silicom/bp_ioctl.h+140−0

This diff is large: its 141 lines aren’t shown here.

drivers/staging/silicom/bp_mod.c+8931−0

This diff is large: its 8932 lines aren’t shown here.

drivers/staging/silicom/bp_mod.h+704−0

This diff is large: its 705 lines aren’t shown here.

drivers/staging/silicom/bp_proc.c+1350−0

This diff is large: its 1351 lines aren’t shown here.

drivers/staging/silicom/bypass.h+202−0

This diff is large: its 203 lines aren’t shown here.

drivers/staging/silicom/bypasslib/Makefile+6−0

This diff is large: its 7 lines aren’t shown here.

drivers/staging/silicom/bypasslib/bp_ioctl.h+198−0

This diff is large: its 199 lines aren’t shown here.

drivers/staging/silicom/bypasslib/bplibk.h+47−0

This diff is large: its 48 lines aren’t shown here.

drivers/staging/silicom/bypasslib/bypass.c+529−0

This diff is large: its 530 lines aren’t shown here.

drivers/staging/silicom/bypasslib/libbp_sd.h+509−0

This diff is large: its 510 lines aren’t shown here.

drivers/staging/silicom/libbp_sd.h+550−0

This diff is large: its 551 lines aren’t shown here.

drivers/staging/slicoss/slicoss.c+14−26

This diff is large: its 97 lines aren’t shown here.

drivers/staging/sm7xxfb/sm7xx.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/sm7xxfb/sm7xxfb.c+49−70

This diff is large: its 241 lines aren’t shown here.

drivers/staging/speakup/i18n.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/staging/speakup/speakup_soft.c+5−10

This diff is large: its 41 lines aren’t shown here.

drivers/staging/telephony/ixj.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/tidspbridge/Documentation/error-codes+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/tidspbridge/core/_tiomap.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/tidspbridge/core/chnl_sm.c+5−4

This diff is large: its 44 lines aren’t shown here.

drivers/staging/tidspbridge/core/dsp-clock.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/staging/tidspbridge/core/io_sm.c+5−5

This diff is large: its 38 lines aren’t shown here.

drivers/staging/tidspbridge/core/sync.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/tidspbridge/core/tiomap3430.c+4−4

This diff is large: its 31 lines aren’t shown here.

drivers/staging/tidspbridge/core/tiomap3430_pwr.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/tidspbridge/core/wdt.c+4−3

This diff is large: its 22 lines aren’t shown here.

drivers/staging/tidspbridge/dynload/tramp.c+4−4

This diff is large: its 36 lines aren’t shown here.

drivers/staging/tidspbridge/gen/uuidutil.c+0−21

This diff is large: its 28 lines aren’t shown here.

drivers/staging/tidspbridge/hw/hw_mmu.c+3−3

This diff is large: its 27 lines aren’t shown here.

drivers/staging/tidspbridge/include/dspbridge/dspioctl.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/tidspbridge/include/dspbridge/node.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/tidspbridge/include/dspbridge/ntfy.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/tidspbridge/include/dspbridge/proc.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/tidspbridge/include/dspbridge/strm.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/tidspbridge/include/dspbridge/sync.h+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/tidspbridge/include/dspbridge/uuidutil.h+0−20

This diff is large: its 27 lines aren’t shown here.

drivers/staging/tidspbridge/rmgr/dbdcd.c+23−6

This diff is large: its 88 lines aren’t shown here.

drivers/staging/tidspbridge/rmgr/drv_interface.c+1−13

This diff is large: its 25 lines aren’t shown here.

drivers/staging/tidspbridge/rmgr/dspdrv.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/tidspbridge/rmgr/mgr.c+2−2

This diff is large: its 11 lines aren’t shown here.

drivers/staging/tidspbridge/rmgr/nldr.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/tidspbridge/rmgr/node.c+2−3

This diff is large: its 19 lines aren’t shown here.

drivers/staging/tidspbridge/rmgr/proc.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/usbip/Kconfig+2−2

This diff is large: its 9 lines aren’t shown here.

drivers/staging/usbip/stub_dev.c+6−2

This diff is large: its 17 lines aren’t shown here.

drivers/staging/usbip/stub_rx.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/usbip/usbip_common.c+4−0

This diff is large: its 19 lines aren’t shown here.

drivers/staging/usbip/userspace/configure.ac+6−6

This diff is large: its 28 lines aren’t shown here.

drivers/staging/usbip/userspace/doc/usbip.8+42−24

This diff is large: its 112 lines aren’t shown here.

drivers/staging/usbip/userspace/doc/usbip_bind_driver.8+0−42

This diff is large: its 43 lines aren’t shown here.

drivers/staging/usbip/userspace/doc/usbipd.8+10−6

This diff is large: its 41 lines aren’t shown here.

drivers/staging/usbip/vhci_hcd.c+22−9

This diff is large: its 90 lines aren’t shown here.

drivers/staging/vme/devices/vme_pio2_core.c+5−5

This diff is large: its 28 lines aren’t shown here.

drivers/staging/vme/devices/vme_user.c+5−5

This diff is large: its 35 lines aren’t shown here.

drivers/staging/vt6655/80211mgr.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/baseband.c+86−86

This diff is large: its 463 lines aren’t shown here.

drivers/staging/vt6655/baseband.h+5−5

This diff is large: its 35 lines aren’t shown here.

drivers/staging/vt6655/bssdb.c+2−2

This diff is large: its 11 lines aren’t shown here.

drivers/staging/vt6655/card.c+51−50

This diff is large: its 337 lines aren’t shown here.

drivers/staging/vt6655/datarate.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/device.h+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/vt6655/device_main.c+48−56

This diff is large: its 196 lines aren’t shown here.

drivers/staging/vt6655/dpc.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/hostap.c+2−6

This diff is large: its 22 lines aren’t shown here.

drivers/staging/vt6655/ioctl.c+3−6

This diff is large: its 23 lines aren’t shown here.

drivers/staging/vt6655/iwctl.c+3−3

This diff is large: its 27 lines aren’t shown here.

drivers/staging/vt6655/key.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/mac.c+6−6

This diff is large: its 40 lines aren’t shown here.

drivers/staging/vt6655/mac.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/mib.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/power.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/rf.c+41−41

This diff is large: its 192 lines aren’t shown here.

drivers/staging/vt6655/rf.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/rxtx.c+21−21

This diff is large: its 173 lines aren’t shown here.

drivers/staging/vt6655/tcrc.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/tcrc.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/tether.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/vt6655/tkip.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/vntwifi.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/wcmd.c+3−3

This diff is large: its 20 lines aren’t shown here.

drivers/staging/vt6655/wmgr.c+28−28

This diff is large: its 237 lines aren’t shown here.

drivers/staging/vt6655/wmgr.h+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/vt6655/wpa.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6655/wpa2.c+4−4

This diff is large: its 29 lines aren’t shown here.

drivers/staging/vt6655/wpactl.c+3−3

This diff is large: its 27 lines aren’t shown here.

drivers/staging/vt6655/wroute.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/80211mgr.h+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/vt6656/baseband.c+3−3

This diff is large: its 27 lines aren’t shown here.

drivers/staging/vt6656/baseband.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/bssdb.c+9−9

This diff is large: its 60 lines aren’t shown here.

drivers/staging/vt6656/card.c+19−19

This diff is large: its 149 lines aren’t shown here.

drivers/staging/vt6656/device.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/dpc.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/hostap.c+13−17

This diff is large: its 96 lines aren’t shown here.

drivers/staging/vt6656/int.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/ioctl.c+4−7

This diff is large: its 32 lines aren’t shown here.

drivers/staging/vt6656/iwctl.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/key.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/vt6656/main_usb.c+10−10

This diff is large: its 81 lines aren’t shown here.

drivers/staging/vt6656/power.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/rf.c+29−29

This diff is large: its 166 lines aren’t shown here.

drivers/staging/vt6656/rf.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/rxtx.c+26−26

This diff is large: its 214 lines aren’t shown here.

drivers/staging/vt6656/tcrc.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/tcrc.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/tether.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/vt6656/tkip.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/wcmd.c+4−4

This diff is large: its 36 lines aren’t shown here.

drivers/staging/vt6656/wctl.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/wmgr.c+13−13

This diff is large: its 117 lines aren’t shown here.

drivers/staging/vt6656/wpa.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/vt6656/wpa2.c+3−3

This diff is large: its 20 lines aren’t shown here.

drivers/staging/vt6656/wpactl.c+3−3

This diff is large: its 27 lines aren’t shown here.

drivers/staging/winbond/Kconfig+1−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/winbond/localpara.h+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/winbond/mds.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/winbond/mto.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/winbond/phy_calibration.c+7−7

This diff is large: its 63 lines aren’t shown here.

drivers/staging/winbond/reg.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/winbond/sme_api.h+5−6

This diff is large: its 47 lines aren’t shown here.

drivers/staging/winbond/wb35reg.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/winbond/wb35tx.c+74−80

This diff is large: its 324 lines aren’t shown here.

drivers/staging/winbond/wb35tx_s.h+19−27

This diff is large: its 65 lines aren’t shown here.

drivers/staging/wlags49_h2/README.ubuntu+6−6

This diff is large: its 44 lines aren’t shown here.

drivers/staging/wlags49_h2/TODO+5−5

This diff is large: its 30 lines aren’t shown here.

drivers/staging/wlags49_h2/hcf.c+10−10

This diff is large: its 84 lines aren’t shown here.

drivers/staging/wlags49_h2/hcfcfg.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/wlags49_h2/hcfdef.h+3−3

This diff is large: its 19 lines aren’t shown here.

drivers/staging/wlags49_h2/mdd.h+4−4

This diff is large: its 34 lines aren’t shown here.

drivers/staging/wlags49_h2/sta_h2.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/wlags49_h2/sta_h25.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/wlags49_h2/wl_enc.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/wlags49_h2/wl_if.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/wlags49_h2/wl_internal.h+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/wlags49_h2/wl_main.c+9−9

This diff is large: its 81 lines aren’t shown here.

drivers/staging/wlags49_h2/wl_netdev.c+19−40

This diff is large: its 204 lines aren’t shown here.

drivers/staging/wlags49_h2/wl_pci.c+4−4

This diff is large: its 36 lines aren’t shown here.

drivers/staging/wlags49_h2/wl_priv.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/wlags49_h2/wl_profile.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/wlags49_h2/wl_version.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/wlags49_h2/wl_wext.c+14−13

This diff is large: its 125 lines aren’t shown here.

drivers/staging/wlags49_h25/Kconfig+1−1

This diff is large: its 6 lines aren’t shown here.

drivers/staging/wlags49_h25/TODO+4−4

This diff is large: its 29 lines aren’t shown here.

drivers/staging/wlan-ng/cfg80211.c+7−4

This diff is large: its 40 lines aren’t shown here.

drivers/staging/wlan-ng/hfa384x_usb.c+11−26

This diff is large: its 89 lines aren’t shown here.

drivers/staging/wlan-ng/p80211conv.c+3−6

This diff is large: its 36 lines aren’t shown here.

drivers/staging/wlan-ng/p80211netdev.c+4−17

This diff is large: its 70 lines aren’t shown here.

drivers/staging/wlan-ng/p80211netdev.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/wlan-ng/p80211req.c+69−83

This diff is large: its 187 lines aren’t shown here.

drivers/staging/wlan-ng/p80211types.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/wlan-ng/p80211wep.c+6−12

This diff is large: its 39 lines aren’t shown here.

drivers/staging/wlan-ng/prism2fw.c+28−28

This diff is large: its 164 lines aren’t shown here.

drivers/staging/wlan-ng/prism2sta.c+13−40

This diff is large: its 248 lines aren’t shown here.

drivers/staging/xgifb/XGI_main_26.c+25−20

This diff is large: its 122 lines aren’t shown here.

drivers/staging/xgifb/vb_def.h+0−21

This diff is large: its 43 lines aren’t shown here.

drivers/staging/xgifb/vb_init.c+1−4

This diff is large: its 26 lines aren’t shown here.

drivers/staging/xgifb/vb_setmode.c+170−431

This diff is large: its 986 lines aren’t shown here.

drivers/staging/xgifb/vb_struct.h+6−43

This diff is large: its 101 lines aren’t shown here.

drivers/staging/xgifb/vb_table.h+46−148

This diff is large: its 432 lines aren’t shown here.

drivers/staging/zcache/tmem.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/zsmalloc/zsmalloc-main.c+273−49

This diff is large: its 421 lines aren’t shown here.

drivers/staging/zsmalloc/zsmalloc_int.h+0−155

This diff is large: its 156 lines aren’t shown here.

include/linux/hid-sensor-hub.h+160−0

This diff is large: its 161 lines aren’t shown here.

include/linux/hid-sensor-ids.h+112−0

This diff is large: its 113 lines aren’t shown here.

include/linux/iio/adc/ad_sigma_delta.h+173−0

This diff is large: its 174 lines aren’t shown here.

include/linux/iio/buffer.h+2−4

This diff is large: its 21 lines aren’t shown here.

include/linux/iio/consumer.h+41−3

This diff is large: its 77 lines aren’t shown here.

include/linux/iio/iio.h+58−7

This diff is large: its 133 lines aren’t shown here.

include/linux/iio/kfifo_buf.h+3−0

This diff is large: its 11 lines aren’t shown here.

include/linux/iio/machine.h+5−0

This diff is large: its 16 lines aren’t shown here.

include/linux/iio/trigger.h+7−6

This diff is large: its 51 lines aren’t shown here.

include/linux/iio/trigger_consumer.h+11−0

This diff is large: its 22 lines aren’t shown here.

include/linux/iio/types.h+1−0

This diff is large: its 7 lines aren’t shown here.

include/linux/mod_devicetable.h+8−0

This diff is large: its 13 lines aren’t shown here.

include/linux/platform_data/ad5755.h+103−0

This diff is large: its 104 lines aren’t shown here.

include/linux/platform_data/ad7791.h+17−0

This diff is large: its 18 lines aren’t shown here.

include/linux/power/generic-adc-battery.h+29−0

This diff is large: its 30 lines aren’t shown here.

scripts/mod/file2alias.c+15−0

This diff is large: its 22 lines aren’t shown here.