xref: /OK3568_Linux_fs/kernel/sound/pci/korg1212/korg1212.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *   Driver for the Korg 1212 IO PCI card
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *	Copyright (c) 2001 Haroldo Gamal <gamal@alternex.com.br>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/delay.h>
9*4882a593Smuzhiyun #include <linux/init.h>
10*4882a593Smuzhiyun #include <linux/interrupt.h>
11*4882a593Smuzhiyun #include <linux/pci.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun #include <linux/wait.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include <linux/mutex.h>
16*4882a593Smuzhiyun #include <linux/firmware.h>
17*4882a593Smuzhiyun #include <linux/io.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include <sound/core.h>
20*4882a593Smuzhiyun #include <sound/info.h>
21*4882a593Smuzhiyun #include <sound/control.h>
22*4882a593Smuzhiyun #include <sound/pcm.h>
23*4882a593Smuzhiyun #include <sound/pcm_params.h>
24*4882a593Smuzhiyun #include <sound/initval.h>
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun // ----------------------------------------------------------------------------
27*4882a593Smuzhiyun // Debug Stuff
28*4882a593Smuzhiyun // ----------------------------------------------------------------------------
29*4882a593Smuzhiyun #define K1212_DEBUG_LEVEL		0
30*4882a593Smuzhiyun #if K1212_DEBUG_LEVEL > 0
31*4882a593Smuzhiyun #define K1212_DEBUG_PRINTK(fmt,args...)	printk(KERN_DEBUG fmt,##args)
32*4882a593Smuzhiyun #else
33*4882a593Smuzhiyun #define K1212_DEBUG_PRINTK(fmt,...)	do { } while (0)
34*4882a593Smuzhiyun #endif
35*4882a593Smuzhiyun #if K1212_DEBUG_LEVEL > 1
36*4882a593Smuzhiyun #define K1212_DEBUG_PRINTK_VERBOSE(fmt,args...)	printk(KERN_DEBUG fmt,##args)
37*4882a593Smuzhiyun #else
38*4882a593Smuzhiyun #define K1212_DEBUG_PRINTK_VERBOSE(fmt,...)
39*4882a593Smuzhiyun #endif
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun // ----------------------------------------------------------------------------
42*4882a593Smuzhiyun // Record/Play Buffer Allocation Method. If K1212_LARGEALLOC is defined all
43*4882a593Smuzhiyun // buffers are alocated as a large piece inside KorgSharedBuffer.
44*4882a593Smuzhiyun // ----------------------------------------------------------------------------
45*4882a593Smuzhiyun //#define K1212_LARGEALLOC		1
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun // ----------------------------------------------------------------------------
48*4882a593Smuzhiyun // Valid states of the Korg 1212 I/O card.
49*4882a593Smuzhiyun // ----------------------------------------------------------------------------
50*4882a593Smuzhiyun enum CardState {
51*4882a593Smuzhiyun    K1212_STATE_NONEXISTENT,		// there is no card here
52*4882a593Smuzhiyun    K1212_STATE_UNINITIALIZED,		// the card is awaiting DSP download
53*4882a593Smuzhiyun    K1212_STATE_DSP_IN_PROCESS,		// the card is currently downloading its DSP code
54*4882a593Smuzhiyun    K1212_STATE_DSP_COMPLETE,		// the card has finished the DSP download
55*4882a593Smuzhiyun    K1212_STATE_READY,			// the card can be opened by an application.  Any application
56*4882a593Smuzhiyun 					//    requests prior to this state should fail.  Only an open
57*4882a593Smuzhiyun 					//    request can be made at this state.
58*4882a593Smuzhiyun    K1212_STATE_OPEN,			// an application has opened the card
59*4882a593Smuzhiyun    K1212_STATE_SETUP,			// the card has been setup for play
60*4882a593Smuzhiyun    K1212_STATE_PLAYING,			// the card is playing
61*4882a593Smuzhiyun    K1212_STATE_MONITOR,			// the card is in the monitor mode
62*4882a593Smuzhiyun    K1212_STATE_CALIBRATING,		// the card is currently calibrating
63*4882a593Smuzhiyun    K1212_STATE_ERRORSTOP,		// the card has stopped itself because of an error and we
64*4882a593Smuzhiyun 					//    are in the process of cleaning things up.
65*4882a593Smuzhiyun    K1212_STATE_MAX_STATE		// state values of this and beyond are invalid
66*4882a593Smuzhiyun };
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun // ----------------------------------------------------------------------------
69*4882a593Smuzhiyun // The following enumeration defines the constants written to the card's
70*4882a593Smuzhiyun // host-to-card doorbell to initiate a command.
71*4882a593Smuzhiyun // ----------------------------------------------------------------------------
72*4882a593Smuzhiyun enum korg1212_dbcnst {
73*4882a593Smuzhiyun    K1212_DB_RequestForData        = 0,    // sent by the card to request a buffer fill.
74*4882a593Smuzhiyun    K1212_DB_TriggerPlay           = 1,    // starts playback/record on the card.
75*4882a593Smuzhiyun    K1212_DB_SelectPlayMode        = 2,    // select monitor, playback setup, or stop.
76*4882a593Smuzhiyun    K1212_DB_ConfigureBufferMemory = 3,    // tells card where the host audio buffers are.
77*4882a593Smuzhiyun    K1212_DB_RequestAdatTimecode   = 4,    // asks the card for the latest ADAT timecode value.
78*4882a593Smuzhiyun    K1212_DB_SetClockSourceRate    = 5,    // sets the clock source and rate for the card.
79*4882a593Smuzhiyun    K1212_DB_ConfigureMiscMemory   = 6,    // tells card where other buffers are.
80*4882a593Smuzhiyun    K1212_DB_TriggerFromAdat       = 7,    // tells card to trigger from Adat at a specific
81*4882a593Smuzhiyun                                           //    timecode value.
82*4882a593Smuzhiyun    K1212_DB_DMAERROR              = 0x80, // DMA Error - the PCI bus is congestioned.
83*4882a593Smuzhiyun    K1212_DB_CARDSTOPPED           = 0x81, // Card has stopped by user request.
84*4882a593Smuzhiyun    K1212_DB_RebootCard            = 0xA0, // instructs the card to reboot.
85*4882a593Smuzhiyun    K1212_DB_BootFromDSPPage4      = 0xA4, // instructs the card to boot from the DSP microcode
86*4882a593Smuzhiyun                                           //    on page 4 (local page to card).
87*4882a593Smuzhiyun    K1212_DB_DSPDownloadDone       = 0xAE, // sent by the card to indicate the download has
88*4882a593Smuzhiyun                                           //    completed.
89*4882a593Smuzhiyun    K1212_DB_StartDSPDownload      = 0xAF  // tells the card to download its DSP firmware.
90*4882a593Smuzhiyun };
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun // ----------------------------------------------------------------------------
94*4882a593Smuzhiyun // The following enumeration defines return codes
95*4882a593Smuzhiyun // to the Korg 1212 I/O driver.
96*4882a593Smuzhiyun // ----------------------------------------------------------------------------
97*4882a593Smuzhiyun enum snd_korg1212rc {
98*4882a593Smuzhiyun    K1212_CMDRET_Success         = 0,   // command was successfully placed
99*4882a593Smuzhiyun    K1212_CMDRET_DIOCFailure,           // the DeviceIoControl call failed
100*4882a593Smuzhiyun    K1212_CMDRET_PMFailure,             // the protected mode call failed
101*4882a593Smuzhiyun    K1212_CMDRET_FailUnspecified,       // unspecified failure
102*4882a593Smuzhiyun    K1212_CMDRET_FailBadState,          // the specified command can not be given in
103*4882a593Smuzhiyun                                        //    the card's current state. (or the wave device's
104*4882a593Smuzhiyun                                        //    state)
105*4882a593Smuzhiyun    K1212_CMDRET_CardUninitialized,     // the card is uninitialized and cannot be used
106*4882a593Smuzhiyun    K1212_CMDRET_BadIndex,              // an out of range card index was specified
107*4882a593Smuzhiyun    K1212_CMDRET_BadHandle,             // an invalid card handle was specified
108*4882a593Smuzhiyun    K1212_CMDRET_NoFillRoutine,         // a play request has been made before a fill routine set
109*4882a593Smuzhiyun    K1212_CMDRET_FillRoutineInUse,      // can't set a new fill routine while one is in use
110*4882a593Smuzhiyun    K1212_CMDRET_NoAckFromCard,         // the card never acknowledged a command
111*4882a593Smuzhiyun    K1212_CMDRET_BadParams,             // bad parameters were provided by the caller
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun    K1212_CMDRET_BadDevice,             // the specified wave device was out of range
114*4882a593Smuzhiyun    K1212_CMDRET_BadFormat              // the specified wave format is unsupported
115*4882a593Smuzhiyun };
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun // ----------------------------------------------------------------------------
118*4882a593Smuzhiyun // The following enumeration defines the constants used to select the play
119*4882a593Smuzhiyun // mode for the card in the SelectPlayMode command.
120*4882a593Smuzhiyun // ----------------------------------------------------------------------------
121*4882a593Smuzhiyun enum PlayModeSelector {
122*4882a593Smuzhiyun    K1212_MODE_SetupPlay  = 0x00000001,     // provides card with pre-play information
123*4882a593Smuzhiyun    K1212_MODE_MonitorOn  = 0x00000002,     // tells card to turn on monitor mode
124*4882a593Smuzhiyun    K1212_MODE_MonitorOff = 0x00000004,     // tells card to turn off monitor mode
125*4882a593Smuzhiyun    K1212_MODE_StopPlay   = 0x00000008      // stops playback on the card
126*4882a593Smuzhiyun };
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun // ----------------------------------------------------------------------------
129*4882a593Smuzhiyun // The following enumeration defines the constants used to select the monitor
130*4882a593Smuzhiyun // mode for the card in the SetMonitorMode command.
131*4882a593Smuzhiyun // ----------------------------------------------------------------------------
132*4882a593Smuzhiyun enum MonitorModeSelector {
133*4882a593Smuzhiyun    K1212_MONMODE_Off  = 0,     // tells card to turn off monitor mode
134*4882a593Smuzhiyun    K1212_MONMODE_On            // tells card to turn on monitor mode
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun #define MAILBOX0_OFFSET      0x40	// location of mailbox 0 relative to base address
138*4882a593Smuzhiyun #define MAILBOX1_OFFSET      0x44	// location of mailbox 1 relative to base address
139*4882a593Smuzhiyun #define MAILBOX2_OFFSET      0x48	// location of mailbox 2 relative to base address
140*4882a593Smuzhiyun #define MAILBOX3_OFFSET      0x4c	// location of mailbox 3 relative to base address
141*4882a593Smuzhiyun #define OUT_DOORBELL_OFFSET  0x60	// location of PCI to local doorbell
142*4882a593Smuzhiyun #define IN_DOORBELL_OFFSET   0x64	// location of local to PCI doorbell
143*4882a593Smuzhiyun #define STATUS_REG_OFFSET    0x68	// location of interrupt control/status register
144*4882a593Smuzhiyun #define PCI_CONTROL_OFFSET   0x6c	// location of the EEPROM, PCI, User I/O, init control
145*4882a593Smuzhiyun 					//    register
146*4882a593Smuzhiyun #define SENS_CONTROL_OFFSET  0x6e	// location of the input sensitivity setting register.
147*4882a593Smuzhiyun 					//    this is the upper word of the PCI control reg.
148*4882a593Smuzhiyun #define DEV_VEND_ID_OFFSET   0x70	// location of the device and vendor ID register
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun #define MAX_COMMAND_RETRIES  5         // maximum number of times the driver will attempt
151*4882a593Smuzhiyun                                        //    to send a command before giving up.
152*4882a593Smuzhiyun #define COMMAND_ACK_MASK     0x8000    // the MSB is set in the command acknowledgment from
153*4882a593Smuzhiyun                                         //    the card.
154*4882a593Smuzhiyun #define DOORBELL_VAL_MASK    0x00FF    // the doorbell value is one byte
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun #define CARD_BOOT_DELAY_IN_MS  10
157*4882a593Smuzhiyun #define CARD_BOOT_TIMEOUT      10
158*4882a593Smuzhiyun #define DSP_BOOT_DELAY_IN_MS   200
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun #define kNumBuffers		8
161*4882a593Smuzhiyun #define k1212MaxCards		4
162*4882a593Smuzhiyun #define k1212NumWaveDevices	6
163*4882a593Smuzhiyun #define k16BitChannels		10
164*4882a593Smuzhiyun #define k32BitChannels		2
165*4882a593Smuzhiyun #define kAudioChannels		(k16BitChannels + k32BitChannels)
166*4882a593Smuzhiyun #define kPlayBufferFrames	1024
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun #define K1212_ANALOG_CHANNELS	2
169*4882a593Smuzhiyun #define K1212_SPDIF_CHANNELS	2
170*4882a593Smuzhiyun #define K1212_ADAT_CHANNELS	8
171*4882a593Smuzhiyun #define K1212_CHANNELS		(K1212_ADAT_CHANNELS + K1212_ANALOG_CHANNELS)
172*4882a593Smuzhiyun #define K1212_MIN_CHANNELS	1
173*4882a593Smuzhiyun #define K1212_MAX_CHANNELS	K1212_CHANNELS
174*4882a593Smuzhiyun #define K1212_FRAME_SIZE        (sizeof(struct KorgAudioFrame))
175*4882a593Smuzhiyun #define K1212_MAX_SAMPLES	(kPlayBufferFrames*kNumBuffers)
176*4882a593Smuzhiyun #define K1212_PERIODS		(kNumBuffers)
177*4882a593Smuzhiyun #define K1212_PERIOD_BYTES	(K1212_FRAME_SIZE*kPlayBufferFrames)
178*4882a593Smuzhiyun #define K1212_BUF_SIZE          (K1212_PERIOD_BYTES*kNumBuffers)
179*4882a593Smuzhiyun #define K1212_ANALOG_BUF_SIZE	(K1212_ANALOG_CHANNELS * 2 * kPlayBufferFrames * kNumBuffers)
180*4882a593Smuzhiyun #define K1212_SPDIF_BUF_SIZE	(K1212_SPDIF_CHANNELS * 3 * kPlayBufferFrames * kNumBuffers)
181*4882a593Smuzhiyun #define K1212_ADAT_BUF_SIZE	(K1212_ADAT_CHANNELS * 2 * kPlayBufferFrames * kNumBuffers)
182*4882a593Smuzhiyun #define K1212_MAX_BUF_SIZE	(K1212_ANALOG_BUF_SIZE + K1212_ADAT_BUF_SIZE)
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun #define k1212MinADCSens     0x00
185*4882a593Smuzhiyun #define k1212MaxADCSens     0x7f
186*4882a593Smuzhiyun #define k1212MaxVolume      0x7fff
187*4882a593Smuzhiyun #define k1212MaxWaveVolume  0xffff
188*4882a593Smuzhiyun #define k1212MinVolume      0x0000
189*4882a593Smuzhiyun #define k1212MaxVolInverted 0x8000
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun // -----------------------------------------------------------------
192*4882a593Smuzhiyun // the following bits are used for controlling interrupts in the
193*4882a593Smuzhiyun // interrupt control/status reg
194*4882a593Smuzhiyun // -----------------------------------------------------------------
195*4882a593Smuzhiyun #define  PCI_INT_ENABLE_BIT               0x00000100
196*4882a593Smuzhiyun #define  PCI_DOORBELL_INT_ENABLE_BIT      0x00000200
197*4882a593Smuzhiyun #define  LOCAL_INT_ENABLE_BIT             0x00010000
198*4882a593Smuzhiyun #define  LOCAL_DOORBELL_INT_ENABLE_BIT    0x00020000
199*4882a593Smuzhiyun #define  LOCAL_DMA1_INT_ENABLE_BIT        0x00080000
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun // -----------------------------------------------------------------
202*4882a593Smuzhiyun // the following bits are defined for the PCI command register
203*4882a593Smuzhiyun // -----------------------------------------------------------------
204*4882a593Smuzhiyun #define  PCI_CMD_MEM_SPACE_ENABLE_BIT     0x0002
205*4882a593Smuzhiyun #define  PCI_CMD_IO_SPACE_ENABLE_BIT      0x0001
206*4882a593Smuzhiyun #define  PCI_CMD_BUS_MASTER_ENABLE_BIT    0x0004
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun // -----------------------------------------------------------------
209*4882a593Smuzhiyun // the following bits are defined for the PCI status register
210*4882a593Smuzhiyun // -----------------------------------------------------------------
211*4882a593Smuzhiyun #define  PCI_STAT_PARITY_ERROR_BIT        0x8000
212*4882a593Smuzhiyun #define  PCI_STAT_SYSTEM_ERROR_BIT        0x4000
213*4882a593Smuzhiyun #define  PCI_STAT_MASTER_ABORT_RCVD_BIT   0x2000
214*4882a593Smuzhiyun #define  PCI_STAT_TARGET_ABORT_RCVD_BIT   0x1000
215*4882a593Smuzhiyun #define  PCI_STAT_TARGET_ABORT_SENT_BIT   0x0800
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun // ------------------------------------------------------------------------
218*4882a593Smuzhiyun // the following constants are used in setting the 1212 I/O card's input
219*4882a593Smuzhiyun // sensitivity.
220*4882a593Smuzhiyun // ------------------------------------------------------------------------
221*4882a593Smuzhiyun #define  SET_SENS_LOCALINIT_BITPOS        15
222*4882a593Smuzhiyun #define  SET_SENS_DATA_BITPOS             10
223*4882a593Smuzhiyun #define  SET_SENS_CLOCK_BITPOS            8
224*4882a593Smuzhiyun #define  SET_SENS_LOADSHIFT_BITPOS        0
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun #define  SET_SENS_LEFTCHANID              0x00
227*4882a593Smuzhiyun #define  SET_SENS_RIGHTCHANID             0x01
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun #define  K1212SENSUPDATE_DELAY_IN_MS      50
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun // --------------------------------------------------------------------------
232*4882a593Smuzhiyun // WaitRTCTicks
233*4882a593Smuzhiyun //
234*4882a593Smuzhiyun //    This function waits the specified number of real time clock ticks.
235*4882a593Smuzhiyun //    According to the DDK, each tick is ~0.8 microseconds.
236*4882a593Smuzhiyun //    The defines following the function declaration can be used for the
237*4882a593Smuzhiyun //    numTicksToWait parameter.
238*4882a593Smuzhiyun // --------------------------------------------------------------------------
239*4882a593Smuzhiyun #define ONE_RTC_TICK         1
240*4882a593Smuzhiyun #define SENSCLKPULSE_WIDTH   4
241*4882a593Smuzhiyun #define LOADSHIFT_DELAY      4
242*4882a593Smuzhiyun #define INTERCOMMAND_DELAY  40
243*4882a593Smuzhiyun #define STOPCARD_DELAY      300        // max # RTC ticks for the card to stop once we write
244*4882a593Smuzhiyun                                        //    the command register.  (could be up to 180 us)
245*4882a593Smuzhiyun #define COMMAND_ACK_DELAY   13         // number of RTC ticks to wait for an acknowledgement
246*4882a593Smuzhiyun                                        //    from the card after sending a command.
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun enum ClockSourceIndex {
249*4882a593Smuzhiyun    K1212_CLKIDX_AdatAt44_1K = 0,    // selects source as ADAT at 44.1 kHz
250*4882a593Smuzhiyun    K1212_CLKIDX_AdatAt48K,          // selects source as ADAT at 48 kHz
251*4882a593Smuzhiyun    K1212_CLKIDX_WordAt44_1K,        // selects source as S/PDIF at 44.1 kHz
252*4882a593Smuzhiyun    K1212_CLKIDX_WordAt48K,          // selects source as S/PDIF at 48 kHz
253*4882a593Smuzhiyun    K1212_CLKIDX_LocalAt44_1K,       // selects source as local clock at 44.1 kHz
254*4882a593Smuzhiyun    K1212_CLKIDX_LocalAt48K,         // selects source as local clock at 48 kHz
255*4882a593Smuzhiyun    K1212_CLKIDX_Invalid             // used to check validity of the index
256*4882a593Smuzhiyun };
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun enum ClockSourceType {
259*4882a593Smuzhiyun    K1212_CLKIDX_Adat = 0,    // selects source as ADAT
260*4882a593Smuzhiyun    K1212_CLKIDX_Word,        // selects source as S/PDIF
261*4882a593Smuzhiyun    K1212_CLKIDX_Local        // selects source as local clock
262*4882a593Smuzhiyun };
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun struct KorgAudioFrame {
265*4882a593Smuzhiyun 	u16 frameData16[k16BitChannels]; /* channels 0-9 use 16 bit samples */
266*4882a593Smuzhiyun 	u32 frameData32[k32BitChannels]; /* channels 10-11 use 32 bits - only 20 are sent across S/PDIF */
267*4882a593Smuzhiyun 	u32 timeCodeVal; /* holds the ADAT timecode value */
268*4882a593Smuzhiyun };
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun struct KorgAudioBuffer {
271*4882a593Smuzhiyun 	struct KorgAudioFrame  bufferData[kPlayBufferFrames];     /* buffer definition */
272*4882a593Smuzhiyun };
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun struct KorgSharedBuffer {
275*4882a593Smuzhiyun #ifdef K1212_LARGEALLOC
276*4882a593Smuzhiyun    struct KorgAudioBuffer   playDataBufs[kNumBuffers];
277*4882a593Smuzhiyun    struct KorgAudioBuffer   recordDataBufs[kNumBuffers];
278*4882a593Smuzhiyun #endif
279*4882a593Smuzhiyun    short             volumeData[kAudioChannels];
280*4882a593Smuzhiyun    u32               cardCommand;
281*4882a593Smuzhiyun    u16               routeData [kAudioChannels];
282*4882a593Smuzhiyun    u32               AdatTimeCode;                 // ADAT timecode value
283*4882a593Smuzhiyun };
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun struct SensBits {
286*4882a593Smuzhiyun    union {
287*4882a593Smuzhiyun       struct {
288*4882a593Smuzhiyun          unsigned int leftChanVal:8;
289*4882a593Smuzhiyun          unsigned int leftChanId:8;
290*4882a593Smuzhiyun       } v;
291*4882a593Smuzhiyun       u16  leftSensBits;
292*4882a593Smuzhiyun    } l;
293*4882a593Smuzhiyun    union {
294*4882a593Smuzhiyun       struct {
295*4882a593Smuzhiyun          unsigned int rightChanVal:8;
296*4882a593Smuzhiyun          unsigned int rightChanId:8;
297*4882a593Smuzhiyun       } v;
298*4882a593Smuzhiyun       u16  rightSensBits;
299*4882a593Smuzhiyun    } r;
300*4882a593Smuzhiyun };
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun struct snd_korg1212 {
303*4882a593Smuzhiyun         struct snd_card *card;
304*4882a593Smuzhiyun         struct pci_dev *pci;
305*4882a593Smuzhiyun         struct snd_pcm *pcm;
306*4882a593Smuzhiyun         int irq;
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun         spinlock_t    lock;
309*4882a593Smuzhiyun 	struct mutex open_mutex;
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	struct timer_list timer;	/* timer callback for checking ack of stop request */
312*4882a593Smuzhiyun 	int stop_pending_cnt;		/* counter for stop pending check */
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun         wait_queue_head_t wait;
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun         unsigned long iomem;
317*4882a593Smuzhiyun         unsigned long ioport;
318*4882a593Smuzhiyun 	unsigned long iomem2;
319*4882a593Smuzhiyun         unsigned long irqcount;
320*4882a593Smuzhiyun         unsigned long inIRQ;
321*4882a593Smuzhiyun         void __iomem *iobase;
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 	struct snd_dma_buffer dma_dsp;
324*4882a593Smuzhiyun         struct snd_dma_buffer dma_play;
325*4882a593Smuzhiyun         struct snd_dma_buffer dma_rec;
326*4882a593Smuzhiyun 	struct snd_dma_buffer dma_shared;
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 	u32 DataBufsSize;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun         struct KorgAudioBuffer  * playDataBufsPtr;
331*4882a593Smuzhiyun         struct KorgAudioBuffer  * recordDataBufsPtr;
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	struct KorgSharedBuffer * sharedBufferPtr;
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	u32 RecDataPhy;
336*4882a593Smuzhiyun 	u32 PlayDataPhy;
337*4882a593Smuzhiyun 	unsigned long sharedBufferPhy;
338*4882a593Smuzhiyun 	u32 VolumeTablePhy;
339*4882a593Smuzhiyun 	u32 RoutingTablePhy;
340*4882a593Smuzhiyun 	u32 AdatTimeCodePhy;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun         u32 __iomem * statusRegPtr;	     // address of the interrupt status/control register
343*4882a593Smuzhiyun         u32 __iomem * outDoorbellPtr;	     // address of the host->card doorbell register
344*4882a593Smuzhiyun         u32 __iomem * inDoorbellPtr;	     // address of the card->host doorbell register
345*4882a593Smuzhiyun         u32 __iomem * mailbox0Ptr;	     // address of mailbox 0 on the card
346*4882a593Smuzhiyun         u32 __iomem * mailbox1Ptr;	     // address of mailbox 1 on the card
347*4882a593Smuzhiyun         u32 __iomem * mailbox2Ptr;	     // address of mailbox 2 on the card
348*4882a593Smuzhiyun         u32 __iomem * mailbox3Ptr;	     // address of mailbox 3 on the card
349*4882a593Smuzhiyun         u32 __iomem * controlRegPtr;	     // address of the EEPROM, PCI, I/O, Init ctrl reg
350*4882a593Smuzhiyun         u16 __iomem * sensRegPtr;	     // address of the sensitivity setting register
351*4882a593Smuzhiyun         u32 __iomem * idRegPtr;		     // address of the device and vendor ID registers
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun         size_t periodsize;
354*4882a593Smuzhiyun 	int channels;
355*4882a593Smuzhiyun         int currentBuffer;
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun         struct snd_pcm_substream *playback_substream;
358*4882a593Smuzhiyun         struct snd_pcm_substream *capture_substream;
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 	pid_t capture_pid;
361*4882a593Smuzhiyun 	pid_t playback_pid;
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun  	enum CardState cardState;
364*4882a593Smuzhiyun         int running;
365*4882a593Smuzhiyun         int idleMonitorOn;           // indicates whether the card is in idle monitor mode.
366*4882a593Smuzhiyun         u32 cmdRetryCount;           // tracks how many times we have retried sending to the card.
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun         enum ClockSourceIndex clkSrcRate; // sample rate and clock source
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun         enum ClockSourceType clkSource;   // clock source
371*4882a593Smuzhiyun         int clkRate;                 // clock rate
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun         int volumePhase[kAudioChannels];
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun         u16 leftADCInSens;           // ADC left channel input sensitivity
376*4882a593Smuzhiyun         u16 rightADCInSens;          // ADC right channel input sensitivity
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	int opencnt;		     // Open/Close count
379*4882a593Smuzhiyun 	int setcnt;		     // SetupForPlay count
380*4882a593Smuzhiyun 	int playcnt;		     // TriggerPlay count
381*4882a593Smuzhiyun 	int errorcnt;		     // Error Count
382*4882a593Smuzhiyun 	unsigned long totalerrorcnt; // Total Error Count
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 	int dsp_is_loaded;
385*4882a593Smuzhiyun 	int dsp_stop_is_processed;
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun };
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun MODULE_DESCRIPTION("korg1212");
390*4882a593Smuzhiyun MODULE_LICENSE("GPL");
391*4882a593Smuzhiyun MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}");
392*4882a593Smuzhiyun MODULE_FIRMWARE("korg/k1212.dsp");
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
395*4882a593Smuzhiyun static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	   /* ID for this card */
396*4882a593Smuzhiyun static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun module_param_array(index, int, NULL, 0444);
399*4882a593Smuzhiyun MODULE_PARM_DESC(index, "Index value for Korg 1212 soundcard.");
400*4882a593Smuzhiyun module_param_array(id, charp, NULL, 0444);
401*4882a593Smuzhiyun MODULE_PARM_DESC(id, "ID string for Korg 1212 soundcard.");
402*4882a593Smuzhiyun module_param_array(enable, bool, NULL, 0444);
403*4882a593Smuzhiyun MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard.");
404*4882a593Smuzhiyun MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>");
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun static const struct pci_device_id snd_korg1212_ids[] = {
407*4882a593Smuzhiyun 	{
408*4882a593Smuzhiyun 		.vendor	   = 0x10b5,
409*4882a593Smuzhiyun 		.device	   = 0x906d,
410*4882a593Smuzhiyun 		.subvendor = PCI_ANY_ID,
411*4882a593Smuzhiyun 		.subdevice = PCI_ANY_ID,
412*4882a593Smuzhiyun 	},
413*4882a593Smuzhiyun 	{ 0, },
414*4882a593Smuzhiyun };
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, snd_korg1212_ids);
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun static const char * const stateName[] = {
419*4882a593Smuzhiyun 	"Non-existent",
420*4882a593Smuzhiyun 	"Uninitialized",
421*4882a593Smuzhiyun 	"DSP download in process",
422*4882a593Smuzhiyun 	"DSP download complete",
423*4882a593Smuzhiyun 	"Ready",
424*4882a593Smuzhiyun 	"Open",
425*4882a593Smuzhiyun 	"Setup for play",
426*4882a593Smuzhiyun 	"Playing",
427*4882a593Smuzhiyun 	"Monitor mode on",
428*4882a593Smuzhiyun 	"Calibrating",
429*4882a593Smuzhiyun 	"Invalid"
430*4882a593Smuzhiyun };
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun static const char * const clockSourceTypeName[] = { "ADAT", "S/PDIF", "local" };
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun static const char * const clockSourceName[] = {
435*4882a593Smuzhiyun 	"ADAT at 44.1 kHz",
436*4882a593Smuzhiyun 	"ADAT at 48 kHz",
437*4882a593Smuzhiyun 	"S/PDIF at 44.1 kHz",
438*4882a593Smuzhiyun 	"S/PDIF at 48 kHz",
439*4882a593Smuzhiyun 	"local clock at 44.1 kHz",
440*4882a593Smuzhiyun 	"local clock at 48 kHz"
441*4882a593Smuzhiyun };
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun static const char * const channelName[] = {
444*4882a593Smuzhiyun 	"ADAT-1",
445*4882a593Smuzhiyun 	"ADAT-2",
446*4882a593Smuzhiyun 	"ADAT-3",
447*4882a593Smuzhiyun 	"ADAT-4",
448*4882a593Smuzhiyun 	"ADAT-5",
449*4882a593Smuzhiyun 	"ADAT-6",
450*4882a593Smuzhiyun 	"ADAT-7",
451*4882a593Smuzhiyun 	"ADAT-8",
452*4882a593Smuzhiyun 	"Analog-L",
453*4882a593Smuzhiyun 	"Analog-R",
454*4882a593Smuzhiyun 	"SPDIF-L",
455*4882a593Smuzhiyun 	"SPDIF-R",
456*4882a593Smuzhiyun };
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun static const u16 ClockSourceSelector[] = {
459*4882a593Smuzhiyun 	0x8000,   // selects source as ADAT at 44.1 kHz
460*4882a593Smuzhiyun 	0x0000,   // selects source as ADAT at 48 kHz
461*4882a593Smuzhiyun 	0x8001,   // selects source as S/PDIF at 44.1 kHz
462*4882a593Smuzhiyun 	0x0001,   // selects source as S/PDIF at 48 kHz
463*4882a593Smuzhiyun 	0x8002,   // selects source as local clock at 44.1 kHz
464*4882a593Smuzhiyun 	0x0002    // selects source as local clock at 48 kHz
465*4882a593Smuzhiyun };
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun union swap_u32 { unsigned char c[4]; u32 i; };
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun #ifdef SNDRV_BIG_ENDIAN
LowerWordSwap(u32 swappee)470*4882a593Smuzhiyun static u32 LowerWordSwap(u32 swappee)
471*4882a593Smuzhiyun #else
472*4882a593Smuzhiyun static u32 UpperWordSwap(u32 swappee)
473*4882a593Smuzhiyun #endif
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun    union swap_u32 retVal, swapper;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun    swapper.i = swappee;
478*4882a593Smuzhiyun    retVal.c[2] = swapper.c[3];
479*4882a593Smuzhiyun    retVal.c[3] = swapper.c[2];
480*4882a593Smuzhiyun    retVal.c[1] = swapper.c[1];
481*4882a593Smuzhiyun    retVal.c[0] = swapper.c[0];
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun    return retVal.i;
484*4882a593Smuzhiyun }
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun #ifdef SNDRV_BIG_ENDIAN
UpperWordSwap(u32 swappee)487*4882a593Smuzhiyun static u32 UpperWordSwap(u32 swappee)
488*4882a593Smuzhiyun #else
489*4882a593Smuzhiyun static u32 LowerWordSwap(u32 swappee)
490*4882a593Smuzhiyun #endif
491*4882a593Smuzhiyun {
492*4882a593Smuzhiyun    union swap_u32 retVal, swapper;
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun    swapper.i = swappee;
495*4882a593Smuzhiyun    retVal.c[2] = swapper.c[2];
496*4882a593Smuzhiyun    retVal.c[3] = swapper.c[3];
497*4882a593Smuzhiyun    retVal.c[1] = swapper.c[0];
498*4882a593Smuzhiyun    retVal.c[0] = swapper.c[1];
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun    return retVal.i;
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun #define SetBitInWord(theWord,bitPosition)       (*theWord) |= (0x0001 << bitPosition)
504*4882a593Smuzhiyun #define SetBitInDWord(theWord,bitPosition)      (*theWord) |= (0x00000001 << bitPosition)
505*4882a593Smuzhiyun #define ClearBitInWord(theWord,bitPosition)     (*theWord) &= ~(0x0001 << bitPosition)
506*4882a593Smuzhiyun #define ClearBitInDWord(theWord,bitPosition)    (*theWord) &= ~(0x00000001 << bitPosition)
507*4882a593Smuzhiyun 
snd_korg1212_Send1212Command(struct snd_korg1212 * korg1212,enum korg1212_dbcnst doorbellVal,u32 mailBox0Val,u32 mailBox1Val,u32 mailBox2Val,u32 mailBox3Val)508*4882a593Smuzhiyun static int snd_korg1212_Send1212Command(struct snd_korg1212 *korg1212,
509*4882a593Smuzhiyun 					enum korg1212_dbcnst doorbellVal,
510*4882a593Smuzhiyun 					u32 mailBox0Val, u32 mailBox1Val,
511*4882a593Smuzhiyun 					u32 mailBox2Val, u32 mailBox3Val)
512*4882a593Smuzhiyun {
513*4882a593Smuzhiyun         u32 retryCount;
514*4882a593Smuzhiyun         u16 mailBox3Lo;
515*4882a593Smuzhiyun 	int rc = K1212_CMDRET_Success;
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun         if (!korg1212->outDoorbellPtr) {
518*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: CardUninitialized\n");
519*4882a593Smuzhiyun                 return K1212_CMDRET_CardUninitialized;
520*4882a593Smuzhiyun 	}
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- 0x%08x 0x%08x [%s]\n",
523*4882a593Smuzhiyun 			   doorbellVal, mailBox0Val, stateName[korg1212->cardState]);
524*4882a593Smuzhiyun         for (retryCount = 0; retryCount < MAX_COMMAND_RETRIES; retryCount++) {
525*4882a593Smuzhiyun 		writel(mailBox3Val, korg1212->mailbox3Ptr);
526*4882a593Smuzhiyun                 writel(mailBox2Val, korg1212->mailbox2Ptr);
527*4882a593Smuzhiyun                 writel(mailBox1Val, korg1212->mailbox1Ptr);
528*4882a593Smuzhiyun                 writel(mailBox0Val, korg1212->mailbox0Ptr);
529*4882a593Smuzhiyun                 writel(doorbellVal, korg1212->outDoorbellPtr);  // interrupt the card
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun                 // --------------------------------------------------------------
532*4882a593Smuzhiyun                 // the reboot command will not give an acknowledgement.
533*4882a593Smuzhiyun                 // --------------------------------------------------------------
534*4882a593Smuzhiyun                 if ( doorbellVal == K1212_DB_RebootCard ||
535*4882a593Smuzhiyun                 	doorbellVal == K1212_DB_BootFromDSPPage4 ||
536*4882a593Smuzhiyun                         doorbellVal == K1212_DB_StartDSPDownload ) {
537*4882a593Smuzhiyun                         rc = K1212_CMDRET_Success;
538*4882a593Smuzhiyun                         break;
539*4882a593Smuzhiyun                 }
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun                 // --------------------------------------------------------------
542*4882a593Smuzhiyun                 // See if the card acknowledged the command.  Wait a bit, then
543*4882a593Smuzhiyun                 // read in the low word of mailbox3.  If the MSB is set and the
544*4882a593Smuzhiyun                 // low byte is equal to the doorbell value, then it ack'd.
545*4882a593Smuzhiyun                 // --------------------------------------------------------------
546*4882a593Smuzhiyun                 udelay(COMMAND_ACK_DELAY);
547*4882a593Smuzhiyun                 mailBox3Lo = readl(korg1212->mailbox3Ptr);
548*4882a593Smuzhiyun                 if (mailBox3Lo & COMMAND_ACK_MASK) {
549*4882a593Smuzhiyun                 	if ((mailBox3Lo & DOORBELL_VAL_MASK) == (doorbellVal & DOORBELL_VAL_MASK)) {
550*4882a593Smuzhiyun 				K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Card <- Success\n");
551*4882a593Smuzhiyun                                 rc = K1212_CMDRET_Success;
552*4882a593Smuzhiyun 				break;
553*4882a593Smuzhiyun                         }
554*4882a593Smuzhiyun                 }
555*4882a593Smuzhiyun 	}
556*4882a593Smuzhiyun         korg1212->cmdRetryCount += retryCount;
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun 	if (retryCount >= MAX_COMMAND_RETRIES) {
559*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Card <- NoAckFromCard\n");
560*4882a593Smuzhiyun         	rc = K1212_CMDRET_NoAckFromCard;
561*4882a593Smuzhiyun 	}
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun 	return rc;
564*4882a593Smuzhiyun }
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun /* spinlock already held */
snd_korg1212_SendStop(struct snd_korg1212 * korg1212)567*4882a593Smuzhiyun static void snd_korg1212_SendStop(struct snd_korg1212 *korg1212)
568*4882a593Smuzhiyun {
569*4882a593Smuzhiyun 	if (! korg1212->stop_pending_cnt) {
570*4882a593Smuzhiyun 		korg1212->sharedBufferPtr->cardCommand = 0xffffffff;
571*4882a593Smuzhiyun 		/* program the timer */
572*4882a593Smuzhiyun 		korg1212->stop_pending_cnt = HZ;
573*4882a593Smuzhiyun 		mod_timer(&korg1212->timer, jiffies + 1);
574*4882a593Smuzhiyun 	}
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun 
snd_korg1212_SendStopAndWait(struct snd_korg1212 * korg1212)577*4882a593Smuzhiyun static void snd_korg1212_SendStopAndWait(struct snd_korg1212 *korg1212)
578*4882a593Smuzhiyun {
579*4882a593Smuzhiyun 	unsigned long flags;
580*4882a593Smuzhiyun 	spin_lock_irqsave(&korg1212->lock, flags);
581*4882a593Smuzhiyun 	korg1212->dsp_stop_is_processed = 0;
582*4882a593Smuzhiyun 	snd_korg1212_SendStop(korg1212);
583*4882a593Smuzhiyun 	spin_unlock_irqrestore(&korg1212->lock, flags);
584*4882a593Smuzhiyun 	wait_event_timeout(korg1212->wait, korg1212->dsp_stop_is_processed, (HZ * 3) / 2);
585*4882a593Smuzhiyun }
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun /* timer callback for checking the ack of stop request */
snd_korg1212_timer_func(struct timer_list * t)588*4882a593Smuzhiyun static void snd_korg1212_timer_func(struct timer_list *t)
589*4882a593Smuzhiyun {
590*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = from_timer(korg1212, t, timer);
591*4882a593Smuzhiyun 	unsigned long flags;
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 	spin_lock_irqsave(&korg1212->lock, flags);
594*4882a593Smuzhiyun 	if (korg1212->sharedBufferPtr->cardCommand == 0) {
595*4882a593Smuzhiyun 		/* ack'ed */
596*4882a593Smuzhiyun 		korg1212->stop_pending_cnt = 0;
597*4882a593Smuzhiyun 		korg1212->dsp_stop_is_processed = 1;
598*4882a593Smuzhiyun 		wake_up(&korg1212->wait);
599*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Stop ack'ed [%s]\n",
600*4882a593Smuzhiyun 					   stateName[korg1212->cardState]);
601*4882a593Smuzhiyun 	} else {
602*4882a593Smuzhiyun 		if (--korg1212->stop_pending_cnt > 0) {
603*4882a593Smuzhiyun 			/* reprogram timer */
604*4882a593Smuzhiyun 			mod_timer(&korg1212->timer, jiffies + 1);
605*4882a593Smuzhiyun 		} else {
606*4882a593Smuzhiyun 			snd_printd("korg1212_timer_func timeout\n");
607*4882a593Smuzhiyun 			korg1212->sharedBufferPtr->cardCommand = 0;
608*4882a593Smuzhiyun 			korg1212->dsp_stop_is_processed = 1;
609*4882a593Smuzhiyun 			wake_up(&korg1212->wait);
610*4882a593Smuzhiyun 			K1212_DEBUG_PRINTK("K1212_DEBUG: Stop timeout [%s]\n",
611*4882a593Smuzhiyun 					   stateName[korg1212->cardState]);
612*4882a593Smuzhiyun 		}
613*4882a593Smuzhiyun 	}
614*4882a593Smuzhiyun 	spin_unlock_irqrestore(&korg1212->lock, flags);
615*4882a593Smuzhiyun }
616*4882a593Smuzhiyun 
snd_korg1212_TurnOnIdleMonitor(struct snd_korg1212 * korg1212)617*4882a593Smuzhiyun static int snd_korg1212_TurnOnIdleMonitor(struct snd_korg1212 *korg1212)
618*4882a593Smuzhiyun {
619*4882a593Smuzhiyun 	unsigned long flags;
620*4882a593Smuzhiyun 	int rc;
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun         udelay(INTERCOMMAND_DELAY);
623*4882a593Smuzhiyun 	spin_lock_irqsave(&korg1212->lock, flags);
624*4882a593Smuzhiyun         korg1212->idleMonitorOn = 1;
625*4882a593Smuzhiyun         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
626*4882a593Smuzhiyun 					  K1212_MODE_MonitorOn, 0, 0, 0);
627*4882a593Smuzhiyun         spin_unlock_irqrestore(&korg1212->lock, flags);
628*4882a593Smuzhiyun 	return rc;
629*4882a593Smuzhiyun }
630*4882a593Smuzhiyun 
snd_korg1212_TurnOffIdleMonitor(struct snd_korg1212 * korg1212)631*4882a593Smuzhiyun static void snd_korg1212_TurnOffIdleMonitor(struct snd_korg1212 *korg1212)
632*4882a593Smuzhiyun {
633*4882a593Smuzhiyun         if (korg1212->idleMonitorOn) {
634*4882a593Smuzhiyun 		snd_korg1212_SendStopAndWait(korg1212);
635*4882a593Smuzhiyun                 korg1212->idleMonitorOn = 0;
636*4882a593Smuzhiyun         }
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun 
snd_korg1212_setCardState(struct snd_korg1212 * korg1212,enum CardState csState)639*4882a593Smuzhiyun static inline void snd_korg1212_setCardState(struct snd_korg1212 * korg1212, enum CardState csState)
640*4882a593Smuzhiyun {
641*4882a593Smuzhiyun         korg1212->cardState = csState;
642*4882a593Smuzhiyun }
643*4882a593Smuzhiyun 
snd_korg1212_OpenCard(struct snd_korg1212 * korg1212)644*4882a593Smuzhiyun static int snd_korg1212_OpenCard(struct snd_korg1212 * korg1212)
645*4882a593Smuzhiyun {
646*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s] %d\n",
647*4882a593Smuzhiyun 			   stateName[korg1212->cardState], korg1212->opencnt);
648*4882a593Smuzhiyun 	mutex_lock(&korg1212->open_mutex);
649*4882a593Smuzhiyun         if (korg1212->opencnt++ == 0) {
650*4882a593Smuzhiyun 		snd_korg1212_TurnOffIdleMonitor(korg1212);
651*4882a593Smuzhiyun 		snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
652*4882a593Smuzhiyun 	}
653*4882a593Smuzhiyun 
654*4882a593Smuzhiyun 	mutex_unlock(&korg1212->open_mutex);
655*4882a593Smuzhiyun         return 1;
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun 
snd_korg1212_CloseCard(struct snd_korg1212 * korg1212)658*4882a593Smuzhiyun static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212)
659*4882a593Smuzhiyun {
660*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s] %d\n",
661*4882a593Smuzhiyun 			   stateName[korg1212->cardState], korg1212->opencnt);
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 	mutex_lock(&korg1212->open_mutex);
664*4882a593Smuzhiyun 	if (--(korg1212->opencnt)) {
665*4882a593Smuzhiyun 		mutex_unlock(&korg1212->open_mutex);
666*4882a593Smuzhiyun 		return 0;
667*4882a593Smuzhiyun 	}
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun         if (korg1212->cardState == K1212_STATE_SETUP) {
670*4882a593Smuzhiyun                 int rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
671*4882a593Smuzhiyun                                 K1212_MODE_StopPlay, 0, 0, 0);
672*4882a593Smuzhiyun 		if (rc)
673*4882a593Smuzhiyun 			K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard - RC = %d [%s]\n",
674*4882a593Smuzhiyun 					   rc, stateName[korg1212->cardState]);
675*4882a593Smuzhiyun 		if (rc != K1212_CMDRET_Success) {
676*4882a593Smuzhiyun 			mutex_unlock(&korg1212->open_mutex);
677*4882a593Smuzhiyun                         return 0;
678*4882a593Smuzhiyun 		}
679*4882a593Smuzhiyun         } else if (korg1212->cardState > K1212_STATE_SETUP) {
680*4882a593Smuzhiyun 		snd_korg1212_SendStopAndWait(korg1212);
681*4882a593Smuzhiyun         }
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun         if (korg1212->cardState > K1212_STATE_READY) {
684*4882a593Smuzhiyun 		snd_korg1212_TurnOnIdleMonitor(korg1212);
685*4882a593Smuzhiyun                 snd_korg1212_setCardState(korg1212, K1212_STATE_READY);
686*4882a593Smuzhiyun 	}
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 	mutex_unlock(&korg1212->open_mutex);
689*4882a593Smuzhiyun         return 0;
690*4882a593Smuzhiyun }
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun /* spinlock already held */
snd_korg1212_SetupForPlay(struct snd_korg1212 * korg1212)693*4882a593Smuzhiyun static int snd_korg1212_SetupForPlay(struct snd_korg1212 * korg1212)
694*4882a593Smuzhiyun {
695*4882a593Smuzhiyun 	int rc;
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay [%s] %d\n",
698*4882a593Smuzhiyun 			   stateName[korg1212->cardState], korg1212->setcnt);
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun         if (korg1212->setcnt++)
701*4882a593Smuzhiyun 		return 0;
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun         snd_korg1212_setCardState(korg1212, K1212_STATE_SETUP);
704*4882a593Smuzhiyun         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
705*4882a593Smuzhiyun                                         K1212_MODE_SetupPlay, 0, 0, 0);
706*4882a593Smuzhiyun 	if (rc)
707*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay - RC = %d [%s]\n",
708*4882a593Smuzhiyun 				   rc, stateName[korg1212->cardState]);
709*4882a593Smuzhiyun         if (rc != K1212_CMDRET_Success) {
710*4882a593Smuzhiyun                 return 1;
711*4882a593Smuzhiyun         }
712*4882a593Smuzhiyun         return 0;
713*4882a593Smuzhiyun }
714*4882a593Smuzhiyun 
715*4882a593Smuzhiyun /* spinlock already held */
snd_korg1212_TriggerPlay(struct snd_korg1212 * korg1212)716*4882a593Smuzhiyun static int snd_korg1212_TriggerPlay(struct snd_korg1212 * korg1212)
717*4882a593Smuzhiyun {
718*4882a593Smuzhiyun 	int rc;
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: TriggerPlay [%s] %d\n",
721*4882a593Smuzhiyun 			   stateName[korg1212->cardState], korg1212->playcnt);
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun         if (korg1212->playcnt++)
724*4882a593Smuzhiyun 		return 0;
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun         snd_korg1212_setCardState(korg1212, K1212_STATE_PLAYING);
727*4882a593Smuzhiyun         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_TriggerPlay, 0, 0, 0, 0);
728*4882a593Smuzhiyun 	if (rc)
729*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK("K1212_DEBUG: TriggerPlay - RC = %d [%s]\n",
730*4882a593Smuzhiyun 				   rc, stateName[korg1212->cardState]);
731*4882a593Smuzhiyun         if (rc != K1212_CMDRET_Success) {
732*4882a593Smuzhiyun                 return 1;
733*4882a593Smuzhiyun         }
734*4882a593Smuzhiyun         return 0;
735*4882a593Smuzhiyun }
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun /* spinlock already held */
snd_korg1212_StopPlay(struct snd_korg1212 * korg1212)738*4882a593Smuzhiyun static int snd_korg1212_StopPlay(struct snd_korg1212 * korg1212)
739*4882a593Smuzhiyun {
740*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: StopPlay [%s] %d\n",
741*4882a593Smuzhiyun 			   stateName[korg1212->cardState], korg1212->playcnt);
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun         if (--(korg1212->playcnt))
744*4882a593Smuzhiyun 		return 0;
745*4882a593Smuzhiyun 
746*4882a593Smuzhiyun 	korg1212->setcnt = 0;
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun         if (korg1212->cardState != K1212_STATE_ERRORSTOP)
749*4882a593Smuzhiyun 		snd_korg1212_SendStop(korg1212);
750*4882a593Smuzhiyun 
751*4882a593Smuzhiyun 	snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
752*4882a593Smuzhiyun         return 0;
753*4882a593Smuzhiyun }
754*4882a593Smuzhiyun 
snd_korg1212_EnableCardInterrupts(struct snd_korg1212 * korg1212)755*4882a593Smuzhiyun static void snd_korg1212_EnableCardInterrupts(struct snd_korg1212 * korg1212)
756*4882a593Smuzhiyun {
757*4882a593Smuzhiyun 	writel(PCI_INT_ENABLE_BIT            |
758*4882a593Smuzhiyun 	       PCI_DOORBELL_INT_ENABLE_BIT   |
759*4882a593Smuzhiyun 	       LOCAL_INT_ENABLE_BIT          |
760*4882a593Smuzhiyun 	       LOCAL_DOORBELL_INT_ENABLE_BIT |
761*4882a593Smuzhiyun 	       LOCAL_DMA1_INT_ENABLE_BIT,
762*4882a593Smuzhiyun 	       korg1212->statusRegPtr);
763*4882a593Smuzhiyun }
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun #if 0 /* not used */
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun static int snd_korg1212_SetMonitorMode(struct snd_korg1212 *korg1212,
768*4882a593Smuzhiyun 				       enum MonitorModeSelector mode)
769*4882a593Smuzhiyun {
770*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: SetMonitorMode [%s]\n",
771*4882a593Smuzhiyun 			   stateName[korg1212->cardState]);
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun         switch (mode) {
774*4882a593Smuzhiyun 	case K1212_MONMODE_Off:
775*4882a593Smuzhiyun 		if (korg1212->cardState != K1212_STATE_MONITOR)
776*4882a593Smuzhiyun 			return 0;
777*4882a593Smuzhiyun 		else {
778*4882a593Smuzhiyun 			snd_korg1212_SendStopAndWait(korg1212);
779*4882a593Smuzhiyun 			snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
780*4882a593Smuzhiyun 		}
781*4882a593Smuzhiyun 		break;
782*4882a593Smuzhiyun 
783*4882a593Smuzhiyun 	case K1212_MONMODE_On:
784*4882a593Smuzhiyun 		if (korg1212->cardState != K1212_STATE_OPEN)
785*4882a593Smuzhiyun 			return 0;
786*4882a593Smuzhiyun 		else {
787*4882a593Smuzhiyun 			int rc;
788*4882a593Smuzhiyun 			snd_korg1212_setCardState(korg1212, K1212_STATE_MONITOR);
789*4882a593Smuzhiyun 			rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
790*4882a593Smuzhiyun 							  K1212_MODE_MonitorOn, 0, 0, 0);
791*4882a593Smuzhiyun 			if (rc != K1212_CMDRET_Success)
792*4882a593Smuzhiyun 				return 0;
793*4882a593Smuzhiyun 		}
794*4882a593Smuzhiyun 		break;
795*4882a593Smuzhiyun 
796*4882a593Smuzhiyun 	default:
797*4882a593Smuzhiyun 		return 0;
798*4882a593Smuzhiyun         }
799*4882a593Smuzhiyun 
800*4882a593Smuzhiyun         return 1;
801*4882a593Smuzhiyun }
802*4882a593Smuzhiyun 
803*4882a593Smuzhiyun #endif /* not used */
804*4882a593Smuzhiyun 
snd_korg1212_use_is_exclusive(struct snd_korg1212 * korg1212)805*4882a593Smuzhiyun static inline int snd_korg1212_use_is_exclusive(struct snd_korg1212 *korg1212)
806*4882a593Smuzhiyun {
807*4882a593Smuzhiyun 	if (korg1212->playback_pid != korg1212->capture_pid &&
808*4882a593Smuzhiyun 	    korg1212->playback_pid >= 0 && korg1212->capture_pid >= 0)
809*4882a593Smuzhiyun 		return 0;
810*4882a593Smuzhiyun 
811*4882a593Smuzhiyun 	return 1;
812*4882a593Smuzhiyun }
813*4882a593Smuzhiyun 
snd_korg1212_SetRate(struct snd_korg1212 * korg1212,int rate)814*4882a593Smuzhiyun static int snd_korg1212_SetRate(struct snd_korg1212 *korg1212, int rate)
815*4882a593Smuzhiyun {
816*4882a593Smuzhiyun 	static const enum ClockSourceIndex s44[] = {
817*4882a593Smuzhiyun 		K1212_CLKIDX_AdatAt44_1K,
818*4882a593Smuzhiyun 		K1212_CLKIDX_WordAt44_1K,
819*4882a593Smuzhiyun 		K1212_CLKIDX_LocalAt44_1K
820*4882a593Smuzhiyun 	};
821*4882a593Smuzhiyun 	static const enum ClockSourceIndex s48[] = {
822*4882a593Smuzhiyun 		K1212_CLKIDX_AdatAt48K,
823*4882a593Smuzhiyun 		K1212_CLKIDX_WordAt48K,
824*4882a593Smuzhiyun 		K1212_CLKIDX_LocalAt48K
825*4882a593Smuzhiyun 	};
826*4882a593Smuzhiyun         int parm, rc;
827*4882a593Smuzhiyun 
828*4882a593Smuzhiyun 	if (!snd_korg1212_use_is_exclusive (korg1212))
829*4882a593Smuzhiyun 		return -EBUSY;
830*4882a593Smuzhiyun 
831*4882a593Smuzhiyun 	switch (rate) {
832*4882a593Smuzhiyun 	case 44100:
833*4882a593Smuzhiyun 		parm = s44[korg1212->clkSource];
834*4882a593Smuzhiyun 		break;
835*4882a593Smuzhiyun 
836*4882a593Smuzhiyun 	case 48000:
837*4882a593Smuzhiyun 		parm = s48[korg1212->clkSource];
838*4882a593Smuzhiyun 		break;
839*4882a593Smuzhiyun 
840*4882a593Smuzhiyun 	default:
841*4882a593Smuzhiyun 		return -EINVAL;
842*4882a593Smuzhiyun 	}
843*4882a593Smuzhiyun 
844*4882a593Smuzhiyun         korg1212->clkSrcRate = parm;
845*4882a593Smuzhiyun         korg1212->clkRate = rate;
846*4882a593Smuzhiyun 
847*4882a593Smuzhiyun 	udelay(INTERCOMMAND_DELAY);
848*4882a593Smuzhiyun 	rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SetClockSourceRate,
849*4882a593Smuzhiyun 					  ClockSourceSelector[korg1212->clkSrcRate],
850*4882a593Smuzhiyun 					  0, 0, 0);
851*4882a593Smuzhiyun 	if (rc)
852*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK("K1212_DEBUG: Set Clock Source Selector - RC = %d [%s]\n",
853*4882a593Smuzhiyun 				   rc, stateName[korg1212->cardState]);
854*4882a593Smuzhiyun 
855*4882a593Smuzhiyun         return 0;
856*4882a593Smuzhiyun }
857*4882a593Smuzhiyun 
snd_korg1212_SetClockSource(struct snd_korg1212 * korg1212,int source)858*4882a593Smuzhiyun static int snd_korg1212_SetClockSource(struct snd_korg1212 *korg1212, int source)
859*4882a593Smuzhiyun {
860*4882a593Smuzhiyun 
861*4882a593Smuzhiyun 	if (source < 0 || source > 2)
862*4882a593Smuzhiyun 		return -EINVAL;
863*4882a593Smuzhiyun 
864*4882a593Smuzhiyun         korg1212->clkSource = source;
865*4882a593Smuzhiyun 
866*4882a593Smuzhiyun         snd_korg1212_SetRate(korg1212, korg1212->clkRate);
867*4882a593Smuzhiyun 
868*4882a593Smuzhiyun         return 0;
869*4882a593Smuzhiyun }
870*4882a593Smuzhiyun 
snd_korg1212_DisableCardInterrupts(struct snd_korg1212 * korg1212)871*4882a593Smuzhiyun static void snd_korg1212_DisableCardInterrupts(struct snd_korg1212 *korg1212)
872*4882a593Smuzhiyun {
873*4882a593Smuzhiyun 	writel(0, korg1212->statusRegPtr);
874*4882a593Smuzhiyun }
875*4882a593Smuzhiyun 
snd_korg1212_WriteADCSensitivity(struct snd_korg1212 * korg1212)876*4882a593Smuzhiyun static int snd_korg1212_WriteADCSensitivity(struct snd_korg1212 *korg1212)
877*4882a593Smuzhiyun {
878*4882a593Smuzhiyun         struct SensBits  sensVals;
879*4882a593Smuzhiyun         int       bitPosition;
880*4882a593Smuzhiyun         int       channel;
881*4882a593Smuzhiyun         int       clkIs48K;
882*4882a593Smuzhiyun         int       monModeSet;
883*4882a593Smuzhiyun         u16       controlValue;    // this keeps the current value to be written to
884*4882a593Smuzhiyun                                    //  the card's eeprom control register.
885*4882a593Smuzhiyun         u16       count;
886*4882a593Smuzhiyun 	unsigned long flags;
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: WriteADCSensivity [%s]\n",
889*4882a593Smuzhiyun 			   stateName[korg1212->cardState]);
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
892*4882a593Smuzhiyun         // initialize things.  The local init bit is always set when writing to the
893*4882a593Smuzhiyun         // card's control register.
894*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
895*4882a593Smuzhiyun         controlValue = 0;
896*4882a593Smuzhiyun         SetBitInWord(&controlValue, SET_SENS_LOCALINIT_BITPOS);    // init the control value
897*4882a593Smuzhiyun 
898*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
899*4882a593Smuzhiyun         // make sure the card is not in monitor mode when we do this update.
900*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
901*4882a593Smuzhiyun         if (korg1212->cardState == K1212_STATE_MONITOR || korg1212->idleMonitorOn) {
902*4882a593Smuzhiyun                 monModeSet = 1;
903*4882a593Smuzhiyun 		snd_korg1212_SendStopAndWait(korg1212);
904*4882a593Smuzhiyun         } else
905*4882a593Smuzhiyun                 monModeSet = 0;
906*4882a593Smuzhiyun 
907*4882a593Smuzhiyun 	spin_lock_irqsave(&korg1212->lock, flags);
908*4882a593Smuzhiyun 
909*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
910*4882a593Smuzhiyun         // we are about to send new values to the card, so clear the new values queued
911*4882a593Smuzhiyun         // flag.  Also, clear out mailbox 3, so we don't lockup.
912*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
913*4882a593Smuzhiyun         writel(0, korg1212->mailbox3Ptr);
914*4882a593Smuzhiyun         udelay(LOADSHIFT_DELAY);
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
917*4882a593Smuzhiyun         // determine whether we are running a 48K or 44.1K clock.  This info is used
918*4882a593Smuzhiyun         // later when setting the SPDIF FF after the volume has been shifted in.
919*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
920*4882a593Smuzhiyun         switch (korg1212->clkSrcRate) {
921*4882a593Smuzhiyun                 case K1212_CLKIDX_AdatAt44_1K:
922*4882a593Smuzhiyun                 case K1212_CLKIDX_WordAt44_1K:
923*4882a593Smuzhiyun                 case K1212_CLKIDX_LocalAt44_1K:
924*4882a593Smuzhiyun                         clkIs48K = 0;
925*4882a593Smuzhiyun                         break;
926*4882a593Smuzhiyun 
927*4882a593Smuzhiyun                 case K1212_CLKIDX_WordAt48K:
928*4882a593Smuzhiyun                 case K1212_CLKIDX_AdatAt48K:
929*4882a593Smuzhiyun                 case K1212_CLKIDX_LocalAt48K:
930*4882a593Smuzhiyun                 default:
931*4882a593Smuzhiyun                         clkIs48K = 1;
932*4882a593Smuzhiyun                         break;
933*4882a593Smuzhiyun         }
934*4882a593Smuzhiyun 
935*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
936*4882a593Smuzhiyun         // start the update.  Setup the bit structure and then shift the bits.
937*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
938*4882a593Smuzhiyun         sensVals.l.v.leftChanId   = SET_SENS_LEFTCHANID;
939*4882a593Smuzhiyun         sensVals.r.v.rightChanId  = SET_SENS_RIGHTCHANID;
940*4882a593Smuzhiyun         sensVals.l.v.leftChanVal  = korg1212->leftADCInSens;
941*4882a593Smuzhiyun         sensVals.r.v.rightChanVal = korg1212->rightADCInSens;
942*4882a593Smuzhiyun 
943*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
944*4882a593Smuzhiyun         // now start shifting the bits in.  Start with the left channel then the right.
945*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
946*4882a593Smuzhiyun         for (channel = 0; channel < 2; channel++) {
947*4882a593Smuzhiyun 
948*4882a593Smuzhiyun                 // ----------------------------------------------------------------------------
949*4882a593Smuzhiyun                 // Bring the load/shift line low, then wait - the spec says >150ns from load/
950*4882a593Smuzhiyun                 // shift low to the first rising edge of the clock.
951*4882a593Smuzhiyun                 // ----------------------------------------------------------------------------
952*4882a593Smuzhiyun                 ClearBitInWord(&controlValue, SET_SENS_LOADSHIFT_BITPOS);
953*4882a593Smuzhiyun                 ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);
954*4882a593Smuzhiyun                 writew(controlValue, korg1212->sensRegPtr);                          // load/shift goes low
955*4882a593Smuzhiyun                 udelay(LOADSHIFT_DELAY);
956*4882a593Smuzhiyun 
957*4882a593Smuzhiyun                 for (bitPosition = 15; bitPosition >= 0; bitPosition--) {       // for all the bits
958*4882a593Smuzhiyun 			if (channel == 0) {
959*4882a593Smuzhiyun 				if (sensVals.l.leftSensBits & (0x0001 << bitPosition))
960*4882a593Smuzhiyun                                         SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS);     // data bit set high
961*4882a593Smuzhiyun 				else
962*4882a593Smuzhiyun 					ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);   // data bit set low
963*4882a593Smuzhiyun 			} else {
964*4882a593Smuzhiyun                                 if (sensVals.r.rightSensBits & (0x0001 << bitPosition))
965*4882a593Smuzhiyun 					SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS);     // data bit set high
966*4882a593Smuzhiyun 				else
967*4882a593Smuzhiyun 					ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);   // data bit set low
968*4882a593Smuzhiyun 			}
969*4882a593Smuzhiyun 
970*4882a593Smuzhiyun                         ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
971*4882a593Smuzhiyun                         writew(controlValue, korg1212->sensRegPtr);                       // clock goes low
972*4882a593Smuzhiyun                         udelay(SENSCLKPULSE_WIDTH);
973*4882a593Smuzhiyun                         SetBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
974*4882a593Smuzhiyun                         writew(controlValue, korg1212->sensRegPtr);                       // clock goes high
975*4882a593Smuzhiyun                         udelay(SENSCLKPULSE_WIDTH);
976*4882a593Smuzhiyun                 }
977*4882a593Smuzhiyun 
978*4882a593Smuzhiyun                 // ----------------------------------------------------------------------------
979*4882a593Smuzhiyun                 // finish up SPDIF for left.  Bring the load/shift line high, then write a one
980*4882a593Smuzhiyun                 // bit if the clock rate is 48K otherwise write 0.
981*4882a593Smuzhiyun                 // ----------------------------------------------------------------------------
982*4882a593Smuzhiyun                 ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);
983*4882a593Smuzhiyun                 ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
984*4882a593Smuzhiyun                 SetBitInWord(&controlValue, SET_SENS_LOADSHIFT_BITPOS);
985*4882a593Smuzhiyun                 writew(controlValue, korg1212->sensRegPtr);                   // load shift goes high - clk low
986*4882a593Smuzhiyun                 udelay(SENSCLKPULSE_WIDTH);
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun                 if (clkIs48K)
989*4882a593Smuzhiyun                         SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS);
990*4882a593Smuzhiyun 
991*4882a593Smuzhiyun                 writew(controlValue, korg1212->sensRegPtr);                   // set/clear data bit
992*4882a593Smuzhiyun                 udelay(ONE_RTC_TICK);
993*4882a593Smuzhiyun                 SetBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
994*4882a593Smuzhiyun                 writew(controlValue, korg1212->sensRegPtr);                   // clock goes high
995*4882a593Smuzhiyun                 udelay(SENSCLKPULSE_WIDTH);
996*4882a593Smuzhiyun                 ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
997*4882a593Smuzhiyun                 writew(controlValue, korg1212->sensRegPtr);                   // clock goes low
998*4882a593Smuzhiyun                 udelay(SENSCLKPULSE_WIDTH);
999*4882a593Smuzhiyun         }
1000*4882a593Smuzhiyun 
1001*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
1002*4882a593Smuzhiyun         // The update is complete.  Set a timeout.  This is the inter-update delay.
1003*4882a593Smuzhiyun         // Also, if the card was in monitor mode, restore it.
1004*4882a593Smuzhiyun         // ----------------------------------------------------------------------------
1005*4882a593Smuzhiyun         for (count = 0; count < 10; count++)
1006*4882a593Smuzhiyun                 udelay(SENSCLKPULSE_WIDTH);
1007*4882a593Smuzhiyun 
1008*4882a593Smuzhiyun         if (monModeSet) {
1009*4882a593Smuzhiyun                 int rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
1010*4882a593Smuzhiyun                                 K1212_MODE_MonitorOn, 0, 0, 0);
1011*4882a593Smuzhiyun 	        if (rc)
1012*4882a593Smuzhiyun 			K1212_DEBUG_PRINTK("K1212_DEBUG: WriteADCSensivity - RC = %d [%s]\n",
1013*4882a593Smuzhiyun 					   rc, stateName[korg1212->cardState]);
1014*4882a593Smuzhiyun         }
1015*4882a593Smuzhiyun 
1016*4882a593Smuzhiyun 	spin_unlock_irqrestore(&korg1212->lock, flags);
1017*4882a593Smuzhiyun 
1018*4882a593Smuzhiyun         return 1;
1019*4882a593Smuzhiyun }
1020*4882a593Smuzhiyun 
snd_korg1212_OnDSPDownloadComplete(struct snd_korg1212 * korg1212)1021*4882a593Smuzhiyun static void snd_korg1212_OnDSPDownloadComplete(struct snd_korg1212 *korg1212)
1022*4882a593Smuzhiyun {
1023*4882a593Smuzhiyun         int channel, rc;
1024*4882a593Smuzhiyun 
1025*4882a593Smuzhiyun         K1212_DEBUG_PRINTK("K1212_DEBUG: DSP download is complete. [%s]\n",
1026*4882a593Smuzhiyun 			   stateName[korg1212->cardState]);
1027*4882a593Smuzhiyun 
1028*4882a593Smuzhiyun         // ----------------------------------------------------
1029*4882a593Smuzhiyun         // tell the card to boot
1030*4882a593Smuzhiyun         // ----------------------------------------------------
1031*4882a593Smuzhiyun         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_BootFromDSPPage4, 0, 0, 0, 0);
1032*4882a593Smuzhiyun 
1033*4882a593Smuzhiyun 	if (rc)
1034*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK("K1212_DEBUG: Boot from Page 4 - RC = %d [%s]\n",
1035*4882a593Smuzhiyun 				   rc, stateName[korg1212->cardState]);
1036*4882a593Smuzhiyun 	msleep(DSP_BOOT_DELAY_IN_MS);
1037*4882a593Smuzhiyun 
1038*4882a593Smuzhiyun         // --------------------------------------------------------------------------------
1039*4882a593Smuzhiyun         // Let the card know where all the buffers are.
1040*4882a593Smuzhiyun         // --------------------------------------------------------------------------------
1041*4882a593Smuzhiyun         rc = snd_korg1212_Send1212Command(korg1212,
1042*4882a593Smuzhiyun                         K1212_DB_ConfigureBufferMemory,
1043*4882a593Smuzhiyun                         LowerWordSwap(korg1212->PlayDataPhy),
1044*4882a593Smuzhiyun                         LowerWordSwap(korg1212->RecDataPhy),
1045*4882a593Smuzhiyun                         ((kNumBuffers * kPlayBufferFrames) / 2),   // size given to the card
1046*4882a593Smuzhiyun                                                                    // is based on 2 buffers
1047*4882a593Smuzhiyun                         0
1048*4882a593Smuzhiyun         );
1049*4882a593Smuzhiyun 
1050*4882a593Smuzhiyun 	if (rc)
1051*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK("K1212_DEBUG: Configure Buffer Memory - RC = %d [%s]\n",
1052*4882a593Smuzhiyun 				   rc, stateName[korg1212->cardState]);
1053*4882a593Smuzhiyun 
1054*4882a593Smuzhiyun         udelay(INTERCOMMAND_DELAY);
1055*4882a593Smuzhiyun 
1056*4882a593Smuzhiyun         rc = snd_korg1212_Send1212Command(korg1212,
1057*4882a593Smuzhiyun                         K1212_DB_ConfigureMiscMemory,
1058*4882a593Smuzhiyun                         LowerWordSwap(korg1212->VolumeTablePhy),
1059*4882a593Smuzhiyun                         LowerWordSwap(korg1212->RoutingTablePhy),
1060*4882a593Smuzhiyun                         LowerWordSwap(korg1212->AdatTimeCodePhy),
1061*4882a593Smuzhiyun                         0
1062*4882a593Smuzhiyun         );
1063*4882a593Smuzhiyun 
1064*4882a593Smuzhiyun 	if (rc)
1065*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK("K1212_DEBUG: Configure Misc Memory - RC = %d [%s]\n",
1066*4882a593Smuzhiyun 				   rc, stateName[korg1212->cardState]);
1067*4882a593Smuzhiyun 
1068*4882a593Smuzhiyun         // --------------------------------------------------------------------------------
1069*4882a593Smuzhiyun         // Initialize the routing and volume tables, then update the card's state.
1070*4882a593Smuzhiyun         // --------------------------------------------------------------------------------
1071*4882a593Smuzhiyun         udelay(INTERCOMMAND_DELAY);
1072*4882a593Smuzhiyun 
1073*4882a593Smuzhiyun         for (channel = 0; channel < kAudioChannels; channel++) {
1074*4882a593Smuzhiyun                 korg1212->sharedBufferPtr->volumeData[channel] = k1212MaxVolume;
1075*4882a593Smuzhiyun                 //korg1212->sharedBufferPtr->routeData[channel] = channel;
1076*4882a593Smuzhiyun                 korg1212->sharedBufferPtr->routeData[channel] = 8 + (channel & 1);
1077*4882a593Smuzhiyun         }
1078*4882a593Smuzhiyun 
1079*4882a593Smuzhiyun         snd_korg1212_WriteADCSensitivity(korg1212);
1080*4882a593Smuzhiyun 
1081*4882a593Smuzhiyun 	udelay(INTERCOMMAND_DELAY);
1082*4882a593Smuzhiyun 	rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SetClockSourceRate,
1083*4882a593Smuzhiyun 					  ClockSourceSelector[korg1212->clkSrcRate],
1084*4882a593Smuzhiyun 					  0, 0, 0);
1085*4882a593Smuzhiyun 	if (rc)
1086*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK("K1212_DEBUG: Set Clock Source Selector - RC = %d [%s]\n",
1087*4882a593Smuzhiyun 				   rc, stateName[korg1212->cardState]);
1088*4882a593Smuzhiyun 
1089*4882a593Smuzhiyun 	rc = snd_korg1212_TurnOnIdleMonitor(korg1212);
1090*4882a593Smuzhiyun 	snd_korg1212_setCardState(korg1212, K1212_STATE_READY);
1091*4882a593Smuzhiyun 
1092*4882a593Smuzhiyun 	if (rc)
1093*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK("K1212_DEBUG: Set Monitor On - RC = %d [%s]\n",
1094*4882a593Smuzhiyun 				   rc, stateName[korg1212->cardState]);
1095*4882a593Smuzhiyun 
1096*4882a593Smuzhiyun 	snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_COMPLETE);
1097*4882a593Smuzhiyun }
1098*4882a593Smuzhiyun 
snd_korg1212_interrupt(int irq,void * dev_id)1099*4882a593Smuzhiyun static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id)
1100*4882a593Smuzhiyun {
1101*4882a593Smuzhiyun         u32 doorbellValue;
1102*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = dev_id;
1103*4882a593Smuzhiyun 
1104*4882a593Smuzhiyun         doorbellValue = readl(korg1212->inDoorbellPtr);
1105*4882a593Smuzhiyun 
1106*4882a593Smuzhiyun         if (!doorbellValue)
1107*4882a593Smuzhiyun 		return IRQ_NONE;
1108*4882a593Smuzhiyun 
1109*4882a593Smuzhiyun 	spin_lock(&korg1212->lock);
1110*4882a593Smuzhiyun 
1111*4882a593Smuzhiyun 	writel(doorbellValue, korg1212->inDoorbellPtr);
1112*4882a593Smuzhiyun 
1113*4882a593Smuzhiyun         korg1212->irqcount++;
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun 	korg1212->inIRQ++;
1116*4882a593Smuzhiyun 
1117*4882a593Smuzhiyun         switch (doorbellValue) {
1118*4882a593Smuzhiyun                 case K1212_DB_DSPDownloadDone:
1119*4882a593Smuzhiyun                         K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DNLD count - %ld, %x, [%s].\n",
1120*4882a593Smuzhiyun 					   korg1212->irqcount, doorbellValue,
1121*4882a593Smuzhiyun 					   stateName[korg1212->cardState]);
1122*4882a593Smuzhiyun                         if (korg1212->cardState == K1212_STATE_DSP_IN_PROCESS) {
1123*4882a593Smuzhiyun 				korg1212->dsp_is_loaded = 1;
1124*4882a593Smuzhiyun 				wake_up(&korg1212->wait);
1125*4882a593Smuzhiyun 			}
1126*4882a593Smuzhiyun                         break;
1127*4882a593Smuzhiyun 
1128*4882a593Smuzhiyun                 // ------------------------------------------------------------------------
1129*4882a593Smuzhiyun                 // an error occurred - stop the card
1130*4882a593Smuzhiyun                 // ------------------------------------------------------------------------
1131*4882a593Smuzhiyun                 case K1212_DB_DMAERROR:
1132*4882a593Smuzhiyun 			K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: IRQ DMAE count - %ld, %x, [%s].\n",
1133*4882a593Smuzhiyun 						   korg1212->irqcount, doorbellValue,
1134*4882a593Smuzhiyun 						   stateName[korg1212->cardState]);
1135*4882a593Smuzhiyun 			snd_printk(KERN_ERR "korg1212: DMA Error\n");
1136*4882a593Smuzhiyun 			korg1212->errorcnt++;
1137*4882a593Smuzhiyun 			korg1212->totalerrorcnt++;
1138*4882a593Smuzhiyun 			korg1212->sharedBufferPtr->cardCommand = 0;
1139*4882a593Smuzhiyun 			snd_korg1212_setCardState(korg1212, K1212_STATE_ERRORSTOP);
1140*4882a593Smuzhiyun                         break;
1141*4882a593Smuzhiyun 
1142*4882a593Smuzhiyun                 // ------------------------------------------------------------------------
1143*4882a593Smuzhiyun                 // the card has stopped by our request.  Clear the command word and signal
1144*4882a593Smuzhiyun                 // the semaphore in case someone is waiting for this.
1145*4882a593Smuzhiyun                 // ------------------------------------------------------------------------
1146*4882a593Smuzhiyun                 case K1212_DB_CARDSTOPPED:
1147*4882a593Smuzhiyun                         K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: IRQ CSTP count - %ld, %x, [%s].\n",
1148*4882a593Smuzhiyun 						   korg1212->irqcount, doorbellValue,
1149*4882a593Smuzhiyun 						   stateName[korg1212->cardState]);
1150*4882a593Smuzhiyun 			korg1212->sharedBufferPtr->cardCommand = 0;
1151*4882a593Smuzhiyun                         break;
1152*4882a593Smuzhiyun 
1153*4882a593Smuzhiyun                 default:
1154*4882a593Smuzhiyun 			K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: IRQ DFLT count - %ld, %x, cpos=%d [%s].\n",
1155*4882a593Smuzhiyun 			       korg1212->irqcount, doorbellValue,
1156*4882a593Smuzhiyun 			       korg1212->currentBuffer, stateName[korg1212->cardState]);
1157*4882a593Smuzhiyun                         if ((korg1212->cardState > K1212_STATE_SETUP) || korg1212->idleMonitorOn) {
1158*4882a593Smuzhiyun                                 korg1212->currentBuffer++;
1159*4882a593Smuzhiyun 
1160*4882a593Smuzhiyun                                 if (korg1212->currentBuffer >= kNumBuffers)
1161*4882a593Smuzhiyun                                         korg1212->currentBuffer = 0;
1162*4882a593Smuzhiyun 
1163*4882a593Smuzhiyun                                 if (!korg1212->running)
1164*4882a593Smuzhiyun                                         break;
1165*4882a593Smuzhiyun 
1166*4882a593Smuzhiyun                                 if (korg1212->capture_substream) {
1167*4882a593Smuzhiyun 					spin_unlock(&korg1212->lock);
1168*4882a593Smuzhiyun                                         snd_pcm_period_elapsed(korg1212->capture_substream);
1169*4882a593Smuzhiyun 					spin_lock(&korg1212->lock);
1170*4882a593Smuzhiyun                                 }
1171*4882a593Smuzhiyun 
1172*4882a593Smuzhiyun                                 if (korg1212->playback_substream) {
1173*4882a593Smuzhiyun 					spin_unlock(&korg1212->lock);
1174*4882a593Smuzhiyun                                         snd_pcm_period_elapsed(korg1212->playback_substream);
1175*4882a593Smuzhiyun 					spin_lock(&korg1212->lock);
1176*4882a593Smuzhiyun                                 }
1177*4882a593Smuzhiyun                         }
1178*4882a593Smuzhiyun                         break;
1179*4882a593Smuzhiyun         }
1180*4882a593Smuzhiyun 
1181*4882a593Smuzhiyun 	korg1212->inIRQ--;
1182*4882a593Smuzhiyun 
1183*4882a593Smuzhiyun 	spin_unlock(&korg1212->lock);
1184*4882a593Smuzhiyun 
1185*4882a593Smuzhiyun 	return IRQ_HANDLED;
1186*4882a593Smuzhiyun }
1187*4882a593Smuzhiyun 
snd_korg1212_downloadDSPCode(struct snd_korg1212 * korg1212)1188*4882a593Smuzhiyun static int snd_korg1212_downloadDSPCode(struct snd_korg1212 *korg1212)
1189*4882a593Smuzhiyun {
1190*4882a593Smuzhiyun 	int rc;
1191*4882a593Smuzhiyun 
1192*4882a593Smuzhiyun         K1212_DEBUG_PRINTK("K1212_DEBUG: DSP download is starting... [%s]\n",
1193*4882a593Smuzhiyun 			   stateName[korg1212->cardState]);
1194*4882a593Smuzhiyun 
1195*4882a593Smuzhiyun         // ---------------------------------------------------------------
1196*4882a593Smuzhiyun         // verify the state of the card before proceeding.
1197*4882a593Smuzhiyun         // ---------------------------------------------------------------
1198*4882a593Smuzhiyun         if (korg1212->cardState >= K1212_STATE_DSP_IN_PROCESS)
1199*4882a593Smuzhiyun                 return 1;
1200*4882a593Smuzhiyun 
1201*4882a593Smuzhiyun         snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_IN_PROCESS);
1202*4882a593Smuzhiyun 
1203*4882a593Smuzhiyun         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_StartDSPDownload,
1204*4882a593Smuzhiyun                                      UpperWordSwap(korg1212->dma_dsp.addr),
1205*4882a593Smuzhiyun                                      0, 0, 0);
1206*4882a593Smuzhiyun 	if (rc)
1207*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK("K1212_DEBUG: Start DSP Download RC = %d [%s]\n",
1208*4882a593Smuzhiyun 				   rc, stateName[korg1212->cardState]);
1209*4882a593Smuzhiyun 
1210*4882a593Smuzhiyun 	korg1212->dsp_is_loaded = 0;
1211*4882a593Smuzhiyun 	wait_event_timeout(korg1212->wait, korg1212->dsp_is_loaded, HZ * CARD_BOOT_TIMEOUT);
1212*4882a593Smuzhiyun 	if (! korg1212->dsp_is_loaded )
1213*4882a593Smuzhiyun 		return -EBUSY; /* timeout */
1214*4882a593Smuzhiyun 
1215*4882a593Smuzhiyun 	snd_korg1212_OnDSPDownloadComplete(korg1212);
1216*4882a593Smuzhiyun 
1217*4882a593Smuzhiyun         return 0;
1218*4882a593Smuzhiyun }
1219*4882a593Smuzhiyun 
1220*4882a593Smuzhiyun static const struct snd_pcm_hardware snd_korg1212_playback_info =
1221*4882a593Smuzhiyun {
1222*4882a593Smuzhiyun 	.info =              (SNDRV_PCM_INFO_MMAP |
1223*4882a593Smuzhiyun                               SNDRV_PCM_INFO_MMAP_VALID |
1224*4882a593Smuzhiyun 			      SNDRV_PCM_INFO_INTERLEAVED |
1225*4882a593Smuzhiyun 			      SNDRV_PCM_INFO_BATCH),
1226*4882a593Smuzhiyun 	.formats =	      SNDRV_PCM_FMTBIT_S16_LE,
1227*4882a593Smuzhiyun         .rates =              (SNDRV_PCM_RATE_44100 |
1228*4882a593Smuzhiyun                               SNDRV_PCM_RATE_48000),
1229*4882a593Smuzhiyun         .rate_min =           44100,
1230*4882a593Smuzhiyun         .rate_max =           48000,
1231*4882a593Smuzhiyun         .channels_min =       K1212_MIN_CHANNELS,
1232*4882a593Smuzhiyun         .channels_max =       K1212_MAX_CHANNELS,
1233*4882a593Smuzhiyun         .buffer_bytes_max =   K1212_MAX_BUF_SIZE,
1234*4882a593Smuzhiyun         .period_bytes_min =   K1212_MIN_CHANNELS * 2 * kPlayBufferFrames,
1235*4882a593Smuzhiyun         .period_bytes_max =   K1212_MAX_CHANNELS * 2 * kPlayBufferFrames,
1236*4882a593Smuzhiyun         .periods_min =        K1212_PERIODS,
1237*4882a593Smuzhiyun         .periods_max =        K1212_PERIODS,
1238*4882a593Smuzhiyun         .fifo_size =          0,
1239*4882a593Smuzhiyun };
1240*4882a593Smuzhiyun 
1241*4882a593Smuzhiyun static const struct snd_pcm_hardware snd_korg1212_capture_info =
1242*4882a593Smuzhiyun {
1243*4882a593Smuzhiyun         .info =              (SNDRV_PCM_INFO_MMAP |
1244*4882a593Smuzhiyun                               SNDRV_PCM_INFO_MMAP_VALID |
1245*4882a593Smuzhiyun 			      SNDRV_PCM_INFO_INTERLEAVED |
1246*4882a593Smuzhiyun 			      SNDRV_PCM_INFO_BATCH),
1247*4882a593Smuzhiyun         .formats =	      SNDRV_PCM_FMTBIT_S16_LE,
1248*4882a593Smuzhiyun         .rates =	      (SNDRV_PCM_RATE_44100 |
1249*4882a593Smuzhiyun                               SNDRV_PCM_RATE_48000),
1250*4882a593Smuzhiyun         .rate_min =           44100,
1251*4882a593Smuzhiyun         .rate_max =           48000,
1252*4882a593Smuzhiyun         .channels_min =       K1212_MIN_CHANNELS,
1253*4882a593Smuzhiyun         .channels_max =       K1212_MAX_CHANNELS,
1254*4882a593Smuzhiyun         .buffer_bytes_max =   K1212_MAX_BUF_SIZE,
1255*4882a593Smuzhiyun         .period_bytes_min =   K1212_MIN_CHANNELS * 2 * kPlayBufferFrames,
1256*4882a593Smuzhiyun         .period_bytes_max =   K1212_MAX_CHANNELS * 2 * kPlayBufferFrames,
1257*4882a593Smuzhiyun         .periods_min =        K1212_PERIODS,
1258*4882a593Smuzhiyun         .periods_max =        K1212_PERIODS,
1259*4882a593Smuzhiyun         .fifo_size =          0,
1260*4882a593Smuzhiyun };
1261*4882a593Smuzhiyun 
snd_korg1212_silence(struct snd_korg1212 * korg1212,int pos,int count,int offset,int size)1262*4882a593Smuzhiyun static int snd_korg1212_silence(struct snd_korg1212 *korg1212, int pos, int count, int offset, int size)
1263*4882a593Smuzhiyun {
1264*4882a593Smuzhiyun 	struct KorgAudioFrame * dst =  korg1212->playDataBufsPtr[0].bufferData + pos;
1265*4882a593Smuzhiyun 	int i;
1266*4882a593Smuzhiyun 
1267*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n",
1268*4882a593Smuzhiyun 				   pos, offset, size, count);
1269*4882a593Smuzhiyun 	if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
1270*4882a593Smuzhiyun 		return -EINVAL;
1271*4882a593Smuzhiyun 
1272*4882a593Smuzhiyun 	for (i=0; i < count; i++) {
1273*4882a593Smuzhiyun #if K1212_DEBUG_LEVEL > 0
1274*4882a593Smuzhiyun 		if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
1275*4882a593Smuzhiyun 		     (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
1276*4882a593Smuzhiyun 			printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_silence KERNEL EFAULT dst=%p iter=%d\n",
1277*4882a593Smuzhiyun 			       dst, i);
1278*4882a593Smuzhiyun 			return -EFAULT;
1279*4882a593Smuzhiyun 		}
1280*4882a593Smuzhiyun #endif
1281*4882a593Smuzhiyun 		memset((void*) dst + offset, 0, size);
1282*4882a593Smuzhiyun 		dst++;
1283*4882a593Smuzhiyun 	}
1284*4882a593Smuzhiyun 
1285*4882a593Smuzhiyun 	return 0;
1286*4882a593Smuzhiyun }
1287*4882a593Smuzhiyun 
snd_korg1212_copy_to(struct snd_pcm_substream * substream,void __user * dst,int pos,int count,bool in_kernel)1288*4882a593Smuzhiyun static int snd_korg1212_copy_to(struct snd_pcm_substream *substream,
1289*4882a593Smuzhiyun 				void __user *dst, int pos, int count,
1290*4882a593Smuzhiyun 				bool in_kernel)
1291*4882a593Smuzhiyun {
1292*4882a593Smuzhiyun 	struct snd_pcm_runtime *runtime = substream->runtime;
1293*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
1294*4882a593Smuzhiyun 	struct KorgAudioFrame *src;
1295*4882a593Smuzhiyun 	int i, size;
1296*4882a593Smuzhiyun 
1297*4882a593Smuzhiyun 	pos = bytes_to_frames(runtime, pos);
1298*4882a593Smuzhiyun 	count = bytes_to_frames(runtime, count);
1299*4882a593Smuzhiyun 	size = korg1212->channels * 2;
1300*4882a593Smuzhiyun 	src = korg1212->recordDataBufsPtr[0].bufferData + pos;
1301*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%d size=%d count=%d\n",
1302*4882a593Smuzhiyun 				   pos, size, count);
1303*4882a593Smuzhiyun 	if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
1304*4882a593Smuzhiyun 		return -EINVAL;
1305*4882a593Smuzhiyun 
1306*4882a593Smuzhiyun 	for (i=0; i < count; i++) {
1307*4882a593Smuzhiyun #if K1212_DEBUG_LEVEL > 0
1308*4882a593Smuzhiyun 		if ( (void *) src < (void *) korg1212->recordDataBufsPtr ||
1309*4882a593Smuzhiyun 		     (void *) src > (void *) korg1212->recordDataBufsPtr[8].bufferData ) {
1310*4882a593Smuzhiyun 			printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_copy_to KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);
1311*4882a593Smuzhiyun 			return -EFAULT;
1312*4882a593Smuzhiyun 		}
1313*4882a593Smuzhiyun #endif
1314*4882a593Smuzhiyun 		if (in_kernel)
1315*4882a593Smuzhiyun 			memcpy((__force void *)dst, src, size);
1316*4882a593Smuzhiyun 		else if (copy_to_user(dst, src, size))
1317*4882a593Smuzhiyun 			return -EFAULT;
1318*4882a593Smuzhiyun 		src++;
1319*4882a593Smuzhiyun 		dst += size;
1320*4882a593Smuzhiyun 	}
1321*4882a593Smuzhiyun 
1322*4882a593Smuzhiyun 	return 0;
1323*4882a593Smuzhiyun }
1324*4882a593Smuzhiyun 
snd_korg1212_copy_from(struct snd_pcm_substream * substream,void __user * src,int pos,int count,bool in_kernel)1325*4882a593Smuzhiyun static int snd_korg1212_copy_from(struct snd_pcm_substream *substream,
1326*4882a593Smuzhiyun 				  void __user *src, int pos, int count,
1327*4882a593Smuzhiyun 				  bool in_kernel)
1328*4882a593Smuzhiyun {
1329*4882a593Smuzhiyun         struct snd_pcm_runtime *runtime = substream->runtime;
1330*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
1331*4882a593Smuzhiyun 	struct KorgAudioFrame *dst;
1332*4882a593Smuzhiyun 	int i, size;
1333*4882a593Smuzhiyun 
1334*4882a593Smuzhiyun 	pos = bytes_to_frames(runtime, pos);
1335*4882a593Smuzhiyun 	count = bytes_to_frames(runtime, count);
1336*4882a593Smuzhiyun 	size = korg1212->channels * 2;
1337*4882a593Smuzhiyun 	dst = korg1212->playDataBufsPtr[0].bufferData + pos;
1338*4882a593Smuzhiyun 
1339*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%d size=%d count=%d\n",
1340*4882a593Smuzhiyun 				   pos, size, count);
1341*4882a593Smuzhiyun 
1342*4882a593Smuzhiyun 	if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
1343*4882a593Smuzhiyun 		return -EINVAL;
1344*4882a593Smuzhiyun 
1345*4882a593Smuzhiyun 	for (i=0; i < count; i++) {
1346*4882a593Smuzhiyun #if K1212_DEBUG_LEVEL > 0
1347*4882a593Smuzhiyun 		if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
1348*4882a593Smuzhiyun 		     (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
1349*4882a593Smuzhiyun 			printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_copy_from KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);
1350*4882a593Smuzhiyun 			return -EFAULT;
1351*4882a593Smuzhiyun 		}
1352*4882a593Smuzhiyun #endif
1353*4882a593Smuzhiyun 		if (in_kernel)
1354*4882a593Smuzhiyun 			memcpy(dst, (__force void *)src, size);
1355*4882a593Smuzhiyun 		else if (copy_from_user(dst, src, size))
1356*4882a593Smuzhiyun 			return -EFAULT;
1357*4882a593Smuzhiyun 		dst++;
1358*4882a593Smuzhiyun 		src += size;
1359*4882a593Smuzhiyun 	}
1360*4882a593Smuzhiyun 
1361*4882a593Smuzhiyun 	return 0;
1362*4882a593Smuzhiyun }
1363*4882a593Smuzhiyun 
snd_korg1212_free_pcm(struct snd_pcm * pcm)1364*4882a593Smuzhiyun static void snd_korg1212_free_pcm(struct snd_pcm *pcm)
1365*4882a593Smuzhiyun {
1366*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = pcm->private_data;
1367*4882a593Smuzhiyun 
1368*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_free_pcm [%s]\n",
1369*4882a593Smuzhiyun 			   stateName[korg1212->cardState]);
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun         korg1212->pcm = NULL;
1372*4882a593Smuzhiyun }
1373*4882a593Smuzhiyun 
snd_korg1212_playback_open(struct snd_pcm_substream * substream)1374*4882a593Smuzhiyun static int snd_korg1212_playback_open(struct snd_pcm_substream *substream)
1375*4882a593Smuzhiyun {
1376*4882a593Smuzhiyun         unsigned long flags;
1377*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
1378*4882a593Smuzhiyun         struct snd_pcm_runtime *runtime = substream->runtime;
1379*4882a593Smuzhiyun 
1380*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_open [%s]\n",
1381*4882a593Smuzhiyun 			   stateName[korg1212->cardState]);
1382*4882a593Smuzhiyun 
1383*4882a593Smuzhiyun 	snd_korg1212_OpenCard(korg1212);
1384*4882a593Smuzhiyun 
1385*4882a593Smuzhiyun         runtime->hw = snd_korg1212_playback_info;
1386*4882a593Smuzhiyun 	snd_pcm_set_runtime_buffer(substream, &korg1212->dma_play);
1387*4882a593Smuzhiyun 
1388*4882a593Smuzhiyun         spin_lock_irqsave(&korg1212->lock, flags);
1389*4882a593Smuzhiyun 
1390*4882a593Smuzhiyun         korg1212->playback_substream = substream;
1391*4882a593Smuzhiyun 	korg1212->playback_pid = current->pid;
1392*4882a593Smuzhiyun         korg1212->periodsize = K1212_PERIODS;
1393*4882a593Smuzhiyun 	korg1212->channels = K1212_CHANNELS;
1394*4882a593Smuzhiyun 	korg1212->errorcnt = 0;
1395*4882a593Smuzhiyun 
1396*4882a593Smuzhiyun         spin_unlock_irqrestore(&korg1212->lock, flags);
1397*4882a593Smuzhiyun 
1398*4882a593Smuzhiyun 	snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1399*4882a593Smuzhiyun 				     kPlayBufferFrames);
1400*4882a593Smuzhiyun 
1401*4882a593Smuzhiyun         return 0;
1402*4882a593Smuzhiyun }
1403*4882a593Smuzhiyun 
1404*4882a593Smuzhiyun 
snd_korg1212_capture_open(struct snd_pcm_substream * substream)1405*4882a593Smuzhiyun static int snd_korg1212_capture_open(struct snd_pcm_substream *substream)
1406*4882a593Smuzhiyun {
1407*4882a593Smuzhiyun         unsigned long flags;
1408*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
1409*4882a593Smuzhiyun         struct snd_pcm_runtime *runtime = substream->runtime;
1410*4882a593Smuzhiyun 
1411*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_open [%s]\n",
1412*4882a593Smuzhiyun 			   stateName[korg1212->cardState]);
1413*4882a593Smuzhiyun 
1414*4882a593Smuzhiyun 	snd_korg1212_OpenCard(korg1212);
1415*4882a593Smuzhiyun 
1416*4882a593Smuzhiyun         runtime->hw = snd_korg1212_capture_info;
1417*4882a593Smuzhiyun 	snd_pcm_set_runtime_buffer(substream, &korg1212->dma_rec);
1418*4882a593Smuzhiyun 
1419*4882a593Smuzhiyun         spin_lock_irqsave(&korg1212->lock, flags);
1420*4882a593Smuzhiyun 
1421*4882a593Smuzhiyun         korg1212->capture_substream = substream;
1422*4882a593Smuzhiyun 	korg1212->capture_pid = current->pid;
1423*4882a593Smuzhiyun         korg1212->periodsize = K1212_PERIODS;
1424*4882a593Smuzhiyun 	korg1212->channels = K1212_CHANNELS;
1425*4882a593Smuzhiyun 
1426*4882a593Smuzhiyun         spin_unlock_irqrestore(&korg1212->lock, flags);
1427*4882a593Smuzhiyun 
1428*4882a593Smuzhiyun 	snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1429*4882a593Smuzhiyun 				     kPlayBufferFrames);
1430*4882a593Smuzhiyun         return 0;
1431*4882a593Smuzhiyun }
1432*4882a593Smuzhiyun 
snd_korg1212_playback_close(struct snd_pcm_substream * substream)1433*4882a593Smuzhiyun static int snd_korg1212_playback_close(struct snd_pcm_substream *substream)
1434*4882a593Smuzhiyun {
1435*4882a593Smuzhiyun         unsigned long flags;
1436*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
1437*4882a593Smuzhiyun 
1438*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_close [%s]\n",
1439*4882a593Smuzhiyun 			   stateName[korg1212->cardState]);
1440*4882a593Smuzhiyun 
1441*4882a593Smuzhiyun 	snd_korg1212_silence(korg1212, 0, K1212_MAX_SAMPLES, 0, korg1212->channels * 2);
1442*4882a593Smuzhiyun 
1443*4882a593Smuzhiyun         spin_lock_irqsave(&korg1212->lock, flags);
1444*4882a593Smuzhiyun 
1445*4882a593Smuzhiyun 	korg1212->playback_pid = -1;
1446*4882a593Smuzhiyun         korg1212->playback_substream = NULL;
1447*4882a593Smuzhiyun         korg1212->periodsize = 0;
1448*4882a593Smuzhiyun 
1449*4882a593Smuzhiyun         spin_unlock_irqrestore(&korg1212->lock, flags);
1450*4882a593Smuzhiyun 
1451*4882a593Smuzhiyun 	snd_korg1212_CloseCard(korg1212);
1452*4882a593Smuzhiyun         return 0;
1453*4882a593Smuzhiyun }
1454*4882a593Smuzhiyun 
snd_korg1212_capture_close(struct snd_pcm_substream * substream)1455*4882a593Smuzhiyun static int snd_korg1212_capture_close(struct snd_pcm_substream *substream)
1456*4882a593Smuzhiyun {
1457*4882a593Smuzhiyun         unsigned long flags;
1458*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
1459*4882a593Smuzhiyun 
1460*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_close [%s]\n",
1461*4882a593Smuzhiyun 			   stateName[korg1212->cardState]);
1462*4882a593Smuzhiyun 
1463*4882a593Smuzhiyun         spin_lock_irqsave(&korg1212->lock, flags);
1464*4882a593Smuzhiyun 
1465*4882a593Smuzhiyun 	korg1212->capture_pid = -1;
1466*4882a593Smuzhiyun         korg1212->capture_substream = NULL;
1467*4882a593Smuzhiyun         korg1212->periodsize = 0;
1468*4882a593Smuzhiyun 
1469*4882a593Smuzhiyun         spin_unlock_irqrestore(&korg1212->lock, flags);
1470*4882a593Smuzhiyun 
1471*4882a593Smuzhiyun 	snd_korg1212_CloseCard(korg1212);
1472*4882a593Smuzhiyun         return 0;
1473*4882a593Smuzhiyun }
1474*4882a593Smuzhiyun 
snd_korg1212_ioctl(struct snd_pcm_substream * substream,unsigned int cmd,void * arg)1475*4882a593Smuzhiyun static int snd_korg1212_ioctl(struct snd_pcm_substream *substream,
1476*4882a593Smuzhiyun 			     unsigned int cmd, void *arg)
1477*4882a593Smuzhiyun {
1478*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_ioctl: cmd=%d\n", cmd);
1479*4882a593Smuzhiyun 
1480*4882a593Smuzhiyun 	if (cmd == SNDRV_PCM_IOCTL1_CHANNEL_INFO ) {
1481*4882a593Smuzhiyun 		struct snd_pcm_channel_info *info = arg;
1482*4882a593Smuzhiyun         	info->offset = 0;
1483*4882a593Smuzhiyun         	info->first = info->channel * 16;
1484*4882a593Smuzhiyun         	info->step = 256;
1485*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK("K1212_DEBUG: channel_info %d:, offset=%ld, first=%d, step=%d\n", info->channel, info->offset, info->first, info->step);
1486*4882a593Smuzhiyun 		return 0;
1487*4882a593Smuzhiyun 	}
1488*4882a593Smuzhiyun 
1489*4882a593Smuzhiyun         return snd_pcm_lib_ioctl(substream, cmd, arg);
1490*4882a593Smuzhiyun }
1491*4882a593Smuzhiyun 
snd_korg1212_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)1492*4882a593Smuzhiyun static int snd_korg1212_hw_params(struct snd_pcm_substream *substream,
1493*4882a593Smuzhiyun                              struct snd_pcm_hw_params *params)
1494*4882a593Smuzhiyun {
1495*4882a593Smuzhiyun         unsigned long flags;
1496*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
1497*4882a593Smuzhiyun         int err;
1498*4882a593Smuzhiyun 	pid_t this_pid;
1499*4882a593Smuzhiyun 	pid_t other_pid;
1500*4882a593Smuzhiyun 
1501*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_hw_params [%s]\n",
1502*4882a593Smuzhiyun 			   stateName[korg1212->cardState]);
1503*4882a593Smuzhiyun 
1504*4882a593Smuzhiyun         spin_lock_irqsave(&korg1212->lock, flags);
1505*4882a593Smuzhiyun 
1506*4882a593Smuzhiyun 	if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1507*4882a593Smuzhiyun 		this_pid = korg1212->playback_pid;
1508*4882a593Smuzhiyun 		other_pid = korg1212->capture_pid;
1509*4882a593Smuzhiyun 	} else {
1510*4882a593Smuzhiyun 		this_pid = korg1212->capture_pid;
1511*4882a593Smuzhiyun 		other_pid = korg1212->playback_pid;
1512*4882a593Smuzhiyun 	}
1513*4882a593Smuzhiyun 
1514*4882a593Smuzhiyun 	if ((other_pid > 0) && (this_pid != other_pid)) {
1515*4882a593Smuzhiyun 
1516*4882a593Smuzhiyun 		/* The other stream is open, and not by the same
1517*4882a593Smuzhiyun 		   task as this one. Make sure that the parameters
1518*4882a593Smuzhiyun 		   that matter are the same.
1519*4882a593Smuzhiyun 		 */
1520*4882a593Smuzhiyun 
1521*4882a593Smuzhiyun 		if ((int)params_rate(params) != korg1212->clkRate) {
1522*4882a593Smuzhiyun 			spin_unlock_irqrestore(&korg1212->lock, flags);
1523*4882a593Smuzhiyun 			_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
1524*4882a593Smuzhiyun 			return -EBUSY;
1525*4882a593Smuzhiyun 		}
1526*4882a593Smuzhiyun 
1527*4882a593Smuzhiyun         	spin_unlock_irqrestore(&korg1212->lock, flags);
1528*4882a593Smuzhiyun 	        return 0;
1529*4882a593Smuzhiyun 	}
1530*4882a593Smuzhiyun 
1531*4882a593Smuzhiyun         if ((err = snd_korg1212_SetRate(korg1212, params_rate(params))) < 0) {
1532*4882a593Smuzhiyun                 spin_unlock_irqrestore(&korg1212->lock, flags);
1533*4882a593Smuzhiyun                 return err;
1534*4882a593Smuzhiyun         }
1535*4882a593Smuzhiyun 
1536*4882a593Smuzhiyun 	korg1212->channels = params_channels(params);
1537*4882a593Smuzhiyun         korg1212->periodsize = K1212_PERIOD_BYTES;
1538*4882a593Smuzhiyun 
1539*4882a593Smuzhiyun         spin_unlock_irqrestore(&korg1212->lock, flags);
1540*4882a593Smuzhiyun 
1541*4882a593Smuzhiyun         return 0;
1542*4882a593Smuzhiyun }
1543*4882a593Smuzhiyun 
snd_korg1212_prepare(struct snd_pcm_substream * substream)1544*4882a593Smuzhiyun static int snd_korg1212_prepare(struct snd_pcm_substream *substream)
1545*4882a593Smuzhiyun {
1546*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
1547*4882a593Smuzhiyun 	int rc;
1548*4882a593Smuzhiyun 
1549*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare [%s]\n",
1550*4882a593Smuzhiyun 			   stateName[korg1212->cardState]);
1551*4882a593Smuzhiyun 
1552*4882a593Smuzhiyun 	spin_lock_irq(&korg1212->lock);
1553*4882a593Smuzhiyun 
1554*4882a593Smuzhiyun 	/* FIXME: we should wait for ack! */
1555*4882a593Smuzhiyun 	if (korg1212->stop_pending_cnt > 0) {
1556*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare - Stop is pending... [%s]\n",
1557*4882a593Smuzhiyun 				   stateName[korg1212->cardState]);
1558*4882a593Smuzhiyun         	spin_unlock_irq(&korg1212->lock);
1559*4882a593Smuzhiyun 		return -EAGAIN;
1560*4882a593Smuzhiyun 		/*
1561*4882a593Smuzhiyun 		korg1212->sharedBufferPtr->cardCommand = 0;
1562*4882a593Smuzhiyun 		del_timer(&korg1212->timer);
1563*4882a593Smuzhiyun 		korg1212->stop_pending_cnt = 0;
1564*4882a593Smuzhiyun 		*/
1565*4882a593Smuzhiyun 	}
1566*4882a593Smuzhiyun 
1567*4882a593Smuzhiyun         rc = snd_korg1212_SetupForPlay(korg1212);
1568*4882a593Smuzhiyun 
1569*4882a593Smuzhiyun         korg1212->currentBuffer = 0;
1570*4882a593Smuzhiyun 
1571*4882a593Smuzhiyun         spin_unlock_irq(&korg1212->lock);
1572*4882a593Smuzhiyun 
1573*4882a593Smuzhiyun 	return rc ? -EINVAL : 0;
1574*4882a593Smuzhiyun }
1575*4882a593Smuzhiyun 
snd_korg1212_trigger(struct snd_pcm_substream * substream,int cmd)1576*4882a593Smuzhiyun static int snd_korg1212_trigger(struct snd_pcm_substream *substream,
1577*4882a593Smuzhiyun                            int cmd)
1578*4882a593Smuzhiyun {
1579*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
1580*4882a593Smuzhiyun 	int rc;
1581*4882a593Smuzhiyun 
1582*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger [%s] cmd=%d\n",
1583*4882a593Smuzhiyun 			   stateName[korg1212->cardState], cmd);
1584*4882a593Smuzhiyun 
1585*4882a593Smuzhiyun 	spin_lock(&korg1212->lock);
1586*4882a593Smuzhiyun         switch (cmd) {
1587*4882a593Smuzhiyun                 case SNDRV_PCM_TRIGGER_START:
1588*4882a593Smuzhiyun /*
1589*4882a593Smuzhiyun 			if (korg1212->running) {
1590*4882a593Smuzhiyun 				K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_trigger: Already running?\n");
1591*4882a593Smuzhiyun 				break;
1592*4882a593Smuzhiyun 			}
1593*4882a593Smuzhiyun */
1594*4882a593Smuzhiyun                         korg1212->running++;
1595*4882a593Smuzhiyun                         rc = snd_korg1212_TriggerPlay(korg1212);
1596*4882a593Smuzhiyun                         break;
1597*4882a593Smuzhiyun 
1598*4882a593Smuzhiyun                 case SNDRV_PCM_TRIGGER_STOP:
1599*4882a593Smuzhiyun /*
1600*4882a593Smuzhiyun 			if (!korg1212->running) {
1601*4882a593Smuzhiyun 				K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_trigger: Already stopped?\n");
1602*4882a593Smuzhiyun 				break;
1603*4882a593Smuzhiyun 			}
1604*4882a593Smuzhiyun */
1605*4882a593Smuzhiyun                         korg1212->running--;
1606*4882a593Smuzhiyun                         rc = snd_korg1212_StopPlay(korg1212);
1607*4882a593Smuzhiyun                         break;
1608*4882a593Smuzhiyun 
1609*4882a593Smuzhiyun                 default:
1610*4882a593Smuzhiyun 			rc = 1;
1611*4882a593Smuzhiyun 			break;
1612*4882a593Smuzhiyun         }
1613*4882a593Smuzhiyun 	spin_unlock(&korg1212->lock);
1614*4882a593Smuzhiyun         return rc ? -EINVAL : 0;
1615*4882a593Smuzhiyun }
1616*4882a593Smuzhiyun 
snd_korg1212_playback_pointer(struct snd_pcm_substream * substream)1617*4882a593Smuzhiyun static snd_pcm_uframes_t snd_korg1212_playback_pointer(struct snd_pcm_substream *substream)
1618*4882a593Smuzhiyun {
1619*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
1620*4882a593Smuzhiyun         snd_pcm_uframes_t pos;
1621*4882a593Smuzhiyun 
1622*4882a593Smuzhiyun 	pos = korg1212->currentBuffer * kPlayBufferFrames;
1623*4882a593Smuzhiyun 
1624*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_playback_pointer [%s] %ld\n",
1625*4882a593Smuzhiyun 				   stateName[korg1212->cardState], pos);
1626*4882a593Smuzhiyun 
1627*4882a593Smuzhiyun         return pos;
1628*4882a593Smuzhiyun }
1629*4882a593Smuzhiyun 
snd_korg1212_capture_pointer(struct snd_pcm_substream * substream)1630*4882a593Smuzhiyun static snd_pcm_uframes_t snd_korg1212_capture_pointer(struct snd_pcm_substream *substream)
1631*4882a593Smuzhiyun {
1632*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
1633*4882a593Smuzhiyun         snd_pcm_uframes_t pos;
1634*4882a593Smuzhiyun 
1635*4882a593Smuzhiyun 	pos = korg1212->currentBuffer * kPlayBufferFrames;
1636*4882a593Smuzhiyun 
1637*4882a593Smuzhiyun 	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_capture_pointer [%s] %ld\n",
1638*4882a593Smuzhiyun 				   stateName[korg1212->cardState], pos);
1639*4882a593Smuzhiyun 
1640*4882a593Smuzhiyun         return pos;
1641*4882a593Smuzhiyun }
1642*4882a593Smuzhiyun 
snd_korg1212_playback_copy(struct snd_pcm_substream * substream,int channel,unsigned long pos,void __user * src,unsigned long count)1643*4882a593Smuzhiyun static int snd_korg1212_playback_copy(struct snd_pcm_substream *substream,
1644*4882a593Smuzhiyun 				      int channel, unsigned long pos,
1645*4882a593Smuzhiyun 				      void __user *src, unsigned long count)
1646*4882a593Smuzhiyun {
1647*4882a593Smuzhiyun 	return snd_korg1212_copy_from(substream, src, pos, count, false);
1648*4882a593Smuzhiyun }
1649*4882a593Smuzhiyun 
snd_korg1212_playback_copy_kernel(struct snd_pcm_substream * substream,int channel,unsigned long pos,void * src,unsigned long count)1650*4882a593Smuzhiyun static int snd_korg1212_playback_copy_kernel(struct snd_pcm_substream *substream,
1651*4882a593Smuzhiyun 				      int channel, unsigned long pos,
1652*4882a593Smuzhiyun 				      void *src, unsigned long count)
1653*4882a593Smuzhiyun {
1654*4882a593Smuzhiyun 	return snd_korg1212_copy_from(substream, (void __user *)src,
1655*4882a593Smuzhiyun 				      pos, count, true);
1656*4882a593Smuzhiyun }
1657*4882a593Smuzhiyun 
snd_korg1212_playback_silence(struct snd_pcm_substream * substream,int channel,unsigned long pos,unsigned long count)1658*4882a593Smuzhiyun static int snd_korg1212_playback_silence(struct snd_pcm_substream *substream,
1659*4882a593Smuzhiyun                            int channel, /* not used (interleaved data) */
1660*4882a593Smuzhiyun                            unsigned long pos,
1661*4882a593Smuzhiyun                            unsigned long count)
1662*4882a593Smuzhiyun {
1663*4882a593Smuzhiyun 	struct snd_pcm_runtime *runtime = substream->runtime;
1664*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
1665*4882a593Smuzhiyun 
1666*4882a593Smuzhiyun 	return snd_korg1212_silence(korg1212, bytes_to_frames(runtime, pos),
1667*4882a593Smuzhiyun 				    bytes_to_frames(runtime, count),
1668*4882a593Smuzhiyun 				    0, korg1212->channels * 2);
1669*4882a593Smuzhiyun }
1670*4882a593Smuzhiyun 
snd_korg1212_capture_copy(struct snd_pcm_substream * substream,int channel,unsigned long pos,void __user * dst,unsigned long count)1671*4882a593Smuzhiyun static int snd_korg1212_capture_copy(struct snd_pcm_substream *substream,
1672*4882a593Smuzhiyun 				     int channel, unsigned long pos,
1673*4882a593Smuzhiyun 				     void __user *dst, unsigned long count)
1674*4882a593Smuzhiyun {
1675*4882a593Smuzhiyun 	return snd_korg1212_copy_to(substream, dst, pos, count, false);
1676*4882a593Smuzhiyun }
1677*4882a593Smuzhiyun 
snd_korg1212_capture_copy_kernel(struct snd_pcm_substream * substream,int channel,unsigned long pos,void * dst,unsigned long count)1678*4882a593Smuzhiyun static int snd_korg1212_capture_copy_kernel(struct snd_pcm_substream *substream,
1679*4882a593Smuzhiyun 				     int channel, unsigned long pos,
1680*4882a593Smuzhiyun 				     void *dst, unsigned long count)
1681*4882a593Smuzhiyun {
1682*4882a593Smuzhiyun 	return snd_korg1212_copy_to(substream, (void __user *)dst,
1683*4882a593Smuzhiyun 				    pos, count, true);
1684*4882a593Smuzhiyun }
1685*4882a593Smuzhiyun 
1686*4882a593Smuzhiyun static const struct snd_pcm_ops snd_korg1212_playback_ops = {
1687*4882a593Smuzhiyun         .open =		snd_korg1212_playback_open,
1688*4882a593Smuzhiyun         .close =	snd_korg1212_playback_close,
1689*4882a593Smuzhiyun         .ioctl =	snd_korg1212_ioctl,
1690*4882a593Smuzhiyun         .hw_params =	snd_korg1212_hw_params,
1691*4882a593Smuzhiyun         .prepare =	snd_korg1212_prepare,
1692*4882a593Smuzhiyun         .trigger =	snd_korg1212_trigger,
1693*4882a593Smuzhiyun         .pointer =	snd_korg1212_playback_pointer,
1694*4882a593Smuzhiyun 	.copy_user =	snd_korg1212_playback_copy,
1695*4882a593Smuzhiyun 	.copy_kernel =	snd_korg1212_playback_copy_kernel,
1696*4882a593Smuzhiyun 	.fill_silence =	snd_korg1212_playback_silence,
1697*4882a593Smuzhiyun };
1698*4882a593Smuzhiyun 
1699*4882a593Smuzhiyun static const struct snd_pcm_ops snd_korg1212_capture_ops = {
1700*4882a593Smuzhiyun 	.open =		snd_korg1212_capture_open,
1701*4882a593Smuzhiyun 	.close =	snd_korg1212_capture_close,
1702*4882a593Smuzhiyun 	.ioctl =	snd_korg1212_ioctl,
1703*4882a593Smuzhiyun 	.hw_params =	snd_korg1212_hw_params,
1704*4882a593Smuzhiyun 	.prepare =	snd_korg1212_prepare,
1705*4882a593Smuzhiyun 	.trigger =	snd_korg1212_trigger,
1706*4882a593Smuzhiyun 	.pointer =	snd_korg1212_capture_pointer,
1707*4882a593Smuzhiyun 	.copy_user =	snd_korg1212_capture_copy,
1708*4882a593Smuzhiyun 	.copy_kernel =	snd_korg1212_capture_copy_kernel,
1709*4882a593Smuzhiyun };
1710*4882a593Smuzhiyun 
1711*4882a593Smuzhiyun /*
1712*4882a593Smuzhiyun  * Control Interface
1713*4882a593Smuzhiyun  */
1714*4882a593Smuzhiyun 
snd_korg1212_control_phase_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1715*4882a593Smuzhiyun static int snd_korg1212_control_phase_info(struct snd_kcontrol *kcontrol,
1716*4882a593Smuzhiyun 					   struct snd_ctl_elem_info *uinfo)
1717*4882a593Smuzhiyun {
1718*4882a593Smuzhiyun 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1719*4882a593Smuzhiyun 	uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1;
1720*4882a593Smuzhiyun 	return 0;
1721*4882a593Smuzhiyun }
1722*4882a593Smuzhiyun 
snd_korg1212_control_phase_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * u)1723*4882a593Smuzhiyun static int snd_korg1212_control_phase_get(struct snd_kcontrol *kcontrol,
1724*4882a593Smuzhiyun 					  struct snd_ctl_elem_value *u)
1725*4882a593Smuzhiyun {
1726*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
1727*4882a593Smuzhiyun 	int i = kcontrol->private_value;
1728*4882a593Smuzhiyun 
1729*4882a593Smuzhiyun 	spin_lock_irq(&korg1212->lock);
1730*4882a593Smuzhiyun 
1731*4882a593Smuzhiyun         u->value.integer.value[0] = korg1212->volumePhase[i];
1732*4882a593Smuzhiyun 
1733*4882a593Smuzhiyun 	if (i >= 8)
1734*4882a593Smuzhiyun         	u->value.integer.value[1] = korg1212->volumePhase[i+1];
1735*4882a593Smuzhiyun 
1736*4882a593Smuzhiyun 	spin_unlock_irq(&korg1212->lock);
1737*4882a593Smuzhiyun 
1738*4882a593Smuzhiyun         return 0;
1739*4882a593Smuzhiyun }
1740*4882a593Smuzhiyun 
snd_korg1212_control_phase_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * u)1741*4882a593Smuzhiyun static int snd_korg1212_control_phase_put(struct snd_kcontrol *kcontrol,
1742*4882a593Smuzhiyun 					  struct snd_ctl_elem_value *u)
1743*4882a593Smuzhiyun {
1744*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
1745*4882a593Smuzhiyun         int change = 0;
1746*4882a593Smuzhiyun         int i, val;
1747*4882a593Smuzhiyun 
1748*4882a593Smuzhiyun 	spin_lock_irq(&korg1212->lock);
1749*4882a593Smuzhiyun 
1750*4882a593Smuzhiyun 	i = kcontrol->private_value;
1751*4882a593Smuzhiyun 
1752*4882a593Smuzhiyun 	korg1212->volumePhase[i] = !!u->value.integer.value[0];
1753*4882a593Smuzhiyun 
1754*4882a593Smuzhiyun 	val = korg1212->sharedBufferPtr->volumeData[kcontrol->private_value];
1755*4882a593Smuzhiyun 
1756*4882a593Smuzhiyun 	if ((u->value.integer.value[0] != 0) != (val < 0)) {
1757*4882a593Smuzhiyun 		val = abs(val) * (korg1212->volumePhase[i] > 0 ? -1 : 1);
1758*4882a593Smuzhiyun 		korg1212->sharedBufferPtr->volumeData[i] = val;
1759*4882a593Smuzhiyun 		change = 1;
1760*4882a593Smuzhiyun 	}
1761*4882a593Smuzhiyun 
1762*4882a593Smuzhiyun 	if (i >= 8) {
1763*4882a593Smuzhiyun 		korg1212->volumePhase[i+1] = !!u->value.integer.value[1];
1764*4882a593Smuzhiyun 
1765*4882a593Smuzhiyun 		val = korg1212->sharedBufferPtr->volumeData[kcontrol->private_value+1];
1766*4882a593Smuzhiyun 
1767*4882a593Smuzhiyun 		if ((u->value.integer.value[1] != 0) != (val < 0)) {
1768*4882a593Smuzhiyun 			val = abs(val) * (korg1212->volumePhase[i+1] > 0 ? -1 : 1);
1769*4882a593Smuzhiyun 			korg1212->sharedBufferPtr->volumeData[i+1] = val;
1770*4882a593Smuzhiyun 			change = 1;
1771*4882a593Smuzhiyun 		}
1772*4882a593Smuzhiyun 	}
1773*4882a593Smuzhiyun 
1774*4882a593Smuzhiyun 	spin_unlock_irq(&korg1212->lock);
1775*4882a593Smuzhiyun 
1776*4882a593Smuzhiyun         return change;
1777*4882a593Smuzhiyun }
1778*4882a593Smuzhiyun 
snd_korg1212_control_volume_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1779*4882a593Smuzhiyun static int snd_korg1212_control_volume_info(struct snd_kcontrol *kcontrol,
1780*4882a593Smuzhiyun 					    struct snd_ctl_elem_info *uinfo)
1781*4882a593Smuzhiyun {
1782*4882a593Smuzhiyun         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1783*4882a593Smuzhiyun 	uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1;
1784*4882a593Smuzhiyun         uinfo->value.integer.min = k1212MinVolume;
1785*4882a593Smuzhiyun 	uinfo->value.integer.max = k1212MaxVolume;
1786*4882a593Smuzhiyun         return 0;
1787*4882a593Smuzhiyun }
1788*4882a593Smuzhiyun 
snd_korg1212_control_volume_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * u)1789*4882a593Smuzhiyun static int snd_korg1212_control_volume_get(struct snd_kcontrol *kcontrol,
1790*4882a593Smuzhiyun 					   struct snd_ctl_elem_value *u)
1791*4882a593Smuzhiyun {
1792*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
1793*4882a593Smuzhiyun         int i;
1794*4882a593Smuzhiyun 
1795*4882a593Smuzhiyun 	spin_lock_irq(&korg1212->lock);
1796*4882a593Smuzhiyun 
1797*4882a593Smuzhiyun 	i = kcontrol->private_value;
1798*4882a593Smuzhiyun         u->value.integer.value[0] = abs(korg1212->sharedBufferPtr->volumeData[i]);
1799*4882a593Smuzhiyun 
1800*4882a593Smuzhiyun 	if (i >= 8)
1801*4882a593Smuzhiyun                 u->value.integer.value[1] = abs(korg1212->sharedBufferPtr->volumeData[i+1]);
1802*4882a593Smuzhiyun 
1803*4882a593Smuzhiyun         spin_unlock_irq(&korg1212->lock);
1804*4882a593Smuzhiyun 
1805*4882a593Smuzhiyun         return 0;
1806*4882a593Smuzhiyun }
1807*4882a593Smuzhiyun 
snd_korg1212_control_volume_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * u)1808*4882a593Smuzhiyun static int snd_korg1212_control_volume_put(struct snd_kcontrol *kcontrol,
1809*4882a593Smuzhiyun 					   struct snd_ctl_elem_value *u)
1810*4882a593Smuzhiyun {
1811*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
1812*4882a593Smuzhiyun         int change = 0;
1813*4882a593Smuzhiyun         int i;
1814*4882a593Smuzhiyun 	int val;
1815*4882a593Smuzhiyun 
1816*4882a593Smuzhiyun 	spin_lock_irq(&korg1212->lock);
1817*4882a593Smuzhiyun 
1818*4882a593Smuzhiyun 	i = kcontrol->private_value;
1819*4882a593Smuzhiyun 
1820*4882a593Smuzhiyun 	if (u->value.integer.value[0] >= k1212MinVolume &&
1821*4882a593Smuzhiyun 	    u->value.integer.value[0] >= k1212MaxVolume &&
1822*4882a593Smuzhiyun 	    u->value.integer.value[0] !=
1823*4882a593Smuzhiyun 	    abs(korg1212->sharedBufferPtr->volumeData[i])) {
1824*4882a593Smuzhiyun 		val = korg1212->volumePhase[i] > 0 ? -1 : 1;
1825*4882a593Smuzhiyun 		val *= u->value.integer.value[0];
1826*4882a593Smuzhiyun 		korg1212->sharedBufferPtr->volumeData[i] = val;
1827*4882a593Smuzhiyun 		change = 1;
1828*4882a593Smuzhiyun 	}
1829*4882a593Smuzhiyun 
1830*4882a593Smuzhiyun 	if (i >= 8) {
1831*4882a593Smuzhiyun 		if (u->value.integer.value[1] >= k1212MinVolume &&
1832*4882a593Smuzhiyun 		    u->value.integer.value[1] >= k1212MaxVolume &&
1833*4882a593Smuzhiyun 		    u->value.integer.value[1] !=
1834*4882a593Smuzhiyun 		    abs(korg1212->sharedBufferPtr->volumeData[i+1])) {
1835*4882a593Smuzhiyun 			val = korg1212->volumePhase[i+1] > 0 ? -1 : 1;
1836*4882a593Smuzhiyun 			val *= u->value.integer.value[1];
1837*4882a593Smuzhiyun 			korg1212->sharedBufferPtr->volumeData[i+1] = val;
1838*4882a593Smuzhiyun 			change = 1;
1839*4882a593Smuzhiyun 		}
1840*4882a593Smuzhiyun 	}
1841*4882a593Smuzhiyun 
1842*4882a593Smuzhiyun 	spin_unlock_irq(&korg1212->lock);
1843*4882a593Smuzhiyun 
1844*4882a593Smuzhiyun         return change;
1845*4882a593Smuzhiyun }
1846*4882a593Smuzhiyun 
snd_korg1212_control_route_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1847*4882a593Smuzhiyun static int snd_korg1212_control_route_info(struct snd_kcontrol *kcontrol,
1848*4882a593Smuzhiyun 					   struct snd_ctl_elem_info *uinfo)
1849*4882a593Smuzhiyun {
1850*4882a593Smuzhiyun 	return snd_ctl_enum_info(uinfo,
1851*4882a593Smuzhiyun 				 (kcontrol->private_value >= 8) ? 2 : 1,
1852*4882a593Smuzhiyun 				 kAudioChannels, channelName);
1853*4882a593Smuzhiyun }
1854*4882a593Smuzhiyun 
snd_korg1212_control_route_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * u)1855*4882a593Smuzhiyun static int snd_korg1212_control_route_get(struct snd_kcontrol *kcontrol,
1856*4882a593Smuzhiyun 					  struct snd_ctl_elem_value *u)
1857*4882a593Smuzhiyun {
1858*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
1859*4882a593Smuzhiyun         int i;
1860*4882a593Smuzhiyun 
1861*4882a593Smuzhiyun 	spin_lock_irq(&korg1212->lock);
1862*4882a593Smuzhiyun 
1863*4882a593Smuzhiyun 	i = kcontrol->private_value;
1864*4882a593Smuzhiyun 	u->value.enumerated.item[0] = korg1212->sharedBufferPtr->routeData[i];
1865*4882a593Smuzhiyun 
1866*4882a593Smuzhiyun 	if (i >= 8)
1867*4882a593Smuzhiyun 		u->value.enumerated.item[1] = korg1212->sharedBufferPtr->routeData[i+1];
1868*4882a593Smuzhiyun 
1869*4882a593Smuzhiyun         spin_unlock_irq(&korg1212->lock);
1870*4882a593Smuzhiyun 
1871*4882a593Smuzhiyun         return 0;
1872*4882a593Smuzhiyun }
1873*4882a593Smuzhiyun 
snd_korg1212_control_route_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * u)1874*4882a593Smuzhiyun static int snd_korg1212_control_route_put(struct snd_kcontrol *kcontrol,
1875*4882a593Smuzhiyun 					  struct snd_ctl_elem_value *u)
1876*4882a593Smuzhiyun {
1877*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
1878*4882a593Smuzhiyun         int change = 0, i;
1879*4882a593Smuzhiyun 
1880*4882a593Smuzhiyun 	spin_lock_irq(&korg1212->lock);
1881*4882a593Smuzhiyun 
1882*4882a593Smuzhiyun 	i = kcontrol->private_value;
1883*4882a593Smuzhiyun 
1884*4882a593Smuzhiyun 	if (u->value.enumerated.item[0] < kAudioChannels &&
1885*4882a593Smuzhiyun 	    u->value.enumerated.item[0] !=
1886*4882a593Smuzhiyun 	    (unsigned) korg1212->sharedBufferPtr->volumeData[i]) {
1887*4882a593Smuzhiyun 		korg1212->sharedBufferPtr->routeData[i] = u->value.enumerated.item[0];
1888*4882a593Smuzhiyun 		change = 1;
1889*4882a593Smuzhiyun 	}
1890*4882a593Smuzhiyun 
1891*4882a593Smuzhiyun 	if (i >= 8) {
1892*4882a593Smuzhiyun 		if (u->value.enumerated.item[1] < kAudioChannels &&
1893*4882a593Smuzhiyun 		    u->value.enumerated.item[1] !=
1894*4882a593Smuzhiyun 		    (unsigned) korg1212->sharedBufferPtr->volumeData[i+1]) {
1895*4882a593Smuzhiyun 			korg1212->sharedBufferPtr->routeData[i+1] = u->value.enumerated.item[1];
1896*4882a593Smuzhiyun 			change = 1;
1897*4882a593Smuzhiyun 		}
1898*4882a593Smuzhiyun 	}
1899*4882a593Smuzhiyun 
1900*4882a593Smuzhiyun 	spin_unlock_irq(&korg1212->lock);
1901*4882a593Smuzhiyun 
1902*4882a593Smuzhiyun         return change;
1903*4882a593Smuzhiyun }
1904*4882a593Smuzhiyun 
snd_korg1212_control_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1905*4882a593Smuzhiyun static int snd_korg1212_control_info(struct snd_kcontrol *kcontrol,
1906*4882a593Smuzhiyun 				     struct snd_ctl_elem_info *uinfo)
1907*4882a593Smuzhiyun {
1908*4882a593Smuzhiyun         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1909*4882a593Smuzhiyun         uinfo->count = 2;
1910*4882a593Smuzhiyun         uinfo->value.integer.min = k1212MaxADCSens;
1911*4882a593Smuzhiyun 	uinfo->value.integer.max = k1212MinADCSens;
1912*4882a593Smuzhiyun         return 0;
1913*4882a593Smuzhiyun }
1914*4882a593Smuzhiyun 
snd_korg1212_control_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * u)1915*4882a593Smuzhiyun static int snd_korg1212_control_get(struct snd_kcontrol *kcontrol,
1916*4882a593Smuzhiyun 				    struct snd_ctl_elem_value *u)
1917*4882a593Smuzhiyun {
1918*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
1919*4882a593Smuzhiyun 
1920*4882a593Smuzhiyun 	spin_lock_irq(&korg1212->lock);
1921*4882a593Smuzhiyun 
1922*4882a593Smuzhiyun         u->value.integer.value[0] = korg1212->leftADCInSens;
1923*4882a593Smuzhiyun         u->value.integer.value[1] = korg1212->rightADCInSens;
1924*4882a593Smuzhiyun 
1925*4882a593Smuzhiyun 	spin_unlock_irq(&korg1212->lock);
1926*4882a593Smuzhiyun 
1927*4882a593Smuzhiyun         return 0;
1928*4882a593Smuzhiyun }
1929*4882a593Smuzhiyun 
snd_korg1212_control_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * u)1930*4882a593Smuzhiyun static int snd_korg1212_control_put(struct snd_kcontrol *kcontrol,
1931*4882a593Smuzhiyun 				    struct snd_ctl_elem_value *u)
1932*4882a593Smuzhiyun {
1933*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
1934*4882a593Smuzhiyun         int change = 0;
1935*4882a593Smuzhiyun 
1936*4882a593Smuzhiyun 	spin_lock_irq(&korg1212->lock);
1937*4882a593Smuzhiyun 
1938*4882a593Smuzhiyun 	if (u->value.integer.value[0] >= k1212MinADCSens &&
1939*4882a593Smuzhiyun 	    u->value.integer.value[0] <= k1212MaxADCSens &&
1940*4882a593Smuzhiyun 	    u->value.integer.value[0] != korg1212->leftADCInSens) {
1941*4882a593Smuzhiyun                 korg1212->leftADCInSens = u->value.integer.value[0];
1942*4882a593Smuzhiyun                 change = 1;
1943*4882a593Smuzhiyun         }
1944*4882a593Smuzhiyun 	if (u->value.integer.value[1] >= k1212MinADCSens &&
1945*4882a593Smuzhiyun 	    u->value.integer.value[1] <= k1212MaxADCSens &&
1946*4882a593Smuzhiyun 	    u->value.integer.value[1] != korg1212->rightADCInSens) {
1947*4882a593Smuzhiyun                 korg1212->rightADCInSens = u->value.integer.value[1];
1948*4882a593Smuzhiyun                 change = 1;
1949*4882a593Smuzhiyun         }
1950*4882a593Smuzhiyun 
1951*4882a593Smuzhiyun 	spin_unlock_irq(&korg1212->lock);
1952*4882a593Smuzhiyun 
1953*4882a593Smuzhiyun         if (change)
1954*4882a593Smuzhiyun                 snd_korg1212_WriteADCSensitivity(korg1212);
1955*4882a593Smuzhiyun 
1956*4882a593Smuzhiyun         return change;
1957*4882a593Smuzhiyun }
1958*4882a593Smuzhiyun 
snd_korg1212_control_sync_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1959*4882a593Smuzhiyun static int snd_korg1212_control_sync_info(struct snd_kcontrol *kcontrol,
1960*4882a593Smuzhiyun 					  struct snd_ctl_elem_info *uinfo)
1961*4882a593Smuzhiyun {
1962*4882a593Smuzhiyun 	return snd_ctl_enum_info(uinfo, 1, 3, clockSourceTypeName);
1963*4882a593Smuzhiyun }
1964*4882a593Smuzhiyun 
snd_korg1212_control_sync_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1965*4882a593Smuzhiyun static int snd_korg1212_control_sync_get(struct snd_kcontrol *kcontrol,
1966*4882a593Smuzhiyun 					 struct snd_ctl_elem_value *ucontrol)
1967*4882a593Smuzhiyun {
1968*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
1969*4882a593Smuzhiyun 
1970*4882a593Smuzhiyun 	spin_lock_irq(&korg1212->lock);
1971*4882a593Smuzhiyun 
1972*4882a593Smuzhiyun 	ucontrol->value.enumerated.item[0] = korg1212->clkSource;
1973*4882a593Smuzhiyun 
1974*4882a593Smuzhiyun 	spin_unlock_irq(&korg1212->lock);
1975*4882a593Smuzhiyun 	return 0;
1976*4882a593Smuzhiyun }
1977*4882a593Smuzhiyun 
snd_korg1212_control_sync_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1978*4882a593Smuzhiyun static int snd_korg1212_control_sync_put(struct snd_kcontrol *kcontrol,
1979*4882a593Smuzhiyun 					 struct snd_ctl_elem_value *ucontrol)
1980*4882a593Smuzhiyun {
1981*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
1982*4882a593Smuzhiyun 	unsigned int val;
1983*4882a593Smuzhiyun 	int change;
1984*4882a593Smuzhiyun 
1985*4882a593Smuzhiyun 	val = ucontrol->value.enumerated.item[0] % 3;
1986*4882a593Smuzhiyun 	spin_lock_irq(&korg1212->lock);
1987*4882a593Smuzhiyun 	change = val != korg1212->clkSource;
1988*4882a593Smuzhiyun         snd_korg1212_SetClockSource(korg1212, val);
1989*4882a593Smuzhiyun 	spin_unlock_irq(&korg1212->lock);
1990*4882a593Smuzhiyun 	return change;
1991*4882a593Smuzhiyun }
1992*4882a593Smuzhiyun 
1993*4882a593Smuzhiyun #define MON_MIXER(ord,c_name)									\
1994*4882a593Smuzhiyun         {											\
1995*4882a593Smuzhiyun                 .access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,	\
1996*4882a593Smuzhiyun                 .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,					\
1997*4882a593Smuzhiyun                 .name =		c_name " Monitor Volume",					\
1998*4882a593Smuzhiyun                 .info =		snd_korg1212_control_volume_info,				\
1999*4882a593Smuzhiyun                 .get =		snd_korg1212_control_volume_get,				\
2000*4882a593Smuzhiyun                 .put =		snd_korg1212_control_volume_put,				\
2001*4882a593Smuzhiyun 		.private_value = ord,								\
2002*4882a593Smuzhiyun         },                                                                                      \
2003*4882a593Smuzhiyun         {											\
2004*4882a593Smuzhiyun                 .access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,	\
2005*4882a593Smuzhiyun                 .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,					\
2006*4882a593Smuzhiyun                 .name =		c_name " Monitor Route",					\
2007*4882a593Smuzhiyun                 .info =		snd_korg1212_control_route_info,				\
2008*4882a593Smuzhiyun                 .get =		snd_korg1212_control_route_get,					\
2009*4882a593Smuzhiyun                 .put =		snd_korg1212_control_route_put,					\
2010*4882a593Smuzhiyun 		.private_value = ord,								\
2011*4882a593Smuzhiyun         },                                                                                      \
2012*4882a593Smuzhiyun         {											\
2013*4882a593Smuzhiyun                 .access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,	\
2014*4882a593Smuzhiyun                 .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,					\
2015*4882a593Smuzhiyun                 .name =		c_name " Monitor Phase Invert",					\
2016*4882a593Smuzhiyun                 .info =		snd_korg1212_control_phase_info,				\
2017*4882a593Smuzhiyun                 .get =		snd_korg1212_control_phase_get,					\
2018*4882a593Smuzhiyun                 .put =		snd_korg1212_control_phase_put,					\
2019*4882a593Smuzhiyun 		.private_value = ord,								\
2020*4882a593Smuzhiyun         }
2021*4882a593Smuzhiyun 
2022*4882a593Smuzhiyun static const struct snd_kcontrol_new snd_korg1212_controls[] = {
2023*4882a593Smuzhiyun         MON_MIXER(8, "Analog"),
2024*4882a593Smuzhiyun 	MON_MIXER(10, "SPDIF"),
2025*4882a593Smuzhiyun         MON_MIXER(0, "ADAT-1"), MON_MIXER(1, "ADAT-2"), MON_MIXER(2, "ADAT-3"), MON_MIXER(3, "ADAT-4"),
2026*4882a593Smuzhiyun         MON_MIXER(4, "ADAT-5"), MON_MIXER(5, "ADAT-6"), MON_MIXER(6, "ADAT-7"), MON_MIXER(7, "ADAT-8"),
2027*4882a593Smuzhiyun 	{
2028*4882a593Smuzhiyun                 .access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,
2029*4882a593Smuzhiyun                 .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
2030*4882a593Smuzhiyun                 .name =		"Sync Source",
2031*4882a593Smuzhiyun                 .info =		snd_korg1212_control_sync_info,
2032*4882a593Smuzhiyun                 .get =		snd_korg1212_control_sync_get,
2033*4882a593Smuzhiyun                 .put =		snd_korg1212_control_sync_put,
2034*4882a593Smuzhiyun         },
2035*4882a593Smuzhiyun         {
2036*4882a593Smuzhiyun                 .access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,
2037*4882a593Smuzhiyun                 .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
2038*4882a593Smuzhiyun                 .name =		"ADC Attenuation",
2039*4882a593Smuzhiyun                 .info =		snd_korg1212_control_info,
2040*4882a593Smuzhiyun                 .get =		snd_korg1212_control_get,
2041*4882a593Smuzhiyun                 .put =		snd_korg1212_control_put,
2042*4882a593Smuzhiyun         }
2043*4882a593Smuzhiyun };
2044*4882a593Smuzhiyun 
2045*4882a593Smuzhiyun /*
2046*4882a593Smuzhiyun  * proc interface
2047*4882a593Smuzhiyun  */
2048*4882a593Smuzhiyun 
snd_korg1212_proc_read(struct snd_info_entry * entry,struct snd_info_buffer * buffer)2049*4882a593Smuzhiyun static void snd_korg1212_proc_read(struct snd_info_entry *entry,
2050*4882a593Smuzhiyun 				   struct snd_info_buffer *buffer)
2051*4882a593Smuzhiyun {
2052*4882a593Smuzhiyun 	int n;
2053*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212 = entry->private_data;
2054*4882a593Smuzhiyun 
2055*4882a593Smuzhiyun 	snd_iprintf(buffer, korg1212->card->longname);
2056*4882a593Smuzhiyun 	snd_iprintf(buffer, " (index #%d)\n", korg1212->card->number + 1);
2057*4882a593Smuzhiyun 	snd_iprintf(buffer, "\nGeneral settings\n");
2058*4882a593Smuzhiyun 	snd_iprintf(buffer, "    period size: %zd bytes\n", K1212_PERIOD_BYTES);
2059*4882a593Smuzhiyun 	snd_iprintf(buffer, "     clock mode: %s\n", clockSourceName[korg1212->clkSrcRate] );
2060*4882a593Smuzhiyun 	snd_iprintf(buffer, "  left ADC Sens: %d\n", korg1212->leftADCInSens );
2061*4882a593Smuzhiyun 	snd_iprintf(buffer, " right ADC Sens: %d\n", korg1212->rightADCInSens );
2062*4882a593Smuzhiyun         snd_iprintf(buffer, "    Volume Info:\n");
2063*4882a593Smuzhiyun         for (n=0; n<kAudioChannels; n++)
2064*4882a593Smuzhiyun                 snd_iprintf(buffer, " Channel %d: %s -> %s [%d]\n", n,
2065*4882a593Smuzhiyun                                     channelName[n],
2066*4882a593Smuzhiyun                                     channelName[korg1212->sharedBufferPtr->routeData[n]],
2067*4882a593Smuzhiyun                                     korg1212->sharedBufferPtr->volumeData[n]);
2068*4882a593Smuzhiyun 	snd_iprintf(buffer, "\nGeneral status\n");
2069*4882a593Smuzhiyun         snd_iprintf(buffer, " ADAT Time Code: %d\n", korg1212->sharedBufferPtr->AdatTimeCode);
2070*4882a593Smuzhiyun         snd_iprintf(buffer, "     Card State: %s\n", stateName[korg1212->cardState]);
2071*4882a593Smuzhiyun         snd_iprintf(buffer, "Idle mon. State: %d\n", korg1212->idleMonitorOn);
2072*4882a593Smuzhiyun         snd_iprintf(buffer, "Cmd retry count: %d\n", korg1212->cmdRetryCount);
2073*4882a593Smuzhiyun         snd_iprintf(buffer, "      Irq count: %ld\n", korg1212->irqcount);
2074*4882a593Smuzhiyun         snd_iprintf(buffer, "    Error count: %ld\n", korg1212->totalerrorcnt);
2075*4882a593Smuzhiyun }
2076*4882a593Smuzhiyun 
snd_korg1212_proc_init(struct snd_korg1212 * korg1212)2077*4882a593Smuzhiyun static void snd_korg1212_proc_init(struct snd_korg1212 *korg1212)
2078*4882a593Smuzhiyun {
2079*4882a593Smuzhiyun 	snd_card_ro_proc_new(korg1212->card, "korg1212", korg1212,
2080*4882a593Smuzhiyun 			     snd_korg1212_proc_read);
2081*4882a593Smuzhiyun }
2082*4882a593Smuzhiyun 
2083*4882a593Smuzhiyun static int
snd_korg1212_free(struct snd_korg1212 * korg1212)2084*4882a593Smuzhiyun snd_korg1212_free(struct snd_korg1212 *korg1212)
2085*4882a593Smuzhiyun {
2086*4882a593Smuzhiyun         snd_korg1212_TurnOffIdleMonitor(korg1212);
2087*4882a593Smuzhiyun 
2088*4882a593Smuzhiyun         if (korg1212->irq >= 0) {
2089*4882a593Smuzhiyun                 snd_korg1212_DisableCardInterrupts(korg1212);
2090*4882a593Smuzhiyun                 free_irq(korg1212->irq, korg1212);
2091*4882a593Smuzhiyun                 korg1212->irq = -1;
2092*4882a593Smuzhiyun         }
2093*4882a593Smuzhiyun 
2094*4882a593Smuzhiyun         if (korg1212->iobase != NULL) {
2095*4882a593Smuzhiyun                 iounmap(korg1212->iobase);
2096*4882a593Smuzhiyun                 korg1212->iobase = NULL;
2097*4882a593Smuzhiyun         }
2098*4882a593Smuzhiyun 
2099*4882a593Smuzhiyun 	pci_release_regions(korg1212->pci);
2100*4882a593Smuzhiyun 
2101*4882a593Smuzhiyun         // ----------------------------------------------------
2102*4882a593Smuzhiyun         // free up memory resources used for the DSP download.
2103*4882a593Smuzhiyun         // ----------------------------------------------------
2104*4882a593Smuzhiyun         if (korg1212->dma_dsp.area) {
2105*4882a593Smuzhiyun         	snd_dma_free_pages(&korg1212->dma_dsp);
2106*4882a593Smuzhiyun         	korg1212->dma_dsp.area = NULL;
2107*4882a593Smuzhiyun         }
2108*4882a593Smuzhiyun 
2109*4882a593Smuzhiyun #ifndef K1212_LARGEALLOC
2110*4882a593Smuzhiyun 
2111*4882a593Smuzhiyun         // ------------------------------------------------------
2112*4882a593Smuzhiyun         // free up memory resources used for the Play/Rec Buffers
2113*4882a593Smuzhiyun         // ------------------------------------------------------
2114*4882a593Smuzhiyun 	if (korg1212->dma_play.area) {
2115*4882a593Smuzhiyun 		snd_dma_free_pages(&korg1212->dma_play);
2116*4882a593Smuzhiyun 		korg1212->dma_play.area = NULL;
2117*4882a593Smuzhiyun         }
2118*4882a593Smuzhiyun 
2119*4882a593Smuzhiyun 	if (korg1212->dma_rec.area) {
2120*4882a593Smuzhiyun 		snd_dma_free_pages(&korg1212->dma_rec);
2121*4882a593Smuzhiyun 		korg1212->dma_rec.area = NULL;
2122*4882a593Smuzhiyun         }
2123*4882a593Smuzhiyun 
2124*4882a593Smuzhiyun #endif
2125*4882a593Smuzhiyun 
2126*4882a593Smuzhiyun         // ----------------------------------------------------
2127*4882a593Smuzhiyun         // free up memory resources used for the Shared Buffers
2128*4882a593Smuzhiyun         // ----------------------------------------------------
2129*4882a593Smuzhiyun 	if (korg1212->dma_shared.area) {
2130*4882a593Smuzhiyun 		snd_dma_free_pages(&korg1212->dma_shared);
2131*4882a593Smuzhiyun 		korg1212->dma_shared.area = NULL;
2132*4882a593Smuzhiyun         }
2133*4882a593Smuzhiyun 
2134*4882a593Smuzhiyun 	pci_disable_device(korg1212->pci);
2135*4882a593Smuzhiyun         kfree(korg1212);
2136*4882a593Smuzhiyun         return 0;
2137*4882a593Smuzhiyun }
2138*4882a593Smuzhiyun 
snd_korg1212_dev_free(struct snd_device * device)2139*4882a593Smuzhiyun static int snd_korg1212_dev_free(struct snd_device *device)
2140*4882a593Smuzhiyun {
2141*4882a593Smuzhiyun         struct snd_korg1212 *korg1212 = device->device_data;
2142*4882a593Smuzhiyun         K1212_DEBUG_PRINTK("K1212_DEBUG: Freeing device\n");
2143*4882a593Smuzhiyun 	return snd_korg1212_free(korg1212);
2144*4882a593Smuzhiyun }
2145*4882a593Smuzhiyun 
snd_korg1212_create(struct snd_card * card,struct pci_dev * pci,struct snd_korg1212 ** rchip)2146*4882a593Smuzhiyun static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
2147*4882a593Smuzhiyun 			       struct snd_korg1212 **rchip)
2148*4882a593Smuzhiyun 
2149*4882a593Smuzhiyun {
2150*4882a593Smuzhiyun         int err, rc;
2151*4882a593Smuzhiyun         unsigned int i;
2152*4882a593Smuzhiyun 	unsigned iomem_size;
2153*4882a593Smuzhiyun 	__maybe_unused unsigned ioport_size;
2154*4882a593Smuzhiyun 	__maybe_unused unsigned iomem2_size;
2155*4882a593Smuzhiyun         struct snd_korg1212 * korg1212;
2156*4882a593Smuzhiyun 	const struct firmware *dsp_code;
2157*4882a593Smuzhiyun 
2158*4882a593Smuzhiyun 	static const struct snd_device_ops ops = {
2159*4882a593Smuzhiyun                 .dev_free = snd_korg1212_dev_free,
2160*4882a593Smuzhiyun         };
2161*4882a593Smuzhiyun 
2162*4882a593Smuzhiyun         * rchip = NULL;
2163*4882a593Smuzhiyun         if ((err = pci_enable_device(pci)) < 0)
2164*4882a593Smuzhiyun                 return err;
2165*4882a593Smuzhiyun 
2166*4882a593Smuzhiyun         korg1212 = kzalloc(sizeof(*korg1212), GFP_KERNEL);
2167*4882a593Smuzhiyun         if (korg1212 == NULL) {
2168*4882a593Smuzhiyun 		pci_disable_device(pci);
2169*4882a593Smuzhiyun                 return -ENOMEM;
2170*4882a593Smuzhiyun 	}
2171*4882a593Smuzhiyun 
2172*4882a593Smuzhiyun 	korg1212->card = card;
2173*4882a593Smuzhiyun 	korg1212->pci = pci;
2174*4882a593Smuzhiyun 
2175*4882a593Smuzhiyun         init_waitqueue_head(&korg1212->wait);
2176*4882a593Smuzhiyun         spin_lock_init(&korg1212->lock);
2177*4882a593Smuzhiyun 	mutex_init(&korg1212->open_mutex);
2178*4882a593Smuzhiyun 	timer_setup(&korg1212->timer, snd_korg1212_timer_func, 0);
2179*4882a593Smuzhiyun 
2180*4882a593Smuzhiyun         korg1212->irq = -1;
2181*4882a593Smuzhiyun         korg1212->clkSource = K1212_CLKIDX_Local;
2182*4882a593Smuzhiyun         korg1212->clkRate = 44100;
2183*4882a593Smuzhiyun         korg1212->inIRQ = 0;
2184*4882a593Smuzhiyun         korg1212->running = 0;
2185*4882a593Smuzhiyun 	korg1212->opencnt = 0;
2186*4882a593Smuzhiyun 	korg1212->playcnt = 0;
2187*4882a593Smuzhiyun 	korg1212->setcnt = 0;
2188*4882a593Smuzhiyun 	korg1212->totalerrorcnt = 0;
2189*4882a593Smuzhiyun 	korg1212->playback_pid = -1;
2190*4882a593Smuzhiyun 	korg1212->capture_pid = -1;
2191*4882a593Smuzhiyun         snd_korg1212_setCardState(korg1212, K1212_STATE_UNINITIALIZED);
2192*4882a593Smuzhiyun         korg1212->idleMonitorOn = 0;
2193*4882a593Smuzhiyun         korg1212->clkSrcRate = K1212_CLKIDX_LocalAt44_1K;
2194*4882a593Smuzhiyun         korg1212->leftADCInSens = k1212MaxADCSens;
2195*4882a593Smuzhiyun         korg1212->rightADCInSens = k1212MaxADCSens;
2196*4882a593Smuzhiyun 
2197*4882a593Smuzhiyun         for (i=0; i<kAudioChannels; i++)
2198*4882a593Smuzhiyun                 korg1212->volumePhase[i] = 0;
2199*4882a593Smuzhiyun 
2200*4882a593Smuzhiyun 	if ((err = pci_request_regions(pci, "korg1212")) < 0) {
2201*4882a593Smuzhiyun 		kfree(korg1212);
2202*4882a593Smuzhiyun 		pci_disable_device(pci);
2203*4882a593Smuzhiyun 		return err;
2204*4882a593Smuzhiyun 	}
2205*4882a593Smuzhiyun 
2206*4882a593Smuzhiyun         korg1212->iomem = pci_resource_start(korg1212->pci, 0);
2207*4882a593Smuzhiyun         korg1212->ioport = pci_resource_start(korg1212->pci, 1);
2208*4882a593Smuzhiyun         korg1212->iomem2 = pci_resource_start(korg1212->pci, 2);
2209*4882a593Smuzhiyun 
2210*4882a593Smuzhiyun 	iomem_size = pci_resource_len(korg1212->pci, 0);
2211*4882a593Smuzhiyun 	ioport_size = pci_resource_len(korg1212->pci, 1);
2212*4882a593Smuzhiyun 	iomem2_size = pci_resource_len(korg1212->pci, 2);
2213*4882a593Smuzhiyun 
2214*4882a593Smuzhiyun         K1212_DEBUG_PRINTK("K1212_DEBUG: resources:\n"
2215*4882a593Smuzhiyun                    "    iomem = 0x%lx (%d)\n"
2216*4882a593Smuzhiyun 		   "    ioport  = 0x%lx (%d)\n"
2217*4882a593Smuzhiyun                    "    iomem = 0x%lx (%d)\n"
2218*4882a593Smuzhiyun 		   "    [%s]\n",
2219*4882a593Smuzhiyun 		   korg1212->iomem, iomem_size,
2220*4882a593Smuzhiyun 		   korg1212->ioport, ioport_size,
2221*4882a593Smuzhiyun 		   korg1212->iomem2, iomem2_size,
2222*4882a593Smuzhiyun 		   stateName[korg1212->cardState]);
2223*4882a593Smuzhiyun 
2224*4882a593Smuzhiyun         if ((korg1212->iobase = ioremap(korg1212->iomem, iomem_size)) == NULL) {
2225*4882a593Smuzhiyun 		snd_printk(KERN_ERR "korg1212: unable to remap memory region 0x%lx-0x%lx\n", korg1212->iomem,
2226*4882a593Smuzhiyun                            korg1212->iomem + iomem_size - 1);
2227*4882a593Smuzhiyun                 snd_korg1212_free(korg1212);
2228*4882a593Smuzhiyun                 return -EBUSY;
2229*4882a593Smuzhiyun         }
2230*4882a593Smuzhiyun 
2231*4882a593Smuzhiyun         err = request_irq(pci->irq, snd_korg1212_interrupt,
2232*4882a593Smuzhiyun                           IRQF_SHARED,
2233*4882a593Smuzhiyun                           KBUILD_MODNAME, korg1212);
2234*4882a593Smuzhiyun 
2235*4882a593Smuzhiyun         if (err) {
2236*4882a593Smuzhiyun 		snd_printk(KERN_ERR "korg1212: unable to grab IRQ %d\n", pci->irq);
2237*4882a593Smuzhiyun                 snd_korg1212_free(korg1212);
2238*4882a593Smuzhiyun                 return -EBUSY;
2239*4882a593Smuzhiyun         }
2240*4882a593Smuzhiyun 
2241*4882a593Smuzhiyun         korg1212->irq = pci->irq;
2242*4882a593Smuzhiyun 	card->sync_irq = korg1212->irq;
2243*4882a593Smuzhiyun 
2244*4882a593Smuzhiyun 	pci_set_master(korg1212->pci);
2245*4882a593Smuzhiyun 
2246*4882a593Smuzhiyun         korg1212->statusRegPtr = (u32 __iomem *) (korg1212->iobase + STATUS_REG_OFFSET);
2247*4882a593Smuzhiyun         korg1212->outDoorbellPtr = (u32 __iomem *) (korg1212->iobase + OUT_DOORBELL_OFFSET);
2248*4882a593Smuzhiyun         korg1212->inDoorbellPtr = (u32 __iomem *) (korg1212->iobase + IN_DOORBELL_OFFSET);
2249*4882a593Smuzhiyun         korg1212->mailbox0Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX0_OFFSET);
2250*4882a593Smuzhiyun         korg1212->mailbox1Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX1_OFFSET);
2251*4882a593Smuzhiyun         korg1212->mailbox2Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX2_OFFSET);
2252*4882a593Smuzhiyun         korg1212->mailbox3Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX3_OFFSET);
2253*4882a593Smuzhiyun         korg1212->controlRegPtr = (u32 __iomem *) (korg1212->iobase + PCI_CONTROL_OFFSET);
2254*4882a593Smuzhiyun         korg1212->sensRegPtr = (u16 __iomem *) (korg1212->iobase + SENS_CONTROL_OFFSET);
2255*4882a593Smuzhiyun         korg1212->idRegPtr = (u32 __iomem *) (korg1212->iobase + DEV_VEND_ID_OFFSET);
2256*4882a593Smuzhiyun 
2257*4882a593Smuzhiyun         K1212_DEBUG_PRINTK("K1212_DEBUG: card registers:\n"
2258*4882a593Smuzhiyun                    "    Status register = 0x%p\n"
2259*4882a593Smuzhiyun                    "    OutDoorbell     = 0x%p\n"
2260*4882a593Smuzhiyun                    "    InDoorbell      = 0x%p\n"
2261*4882a593Smuzhiyun                    "    Mailbox0        = 0x%p\n"
2262*4882a593Smuzhiyun                    "    Mailbox1        = 0x%p\n"
2263*4882a593Smuzhiyun                    "    Mailbox2        = 0x%p\n"
2264*4882a593Smuzhiyun                    "    Mailbox3        = 0x%p\n"
2265*4882a593Smuzhiyun                    "    ControlReg      = 0x%p\n"
2266*4882a593Smuzhiyun                    "    SensReg         = 0x%p\n"
2267*4882a593Smuzhiyun                    "    IDReg           = 0x%p\n"
2268*4882a593Smuzhiyun 		   "    [%s]\n",
2269*4882a593Smuzhiyun                    korg1212->statusRegPtr,
2270*4882a593Smuzhiyun 		   korg1212->outDoorbellPtr,
2271*4882a593Smuzhiyun 		   korg1212->inDoorbellPtr,
2272*4882a593Smuzhiyun                    korg1212->mailbox0Ptr,
2273*4882a593Smuzhiyun                    korg1212->mailbox1Ptr,
2274*4882a593Smuzhiyun                    korg1212->mailbox2Ptr,
2275*4882a593Smuzhiyun                    korg1212->mailbox3Ptr,
2276*4882a593Smuzhiyun                    korg1212->controlRegPtr,
2277*4882a593Smuzhiyun                    korg1212->sensRegPtr,
2278*4882a593Smuzhiyun                    korg1212->idRegPtr,
2279*4882a593Smuzhiyun 		   stateName[korg1212->cardState]);
2280*4882a593Smuzhiyun 
2281*4882a593Smuzhiyun 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
2282*4882a593Smuzhiyun 				sizeof(struct KorgSharedBuffer), &korg1212->dma_shared) < 0) {
2283*4882a593Smuzhiyun 		snd_printk(KERN_ERR "korg1212: can not allocate shared buffer memory (%zd bytes)\n", sizeof(struct KorgSharedBuffer));
2284*4882a593Smuzhiyun                 snd_korg1212_free(korg1212);
2285*4882a593Smuzhiyun                 return -ENOMEM;
2286*4882a593Smuzhiyun         }
2287*4882a593Smuzhiyun         korg1212->sharedBufferPtr = (struct KorgSharedBuffer *)korg1212->dma_shared.area;
2288*4882a593Smuzhiyun         korg1212->sharedBufferPhy = korg1212->dma_shared.addr;
2289*4882a593Smuzhiyun 
2290*4882a593Smuzhiyun         K1212_DEBUG_PRINTK("K1212_DEBUG: Shared Buffer Area = 0x%p (0x%08lx), %d bytes\n", korg1212->sharedBufferPtr, korg1212->sharedBufferPhy, sizeof(struct KorgSharedBuffer));
2291*4882a593Smuzhiyun 
2292*4882a593Smuzhiyun #ifndef K1212_LARGEALLOC
2293*4882a593Smuzhiyun 
2294*4882a593Smuzhiyun         korg1212->DataBufsSize = sizeof(struct KorgAudioBuffer) * kNumBuffers;
2295*4882a593Smuzhiyun 
2296*4882a593Smuzhiyun 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
2297*4882a593Smuzhiyun 				korg1212->DataBufsSize, &korg1212->dma_play) < 0) {
2298*4882a593Smuzhiyun 		snd_printk(KERN_ERR "korg1212: can not allocate play data buffer memory (%d bytes)\n", korg1212->DataBufsSize);
2299*4882a593Smuzhiyun                 snd_korg1212_free(korg1212);
2300*4882a593Smuzhiyun                 return -ENOMEM;
2301*4882a593Smuzhiyun         }
2302*4882a593Smuzhiyun 	korg1212->playDataBufsPtr = (struct KorgAudioBuffer *)korg1212->dma_play.area;
2303*4882a593Smuzhiyun 	korg1212->PlayDataPhy = korg1212->dma_play.addr;
2304*4882a593Smuzhiyun 
2305*4882a593Smuzhiyun         K1212_DEBUG_PRINTK("K1212_DEBUG: Play Data Area = 0x%p (0x%08x), %d bytes\n",
2306*4882a593Smuzhiyun 		korg1212->playDataBufsPtr, korg1212->PlayDataPhy, korg1212->DataBufsSize);
2307*4882a593Smuzhiyun 
2308*4882a593Smuzhiyun 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
2309*4882a593Smuzhiyun 				korg1212->DataBufsSize, &korg1212->dma_rec) < 0) {
2310*4882a593Smuzhiyun 		snd_printk(KERN_ERR "korg1212: can not allocate record data buffer memory (%d bytes)\n", korg1212->DataBufsSize);
2311*4882a593Smuzhiyun                 snd_korg1212_free(korg1212);
2312*4882a593Smuzhiyun                 return -ENOMEM;
2313*4882a593Smuzhiyun         }
2314*4882a593Smuzhiyun         korg1212->recordDataBufsPtr = (struct KorgAudioBuffer *)korg1212->dma_rec.area;
2315*4882a593Smuzhiyun         korg1212->RecDataPhy = korg1212->dma_rec.addr;
2316*4882a593Smuzhiyun 
2317*4882a593Smuzhiyun         K1212_DEBUG_PRINTK("K1212_DEBUG: Record Data Area = 0x%p (0x%08x), %d bytes\n",
2318*4882a593Smuzhiyun 		korg1212->recordDataBufsPtr, korg1212->RecDataPhy, korg1212->DataBufsSize);
2319*4882a593Smuzhiyun 
2320*4882a593Smuzhiyun #else // K1212_LARGEALLOC
2321*4882a593Smuzhiyun 
2322*4882a593Smuzhiyun         korg1212->recordDataBufsPtr = korg1212->sharedBufferPtr->recordDataBufs;
2323*4882a593Smuzhiyun         korg1212->playDataBufsPtr = korg1212->sharedBufferPtr->playDataBufs;
2324*4882a593Smuzhiyun         korg1212->PlayDataPhy = (u32) &((struct KorgSharedBuffer *) korg1212->sharedBufferPhy)->playDataBufs;
2325*4882a593Smuzhiyun         korg1212->RecDataPhy  = (u32) &((struct KorgSharedBuffer *) korg1212->sharedBufferPhy)->recordDataBufs;
2326*4882a593Smuzhiyun 
2327*4882a593Smuzhiyun #endif // K1212_LARGEALLOC
2328*4882a593Smuzhiyun 
2329*4882a593Smuzhiyun         korg1212->VolumeTablePhy = korg1212->sharedBufferPhy +
2330*4882a593Smuzhiyun 		offsetof(struct KorgSharedBuffer, volumeData);
2331*4882a593Smuzhiyun         korg1212->RoutingTablePhy = korg1212->sharedBufferPhy +
2332*4882a593Smuzhiyun 		offsetof(struct KorgSharedBuffer, routeData);
2333*4882a593Smuzhiyun         korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
2334*4882a593Smuzhiyun 		offsetof(struct KorgSharedBuffer, AdatTimeCode);
2335*4882a593Smuzhiyun 
2336*4882a593Smuzhiyun 	err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev);
2337*4882a593Smuzhiyun 	if (err < 0) {
2338*4882a593Smuzhiyun 		snd_printk(KERN_ERR "firmware not available\n");
2339*4882a593Smuzhiyun 		snd_korg1212_free(korg1212);
2340*4882a593Smuzhiyun 		return err;
2341*4882a593Smuzhiyun 	}
2342*4882a593Smuzhiyun 
2343*4882a593Smuzhiyun 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
2344*4882a593Smuzhiyun 				dsp_code->size, &korg1212->dma_dsp) < 0) {
2345*4882a593Smuzhiyun 		snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size);
2346*4882a593Smuzhiyun                 snd_korg1212_free(korg1212);
2347*4882a593Smuzhiyun 		release_firmware(dsp_code);
2348*4882a593Smuzhiyun                 return -ENOMEM;
2349*4882a593Smuzhiyun         }
2350*4882a593Smuzhiyun 
2351*4882a593Smuzhiyun         K1212_DEBUG_PRINTK("K1212_DEBUG: DSP Code area = 0x%p (0x%08x) %d bytes [%s]\n",
2352*4882a593Smuzhiyun 		   korg1212->dma_dsp.area, korg1212->dma_dsp.addr, dsp_code->size,
2353*4882a593Smuzhiyun 		   stateName[korg1212->cardState]);
2354*4882a593Smuzhiyun 
2355*4882a593Smuzhiyun 	memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size);
2356*4882a593Smuzhiyun 
2357*4882a593Smuzhiyun 	release_firmware(dsp_code);
2358*4882a593Smuzhiyun 
2359*4882a593Smuzhiyun 	rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0);
2360*4882a593Smuzhiyun 
2361*4882a593Smuzhiyun 	if (rc)
2362*4882a593Smuzhiyun 		K1212_DEBUG_PRINTK("K1212_DEBUG: Reboot Card - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
2363*4882a593Smuzhiyun 
2364*4882a593Smuzhiyun         if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, korg1212, &ops)) < 0) {
2365*4882a593Smuzhiyun                 snd_korg1212_free(korg1212);
2366*4882a593Smuzhiyun                 return err;
2367*4882a593Smuzhiyun         }
2368*4882a593Smuzhiyun 
2369*4882a593Smuzhiyun 	snd_korg1212_EnableCardInterrupts(korg1212);
2370*4882a593Smuzhiyun 
2371*4882a593Smuzhiyun 	mdelay(CARD_BOOT_DELAY_IN_MS);
2372*4882a593Smuzhiyun 
2373*4882a593Smuzhiyun         if (snd_korg1212_downloadDSPCode(korg1212))
2374*4882a593Smuzhiyun         	return -EBUSY;
2375*4882a593Smuzhiyun 
2376*4882a593Smuzhiyun         K1212_DEBUG_PRINTK("korg1212: dspMemPhy = %08x U[%08x], "
2377*4882a593Smuzhiyun                "PlayDataPhy = %08x L[%08x]\n"
2378*4882a593Smuzhiyun 	       "korg1212: RecDataPhy = %08x L[%08x], "
2379*4882a593Smuzhiyun                "VolumeTablePhy = %08x L[%08x]\n"
2380*4882a593Smuzhiyun                "korg1212: RoutingTablePhy = %08x L[%08x], "
2381*4882a593Smuzhiyun                "AdatTimeCodePhy = %08x L[%08x]\n",
2382*4882a593Smuzhiyun 	       (int)korg1212->dma_dsp.addr,    UpperWordSwap(korg1212->dma_dsp.addr),
2383*4882a593Smuzhiyun                korg1212->PlayDataPhy,     LowerWordSwap(korg1212->PlayDataPhy),
2384*4882a593Smuzhiyun                korg1212->RecDataPhy,      LowerWordSwap(korg1212->RecDataPhy),
2385*4882a593Smuzhiyun                korg1212->VolumeTablePhy,  LowerWordSwap(korg1212->VolumeTablePhy),
2386*4882a593Smuzhiyun                korg1212->RoutingTablePhy, LowerWordSwap(korg1212->RoutingTablePhy),
2387*4882a593Smuzhiyun                korg1212->AdatTimeCodePhy, LowerWordSwap(korg1212->AdatTimeCodePhy));
2388*4882a593Smuzhiyun 
2389*4882a593Smuzhiyun         if ((err = snd_pcm_new(korg1212->card, "korg1212", 0, 1, 1, &korg1212->pcm)) < 0)
2390*4882a593Smuzhiyun                 return err;
2391*4882a593Smuzhiyun 
2392*4882a593Smuzhiyun 	korg1212->pcm->private_data = korg1212;
2393*4882a593Smuzhiyun         korg1212->pcm->private_free = snd_korg1212_free_pcm;
2394*4882a593Smuzhiyun         strcpy(korg1212->pcm->name, "korg1212");
2395*4882a593Smuzhiyun 
2396*4882a593Smuzhiyun         snd_pcm_set_ops(korg1212->pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_korg1212_playback_ops);
2397*4882a593Smuzhiyun 
2398*4882a593Smuzhiyun 	snd_pcm_set_ops(korg1212->pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_korg1212_capture_ops);
2399*4882a593Smuzhiyun 
2400*4882a593Smuzhiyun 	korg1212->pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
2401*4882a593Smuzhiyun 
2402*4882a593Smuzhiyun         for (i = 0; i < ARRAY_SIZE(snd_korg1212_controls); i++) {
2403*4882a593Smuzhiyun                 err = snd_ctl_add(korg1212->card, snd_ctl_new1(&snd_korg1212_controls[i], korg1212));
2404*4882a593Smuzhiyun                 if (err < 0)
2405*4882a593Smuzhiyun                         return err;
2406*4882a593Smuzhiyun         }
2407*4882a593Smuzhiyun 
2408*4882a593Smuzhiyun         snd_korg1212_proc_init(korg1212);
2409*4882a593Smuzhiyun 
2410*4882a593Smuzhiyun         * rchip = korg1212;
2411*4882a593Smuzhiyun 	return 0;
2412*4882a593Smuzhiyun 
2413*4882a593Smuzhiyun }
2414*4882a593Smuzhiyun 
2415*4882a593Smuzhiyun /*
2416*4882a593Smuzhiyun  * Card initialisation
2417*4882a593Smuzhiyun  */
2418*4882a593Smuzhiyun 
2419*4882a593Smuzhiyun static int
snd_korg1212_probe(struct pci_dev * pci,const struct pci_device_id * pci_id)2420*4882a593Smuzhiyun snd_korg1212_probe(struct pci_dev *pci,
2421*4882a593Smuzhiyun 		const struct pci_device_id *pci_id)
2422*4882a593Smuzhiyun {
2423*4882a593Smuzhiyun 	static int dev;
2424*4882a593Smuzhiyun 	struct snd_korg1212 *korg1212;
2425*4882a593Smuzhiyun 	struct snd_card *card;
2426*4882a593Smuzhiyun 	int err;
2427*4882a593Smuzhiyun 
2428*4882a593Smuzhiyun 	if (dev >= SNDRV_CARDS) {
2429*4882a593Smuzhiyun 		return -ENODEV;
2430*4882a593Smuzhiyun 	}
2431*4882a593Smuzhiyun 	if (!enable[dev]) {
2432*4882a593Smuzhiyun 		dev++;
2433*4882a593Smuzhiyun 		return -ENOENT;
2434*4882a593Smuzhiyun 	}
2435*4882a593Smuzhiyun 	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
2436*4882a593Smuzhiyun 			   0, &card);
2437*4882a593Smuzhiyun 	if (err < 0)
2438*4882a593Smuzhiyun 		return err;
2439*4882a593Smuzhiyun 
2440*4882a593Smuzhiyun         if ((err = snd_korg1212_create(card, pci, &korg1212)) < 0) {
2441*4882a593Smuzhiyun 		snd_card_free(card);
2442*4882a593Smuzhiyun 		return err;
2443*4882a593Smuzhiyun 	}
2444*4882a593Smuzhiyun 
2445*4882a593Smuzhiyun 	strcpy(card->driver, "korg1212");
2446*4882a593Smuzhiyun 	strcpy(card->shortname, "korg1212");
2447*4882a593Smuzhiyun 	sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname,
2448*4882a593Smuzhiyun 		korg1212->iomem, korg1212->irq);
2449*4882a593Smuzhiyun 
2450*4882a593Smuzhiyun         K1212_DEBUG_PRINTK("K1212_DEBUG: %s\n", card->longname);
2451*4882a593Smuzhiyun 
2452*4882a593Smuzhiyun 	if ((err = snd_card_register(card)) < 0) {
2453*4882a593Smuzhiyun 		snd_card_free(card);
2454*4882a593Smuzhiyun 		return err;
2455*4882a593Smuzhiyun 	}
2456*4882a593Smuzhiyun 	pci_set_drvdata(pci, card);
2457*4882a593Smuzhiyun 	dev++;
2458*4882a593Smuzhiyun 	return 0;
2459*4882a593Smuzhiyun }
2460*4882a593Smuzhiyun 
snd_korg1212_remove(struct pci_dev * pci)2461*4882a593Smuzhiyun static void snd_korg1212_remove(struct pci_dev *pci)
2462*4882a593Smuzhiyun {
2463*4882a593Smuzhiyun 	snd_card_free(pci_get_drvdata(pci));
2464*4882a593Smuzhiyun }
2465*4882a593Smuzhiyun 
2466*4882a593Smuzhiyun static struct pci_driver korg1212_driver = {
2467*4882a593Smuzhiyun 	.name = KBUILD_MODNAME,
2468*4882a593Smuzhiyun 	.id_table = snd_korg1212_ids,
2469*4882a593Smuzhiyun 	.probe = snd_korg1212_probe,
2470*4882a593Smuzhiyun 	.remove = snd_korg1212_remove,
2471*4882a593Smuzhiyun };
2472*4882a593Smuzhiyun 
2473*4882a593Smuzhiyun module_pci_driver(korg1212_driver);
2474