Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* |
| 2 | ********************************************************************** |
| 3 | * ecard.c - E-card initialization code |
| 4 | * Copyright 1999, 2000 Creative Labs, Inc. |
| 5 | * |
| 6 | ********************************************************************** |
| 7 | * |
| 8 | * Date Author Summary of changes |
| 9 | * ---- ------ ------------------ |
| 10 | * October 20, 1999 Bertrand Lee base code release |
| 11 | * |
| 12 | ********************************************************************** |
| 13 | * |
| 14 | * This program is free software; you can redistribute it and/or |
| 15 | * modify it under the terms of the GNU General Public License as |
| 16 | * published by the Free Software Foundation; either version 2 of |
| 17 | * the License, or (at your option) any later version. |
| 18 | * |
| 19 | * This program is distributed in the hope that it will be useful, |
| 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 22 | * GNU General Public License for more details. |
| 23 | * |
| 24 | * You should have received a copy of the GNU General Public |
| 25 | * License along with this program; if not, write to the Free |
| 26 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, |
| 27 | * USA. |
| 28 | * |
| 29 | ********************************************************************** |
| 30 | */ |
| 31 | |
| 32 | #include "ecard.h" |
| 33 | #include "hwaccess.h" |
| 34 | |
| 35 | /* Private routines */ |
| 36 | static void ecard_setadcgain(struct emu10k1_card *, struct ecard_state *, u16); |
| 37 | static void ecard_write(struct emu10k1_card *, u32); |
| 38 | |
| 39 | /************************************************************************** |
| 40 | * @func Set the gain of the ECARD's CS3310 Trim/gain controller. The |
| 41 | * trim value consists of a 16bit value which is composed of two |
| 42 | * 8 bit gain/trim values, one for the left channel and one for the |
| 43 | * right channel. The following table maps from the Gain/Attenuation |
| 44 | * value in decibels into the corresponding bit pattern for a single |
| 45 | * channel. |
| 46 | */ |
| 47 | |
| 48 | static void ecard_setadcgain(struct emu10k1_card *card, struct ecard_state *ecard, u16 gain) |
| 49 | { |
| 50 | u32 currbit; |
| 51 | ecard->adc_gain = gain; |
| 52 | |
| 53 | /* Enable writing to the TRIM registers */ |
| 54 | ecard_write(card, ecard->control_bits & ~EC_TRIM_CSN); |
| 55 | |
| 56 | /* Do it again to insure that we meet hold time requirements */ |
| 57 | ecard_write(card, ecard->control_bits & ~EC_TRIM_CSN); |
| 58 | |
| 59 | for (currbit = (1L << 15); currbit; currbit >>= 1) { |
| 60 | |
| 61 | u32 value = ecard->control_bits & ~(EC_TRIM_CSN|EC_TRIM_SDATA); |
| 62 | |
| 63 | if (gain & currbit) |
| 64 | value |= EC_TRIM_SDATA; |
| 65 | |
| 66 | /* Clock the bit */ |
| 67 | ecard_write(card, value); |
| 68 | ecard_write(card, value | EC_TRIM_SCLK); |
| 69 | ecard_write(card, value); |
| 70 | } |
| 71 | |
| 72 | ecard_write(card, ecard->control_bits); |
| 73 | } |
| 74 | |
| 75 | /************************************************************************** |
| 76 | * @func Clock bits into the Ecard's control latch. The Ecard uses a |
| 77 | * control latch will is loaded bit-serially by toggling the Modem control |
| 78 | * lines from function 2 on the E8010. This function hides these details |
| 79 | * and presents the illusion that we are actually writing to a distinct |
| 80 | * register. |
| 81 | */ |
| 82 | static void ecard_write(struct emu10k1_card *card, u32 value) |
| 83 | { |
| 84 | u16 count; |
| 85 | u32 data, hcvalue; |
| 86 | unsigned long flags; |
| 87 | |
| 88 | spin_lock_irqsave(&card->lock, flags); |
| 89 | |
| 90 | hcvalue = inl(card->iobase + HCFG) & ~(HOOKN_BIT|HANDN_BIT|PULSEN_BIT); |
| 91 | |
| 92 | outl(card->iobase + HCFG, hcvalue); |
| 93 | |
| 94 | for (count = 0 ; count < EC_NUM_CONTROL_BITS; count++) { |
| 95 | |
| 96 | /* Set up the value */ |
| 97 | data = ((value & 0x1) ? PULSEN_BIT : 0); |
| 98 | value >>= 1; |
| 99 | |
| 100 | outl(card->iobase + HCFG, hcvalue | data); |
| 101 | |
| 102 | /* Clock the shift register */ |
| 103 | outl(card->iobase + HCFG, hcvalue | data | HANDN_BIT); |
| 104 | outl(card->iobase + HCFG, hcvalue | data); |
| 105 | } |
| 106 | |
| 107 | /* Latch the bits */ |
| 108 | outl(card->iobase + HCFG, hcvalue | HOOKN_BIT); |
| 109 | outl(card->iobase + HCFG, hcvalue); |
| 110 | |
| 111 | spin_unlock_irqrestore(&card->lock, flags); |
| 112 | } |
| 113 | |
| 114 | void __devinit emu10k1_ecard_init(struct emu10k1_card *card) |
| 115 | { |
| 116 | u32 hcvalue; |
| 117 | struct ecard_state ecard; |
| 118 | |
| 119 | /* Set up the initial settings */ |
| 120 | ecard.mux0_setting = EC_DEFAULT_SPDIF0_SEL; |
| 121 | ecard.mux1_setting = EC_DEFAULT_SPDIF1_SEL; |
| 122 | ecard.mux2_setting = 0; |
| 123 | ecard.adc_gain = EC_DEFAULT_ADC_GAIN; |
| 124 | ecard.control_bits = EC_RAW_RUN_MODE | |
| 125 | EC_SPDIF0_SELECT(ecard.mux0_setting) | |
| 126 | EC_SPDIF1_SELECT(ecard.mux1_setting); |
| 127 | |
| 128 | |
| 129 | /* Step 0: Set the codec type in the hardware control register |
| 130 | * and enable audio output */ |
| 131 | hcvalue = emu10k1_readfn0(card, HCFG); |
| 132 | emu10k1_writefn0(card, HCFG, hcvalue | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S); |
| 133 | |
| 134 | /* Step 1: Turn off the led and deassert TRIM_CS */ |
| 135 | ecard_write(card, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN); |
| 136 | |
| 137 | /* Step 2: Calibrate the ADC and DAC */ |
| 138 | ecard_write(card, EC_DACCAL | EC_LEDN | EC_TRIM_CSN); |
| 139 | |
| 140 | /* Step 3: Wait for awhile; FIXME: Is this correct? */ |
| 141 | |
| 142 | current->state = TASK_INTERRUPTIBLE; |
| 143 | schedule_timeout(HZ); |
| 144 | |
| 145 | /* Step 4: Switch off the DAC and ADC calibration. Note |
| 146 | * That ADC_CAL is actually an inverted signal, so we assert |
| 147 | * it here to stop calibration. */ |
| 148 | ecard_write(card, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN); |
| 149 | |
| 150 | /* Step 4: Switch into run mode */ |
| 151 | ecard_write(card, ecard.control_bits); |
| 152 | |
| 153 | /* Step 5: Set the analog input gain */ |
| 154 | ecard_setadcgain(card, &ecard, ecard.adc_gain); |
| 155 | } |
| 156 | |
| 157 | |