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 #include <linux/init.h>
0033 #include <linux/err.h>
0034 #include <linux/isa.h>
0035 #include <linux/pnp.h>
0036 #include <linux/module.h>
0037 #include <sound/core.h>
0038 #include <sound/wss.h>
0039 #include <sound/opl3.h>
0040 #include <sound/mpu401.h>
0041 #include <sound/sb.h>
0042 #include <sound/initval.h>
0043
0044
0045
0046
0047 #define PLAYBACK_ON_SB
0048
0049
0050
0051 MODULE_AUTHOR("George Talusan <gstalusan@uwaterloo.ca>");
0052 MODULE_DESCRIPTION("C-Media CMI8330/CMI8329");
0053 MODULE_LICENSE("GPL");
0054
0055 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
0056 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
0057 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
0058 #ifdef CONFIG_PNP
0059 static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
0060 #endif
0061 static long sbport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
0062 static int sbirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
0063 static int sbdma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
0064 static int sbdma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
0065 static long wssport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
0066 static int wssirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
0067 static int wssdma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
0068 static long fmport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
0069 static long mpuport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
0070 static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
0071
0072 module_param_array(index, int, NULL, 0444);
0073 MODULE_PARM_DESC(index, "Index value for CMI8330/CMI8329 soundcard.");
0074 module_param_array(id, charp, NULL, 0444);
0075 MODULE_PARM_DESC(id, "ID string for CMI8330/CMI8329 soundcard.");
0076 module_param_array(enable, bool, NULL, 0444);
0077 MODULE_PARM_DESC(enable, "Enable CMI8330/CMI8329 soundcard.");
0078 #ifdef CONFIG_PNP
0079 module_param_array(isapnp, bool, NULL, 0444);
0080 MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
0081 #endif
0082
0083 module_param_hw_array(sbport, long, ioport, NULL, 0444);
0084 MODULE_PARM_DESC(sbport, "Port # for CMI8330/CMI8329 SB driver.");
0085 module_param_hw_array(sbirq, int, irq, NULL, 0444);
0086 MODULE_PARM_DESC(sbirq, "IRQ # for CMI8330/CMI8329 SB driver.");
0087 module_param_hw_array(sbdma8, int, dma, NULL, 0444);
0088 MODULE_PARM_DESC(sbdma8, "DMA8 for CMI8330/CMI8329 SB driver.");
0089 module_param_hw_array(sbdma16, int, dma, NULL, 0444);
0090 MODULE_PARM_DESC(sbdma16, "DMA16 for CMI8330/CMI8329 SB driver.");
0091
0092 module_param_hw_array(wssport, long, ioport, NULL, 0444);
0093 MODULE_PARM_DESC(wssport, "Port # for CMI8330/CMI8329 WSS driver.");
0094 module_param_hw_array(wssirq, int, irq, NULL, 0444);
0095 MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330/CMI8329 WSS driver.");
0096 module_param_hw_array(wssdma, int, dma, NULL, 0444);
0097 MODULE_PARM_DESC(wssdma, "DMA for CMI8330/CMI8329 WSS driver.");
0098
0099 module_param_hw_array(fmport, long, ioport, NULL, 0444);
0100 MODULE_PARM_DESC(fmport, "FM port # for CMI8330/CMI8329 driver.");
0101 module_param_hw_array(mpuport, long, ioport, NULL, 0444);
0102 MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330/CMI8329 driver.");
0103 module_param_hw_array(mpuirq, int, irq, NULL, 0444);
0104 MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330/CMI8329 MPU-401 port.");
0105 #ifdef CONFIG_PNP
0106 static int isa_registered;
0107 static int pnp_registered;
0108 #endif
0109
0110 #define CMI8330_RMUX3D 16
0111 #define CMI8330_MUTEMUX 17
0112 #define CMI8330_OUTPUTVOL 18
0113 #define CMI8330_MASTVOL 19
0114 #define CMI8330_LINVOL 20
0115 #define CMI8330_CDINVOL 21
0116 #define CMI8330_WAVVOL 22
0117 #define CMI8330_RECMUX 23
0118 #define CMI8330_WAVGAIN 24
0119 #define CMI8330_LINGAIN 25
0120 #define CMI8330_CDINGAIN 26
0121
0122 static const unsigned char snd_cmi8330_image[((CMI8330_CDINGAIN)-16) + 1] =
0123 {
0124 0x40,
0125 #ifdef ENABLE_SB_MIXER
0126 0x40,
0127 #else
0128 0x0,
0129 #endif
0130 0x0,
0131 0x0,
0132 0x0,
0133 0x0,
0134 0x0,
0135 0x0,
0136 0x0,
0137 0x0,
0138 0x0
0139 };
0140
0141 typedef int (*snd_pcm_open_callback_t)(struct snd_pcm_substream *);
0142
0143 enum card_type {
0144 CMI8330,
0145 CMI8329
0146 };
0147
0148 struct snd_cmi8330 {
0149 #ifdef CONFIG_PNP
0150 struct pnp_dev *cap;
0151 struct pnp_dev *play;
0152 struct pnp_dev *mpu;
0153 #endif
0154 struct snd_card *card;
0155 struct snd_wss *wss;
0156 struct snd_sb *sb;
0157
0158 struct snd_pcm *pcm;
0159 struct snd_cmi8330_stream {
0160 struct snd_pcm_ops ops;
0161 snd_pcm_open_callback_t open;
0162 void *private_data;
0163 } streams[2];
0164
0165 enum card_type type;
0166 };
0167
0168 #ifdef CONFIG_PNP
0169
0170 static const struct pnp_card_device_id snd_cmi8330_pnpids[] = {
0171 { .id = "CMI0001", .devs = { { "@X@0001" }, { "@@@0001" }, { "@H@0001" }, { "A@@0001" } } },
0172 { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } },
0173 { .id = "" }
0174 };
0175
0176 MODULE_DEVICE_TABLE(pnp_card, snd_cmi8330_pnpids);
0177
0178 #endif
0179
0180
0181 static const struct snd_kcontrol_new snd_cmi8330_controls[] = {
0182 WSS_DOUBLE("Master Playback Volume", 0,
0183 CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0),
0184 WSS_SINGLE("Loud Playback Switch", 0,
0185 CMI8330_MUTEMUX, 6, 1, 1),
0186 WSS_DOUBLE("PCM Playback Switch", 0,
0187 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
0188 WSS_DOUBLE("PCM Playback Volume", 0,
0189 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
0190 WSS_DOUBLE("Line Playback Switch", 0,
0191 CMI8330_MUTEMUX, CMI8330_MUTEMUX, 4, 3, 1, 0),
0192 WSS_DOUBLE("Line Playback Volume", 0,
0193 CMI8330_LINVOL, CMI8330_LINVOL, 4, 0, 15, 0),
0194 WSS_DOUBLE("Line Capture Switch", 0,
0195 CMI8330_RMUX3D, CMI8330_RMUX3D, 2, 1, 1, 0),
0196 WSS_DOUBLE("Line Capture Volume", 0,
0197 CMI8330_LINGAIN, CMI8330_LINGAIN, 4, 0, 15, 0),
0198 WSS_DOUBLE("CD Playback Switch", 0,
0199 CMI8330_MUTEMUX, CMI8330_MUTEMUX, 2, 1, 1, 0),
0200 WSS_DOUBLE("CD Capture Switch", 0,
0201 CMI8330_RMUX3D, CMI8330_RMUX3D, 4, 3, 1, 0),
0202 WSS_DOUBLE("CD Playback Volume", 0,
0203 CMI8330_CDINVOL, CMI8330_CDINVOL, 4, 0, 15, 0),
0204 WSS_DOUBLE("CD Capture Volume", 0,
0205 CMI8330_CDINGAIN, CMI8330_CDINGAIN, 4, 0, 15, 0),
0206 WSS_SINGLE("Mic Playback Switch", 0,
0207 CMI8330_MUTEMUX, 0, 1, 0),
0208 WSS_SINGLE("Mic Playback Volume", 0,
0209 CMI8330_OUTPUTVOL, 0, 7, 0),
0210 WSS_SINGLE("Mic Capture Switch", 0,
0211 CMI8330_RMUX3D, 0, 1, 0),
0212 WSS_SINGLE("Mic Capture Volume", 0,
0213 CMI8330_OUTPUTVOL, 5, 7, 0),
0214 WSS_DOUBLE("Wavetable Playback Switch", 0,
0215 CMI8330_RECMUX, CMI8330_RECMUX, 1, 0, 1, 0),
0216 WSS_DOUBLE("Wavetable Playback Volume", 0,
0217 CMI8330_WAVVOL, CMI8330_WAVVOL, 4, 0, 15, 0),
0218 WSS_DOUBLE("Wavetable Capture Switch", 0,
0219 CMI8330_RECMUX, CMI8330_RECMUX, 5, 4, 1, 0),
0220 WSS_DOUBLE("Wavetable Capture Volume", 0,
0221 CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0),
0222 WSS_SINGLE("3D Control - Switch", 0,
0223 CMI8330_RMUX3D, 5, 1, 1),
0224 WSS_SINGLE("Beep Playback Volume", 0,
0225 CMI8330_OUTPUTVOL, 3, 3, 0),
0226 WSS_DOUBLE("FM Playback Switch", 0,
0227 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
0228 WSS_DOUBLE("FM Playback Volume", 0,
0229 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
0230 WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", CAPTURE, SWITCH), 0,
0231 CMI8330_RMUX3D, 7, 1, 1),
0232 WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", PLAYBACK, SWITCH), 0,
0233 CMI8330_MUTEMUX, 7, 1, 1),
0234 };
0235
0236 #ifdef ENABLE_SB_MIXER
0237 static const struct sbmix_elem cmi8330_sb_mixers[] = {
0238 SB_DOUBLE("SB Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31),
0239 SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15),
0240 SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15),
0241 SB_DOUBLE("SB PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31),
0242 SB_DOUBLE("SB Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31),
0243 SB_DOUBLE("SB CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
0244 SB_DOUBLE("SB CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31),
0245 SB_DOUBLE("SB Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
0246 SB_DOUBLE("SB Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31),
0247 SB_SINGLE("SB Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
0248 SB_SINGLE("SB Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
0249 SB_SINGLE("SB Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
0250 SB_DOUBLE("SB Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3),
0251 SB_DOUBLE("SB Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3),
0252 SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1),
0253 };
0254
0255 static const unsigned char cmi8330_sb_init_values[][2] = {
0256 { SB_DSP4_MASTER_DEV + 0, 0 },
0257 { SB_DSP4_MASTER_DEV + 1, 0 },
0258 { SB_DSP4_PCM_DEV + 0, 0 },
0259 { SB_DSP4_PCM_DEV + 1, 0 },
0260 { SB_DSP4_SYNTH_DEV + 0, 0 },
0261 { SB_DSP4_SYNTH_DEV + 1, 0 },
0262 { SB_DSP4_INPUT_LEFT, 0 },
0263 { SB_DSP4_INPUT_RIGHT, 0 },
0264 { SB_DSP4_OUTPUT_SW, 0 },
0265 { SB_DSP4_SPEAKER_DEV, 0 },
0266 };
0267
0268
0269 static int cmi8330_add_sb_mixers(struct snd_sb *chip)
0270 {
0271 int idx, err;
0272 unsigned long flags;
0273
0274 spin_lock_irqsave(&chip->mixer_lock, flags);
0275 snd_sbmixer_write(chip, 0x00, 0x00);
0276 spin_unlock_irqrestore(&chip->mixer_lock, flags);
0277
0278
0279 for (idx = 0; idx < ARRAY_SIZE(cmi8330_sb_init_values); idx++) {
0280 spin_lock_irqsave(&chip->mixer_lock, flags);
0281 snd_sbmixer_write(chip, cmi8330_sb_init_values[idx][0],
0282 cmi8330_sb_init_values[idx][1]);
0283 spin_unlock_irqrestore(&chip->mixer_lock, flags);
0284 }
0285
0286 for (idx = 0; idx < ARRAY_SIZE(cmi8330_sb_mixers); idx++) {
0287 err = snd_sbmixer_add_ctl_elem(chip, &cmi8330_sb_mixers[idx]);
0288 if (err < 0)
0289 return err;
0290 }
0291 return 0;
0292 }
0293 #endif
0294
0295 static int snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330 *acard)
0296 {
0297 unsigned int idx;
0298 int err;
0299
0300 strcpy(card->mixername, (acard->type == CMI8329) ? "CMI8329" : "CMI8330/C3D");
0301
0302 for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) {
0303 err = snd_ctl_add(card,
0304 snd_ctl_new1(&snd_cmi8330_controls[idx],
0305 acard->wss));
0306 if (err < 0)
0307 return err;
0308 }
0309
0310 #ifdef ENABLE_SB_MIXER
0311 err = cmi8330_add_sb_mixers(acard->sb);
0312 if (err < 0)
0313 return err;
0314 #endif
0315 return 0;
0316 }
0317
0318 #ifdef CONFIG_PNP
0319 static int snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
0320 struct pnp_card_link *card,
0321 const struct pnp_card_device_id *id)
0322 {
0323 struct pnp_dev *pdev;
0324 int err;
0325
0326
0327 acard->type = (id->devs[3].id[0]) ? CMI8329 : CMI8330;
0328
0329 acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL);
0330 if (acard->cap == NULL)
0331 return -EBUSY;
0332
0333 acard->play = pnp_request_card_device(card, id->devs[1].id, NULL);
0334 if (acard->play == NULL)
0335 return -EBUSY;
0336
0337 acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL);
0338 if (acard->mpu == NULL)
0339 return -EBUSY;
0340
0341 pdev = acard->cap;
0342
0343 err = pnp_activate_dev(pdev);
0344 if (err < 0) {
0345 snd_printk(KERN_ERR "AD1848 PnP configure failure\n");
0346 return -EBUSY;
0347 }
0348 wssport[dev] = pnp_port_start(pdev, 0);
0349 wssdma[dev] = pnp_dma(pdev, 0);
0350 wssirq[dev] = pnp_irq(pdev, 0);
0351 if (pnp_port_start(pdev, 1))
0352 fmport[dev] = pnp_port_start(pdev, 1);
0353
0354
0355 pdev = acard->play;
0356
0357 err = pnp_activate_dev(pdev);
0358 if (err < 0) {
0359 snd_printk(KERN_ERR "SB16 PnP configure failure\n");
0360 return -EBUSY;
0361 }
0362 sbport[dev] = pnp_port_start(pdev, 0);
0363 sbdma8[dev] = pnp_dma(pdev, 0);
0364 sbdma16[dev] = pnp_dma(pdev, 1);
0365 sbirq[dev] = pnp_irq(pdev, 0);
0366
0367 if (fmport[dev] == SNDRV_AUTO_PORT) {
0368 if (pnp_port_start(pdev, 1))
0369 fmport[dev] = pnp_port_start(pdev, 1);
0370 else
0371 fmport[dev] = 0x388;
0372 }
0373
0374
0375 pdev = acard->mpu;
0376
0377 err = pnp_activate_dev(pdev);
0378 if (err < 0)
0379 snd_printk(KERN_ERR "MPU-401 PnP configure failure: will be disabled\n");
0380 else {
0381 mpuport[dev] = pnp_port_start(pdev, 0);
0382 mpuirq[dev] = pnp_irq(pdev, 0);
0383 }
0384 return 0;
0385 }
0386 #endif
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401 #ifdef PLAYBACK_ON_SB
0402 #define CMI_SB_STREAM SNDRV_PCM_STREAM_PLAYBACK
0403 #define CMI_AD_STREAM SNDRV_PCM_STREAM_CAPTURE
0404 #else
0405 #define CMI_SB_STREAM SNDRV_PCM_STREAM_CAPTURE
0406 #define CMI_AD_STREAM SNDRV_PCM_STREAM_PLAYBACK
0407 #endif
0408
0409 static int snd_cmi8330_playback_open(struct snd_pcm_substream *substream)
0410 {
0411 struct snd_cmi8330 *chip = snd_pcm_substream_chip(substream);
0412
0413
0414 substream->private_data = chip->streams[SNDRV_PCM_STREAM_PLAYBACK].private_data;
0415 return chip->streams[SNDRV_PCM_STREAM_PLAYBACK].open(substream);
0416 }
0417
0418 static int snd_cmi8330_capture_open(struct snd_pcm_substream *substream)
0419 {
0420 struct snd_cmi8330 *chip = snd_pcm_substream_chip(substream);
0421
0422
0423 substream->private_data = chip->streams[SNDRV_PCM_STREAM_CAPTURE].private_data;
0424 return chip->streams[SNDRV_PCM_STREAM_CAPTURE].open(substream);
0425 }
0426
0427 static int snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *chip)
0428 {
0429 struct snd_pcm *pcm;
0430 const struct snd_pcm_ops *ops;
0431 int err;
0432 static const snd_pcm_open_callback_t cmi_open_callbacks[2] = {
0433 snd_cmi8330_playback_open,
0434 snd_cmi8330_capture_open
0435 };
0436
0437 err = snd_pcm_new(card, (chip->type == CMI8329) ? "CMI8329" : "CMI8330", 0, 1, 1, &pcm);
0438 if (err < 0)
0439 return err;
0440 strcpy(pcm->name, (chip->type == CMI8329) ? "CMI8329" : "CMI8330");
0441 pcm->private_data = chip;
0442
0443
0444 ops = snd_sb16dsp_get_pcm_ops(CMI_SB_STREAM);
0445 chip->streams[CMI_SB_STREAM].ops = *ops;
0446 chip->streams[CMI_SB_STREAM].open = ops->open;
0447 chip->streams[CMI_SB_STREAM].ops.open = cmi_open_callbacks[CMI_SB_STREAM];
0448 chip->streams[CMI_SB_STREAM].private_data = chip->sb;
0449
0450
0451 ops = snd_wss_get_pcm_ops(CMI_AD_STREAM);
0452 chip->streams[CMI_AD_STREAM].ops = *ops;
0453 chip->streams[CMI_AD_STREAM].open = ops->open;
0454 chip->streams[CMI_AD_STREAM].ops.open = cmi_open_callbacks[CMI_AD_STREAM];
0455 chip->streams[CMI_AD_STREAM].private_data = chip->wss;
0456
0457 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &chip->streams[SNDRV_PCM_STREAM_PLAYBACK].ops);
0458 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &chip->streams[SNDRV_PCM_STREAM_CAPTURE].ops);
0459
0460 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
0461 card->dev, 64*1024, 128*1024);
0462 chip->pcm = pcm;
0463
0464 return 0;
0465 }
0466
0467
0468 #ifdef CONFIG_PM
0469 static int snd_cmi8330_suspend(struct snd_card *card)
0470 {
0471 struct snd_cmi8330 *acard = card->private_data;
0472
0473 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
0474 acard->wss->suspend(acard->wss);
0475 snd_sbmixer_suspend(acard->sb);
0476 return 0;
0477 }
0478
0479 static int snd_cmi8330_resume(struct snd_card *card)
0480 {
0481 struct snd_cmi8330 *acard = card->private_data;
0482
0483 snd_sbdsp_reset(acard->sb);
0484 snd_sbmixer_suspend(acard->sb);
0485 acard->wss->resume(acard->wss);
0486 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
0487 return 0;
0488 }
0489 #endif
0490
0491
0492
0493
0494
0495 #ifdef CONFIG_PNP
0496 #define is_isapnp_selected(dev) isapnp[dev]
0497 #else
0498 #define is_isapnp_selected(dev) 0
0499 #endif
0500
0501 #define PFX "cmi8330: "
0502
0503 static int snd_cmi8330_card_new(struct device *pdev, int dev,
0504 struct snd_card **cardp)
0505 {
0506 struct snd_card *card;
0507 struct snd_cmi8330 *acard;
0508 int err;
0509
0510 err = snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE,
0511 sizeof(struct snd_cmi8330), &card);
0512 if (err < 0) {
0513 snd_printk(KERN_ERR PFX "could not get a new card\n");
0514 return err;
0515 }
0516 acard = card->private_data;
0517 acard->card = card;
0518 *cardp = card;
0519 return 0;
0520 }
0521
0522 static int snd_cmi8330_probe(struct snd_card *card, int dev)
0523 {
0524 struct snd_cmi8330 *acard;
0525 int i, err;
0526 struct snd_opl3 *opl3;
0527
0528 acard = card->private_data;
0529 err = snd_wss_create(card, wssport[dev] + 4, -1,
0530 wssirq[dev],
0531 wssdma[dev], -1,
0532 WSS_HW_DETECT, 0, &acard->wss);
0533 if (err < 0) {
0534 snd_printk(KERN_ERR PFX "AD1848 device busy??\n");
0535 return err;
0536 }
0537 if (acard->wss->hardware != WSS_HW_CMI8330) {
0538 snd_printk(KERN_ERR PFX "AD1848 not found during probe\n");
0539 return -ENODEV;
0540 }
0541
0542 err = snd_sbdsp_create(card, sbport[dev],
0543 sbirq[dev],
0544 snd_sb16dsp_interrupt,
0545 sbdma8[dev],
0546 sbdma16[dev],
0547 SB_HW_AUTO, &acard->sb);
0548 if (err < 0) {
0549 snd_printk(KERN_ERR PFX "SB16 device busy??\n");
0550 return err;
0551 }
0552 if (acard->sb->hardware != SB_HW_16) {
0553 snd_printk(KERN_ERR PFX "SB16 not found during probe\n");
0554 return -ENODEV;
0555 }
0556
0557 snd_wss_out(acard->wss, CS4231_MISC_INFO, 0x40);
0558 for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++)
0559 snd_wss_out(acard->wss, i,
0560 snd_cmi8330_image[i - CMI8330_RMUX3D]);
0561
0562 err = snd_cmi8330_mixer(card, acard);
0563 if (err < 0) {
0564 snd_printk(KERN_ERR PFX "failed to create mixers\n");
0565 return err;
0566 }
0567
0568 err = snd_cmi8330_pcm(card, acard);
0569 if (err < 0) {
0570 snd_printk(KERN_ERR PFX "failed to create pcms\n");
0571 return err;
0572 }
0573 if (fmport[dev] != SNDRV_AUTO_PORT) {
0574 if (snd_opl3_create(card,
0575 fmport[dev], fmport[dev] + 2,
0576 OPL3_HW_AUTO, 0, &opl3) < 0) {
0577 snd_printk(KERN_ERR PFX
0578 "no OPL device at 0x%lx-0x%lx ?\n",
0579 fmport[dev], fmport[dev] + 2);
0580 } else {
0581 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
0582 if (err < 0)
0583 return err;
0584 }
0585 }
0586
0587 if (mpuport[dev] != SNDRV_AUTO_PORT) {
0588 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
0589 mpuport[dev], 0, mpuirq[dev],
0590 NULL) < 0)
0591 printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n",
0592 mpuport[dev]);
0593 }
0594
0595 strcpy(card->driver, (acard->type == CMI8329) ? "CMI8329" : "CMI8330/C3D");
0596 strcpy(card->shortname, (acard->type == CMI8329) ? "C-Media CMI8329" : "C-Media CMI8330/C3D");
0597 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
0598 card->shortname,
0599 acard->wss->port,
0600 wssirq[dev],
0601 wssdma[dev]);
0602
0603 return snd_card_register(card);
0604 }
0605
0606 static int snd_cmi8330_isa_match(struct device *pdev,
0607 unsigned int dev)
0608 {
0609 if (!enable[dev] || is_isapnp_selected(dev))
0610 return 0;
0611 if (wssport[dev] == SNDRV_AUTO_PORT) {
0612 snd_printk(KERN_ERR PFX "specify wssport\n");
0613 return 0;
0614 }
0615 if (sbport[dev] == SNDRV_AUTO_PORT) {
0616 snd_printk(KERN_ERR PFX "specify sbport\n");
0617 return 0;
0618 }
0619 return 1;
0620 }
0621
0622 static int snd_cmi8330_isa_probe(struct device *pdev,
0623 unsigned int dev)
0624 {
0625 struct snd_card *card;
0626 int err;
0627
0628 err = snd_cmi8330_card_new(pdev, dev, &card);
0629 if (err < 0)
0630 return err;
0631 err = snd_cmi8330_probe(card, dev);
0632 if (err < 0)
0633 return err;
0634 dev_set_drvdata(pdev, card);
0635 return 0;
0636 }
0637
0638 #ifdef CONFIG_PM
0639 static int snd_cmi8330_isa_suspend(struct device *dev, unsigned int n,
0640 pm_message_t state)
0641 {
0642 return snd_cmi8330_suspend(dev_get_drvdata(dev));
0643 }
0644
0645 static int snd_cmi8330_isa_resume(struct device *dev, unsigned int n)
0646 {
0647 return snd_cmi8330_resume(dev_get_drvdata(dev));
0648 }
0649 #endif
0650
0651 #define DEV_NAME "cmi8330"
0652
0653 static struct isa_driver snd_cmi8330_driver = {
0654 .match = snd_cmi8330_isa_match,
0655 .probe = snd_cmi8330_isa_probe,
0656 #ifdef CONFIG_PM
0657 .suspend = snd_cmi8330_isa_suspend,
0658 .resume = snd_cmi8330_isa_resume,
0659 #endif
0660 .driver = {
0661 .name = DEV_NAME
0662 },
0663 };
0664
0665
0666 #ifdef CONFIG_PNP
0667 static int snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
0668 const struct pnp_card_device_id *pid)
0669 {
0670 static int dev;
0671 struct snd_card *card;
0672 int res;
0673
0674 for ( ; dev < SNDRV_CARDS; dev++) {
0675 if (enable[dev] && isapnp[dev])
0676 break;
0677 }
0678 if (dev >= SNDRV_CARDS)
0679 return -ENODEV;
0680
0681 res = snd_cmi8330_card_new(&pcard->card->dev, dev, &card);
0682 if (res < 0)
0683 return res;
0684 res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid);
0685 if (res < 0) {
0686 snd_printk(KERN_ERR PFX "PnP detection failed\n");
0687 return res;
0688 }
0689 res = snd_cmi8330_probe(card, dev);
0690 if (res < 0)
0691 return res;
0692 pnp_set_card_drvdata(pcard, card);
0693 dev++;
0694 return 0;
0695 }
0696
0697 #ifdef CONFIG_PM
0698 static int snd_cmi8330_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
0699 {
0700 return snd_cmi8330_suspend(pnp_get_card_drvdata(pcard));
0701 }
0702
0703 static int snd_cmi8330_pnp_resume(struct pnp_card_link *pcard)
0704 {
0705 return snd_cmi8330_resume(pnp_get_card_drvdata(pcard));
0706 }
0707 #endif
0708
0709 static struct pnp_card_driver cmi8330_pnpc_driver = {
0710 .flags = PNP_DRIVER_RES_DISABLE,
0711 .name = "cmi8330",
0712 .id_table = snd_cmi8330_pnpids,
0713 .probe = snd_cmi8330_pnp_detect,
0714 #ifdef CONFIG_PM
0715 .suspend = snd_cmi8330_pnp_suspend,
0716 .resume = snd_cmi8330_pnp_resume,
0717 #endif
0718 };
0719 #endif
0720
0721 static int __init alsa_card_cmi8330_init(void)
0722 {
0723 int err;
0724
0725 err = isa_register_driver(&snd_cmi8330_driver, SNDRV_CARDS);
0726 #ifdef CONFIG_PNP
0727 if (!err)
0728 isa_registered = 1;
0729
0730 err = pnp_register_card_driver(&cmi8330_pnpc_driver);
0731 if (!err)
0732 pnp_registered = 1;
0733
0734 if (isa_registered)
0735 err = 0;
0736 #endif
0737 return err;
0738 }
0739
0740 static void __exit alsa_card_cmi8330_exit(void)
0741 {
0742 #ifdef CONFIG_PNP
0743 if (pnp_registered)
0744 pnp_unregister_card_driver(&cmi8330_pnpc_driver);
0745
0746 if (isa_registered)
0747 #endif
0748 isa_unregister_driver(&snd_cmi8330_driver);
0749 }
0750
0751 module_init(alsa_card_cmi8330_init)
0752 module_exit(alsa_card_cmi8330_exit)