Back to home page

OSCL-LXR

 
 

    


0001 /*
0002 *
0003 * smapi.c -- SMAPI interface routines
0004 *
0005 *
0006 * Written By: Mike Sullivan IBM Corporation
0007 *
0008 * Copyright (C) 1999 IBM Corporation
0009 *
0010 * This program is free software; you can redistribute it and/or modify
0011 * it under the terms of the GNU General Public License as published by
0012 * the Free Software Foundation; either version 2 of the License, or
0013 * (at your option) any later version.
0014 *
0015 * This program is distributed in the hope that it will be useful,
0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0018 * GNU General Public License for more details.
0019 *
0020 * NO WARRANTY
0021 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
0022 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
0023 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
0024 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
0025 * solely responsible for determining the appropriateness of using and
0026 * distributing the Program and assumes all risks associated with its
0027 * exercise of rights under this Agreement, including but not limited to
0028 * the risks and costs of program errors, damage to or loss of data,
0029 * programs or equipment, and unavailability or interruption of operations.
0030 *
0031 * DISCLAIMER OF LIABILITY
0032 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
0033 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0034 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
0035 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
0036 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
0037 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
0038 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
0039 *
0040 * You should have received a copy of the GNU General Public License
0041 * along with this program; if not, write to the Free Software
0042 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0043 *
0044 *
0045 * 10/23/2000 - Alpha Release
0046 *   First release to the public
0047 */
0048 
0049 #include <linux/kernel.h>
0050 #include <linux/mc146818rtc.h>  /* CMOS defines */
0051 #include "smapi.h"
0052 #include "mwavedd.h"
0053 
0054 static unsigned short g_usSmapiPort = 0;
0055 
0056 
0057 static int smapi_request(unsigned short inBX, unsigned short inCX,
0058              unsigned short inDI, unsigned short inSI,
0059              unsigned short *outAX, unsigned short *outBX,
0060              unsigned short *outCX, unsigned short *outDX,
0061              unsigned short *outDI, unsigned short *outSI)
0062 {
0063     unsigned short myoutAX = 2, *pmyoutAX = &myoutAX;
0064     unsigned short myoutBX = 3, *pmyoutBX = &myoutBX;
0065     unsigned short myoutCX = 4, *pmyoutCX = &myoutCX;
0066     unsigned short myoutDX = 5, *pmyoutDX = &myoutDX;
0067     unsigned short myoutDI = 6, *pmyoutDI = &myoutDI;
0068     unsigned short myoutSI = 7, *pmyoutSI = &myoutSI;
0069     unsigned short usSmapiOK = -EIO, *pusSmapiOK = &usSmapiOK;
0070     unsigned int inBXCX = (inBX << 16) | inCX;
0071     unsigned int inDISI = (inDI << 16) | inSI;
0072     int retval = 0;
0073 
0074     PRINTK_5(TRACE_SMAPI, "inBX %x inCX %x inDI %x inSI %x\n",
0075         inBX, inCX, inDI, inSI);
0076 
0077     __asm__ __volatile__("movw  $0x5380,%%ax\n\t"
0078                 "movl  %7,%%ebx\n\t"
0079                 "shrl  $16, %%ebx\n\t"
0080                 "movw  %7,%%cx\n\t"
0081                 "movl  %8,%%edi\n\t"
0082                 "shrl  $16,%%edi\n\t"
0083                 "movw  %8,%%si\n\t"
0084                 "movw  %9,%%dx\n\t"
0085                 "out   %%al,%%dx\n\t"
0086                 "out   %%al,$0x4F\n\t"
0087                 "cmpb  $0x53,%%ah\n\t"
0088                 "je    2f\n\t"
0089                 "1:\n\t"
0090                 "orb   %%ah,%%ah\n\t"
0091                 "jnz   2f\n\t"
0092                 "movw  %%ax,%0\n\t"
0093                 "movw  %%bx,%1\n\t"
0094                 "movw  %%cx,%2\n\t"
0095                 "movw  %%dx,%3\n\t"
0096                 "movw  %%di,%4\n\t"
0097                 "movw  %%si,%5\n\t"
0098                 "movw  $1,%6\n\t"
0099                 "2:\n\t":"=m"(*(unsigned short *) pmyoutAX),
0100                 "=m"(*(unsigned short *) pmyoutBX),
0101                 "=m"(*(unsigned short *) pmyoutCX),
0102                 "=m"(*(unsigned short *) pmyoutDX),
0103                 "=m"(*(unsigned short *) pmyoutDI),
0104                 "=m"(*(unsigned short *) pmyoutSI),
0105                 "=m"(*(unsigned short *) pusSmapiOK)
0106                 :"m"(inBXCX), "m"(inDISI), "m"(g_usSmapiPort)
0107                 :"%eax", "%ebx", "%ecx", "%edx", "%edi",
0108                 "%esi");
0109 
0110     PRINTK_8(TRACE_SMAPI,
0111         "myoutAX %x myoutBX %x myoutCX %x myoutDX %x myoutDI %x myoutSI %x usSmapiOK %x\n",
0112         myoutAX, myoutBX, myoutCX, myoutDX, myoutDI, myoutSI,
0113         usSmapiOK);
0114     *outAX = myoutAX;
0115     *outBX = myoutBX;
0116     *outCX = myoutCX;
0117     *outDX = myoutDX;
0118     *outDI = myoutDI;
0119     *outSI = myoutSI;
0120 
0121     retval = (usSmapiOK == 1) ? 0 : -EIO;
0122     PRINTK_2(TRACE_SMAPI, "smapi::smapi_request exit retval %x\n", retval);
0123     return retval;
0124 }
0125 
0126 
0127 int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings)
0128 {
0129     int bRC;
0130     unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
0131     static const unsigned short ausDspBases[] = {
0132         0x0030, 0x4E30, 0x8E30, 0xCE30,
0133         0x0130, 0x0350, 0x0070, 0x0DB0 };
0134     static const unsigned short ausUartBases[] = {
0135         0x03F8, 0x02F8, 0x03E8, 0x02E8 };
0136 
0137     PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg entry\n");
0138 
0139     bRC = smapi_request(0x1802, 0x0000, 0, 0,
0140         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0141     if (bRC) {
0142         PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Error: Could not get DSP Settings. Aborting.\n");
0143         return bRC;
0144     }
0145 
0146     PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n");
0147 
0148     pSettings->bDSPPresent = ((usBX & 0x0100) != 0);
0149     pSettings->bDSPEnabled = ((usCX & 0x0001) != 0);
0150     pSettings->usDspIRQ = usSI & 0x00FF;
0151     pSettings->usDspDMA = (usSI & 0xFF00) >> 8;
0152     if ((usDI & 0x00FF) < ARRAY_SIZE(ausDspBases)) {
0153         pSettings->usDspBaseIO = ausDspBases[usDI & 0x00FF];
0154     } else {
0155         pSettings->usDspBaseIO = 0;
0156     }
0157     PRINTK_6(TRACE_SMAPI,
0158         "smapi::smapi_query_DSP_cfg get DSP Settings bDSPPresent %x bDSPEnabled %x usDspIRQ %x usDspDMA %x usDspBaseIO %x\n",
0159         pSettings->bDSPPresent, pSettings->bDSPEnabled,
0160         pSettings->usDspIRQ, pSettings->usDspDMA,
0161         pSettings->usDspBaseIO);
0162 
0163     /* check for illegal values */
0164     if ( pSettings->usDspBaseIO == 0 ) 
0165         PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP base I/O address is 0\n");
0166     if ( pSettings->usDspIRQ == 0 )
0167         PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP IRQ line is 0\n");
0168 
0169     bRC = smapi_request(0x1804, 0x0000, 0, 0,
0170         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0171     if (bRC) {
0172         PRINTK_ERROR("smapi::smapi_query_DSP_cfg: Error: Could not get DSP modem settings. Aborting.\n");
0173         return bRC;
0174     } 
0175 
0176     PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n");
0177 
0178     pSettings->bModemEnabled = ((usCX & 0x0001) != 0);
0179     pSettings->usUartIRQ = usSI & 0x000F;
0180     if (((usSI & 0xFF00) >> 8) < ARRAY_SIZE(ausUartBases)) {
0181         pSettings->usUartBaseIO = ausUartBases[(usSI & 0xFF00) >> 8];
0182     } else {
0183         pSettings->usUartBaseIO = 0;
0184     }
0185 
0186     PRINTK_4(TRACE_SMAPI,
0187         "smapi::smapi_query_DSP_cfg get DSP modem settings bModemEnabled %x usUartIRQ %x usUartBaseIO %x\n",
0188         pSettings->bModemEnabled,
0189         pSettings->usUartIRQ,
0190         pSettings->usUartBaseIO);
0191 
0192     /* check for illegal values */
0193     if ( pSettings->usUartBaseIO == 0 ) 
0194         PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART base I/O address is 0\n");
0195     if ( pSettings->usUartIRQ == 0 )
0196         PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART IRQ line is 0\n");
0197 
0198     PRINTK_2(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg exit bRC %x\n", bRC);
0199 
0200     return bRC;
0201 }
0202 
0203 
0204 int smapi_set_DSP_cfg(void)
0205 {
0206     int bRC = -EIO;
0207     int i;
0208     unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
0209     static const unsigned short ausDspBases[] = {
0210         0x0030, 0x4E30, 0x8E30, 0xCE30,
0211         0x0130, 0x0350, 0x0070, 0x0DB0 };
0212     static const unsigned short ausUartBases[] = {
0213         0x03F8, 0x02F8, 0x03E8, 0x02E8 };
0214     static const unsigned short ausDspIrqs[] = {
0215         5, 7, 10, 11, 15 };
0216     static const unsigned short ausUartIrqs[] = {
0217         3, 4 };
0218 
0219     unsigned short dspio_index = 0, uartio_index = 0;
0220 
0221     PRINTK_5(TRACE_SMAPI,
0222         "smapi::smapi_set_DSP_cfg entry mwave_3780i_irq %x mwave_3780i_io %x mwave_uart_irq %x mwave_uart_io %x\n",
0223         mwave_3780i_irq, mwave_3780i_io, mwave_uart_irq, mwave_uart_io);
0224 
0225     if (mwave_3780i_io) {
0226         for (i = 0; i < ARRAY_SIZE(ausDspBases); i++) {
0227             if (mwave_3780i_io == ausDspBases[i])
0228                 break;
0229         }
0230         if (i == ARRAY_SIZE(ausDspBases)) {
0231             PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_io address %x. Aborting.\n", mwave_3780i_io);
0232             return bRC;
0233         }
0234         dspio_index = i;
0235     }
0236 
0237     if (mwave_3780i_irq) {
0238         for (i = 0; i < ARRAY_SIZE(ausDspIrqs); i++) {
0239             if (mwave_3780i_irq == ausDspIrqs[i])
0240                 break;
0241         }
0242         if (i == ARRAY_SIZE(ausDspIrqs)) {
0243             PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_irq %x. Aborting.\n", mwave_3780i_irq);
0244             return bRC;
0245         }
0246     }
0247 
0248     if (mwave_uart_io) {
0249         for (i = 0; i < ARRAY_SIZE(ausUartBases); i++) {
0250             if (mwave_uart_io == ausUartBases[i])
0251                 break;
0252         }
0253         if (i == ARRAY_SIZE(ausUartBases)) {
0254             PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_io address %x. Aborting.\n", mwave_uart_io);
0255             return bRC;
0256         }
0257         uartio_index = i;
0258     }
0259 
0260 
0261     if (mwave_uart_irq) {
0262         for (i = 0; i < ARRAY_SIZE(ausUartIrqs); i++) {
0263             if (mwave_uart_irq == ausUartIrqs[i])
0264                 break;
0265         }
0266         if (i == ARRAY_SIZE(ausUartIrqs)) {
0267             PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_irq %x. Aborting.\n", mwave_uart_irq);
0268             return bRC;
0269         }
0270     }
0271 
0272     if (mwave_uart_irq || mwave_uart_io) {
0273 
0274         /* Check serial port A */
0275         bRC = smapi_request(0x1402, 0x0000, 0, 0,
0276             &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0277         if (bRC) goto exit_smapi_request_error;
0278         /* bRC == 0 */
0279         if (usBX & 0x0100) {    /* serial port A is present */
0280             if (usCX & 1) { /* serial port is enabled */
0281                 if ((usSI & 0xFF) == mwave_uart_irq) {
0282 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
0283                     PRINTK_ERROR(KERN_ERR_MWAVE
0284                         "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
0285 #else
0286                     PRINTK_3(TRACE_SMAPI,
0287                         "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
0288 #endif
0289 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
0290                     PRINTK_1(TRACE_SMAPI,
0291                         "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
0292                     bRC = smapi_request(0x1403, 0x0100, 0, usSI,
0293                         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0294                     if (bRC) goto exit_smapi_request_error;
0295                     bRC = smapi_request(0x1402, 0x0000, 0, 0,
0296                         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0297                     if (bRC) goto exit_smapi_request_error;
0298 #else
0299                     goto exit_conflict;
0300 #endif
0301                 } else {
0302                     if ((usSI >> 8) == uartio_index) {
0303 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
0304                         PRINTK_ERROR(KERN_ERR_MWAVE
0305                             "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]);
0306 #else
0307                         PRINTK_3(TRACE_SMAPI,
0308                             "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]);
0309 #endif
0310 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
0311                         PRINTK_1(TRACE_SMAPI,
0312                             "smapi::smapi_set_DSP_cfg Disabling conflicting serial port A\n");
0313                         bRC = smapi_request (0x1403, 0x0100, 0, usSI,
0314                             &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0315                         if (bRC) goto exit_smapi_request_error;
0316                         bRC = smapi_request (0x1402, 0x0000, 0, 0,
0317                             &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0318                         if (bRC) goto exit_smapi_request_error;
0319 #else
0320                         goto exit_conflict;
0321 #endif
0322                     }
0323                 }
0324             }
0325         }
0326 
0327         /* Check serial port B */
0328         bRC = smapi_request(0x1404, 0x0000, 0, 0,
0329             &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0330         if (bRC) goto exit_smapi_request_error;
0331         /* bRC == 0 */
0332         if (usBX & 0x0100) {    /* serial port B is present */
0333             if (usCX & 1) { /* serial port is enabled */
0334                 if ((usSI & 0xFF) == mwave_uart_irq) {
0335 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
0336                     PRINTK_ERROR(KERN_ERR_MWAVE
0337                         "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
0338 #else
0339                     PRINTK_3(TRACE_SMAPI,
0340                         "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
0341 #endif
0342 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
0343                     PRINTK_1(TRACE_SMAPI,
0344                         "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n");
0345                     bRC = smapi_request(0x1405, 0x0100, 0, usSI,
0346                         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0347                     if (bRC) goto exit_smapi_request_error;
0348                     bRC = smapi_request(0x1404, 0x0000, 0, 0,
0349                         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0350                     if (bRC) goto exit_smapi_request_error;
0351 #else
0352                     goto exit_conflict;
0353 #endif
0354                 } else {
0355                     if ((usSI >> 8) == uartio_index) {
0356 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
0357                         PRINTK_ERROR(KERN_ERR_MWAVE
0358                             "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]);
0359 #else
0360                         PRINTK_3(TRACE_SMAPI,
0361                             "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]);
0362 #endif
0363 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
0364                         PRINTK_1 (TRACE_SMAPI,
0365                             "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n");
0366                         bRC = smapi_request (0x1405, 0x0100, 0, usSI,
0367                             &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0368                         if (bRC) goto exit_smapi_request_error;
0369                         bRC = smapi_request (0x1404, 0x0000, 0, 0,
0370                             &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0371                         if (bRC) goto exit_smapi_request_error;
0372 #else
0373                         goto exit_conflict;
0374 #endif
0375                     }
0376                 }
0377             }
0378         }
0379 
0380         /* Check IR port */
0381         bRC = smapi_request(0x1700, 0x0000, 0, 0,
0382             &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0383         if (bRC) goto exit_smapi_request_error;
0384         bRC = smapi_request(0x1704, 0x0000, 0, 0,
0385             &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0386         if (bRC) goto exit_smapi_request_error;
0387         /* bRC == 0 */
0388         if ((usCX & 0xff) != 0xff) { /* IR port not disabled */
0389             if ((usCX & 0xff) == mwave_uart_irq) {
0390 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
0391                 PRINTK_ERROR(KERN_ERR_MWAVE
0392                     "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);
0393 #else
0394                 PRINTK_3(TRACE_SMAPI,
0395                     "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);
0396 #endif
0397 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
0398                 PRINTK_1(TRACE_SMAPI,
0399                     "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
0400                 bRC = smapi_request(0x1701, 0x0100, 0, 0,
0401                     &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0402                 if (bRC) goto exit_smapi_request_error;
0403                 bRC = smapi_request(0x1700, 0, 0, 0,
0404                     &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0405                 if (bRC) goto exit_smapi_request_error;
0406                 bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
0407                     &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0408                 if (bRC) goto exit_smapi_request_error;
0409                 bRC = smapi_request(0x1704, 0x0000, 0, 0,
0410                     &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0411                 if (bRC) goto exit_smapi_request_error;
0412 #else
0413                 goto exit_conflict;
0414 #endif
0415             } else {
0416                 if ((usSI & 0xff) == uartio_index) {
0417 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
0418                     PRINTK_ERROR(KERN_ERR_MWAVE
0419                         "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]);
0420 #else
0421                     PRINTK_3(TRACE_SMAPI,
0422                         "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]);
0423 #endif
0424 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
0425                     PRINTK_1(TRACE_SMAPI,
0426                         "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
0427                     bRC = smapi_request(0x1701, 0x0100, 0, 0,
0428                         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0429                     if (bRC) goto exit_smapi_request_error;
0430                     bRC = smapi_request(0x1700, 0, 0, 0,
0431                         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0432                     if (bRC) goto exit_smapi_request_error;
0433                     bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
0434                         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0435                     if (bRC) goto exit_smapi_request_error;
0436                     bRC = smapi_request(0x1704, 0x0000, 0, 0,
0437                         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0438                     if (bRC) goto exit_smapi_request_error;
0439 #else
0440                     goto exit_conflict;
0441 #endif
0442                 }
0443             }
0444         }
0445     }
0446 
0447     bRC = smapi_request(0x1802, 0x0000, 0, 0,
0448         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0449     if (bRC) goto exit_smapi_request_error;
0450 
0451     if (mwave_3780i_io) {
0452         usDI = dspio_index;
0453     }
0454     if (mwave_3780i_irq) {
0455         usSI = (usSI & 0xff00) | mwave_3780i_irq;
0456     }
0457 
0458     bRC = smapi_request(0x1803, 0x0101, usDI, usSI,
0459         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0460     if (bRC) goto exit_smapi_request_error;
0461 
0462     bRC = smapi_request(0x1804, 0x0000, 0, 0,
0463         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0464     if (bRC) goto exit_smapi_request_error;
0465 
0466     if (mwave_uart_io) {
0467         usSI = (usSI & 0x00ff) | (uartio_index << 8);
0468     }
0469     if (mwave_uart_irq) {
0470         usSI = (usSI & 0xff00) | mwave_uart_irq;
0471     }
0472     bRC = smapi_request(0x1805, 0x0101, 0, usSI,
0473         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0474     if (bRC) goto exit_smapi_request_error;
0475 
0476     bRC = smapi_request(0x1802, 0x0000, 0, 0,
0477         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0478     if (bRC) goto exit_smapi_request_error;
0479 
0480     bRC = smapi_request(0x1804, 0x0000, 0, 0,
0481         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0482     if (bRC) goto exit_smapi_request_error;
0483 
0484 /* normal exit: */
0485     PRINTK_1(TRACE_SMAPI, "smapi::smapi_set_DSP_cfg exit\n");
0486     return 0;
0487 
0488 exit_conflict:
0489     /* Message has already been printed */
0490     return -EIO;
0491 
0492 exit_smapi_request_error:
0493     PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg exit on smapi_request error bRC %x\n", bRC);
0494     return bRC;
0495 }
0496 
0497 
0498 int smapi_set_DSP_power_state(bool bOn)
0499 {
0500     int bRC;
0501     unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
0502     unsigned short usPowerFunction;
0503 
0504     PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state entry bOn %x\n", bOn);
0505 
0506     usPowerFunction = (bOn) ? 1 : 0;
0507 
0508     bRC = smapi_request(0x4901, 0x0000, 0, usPowerFunction,
0509         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0510 
0511     PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state exit bRC %x\n", bRC);
0512 
0513     return bRC;
0514 }
0515 
0516 #if 0
0517 static int SmapiQuerySystemID(void)
0518 {
0519     int bRC = -EIO;
0520     unsigned short usAX = 0xffff, usBX = 0xffff, usCX = 0xffff,
0521         usDX = 0xffff, usDI = 0xffff, usSI = 0xffff;
0522 
0523     printk("smapi::SmapiQUerySystemID entry\n");
0524     bRC = smapi_request(0x0000, 0, 0, 0,
0525         &usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
0526 
0527     if (bRC == 0) {
0528         printk("AX=%x, BX=%x, CX=%x, DX=%x, DI=%x, SI=%x\n",
0529             usAX, usBX, usCX, usDX, usDI, usSI);
0530     } else {
0531         printk("smapi::SmapiQuerySystemID smapi_request error\n");
0532     }
0533 
0534     return bRC;
0535 }
0536 #endif  /*  0  */
0537 
0538 int smapi_init(void)
0539 {
0540     int retval = -EIO;
0541     unsigned short usSmapiID = 0;
0542     unsigned long flags;
0543 
0544     PRINTK_1(TRACE_SMAPI, "smapi::smapi_init entry\n");
0545 
0546     spin_lock_irqsave(&rtc_lock, flags);
0547     usSmapiID = CMOS_READ(0x7C);
0548     usSmapiID |= (CMOS_READ(0x7D) << 8);
0549     spin_unlock_irqrestore(&rtc_lock, flags);
0550     PRINTK_2(TRACE_SMAPI, "smapi::smapi_init usSmapiID %x\n", usSmapiID);
0551 
0552     if (usSmapiID == 0x5349) {
0553         spin_lock_irqsave(&rtc_lock, flags);
0554         g_usSmapiPort = CMOS_READ(0x7E);
0555         g_usSmapiPort |= (CMOS_READ(0x7F) << 8);
0556         spin_unlock_irqrestore(&rtc_lock, flags);
0557         if (g_usSmapiPort == 0) {
0558             PRINTK_ERROR("smapi::smapi_init, ERROR unable to read from SMAPI port\n");
0559         } else {
0560             PRINTK_2(TRACE_SMAPI,
0561                 "smapi::smapi_init, exit true g_usSmapiPort %x\n",
0562                 g_usSmapiPort);
0563             retval = 0;
0564             //SmapiQuerySystemID();
0565         }
0566     } else {
0567         PRINTK_ERROR("smapi::smapi_init, ERROR invalid usSmapiID\n");
0568         retval = -ENXIO;
0569     }
0570 
0571     return retval;
0572 }