smapi.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  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 = -EIO;
  120. unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
  121. unsigned short ausDspBases[] = { 0x0030, 0x4E30, 0x8E30, 0xCE30, 0x0130, 0x0350, 0x0070, 0x0DB0 };
  122. unsigned short ausUartBases[] = { 0x03F8, 0x02F8, 0x03E8, 0x02E8 };
  123. unsigned short numDspBases = 8;
  124. unsigned short numUartBases = 4;
  125. PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg entry\n");
  126. bRC = smapi_request(0x1802, 0x0000, 0, 0,
  127. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  128. if (bRC) {
  129. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Error: Could not get DSP Settings. Aborting.\n");
  130. return bRC;
  131. }
  132. PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n");
  133. pSettings->bDSPPresent = ((usBX & 0x0100) != 0);
  134. pSettings->bDSPEnabled = ((usCX & 0x0001) != 0);
  135. pSettings->usDspIRQ = usSI & 0x00FF;
  136. pSettings->usDspDMA = (usSI & 0xFF00) >> 8;
  137. if ((usDI & 0x00FF) < numDspBases) {
  138. pSettings->usDspBaseIO = ausDspBases[usDI & 0x00FF];
  139. } else {
  140. pSettings->usDspBaseIO = 0;
  141. }
  142. PRINTK_6(TRACE_SMAPI,
  143. "smapi::smapi_query_DSP_cfg get DSP Settings bDSPPresent %x bDSPEnabled %x usDspIRQ %x usDspDMA %x usDspBaseIO %x\n",
  144. pSettings->bDSPPresent, pSettings->bDSPEnabled,
  145. pSettings->usDspIRQ, pSettings->usDspDMA,
  146. pSettings->usDspBaseIO);
  147. /* check for illegal values */
  148. if ( pSettings->usDspBaseIO == 0 )
  149. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP base I/O address is 0\n");
  150. if ( pSettings->usDspIRQ == 0 )
  151. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP IRQ line is 0\n");
  152. bRC = smapi_request(0x1804, 0x0000, 0, 0,
  153. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  154. if (bRC) {
  155. PRINTK_ERROR("smapi::smapi_query_DSP_cfg: Error: Could not get DSP modem settings. Aborting.\n");
  156. return bRC;
  157. }
  158. PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n");
  159. pSettings->bModemEnabled = ((usCX & 0x0001) != 0);
  160. pSettings->usUartIRQ = usSI & 0x000F;
  161. if (((usSI & 0xFF00) >> 8) < numUartBases) {
  162. pSettings->usUartBaseIO = ausUartBases[(usSI & 0xFF00) >> 8];
  163. } else {
  164. pSettings->usUartBaseIO = 0;
  165. }
  166. PRINTK_4(TRACE_SMAPI,
  167. "smapi::smapi_query_DSP_cfg get DSP modem settings bModemEnabled %x usUartIRQ %x usUartBaseIO %x\n",
  168. pSettings->bModemEnabled,
  169. pSettings->usUartIRQ,
  170. pSettings->usUartBaseIO);
  171. /* check for illegal values */
  172. if ( pSettings->usUartBaseIO == 0 )
  173. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART base I/O address is 0\n");
  174. if ( pSettings->usUartIRQ == 0 )
  175. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART IRQ line is 0\n");
  176. PRINTK_2(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg exit bRC %x\n", bRC);
  177. return bRC;
  178. }
  179. int smapi_set_DSP_cfg(void)
  180. {
  181. int bRC = -EIO;
  182. int i;
  183. unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
  184. unsigned short ausDspBases[] = { 0x0030, 0x4E30, 0x8E30, 0xCE30, 0x0130, 0x0350, 0x0070, 0x0DB0 };
  185. unsigned short ausUartBases[] = { 0x03F8, 0x02F8, 0x03E8, 0x02E8 };
  186. unsigned short ausDspIrqs[] = { 5, 7, 10, 11, 15 };
  187. unsigned short ausUartIrqs[] = { 3, 4 };
  188. unsigned short numDspBases = 8;
  189. unsigned short numUartBases = 4;
  190. unsigned short numDspIrqs = 5;
  191. unsigned short numUartIrqs = 2;
  192. unsigned short dspio_index = 0, uartio_index = 0;
  193. PRINTK_5(TRACE_SMAPI,
  194. "smapi::smapi_set_DSP_cfg entry mwave_3780i_irq %x mwave_3780i_io %x mwave_uart_irq %x mwave_uart_io %x\n",
  195. mwave_3780i_irq, mwave_3780i_io, mwave_uart_irq, mwave_uart_io);
  196. if (mwave_3780i_io) {
  197. for (i = 0; i < numDspBases; i++) {
  198. if (mwave_3780i_io == ausDspBases[i])
  199. break;
  200. }
  201. if (i == numDspBases) {
  202. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_io address %x. Aborting.\n", mwave_3780i_io);
  203. return bRC;
  204. }
  205. dspio_index = i;
  206. }
  207. if (mwave_3780i_irq) {
  208. for (i = 0; i < numDspIrqs; i++) {
  209. if (mwave_3780i_irq == ausDspIrqs[i])
  210. break;
  211. }
  212. if (i == numDspIrqs) {
  213. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_irq %x. Aborting.\n", mwave_3780i_irq);
  214. return bRC;
  215. }
  216. }
  217. if (mwave_uart_io) {
  218. for (i = 0; i < numUartBases; i++) {
  219. if (mwave_uart_io == ausUartBases[i])
  220. break;
  221. }
  222. if (i == numUartBases) {
  223. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_io address %x. Aborting.\n", mwave_uart_io);
  224. return bRC;
  225. }
  226. uartio_index = i;
  227. }
  228. if (mwave_uart_irq) {
  229. for (i = 0; i < numUartIrqs; i++) {
  230. if (mwave_uart_irq == ausUartIrqs[i])
  231. break;
  232. }
  233. if (i == numUartIrqs) {
  234. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_irq %x. Aborting.\n", mwave_uart_irq);
  235. return bRC;
  236. }
  237. }
  238. if (mwave_uart_irq || mwave_uart_io) {
  239. /* Check serial port A */
  240. bRC = smapi_request(0x1402, 0x0000, 0, 0,
  241. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  242. if (bRC) goto exit_smapi_request_error;
  243. /* bRC == 0 */
  244. if (usBX & 0x0100) { /* serial port A is present */
  245. if (usCX & 1) { /* serial port is enabled */
  246. if ((usSI & 0xFF) == mwave_uart_irq) {
  247. #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
  248. PRINTK_ERROR(KERN_ERR_MWAVE
  249. "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
  250. #else
  251. PRINTK_3(TRACE_SMAPI,
  252. "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
  253. #endif
  254. #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
  255. PRINTK_1(TRACE_SMAPI,
  256. "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
  257. bRC = smapi_request(0x1403, 0x0100, 0, usSI,
  258. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  259. if (bRC) goto exit_smapi_request_error;
  260. bRC = smapi_request(0x1402, 0x0000, 0, 0,
  261. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  262. if (bRC) goto exit_smapi_request_error;
  263. #else
  264. goto exit_conflict;
  265. #endif
  266. } else {
  267. if ((usSI >> 8) == uartio_index) {
  268. #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
  269. PRINTK_ERROR(KERN_ERR_MWAVE
  270. "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]);
  271. #else
  272. PRINTK_3(TRACE_SMAPI,
  273. "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]);
  274. #endif
  275. #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
  276. PRINTK_1(TRACE_SMAPI,
  277. "smapi::smapi_set_DSP_cfg Disabling conflicting serial port A\n");
  278. bRC = smapi_request (0x1403, 0x0100, 0, usSI,
  279. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  280. if (bRC) goto exit_smapi_request_error;
  281. bRC = smapi_request (0x1402, 0x0000, 0, 0,
  282. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  283. if (bRC) goto exit_smapi_request_error;
  284. #else
  285. goto exit_conflict;
  286. #endif
  287. }
  288. }
  289. }
  290. }
  291. /* Check serial port B */
  292. bRC = smapi_request(0x1404, 0x0000, 0, 0,
  293. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  294. if (bRC) goto exit_smapi_request_error;
  295. /* bRC == 0 */
  296. if (usBX & 0x0100) { /* serial port B is present */
  297. if (usCX & 1) { /* serial port is enabled */
  298. if ((usSI & 0xFF) == mwave_uart_irq) {
  299. #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
  300. PRINTK_ERROR(KERN_ERR_MWAVE
  301. "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
  302. #else
  303. PRINTK_3(TRACE_SMAPI,
  304. "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
  305. #endif
  306. #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
  307. PRINTK_1(TRACE_SMAPI,
  308. "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n");
  309. bRC = smapi_request(0x1405, 0x0100, 0, usSI,
  310. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  311. if (bRC) goto exit_smapi_request_error;
  312. bRC = smapi_request(0x1404, 0x0000, 0, 0,
  313. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  314. if (bRC) goto exit_smapi_request_error;
  315. #else
  316. goto exit_conflict;
  317. #endif
  318. } else {
  319. if ((usSI >> 8) == uartio_index) {
  320. #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
  321. PRINTK_ERROR(KERN_ERR_MWAVE
  322. "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]);
  323. #else
  324. PRINTK_3(TRACE_SMAPI,
  325. "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]);
  326. #endif
  327. #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
  328. PRINTK_1 (TRACE_SMAPI,
  329. "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n");
  330. bRC = smapi_request (0x1405, 0x0100, 0, usSI,
  331. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  332. if (bRC) goto exit_smapi_request_error;
  333. bRC = smapi_request (0x1404, 0x0000, 0, 0,
  334. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  335. if (bRC) goto exit_smapi_request_error;
  336. #else
  337. goto exit_conflict;
  338. #endif
  339. }
  340. }
  341. }
  342. }
  343. /* Check IR port */
  344. bRC = smapi_request(0x1700, 0x0000, 0, 0,
  345. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  346. if (bRC) goto exit_smapi_request_error;
  347. bRC = smapi_request(0x1704, 0x0000, 0, 0,
  348. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  349. if (bRC) goto exit_smapi_request_error;
  350. /* bRC == 0 */
  351. if ((usCX & 0xff) != 0xff) { /* IR port not disabled */
  352. if ((usCX & 0xff) == mwave_uart_irq) {
  353. #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
  354. PRINTK_ERROR(KERN_ERR_MWAVE
  355. "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);
  356. #else
  357. PRINTK_3(TRACE_SMAPI,
  358. "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);
  359. #endif
  360. #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
  361. PRINTK_1(TRACE_SMAPI,
  362. "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
  363. bRC = smapi_request(0x1701, 0x0100, 0, 0,
  364. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  365. if (bRC) goto exit_smapi_request_error;
  366. bRC = smapi_request(0x1700, 0, 0, 0,
  367. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  368. if (bRC) goto exit_smapi_request_error;
  369. bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
  370. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  371. if (bRC) goto exit_smapi_request_error;
  372. bRC = smapi_request(0x1704, 0x0000, 0, 0,
  373. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  374. if (bRC) goto exit_smapi_request_error;
  375. #else
  376. goto exit_conflict;
  377. #endif
  378. } else {
  379. if ((usSI & 0xff) == uartio_index) {
  380. #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
  381. PRINTK_ERROR(KERN_ERR_MWAVE
  382. "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]);
  383. #else
  384. PRINTK_3(TRACE_SMAPI,
  385. "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]);
  386. #endif
  387. #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
  388. PRINTK_1(TRACE_SMAPI,
  389. "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
  390. bRC = smapi_request(0x1701, 0x0100, 0, 0,
  391. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  392. if (bRC) goto exit_smapi_request_error;
  393. bRC = smapi_request(0x1700, 0, 0, 0,
  394. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  395. if (bRC) goto exit_smapi_request_error;
  396. bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
  397. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  398. if (bRC) goto exit_smapi_request_error;
  399. bRC = smapi_request(0x1704, 0x0000, 0, 0,
  400. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  401. if (bRC) goto exit_smapi_request_error;
  402. #else
  403. goto exit_conflict;
  404. #endif
  405. }
  406. }
  407. }
  408. }
  409. bRC = smapi_request(0x1802, 0x0000, 0, 0,
  410. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  411. if (bRC) goto exit_smapi_request_error;
  412. if (mwave_3780i_io) {
  413. usDI = dspio_index;
  414. }
  415. if (mwave_3780i_irq) {
  416. usSI = (usSI & 0xff00) | mwave_3780i_irq;
  417. }
  418. bRC = smapi_request(0x1803, 0x0101, usDI, usSI,
  419. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  420. if (bRC) goto exit_smapi_request_error;
  421. bRC = smapi_request(0x1804, 0x0000, 0, 0,
  422. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  423. if (bRC) goto exit_smapi_request_error;
  424. if (mwave_uart_io) {
  425. usSI = (usSI & 0x00ff) | (uartio_index << 8);
  426. }
  427. if (mwave_uart_irq) {
  428. usSI = (usSI & 0xff00) | mwave_uart_irq;
  429. }
  430. bRC = smapi_request(0x1805, 0x0101, 0, usSI,
  431. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  432. if (bRC) goto exit_smapi_request_error;
  433. bRC = smapi_request(0x1802, 0x0000, 0, 0,
  434. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  435. if (bRC) goto exit_smapi_request_error;
  436. bRC = smapi_request(0x1804, 0x0000, 0, 0,
  437. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  438. if (bRC) goto exit_smapi_request_error;
  439. /* normal exit: */
  440. PRINTK_1(TRACE_SMAPI, "smapi::smapi_set_DSP_cfg exit\n");
  441. return 0;
  442. exit_conflict:
  443. /* Message has already been printed */
  444. return -EIO;
  445. exit_smapi_request_error:
  446. PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg exit on smapi_request error bRC %x\n", bRC);
  447. return bRC;
  448. }
  449. int smapi_set_DSP_power_state(BOOLEAN bOn)
  450. {
  451. int bRC = -EIO;
  452. unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
  453. unsigned short usPowerFunction;
  454. PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state entry bOn %x\n", bOn);
  455. usPowerFunction = (bOn) ? 1 : 0;
  456. bRC = smapi_request(0x4901, 0x0000, 0, usPowerFunction,
  457. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  458. PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state exit bRC %x\n", bRC);
  459. return bRC;
  460. }
  461. #if 0
  462. static int SmapiQuerySystemID(void)
  463. {
  464. int bRC = -EIO;
  465. unsigned short usAX = 0xffff, usBX = 0xffff, usCX = 0xffff,
  466. usDX = 0xffff, usDI = 0xffff, usSI = 0xffff;
  467. printk("smapi::SmapiQUerySystemID entry\n");
  468. bRC = smapi_request(0x0000, 0, 0, 0,
  469. &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
  470. if (bRC == 0) {
  471. printk("AX=%x, BX=%x, CX=%x, DX=%x, DI=%x, SI=%x\n",
  472. usAX, usBX, usCX, usDX, usDI, usSI);
  473. } else {
  474. printk("smapi::SmapiQuerySystemID smapi_request error\n");
  475. }
  476. return bRC;
  477. }
  478. #endif /* 0 */
  479. int smapi_init(void)
  480. {
  481. int retval = -EIO;
  482. unsigned short usSmapiID = 0;
  483. unsigned long flags;
  484. PRINTK_1(TRACE_SMAPI, "smapi::smapi_init entry\n");
  485. spin_lock_irqsave(&rtc_lock, flags);
  486. usSmapiID = CMOS_READ(0x7C);
  487. usSmapiID |= (CMOS_READ(0x7D) << 8);
  488. spin_unlock_irqrestore(&rtc_lock, flags);
  489. PRINTK_2(TRACE_SMAPI, "smapi::smapi_init usSmapiID %x\n", usSmapiID);
  490. if (usSmapiID == 0x5349) {
  491. spin_lock_irqsave(&rtc_lock, flags);
  492. g_usSmapiPort = CMOS_READ(0x7E);
  493. g_usSmapiPort |= (CMOS_READ(0x7F) << 8);
  494. spin_unlock_irqrestore(&rtc_lock, flags);
  495. if (g_usSmapiPort == 0) {
  496. PRINTK_ERROR("smapi::smapi_init, ERROR unable to read from SMAPI port\n");
  497. } else {
  498. PRINTK_2(TRACE_SMAPI,
  499. "smapi::smapi_init, exit TRUE g_usSmapiPort %x\n",
  500. g_usSmapiPort);
  501. retval = 0;
  502. //SmapiQuerySystemID();
  503. }
  504. } else {
  505. PRINTK_ERROR("smapi::smapi_init, ERROR invalid usSmapiID\n");
  506. retval = -ENXIO;
  507. }
  508. return retval;
  509. }