11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * 31da177e4SLinus Torvalds * smapi.c -- SMAPI interface routines 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Written By: Mike Sullivan IBM Corporation 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * Copyright (C) 1999 IBM Corporation 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 111da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by 121da177e4SLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 131da177e4SLinus Torvalds * (at your option) any later version. 141da177e4SLinus Torvalds * 151da177e4SLinus Torvalds * This program is distributed in the hope that it will be useful, 161da177e4SLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 171da177e4SLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 181da177e4SLinus Torvalds * GNU General Public License for more details. 191da177e4SLinus Torvalds * 201da177e4SLinus Torvalds * NO WARRANTY 211da177e4SLinus Torvalds * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 221da177e4SLinus Torvalds * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 231da177e4SLinus Torvalds * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 241da177e4SLinus Torvalds * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 251da177e4SLinus Torvalds * solely responsible for determining the appropriateness of using and 261da177e4SLinus Torvalds * distributing the Program and assumes all risks associated with its 271da177e4SLinus Torvalds * exercise of rights under this Agreement, including but not limited to 281da177e4SLinus Torvalds * the risks and costs of program errors, damage to or loss of data, 291da177e4SLinus Torvalds * programs or equipment, and unavailability or interruption of operations. 301da177e4SLinus Torvalds * 311da177e4SLinus Torvalds * DISCLAIMER OF LIABILITY 321da177e4SLinus Torvalds * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 331da177e4SLinus Torvalds * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 341da177e4SLinus Torvalds * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 351da177e4SLinus Torvalds * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 361da177e4SLinus Torvalds * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 371da177e4SLinus Torvalds * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 381da177e4SLinus Torvalds * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 391da177e4SLinus Torvalds * 401da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License 411da177e4SLinus Torvalds * along with this program; if not, write to the Free Software 421da177e4SLinus Torvalds * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 431da177e4SLinus Torvalds * 441da177e4SLinus Torvalds * 451da177e4SLinus Torvalds * 10/23/2000 - Alpha Release 461da177e4SLinus Torvalds * First release to the public 471da177e4SLinus Torvalds */ 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds #include <linux/kernel.h> 501da177e4SLinus Torvalds #include <linux/mc146818rtc.h> /* CMOS defines */ 511da177e4SLinus Torvalds #include "smapi.h" 521da177e4SLinus Torvalds #include "mwavedd.h" 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds static unsigned short g_usSmapiPort = 0; 551da177e4SLinus Torvalds 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds static int smapi_request(unsigned short inBX, unsigned short inCX, 581da177e4SLinus Torvalds unsigned short inDI, unsigned short inSI, 591da177e4SLinus Torvalds unsigned short *outAX, unsigned short *outBX, 601da177e4SLinus Torvalds unsigned short *outCX, unsigned short *outDX, 611da177e4SLinus Torvalds unsigned short *outDI, unsigned short *outSI) 621da177e4SLinus Torvalds { 631da177e4SLinus Torvalds unsigned short myoutAX = 2, *pmyoutAX = &myoutAX; 641da177e4SLinus Torvalds unsigned short myoutBX = 3, *pmyoutBX = &myoutBX; 651da177e4SLinus Torvalds unsigned short myoutCX = 4, *pmyoutCX = &myoutCX; 661da177e4SLinus Torvalds unsigned short myoutDX = 5, *pmyoutDX = &myoutDX; 671da177e4SLinus Torvalds unsigned short myoutDI = 6, *pmyoutDI = &myoutDI; 681da177e4SLinus Torvalds unsigned short myoutSI = 7, *pmyoutSI = &myoutSI; 691da177e4SLinus Torvalds unsigned short usSmapiOK = -EIO, *pusSmapiOK = &usSmapiOK; 701da177e4SLinus Torvalds unsigned int inBXCX = (inBX << 16) | inCX; 711da177e4SLinus Torvalds unsigned int inDISI = (inDI << 16) | inSI; 721da177e4SLinus Torvalds int retval = 0; 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds PRINTK_5(TRACE_SMAPI, "inBX %x inCX %x inDI %x inSI %x\n", 751da177e4SLinus Torvalds inBX, inCX, inDI, inSI); 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds __asm__ __volatile__("movw $0x5380,%%ax\n\t" 781da177e4SLinus Torvalds "movl %7,%%ebx\n\t" 791da177e4SLinus Torvalds "shrl $16, %%ebx\n\t" 801da177e4SLinus Torvalds "movw %7,%%cx\n\t" 811da177e4SLinus Torvalds "movl %8,%%edi\n\t" 821da177e4SLinus Torvalds "shrl $16,%%edi\n\t" 831da177e4SLinus Torvalds "movw %8,%%si\n\t" 841da177e4SLinus Torvalds "movw %9,%%dx\n\t" 851da177e4SLinus Torvalds "out %%al,%%dx\n\t" 861da177e4SLinus Torvalds "out %%al,$0x4F\n\t" 871da177e4SLinus Torvalds "cmpb $0x53,%%ah\n\t" 881da177e4SLinus Torvalds "je 2f\n\t" 891da177e4SLinus Torvalds "1:\n\t" 901da177e4SLinus Torvalds "orb %%ah,%%ah\n\t" 911da177e4SLinus Torvalds "jnz 2f\n\t" 921da177e4SLinus Torvalds "movw %%ax,%0\n\t" 931da177e4SLinus Torvalds "movw %%bx,%1\n\t" 941da177e4SLinus Torvalds "movw %%cx,%2\n\t" 951da177e4SLinus Torvalds "movw %%dx,%3\n\t" 961da177e4SLinus Torvalds "movw %%di,%4\n\t" 971da177e4SLinus Torvalds "movw %%si,%5\n\t" 981da177e4SLinus Torvalds "movw $1,%6\n\t" 991da177e4SLinus Torvalds "2:\n\t":"=m"(*(unsigned short *) pmyoutAX), 1001da177e4SLinus Torvalds "=m"(*(unsigned short *) pmyoutBX), 1011da177e4SLinus Torvalds "=m"(*(unsigned short *) pmyoutCX), 1021da177e4SLinus Torvalds "=m"(*(unsigned short *) pmyoutDX), 1031da177e4SLinus Torvalds "=m"(*(unsigned short *) pmyoutDI), 1041da177e4SLinus Torvalds "=m"(*(unsigned short *) pmyoutSI), 1051da177e4SLinus Torvalds "=m"(*(unsigned short *) pusSmapiOK) 1061da177e4SLinus Torvalds :"m"(inBXCX), "m"(inDISI), "m"(g_usSmapiPort) 1071da177e4SLinus Torvalds :"%eax", "%ebx", "%ecx", "%edx", "%edi", 1081da177e4SLinus Torvalds "%esi"); 1091da177e4SLinus Torvalds 1101da177e4SLinus Torvalds PRINTK_8(TRACE_SMAPI, 1111da177e4SLinus Torvalds "myoutAX %x myoutBX %x myoutCX %x myoutDX %x myoutDI %x myoutSI %x usSmapiOK %x\n", 1121da177e4SLinus Torvalds myoutAX, myoutBX, myoutCX, myoutDX, myoutDI, myoutSI, 1131da177e4SLinus Torvalds usSmapiOK); 1141da177e4SLinus Torvalds *outAX = myoutAX; 1151da177e4SLinus Torvalds *outBX = myoutBX; 1161da177e4SLinus Torvalds *outCX = myoutCX; 1171da177e4SLinus Torvalds *outDX = myoutDX; 1181da177e4SLinus Torvalds *outDI = myoutDI; 1191da177e4SLinus Torvalds *outSI = myoutSI; 1201da177e4SLinus Torvalds 1211da177e4SLinus Torvalds retval = (usSmapiOK == 1) ? 0 : -EIO; 1221da177e4SLinus Torvalds PRINTK_2(TRACE_SMAPI, "smapi::smapi_request exit retval %x\n", retval); 1231da177e4SLinus Torvalds return retval; 1241da177e4SLinus Torvalds } 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings) 1281da177e4SLinus Torvalds { 129*7ca78630SColin Ian King int bRC; 1301da177e4SLinus Torvalds unsigned short usAX, usBX, usCX, usDX, usDI, usSI; 131caa97be1SColin Ian King static const unsigned short ausDspBases[] = { 132caa97be1SColin Ian King 0x0030, 0x4E30, 0x8E30, 0xCE30, 133caa97be1SColin Ian King 0x0130, 0x0350, 0x0070, 0x0DB0 }; 134caa97be1SColin Ian King static const unsigned short ausUartBases[] = { 135caa97be1SColin Ian King 0x03F8, 0x02F8, 0x03E8, 0x02E8 }; 1361da177e4SLinus Torvalds 1371da177e4SLinus Torvalds PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg entry\n"); 1381da177e4SLinus Torvalds 1391da177e4SLinus Torvalds bRC = smapi_request(0x1802, 0x0000, 0, 0, 1401da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 1411da177e4SLinus Torvalds if (bRC) { 1421da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Error: Could not get DSP Settings. Aborting.\n"); 1431da177e4SLinus Torvalds return bRC; 1441da177e4SLinus Torvalds } 1451da177e4SLinus Torvalds 1461da177e4SLinus Torvalds PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n"); 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds pSettings->bDSPPresent = ((usBX & 0x0100) != 0); 1491da177e4SLinus Torvalds pSettings->bDSPEnabled = ((usCX & 0x0001) != 0); 1501da177e4SLinus Torvalds pSettings->usDspIRQ = usSI & 0x00FF; 1511da177e4SLinus Torvalds pSettings->usDspDMA = (usSI & 0xFF00) >> 8; 152caa97be1SColin Ian King if ((usDI & 0x00FF) < ARRAY_SIZE(ausDspBases)) { 1531da177e4SLinus Torvalds pSettings->usDspBaseIO = ausDspBases[usDI & 0x00FF]; 1541da177e4SLinus Torvalds } else { 1551da177e4SLinus Torvalds pSettings->usDspBaseIO = 0; 1561da177e4SLinus Torvalds } 1571da177e4SLinus Torvalds PRINTK_6(TRACE_SMAPI, 1581da177e4SLinus Torvalds "smapi::smapi_query_DSP_cfg get DSP Settings bDSPPresent %x bDSPEnabled %x usDspIRQ %x usDspDMA %x usDspBaseIO %x\n", 1591da177e4SLinus Torvalds pSettings->bDSPPresent, pSettings->bDSPEnabled, 1601da177e4SLinus Torvalds pSettings->usDspIRQ, pSettings->usDspDMA, 1611da177e4SLinus Torvalds pSettings->usDspBaseIO); 1621da177e4SLinus Torvalds 1631da177e4SLinus Torvalds /* check for illegal values */ 1641da177e4SLinus Torvalds if ( pSettings->usDspBaseIO == 0 ) 1651da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP base I/O address is 0\n"); 1661da177e4SLinus Torvalds if ( pSettings->usDspIRQ == 0 ) 1671da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP IRQ line is 0\n"); 1681da177e4SLinus Torvalds 1691da177e4SLinus Torvalds bRC = smapi_request(0x1804, 0x0000, 0, 0, 1701da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 1711da177e4SLinus Torvalds if (bRC) { 1721da177e4SLinus Torvalds PRINTK_ERROR("smapi::smapi_query_DSP_cfg: Error: Could not get DSP modem settings. Aborting.\n"); 1731da177e4SLinus Torvalds return bRC; 1741da177e4SLinus Torvalds } 1751da177e4SLinus Torvalds 1761da177e4SLinus Torvalds PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n"); 1771da177e4SLinus Torvalds 1781da177e4SLinus Torvalds pSettings->bModemEnabled = ((usCX & 0x0001) != 0); 1791da177e4SLinus Torvalds pSettings->usUartIRQ = usSI & 0x000F; 180caa97be1SColin Ian King if (((usSI & 0xFF00) >> 8) < ARRAY_SIZE(ausUartBases)) { 1811da177e4SLinus Torvalds pSettings->usUartBaseIO = ausUartBases[(usSI & 0xFF00) >> 8]; 1821da177e4SLinus Torvalds } else { 1831da177e4SLinus Torvalds pSettings->usUartBaseIO = 0; 1841da177e4SLinus Torvalds } 1851da177e4SLinus Torvalds 1861da177e4SLinus Torvalds PRINTK_4(TRACE_SMAPI, 1871da177e4SLinus Torvalds "smapi::smapi_query_DSP_cfg get DSP modem settings bModemEnabled %x usUartIRQ %x usUartBaseIO %x\n", 1881da177e4SLinus Torvalds pSettings->bModemEnabled, 1891da177e4SLinus Torvalds pSettings->usUartIRQ, 1901da177e4SLinus Torvalds pSettings->usUartBaseIO); 1911da177e4SLinus Torvalds 1921da177e4SLinus Torvalds /* check for illegal values */ 1931da177e4SLinus Torvalds if ( pSettings->usUartBaseIO == 0 ) 1941da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART base I/O address is 0\n"); 1951da177e4SLinus Torvalds if ( pSettings->usUartIRQ == 0 ) 1961da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART IRQ line is 0\n"); 1971da177e4SLinus Torvalds 1981da177e4SLinus Torvalds PRINTK_2(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg exit bRC %x\n", bRC); 1991da177e4SLinus Torvalds 2001da177e4SLinus Torvalds return bRC; 2011da177e4SLinus Torvalds } 2021da177e4SLinus Torvalds 2031da177e4SLinus Torvalds 2041da177e4SLinus Torvalds int smapi_set_DSP_cfg(void) 2051da177e4SLinus Torvalds { 2061da177e4SLinus Torvalds int bRC = -EIO; 2071da177e4SLinus Torvalds int i; 2081da177e4SLinus Torvalds unsigned short usAX, usBX, usCX, usDX, usDI, usSI; 209caa97be1SColin Ian King static const unsigned short ausDspBases[] = { 210caa97be1SColin Ian King 0x0030, 0x4E30, 0x8E30, 0xCE30, 211caa97be1SColin Ian King 0x0130, 0x0350, 0x0070, 0x0DB0 }; 212caa97be1SColin Ian King static const unsigned short ausUartBases[] = { 213caa97be1SColin Ian King 0x03F8, 0x02F8, 0x03E8, 0x02E8 }; 214caa97be1SColin Ian King static const unsigned short ausDspIrqs[] = { 215caa97be1SColin Ian King 5, 7, 10, 11, 15 }; 216caa97be1SColin Ian King static const unsigned short ausUartIrqs[] = { 217caa97be1SColin Ian King 3, 4 }; 2181da177e4SLinus Torvalds 2191da177e4SLinus Torvalds unsigned short dspio_index = 0, uartio_index = 0; 2201da177e4SLinus Torvalds 2211da177e4SLinus Torvalds PRINTK_5(TRACE_SMAPI, 2221da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg entry mwave_3780i_irq %x mwave_3780i_io %x mwave_uart_irq %x mwave_uart_io %x\n", 2231da177e4SLinus Torvalds mwave_3780i_irq, mwave_3780i_io, mwave_uart_irq, mwave_uart_io); 2241da177e4SLinus Torvalds 2251da177e4SLinus Torvalds if (mwave_3780i_io) { 226caa97be1SColin Ian King for (i = 0; i < ARRAY_SIZE(ausDspBases); i++) { 2271da177e4SLinus Torvalds if (mwave_3780i_io == ausDspBases[i]) 2281da177e4SLinus Torvalds break; 2291da177e4SLinus Torvalds } 230caa97be1SColin Ian King if (i == ARRAY_SIZE(ausDspBases)) { 2311da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_io address %x. Aborting.\n", mwave_3780i_io); 2321da177e4SLinus Torvalds return bRC; 2331da177e4SLinus Torvalds } 2341da177e4SLinus Torvalds dspio_index = i; 2351da177e4SLinus Torvalds } 2361da177e4SLinus Torvalds 2371da177e4SLinus Torvalds if (mwave_3780i_irq) { 238caa97be1SColin Ian King for (i = 0; i < ARRAY_SIZE(ausDspIrqs); i++) { 2391da177e4SLinus Torvalds if (mwave_3780i_irq == ausDspIrqs[i]) 2401da177e4SLinus Torvalds break; 2411da177e4SLinus Torvalds } 242caa97be1SColin Ian King if (i == ARRAY_SIZE(ausDspIrqs)) { 2431da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_irq %x. Aborting.\n", mwave_3780i_irq); 2441da177e4SLinus Torvalds return bRC; 2451da177e4SLinus Torvalds } 2461da177e4SLinus Torvalds } 2471da177e4SLinus Torvalds 2481da177e4SLinus Torvalds if (mwave_uart_io) { 249caa97be1SColin Ian King for (i = 0; i < ARRAY_SIZE(ausUartBases); i++) { 2501da177e4SLinus Torvalds if (mwave_uart_io == ausUartBases[i]) 2511da177e4SLinus Torvalds break; 2521da177e4SLinus Torvalds } 253caa97be1SColin Ian King if (i == ARRAY_SIZE(ausUartBases)) { 2541da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_io address %x. Aborting.\n", mwave_uart_io); 2551da177e4SLinus Torvalds return bRC; 2561da177e4SLinus Torvalds } 2571da177e4SLinus Torvalds uartio_index = i; 2581da177e4SLinus Torvalds } 2591da177e4SLinus Torvalds 2601da177e4SLinus Torvalds 2611da177e4SLinus Torvalds if (mwave_uart_irq) { 262caa97be1SColin Ian King for (i = 0; i < ARRAY_SIZE(ausUartIrqs); i++) { 2631da177e4SLinus Torvalds if (mwave_uart_irq == ausUartIrqs[i]) 2641da177e4SLinus Torvalds break; 2651da177e4SLinus Torvalds } 266caa97be1SColin Ian King if (i == ARRAY_SIZE(ausUartIrqs)) { 2671da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_irq %x. Aborting.\n", mwave_uart_irq); 2681da177e4SLinus Torvalds return bRC; 2691da177e4SLinus Torvalds } 2701da177e4SLinus Torvalds } 2711da177e4SLinus Torvalds 2721da177e4SLinus Torvalds if (mwave_uart_irq || mwave_uart_io) { 2731da177e4SLinus Torvalds 2741da177e4SLinus Torvalds /* Check serial port A */ 2751da177e4SLinus Torvalds bRC = smapi_request(0x1402, 0x0000, 0, 0, 2761da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 2771da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 2781da177e4SLinus Torvalds /* bRC == 0 */ 2791da177e4SLinus Torvalds if (usBX & 0x0100) { /* serial port A is present */ 2801da177e4SLinus Torvalds if (usCX & 1) { /* serial port is enabled */ 2811da177e4SLinus Torvalds if ((usSI & 0xFF) == mwave_uart_irq) { 2821da177e4SLinus Torvalds #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES 2831da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE 2841da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq); 2851da177e4SLinus Torvalds #else 2861da177e4SLinus Torvalds PRINTK_3(TRACE_SMAPI, 2871da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq); 2881da177e4SLinus Torvalds #endif 2891da177e4SLinus Torvalds #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES 2901da177e4SLinus Torvalds PRINTK_1(TRACE_SMAPI, 2911da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n"); 2921da177e4SLinus Torvalds bRC = smapi_request(0x1403, 0x0100, 0, usSI, 2931da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 2941da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 2951da177e4SLinus Torvalds bRC = smapi_request(0x1402, 0x0000, 0, 0, 2961da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 2971da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 2981da177e4SLinus Torvalds #else 2991da177e4SLinus Torvalds goto exit_conflict; 3001da177e4SLinus Torvalds #endif 3011da177e4SLinus Torvalds } else { 3021da177e4SLinus Torvalds if ((usSI >> 8) == uartio_index) { 3031da177e4SLinus Torvalds #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES 3041da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE 3051da177e4SLinus Torvalds "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]); 3061da177e4SLinus Torvalds #else 3071da177e4SLinus Torvalds PRINTK_3(TRACE_SMAPI, 3081da177e4SLinus Torvalds "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]); 3091da177e4SLinus Torvalds #endif 3101da177e4SLinus Torvalds #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES 3111da177e4SLinus Torvalds PRINTK_1(TRACE_SMAPI, 3121da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg Disabling conflicting serial port A\n"); 3131da177e4SLinus Torvalds bRC = smapi_request (0x1403, 0x0100, 0, usSI, 3141da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 3151da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 3161da177e4SLinus Torvalds bRC = smapi_request (0x1402, 0x0000, 0, 0, 3171da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 3181da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 3191da177e4SLinus Torvalds #else 3201da177e4SLinus Torvalds goto exit_conflict; 3211da177e4SLinus Torvalds #endif 3221da177e4SLinus Torvalds } 3231da177e4SLinus Torvalds } 3241da177e4SLinus Torvalds } 3251da177e4SLinus Torvalds } 3261da177e4SLinus Torvalds 3271da177e4SLinus Torvalds /* Check serial port B */ 3281da177e4SLinus Torvalds bRC = smapi_request(0x1404, 0x0000, 0, 0, 3291da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 3301da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 3311da177e4SLinus Torvalds /* bRC == 0 */ 3321da177e4SLinus Torvalds if (usBX & 0x0100) { /* serial port B is present */ 3331da177e4SLinus Torvalds if (usCX & 1) { /* serial port is enabled */ 3341da177e4SLinus Torvalds if ((usSI & 0xFF) == mwave_uart_irq) { 3351da177e4SLinus Torvalds #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES 3361da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE 3371da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq); 3381da177e4SLinus Torvalds #else 3391da177e4SLinus Torvalds PRINTK_3(TRACE_SMAPI, 3401da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq); 3411da177e4SLinus Torvalds #endif 3421da177e4SLinus Torvalds #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES 3431da177e4SLinus Torvalds PRINTK_1(TRACE_SMAPI, 3441da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n"); 3451da177e4SLinus Torvalds bRC = smapi_request(0x1405, 0x0100, 0, usSI, 3461da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 3471da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 3481da177e4SLinus Torvalds bRC = smapi_request(0x1404, 0x0000, 0, 0, 3491da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 3501da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 3511da177e4SLinus Torvalds #else 3521da177e4SLinus Torvalds goto exit_conflict; 3531da177e4SLinus Torvalds #endif 3541da177e4SLinus Torvalds } else { 3551da177e4SLinus Torvalds if ((usSI >> 8) == uartio_index) { 3561da177e4SLinus Torvalds #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES 3571da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE 3581da177e4SLinus Torvalds "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]); 3591da177e4SLinus Torvalds #else 3601da177e4SLinus Torvalds PRINTK_3(TRACE_SMAPI, 3611da177e4SLinus Torvalds "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]); 3621da177e4SLinus Torvalds #endif 3631da177e4SLinus Torvalds #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES 3641da177e4SLinus Torvalds PRINTK_1 (TRACE_SMAPI, 3651da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n"); 3661da177e4SLinus Torvalds bRC = smapi_request (0x1405, 0x0100, 0, usSI, 3671da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 3681da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 3691da177e4SLinus Torvalds bRC = smapi_request (0x1404, 0x0000, 0, 0, 3701da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 3711da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 3721da177e4SLinus Torvalds #else 3731da177e4SLinus Torvalds goto exit_conflict; 3741da177e4SLinus Torvalds #endif 3751da177e4SLinus Torvalds } 3761da177e4SLinus Torvalds } 3771da177e4SLinus Torvalds } 3781da177e4SLinus Torvalds } 3791da177e4SLinus Torvalds 3801da177e4SLinus Torvalds /* Check IR port */ 3811da177e4SLinus Torvalds bRC = smapi_request(0x1700, 0x0000, 0, 0, 3821da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 3831da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 3841da177e4SLinus Torvalds bRC = smapi_request(0x1704, 0x0000, 0, 0, 3851da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 3861da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 3871da177e4SLinus Torvalds /* bRC == 0 */ 3881da177e4SLinus Torvalds if ((usCX & 0xff) != 0xff) { /* IR port not disabled */ 3891da177e4SLinus Torvalds if ((usCX & 0xff) == mwave_uart_irq) { 3901da177e4SLinus Torvalds #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES 3911da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE 3921da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq); 3931da177e4SLinus Torvalds #else 3941da177e4SLinus Torvalds PRINTK_3(TRACE_SMAPI, 3951da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq); 3961da177e4SLinus Torvalds #endif 3971da177e4SLinus Torvalds #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES 3981da177e4SLinus Torvalds PRINTK_1(TRACE_SMAPI, 3991da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n"); 4001da177e4SLinus Torvalds bRC = smapi_request(0x1701, 0x0100, 0, 0, 4011da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4021da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4031da177e4SLinus Torvalds bRC = smapi_request(0x1700, 0, 0, 0, 4041da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4051da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4061da177e4SLinus Torvalds bRC = smapi_request(0x1705, 0x01ff, 0, usSI, 4071da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4081da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4091da177e4SLinus Torvalds bRC = smapi_request(0x1704, 0x0000, 0, 0, 4101da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4111da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4121da177e4SLinus Torvalds #else 4131da177e4SLinus Torvalds goto exit_conflict; 4141da177e4SLinus Torvalds #endif 4151da177e4SLinus Torvalds } else { 4161da177e4SLinus Torvalds if ((usSI & 0xff) == uartio_index) { 4171da177e4SLinus Torvalds #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES 4181da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE 4191da177e4SLinus Torvalds "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]); 4201da177e4SLinus Torvalds #else 4211da177e4SLinus Torvalds PRINTK_3(TRACE_SMAPI, 4221da177e4SLinus Torvalds "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]); 4231da177e4SLinus Torvalds #endif 4241da177e4SLinus Torvalds #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES 4251da177e4SLinus Torvalds PRINTK_1(TRACE_SMAPI, 4261da177e4SLinus Torvalds "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n"); 4271da177e4SLinus Torvalds bRC = smapi_request(0x1701, 0x0100, 0, 0, 4281da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4291da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4301da177e4SLinus Torvalds bRC = smapi_request(0x1700, 0, 0, 0, 4311da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4321da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4331da177e4SLinus Torvalds bRC = smapi_request(0x1705, 0x01ff, 0, usSI, 4341da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4351da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4361da177e4SLinus Torvalds bRC = smapi_request(0x1704, 0x0000, 0, 0, 4371da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4381da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4391da177e4SLinus Torvalds #else 4401da177e4SLinus Torvalds goto exit_conflict; 4411da177e4SLinus Torvalds #endif 4421da177e4SLinus Torvalds } 4431da177e4SLinus Torvalds } 4441da177e4SLinus Torvalds } 4451da177e4SLinus Torvalds } 4461da177e4SLinus Torvalds 4471da177e4SLinus Torvalds bRC = smapi_request(0x1802, 0x0000, 0, 0, 4481da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4491da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4501da177e4SLinus Torvalds 4511da177e4SLinus Torvalds if (mwave_3780i_io) { 4521da177e4SLinus Torvalds usDI = dspio_index; 4531da177e4SLinus Torvalds } 4541da177e4SLinus Torvalds if (mwave_3780i_irq) { 4551da177e4SLinus Torvalds usSI = (usSI & 0xff00) | mwave_3780i_irq; 4561da177e4SLinus Torvalds } 4571da177e4SLinus Torvalds 4581da177e4SLinus Torvalds bRC = smapi_request(0x1803, 0x0101, usDI, usSI, 4591da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4601da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4611da177e4SLinus Torvalds 4621da177e4SLinus Torvalds bRC = smapi_request(0x1804, 0x0000, 0, 0, 4631da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4641da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4651da177e4SLinus Torvalds 4661da177e4SLinus Torvalds if (mwave_uart_io) { 4671da177e4SLinus Torvalds usSI = (usSI & 0x00ff) | (uartio_index << 8); 4681da177e4SLinus Torvalds } 4691da177e4SLinus Torvalds if (mwave_uart_irq) { 4701da177e4SLinus Torvalds usSI = (usSI & 0xff00) | mwave_uart_irq; 4711da177e4SLinus Torvalds } 4721da177e4SLinus Torvalds bRC = smapi_request(0x1805, 0x0101, 0, usSI, 4731da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4741da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4751da177e4SLinus Torvalds 4761da177e4SLinus Torvalds bRC = smapi_request(0x1802, 0x0000, 0, 0, 4771da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4781da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4791da177e4SLinus Torvalds 4801da177e4SLinus Torvalds bRC = smapi_request(0x1804, 0x0000, 0, 0, 4811da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 4821da177e4SLinus Torvalds if (bRC) goto exit_smapi_request_error; 4831da177e4SLinus Torvalds 4841da177e4SLinus Torvalds /* normal exit: */ 4851da177e4SLinus Torvalds PRINTK_1(TRACE_SMAPI, "smapi::smapi_set_DSP_cfg exit\n"); 4861da177e4SLinus Torvalds return 0; 4871da177e4SLinus Torvalds 4881da177e4SLinus Torvalds exit_conflict: 4891da177e4SLinus Torvalds /* Message has already been printed */ 4901da177e4SLinus Torvalds return -EIO; 4911da177e4SLinus Torvalds 4921da177e4SLinus Torvalds exit_smapi_request_error: 4931da177e4SLinus Torvalds PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg exit on smapi_request error bRC %x\n", bRC); 4941da177e4SLinus Torvalds return bRC; 4951da177e4SLinus Torvalds } 4961da177e4SLinus Torvalds 4971da177e4SLinus Torvalds 49826ec99b1SArnd Bergmann int smapi_set_DSP_power_state(bool bOn) 4991da177e4SLinus Torvalds { 500*7ca78630SColin Ian King int bRC; 5011da177e4SLinus Torvalds unsigned short usAX, usBX, usCX, usDX, usDI, usSI; 5021da177e4SLinus Torvalds unsigned short usPowerFunction; 5031da177e4SLinus Torvalds 5041da177e4SLinus Torvalds PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state entry bOn %x\n", bOn); 5051da177e4SLinus Torvalds 5061da177e4SLinus Torvalds usPowerFunction = (bOn) ? 1 : 0; 5071da177e4SLinus Torvalds 5081da177e4SLinus Torvalds bRC = smapi_request(0x4901, 0x0000, 0, usPowerFunction, 5091da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 5101da177e4SLinus Torvalds 5111da177e4SLinus Torvalds PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state exit bRC %x\n", bRC); 5121da177e4SLinus Torvalds 5131da177e4SLinus Torvalds return bRC; 5141da177e4SLinus Torvalds } 5151da177e4SLinus Torvalds 5161da177e4SLinus Torvalds #if 0 5171da177e4SLinus Torvalds static int SmapiQuerySystemID(void) 5181da177e4SLinus Torvalds { 5191da177e4SLinus Torvalds int bRC = -EIO; 5201da177e4SLinus Torvalds unsigned short usAX = 0xffff, usBX = 0xffff, usCX = 0xffff, 5211da177e4SLinus Torvalds usDX = 0xffff, usDI = 0xffff, usSI = 0xffff; 5221da177e4SLinus Torvalds 5231da177e4SLinus Torvalds printk("smapi::SmapiQUerySystemID entry\n"); 5241da177e4SLinus Torvalds bRC = smapi_request(0x0000, 0, 0, 0, 5251da177e4SLinus Torvalds &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); 5261da177e4SLinus Torvalds 5271da177e4SLinus Torvalds if (bRC == 0) { 5281da177e4SLinus Torvalds printk("AX=%x, BX=%x, CX=%x, DX=%x, DI=%x, SI=%x\n", 5291da177e4SLinus Torvalds usAX, usBX, usCX, usDX, usDI, usSI); 5301da177e4SLinus Torvalds } else { 5311da177e4SLinus Torvalds printk("smapi::SmapiQuerySystemID smapi_request error\n"); 5321da177e4SLinus Torvalds } 5331da177e4SLinus Torvalds 5341da177e4SLinus Torvalds return bRC; 5351da177e4SLinus Torvalds } 5361da177e4SLinus Torvalds #endif /* 0 */ 5371da177e4SLinus Torvalds 5381da177e4SLinus Torvalds int smapi_init(void) 5391da177e4SLinus Torvalds { 5401da177e4SLinus Torvalds int retval = -EIO; 5411da177e4SLinus Torvalds unsigned short usSmapiID = 0; 5421da177e4SLinus Torvalds unsigned long flags; 5431da177e4SLinus Torvalds 5441da177e4SLinus Torvalds PRINTK_1(TRACE_SMAPI, "smapi::smapi_init entry\n"); 5451da177e4SLinus Torvalds 5461da177e4SLinus Torvalds spin_lock_irqsave(&rtc_lock, flags); 5471da177e4SLinus Torvalds usSmapiID = CMOS_READ(0x7C); 5481da177e4SLinus Torvalds usSmapiID |= (CMOS_READ(0x7D) << 8); 5491da177e4SLinus Torvalds spin_unlock_irqrestore(&rtc_lock, flags); 5501da177e4SLinus Torvalds PRINTK_2(TRACE_SMAPI, "smapi::smapi_init usSmapiID %x\n", usSmapiID); 5511da177e4SLinus Torvalds 5521da177e4SLinus Torvalds if (usSmapiID == 0x5349) { 5531da177e4SLinus Torvalds spin_lock_irqsave(&rtc_lock, flags); 5541da177e4SLinus Torvalds g_usSmapiPort = CMOS_READ(0x7E); 5551da177e4SLinus Torvalds g_usSmapiPort |= (CMOS_READ(0x7F) << 8); 5561da177e4SLinus Torvalds spin_unlock_irqrestore(&rtc_lock, flags); 5571da177e4SLinus Torvalds if (g_usSmapiPort == 0) { 5581da177e4SLinus Torvalds PRINTK_ERROR("smapi::smapi_init, ERROR unable to read from SMAPI port\n"); 5591da177e4SLinus Torvalds } else { 5601da177e4SLinus Torvalds PRINTK_2(TRACE_SMAPI, 56126ec99b1SArnd Bergmann "smapi::smapi_init, exit true g_usSmapiPort %x\n", 5621da177e4SLinus Torvalds g_usSmapiPort); 5631da177e4SLinus Torvalds retval = 0; 5641da177e4SLinus Torvalds //SmapiQuerySystemID(); 5651da177e4SLinus Torvalds } 5661da177e4SLinus Torvalds } else { 5671da177e4SLinus Torvalds PRINTK_ERROR("smapi::smapi_init, ERROR invalid usSmapiID\n"); 5681da177e4SLinus Torvalds retval = -ENXIO; 5691da177e4SLinus Torvalds } 5701da177e4SLinus Torvalds 5711da177e4SLinus Torvalds return retval; 5721da177e4SLinus Torvalds } 573