Back to home page

OSCL-LXR

 
 

    


0001 /*
0002 *
0003 * tp3780i.c -- board driver for 3780i on ThinkPads
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/interrupt.h>
0050 #include <linux/kernel.h>
0051 #include <linux/ptrace.h>
0052 #include <linux/ioport.h>
0053 #include <asm/io.h>
0054 #include "smapi.h"
0055 #include "mwavedd.h"
0056 #include "tp3780i.h"
0057 #include "3780i.h"
0058 #include "mwavepub.h"
0059 
0060 static unsigned short s_ausThinkpadIrqToField[16] =
0061     { 0xFFFF, 0xFFFF, 0xFFFF, 0x0001, 0x0002, 0x0003, 0xFFFF, 0x0004,
0062     0xFFFF, 0xFFFF, 0x0005, 0x0006, 0xFFFF, 0xFFFF, 0xFFFF, 0x0007 };
0063 static unsigned short s_ausThinkpadDmaToField[8] =
0064     { 0x0001, 0x0002, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0003, 0x0004 };
0065 static unsigned short s_numIrqs = 16, s_numDmas = 8;
0066 
0067 
0068 static void EnableSRAM(THINKPAD_BD_DATA * pBDData)
0069 {
0070     DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
0071     unsigned short usDspBaseIO = pSettings->usDspBaseIO;
0072     DSP_GPIO_OUTPUT_DATA_15_8 rGpioOutputData;
0073     DSP_GPIO_DRIVER_ENABLE_15_8 rGpioDriverEnable;
0074     DSP_GPIO_MODE_15_8 rGpioMode;
0075 
0076     PRINTK_1(TRACE_TP3780I, "tp3780i::EnableSRAM, entry\n");
0077 
0078     MKWORD(rGpioMode) = ReadMsaCfg(DSP_GpioModeControl_15_8);
0079     rGpioMode.GpioMode10 = 0;
0080     WriteMsaCfg(DSP_GpioModeControl_15_8, MKWORD(rGpioMode));
0081 
0082     MKWORD(rGpioDriverEnable) = 0;
0083     rGpioDriverEnable.Enable10 = true;
0084     rGpioDriverEnable.Mask10 = true;
0085     WriteMsaCfg(DSP_GpioDriverEnable_15_8, MKWORD(rGpioDriverEnable));
0086 
0087     MKWORD(rGpioOutputData) = 0;
0088     rGpioOutputData.Latch10 = 0;
0089     rGpioOutputData.Mask10 = true;
0090     WriteMsaCfg(DSP_GpioOutputData_15_8, MKWORD(rGpioOutputData));
0091 
0092     PRINTK_1(TRACE_TP3780I, "tp3780i::EnableSRAM exit\n");
0093 }
0094 
0095 
0096 static irqreturn_t UartInterrupt(int irq, void *dev_id)
0097 {
0098     PRINTK_3(TRACE_TP3780I,
0099         "tp3780i::UartInterrupt entry irq %x dev_id %p\n", irq, dev_id);
0100     return IRQ_HANDLED;
0101 }
0102 
0103 static irqreturn_t DspInterrupt(int irq, void *dev_id)
0104 {
0105     pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
0106     DSP_3780I_CONFIG_SETTINGS *pSettings = &pDrvData->rBDData.rDspSettings;
0107     unsigned short usDspBaseIO = pSettings->usDspBaseIO;
0108     unsigned short usIPCSource = 0, usIsolationMask, usPCNum;
0109 
0110     PRINTK_3(TRACE_TP3780I,
0111         "tp3780i::DspInterrupt entry irq %x dev_id %p\n", irq, dev_id);
0112 
0113     if (dsp3780I_GetIPCSource(usDspBaseIO, &usIPCSource) == 0) {
0114         PRINTK_2(TRACE_TP3780I,
0115             "tp3780i::DspInterrupt, return from dsp3780i_GetIPCSource, usIPCSource %x\n",
0116             usIPCSource);
0117         usIsolationMask = 1;
0118         for (usPCNum = 1; usPCNum <= 16; usPCNum++) {
0119             if (usIPCSource & usIsolationMask) {
0120                 usIPCSource &= ~usIsolationMask;
0121                 PRINTK_3(TRACE_TP3780I,
0122                     "tp3780i::DspInterrupt usPCNum %x usIPCSource %x\n",
0123                     usPCNum, usIPCSource);
0124                 if (pDrvData->IPCs[usPCNum - 1].usIntCount == 0) {
0125                     pDrvData->IPCs[usPCNum - 1].usIntCount = 1;
0126                 }
0127                 PRINTK_2(TRACE_TP3780I,
0128                     "tp3780i::DspInterrupt usIntCount %x\n",
0129                     pDrvData->IPCs[usPCNum - 1].usIntCount);
0130                 if (pDrvData->IPCs[usPCNum - 1].bIsEnabled == true) {
0131                     PRINTK_2(TRACE_TP3780I,
0132                         "tp3780i::DspInterrupt, waking up usPCNum %x\n",
0133                         usPCNum - 1);
0134                     wake_up_interruptible(&pDrvData->IPCs[usPCNum - 1].ipc_wait_queue);
0135                 } else {
0136                     PRINTK_2(TRACE_TP3780I,
0137                         "tp3780i::DspInterrupt, no one waiting for IPC %x\n",
0138                         usPCNum - 1);
0139                 }
0140             }
0141             if (usIPCSource == 0)
0142                 break;
0143             /* try next IPC */
0144             usIsolationMask = usIsolationMask << 1;
0145         }
0146     } else {
0147         PRINTK_1(TRACE_TP3780I,
0148             "tp3780i::DspInterrupt, return false from dsp3780i_GetIPCSource\n");
0149     }
0150     PRINTK_1(TRACE_TP3780I, "tp3780i::DspInterrupt exit\n");
0151     return IRQ_HANDLED;
0152 }
0153 
0154 
0155 int tp3780I_InitializeBoardData(THINKPAD_BD_DATA * pBDData)
0156 {
0157     int retval = 0;
0158     DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
0159 
0160 
0161     PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_InitializeBoardData entry pBDData %p\n", pBDData);
0162 
0163     pBDData->bDSPEnabled = false;
0164     pSettings->bInterruptClaimed = false;
0165 
0166     retval = smapi_init();
0167     if (retval) {
0168         PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_InitializeBoardData: Error: SMAPI is not available on this machine\n");
0169     } else {
0170         if (mwave_3780i_irq || mwave_3780i_io || mwave_uart_irq || mwave_uart_io) {
0171             retval = smapi_set_DSP_cfg();
0172         }
0173     }
0174 
0175     PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_InitializeBoardData exit retval %x\n", retval);
0176 
0177     return retval;
0178 }
0179 
0180 void tp3780I_Cleanup(THINKPAD_BD_DATA *pBDData)
0181 {
0182     PRINTK_2(TRACE_TP3780I,
0183         "tp3780i::tp3780I_Cleanup entry and exit pBDData %p\n", pBDData);
0184 }
0185 
0186 int tp3780I_CalcResources(THINKPAD_BD_DATA * pBDData)
0187 {
0188     SMAPI_DSP_SETTINGS rSmapiInfo;
0189     DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
0190 
0191     PRINTK_2(TRACE_TP3780I,
0192         "tp3780i::tp3780I_CalcResources entry pBDData %p\n", pBDData);
0193 
0194     if (smapi_query_DSP_cfg(&rSmapiInfo)) {
0195         PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_CalcResources: Error: Could not query DSP config. Aborting.\n");
0196         return -EIO;
0197     }
0198 
0199     /* Sanity check */
0200     if (
0201         ( rSmapiInfo.usDspIRQ == 0 )
0202         || ( rSmapiInfo.usDspBaseIO ==  0 )
0203         || ( rSmapiInfo.usUartIRQ ==  0 )
0204         || ( rSmapiInfo.usUartBaseIO ==  0 )
0205     ) {
0206         PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_CalcResources: Error: Illegal resource setting. Aborting.\n");
0207         return -EIO;
0208     }
0209 
0210     pSettings->bDSPEnabled = (rSmapiInfo.bDSPEnabled && rSmapiInfo.bDSPPresent);
0211     pSettings->bModemEnabled = rSmapiInfo.bModemEnabled;
0212     pSettings->usDspIrq = rSmapiInfo.usDspIRQ;
0213     pSettings->usDspDma = rSmapiInfo.usDspDMA;
0214     pSettings->usDspBaseIO = rSmapiInfo.usDspBaseIO;
0215     pSettings->usUartIrq = rSmapiInfo.usUartIRQ;
0216     pSettings->usUartBaseIO = rSmapiInfo.usUartBaseIO;
0217 
0218     pSettings->uDStoreSize = TP_ABILITIES_DATA_SIZE;
0219     pSettings->uIStoreSize = TP_ABILITIES_INST_SIZE;
0220     pSettings->uIps = TP_ABILITIES_INTS_PER_SEC;
0221 
0222     if (pSettings->bDSPEnabled && pSettings->bModemEnabled && pSettings->usDspIrq == pSettings->usUartIrq) {
0223         pBDData->bShareDspIrq = pBDData->bShareUartIrq = 1;
0224     } else {
0225         pBDData->bShareDspIrq = pBDData->bShareUartIrq = 0;
0226     }
0227 
0228     PRINTK_1(TRACE_TP3780I, "tp3780i::tp3780I_CalcResources exit\n");
0229 
0230     return 0;
0231 }
0232 
0233 
0234 int tp3780I_ClaimResources(THINKPAD_BD_DATA * pBDData)
0235 {
0236     int retval = 0;
0237     DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
0238     struct resource *pres;
0239 
0240     PRINTK_2(TRACE_TP3780I,
0241         "tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData);
0242 
0243     pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
0244     if ( pres == NULL ) retval = -EIO;
0245 
0246     if (retval) {
0247         PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO);
0248         retval = -EIO;
0249     }
0250 
0251     PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ClaimResources exit retval %x\n", retval);
0252 
0253     return retval;
0254 }
0255 
0256 int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData)
0257 {
0258     int retval = 0;
0259     DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
0260 
0261     PRINTK_2(TRACE_TP3780I,
0262         "tp3780i::tp3780I_ReleaseResources entry pBDData %p\n", pBDData);
0263 
0264     release_region(pSettings->usDspBaseIO & (~3), 16);
0265 
0266     if (pSettings->bInterruptClaimed) {
0267         free_irq(pSettings->usDspIrq, NULL);
0268         pSettings->bInterruptClaimed = false;
0269     }
0270 
0271     PRINTK_2(TRACE_TP3780I,
0272         "tp3780i::tp3780I_ReleaseResources exit retval %x\n", retval);
0273 
0274     return retval;
0275 }
0276 
0277 
0278 
0279 int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
0280 {
0281     DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
0282     bool bDSPPoweredUp = false, bInterruptAllocated = false;
0283 
0284     PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData);
0285 
0286     if (pBDData->bDSPEnabled) {
0287         PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: DSP already enabled!\n");
0288         goto exit_cleanup;
0289     }
0290 
0291     if (!pSettings->bDSPEnabled) {
0292         PRINTK_ERROR(KERN_ERR_MWAVE "tp3780::tp3780I_EnableDSP: Error: pSettings->bDSPEnabled not set\n");
0293         goto exit_cleanup;
0294     }
0295 
0296     if (
0297         (pSettings->usDspIrq >= s_numIrqs)
0298         || (pSettings->usDspDma >= s_numDmas)
0299         || (s_ausThinkpadIrqToField[pSettings->usDspIrq] == 0xFFFF)
0300         || (s_ausThinkpadDmaToField[pSettings->usDspDma] == 0xFFFF)
0301     ) {
0302         PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: invalid irq %x\n", pSettings->usDspIrq);
0303         goto exit_cleanup;
0304     }
0305 
0306     if (
0307         ((pSettings->usDspBaseIO & 0xF00F) != 0)
0308         || (pSettings->usDspBaseIO & 0x0FF0) == 0
0309     ) {
0310         PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Invalid DSP base I/O address %x\n", pSettings->usDspBaseIO);
0311         goto exit_cleanup;
0312     }
0313 
0314     if (pSettings->bModemEnabled) {
0315         if (
0316             pSettings->usUartIrq >= s_numIrqs
0317             || s_ausThinkpadIrqToField[pSettings->usUartIrq] == 0xFFFF
0318         ) {
0319             PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Invalid UART IRQ %x\n", pSettings->usUartIrq);
0320             goto exit_cleanup;
0321         }
0322         switch (pSettings->usUartBaseIO) {
0323             case 0x03F8:
0324             case 0x02F8:
0325             case 0x03E8:
0326             case 0x02E8:
0327                 break;
0328 
0329             default:
0330                 PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: Invalid UART base I/O address %x\n", pSettings->usUartBaseIO);
0331                 goto exit_cleanup;
0332         }
0333     }
0334 
0335     pSettings->bDspIrqActiveLow = pSettings->bDspIrqPulse = true;
0336     pSettings->bUartIrqActiveLow = pSettings->bUartIrqPulse = true;
0337 
0338     if (pBDData->bShareDspIrq) {
0339         pSettings->bDspIrqActiveLow = false;
0340     }
0341     if (pBDData->bShareUartIrq) {
0342         pSettings->bUartIrqActiveLow = false;
0343     }
0344 
0345     pSettings->usNumTransfers = TP_CFG_NumTransfers;
0346     pSettings->usReRequest = TP_CFG_RerequestTimer;
0347     pSettings->bEnableMEMCS16 = TP_CFG_MEMCS16;
0348     pSettings->usIsaMemCmdWidth = TP_CFG_IsaMemCmdWidth;
0349     pSettings->bGateIOCHRDY = TP_CFG_GateIOCHRDY;
0350     pSettings->bEnablePwrMgmt = TP_CFG_EnablePwrMgmt;
0351     pSettings->usHBusTimerLoadValue = TP_CFG_HBusTimerValue;
0352     pSettings->bDisableLBusTimeout = TP_CFG_DisableLBusTimeout;
0353     pSettings->usN_Divisor = TP_CFG_N_Divisor;
0354     pSettings->usM_Multiplier = TP_CFG_M_Multiplier;
0355     pSettings->bPllBypass = TP_CFG_PllBypass;
0356     pSettings->usChipletEnable = TP_CFG_ChipletEnable;
0357 
0358     if (request_irq(pSettings->usUartIrq, &UartInterrupt, 0, "mwave_uart", NULL)) {
0359         PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Could not get UART IRQ %x\n", pSettings->usUartIrq);
0360         goto exit_cleanup;
0361     } else {        /* no conflict just release */
0362         free_irq(pSettings->usUartIrq, NULL);
0363     }
0364 
0365     if (request_irq(pSettings->usDspIrq, &DspInterrupt, 0, "mwave_3780i", NULL)) {
0366         PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: Could not get 3780i IRQ %x\n", pSettings->usDspIrq);
0367         goto exit_cleanup;
0368     } else {
0369         PRINTK_3(TRACE_TP3780I,
0370             "tp3780i::tp3780I_EnableDSP, got interrupt %x bShareDspIrq %x\n",
0371             pSettings->usDspIrq, pBDData->bShareDspIrq);
0372         bInterruptAllocated = true;
0373         pSettings->bInterruptClaimed = true;
0374     }
0375 
0376     smapi_set_DSP_power_state(false);
0377     if (smapi_set_DSP_power_state(true)) {
0378         PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: smapi_set_DSP_power_state(true) failed\n");
0379         goto exit_cleanup;
0380     } else {
0381         bDSPPoweredUp = true;
0382     }
0383 
0384     if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) {
0385         PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n");
0386         goto exit_cleanup;
0387     }
0388 
0389     EnableSRAM(pBDData);
0390 
0391     pBDData->bDSPEnabled = true;
0392 
0393     PRINTK_1(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP exit\n");
0394 
0395     return 0;
0396 
0397 exit_cleanup:
0398     PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n");
0399     if (bDSPPoweredUp)
0400         smapi_set_DSP_power_state(false);
0401     if (bInterruptAllocated) {
0402         free_irq(pSettings->usDspIrq, NULL);
0403         pSettings->bInterruptClaimed = false;
0404     }
0405     return -EIO;
0406 }
0407 
0408 
0409 int tp3780I_DisableDSP(THINKPAD_BD_DATA * pBDData)
0410 {
0411     int retval = 0;
0412     DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
0413 
0414     PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_DisableDSP entry pBDData %p\n", pBDData);
0415 
0416     if (pBDData->bDSPEnabled) {
0417         dsp3780I_DisableDSP(&pBDData->rDspSettings);
0418         if (pSettings->bInterruptClaimed) {
0419             free_irq(pSettings->usDspIrq, NULL);
0420             pSettings->bInterruptClaimed = false;
0421         }
0422         smapi_set_DSP_power_state(false);
0423         pBDData->bDSPEnabled = false;
0424     }
0425 
0426     PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_DisableDSP exit retval %x\n", retval);
0427 
0428     return retval;
0429 }
0430 
0431 
0432 int tp3780I_ResetDSP(THINKPAD_BD_DATA * pBDData)
0433 {
0434     int retval = 0;
0435     DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
0436 
0437     PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ResetDSP entry pBDData %p\n",
0438         pBDData);
0439 
0440     if (dsp3780I_Reset(pSettings) == 0) {
0441         EnableSRAM(pBDData);
0442     } else {
0443         retval = -EIO;
0444     }
0445 
0446     PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ResetDSP exit retval %x\n", retval);
0447 
0448     return retval;
0449 }
0450 
0451 
0452 int tp3780I_StartDSP(THINKPAD_BD_DATA * pBDData)
0453 {
0454     int retval = 0;
0455     DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
0456 
0457     PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_StartDSP entry pBDData %p\n", pBDData);
0458 
0459     if (dsp3780I_Run(pSettings) == 0) {
0460         // @BUG @TBD EnableSRAM(pBDData);
0461     } else {
0462         retval = -EIO;
0463     }
0464 
0465     PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_StartDSP exit retval %x\n", retval);
0466 
0467     return retval;
0468 }
0469 
0470 
0471 int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities)
0472 {
0473     PRINTK_2(TRACE_TP3780I,
0474         "tp3780i::tp3780I_QueryAbilities entry pBDData %p\n", pBDData);
0475 
0476     memset(pAbilities, 0, sizeof(*pAbilities));
0477     /* fill out standard constant fields */
0478     pAbilities->instr_per_sec = pBDData->rDspSettings.uIps;
0479     pAbilities->data_size = pBDData->rDspSettings.uDStoreSize;
0480     pAbilities->inst_size = pBDData->rDspSettings.uIStoreSize;
0481     pAbilities->bus_dma_bw = pBDData->rDspSettings.uDmaBandwidth;
0482 
0483     /* fill out dynamically determined fields */
0484     pAbilities->component_list[0] = 0x00010000 | MW_ADC_MASK;
0485     pAbilities->component_list[1] = 0x00010000 | MW_ACI_MASK;
0486     pAbilities->component_list[2] = 0x00010000 | MW_AIC1_MASK;
0487     pAbilities->component_list[3] = 0x00010000 | MW_AIC2_MASK;
0488     pAbilities->component_list[4] = 0x00010000 | MW_CDDAC_MASK;
0489     pAbilities->component_list[5] = 0x00010000 | MW_MIDI_MASK;
0490     pAbilities->component_list[6] = 0x00010000 | MW_UART_MASK;
0491     pAbilities->component_count = 7;
0492 
0493     /* Fill out Mwave OS and BIOS task names */
0494 
0495     memcpy(pAbilities->mwave_os_name, TP_ABILITIES_MWAVEOS_NAME,
0496         sizeof(TP_ABILITIES_MWAVEOS_NAME));
0497     memcpy(pAbilities->bios_task_name, TP_ABILITIES_BIOSTASK_NAME,
0498         sizeof(TP_ABILITIES_BIOSTASK_NAME));
0499 
0500     PRINTK_1(TRACE_TP3780I,
0501         "tp3780i::tp3780I_QueryAbilities exit retval=SUCCESSFUL\n");
0502 
0503     return 0;
0504 }
0505 
0506 int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
0507                                void __user *pvBuffer, unsigned int uCount,
0508                                unsigned long ulDSPAddr)
0509 {
0510     int retval = 0;
0511     DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
0512     unsigned short usDspBaseIO = pSettings->usDspBaseIO;
0513     bool bRC = 0;
0514 
0515     PRINTK_6(TRACE_TP3780I,
0516         "tp3780i::tp3780I_ReadWriteDspDStore entry pBDData %p, uOpcode %x, pvBuffer %p, uCount %x, ulDSPAddr %lx\n",
0517         pBDData, uOpcode, pvBuffer, uCount, ulDSPAddr);
0518 
0519     if (pBDData->bDSPEnabled) {
0520         switch (uOpcode) {
0521         case IOCTL_MW_READ_DATA:
0522             bRC = dsp3780I_ReadDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
0523             break;
0524 
0525         case IOCTL_MW_READCLEAR_DATA:
0526             bRC = dsp3780I_ReadAndClearDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
0527             break;
0528 
0529         case IOCTL_MW_WRITE_DATA:
0530             bRC = dsp3780I_WriteDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
0531             break;
0532         }
0533     }
0534 
0535     retval = (bRC) ? -EIO : 0;
0536     PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ReadWriteDspDStore exit retval %x\n", retval);
0537 
0538     return retval;
0539 }
0540 
0541 
0542 int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
0543                                void __user *pvBuffer, unsigned int uCount,
0544                                unsigned long ulDSPAddr)
0545 {
0546     int retval = 0;
0547     DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
0548     unsigned short usDspBaseIO = pSettings->usDspBaseIO;
0549     bool bRC = 0;
0550 
0551     PRINTK_6(TRACE_TP3780I,
0552         "tp3780i::tp3780I_ReadWriteDspIStore entry pBDData %p, uOpcode %x, pvBuffer %p, uCount %x, ulDSPAddr %lx\n",
0553         pBDData, uOpcode, pvBuffer, uCount, ulDSPAddr);
0554 
0555     if (pBDData->bDSPEnabled) {
0556         switch (uOpcode) {
0557         case IOCTL_MW_READ_INST:
0558             bRC = dsp3780I_ReadIStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
0559             break;
0560 
0561         case IOCTL_MW_WRITE_INST:
0562             bRC = dsp3780I_WriteIStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
0563             break;
0564         }
0565     }
0566 
0567     retval = (bRC) ? -EIO : 0;
0568 
0569     PRINTK_2(TRACE_TP3780I,
0570         "tp3780i::tp3780I_ReadWriteDspIStore exit retval %x\n", retval);
0571 
0572     return retval;
0573 }
0574