Root/drivers/char/mwave/smapi.c

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
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 = -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
203int 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
486exit_conflict:
487    /* Message has already been printed */
488    return -EIO;
489
490exit_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
496int smapi_set_DSP_power_state(BOOLEAN 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
515static 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
536int 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

Archive Download this file



interactive