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 49 #include <linux/kernel.h> 50 #include <linux/mc146818rtc.h> /* CMOS defines */ 51 #include "smapi.h" 52 #include "mwavedd.h" 53 54 static unsigned short g_usSmapiPort = 0; 55 56 57 static int smapi_request(unsigned short inBX, unsigned short inCX, 58 unsigned short inDI, unsigned short inSI, 59 unsigned short *outAX, unsigned short *outBX, 60 unsigned short *outCX, unsigned short *outDX, 61 unsigned short *outDI, unsigned short *outSI) 62 { 63 unsigned short myoutAX = 2, *pmyoutAX = &myoutAX; 64 unsigned short myoutBX = 3, *pmyoutBX = &myoutBX; 65 unsigned short myoutCX = 4, *pmyoutCX = &myoutCX; 66 unsigned short myoutDX = 5, *pmyoutDX = &myoutDX; 67 unsigned short myoutDI = 6, *pmyoutDI = &myoutDI; 68 unsigned short myoutSI = 7, *pmyoutSI = &myoutSI; 69 unsigned short usSmapiOK = -EIO, *pusSmapiOK = &usSmapiOK; 70 unsigned int inBXCX = (inBX << 16) | inCX; 71 unsigned int inDISI = (inDI << 16) | inSI; 72 int retval = 0; 73 74 PRINTK_5(TRACE_SMAPI, "inBX %x inCX %x inDI %x inSI %x\n", 75 inBX, inCX, inDI, inSI); 76 77 __asm__ __volatile__("movw $0x5380,%%ax\n\t" 78 "movl %7,%%ebx\n\t" 79 "shrl $16, %%ebx\n\t" 80 "movw %7,%%cx\n\t" 81 "movl %8,%%edi\n\t" 82 "shrl $16,%%edi\n\t" 83 "movw %8,%%si\n\t" 84 "movw %9,%%dx\n\t" 85 "out %%al,%%dx\n\t" 86 "out %%al,$0x4F\n\t" 87 "cmpb $0x53,%%ah\n\t" 88 "je 2f\n\t" 89 "1:\n\t" 90 "orb %%ah,%%ah\n\t" 91 "jnz 2f\n\t" 92 "movw %%ax,%0\n\t" 93 "movw %%bx,%1\n\t" 94 "movw %%cx,%2\n\t" 95 "movw %%dx,%3\n\t" 96 "movw %%di,%4\n\t" 97 "movw %%si,%5\n\t" 98 "movw $1,%6\n\t" 99 "2:\n\t":"=m"(*(unsigned short *) pmyoutAX), 100 "=m"(*(unsigned short *) pmyoutBX), 101 "=m"(*(unsigned short *) pmyoutCX), 102 "=m"(*(unsigned short *) pmyoutDX), 103 "=m"(*(unsigned short *) pmyoutDI), 104 "=m"(*(unsigned short *) pmyoutSI), 105 "=m"(*(unsigned short *) pusSmapiOK) 106 :"m"(inBXCX), "m"(inDISI), "m"(g_usSmapiPort) 107 :"%eax", "%ebx", "%ecx", "%edx", "%edi", 108 "%esi"); 109 110 PRINTK_8(TRACE_SMAPI, 111 "myoutAX %x myoutBX %x myoutCX %x myoutDX %x myoutDI %x myoutSI %x usSmapiOK %x\n", 112 myoutAX, myoutBX, myoutCX, myoutDX, myoutDI, myoutSI, 113 usSmapiOK); 114 *outAX = myoutAX; 115 *outBX = myoutBX; 116 *outCX = myoutCX; 117 *outDX = myoutDX; 118 *outDI = myoutDI; 119 *outSI = myoutSI; 120 121 retval = (usSmapiOK == 1) ? 0 : -EIO; 122 PRINTK_2(TRACE_SMAPI, "smapi::smapi_request exit retval %x\n", retval); 123 return retval; 124 } 125 126 127 int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings) 128 { 129 int bRC = -EIO; 130 unsigned short usAX, usBX, usCX, usDX, usDI, usSI; 131 static const unsigned short ausDspBases[] = { 132 0x0030, 0x4E30, 0x8E30, 0xCE30, 133 0x0130, 0x0350, 0x0070, 0x0DB0 }; 134 static const unsigned short ausUartBases[] = { 135 0x03F8, 0x02F8, 0x03E8, 0x02E8 }; 136 137 PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg entry\n"); 138 139 bRC = smapi_request(0x1802, 0x0000, 0, 0, 140 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 141 if (bRC) { 142 PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Error: Could not get DSP Settings. Aborting.\n"); 143 return bRC; 144 } 145 146 PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n"); 147 148 pSettings->bDSPPresent = ((usBX & 0x0100) != 0); 149 pSettings->bDSPEnabled = ((usCX & 0x0001) != 0); 150 pSettings->usDspIRQ = usSI & 0x00FF; 151 pSettings->usDspDMA = (usSI & 0xFF00) >> 8; 152 if ((usDI & 0x00FF) < ARRAY_SIZE(ausDspBases)) { 153 pSettings->usDspBaseIO = ausDspBases[usDI & 0x00FF]; 154 } else { 155 pSettings->usDspBaseIO = 0; 156 } 157 PRINTK_6(TRACE_SMAPI, 158 "smapi::smapi_query_DSP_cfg get DSP Settings bDSPPresent %x bDSPEnabled %x usDspIRQ %x usDspDMA %x usDspBaseIO %x\n", 159 pSettings->bDSPPresent, pSettings->bDSPEnabled, 160 pSettings->usDspIRQ, pSettings->usDspDMA, 161 pSettings->usDspBaseIO); 162 163 /* check for illegal values */ 164 if ( pSettings->usDspBaseIO == 0 ) 165 PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP base I/O address is 0\n"); 166 if ( pSettings->usDspIRQ == 0 ) 167 PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP IRQ line is 0\n"); 168 169 bRC = smapi_request(0x1804, 0x0000, 0, 0, 170 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 171 if (bRC) { 172 PRINTK_ERROR("smapi::smapi_query_DSP_cfg: Error: Could not get DSP modem settings. Aborting.\n"); 173 return bRC; 174 } 175 176 PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n"); 177 178 pSettings->bModemEnabled = ((usCX & 0x0001) != 0); 179 pSettings->usUartIRQ = usSI & 0x000F; 180 if (((usSI & 0xFF00) >> 8) < ARRAY_SIZE(ausUartBases)) { 181 pSettings->usUartBaseIO = ausUartBases[(usSI & 0xFF00) >> 8]; 182 } else { 183 pSettings->usUartBaseIO = 0; 184 } 185 186 PRINTK_4(TRACE_SMAPI, 187 "smapi::smapi_query_DSP_cfg get DSP modem settings bModemEnabled %x usUartIRQ %x usUartBaseIO %x\n", 188 pSettings->bModemEnabled, 189 pSettings->usUartIRQ, 190 pSettings->usUartBaseIO); 191 192 /* check for illegal values */ 193 if ( pSettings->usUartBaseIO == 0 ) 194 PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART base I/O address is 0\n"); 195 if ( pSettings->usUartIRQ == 0 ) 196 PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART IRQ line is 0\n"); 197 198 PRINTK_2(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg exit bRC %x\n", bRC); 199 200 return bRC; 201 } 202 203 204 int smapi_set_DSP_cfg(void) 205 { 206 int bRC = -EIO; 207 int i; 208 unsigned short usAX, usBX, usCX, usDX, usDI, usSI; 209 static const unsigned short ausDspBases[] = { 210 0x0030, 0x4E30, 0x8E30, 0xCE30, 211 0x0130, 0x0350, 0x0070, 0x0DB0 }; 212 static const unsigned short ausUartBases[] = { 213 0x03F8, 0x02F8, 0x03E8, 0x02E8 }; 214 static const unsigned short ausDspIrqs[] = { 215 5, 7, 10, 11, 15 }; 216 static const unsigned short ausUartIrqs[] = { 217 3, 4 }; 218 219 unsigned short dspio_index = 0, uartio_index = 0; 220 221 PRINTK_5(TRACE_SMAPI, 222 "smapi::smapi_set_DSP_cfg entry mwave_3780i_irq %x mwave_3780i_io %x mwave_uart_irq %x mwave_uart_io %x\n", 223 mwave_3780i_irq, mwave_3780i_io, mwave_uart_irq, mwave_uart_io); 224 225 if (mwave_3780i_io) { 226 for (i = 0; i < ARRAY_SIZE(ausDspBases); i++) { 227 if (mwave_3780i_io == ausDspBases[i]) 228 break; 229 } 230 if (i == ARRAY_SIZE(ausDspBases)) { 231 PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_io address %x. Aborting.\n", mwave_3780i_io); 232 return bRC; 233 } 234 dspio_index = i; 235 } 236 237 if (mwave_3780i_irq) { 238 for (i = 0; i < ARRAY_SIZE(ausDspIrqs); i++) { 239 if (mwave_3780i_irq == ausDspIrqs[i]) 240 break; 241 } 242 if (i == ARRAY_SIZE(ausDspIrqs)) { 243 PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_irq %x. Aborting.\n", mwave_3780i_irq); 244 return bRC; 245 } 246 } 247 248 if (mwave_uart_io) { 249 for (i = 0; i < ARRAY_SIZE(ausUartBases); i++) { 250 if (mwave_uart_io == ausUartBases[i]) 251 break; 252 } 253 if (i == ARRAY_SIZE(ausUartBases)) { 254 PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_io address %x. Aborting.\n", mwave_uart_io); 255 return bRC; 256 } 257 uartio_index = i; 258 } 259 260 261 if (mwave_uart_irq) { 262 for (i = 0; i < ARRAY_SIZE(ausUartIrqs); i++) { 263 if (mwave_uart_irq == ausUartIrqs[i]) 264 break; 265 } 266 if (i == ARRAY_SIZE(ausUartIrqs)) { 267 PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_irq %x. Aborting.\n", mwave_uart_irq); 268 return bRC; 269 } 270 } 271 272 if (mwave_uart_irq || mwave_uart_io) { 273 274 /* Check serial port A */ 275 bRC = smapi_request(0x1402, 0x0000, 0, 0, 276 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 277 if (bRC) goto exit_smapi_request_error; 278 /* bRC == 0 */ 279 if (usBX & 0x0100) { /* serial port A is present */ 280 if (usCX & 1) { /* serial port is enabled */ 281 if ((usSI & 0xFF) == mwave_uart_irq) { 282 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES 283 PRINTK_ERROR(KERN_ERR_MWAVE 284 "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq); 285 #else 286 PRINTK_3(TRACE_SMAPI, 287 "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq); 288 #endif 289 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES 290 PRINTK_1(TRACE_SMAPI, 291 "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n"); 292 bRC = smapi_request(0x1403, 0x0100, 0, usSI, 293 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 294 if (bRC) goto exit_smapi_request_error; 295 bRC = smapi_request(0x1402, 0x0000, 0, 0, 296 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 297 if (bRC) goto exit_smapi_request_error; 298 #else 299 goto exit_conflict; 300 #endif 301 } else { 302 if ((usSI >> 8) == uartio_index) { 303 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES 304 PRINTK_ERROR(KERN_ERR_MWAVE 305 "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]); 306 #else 307 PRINTK_3(TRACE_SMAPI, 308 "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]); 309 #endif 310 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES 311 PRINTK_1(TRACE_SMAPI, 312 "smapi::smapi_set_DSP_cfg Disabling conflicting serial port A\n"); 313 bRC = smapi_request (0x1403, 0x0100, 0, usSI, 314 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 315 if (bRC) goto exit_smapi_request_error; 316 bRC = smapi_request (0x1402, 0x0000, 0, 0, 317 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 318 if (bRC) goto exit_smapi_request_error; 319 #else 320 goto exit_conflict; 321 #endif 322 } 323 } 324 } 325 } 326 327 /* Check serial port B */ 328 bRC = smapi_request(0x1404, 0x0000, 0, 0, 329 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 330 if (bRC) goto exit_smapi_request_error; 331 /* bRC == 0 */ 332 if (usBX & 0x0100) { /* serial port B is present */ 333 if (usCX & 1) { /* serial port is enabled */ 334 if ((usSI & 0xFF) == mwave_uart_irq) { 335 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES 336 PRINTK_ERROR(KERN_ERR_MWAVE 337 "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq); 338 #else 339 PRINTK_3(TRACE_SMAPI, 340 "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq); 341 #endif 342 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES 343 PRINTK_1(TRACE_SMAPI, 344 "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n"); 345 bRC = smapi_request(0x1405, 0x0100, 0, usSI, 346 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 347 if (bRC) goto exit_smapi_request_error; 348 bRC = smapi_request(0x1404, 0x0000, 0, 0, 349 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 350 if (bRC) goto exit_smapi_request_error; 351 #else 352 goto exit_conflict; 353 #endif 354 } else { 355 if ((usSI >> 8) == uartio_index) { 356 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES 357 PRINTK_ERROR(KERN_ERR_MWAVE 358 "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]); 359 #else 360 PRINTK_3(TRACE_SMAPI, 361 "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]); 362 #endif 363 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES 364 PRINTK_1 (TRACE_SMAPI, 365 "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n"); 366 bRC = smapi_request (0x1405, 0x0100, 0, usSI, 367 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 368 if (bRC) goto exit_smapi_request_error; 369 bRC = smapi_request (0x1404, 0x0000, 0, 0, 370 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 371 if (bRC) goto exit_smapi_request_error; 372 #else 373 goto exit_conflict; 374 #endif 375 } 376 } 377 } 378 } 379 380 /* Check IR port */ 381 bRC = smapi_request(0x1700, 0x0000, 0, 0, 382 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 383 if (bRC) goto exit_smapi_request_error; 384 bRC = smapi_request(0x1704, 0x0000, 0, 0, 385 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 386 if (bRC) goto exit_smapi_request_error; 387 /* bRC == 0 */ 388 if ((usCX & 0xff) != 0xff) { /* IR port not disabled */ 389 if ((usCX & 0xff) == mwave_uart_irq) { 390 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES 391 PRINTK_ERROR(KERN_ERR_MWAVE 392 "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq); 393 #else 394 PRINTK_3(TRACE_SMAPI, 395 "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq); 396 #endif 397 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES 398 PRINTK_1(TRACE_SMAPI, 399 "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n"); 400 bRC = smapi_request(0x1701, 0x0100, 0, 0, 401 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 402 if (bRC) goto exit_smapi_request_error; 403 bRC = smapi_request(0x1700, 0, 0, 0, 404 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 405 if (bRC) goto exit_smapi_request_error; 406 bRC = smapi_request(0x1705, 0x01ff, 0, usSI, 407 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 408 if (bRC) goto exit_smapi_request_error; 409 bRC = smapi_request(0x1704, 0x0000, 0, 0, 410 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 411 if (bRC) goto exit_smapi_request_error; 412 #else 413 goto exit_conflict; 414 #endif 415 } else { 416 if ((usSI & 0xff) == uartio_index) { 417 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES 418 PRINTK_ERROR(KERN_ERR_MWAVE 419 "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]); 420 #else 421 PRINTK_3(TRACE_SMAPI, 422 "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]); 423 #endif 424 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES 425 PRINTK_1(TRACE_SMAPI, 426 "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n"); 427 bRC = smapi_request(0x1701, 0x0100, 0, 0, 428 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 429 if (bRC) goto exit_smapi_request_error; 430 bRC = smapi_request(0x1700, 0, 0, 0, 431 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 432 if (bRC) goto exit_smapi_request_error; 433 bRC = smapi_request(0x1705, 0x01ff, 0, usSI, 434 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 435 if (bRC) goto exit_smapi_request_error; 436 bRC = smapi_request(0x1704, 0x0000, 0, 0, 437 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 438 if (bRC) goto exit_smapi_request_error; 439 #else 440 goto exit_conflict; 441 #endif 442 } 443 } 444 } 445 } 446 447 bRC = smapi_request(0x1802, 0x0000, 0, 0, 448 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 449 if (bRC) goto exit_smapi_request_error; 450 451 if (mwave_3780i_io) { 452 usDI = dspio_index; 453 } 454 if (mwave_3780i_irq) { 455 usSI = (usSI & 0xff00) | mwave_3780i_irq; 456 } 457 458 bRC = smapi_request(0x1803, 0x0101, usDI, usSI, 459 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 460 if (bRC) goto exit_smapi_request_error; 461 462 bRC = smapi_request(0x1804, 0x0000, 0, 0, 463 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 464 if (bRC) goto exit_smapi_request_error; 465 466 if (mwave_uart_io) { 467 usSI = (usSI & 0x00ff) | (uartio_index << 8); 468 } 469 if (mwave_uart_irq) { 470 usSI = (usSI & 0xff00) | mwave_uart_irq; 471 } 472 bRC = smapi_request(0x1805, 0x0101, 0, usSI, 473 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 474 if (bRC) goto exit_smapi_request_error; 475 476 bRC = smapi_request(0x1802, 0x0000, 0, 0, 477 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 478 if (bRC) goto exit_smapi_request_error; 479 480 bRC = smapi_request(0x1804, 0x0000, 0, 0, 481 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 482 if (bRC) goto exit_smapi_request_error; 483 484 /* normal exit: */ 485 PRINTK_1(TRACE_SMAPI, "smapi::smapi_set_DSP_cfg exit\n"); 486 return 0; 487 488 exit_conflict: 489 /* Message has already been printed */ 490 return -EIO; 491 492 exit_smapi_request_error: 493 PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg exit on smapi_request error bRC %x\n", bRC); 494 return bRC; 495 } 496 497 498 int smapi_set_DSP_power_state(bool bOn) 499 { 500 int bRC = -EIO; 501 unsigned short usAX, usBX, usCX, usDX, usDI, usSI; 502 unsigned short usPowerFunction; 503 504 PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state entry bOn %x\n", bOn); 505 506 usPowerFunction = (bOn) ? 1 : 0; 507 508 bRC = smapi_request(0x4901, 0x0000, 0, usPowerFunction, 509 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 510 511 PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state exit bRC %x\n", bRC); 512 513 return bRC; 514 } 515 516 #if 0 517 static int SmapiQuerySystemID(void) 518 { 519 int bRC = -EIO; 520 unsigned short usAX = 0xffff, usBX = 0xffff, usCX = 0xffff, 521 usDX = 0xffff, usDI = 0xffff, usSI = 0xffff; 522 523 printk("smapi::SmapiQUerySystemID entry\n"); 524 bRC = smapi_request(0x0000, 0, 0, 0, 525 &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 526 527 if (bRC == 0) { 528 printk("AX=%x, BX=%x, CX=%x, DX=%x, DI=%x, SI=%x\n", 529 usAX, usBX, usCX, usDX, usDI, usSI); 530 } else { 531 printk("smapi::SmapiQuerySystemID smapi_request error\n"); 532 } 533 534 return bRC; 535 } 536 #endif /* 0 */ 537 538 int smapi_init(void) 539 { 540 int retval = -EIO; 541 unsigned short usSmapiID = 0; 542 unsigned long flags; 543 544 PRINTK_1(TRACE_SMAPI, "smapi::smapi_init entry\n"); 545 546 spin_lock_irqsave(&rtc_lock, flags); 547 usSmapiID = CMOS_READ(0x7C); 548 usSmapiID |= (CMOS_READ(0x7D) << 8); 549 spin_unlock_irqrestore(&rtc_lock, flags); 550 PRINTK_2(TRACE_SMAPI, "smapi::smapi_init usSmapiID %x\n", usSmapiID); 551 552 if (usSmapiID == 0x5349) { 553 spin_lock_irqsave(&rtc_lock, flags); 554 g_usSmapiPort = CMOS_READ(0x7E); 555 g_usSmapiPort |= (CMOS_READ(0x7F) << 8); 556 spin_unlock_irqrestore(&rtc_lock, flags); 557 if (g_usSmapiPort == 0) { 558 PRINTK_ERROR("smapi::smapi_init, ERROR unable to read from SMAPI port\n"); 559 } else { 560 PRINTK_2(TRACE_SMAPI, 561 "smapi::smapi_init, exit true g_usSmapiPort %x\n", 562 g_usSmapiPort); 563 retval = 0; 564 //SmapiQuerySystemID(); 565 } 566 } else { 567 PRINTK_ERROR("smapi::smapi_init, ERROR invalid usSmapiID\n"); 568 retval = -ENXIO; 569 } 570 571 return retval; 572 } 573