1/* 2 * BeOS Driver for Intel ICH AC'97 Link interface 3 * 4 * Copyright (C) 2002-2004, 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 "debug.h" 31#include "hardware.h" 32#include "ichaudio.h" 33#include "io.h" 34 35status_t ich_codec_wait(ichaudio_cookie *cookie); 36 37uint8 38ich_reg_read_8(ichaudio_cookie *cookie, int regno) 39{ 40 ASSERT(regno >= 0); 41 ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63); 42 if (cookie->flags & TYPE_ICH4) 43 return *(uint8 *)((char *)cookie->mbbar + regno); 44 else 45 return cookie->pci->read_io_8(cookie->nabmbar + regno); 46} 47 48uint16 49ich_reg_read_16(ichaudio_cookie *cookie, int regno) 50{ 51 ASSERT(regno >= 0); 52 ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63); 53 if (cookie->flags & TYPE_ICH4) 54 return *(uint16 *)((char *)cookie->mbbar + regno); 55 else 56 return cookie->pci->read_io_16(cookie->nabmbar + regno); 57} 58 59uint32 60ich_reg_read_32(ichaudio_cookie *cookie, int regno) 61{ 62 ASSERT(regno >= 0); 63 ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63); 64 65 if (cookie->flags & TYPE_ICH4) 66 return *(uint32 *)((char *)cookie->mbbar + regno); 67 else 68 return cookie->pci->read_io_32(cookie->nabmbar + regno); 69} 70 71void 72ich_reg_write_8(ichaudio_cookie *cookie, int regno, uint8 value) 73{ 74 ASSERT(regno >= 0); 75 ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63); 76 77 if (cookie->flags & TYPE_ICH4) 78 *(uint8 *)((char *)cookie->mbbar + regno) = value; 79 else 80 cookie->pci->write_io_8(cookie->nabmbar + regno, value); 81} 82 83void 84ich_reg_write_16(ichaudio_cookie *cookie, int regno, uint16 value) 85{ 86 ASSERT(regno >= 0); 87 ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63); 88 89 if (cookie->flags & TYPE_ICH4) 90 *(uint16 *)((char *)cookie->mbbar + regno) = value; 91 else 92 cookie->pci->write_io_16(cookie->nabmbar + regno, value); 93} 94 95void 96ich_reg_write_32(ichaudio_cookie *cookie, int regno, uint32 value) 97{ 98 ASSERT(regno >= 0); 99 ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63); 100 101 if (cookie->flags & TYPE_ICH4) 102 *(uint32 *)((char *)cookie->mbbar + regno) = value; 103 else 104 cookie->pci->write_io_32(cookie->nabmbar + regno, value); 105} 106 107status_t 108ich_codec_wait(ichaudio_cookie *cookie) 109{ 110 int i; 111 for (i = 0; i < 1100; i++) { 112 if ((ich_reg_read_8(cookie, ICH_REG_ACC_SEMA) & 0x01) == 0) 113 return B_OK; 114 if (i > 100) 115 snooze(1); 116 } 117 return B_TIMED_OUT; 118} 119 120uint16 121ich_codec_read(void *_cookie, int regno) 122{ 123 ichaudio_cookie *cookie = (ichaudio_cookie *)_cookie; 124 125 ASSERT(regno >= 0); 126 ASSERT((regno & 1) == 0); 127 ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255); 128 129 if (regno == 0x54) // intel uses 0x54 for GPIO access, we filter it! 130 return 0; 131 if (B_OK != ich_codec_wait(cookie)) 132 PRINT(("semaphore timeout reading register %#x\n", regno)); 133 if (cookie->flags & TYPE_ICH4) 134 return *(uint16 *)(((char *)cookie->mmbar) + regno); 135 else 136 return cookie->pci->read_io_16(cookie->nambar + regno); 137} 138 139void 140ich_codec_write(void *_cookie, int regno, uint16 value) 141{ 142 ichaudio_cookie *cookie = (ichaudio_cookie *)_cookie; 143 144 ASSERT(regno >= 0); 145 ASSERT((regno & 1) == 0); 146 ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255); 147 148 if (regno == 0x54) // intel uses 0x54 for GPIO access, we filter it! 149 return; 150 if (B_OK != ich_codec_wait(cookie)) 151 PRINT(("semaphore timeout writing register %#x\n", regno)); 152 if (cookie->flags & TYPE_ICH4) 153 *(uint16 *)(((char *)cookie->mmbar) + regno) = value; 154 else 155 cookie->pci->write_io_16(cookie->nambar + regno, value); 156} 157