1/* 2 * BeOS Driver for Intel ICH AC'97 Link interface 3 * 4 * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de> 5 * 6 * All rights reserved. 7 * Redistribution and use in source and binary forms, with or without modification, 8 * are permitted provided that the following conditions are met: 9 * 10 * - Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * - Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 25 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 */ 28#include <KernelExport.h> 29#include <OS.h> 30#include <PCI.h> 31#include "debug.h" 32#include "io.h" 33#include "ich.h" 34#include "config.h" 35 36extern pci_module_info *pci; 37 38status_t ich_codec_wait(void); 39 40uint8 41ich_reg_read_8(int regno) 42{ 43 ASSERT(regno >= 0); 44 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63); 45 if (config->type & TYPE_ICH4) 46 return *(uint8 *)(((char *)config->log_mbbar) + regno); 47 else 48 return pci->read_io_8(config->nabmbar + regno); 49} 50 51uint16 52ich_reg_read_16(int regno) 53{ 54 ASSERT(regno >= 0); 55 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63); 56 if (config->type & TYPE_ICH4) 57 return *(uint16 *)(((char *)config->log_mbbar) + regno); 58 else 59 return pci->read_io_16(config->nabmbar + regno); 60} 61 62uint32 63ich_reg_read_32(int regno) 64{ 65 ASSERT(regno >= 0); 66 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63); 67 if (config->type & TYPE_ICH4) 68 return *(uint32 *)(((char *)config->log_mbbar) + regno); 69 else 70 return pci->read_io_32(config->nabmbar + regno); 71} 72 73void 74ich_reg_write_8(int regno, uint8 value) 75{ 76 ASSERT(regno >= 0); 77 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63); 78 if (config->type & TYPE_ICH4) 79 *(uint8 *)(((char *)config->log_mbbar) + regno) = value; 80 else 81 pci->write_io_8(config->nabmbar + regno, value); 82} 83 84void 85ich_reg_write_16(int regno, uint16 value) 86{ 87 ASSERT(regno >= 0); 88 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63); 89 if (config->type & TYPE_ICH4) 90 *(uint16 *)(((char *)config->log_mbbar) + regno) = value; 91 else 92 pci->write_io_16(config->nabmbar + regno, value); 93} 94 95void 96ich_reg_write_32(int regno, uint32 value) 97{ 98 ASSERT(regno >= 0); 99 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63); 100 if (config->type & TYPE_ICH4) 101 *(uint32 *)(((char *)config->log_mbbar) + regno) = value; 102 else 103 pci->write_io_32(config->nabmbar + regno, value); 104} 105 106status_t 107ich_codec_wait(void) 108{ 109 int i; 110 for (i = 0; i < 1100; i++) { 111 if ((ich_reg_read_8(ICH_REG_ACC_SEMA) & 0x01) == 0) 112 return B_OK; 113 if (i > 100) 114 snooze(1); 115 } 116 return B_TIMED_OUT; 117} 118 119uint16 120ich_codec_read(int regno) 121{ 122 status_t rv; 123 ASSERT(regno >= 0); 124 ASSERT((regno & 1) == 0); 125 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255); 126 if (regno == 0x54) // intel uses 0x54 for GPIO access, we filter it! 127 return 0; 128 rv = ich_codec_wait(); 129 if (rv != B_OK) 130 PRINT(("semaphore timeout reading register %#x\n",regno)); 131 if (config->type & TYPE_ICH4) 132 return *(uint16 *)(((char *)config->log_mmbar) + regno); 133 else 134 return pci->read_io_16(config->nambar + regno); 135} 136 137void 138ich_codec_write(int regno, uint16 value) 139{ 140 status_t rv; 141 ASSERT(regno >= 0); 142 ASSERT((regno & 1) == 0); 143 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255); 144 if (regno == 0x54) // intel uses 0x54 for GPIO access, we filter it! 145 return; 146 rv = ich_codec_wait(); 147 if (rv != B_OK) 148 PRINT(("semaphore timeout writing register %#x\n",regno)); 149 if (config->type & TYPE_ICH4) 150 *(uint16 *)(((char *)config->log_mmbar) + regno) = value; 151 else 152 pci->write_io_16(config->nambar + regno, value); 153} 154