573 lines · c
1/*2*3* smapi.c -- SMAPI interface routines4*5*6* Written By: Mike Sullivan IBM Corporation7*8* Copyright (C) 1999 IBM Corporation9*10* This program is free software; you can redistribute it and/or modify11* it under the terms of the GNU General Public License as published by12* the Free Software Foundation; either version 2 of the License, or13* (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 of17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the18* GNU General Public License for more details.19*20* NO WARRANTY21* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR22* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT23* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,24* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is25* solely responsible for determining the appropriateness of using and26* distributing the Program and assumes all risks associated with its27* exercise of rights under this Agreement, including but not limited to28* 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 LIABILITY32* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY33* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL34* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND35* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR36* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE37* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED38* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES39*40* You should have received a copy of the GNU General Public License41* along with this program; if not, write to the Free Software42* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA43*44*45* 10/23/2000 - Alpha Release46* First release to the public47*/48 49#include <linux/kernel.h>50#include <linux/mc146818rtc.h> /* CMOS defines */51#include "smapi.h"52#include "mwavedd.h"53 54static unsigned short g_usSmapiPort = 0;55 56 57static 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 127int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings)128{129 int bRC;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 204int 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_DEVICES283 PRINTK_ERROR(KERN_ERR_MWAVE284 "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);285#else286 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#endif289#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES290 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#else299 goto exit_conflict;300#endif301 } else {302 if ((usSI >> 8) == uartio_index) {303#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES304 PRINTK_ERROR(KERN_ERR_MWAVE305 "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#else307 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#endif310#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES311 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#else320 goto exit_conflict;321#endif322 }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_DEVICES336 PRINTK_ERROR(KERN_ERR_MWAVE337 "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);338#else339 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#endif342#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES343 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#else352 goto exit_conflict;353#endif354 } else {355 if ((usSI >> 8) == uartio_index) {356#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES357 PRINTK_ERROR(KERN_ERR_MWAVE358 "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#else360 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#endif363#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES364 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#else373 goto exit_conflict;374#endif375 }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_DEVICES391 PRINTK_ERROR(KERN_ERR_MWAVE392 "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);393#else394 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#endif397#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES398 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#else413 goto exit_conflict;414#endif415 } else {416 if ((usSI & 0xff) == uartio_index) {417#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES418 PRINTK_ERROR(KERN_ERR_MWAVE419 "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#else421 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#endif424#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES425 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#else440 goto exit_conflict;441#endif442 }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 488exit_conflict:489 /* Message has already been printed */490 return -EIO;491 492exit_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 498int smapi_set_DSP_power_state(bool bOn)499{500 int bRC;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 0517static 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 538int 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