^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ALSA Driver for Ego Systems Inc. (ESI) Miditerminal 4140
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2006 by Matthias König <mk@phasorlab.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/parport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <sound/rawmidi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define CARD_NAME "Miditerminal 4140"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define DRIVER_NAME "MTS64"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define PLATFORM_DRIVER "snd_mts64"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static struct platform_device *platform_devices[SNDRV_CARDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static int device_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) MODULE_AUTHOR("Matthias Koenig <mk@phasorlab.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) MODULE_DESCRIPTION("ESI Miditerminal 4140");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) MODULE_SUPPORTED_DEVICE("{{ESI,Miditerminal 4140}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Chip specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MTS64_NUM_INPUT_PORTS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MTS64_NUM_OUTPUT_PORTS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define MTS64_SMPTE_SUBSTREAM 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct mts64 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct pardevice *pardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int open_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int current_midi_output_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int current_midi_input_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u8 mode[MTS64_NUM_INPUT_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct snd_rawmidi_substream *midi_input_substream[MTS64_NUM_INPUT_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int smpte_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) u8 time[4]; /* [0]=hh, [1]=mm, [2]=ss, [3]=ff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u8 fps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static int snd_mts64_free(struct mts64 *mts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) kfree(mts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static int snd_mts64_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct pardevice *pardev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct mts64 **rchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct mts64 *mts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *rchip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) mts = kzalloc(sizeof(struct mts64), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (mts == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Init chip specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) spin_lock_init(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mts->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) mts->pardev = pardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) mts->current_midi_output_port = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) mts->current_midi_input_port = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) *rchip = mts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * HW register related constants
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* Status Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define MTS64_STAT_BSY 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define MTS64_STAT_BIT_SET 0x20 /* readout process, bit is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define MTS64_STAT_PORT 0x10 /* read byte is a port number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* Control Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define MTS64_CTL_READOUT 0x08 /* enable readout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define MTS64_CTL_WRITE_CMD 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define MTS64_CTL_WRITE_DATA 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define MTS64_CTL_STROBE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* Command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define MTS64_CMD_RESET 0xfe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define MTS64_CMD_PROBE 0x8f /* Used in probing procedure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define MTS64_CMD_SMPTE_SET_TIME 0xe8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define MTS64_CMD_SMPTE_SET_FPS 0xee
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define MTS64_CMD_SMPTE_STOP 0xef
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define MTS64_CMD_SMPTE_FPS_24 0xe3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define MTS64_CMD_SMPTE_FPS_25 0xe2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define MTS64_CMD_SMPTE_FPS_2997 0xe4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define MTS64_CMD_SMPTE_FPS_30D 0xe1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define MTS64_CMD_SMPTE_FPS_30 0xe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define MTS64_CMD_COM_OPEN 0xf8 /* setting the communication mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define MTS64_CMD_COM_CLOSE1 0xff /* clearing communication mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define MTS64_CMD_COM_CLOSE2 0xf5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * Hardware specific functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void mts64_enable_readout(struct parport *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static void mts64_disable_readout(struct parport *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int mts64_device_ready(struct parport *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static int mts64_device_init(struct parport *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int mts64_device_open(struct mts64 *mts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int mts64_device_close(struct mts64 *mts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static u8 mts64_map_midi_input(u8 c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int mts64_probe(struct parport *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static u16 mts64_read(struct parport *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static u8 mts64_read_char(struct parport *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static void mts64_smpte_start(struct parport *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u8 hours, u8 minutes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u8 seconds, u8 frames,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u8 idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static void mts64_smpte_stop(struct parport *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static void mts64_write_command(struct parport *p, u8 c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static void mts64_write_data(struct parport *p, u8 c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static void mts64_write_midi(struct mts64 *mts, u8 c, int midiport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* Enables the readout procedure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Before we can read a midi byte from the device, we have to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * bit 3 of control port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static void mts64_enable_readout(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u8 c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) c = parport_read_control(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) c |= MTS64_CTL_READOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) parport_write_control(p, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* Disables readout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * Readout is disabled by clearing bit 3 of control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static void mts64_disable_readout(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u8 c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) c = parport_read_control(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) c &= ~MTS64_CTL_READOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) parport_write_control(p, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* waits for device ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * Checks if BUSY (Bit 7 of status) is clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * 1 device ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * 0 failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int mts64_device_ready(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u8 c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) for (i = 0; i < 0xffff; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) c = parport_read_status(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) c &= MTS64_STAT_BSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (c != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* Init device (LED blinking startup magic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * 0 init ok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * -EIO failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int mts64_device_init(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) mts64_write_command(p, MTS64_CMD_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) for (i = 0; i < 64; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (mts64_probe(p) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) mts64_disable_readout(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) mts64_disable_readout(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * Opens the device (set communication mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static int mts64_device_open(struct mts64 *mts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct parport *p = mts->pardev->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) for (i = 0; i < 5; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) mts64_write_command(p, MTS64_CMD_COM_OPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Close device (clear communication mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static int mts64_device_close(struct mts64 *mts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct parport *p = mts->pardev->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) for (i = 0; i < 5; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) mts64_write_command(p, MTS64_CMD_COM_CLOSE1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) mts64_write_command(p, MTS64_CMD_COM_CLOSE2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /* map hardware port to substream number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * When reading a byte from the device, the device tells us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * on what port the byte is. This HW port has to be mapped to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * the midiport (substream number).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * substream 0-3 are Midiports 1-4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * substream 4 is SMPTE Timecode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * The mapping is done by the table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * HW | 0 | 1 | 2 | 3 | 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * SW | 0 | 1 | 4 | 2 | 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static u8 mts64_map_midi_input(u8 c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static const u8 map[] = { 0, 1, 4, 2, 3 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return map[c];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* Probe parport for device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * Do we have a Miditerminal 4140 on parport?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * 0 device found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * -ENODEV no device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static int mts64_probe(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) u8 c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) mts64_smpte_stop(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) mts64_write_command(p, MTS64_CMD_PROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) c = mts64_read(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) c &= 0x00ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (c != MTS64_CMD_PROBE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* Read byte incl. status from device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * data in lower 8 bits and status in upper 8 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static u16 mts64_read(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) u8 data, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) mts64_device_ready(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) mts64_enable_readout(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) status = parport_read_status(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) data = mts64_read_char(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) mts64_disable_readout(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return (status << 8) | data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* Read a byte from device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * Note, that readout mode has to be enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * readout procedure is as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * - Write number of the Bit to read to DATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * - Read STATUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * - Bit 5 of STATUS indicates if Bit is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * Byte read from device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static u8 mts64_read_char(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) u8 c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) for (i = 0; i < 8; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) parport_write_data(p, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) c >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) status = parport_read_status(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (status & MTS64_STAT_BIT_SET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) c |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /* Starts SMPTE Timecode generation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * The device creates SMPTE Timecode by hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * 0 24 fps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * 1 25 fps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * 2 29.97 fps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * 3 30 fps (Drop-frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * 4 30 fps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static void mts64_smpte_start(struct parport *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) u8 hours, u8 minutes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) u8 seconds, u8 frames,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) u8 idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static const u8 fps[5] = { MTS64_CMD_SMPTE_FPS_24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) MTS64_CMD_SMPTE_FPS_25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) MTS64_CMD_SMPTE_FPS_2997,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) MTS64_CMD_SMPTE_FPS_30D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) MTS64_CMD_SMPTE_FPS_30 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) mts64_write_command(p, MTS64_CMD_SMPTE_SET_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) mts64_write_command(p, frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) mts64_write_command(p, seconds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) mts64_write_command(p, minutes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) mts64_write_command(p, hours);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) mts64_write_command(p, MTS64_CMD_SMPTE_SET_FPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) mts64_write_command(p, fps[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* Stops SMPTE Timecode generation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static void mts64_smpte_stop(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) mts64_write_command(p, MTS64_CMD_SMPTE_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* Write a command byte to device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static void mts64_write_command(struct parport *p, u8 c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) mts64_device_ready(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) parport_write_data(p, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) parport_write_control(p, MTS64_CTL_WRITE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) parport_write_control(p, MTS64_CTL_WRITE_CMD | MTS64_CTL_STROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) parport_write_control(p, MTS64_CTL_WRITE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* Write a data byte to device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static void mts64_write_data(struct parport *p, u8 c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) mts64_device_ready(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) parport_write_data(p, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) parport_write_control(p, MTS64_CTL_WRITE_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) parport_write_control(p, MTS64_CTL_WRITE_DATA | MTS64_CTL_STROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) parport_write_control(p, MTS64_CTL_WRITE_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* Write a MIDI byte to midiport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * midiport ranges from 0-3 and maps to Ports 1-4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * assumptions: communication mode is on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static void mts64_write_midi(struct mts64 *mts, u8 c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int midiport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct parport *p = mts->pardev->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* check current midiport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (mts->current_midi_output_port != midiport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) mts64_write_command(p, midiport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* write midi byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) mts64_write_data(p, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * Control elements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* SMPTE Switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) #define snd_mts64_ctl_smpte_switch_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static int snd_mts64_ctl_smpte_switch_get(struct snd_kcontrol* kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct snd_ctl_elem_value *uctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct mts64 *mts = snd_kcontrol_chip(kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) spin_lock_irq(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) uctl->value.integer.value[0] = mts->smpte_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) spin_unlock_irq(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /* smpte_switch is not accessed from IRQ handler, so we just need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) to protect the HW access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static int snd_mts64_ctl_smpte_switch_put(struct snd_kcontrol* kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct snd_ctl_elem_value *uctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct mts64 *mts = snd_kcontrol_chip(kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) int val = !!uctl->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) spin_lock_irq(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (mts->smpte_switch == val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) goto __out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) mts->smpte_switch = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (mts->smpte_switch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) mts64_smpte_start(mts->pardev->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) mts->time[0], mts->time[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) mts->time[2], mts->time[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) mts->fps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) mts64_smpte_stop(mts->pardev->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) __out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) spin_unlock_irq(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static const struct snd_kcontrol_new mts64_ctl_smpte_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) .name = "SMPTE Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .private_value = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .info = snd_mts64_ctl_smpte_switch_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) .get = snd_mts64_ctl_smpte_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) .put = snd_mts64_ctl_smpte_switch_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* Time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static int snd_mts64_ctl_smpte_time_h_info(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) uinfo->value.integer.max = 23;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static int snd_mts64_ctl_smpte_time_f_info(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) uinfo->value.integer.max = 99;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static int snd_mts64_ctl_smpte_time_info(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) uinfo->value.integer.max = 59;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int snd_mts64_ctl_smpte_time_get(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct snd_ctl_elem_value *uctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct mts64 *mts = snd_kcontrol_chip(kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) int idx = kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) spin_lock_irq(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) uctl->value.integer.value[0] = mts->time[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) spin_unlock_irq(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) static int snd_mts64_ctl_smpte_time_put(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct snd_ctl_elem_value *uctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct mts64 *mts = snd_kcontrol_chip(kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) int idx = kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) unsigned int time = uctl->value.integer.value[0] % 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) spin_lock_irq(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (mts->time[idx] != time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) mts->time[idx] = time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) spin_unlock_irq(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static const struct snd_kcontrol_new mts64_ctl_smpte_time_hours = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .name = "SMPTE Time Hours",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .private_value = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .info = snd_mts64_ctl_smpte_time_h_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .get = snd_mts64_ctl_smpte_time_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .put = snd_mts64_ctl_smpte_time_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static const struct snd_kcontrol_new mts64_ctl_smpte_time_minutes = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .name = "SMPTE Time Minutes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .private_value = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) .info = snd_mts64_ctl_smpte_time_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .get = snd_mts64_ctl_smpte_time_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .put = snd_mts64_ctl_smpte_time_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static const struct snd_kcontrol_new mts64_ctl_smpte_time_seconds = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) .name = "SMPTE Time Seconds",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .private_value = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) .info = snd_mts64_ctl_smpte_time_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .get = snd_mts64_ctl_smpte_time_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) .put = snd_mts64_ctl_smpte_time_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static const struct snd_kcontrol_new mts64_ctl_smpte_time_frames = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) .name = "SMPTE Time Frames",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .private_value = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .info = snd_mts64_ctl_smpte_time_f_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .get = snd_mts64_ctl_smpte_time_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .put = snd_mts64_ctl_smpte_time_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /* FPS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static int snd_mts64_ctl_smpte_fps_info(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) static const char * const texts[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) "24", "25", "29.97", "30D", "30"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return snd_ctl_enum_info(uinfo, 1, 5, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static int snd_mts64_ctl_smpte_fps_get(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct snd_ctl_elem_value *uctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct mts64 *mts = snd_kcontrol_chip(kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) spin_lock_irq(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) uctl->value.enumerated.item[0] = mts->fps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) spin_unlock_irq(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static int snd_mts64_ctl_smpte_fps_put(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct snd_ctl_elem_value *uctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct mts64 *mts = snd_kcontrol_chip(kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (uctl->value.enumerated.item[0] >= 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) spin_lock_irq(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (mts->fps != uctl->value.enumerated.item[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) mts->fps = uctl->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) spin_unlock_irq(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static const struct snd_kcontrol_new mts64_ctl_smpte_fps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) .name = "SMPTE Fps",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) .private_value = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) .info = snd_mts64_ctl_smpte_fps_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) .get = snd_mts64_ctl_smpte_fps_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .put = snd_mts64_ctl_smpte_fps_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static int snd_mts64_ctl_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct mts64 *mts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) static const struct snd_kcontrol_new *control[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) &mts64_ctl_smpte_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) &mts64_ctl_smpte_time_hours,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) &mts64_ctl_smpte_time_minutes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) &mts64_ctl_smpte_time_seconds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) &mts64_ctl_smpte_time_frames,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) &mts64_ctl_smpte_fps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) for (i = 0; control[i]; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) err = snd_ctl_add(card, snd_ctl_new1(control[i], mts));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) snd_printd("Cannot create control: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) control[i]->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * Rawmidi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) #define MTS64_MODE_INPUT_TRIGGERED 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static int snd_mts64_rawmidi_open(struct snd_rawmidi_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct mts64 *mts = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (mts->open_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /* We don't need a spinlock here, because this is just called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if the device has not been opened before.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) So there aren't any IRQs from the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) mts64_device_open(mts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) ++(mts->open_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) static int snd_mts64_rawmidi_close(struct snd_rawmidi_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct mts64 *mts = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) --(mts->open_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (mts->open_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /* We need the spinlock_irqsave here because we can still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) have IRQs at this point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) spin_lock_irqsave(&mts->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) mts64_device_close(mts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) spin_unlock_irqrestore(&mts->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) msleep(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) } else if (mts->open_count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) mts->open_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static void snd_mts64_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) int up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct mts64 *mts = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) spin_lock_irqsave(&mts->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) mts64_write_midi(mts, data, substream->number+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) snd_rawmidi_transmit_ack(substream, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) spin_unlock_irqrestore(&mts->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static void snd_mts64_rawmidi_input_trigger(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) int up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct mts64 *mts = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) spin_lock_irqsave(&mts->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) mts->mode[substream->number] |= MTS64_MODE_INPUT_TRIGGERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) mts->mode[substream->number] &= ~MTS64_MODE_INPUT_TRIGGERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) spin_unlock_irqrestore(&mts->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) static const struct snd_rawmidi_ops snd_mts64_rawmidi_output_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) .open = snd_mts64_rawmidi_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) .close = snd_mts64_rawmidi_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) .trigger = snd_mts64_rawmidi_output_trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static const struct snd_rawmidi_ops snd_mts64_rawmidi_input_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) .open = snd_mts64_rawmidi_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) .close = snd_mts64_rawmidi_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .trigger = snd_mts64_rawmidi_input_trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) /* Create and initialize the rawmidi component */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static int snd_mts64_rawmidi_create(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct mts64 *mts = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct snd_rawmidi_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct list_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) err = snd_rawmidi_new(card, CARD_NAME, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) MTS64_NUM_OUTPUT_PORTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) MTS64_NUM_INPUT_PORTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) &rmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) rmidi->private_data = mts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) strcpy(rmidi->name, CARD_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) SNDRV_RAWMIDI_INFO_INPUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) SNDRV_RAWMIDI_INFO_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) mts->rmidi = rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /* register rawmidi ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) &snd_mts64_rawmidi_output_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) &snd_mts64_rawmidi_input_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* name substreams */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) /* output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) list_for_each(list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) substream = list_entry(list, struct snd_rawmidi_substream, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) sprintf(substream->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) "Miditerminal %d", substream->number+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) list_for_each(list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) substream = list_entry(list, struct snd_rawmidi_substream, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) mts->midi_input_substream[substream->number] = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) switch(substream->number) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) case MTS64_SMPTE_SUBSTREAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) strcpy(substream->name, "Miditerminal SMPTE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) sprintf(substream->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) "Miditerminal %d", substream->number+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /* controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) err = snd_mts64_ctl_create(card, mts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * parport stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static void snd_mts64_interrupt(void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct mts64 *mts = ((struct snd_card*)private)->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) u16 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) u8 status, data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) struct snd_rawmidi_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) spin_lock(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ret = mts64_read(mts->pardev->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) data = ret & 0x00ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) status = ret >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (status & MTS64_STAT_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) mts->current_midi_input_port = mts64_map_midi_input(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (mts->current_midi_input_port == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) goto __out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) substream = mts->midi_input_substream[mts->current_midi_input_port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (mts->mode[substream->number] & MTS64_MODE_INPUT_TRIGGERED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) snd_rawmidi_receive(substream, &data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) __out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) spin_unlock(&mts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) static void snd_mts64_attach(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) struct platform_device *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) device = platform_device_alloc(PLATFORM_DRIVER, device_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (!device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) /* Temporary assignment to forward the parport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) platform_set_drvdata(device, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (platform_device_add(device) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) platform_device_put(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) /* Since we dont get the return value of probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * We need to check if device probing succeeded or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (!platform_get_drvdata(device)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) platform_device_unregister(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) /* register device in global table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) platform_devices[device_count] = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) device_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static void snd_mts64_detach(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) /* nothing to do here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) static int snd_mts64_dev_probe(struct pardevice *pardev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (strcmp(pardev->name, DRIVER_NAME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) static struct parport_driver mts64_parport_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .name = "mts64",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) .probe = snd_mts64_dev_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) .match_port = snd_mts64_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) .detach = snd_mts64_detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) .devmodel = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * platform stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) static void snd_mts64_card_private_free(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) struct mts64 *mts = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) struct pardevice *pardev = mts->pardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (pardev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) parport_release(pardev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) parport_unregister_device(pardev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) snd_mts64_free(mts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) static int snd_mts64_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) struct pardevice *pardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct parport *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) int dev = pdev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) struct snd_card *card = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) struct mts64 *mts = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) struct pardev_cb mts64_cb = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .preempt = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .wakeup = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) .irq_func = snd_mts64_interrupt, /* ISR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) .flags = PARPORT_DEV_EXCL, /* flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) p = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) platform_set_drvdata(pdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (!enable[dev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 0, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) snd_printd("Cannot create card\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) strcpy(card->driver, DRIVER_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) strcpy(card->shortname, "ESI " CARD_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) sprintf(card->longname, "%s at 0x%lx, irq %i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) card->shortname, p->base, p->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) mts64_cb.private = card; /* private */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) pardev = parport_register_dev_model(p, /* port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) DRIVER_NAME, /* name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) &mts64_cb, /* callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) pdev->id); /* device number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (!pardev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) snd_printd("Cannot register pardevice\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) goto __err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) /* claim parport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (parport_claim(pardev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) goto free_pardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if ((err = snd_mts64_create(card, pardev, &mts)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) snd_printd("Cannot create main component\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) goto release_pardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) card->private_data = mts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) card->private_free = snd_mts64_card_private_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) err = mts64_probe(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) goto __err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if ((err = snd_mts64_rawmidi_create(card)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) snd_printd("Creating Rawmidi component failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) goto __err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /* init device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if ((err = mts64_device_init(p)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) goto __err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) platform_set_drvdata(pdev, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) /* At this point card will be usable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if ((err = snd_card_register(card)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) snd_printd("Cannot register card\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) goto __err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) snd_printk(KERN_INFO "ESI Miditerminal 4140 on 0x%lx\n", p->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) release_pardev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) parport_release(pardev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) free_pardev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) parport_unregister_device(pardev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) __err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) static int snd_mts64_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) struct snd_card *card = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) static struct platform_driver snd_mts64_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) .probe = snd_mts64_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) .remove = snd_mts64_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) .name = PLATFORM_DRIVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) * module init stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static void snd_mts64_unregister_all(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) for (i = 0; i < SNDRV_CARDS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (platform_devices[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) platform_device_unregister(platform_devices[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) platform_devices[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) platform_driver_unregister(&snd_mts64_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) parport_unregister_driver(&mts64_parport_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) static int __init snd_mts64_module_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if ((err = platform_driver_register(&snd_mts64_driver)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (parport_register_driver(&mts64_parport_driver) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) platform_driver_unregister(&snd_mts64_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (device_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) snd_mts64_unregister_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static void __exit snd_mts64_module_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) snd_mts64_unregister_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) module_init(snd_mts64_module_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) module_exit(snd_mts64_module_exit);