📄 mts64.c
字号:
int idx = kctl->private_value; int changed = 0; spin_lock_irq(&mts->lock); if (mts->time[idx] != uctl->value.integer.value[0]) { changed = 1; mts->time[idx] = uctl->value.integer.value[0]; } spin_unlock_irq(&mts->lock); return changed;}static struct snd_kcontrol_new mts64_ctl_smpte_time_hours __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI, .name = "SMPTE Time Hours", .index = 0, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .private_value = 0, .info = snd_mts64_ctl_smpte_time_h_info, .get = snd_mts64_ctl_smpte_time_get, .put = snd_mts64_ctl_smpte_time_put};static struct snd_kcontrol_new mts64_ctl_smpte_time_minutes __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI, .name = "SMPTE Time Minutes", .index = 0, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .private_value = 1, .info = snd_mts64_ctl_smpte_time_info, .get = snd_mts64_ctl_smpte_time_get, .put = snd_mts64_ctl_smpte_time_put};static struct snd_kcontrol_new mts64_ctl_smpte_time_seconds __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI, .name = "SMPTE Time Seconds", .index = 0, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .private_value = 2, .info = snd_mts64_ctl_smpte_time_info, .get = snd_mts64_ctl_smpte_time_get, .put = snd_mts64_ctl_smpte_time_put};static struct snd_kcontrol_new mts64_ctl_smpte_time_frames __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI, .name = "SMPTE Time Frames", .index = 0, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .private_value = 3, .info = snd_mts64_ctl_smpte_time_f_info, .get = snd_mts64_ctl_smpte_time_get, .put = snd_mts64_ctl_smpte_time_put};/* FPS */static int snd_mts64_ctl_smpte_fps_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo){ static char *texts[5] = { "24", "25", "29.97", "30D", "30" }; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = 5; if (uinfo->value.enumerated.item > 4) uinfo->value.enumerated.item = 4; strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); return 0;}static int snd_mts64_ctl_smpte_fps_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl){ struct mts64 *mts = snd_kcontrol_chip(kctl); spin_lock_irq(&mts->lock); uctl->value.enumerated.item[0] = mts->fps; spin_unlock_irq(&mts->lock); return 0;}static int snd_mts64_ctl_smpte_fps_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl){ struct mts64 *mts = snd_kcontrol_chip(kctl); int changed = 0; spin_lock_irq(&mts->lock); if (mts->fps != uctl->value.enumerated.item[0]) { changed = 1; mts->fps = uctl->value.enumerated.item[0]; } spin_unlock_irq(&mts->lock); return changed;}static struct snd_kcontrol_new mts64_ctl_smpte_fps __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI, .name = "SMPTE Fps", .index = 0, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .private_value = 0, .info = snd_mts64_ctl_smpte_fps_info, .get = snd_mts64_ctl_smpte_fps_get, .put = snd_mts64_ctl_smpte_fps_put};static int __devinit snd_mts64_ctl_create(struct snd_card *card, struct mts64 *mts) { int err, i; static struct snd_kcontrol_new *control[] = { &mts64_ctl_smpte_switch, &mts64_ctl_smpte_time_hours, &mts64_ctl_smpte_time_minutes, &mts64_ctl_smpte_time_seconds, &mts64_ctl_smpte_time_frames, &mts64_ctl_smpte_fps, NULL }; for (i = 0; control[i]; ++i) { err = snd_ctl_add(card, snd_ctl_new1(control[i], mts)); if (err < 0) { snd_printd("Cannot create control: %s\n", control[i]->name); return err; } } return 0;}/********************************************************************* * Rawmidi *********************************************************************/#define MTS64_MODE_INPUT_TRIGGERED 0x01static int snd_mts64_rawmidi_open(struct snd_rawmidi_substream *substream){ struct mts64 *mts = substream->rmidi->private_data; if (mts->open_count == 0) { /* We don't need a spinlock here, because this is just called if the device has not been opened before. So there aren't any IRQs from the device */ mts64_device_open(mts); msleep(50); } ++(mts->open_count); return 0;}static int snd_mts64_rawmidi_close(struct snd_rawmidi_substream *substream){ struct mts64 *mts = substream->rmidi->private_data; unsigned long flags; --(mts->open_count); if (mts->open_count == 0) { /* We need the spinlock_irqsave here because we can still have IRQs at this point */ spin_lock_irqsave(&mts->lock, flags); mts64_device_close(mts); spin_unlock_irqrestore(&mts->lock, flags); msleep(500); } else if (mts->open_count < 0) mts->open_count = 0; return 0;}static void snd_mts64_rawmidi_output_trigger(struct snd_rawmidi_substream *substream, int up){ struct mts64 *mts = substream->rmidi->private_data; u8 data; unsigned long flags; spin_lock_irqsave(&mts->lock, flags); while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) { mts64_write_midi(mts, data, substream->number+1); snd_rawmidi_transmit_ack(substream, 1); } spin_unlock_irqrestore(&mts->lock, flags);}static void snd_mts64_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up){ struct mts64 *mts = substream->rmidi->private_data; unsigned long flags; spin_lock_irqsave(&mts->lock, flags); if (up) mts->mode[substream->number] |= MTS64_MODE_INPUT_TRIGGERED; else mts->mode[substream->number] &= ~MTS64_MODE_INPUT_TRIGGERED; spin_unlock_irqrestore(&mts->lock, flags);}static struct snd_rawmidi_ops snd_mts64_rawmidi_output_ops = { .open = snd_mts64_rawmidi_open, .close = snd_mts64_rawmidi_close, .trigger = snd_mts64_rawmidi_output_trigger};static struct snd_rawmidi_ops snd_mts64_rawmidi_input_ops = { .open = snd_mts64_rawmidi_open, .close = snd_mts64_rawmidi_close, .trigger = snd_mts64_rawmidi_input_trigger};/* Create and initialize the rawmidi component */static int __devinit snd_mts64_rawmidi_create(struct snd_card *card){ struct mts64 *mts = card->private_data; struct snd_rawmidi *rmidi; struct snd_rawmidi_substream *substream; struct list_head *list; int err; err = snd_rawmidi_new(card, CARD_NAME, 0, MTS64_NUM_OUTPUT_PORTS, MTS64_NUM_INPUT_PORTS, &rmidi); if (err < 0) return err; rmidi->private_data = mts; strcpy(rmidi->name, CARD_NAME); rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; mts->rmidi = rmidi; /* register rawmidi ops */ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mts64_rawmidi_output_ops); snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mts64_rawmidi_input_ops); /* name substreams */ /* output */ list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { substream = list_entry(list, struct snd_rawmidi_substream, list); sprintf(substream->name, "Miditerminal %d", substream->number+1); } /* input */ list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) { substream = list_entry(list, struct snd_rawmidi_substream, list); mts->midi_input_substream[substream->number] = substream; switch(substream->number) { case MTS64_SMPTE_SUBSTREAM: strcpy(substream->name, "Miditerminal SMPTE"); break; default: sprintf(substream->name, "Miditerminal %d", substream->number+1); } } /* controls */ err = snd_mts64_ctl_create(card, mts); return err;}/********************************************************************* * parport stuff *********************************************************************/static void snd_mts64_interrupt(void *private){ struct mts64 *mts = ((struct snd_card*)private)->private_data; u16 ret; u8 status, data; struct snd_rawmidi_substream *substream; spin_lock(&mts->lock); ret = mts64_read(mts->pardev->port); data = ret & 0x00ff; status = ret >> 8; if (status & MTS64_STAT_PORT) { mts->current_midi_input_port = mts64_map_midi_input(data); } else { if (mts->current_midi_input_port == -1) goto __out; substream = mts->midi_input_substream[mts->current_midi_input_port]; if (mts->mode[substream->number] & MTS64_MODE_INPUT_TRIGGERED) snd_rawmidi_receive(substream, &data, 1); }__out: spin_unlock(&mts->lock);}static int __devinit snd_mts64_probe_port(struct parport *p){ struct pardevice *pardev; int res; pardev = parport_register_device(p, DRIVER_NAME, NULL, NULL, NULL, 0, NULL); if (!pardev) return -EIO; if (parport_claim(pardev)) { parport_unregister_device(pardev); return -EIO; } res = mts64_probe(p); parport_release(pardev); parport_unregister_device(pardev); return res;}static void __devinit snd_mts64_attach(struct parport *p){ struct platform_device *device; device = platform_device_alloc(PLATFORM_DRIVER, device_count); if (!device) return; /* Temporary assignment to forward the parport */ platform_set_drvdata(device, p); if (platform_device_add(device) < 0) { platform_device_put(device); return; } /* Since we dont get the return value of probe * We need to check if device probing succeeded or not */ if (!platform_get_drvdata(device)) { platform_device_unregister(device); return; } /* register device in global table */ platform_devices[device_count] = device; device_count++;}static void snd_mts64_detach(struct parport *p){ /* nothing to do here */}static struct parport_driver mts64_parport_driver = { .name = "mts64", .attach = snd_mts64_attach, .detach = snd_mts64_detach};/********************************************************************* * platform stuff *********************************************************************/static void snd_mts64_card_private_free(struct snd_card *card){ struct mts64 *mts = card->private_data; struct pardevice *pardev = mts->pardev; if (pardev) { if (mts->pardev_claimed) parport_release(pardev); parport_unregister_device(pardev); } snd_mts64_free(mts);}static int __devinit snd_mts64_probe(struct platform_device *pdev){ struct pardevice *pardev; struct parport *p; int dev = pdev->id; struct snd_card *card = NULL; struct mts64 *mts = NULL; int err; p = platform_get_drvdata(pdev); platform_set_drvdata(pdev, NULL); if (dev >= SNDRV_CARDS) return -ENODEV; if (!enable[dev]) return -ENOENT; if ((err = snd_mts64_probe_port(p)) < 0) return err; card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); if (card == NULL) { snd_printd("Cannot create card\n"); return -ENOMEM; } strcpy(card->driver, DRIVER_NAME); strcpy(card->shortname, "ESI " CARD_NAME); sprintf(card->longname, "%s at 0x%lx, irq %i", card->shortname, p->base, p->irq); pardev = parport_register_device(p, /* port */ DRIVER_NAME, /* name */ NULL, /* preempt */ NULL, /* wakeup */ snd_mts64_interrupt, /* ISR */ PARPORT_DEV_EXCL, /* flags */ (void *)card); /* private */ if (pardev == NULL) { snd_printd("Cannot register pardevice\n"); err = -EIO; goto __err; } if ((err = snd_mts64_create(card, pardev, &mts)) < 0) { snd_printd("Cannot create main component\n"); parport_unregister_device(pardev); goto __err; } card->private_data = mts; card->private_free = snd_mts64_card_private_free; if ((err = snd_mts64_rawmidi_create(card)) < 0) { snd_printd("Creating Rawmidi component failed\n"); goto __err; } /* claim parport */ if (parport_claim(pardev)) { snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base); err = -EIO; goto __err; } mts->pardev_claimed = 1; /* init device */ if ((err = mts64_device_init(p)) < 0) goto __err; platform_set_drvdata(pdev, card); /* At this point card will be usable */ if ((err = snd_card_register(card)) < 0) { snd_printd("Cannot register card\n"); goto __err; } snd_printk("ESI Miditerminal 4140 on 0x%lx\n", p->base); return 0;__err: snd_card_free(card); return err;}static int __devexit snd_mts64_remove(struct platform_device *pdev){ struct snd_card *card = platform_get_drvdata(pdev); if (card) snd_card_free(card); return 0;}static struct platform_driver snd_mts64_driver = { .probe = snd_mts64_probe, .remove = __devexit_p(snd_mts64_remove), .driver = { .name = PLATFORM_DRIVER }};/********************************************************************* * module init stuff *********************************************************************/static void snd_mts64_unregister_all(void){ int i; for (i = 0; i < SNDRV_CARDS; ++i) { if (platform_devices[i]) { platform_device_unregister(platform_devices[i]); platform_devices[i] = NULL; } } platform_driver_unregister(&snd_mts64_driver); parport_unregister_driver(&mts64_parport_driver);}static int __init snd_mts64_module_init(void){ int err; if ((err = platform_driver_register(&snd_mts64_driver)) < 0) return err; if (parport_register_driver(&mts64_parport_driver) != 0) { platform_driver_unregister(&snd_mts64_driver); return -EIO; } if (device_count == 0) { snd_mts64_unregister_all(); return -ENODEV; } return 0;}static void __exit snd_mts64_module_exit(void){ snd_mts64_unregister_all();}module_init(snd_mts64_module_init);module_exit(snd_mts64_module_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -