0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 static int read_dsp(struct echoaudio *chip, u32 *data);
0033 static int set_professional_spdif(struct echoaudio *chip, char prof);
0034 static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
0035 static int check_asic_status(struct echoaudio *chip);
0036 static int update_flags(struct echoaudio *chip);
0037
0038
0039 static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
0040 {
0041 int err;
0042
0043 if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20))
0044 return -ENODEV;
0045
0046 err = init_dsp_comm_page(chip);
0047 if (err) {
0048 dev_err(chip->card->dev,
0049 "init_hw - could not initialize DSP comm page\n");
0050 return err;
0051 }
0052
0053 chip->device_id = device_id;
0054 chip->subdevice_id = subdevice_id;
0055 chip->bad_board = true;
0056 chip->has_midi = true;
0057 chip->dsp_code_to_load = FW_LAYLA20_DSP;
0058 chip->input_clock_types =
0059 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
0060 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
0061 chip->output_clock_types =
0062 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
0063
0064 err = load_firmware(chip);
0065 if (err < 0)
0066 return err;
0067 chip->bad_board = false;
0068
0069 return err;
0070 }
0071
0072
0073
0074 static int set_mixer_defaults(struct echoaudio *chip)
0075 {
0076 chip->professional_spdif = false;
0077 return init_line_levels(chip);
0078 }
0079
0080
0081
0082 static u32 detect_input_clocks(const struct echoaudio *chip)
0083 {
0084 u32 clocks_from_dsp, clock_bits;
0085
0086
0087 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
0088
0089 clock_bits = ECHO_CLOCK_BIT_INTERNAL;
0090
0091 if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
0092 clock_bits |= ECHO_CLOCK_BIT_SPDIF;
0093
0094 if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) {
0095 if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER)
0096 clock_bits |= ECHO_CLOCK_BIT_SUPER;
0097 else
0098 clock_bits |= ECHO_CLOCK_BIT_WORD;
0099 }
0100
0101 return clock_bits;
0102 }
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 static int check_asic_status(struct echoaudio *chip)
0114 {
0115 u32 asic_status;
0116 int goodcnt, i;
0117
0118 chip->asic_loaded = false;
0119 for (i = goodcnt = 0; i < 5; i++) {
0120 send_vector(chip, DSP_VC_TEST_ASIC);
0121
0122
0123
0124 if (read_dsp(chip, &asic_status) < 0) {
0125 dev_err(chip->card->dev,
0126 "check_asic_status: failed on read_dsp\n");
0127 return -EIO;
0128 }
0129
0130 if (asic_status == ASIC_ALREADY_LOADED) {
0131 if (++goodcnt == 3) {
0132 chip->asic_loaded = true;
0133 return 0;
0134 }
0135 }
0136 }
0137 return -EIO;
0138 }
0139
0140
0141
0142
0143 static int load_asic(struct echoaudio *chip)
0144 {
0145 int err;
0146
0147 if (chip->asic_loaded)
0148 return 0;
0149
0150 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC,
0151 FW_LAYLA20_ASIC);
0152 if (err < 0)
0153 return err;
0154
0155
0156 return check_asic_status(chip);
0157 }
0158
0159
0160
0161 static int set_sample_rate(struct echoaudio *chip, u32 rate)
0162 {
0163 if (snd_BUG_ON(rate < 8000 || rate > 50000))
0164 return -EINVAL;
0165
0166
0167
0168 if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
0169 dev_warn(chip->card->dev,
0170 "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n");
0171 chip->comm_page->sample_rate = cpu_to_le32(rate);
0172 chip->sample_rate = rate;
0173 return 0;
0174 }
0175
0176 if (wait_handshake(chip))
0177 return -EIO;
0178
0179 dev_dbg(chip->card->dev, "set_sample_rate(%d)\n", rate);
0180 chip->sample_rate = rate;
0181 chip->comm_page->sample_rate = cpu_to_le32(rate);
0182 clear_handshake(chip);
0183 return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE);
0184 }
0185
0186
0187
0188 static int set_input_clock(struct echoaudio *chip, u16 clock_source)
0189 {
0190 u16 clock;
0191 u32 rate;
0192
0193 rate = 0;
0194 switch (clock_source) {
0195 case ECHO_CLOCK_INTERNAL:
0196 rate = chip->sample_rate;
0197 clock = LAYLA20_CLOCK_INTERNAL;
0198 break;
0199 case ECHO_CLOCK_SPDIF:
0200 clock = LAYLA20_CLOCK_SPDIF;
0201 break;
0202 case ECHO_CLOCK_WORD:
0203 clock = LAYLA20_CLOCK_WORD;
0204 break;
0205 case ECHO_CLOCK_SUPER:
0206 clock = LAYLA20_CLOCK_SUPER;
0207 break;
0208 default:
0209 dev_err(chip->card->dev,
0210 "Input clock 0x%x not supported for Layla24\n",
0211 clock_source);
0212 return -EINVAL;
0213 }
0214 chip->input_clock = clock_source;
0215
0216 chip->comm_page->input_clock = cpu_to_le16(clock);
0217 clear_handshake(chip);
0218 send_vector(chip, DSP_VC_UPDATE_CLOCKS);
0219
0220 if (rate)
0221 set_sample_rate(chip, rate);
0222
0223 return 0;
0224 }
0225
0226
0227
0228 static int set_output_clock(struct echoaudio *chip, u16 clock)
0229 {
0230 switch (clock) {
0231 case ECHO_CLOCK_SUPER:
0232 clock = LAYLA20_OUTPUT_CLOCK_SUPER;
0233 break;
0234 case ECHO_CLOCK_WORD:
0235 clock = LAYLA20_OUTPUT_CLOCK_WORD;
0236 break;
0237 default:
0238 dev_err(chip->card->dev, "set_output_clock wrong clock\n");
0239 return -EINVAL;
0240 }
0241
0242 if (wait_handshake(chip))
0243 return -EIO;
0244
0245 chip->comm_page->output_clock = cpu_to_le16(clock);
0246 chip->output_clock = clock;
0247 clear_handshake(chip);
0248 return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
0249 }
0250
0251
0252
0253
0254 static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
0255 {
0256 if (snd_BUG_ON(input >= num_busses_in(chip)))
0257 return -EINVAL;
0258
0259 if (wait_handshake(chip))
0260 return -EIO;
0261
0262 chip->input_gain[input] = gain;
0263 gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
0264 chip->comm_page->line_in_level[input] = gain;
0265 return 0;
0266 }
0267
0268
0269
0270
0271 static int update_flags(struct echoaudio *chip)
0272 {
0273 if (wait_handshake(chip))
0274 return -EIO;
0275 clear_handshake(chip);
0276 return send_vector(chip, DSP_VC_UPDATE_FLAGS);
0277 }
0278
0279
0280
0281 static int set_professional_spdif(struct echoaudio *chip, char prof)
0282 {
0283 if (prof)
0284 chip->comm_page->flags |=
0285 cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
0286 else
0287 chip->comm_page->flags &=
0288 ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
0289 chip->professional_spdif = prof;
0290 return update_flags(chip);
0291 }