smapi.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. /*
  2. *
  3. * smapi.c -- SMAPI interface routines
  4. *
  5. *
  6. * Written By: Mike Sullivan IBM Corporation
  7. *
  8. * Copyright (C) 1999 IBM Corporation
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * NO WARRANTY
  21. * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  22. * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  23. * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  24. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  25. * solely responsible for determining the appropriateness of using and
  26. * distributing the Program and assumes all risks associated with its
  27. * exercise of rights under this Agreement, including but not limited to
  28. * the risks and costs of program errors, damage to or loss of data,
  29. * programs or equipment, and unavailability or interruption of operations.
  30. *
  31. * DISCLAIMER OF LIABILITY
  32. * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  33. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  34. * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  35. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  36. * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  37. * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  38. * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  39. *
  40. * You should have received a copy of the GNU General Public License
  41. * along with this program; if not, write to the Free Software
  42. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  43. *
  44. *
  45. * 10/23/2000 - Alpha Release
  46. * First release to the public
  47. */
  48. #include <linux/kernel.h>
  49. #include <linux/mc146818rtc.h> /* CMOS defines */
  50. #include "smapi.h"
  51. #include "mwavedd.h"
  52. static unsigned short g_usSmapiPort = 0;
  53. static int smapi_request(unsigned short inBX, unsigned short inCX,
  54. unsigned short inDI, unsigned short inSI,
  55. unsigned short *outAX, unsigned short *outBX,
  56. unsigned short *outCX, unsigned short *outDX,
  57. unsigned short *outDI, unsigned short *outSI)
  58. {
  59. unsigned short myoutAX = 2, *pmyoutAX = &myoutAX;
  60. unsigned short myoutBX = 3, *pmyoutBX = &myoutBX;
  61. unsigned short myoutCX = 4, *pmyoutCX = &myoutCX;
  62. unsigned short myoutDX = 5, *pmyoutDX = &myoutDX;
  63. unsigned short myoutDI = 6, *pmyoutDI = &myoutDI;
  64. unsigned short myoutSI = 7, *pmyoutSI = &myoutSI;
  65. unsigned short usSmapiOK = -EIO, *pusSmapiOK = &usSmapiOK;
  66. unsigned int inBXCX = (inBX << 16) | inCX;
  67. unsigned int inDISI = (inDI << 16) | inSI;
  68. int retval = 0;
  69. PRINTK_5(TRACE_SMAPI, "inBX %x inCX %x inDI %x inSI %x\n",
  70. inBX, inCX, inDI, inSI);
  71. __asm__ __volatile__("movw $0x5380,%%ax\n\t"
  72. "movl %7,%%ebx\n\t"
  73. "shrl $16, %%ebx\n\t"
  74. "movw %7,%%cx\n\t"
  75. "movl %8,%%edi\n\t"
  76. "shrl $16,%%edi\n\t"
  77. "movw %8,%%si\n\t"
  78. "movw %9,%%dx\n\t"
  79. "out %%al,%%dx\n\t"
  80. "out %%al,$0x4F\n\t"
  81. "cmpb $0x53,%%ah\n\t"
  82. "je 2f\n\t"
  83. "1:\n\t"
  84. "orb %%ah,%%ah\n\t"
  85. "jnz 2f\n\t"
  86. "movw %%ax,%0\n\t"
  87. "movw %%bx,%1\n\t"
  88. "movw %%cx,%2\n\t"
  89. "movw %%dx,%3\n\t"
  90. "movw %%di,%4\n\t"
  91. "movw %%si,%5\n\t"
  92. "movw $1,%6\n\t"
  93. "2:\n\t":"=m"(*(unsigned short *) pmyoutAX),
  94. "=m"(*(unsigned short *) pmyoutBX),
  95. "=m"(*(unsigned short *) pmyoutCX),
  96. "=m"(*(unsigned short *) pmyoutDX),
  97. "=m"(*(unsigned short *) pmyoutDI),
  98. "=m"(*(unsigned short *) pmyoutSI),
  99. "=m"(*(unsigned short *) pusSmapiOK)
  100. :"m"(inBXCX), "m"(inDISI), "m"(g_usSmapiPort)
  101. :"%eax", "%ebx", "%ecx", "%edx", "%edi",
  102. "%esi");
  103. PRINTK_8(TRACE_SMAPI,
  104. "myoutAX %x myoutBX %x myoutCX %x myoutDX %x myoutDI %x myoutSI %x usSmapiOK %x\n",
  105. myoutAX, myoutBX, myoutCX, myoutDX, myoutDI, myoutSI,
  106. usSmapiOK);
  107. *outAX = myoutAX;
  108. *outBX = myoutBX;
  109. *outCX = myoutCX;
  110. *outDX = myoutDX;
  111. *outDI = myoutDI;
  112. *outSI = myoutSI;
  113. retval = (usSmapiOK == 1) ? 0 : -EIO;
  114. PRINTK_2(TRACE_SMAPI, "smapi::smapi_request exit retval %x\n", retval);
  115. return retval;
  116. }
  117. int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings)
  118. {
  119. int bRC;
  120. unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
  121. static const unsigned short ausDspBases[] = {
  122. 0x0030, 0x4E30, 0x8E30, 0xCE30,
  123. 0x0130, 0x0350, 0x0070, 0x0DB0 };
  124. static const unsigned short ausUartBases[] = {
  125. 0x03F8, 0x02F8, 0x03E8, 0x02E8 };
  126. PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg entry\n");
  127. bRC = smapi_request(0x1802, 0x0000, 0, 0,
  128. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  129. if (bRC) {
  130. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Error: Could not get DSP Settings. Aborting.\n");
  131. return bRC;
  132. }
  133. PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n");
  134. pSettings->bDSPPresent = ((usBX & 0x0100) != 0);
  135. pSettings->bDSPEnabled = ((usCX & 0x0001) != 0);
  136. pSettings->usDspIRQ = usSI & 0x00FF;
  137. pSettings->usDspDMA = (usSI & 0xFF00) >> 8;
  138. if ((usDI & 0x00FF) < ARRAY_SIZE(ausDspBases)) {
  139. pSettings->usDspBaseIO = ausDspBases[usDI & 0x00FF];
  140. } else {
  141. pSettings->usDspBaseIO = 0;
  142. }
  143. PRINTK_6(TRACE_SMAPI,
  144. "smapi::smapi_query_DSP_cfg get DSP Settings bDSPPresent %x bDSPEnabled %x usDspIRQ %x usDspDMA %x usDspBaseIO %x\n",
  145. pSettings->bDSPPresent, pSettings->bDSPEnabled,
  146. pSettings->usDspIRQ, pSettings->usDspDMA,
  147. pSettings->usDspBaseIO);
  148. /* check for illegal values */
  149. if ( pSettings->usDspBaseIO == 0 )
  150. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP base I/O address is 0\n");
  151. if ( pSettings->usDspIRQ == 0 )
  152. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP IRQ line is 0\n");
  153. bRC = smapi_request(0x1804, 0x0000, 0, 0,
  154. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  155. if (bRC) {
  156. PRINTK_ERROR("smapi::smapi_query_DSP_cfg: Error: Could not get DSP modem settings. Aborting.\n");
  157. return bRC;
  158. }
  159. PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n");
  160. pSettings->bModemEnabled = ((usCX & 0x0001) != 0);
  161. pSettings->usUartIRQ = usSI & 0x000F;
  162. if (((usSI & 0xFF00) >> 8) < ARRAY_SIZE(ausUartBases)) {
  163. pSettings->usUartBaseIO = ausUartBases[(usSI & 0xFF00) >> 8];
  164. } else {
  165. pSettings->usUartBaseIO = 0;
  166. }
  167. PRINTK_4(TRACE_SMAPI,
  168. "smapi::smapi_query_DSP_cfg get DSP modem settings bModemEnabled %x usUartIRQ %x usUartBaseIO %x\n",
  169. pSettings->bModemEnabled,
  170. pSettings->usUartIRQ,
  171. pSettings->usUartBaseIO);
  172. /* check for illegal values */
  173. if ( pSettings->usUartBaseIO == 0 )
  174. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART base I/O address is 0\n");
  175. if ( pSettings->usUartIRQ == 0 )
  176. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART IRQ line is 0\n");
  177. PRINTK_2(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg exit bRC %x\n", bRC);
  178. return bRC;
  179. }
  180. int smapi_set_DSP_cfg(void)
  181. {
  182. int bRC = -EIO;
  183. int i;
  184. unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
  185. static const unsigned short ausDspBases[] = {
  186. 0x0030, 0x4E30, 0x8E30, 0xCE30,
  187. 0x0130, 0x0350, 0x0070, 0x0DB0 };
  188. static const unsigned short ausUartBases[] = {
  189. 0x03F8, 0x02F8, 0x03E8, 0x02E8 };
  190. static const unsigned short ausDspIrqs[] = {
  191. 5, 7, 10, 11, 15 };
  192. static const unsigned short ausUartIrqs[] = {
  193. 3, 4 };
  194. unsigned short dspio_index = 0, uartio_index = 0;
  195. PRINTK_5(TRACE_SMAPI,
  196. "smapi::smapi_set_DSP_cfg entry mwave_3780i_irq %x mwave_3780i_io %x mwave_uart_irq %x mwave_uart_io %x\n",
  197. mwave_3780i_irq, mwave_3780i_io, mwave_uart_irq, mwave_uart_io);
  198. if (mwave_3780i_io) {
  199. for (i = 0; i < ARRAY_SIZE(ausDspBases); i++) {
  200. if (mwave_3780i_io == ausDspBases[i])
  201. break;
  202. }
  203. if (i == ARRAY_SIZE(ausDspBases)) {
  204. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_io address %x. Aborting.\n", mwave_3780i_io);
  205. return bRC;
  206. }
  207. dspio_index = i;
  208. }
  209. if (mwave_3780i_irq) {
  210. for (i = 0; i < ARRAY_SIZE(ausDspIrqs); i++) {
  211. if (mwave_3780i_irq == ausDspIrqs[i])
  212. break;
  213. }
  214. if (i == ARRAY_SIZE(ausDspIrqs)) {
  215. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_irq %x. Aborting.\n", mwave_3780i_irq);
  216. return bRC;
  217. }
  218. }
  219. if (mwave_uart_io) {
  220. for (i = 0; i < ARRAY_SIZE(ausUartBases); i++) {
  221. if (mwave_uart_io == ausUartBases[i])
  222. break;
  223. }
  224. if (i == ARRAY_SIZE(ausUartBases)) {
  225. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_io address %x. Aborting.\n", mwave_uart_io);
  226. return bRC;
  227. }
  228. uartio_index = i;
  229. }
  230. if (mwave_uart_irq) {
  231. for (i = 0; i < ARRAY_SIZE(ausUartIrqs); i++) {
  232. if (mwave_uart_irq == ausUartIrqs[i])
  233. break;
  234. }
  235. if (i == ARRAY_SIZE(ausUartIrqs)) {
  236. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_irq %x. Aborting.\n", mwave_uart_irq);
  237. return bRC;
  238. }
  239. }
  240. if (mwave_uart_irq || mwave_uart_io) {
  241. /* Check serial port A */
  242. bRC = smapi_request(0x1402, 0x0000, 0, 0,
  243. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  244. if (bRC) goto exit_smapi_request_error;
  245. /* bRC == 0 */
  246. if (usBX & 0x0100) { /* serial port A is present */
  247. if (usCX & 1) { /* serial port is enabled */
  248. if ((usSI & 0xFF) == mwave_uart_irq) {
  249. #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
  250. PRINTK_ERROR(KERN_ERR_MWAVE
  251. "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
  252. #else
  253. PRINTK_3(TRACE_SMAPI,
  254. "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
  255. #endif
  256. #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
  257. PRINTK_1(TRACE_SMAPI,
  258. "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
  259. bRC = smapi_request(0x1403, 0x0100, 0, usSI,
  260. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  261. if (bRC) goto exit_smapi_request_error;
  262. bRC = smapi_request(0x1402, 0x0000, 0, 0,
  263. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  264. if (bRC) goto exit_smapi_request_error;
  265. #else
  266. goto exit_conflict;
  267. #endif
  268. } else {
  269. if ((usSI >> 8) == uartio_index) {
  270. #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
  271. PRINTK_ERROR(KERN_ERR_MWAVE
  272. "smapi::smapi_set_DSP_cfg: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
  273. #else
  274. PRINTK_3(TRACE_SMAPI,
  275. "smapi::smapi_set_DSP_cfg: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
  276. #endif
  277. #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
  278. PRINTK_1(TRACE_SMAPI,
  279. "smapi::smapi_set_DSP_cfg Disabling conflicting serial port A\n");
  280. bRC = smapi_request (0x1403, 0x0100, 0, usSI,
  281. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  282. if (bRC) goto exit_smapi_request_error;
  283. bRC = smapi_request (0x1402, 0x0000, 0, 0,
  284. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  285. if (bRC) goto exit_smapi_request_error;
  286. #else
  287. goto exit_conflict;
  288. #endif
  289. }
  290. }
  291. }
  292. }
  293. /* Check serial port B */
  294. bRC = smapi_request(0x1404, 0x0000, 0, 0,
  295. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  296. if (bRC) goto exit_smapi_request_error;
  297. /* bRC == 0 */
  298. if (usBX & 0x0100) { /* serial port B is present */
  299. if (usCX & 1) { /* serial port is enabled */
  300. if ((usSI & 0xFF) == mwave_uart_irq) {
  301. #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
  302. PRINTK_ERROR(KERN_ERR_MWAVE
  303. "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
  304. #else
  305. PRINTK_3(TRACE_SMAPI,
  306. "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
  307. #endif
  308. #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
  309. PRINTK_1(TRACE_SMAPI,
  310. "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n");
  311. bRC = smapi_request(0x1405, 0x0100, 0, usSI,
  312. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  313. if (bRC) goto exit_smapi_request_error;
  314. bRC = smapi_request(0x1404, 0x0000, 0, 0,
  315. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  316. if (bRC) goto exit_smapi_request_error;
  317. #else
  318. goto exit_conflict;
  319. #endif
  320. } else {
  321. if ((usSI >> 8) == uartio_index) {
  322. #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
  323. PRINTK_ERROR(KERN_ERR_MWAVE
  324. "smapi::smapi_set_DSP_cfg: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
  325. #else
  326. PRINTK_3(TRACE_SMAPI,
  327. "smapi::smapi_set_DSP_cfg: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
  328. #endif
  329. #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
  330. PRINTK_1 (TRACE_SMAPI,
  331. "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n");
  332. bRC = smapi_request (0x1405, 0x0100, 0, usSI,
  333. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  334. if (bRC) goto exit_smapi_request_error;
  335. bRC = smapi_request (0x1404, 0x0000, 0, 0,
  336. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  337. if (bRC) goto exit_smapi_request_error;
  338. #else
  339. goto exit_conflict;
  340. #endif
  341. }
  342. }
  343. }
  344. }
  345. /* Check IR port */
  346. bRC = smapi_request(0x1700, 0x0000, 0, 0,
  347. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  348. if (bRC) goto exit_smapi_request_error;
  349. bRC = smapi_request(0x1704, 0x0000, 0, 0,
  350. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  351. if (bRC) goto exit_smapi_request_error;
  352. /* bRC == 0 */
  353. if ((usCX & 0xff) != 0xff) { /* IR port not disabled */
  354. if ((usCX & 0xff) == mwave_uart_irq) {
  355. #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
  356. PRINTK_ERROR(KERN_ERR_MWAVE
  357. "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);
  358. #else
  359. PRINTK_3(TRACE_SMAPI,
  360. "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);
  361. #endif
  362. #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
  363. PRINTK_1(TRACE_SMAPI,
  364. "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
  365. bRC = smapi_request(0x1701, 0x0100, 0, 0,
  366. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  367. if (bRC) goto exit_smapi_request_error;
  368. bRC = smapi_request(0x1700, 0, 0, 0,
  369. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  370. if (bRC) goto exit_smapi_request_error;
  371. bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
  372. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  373. if (bRC) goto exit_smapi_request_error;
  374. bRC = smapi_request(0x1704, 0x0000, 0, 0,
  375. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  376. if (bRC) goto exit_smapi_request_error;
  377. #else
  378. goto exit_conflict;
  379. #endif
  380. } else {
  381. if ((usSI & 0xff) == uartio_index) {
  382. #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
  383. PRINTK_ERROR(KERN_ERR_MWAVE
  384. "smapi::smapi_set_DSP_cfg: IR port base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI & 0xff], ausUartBases[uartio_index]);
  385. #else
  386. PRINTK_3(TRACE_SMAPI,
  387. "smapi::smapi_set_DSP_cfg: IR port base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI & 0xff], ausUartBases[uartio_index]);
  388. #endif
  389. #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
  390. PRINTK_1(TRACE_SMAPI,
  391. "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
  392. bRC = smapi_request(0x1701, 0x0100, 0, 0,
  393. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  394. if (bRC) goto exit_smapi_request_error;
  395. bRC = smapi_request(0x1700, 0, 0, 0,
  396. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  397. if (bRC) goto exit_smapi_request_error;
  398. bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
  399. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  400. if (bRC) goto exit_smapi_request_error;
  401. bRC = smapi_request(0x1704, 0x0000, 0, 0,
  402. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  403. if (bRC) goto exit_smapi_request_error;
  404. #else
  405. goto exit_conflict;
  406. #endif
  407. }
  408. }
  409. }
  410. }
  411. bRC = smapi_request(0x1802, 0x0000, 0, 0,
  412. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  413. if (bRC) goto exit_smapi_request_error;
  414. if (mwave_3780i_io) {
  415. usDI = dspio_index;
  416. }
  417. if (mwave_3780i_irq) {
  418. usSI = (usSI & 0xff00) | mwave_3780i_irq;
  419. }
  420. bRC = smapi_request(0x1803, 0x0101, usDI, usSI,
  421. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  422. if (bRC) goto exit_smapi_request_error;
  423. bRC = smapi_request(0x1804, 0x0000, 0, 0,
  424. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  425. if (bRC) goto exit_smapi_request_error;
  426. if (mwave_uart_io) {
  427. usSI = (usSI & 0x00ff) | (uartio_index << 8);
  428. }
  429. if (mwave_uart_irq) {
  430. usSI = (usSI & 0xff00) | mwave_uart_irq;
  431. }
  432. bRC = smapi_request(0x1805, 0x0101, 0, usSI,
  433. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  434. if (bRC) goto exit_smapi_request_error;
  435. bRC = smapi_request(0x1802, 0x0000, 0, 0,
  436. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  437. if (bRC) goto exit_smapi_request_error;
  438. bRC = smapi_request(0x1804, 0x0000, 0, 0,
  439. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  440. if (bRC) goto exit_smapi_request_error;
  441. /* normal exit: */
  442. PRINTK_1(TRACE_SMAPI, "smapi::smapi_set_DSP_cfg exit\n");
  443. return 0;
  444. exit_conflict:
  445. /* Message has already been printed */
  446. return -EIO;
  447. exit_smapi_request_error:
  448. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg exit on smapi_request error bRC %x\n", bRC);
  449. return bRC;
  450. }
  451. int smapi_set_DSP_power_state(bool bOn)
  452. {
  453. int bRC;
  454. unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
  455. unsigned short usPowerFunction;
  456. PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state entry bOn %x\n", bOn);
  457. usPowerFunction = (bOn) ? 1 : 0;
  458. bRC = smapi_request(0x4901, 0x0000, 0, usPowerFunction,
  459. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  460. PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state exit bRC %x\n", bRC);
  461. return bRC;
  462. }
  463. #if 0
  464. static int SmapiQuerySystemID(void)
  465. {
  466. int bRC = -EIO;
  467. unsigned short usAX = 0xffff, usBX = 0xffff, usCX = 0xffff,
  468. usDX = 0xffff, usDI = 0xffff, usSI = 0xffff;
  469. printk("smapi::SmapiQUerySystemID entry\n");
  470. bRC = smapi_request(0x0000, 0, 0, 0,
  471. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  472. if (bRC == 0) {
  473. printk("AX=%x, BX=%x, CX=%x, DX=%x, DI=%x, SI=%x\n",
  474. usAX, usBX, usCX, usDX, usDI, usSI);
  475. } else {
  476. printk("smapi::SmapiQuerySystemID smapi_request error\n");
  477. }
  478. return bRC;
  479. }
  480. #endif /* 0 */
  481. int smapi_init(void)
  482. {
  483. int retval = -EIO;
  484. unsigned short usSmapiID = 0;
  485. unsigned long flags;
  486. PRINTK_1(TRACE_SMAPI, "smapi::smapi_init entry\n");
  487. spin_lock_irqsave(&rtc_lock, flags);
  488. usSmapiID = CMOS_READ(0x7C);
  489. usSmapiID |= (CMOS_READ(0x7D) << 8);
  490. spin_unlock_irqrestore(&rtc_lock, flags);
  491. PRINTK_2(TRACE_SMAPI, "smapi::smapi_init usSmapiID %x\n", usSmapiID);
  492. if (usSmapiID == 0x5349) {
  493. spin_lock_irqsave(&rtc_lock, flags);
  494. g_usSmapiPort = CMOS_READ(0x7E);
  495. g_usSmapiPort |= (CMOS_READ(0x7F) << 8);
  496. spin_unlock_irqrestore(&rtc_lock, flags);
  497. if (g_usSmapiPort == 0) {
  498. PRINTK_ERROR("smapi::smapi_init, ERROR unable to read from SMAPI port\n");
  499. } else {
  500. PRINTK_2(TRACE_SMAPI,
  501. "smapi::smapi_init, exit true g_usSmapiPort %x\n",
  502. g_usSmapiPort);
  503. retval = 0;
  504. //SmapiQuerySystemID();
  505. }
  506. } else {
  507. PRINTK_ERROR("smapi::smapi_init, ERROR invalid usSmapiID\n");
  508. retval = -ENXIO;
  509. }
  510. return retval;
  511. }