Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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)  *   Driver for Midiman Portman2x4 parallel port midi interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *   Copyright (c) by Levent Guendogdu <levon@feature-it.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * ChangeLog
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Jan 24 2007 Matthias Koenig <mkoenig@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *      - cleanup and rewrite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Sep 30 2004 Tobias Gehrig <tobias@gehrig.tk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *      - source code cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * Sep 03 2004 Tobias Gehrig <tobias@gehrig.tk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *      - fixed compilation problem with alsa 1.0.6a (removed MODULE_CLASSES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *        MODULE_PARM_SYNTAX and changed MODULE_DEVICES to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *        MODULE_SUPPORTED_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * Mar 24 2004 Tobias Gehrig <tobias@gehrig.tk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *      - added 2.6 kernel support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * Mar 18 2004 Tobias Gehrig <tobias@gehrig.tk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *      - added parport_unregister_driver to the startup routine if the driver fails to detect a portman
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *      - added support for all 4 output ports in portman_putmidi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * Mar 17 2004 Tobias Gehrig <tobias@gehrig.tk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *      - added checks for opened input device in interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * Feb 20 2004 Tobias Gehrig <tobias@gehrig.tk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *      - ported from alsa 0.5 to 1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/parport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <sound/rawmidi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define CARD_NAME "Portman 2x4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define DRIVER_NAME "portman"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define PLATFORM_DRIVER "snd_portman2x4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) static int index[SNDRV_CARDS]  = SNDRV_DEFAULT_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static char *id[SNDRV_CARDS]   = SNDRV_DEFAULT_STR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static struct platform_device *platform_devices[SNDRV_CARDS]; 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static int device_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) MODULE_AUTHOR("Levent Guendogdu, Tobias Gehrig, Matthias Koenig");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) MODULE_DESCRIPTION("Midiman Portman2x4");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) MODULE_SUPPORTED_DEVICE("{{Midiman,Portman2x4}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  * Chip specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define PORTMAN_NUM_INPUT_PORTS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define PORTMAN_NUM_OUTPUT_PORTS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) struct portman {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	spinlock_t reg_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct pardevice *pardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	int open_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	int mode[PORTMAN_NUM_INPUT_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct snd_rawmidi_substream *midi_input[PORTMAN_NUM_INPUT_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) static int portman_free(struct portman *pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	kfree(pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) static int portman_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			  struct pardevice *pardev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			  struct portman **rchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	struct portman *pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	*rchip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	pm = kzalloc(sizeof(struct portman), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (pm == NULL) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	/* Init chip specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	spin_lock_init(&pm->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	pm->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	pm->pardev = pardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	*rchip = pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * HW related constants
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* Standard PC parallel port status register equates. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define	PP_STAT_BSY   	0x80	/* Busy status.  Inverted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define	PP_STAT_ACK   	0x40	/* Acknowledge.  Non-Inverted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define	PP_STAT_POUT  	0x20	/* Paper Out.    Non-Inverted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define	PP_STAT_SEL   	0x10	/* Select.       Non-Inverted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define	PP_STAT_ERR   	0x08	/* Error.        Non-Inverted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* Standard PC parallel port command register equates. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define	PP_CMD_IEN  	0x10	/* IRQ Enable.   Non-Inverted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define	PP_CMD_SELI 	0x08	/* Select Input. Inverted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define	PP_CMD_INIT 	0x04	/* Init Printer. Non-Inverted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define	PP_CMD_FEED 	0x02	/* Auto Feed.    Inverted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define	PP_CMD_STB      0x01	/* Strobe.       Inverted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Parallel Port Command Register as implemented by PCP2x4. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define	INT_EN	 	PP_CMD_IEN	/* Interrupt enable. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define	STROBE	        PP_CMD_STB	/* Command strobe. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* The parallel port command register field (b1..b3) selects the 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  * various "registers" within the PC/P 2x4.  These are the internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * address of these "registers" that must be written to the parallel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * port command register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define	RXDATA0		(0 << 1)	/* PCP RxData channel 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define	RXDATA1		(1 << 1)	/* PCP RxData channel 1. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define	GEN_CTL		(2 << 1)	/* PCP General Control Register. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define	SYNC_CTL 	(3 << 1)	/* PCP Sync Control Register. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define	TXDATA0		(4 << 1)	/* PCP TxData channel 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define	TXDATA1		(5 << 1)	/* PCP TxData channel 1. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define	TXDATA2		(6 << 1)	/* PCP TxData channel 2. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define	TXDATA3		(7 << 1)	/* PCP TxData channel 3. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* Parallel Port Status Register as implemented by PCP2x4. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define	ESTB		PP_STAT_POUT	/* Echoed strobe. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define	INT_REQ         PP_STAT_ACK	/* Input data int request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define	BUSY            PP_STAT_ERR	/* Interface Busy. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* Parallel Port Status Register BUSY and SELECT lines are multiplexed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  * between several functions.  Depending on which 2x4 "register" is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  * currently selected (b1..b3), the BUSY and SELECT lines are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  * assigned as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  *   SELECT LINE:                                                    A3 A2 A1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  *                                                                   --------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define	RXAVAIL		PP_STAT_SEL	/* Rx Available, channel 0.   0 0 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) //  RXAVAIL1    PP_STAT_SEL             /* Rx Available, channel 1.   0 0 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define	SYNC_STAT	PP_STAT_SEL	/* Reserved - Sync Status.    0 1 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) //                                      /* Reserved.                  0 1 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define	TXEMPTY		PP_STAT_SEL	/* Tx Empty, channel 0.       1 0 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) //      TXEMPTY1        PP_STAT_SEL     /* Tx Empty, channel 1.       1 0 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) //  TXEMPTY2    PP_STAT_SEL             /* Tx Empty, channel 2.       1 1 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) //  TXEMPTY3    PP_STAT_SEL             /* Tx Empty, channel 3.       1 1 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /*   BUSY LINE:                                                      A3 A2 A1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  *                                                                   --------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define	RXDATA		PP_STAT_BSY	/* Rx Input Data, channel 0.  0 0 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) //      RXDATA1         PP_STAT_BSY     /* Rx Input Data, channel 1.  0 0 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define	SYNC_DATA       PP_STAT_BSY	/* Reserved - Sync Data.      0 1 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 					/* Reserved.                  0 1 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define	DATA_ECHO       PP_STAT_BSY	/* Parallel Port Data Echo.   1 0 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define	A0_ECHO         PP_STAT_BSY	/* Address 0 Echo.            1 0 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define	A1_ECHO         PP_STAT_BSY	/* Address 1 Echo.            1 1 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define	A2_ECHO         PP_STAT_BSY	/* Address 2 Echo.            1 1 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define PORTMAN2X4_MODE_INPUT_TRIGGERED	 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  * Hardware specific functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static inline void portman_write_command(struct portman *pm, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	parport_write_control(pm->pardev->port, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static inline u8 portman_read_command(struct portman *pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	return parport_read_control(pm->pardev->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static inline u8 portman_read_status(struct portman *pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	return parport_read_status(pm->pardev->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static inline u8 portman_read_data(struct portman *pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	return parport_read_data(pm->pardev->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static inline void portman_write_data(struct portman *pm, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	parport_write_data(pm->pardev->port, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static void portman_write_midi(struct portman *pm, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			       int port, u8 mididata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	int command = ((port + 4) << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	/* Get entering data byte and port number in BL and BH respectively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	 * Set up Tx Channel address field for use with PP Cmd Register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	 * Store address field in BH register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	 * Inputs:      AH = Output port number (0..3).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	 *              AL = Data byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	 *    command = TXDATA0 | INT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	 * Align port num with address field (b1...b3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	 * set address for TXDatax, Strobe=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	command |= INT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	/* Disable interrupts so that the process is not interrupted, then 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	 * write the address associated with the current Tx channel to the 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	 * PP Command Reg.  Do not set the Strobe signal yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		portman_write_command(pm, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		/* While the address lines settle, write parallel output data to 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		 * PP Data Reg.  This has no effect until Strobe signal is asserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		portman_write_data(pm, mididata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		/* If PCP channel's TxEmpty is set (TxEmpty is read through the PP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		 * Status Register), then go write data.  Else go back and wait.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	} while ((portman_read_status(pm) & TXEMPTY) != TXEMPTY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	/* TxEmpty is set.  Maintain PC/P destination address and assert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	 * Strobe through the PP Command Reg.  This will Strobe data into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	 * the PC/P transmitter and set the PC/P BUSY signal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	portman_write_command(pm, command | STROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	/* Wait for strobe line to settle and echo back through hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	 * Once it has echoed back, assume that the address and data lines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	 * have settled!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	while ((portman_read_status(pm) & ESTB) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	/* Release strobe and immediately re-allow interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	portman_write_command(pm, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	while ((portman_read_status(pm) & ESTB) == ESTB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	/* PC/P BUSY is now set.  We must wait until BUSY resets itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	 * We'll reenable ints while we're waiting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	while ((portman_read_status(pm) & BUSY) == BUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	/* Data sent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  *  Read MIDI byte from port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  *  Attempt to read input byte from specified hardware input port (0..).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  *  Return -1 if no data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static int portman_read_midi(struct portman *pm, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	unsigned char midi_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	unsigned char cmdout;	/* Saved address+IE bit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	/* Make sure clocking edge is down before starting... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	portman_write_data(pm, 0);	/* Make sure edge is down. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	/* Set destination address to PCP. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	cmdout = (port << 1) | INT_EN;	/* Address + IE + No Strobe. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	portman_write_command(pm, cmdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	while ((portman_read_status(pm) & ESTB) == ESTB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		cpu_relax();	/* Wait for strobe echo. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	/* After the address lines settle, check multiplexed RxAvail signal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	 * If data is available, read it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	if ((portman_read_status(pm) & RXAVAIL) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		return -1;	/* No data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	/* Set the Strobe signal to enable the Rx clocking circuitry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	portman_write_command(pm, cmdout | STROBE);	/* Write address+IE+Strobe. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	while ((portman_read_status(pm) & ESTB) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		cpu_relax(); /* Wait for strobe echo. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	/* The first data bit (msb) is already sitting on the input line. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	midi_data = (portman_read_status(pm) & 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	portman_write_data(pm, 1);	/* Cause rising edge, which shifts data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	/* Data bit 6. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	portman_write_data(pm, 0);	/* Cause falling edge while data settles. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	midi_data |= (portman_read_status(pm) >> 1) & 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	portman_write_data(pm, 1);	/* Cause rising edge, which shifts data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	/* Data bit 5. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	portman_write_data(pm, 0);	/* Cause falling edge while data settles. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	midi_data |= (portman_read_status(pm) >> 2) & 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	portman_write_data(pm, 1);	/* Cause rising edge, which shifts data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	/* Data bit 4. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	portman_write_data(pm, 0);	/* Cause falling edge while data settles. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	midi_data |= (portman_read_status(pm) >> 3) & 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	portman_write_data(pm, 1);	/* Cause rising edge, which shifts data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	/* Data bit 3. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	portman_write_data(pm, 0);	/* Cause falling edge while data settles. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	midi_data |= (portman_read_status(pm) >> 4) & 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	portman_write_data(pm, 1);	/* Cause rising edge, which shifts data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	/* Data bit 2. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	portman_write_data(pm, 0);	/* Cause falling edge while data settles. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	midi_data |= (portman_read_status(pm) >> 5) & 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	portman_write_data(pm, 1);	/* Cause rising edge, which shifts data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	/* Data bit 1. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	portman_write_data(pm, 0);	/* Cause falling edge while data settles. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	midi_data |= (portman_read_status(pm) >> 6) & 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	portman_write_data(pm, 1);	/* Cause rising edge, which shifts data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	/* Data bit 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	portman_write_data(pm, 0);	/* Cause falling edge while data settles. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	midi_data |= (portman_read_status(pm) >> 7) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	portman_write_data(pm, 1);	/* Cause rising edge, which shifts data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	portman_write_data(pm, 0);	/* Return data clock low. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	/* De-assert Strobe and return data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	portman_write_command(pm, cmdout);	/* Output saved address+IE. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	/* Wait for strobe echo. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	while ((portman_read_status(pm) & ESTB) == ESTB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	return (midi_data & 255);	/* Shift back and return value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)  *  Checks if any input data on the given channel is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  *  Checks RxAvail 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static int portman_data_avail(struct portman *pm, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	int command = INT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	switch (channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		command |= RXDATA0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		command |= RXDATA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	/* Write hardware (assumme STROBE=0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	portman_write_command(pm, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	/* Check multiplexed RxAvail signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	if ((portman_read_status(pm) & RXAVAIL) == RXAVAIL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		return 1;	/* Data available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	/* No Data available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)  *  Flushes any input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static void portman_flush_input(struct portman *pm, unsigned char port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	/* Local variable for counting things */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	unsigned int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	unsigned char command = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	switch (port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		command = RXDATA0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		command = RXDATA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		snd_printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			   "portman_flush_input() Won't flush port %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			   port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		return;
^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) 	/* Set address for specified channel in port and allow to settle. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	portman_write_command(pm, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	/* Assert the Strobe and wait for echo back. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	portman_write_command(pm, command | STROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	/* Wait for ESTB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	while ((portman_read_status(pm) & ESTB) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	/* Output clock cycles to the Rx circuitry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	portman_write_data(pm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	/* Flush 250 bits... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	for (i = 0; i < 250; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		portman_write_data(pm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		portman_write_data(pm, 0);
^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) 	/* Deassert the Strobe signal of the port and wait for it to settle. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	portman_write_command(pm, command | INT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	/* Wait for settling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	while ((portman_read_status(pm) & ESTB) == ESTB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int portman_probe(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	/* Initialize the parallel port data register.  Will set Rx clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	 * low in case we happen to be addressing the Rx ports at this time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	/* 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	parport_write_data(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	/* Initialize the parallel port command register, thus initializing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	 * hardware handshake lines to midi box:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	 *                                  Strobe = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	 *                                  Interrupt Enable = 0            
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	/* 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	parport_write_control(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	/* Check if Portman PC/P 2x4 is out there. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	/* 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	parport_write_control(p, RXDATA0);	/* Write Strobe=0 to command reg. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	/* Check for ESTB to be clear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	/* 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	if ((parport_read_status(p) & ESTB) == ESTB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		return 1;	/* CODE 1 - Strobe Failure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	/* Set for RXDATA0 where no damage will be done. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	/* 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	parport_write_control(p, RXDATA0 | STROBE);	/* Write Strobe=1 to command reg. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	/* 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	if ((parport_read_status(p) & ESTB) != ESTB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		return 1;	/* CODE 1 - Strobe Failure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	/* 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	parport_write_control(p, 0);	/* Reset Strobe=0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	/* Check if Tx circuitry is functioning properly.  If initialized 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	 * unit TxEmpty is false, send out char and see if it goes true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	/* 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	parport_write_control(p, TXDATA0);	/* Tx channel 0, strobe off. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	/* If PCP channel's TxEmpty is set (TxEmpty is read through the PP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	 * Status Register), then go write data.  Else go back and wait.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	/* 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	if ((parport_read_status(p) & TXEMPTY) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	/* Return OK status. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) static int portman_device_init(struct portman *pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	portman_flush_input(pm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	portman_flush_input(pm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)  * Rawmidi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)  *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static int snd_portman_midi_open(struct snd_rawmidi_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^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_portman_midi_close(struct snd_rawmidi_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static void snd_portman_midi_input_trigger(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 					   int up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	struct portman *pm = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	spin_lock_irqsave(&pm->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	if (up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		pm->mode[substream->number] |= PORTMAN2X4_MODE_INPUT_TRIGGERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		pm->mode[substream->number] &= ~PORTMAN2X4_MODE_INPUT_TRIGGERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	spin_unlock_irqrestore(&pm->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static void snd_portman_midi_output_trigger(struct snd_rawmidi_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 					    int up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	struct portman *pm = substream->rmidi->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	spin_lock_irqsave(&pm->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	if (up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		while ((snd_rawmidi_transmit(substream, &byte, 1) == 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 			portman_write_midi(pm, substream->number, byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	spin_unlock_irqrestore(&pm->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static const struct snd_rawmidi_ops snd_portman_midi_output = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	.open =		snd_portman_midi_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	.close =	snd_portman_midi_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	.trigger =	snd_portman_midi_output_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static const struct snd_rawmidi_ops snd_portman_midi_input = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	.open =		snd_portman_midi_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	.close =	snd_portman_midi_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	.trigger =	snd_portman_midi_input_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* Create and initialize the rawmidi component */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) static int snd_portman_rawmidi_create(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	struct portman *pm = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	struct snd_rawmidi_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	err = snd_rawmidi_new(card, CARD_NAME, 0, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 			      PORTMAN_NUM_OUTPUT_PORTS, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 			      PORTMAN_NUM_INPUT_PORTS, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 			      &rmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	if (err < 0) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	rmidi->private_data = pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	strcpy(rmidi->name, CARD_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		            SNDRV_RAWMIDI_INFO_INPUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)                             SNDRV_RAWMIDI_INFO_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	pm->rmidi = rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	/* register rawmidi ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 			    &snd_portman_midi_output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 			    &snd_portman_midi_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	/* name substreams */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	/* output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	list_for_each_entry(substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 			    &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 			    list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		sprintf(substream->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 			"Portman2x4 %d", substream->number+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	/* input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	list_for_each_entry(substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 			    &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 			    list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		pm->midi_input[substream->number] = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 		sprintf(substream->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 			"Portman2x4 %d", substream->number+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^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)  * parport stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)  *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static void snd_portman_interrupt(void *userdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	unsigned char midivalue = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	struct portman *pm = ((struct snd_card*)userdata)->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	spin_lock(&pm->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	/* While any input data is waiting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	while ((portman_read_status(pm) & INT_REQ) == INT_REQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		/* If data available on channel 0, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		   read it and stuff it into the queue. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		if (portman_data_avail(pm, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 			/* Read Midi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 			midivalue = portman_read_midi(pm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 			/* put midi into queue... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 			if (pm->mode[0] & PORTMAN2X4_MODE_INPUT_TRIGGERED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 				snd_rawmidi_receive(pm->midi_input[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 						    &midivalue, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		/* If data available on channel 1, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		   read it and stuff it into the queue. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		if (portman_data_avail(pm, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 			/* Read Midi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 			midivalue = portman_read_midi(pm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 			/* put midi into queue... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 			if (pm->mode[1] & PORTMAN2X4_MODE_INPUT_TRIGGERED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 				snd_rawmidi_receive(pm->midi_input[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 						    &midivalue, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	spin_unlock(&pm->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static void snd_portman_attach(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	struct platform_device *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	device = platform_device_alloc(PLATFORM_DRIVER, device_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	if (!device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	/* Temporary assignment to forward the parport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	platform_set_drvdata(device, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	if (platform_device_add(device) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		platform_device_put(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	/* Since we dont get the return value of probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	 * We need to check if device probing succeeded or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	if (!platform_get_drvdata(device)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		platform_device_unregister(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	/* register device in global table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	platform_devices[device_count] = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	device_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static void snd_portman_detach(struct parport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	/* nothing to do here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static int snd_portman_dev_probe(struct pardevice *pardev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	if (strcmp(pardev->name, DRIVER_NAME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static struct parport_driver portman_parport_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	.name		= "portman2x4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	.probe		= snd_portman_dev_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	.match_port	= snd_portman_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	.detach		= snd_portman_detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	.devmodel	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)  * platform stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)  *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static void snd_portman_card_private_free(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	struct portman *pm = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	struct pardevice *pardev = pm->pardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	if (pardev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		parport_release(pardev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		parport_unregister_device(pardev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	portman_free(pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static int snd_portman_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	struct pardevice *pardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	struct parport *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	int dev = pdev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	struct snd_card *card = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	struct portman *pm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	struct pardev_cb portman_cb = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		.preempt = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 		.wakeup = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 		.irq_func = snd_portman_interrupt,	/* ISR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		.flags = PARPORT_DEV_EXCL,		/* flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	p = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	platform_set_drvdata(pdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	if (!enable[dev]) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 			   0, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 		snd_printd("Cannot create card\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	strcpy(card->driver, DRIVER_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	strcpy(card->shortname, CARD_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	sprintf(card->longname,  "%s at 0x%lx, irq %i", 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 		card->shortname, p->base, p->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	portman_cb.private = card;			   /* private */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	pardev = parport_register_dev_model(p,		   /* port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 					    DRIVER_NAME,   /* name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 					    &portman_cb,   /* callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 					    pdev->id);	   /* device number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	if (pardev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		snd_printd("Cannot register pardevice\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		goto __err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	/* claim parport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	if (parport_claim(pardev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 		goto free_pardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	if ((err = portman_create(card, pardev, &pm)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		snd_printd("Cannot create main component\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 		goto release_pardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	card->private_data = pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	card->private_free = snd_portman_card_private_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	err = portman_probe(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 		err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 		goto __err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	if ((err = snd_portman_rawmidi_create(card)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 		snd_printd("Creating Rawmidi component failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 		goto __err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	/* init device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	if ((err = portman_device_init(pm)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 		goto __err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	platform_set_drvdata(pdev, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	/* At this point card will be usable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	if ((err = snd_card_register(card)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		snd_printd("Cannot register card\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 		goto __err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	snd_printk(KERN_INFO "Portman 2x4 on 0x%lx\n", p->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) release_pardev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	parport_release(pardev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) free_pardev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	parport_unregister_device(pardev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) __err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) static int snd_portman_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	struct snd_card *card = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	if (card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 		snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static struct platform_driver snd_portman_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	.probe  = snd_portman_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	.remove = snd_portman_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 		.name = PLATFORM_DRIVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)  * module init stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)  *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static void snd_portman_unregister_all(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	for (i = 0; i < SNDRV_CARDS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 		if (platform_devices[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 			platform_device_unregister(platform_devices[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 			platform_devices[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 	}		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	platform_driver_unregister(&snd_portman_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 	parport_unregister_driver(&portman_parport_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) static int __init snd_portman_module_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	if ((err = platform_driver_register(&snd_portman_driver)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	if (parport_register_driver(&portman_parport_driver) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 		platform_driver_unregister(&snd_portman_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 	if (device_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 		snd_portman_unregister_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) static void __exit snd_portman_module_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 	snd_portman_unregister_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) module_init(snd_portman_module_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) module_exit(snd_portman_module_exit);