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