0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/delay.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/init.h>
0013 #include <linux/slab.h>
0014 #include <linux/mutex.h>
0015
0016 #include <sound/core.h>
0017
0018 #include "ice1712.h"
0019 #include "hoontech.h"
0020
0021
0022 struct hoontech_spec {
0023 unsigned char boxbits[4];
0024 unsigned int config;
0025 unsigned short boxconfig[4];
0026 };
0027
0028 static void snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte)
0029 {
0030 byte |= ICE1712_STDSP24_CLOCK_BIT;
0031 udelay(100);
0032 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
0033 byte &= ~ICE1712_STDSP24_CLOCK_BIT;
0034 udelay(100);
0035 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
0036 byte |= ICE1712_STDSP24_CLOCK_BIT;
0037 udelay(100);
0038 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
0039 }
0040
0041 static void snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate)
0042 {
0043 struct hoontech_spec *spec = ice->spec;
0044 mutex_lock(&ice->gpio_mutex);
0045 ICE1712_STDSP24_0_DAREAR(spec->boxbits, activate);
0046 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
0047 mutex_unlock(&ice->gpio_mutex);
0048 }
0049
0050 static void snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate)
0051 {
0052 struct hoontech_spec *spec = ice->spec;
0053 mutex_lock(&ice->gpio_mutex);
0054 ICE1712_STDSP24_3_MUTE(spec->boxbits, activate);
0055 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
0056 mutex_unlock(&ice->gpio_mutex);
0057 }
0058
0059 static void snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate)
0060 {
0061 struct hoontech_spec *spec = ice->spec;
0062 mutex_lock(&ice->gpio_mutex);
0063 ICE1712_STDSP24_3_INSEL(spec->boxbits, activate);
0064 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
0065 mutex_unlock(&ice->gpio_mutex);
0066 }
0067
0068 static void snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate)
0069 {
0070 struct hoontech_spec *spec = ice->spec;
0071
0072 mutex_lock(&ice->gpio_mutex);
0073
0074
0075 ICE1712_STDSP24_0_BOX(spec->boxbits, box);
0076 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
0077
0078
0079 if (chn == 3)
0080 ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
0081 ICE1712_STDSP24_2_MIDI1(spec->boxbits, activate);
0082 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
0083 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
0084
0085 ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
0086 ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
0087 ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
0088 ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
0089 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
0090 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
0091 udelay(100);
0092 if (chn == 3) {
0093 ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
0094 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
0095 } else {
0096 switch (chn) {
0097 case 0: ICE1712_STDSP24_1_CHN1(spec->boxbits, 0); break;
0098 case 1: ICE1712_STDSP24_1_CHN2(spec->boxbits, 0); break;
0099 case 2: ICE1712_STDSP24_1_CHN3(spec->boxbits, 0); break;
0100 }
0101 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
0102 }
0103 udelay(100);
0104 ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
0105 ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
0106 ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
0107 ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
0108 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
0109 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
0110 udelay(100);
0111
0112 ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
0113 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
0114
0115 mutex_unlock(&ice->gpio_mutex);
0116 }
0117
0118 static void snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master)
0119 {
0120 struct hoontech_spec *spec = ice->spec;
0121
0122 mutex_lock(&ice->gpio_mutex);
0123
0124
0125 ICE1712_STDSP24_0_BOX(spec->boxbits, box);
0126 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
0127
0128 ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
0129 ICE1712_STDSP24_2_MIDI1(spec->boxbits, master);
0130 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
0131 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
0132
0133 udelay(100);
0134
0135 ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 0);
0136 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
0137
0138 mdelay(10);
0139
0140 ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
0141 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
0142
0143 mutex_unlock(&ice->gpio_mutex);
0144 }
0145
0146 static void snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)
0147 {
0148 struct hoontech_spec *spec = ice->spec;
0149 mutex_lock(&ice->gpio_mutex);
0150 ICE1712_STDSP24_3_MIDI2(spec->boxbits, activate);
0151 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
0152 mutex_unlock(&ice->gpio_mutex);
0153 }
0154
0155 static int hoontech_init(struct snd_ice1712 *ice, bool staudio)
0156 {
0157 struct hoontech_spec *spec;
0158 int box, chn;
0159
0160 ice->num_total_dacs = 8;
0161 ice->num_total_adcs = 8;
0162
0163 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
0164 if (!spec)
0165 return -ENOMEM;
0166 ice->spec = spec;
0167
0168 ICE1712_STDSP24_SET_ADDR(spec->boxbits, 0);
0169 ICE1712_STDSP24_CLOCK(spec->boxbits, 0, 1);
0170 ICE1712_STDSP24_0_BOX(spec->boxbits, 0);
0171 ICE1712_STDSP24_0_DAREAR(spec->boxbits, 0);
0172
0173 ICE1712_STDSP24_SET_ADDR(spec->boxbits, 1);
0174 ICE1712_STDSP24_CLOCK(spec->boxbits, 1, 1);
0175 ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
0176 ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
0177 ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
0178
0179 ICE1712_STDSP24_SET_ADDR(spec->boxbits, 2);
0180 ICE1712_STDSP24_CLOCK(spec->boxbits, 2, 1);
0181 ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
0182 ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
0183 ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
0184
0185 ICE1712_STDSP24_SET_ADDR(spec->boxbits, 3);
0186 ICE1712_STDSP24_CLOCK(spec->boxbits, 3, 1);
0187 ICE1712_STDSP24_3_MIDI2(spec->boxbits, 0);
0188 ICE1712_STDSP24_3_MUTE(spec->boxbits, 1);
0189 ICE1712_STDSP24_3_INSEL(spec->boxbits, 0);
0190
0191
0192 if (staudio)
0193 spec->config = ICE1712_STDSP24_MUTE;
0194 else
0195 spec->config = 0;
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212 spec->boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
0213 ICE1712_STDSP24_BOX_CHN2 |
0214 ICE1712_STDSP24_BOX_CHN3 |
0215 ICE1712_STDSP24_BOX_CHN4 |
0216 ICE1712_STDSP24_BOX_MIDI1 |
0217 ICE1712_STDSP24_BOX_MIDI2;
0218 if (staudio) {
0219 spec->boxconfig[1] =
0220 spec->boxconfig[2] =
0221 spec->boxconfig[3] = spec->boxconfig[0];
0222 } else {
0223 spec->boxconfig[1] =
0224 spec->boxconfig[2] =
0225 spec->boxconfig[3] = 0;
0226 }
0227
0228 snd_ice1712_stdsp24_darear(ice,
0229 (spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
0230 snd_ice1712_stdsp24_mute(ice,
0231 (spec->config & ICE1712_STDSP24_MUTE) ? 1 : 0);
0232 snd_ice1712_stdsp24_insel(ice,
0233 (spec->config & ICE1712_STDSP24_INSEL) ? 1 : 0);
0234 for (box = 0; box < 4; box++) {
0235 if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
0236 snd_ice1712_stdsp24_midi2(ice, 1);
0237 for (chn = 0; chn < 4; chn++)
0238 snd_ice1712_stdsp24_box_channel(ice, box, chn,
0239 (spec->boxconfig[box] & (1 << chn)) ? 1 : 0);
0240 if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1)
0241 snd_ice1712_stdsp24_box_midi(ice, box, 1);
0242 }
0243
0244 return 0;
0245 }
0246
0247 static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
0248 {
0249 return hoontech_init(ice, false);
0250 }
0251
0252 static int snd_ice1712_staudio_init(struct snd_ice1712 *ice)
0253 {
0254 return hoontech_init(ice, true);
0255 }
0256
0257
0258
0259
0260
0261
0262 static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip)
0263 {
0264 struct snd_ice1712 *ice = ak->private_data[0];
0265 unsigned char tmp;
0266 snd_ice1712_save_gpio_status(ice);
0267 tmp = ICE1712_STDSP24_SERIAL_DATA |
0268 ICE1712_STDSP24_SERIAL_CLOCK |
0269 ICE1712_STDSP24_AK4524_CS;
0270 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
0271 ice->gpio.direction | tmp);
0272 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
0273 }
0274
0275 static int snd_ice1712_value_init(struct snd_ice1712 *ice)
0276 {
0277
0278 static const struct snd_akm4xxx akm_stdsp24_mv = {
0279 .num_adcs = 2,
0280 .num_dacs = 2,
0281 .type = SND_AK4524,
0282 .ops = {
0283 .lock = stdsp24_ak4524_lock
0284 }
0285 };
0286
0287 static const struct snd_ak4xxx_private akm_stdsp24_mv_priv = {
0288 .caddr = 2,
0289 .cif = 1,
0290 .data_mask = ICE1712_STDSP24_SERIAL_DATA,
0291 .clk_mask = ICE1712_STDSP24_SERIAL_CLOCK,
0292 .cs_mask = ICE1712_STDSP24_AK4524_CS,
0293 .cs_addr = ICE1712_STDSP24_AK4524_CS,
0294 .cs_none = 0,
0295 .add_flags = 0,
0296 };
0297
0298 int err;
0299 struct snd_akm4xxx *ak;
0300
0301
0302 ice->num_total_dacs = 2;
0303
0304
0305 ice->num_total_adcs = 2;
0306
0307
0308 ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
0309 if (! ak)
0310 return -ENOMEM;
0311 ice->akm_codecs = 1;
0312
0313 err = snd_ice1712_akm4xxx_init(ak, &akm_stdsp24_mv, &akm_stdsp24_mv_priv, ice);
0314 if (err < 0)
0315 return err;
0316
0317
0318 return snd_ice1712_akm4xxx_build_controls(ice);
0319 }
0320
0321 static int snd_ice1712_ez8_init(struct snd_ice1712 *ice)
0322 {
0323 ice->gpio.write_mask = ice->eeprom.gpiomask;
0324 ice->gpio.direction = ice->eeprom.gpiodir;
0325 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask);
0326 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir);
0327 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate);
0328 return 0;
0329 }
0330
0331
0332
0333 struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] = {
0334 {
0335 .subvendor = ICE1712_SUBDEVICE_STDSP24,
0336 .name = "Hoontech SoundTrack Audio DSP24",
0337 .model = "dsp24",
0338 .chip_init = snd_ice1712_hoontech_init,
0339 .mpu401_1_name = "MIDI-1 Hoontech/STA DSP24",
0340 .mpu401_2_name = "MIDI-2 Hoontech/STA DSP24",
0341 },
0342 {
0343 .subvendor = ICE1712_SUBDEVICE_STDSP24_VALUE,
0344 .name = "Hoontech SoundTrack Audio DSP24 Value",
0345 .model = "dsp24_value",
0346 .chip_init = snd_ice1712_value_init,
0347 },
0348 {
0349 .subvendor = ICE1712_SUBDEVICE_STDSP24_MEDIA7_1,
0350 .name = "Hoontech STA DSP24 Media 7.1",
0351 .model = "dsp24_71",
0352 .chip_init = snd_ice1712_hoontech_init,
0353 },
0354 {
0355 .subvendor = ICE1712_SUBDEVICE_EVENT_EZ8,
0356 .name = "Event Electronics EZ8",
0357 .model = "ez8",
0358 .chip_init = snd_ice1712_ez8_init,
0359 },
0360 {
0361
0362
0363
0364 .subvendor = ICE1712_SUBDEVICE_STAUDIO_ADCIII,
0365 .name = "STAudio ADCIII",
0366 .model = "staudio",
0367 .chip_init = snd_ice1712_staudio_init,
0368 },
0369 { }
0370 };