1 /* 2 * Auich BeOS Driver for Intel Southbridge audio 3 * 4 * Copyright (c) 2003, Jerome Duval (jerome.duval@free.fr) 5 * 6 * Original code : BeOS Driver for Intel ICH AC'97 Link interface 7 * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de> 8 * 9 * All rights reserved. 10 * Redistribution and use in source and binary forms, with or without modification, 11 * are permitted provided that the following conditions are met: 12 * 13 * - Redistributions of source code must retain the above copyright notice, 14 * this list of conditions and the following disclaimer. 15 * - Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 25 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 */ 31 #include <KernelExport.h> 32 #include <OS.h> 33 #include "io.h" 34 #include "auichreg.h" 35 #include "debug.h" 36 #include <PCI.h> 37 38 extern pci_module_info *pci; 39 40 uint8 41 auich_reg_read_8(device_config *config, 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 51 uint16 52 auich_reg_read_16(device_config *config, 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 62 uint32 63 auich_reg_read_32(device_config *config, 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 73 void 74 auich_reg_write_8(device_config *config, 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 84 void 85 auich_reg_write_16(device_config *config, 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 95 void 96 auich_reg_write_32(device_config *config, 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 106 /* codec */ 107 static int 108 auich_codec_wait(device_config *config) 109 { 110 int i; 111 for (i = 0; i < 1100; i++) { 112 if ((auich_reg_read_8(config, AUICH_REG_ACC_SEMA) & 0x01) == 0) 113 return B_OK; 114 if (i > 100) 115 snooze(10); 116 } 117 return B_TIMED_OUT; 118 } 119 120 uint16 121 auich_codec_read(device_config *config, int regno) 122 { 123 ASSERT(regno >= 0); 124 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255); 125 if(auich_codec_wait(config)!=B_OK) { 126 PRINT(("codec busy (2)\n")); 127 return -1; 128 } 129 130 if (config->type & TYPE_ICH4) 131 return *(uint16 *)(((char *)config->log_mmbar) + regno); 132 else 133 return pci->read_io_16(config->nambar + regno); 134 } 135 136 void 137 auich_codec_write(device_config *config, int regno, uint16 value) 138 { 139 ASSERT(regno >= 0); 140 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255); 141 if(auich_codec_wait(config)!=B_OK) { 142 PRINT(("codec busy (4)\n")); 143 return; 144 } 145 if (config->type & TYPE_ICH4) 146 *(uint16 *)(((char *)config->log_mmbar) + regno) = value; 147 else 148 pci->write_io_16(config->nambar + regno, value); 149 } 150