@@ -131,13 +131,19 @@ enum card_type {
131131struct soundscape {
132132 spinlock_t lock ;
133133 unsigned io_base ;
134+ unsigned long wss_base ;
135+ int irq ;
136+ int mpu_irq ;
137+ int dma1 ;
138+ int dma2 ;
134139 int ic_type ;
135140 enum card_type type ;
136141 struct resource * io_res ;
137142 struct resource * wss_res ;
138143 struct snd_wss * chip ;
139144
140145 unsigned char midi_vol ;
146+ bool joystick ;
141147 struct device * dev ;
142148};
143149
@@ -149,6 +155,21 @@ static inline struct soundscape *get_card_soundscape(struct snd_card *c)
149155 return (struct soundscape * ) (c -> private_data );
150156}
151157
158+ /*
159+ * Store the resolved board settings in the per-card state so that
160+ * the same configuration can be replayed later if necessary.
161+ */
162+ static void sscape_store_settings (struct soundscape * sscape , int dev )
163+ {
164+ sscape -> io_base = port [dev ];
165+ sscape -> wss_base = wss_port [dev ];
166+ sscape -> irq = irq [dev ];
167+ sscape -> mpu_irq = mpu_irq [dev ];
168+ sscape -> dma1 = dma [dev ];
169+ sscape -> dma2 = dma2 [dev ];
170+ sscape -> joystick = joystick [dev ];
171+ }
172+
152173/*
153174 * Allocates some kernel memory that we can use for DMA.
154175 * I think this means that the memory has to map to
@@ -263,34 +284,36 @@ static int host_read_ctrl_unsafe(unsigned io_base, unsigned timeout)
263284
264285/*
265286 * Write to the SoundScape's host-mode control registers, but
266- * leave any locking issues to the caller ...
287+ * leave any locking issues to the caller. Returns true if
288+ * the write succeeded.
267289 */
268- static inline int host_write_unsafe (unsigned io_base , unsigned char data )
290+ static inline bool host_write_unsafe (unsigned int io_base , unsigned char data )
269291{
270292 if ((inb (HOST_CTRL_IO (io_base )) & TX_READY ) != 0 ) {
271293 outb (data , HOST_DATA_IO (io_base ));
272- return 1 ;
294+ return true ;
273295 }
274296
275- return 0 ;
297+ return false ;
276298}
277299
278300/*
279301 * Write to the SoundScape's host-mode control registers, performing
280302 * a limited amount of busy-waiting if the register isn't ready.
281- * Also leaves all locking-issues to the caller ...
303+ * Also leaves all locking-issues to the caller. Returns true if
304+ * the write succeeded before timing out.
282305 */
283- static int host_write_ctrl_unsafe (unsigned io_base , unsigned char data ,
284- unsigned timeout )
306+ static bool host_write_ctrl_unsafe (unsigned int io_base , unsigned char data ,
307+ unsigned int timeout )
285308{
286- int err ;
309+ bool written ;
287310
288- while (!(err = host_write_unsafe (io_base , data )) && ( timeout != 0 ) ) {
311+ while (!(written = host_write_unsafe (io_base , data )) && timeout != 0 ) {
289312 udelay (100 );
290313 -- timeout ;
291314 } /* while */
292315
293- return err ;
316+ return written ;
294317}
295318
296319
@@ -560,6 +583,30 @@ static int sscape_upload_microcode(struct snd_card *card, int version)
560583 return err ;
561584}
562585
586+ /*
587+ * Restore the SoundScape's MIDI control state after the firmware
588+ * upload has made the host interface available again.
589+ */
590+ static int sscape_restore_midi_state (struct soundscape * sscape )
591+ {
592+ bool success ;
593+
594+ guard (spinlock_irqsave )(& sscape -> lock );
595+ set_host_mode_unsafe (sscape -> io_base );
596+
597+ success = host_write_ctrl_unsafe (sscape -> io_base , CMD_SET_MIDI_VOL , 100 ) &&
598+ host_write_ctrl_unsafe (sscape -> io_base , sscape -> midi_vol , 100 ) &&
599+ host_write_ctrl_unsafe (sscape -> io_base , CMD_XXX_MIDI_VOL , 100 ) &&
600+ host_write_ctrl_unsafe (sscape -> io_base , sscape -> midi_vol , 100 ) &&
601+ host_write_ctrl_unsafe (sscape -> io_base , CMD_SET_EXTMIDI , 100 ) &&
602+ host_write_ctrl_unsafe (sscape -> io_base , 0 , 100 ) &&
603+ host_write_ctrl_unsafe (sscape -> io_base , CMD_ACK , 100 );
604+
605+ set_midi_mode_unsafe (sscape -> io_base );
606+
607+ return success ? 0 : - EIO ;
608+ }
609+
563610/*
564611 * Mixer control for the SoundScape's MIDI device.
565612 */
@@ -660,6 +707,59 @@ static unsigned get_irq_config(int sscape_type, int irq)
660707 return INVALID_IRQ ;
661708}
662709
710+ /*
711+ * Program the SoundScape's board-specific routing and enable the
712+ * codec path using the resolved IRQ, DMA and joystick settings.
713+ */
714+ static int sscape_configure_board (struct soundscape * sscape )
715+ {
716+ unsigned int dma_cfg ;
717+ unsigned int irq_cfg ;
718+ unsigned int mpu_irq_cfg ;
719+ int val ;
720+
721+ irq_cfg = get_irq_config (sscape -> type , sscape -> irq );
722+ if (irq_cfg == INVALID_IRQ )
723+ return - ENXIO ;
724+
725+ mpu_irq_cfg = get_irq_config (sscape -> type , sscape -> mpu_irq );
726+ if (mpu_irq_cfg == INVALID_IRQ )
727+ return - ENXIO ;
728+
729+ scoped_guard (spinlock_irqsave , & sscape -> lock ) {
730+ if (sscape -> ic_type == IC_OPUS )
731+ activate_ad1845_unsafe (sscape -> io_base );
732+
733+ sscape_write_unsafe (sscape -> io_base , GA_SMCFGA_REG , 0x2e );
734+ sscape_write_unsafe (sscape -> io_base , GA_SMCFGB_REG , 0x00 );
735+
736+ /*
737+ * Enable and configure the DMA channels ...
738+ */
739+ sscape_write_unsafe (sscape -> io_base , GA_DMACFG_REG , 0x50 );
740+ dma_cfg = (sscape -> ic_type == IC_OPUS ? 0x40 : 0x70 );
741+ sscape_write_unsafe (sscape -> io_base , GA_DMAA_REG , dma_cfg );
742+ sscape_write_unsafe (sscape -> io_base , GA_DMAB_REG , 0x20 );
743+
744+ mpu_irq_cfg |= mpu_irq_cfg << 2 ;
745+ val = sscape_read_unsafe (sscape -> io_base , GA_HMCTL_REG ) & 0xf7 ;
746+ if (sscape -> joystick )
747+ val |= 0x08 ;
748+ sscape_write_unsafe (sscape -> io_base , GA_HMCTL_REG , val | 0xd0 );
749+ sscape_write_unsafe (sscape -> io_base , GA_INTCFG_REG ,
750+ 0xf0 | mpu_irq_cfg );
751+ sscape_write_unsafe (sscape -> io_base , GA_CDCFG_REG ,
752+ 0x09 | DMA_8BIT |
753+ (sscape -> dma1 << 4 ) | (irq_cfg << 1 ));
754+ /*
755+ * Enable the master IRQ ...
756+ */
757+ sscape_write_unsafe (sscape -> io_base , GA_INTENA_REG , 0x80 );
758+ }
759+
760+ return 0 ;
761+ }
762+
663763/*
664764 * Perform certain arcane port-checks to see whether there
665765 * is a SoundScape board lurking behind the given ports.
@@ -890,56 +990,51 @@ static int create_ad1845(struct snd_card *card, unsigned port,
890990
891991/*
892992 * Create an ALSA soundcard entry for the SoundScape, using
893- * the given list of port, IRQ and DMA resources.
993+ * the resolved port, IRQ and DMA resources.
894994 */
895- static int create_sscape (int dev , struct snd_card * card )
995+ static int create_sscape (struct snd_card * card )
896996{
897997 struct soundscape * sscape = get_card_soundscape (card );
898- unsigned dma_cfg ;
899- unsigned irq_cfg ;
900- unsigned mpu_irq_cfg ;
901998 struct resource * io_res ;
902999 struct resource * wss_res ;
9031000 int err ;
904- int val ;
9051001 const char * name ;
9061002
9071003 /*
9081004 * Grab IO ports that we will need to probe so that we
9091005 * can detect and control this hardware ...
9101006 */
911- io_res = devm_request_region (card -> dev , port [ dev ] , 8 , "SoundScape" );
1007+ io_res = devm_request_region (card -> dev , sscape -> io_base , 8 , "SoundScape" );
9121008 if (!io_res ) {
9131009 dev_err (card -> dev ,
914- "sscape: can't grab port 0x%lx \n" , port [ dev ] );
1010+ "sscape: can't grab port 0x%x \n" , sscape -> io_base );
9151011 return - EBUSY ;
9161012 }
9171013 wss_res = NULL ;
9181014 if (sscape -> type == SSCAPE_VIVO ) {
919- wss_res = devm_request_region (card -> dev , wss_port [ dev ] , 4 ,
1015+ wss_res = devm_request_region (card -> dev , sscape -> wss_base , 4 ,
9201016 "SoundScape" );
9211017 if (!wss_res ) {
9221018 dev_err (card -> dev , "sscape: can't grab port 0x%lx\n" ,
923- wss_port [ dev ] );
1019+ sscape -> wss_base );
9241020 return - EBUSY ;
9251021 }
9261022 }
9271023
9281024 /*
9291025 * Grab one DMA channel ...
9301026 */
931- err = snd_devm_request_dma (card -> dev , dma [ dev ] , "SoundScape" );
1027+ err = snd_devm_request_dma (card -> dev , sscape -> dma1 , "SoundScape" );
9321028 if (err < 0 ) {
933- dev_err (card -> dev , "sscape: can't grab DMA %d\n" , dma [ dev ] );
1029+ dev_err (card -> dev , "sscape: can't grab DMA %d\n" , sscape -> dma1 );
9341030 return err ;
9351031 }
9361032
9371033 spin_lock_init (& sscape -> lock );
9381034 sscape -> io_res = io_res ;
9391035 sscape -> wss_res = wss_res ;
940- sscape -> io_base = port [dev ];
9411036
942- if (!detect_sscape (sscape , wss_port [ dev ] )) {
1037+ if (!detect_sscape (sscape , sscape -> wss_base )) {
9431038 dev_err (card -> dev , "sscape: hardware not detected at 0x%x\n" ,
9441039 sscape -> io_base );
9451040 return - ENODEV ;
@@ -964,66 +1059,28 @@ static int create_sscape(int dev, struct snd_card *card)
9641059 }
9651060
9661061 dev_info (card -> dev , "sscape: %s card detected at 0x%x, using IRQ %d, DMA %d\n" ,
967- name , sscape -> io_base , irq [dev ], dma [dev ]);
968-
969- /*
970- * Check that the user didn't pass us garbage data ...
971- */
972- irq_cfg = get_irq_config (sscape -> type , irq [dev ]);
973- if (irq_cfg == INVALID_IRQ ) {
974- dev_err (card -> dev , "sscape: Invalid IRQ %d\n" , irq [dev ]);
975- return - ENXIO ;
976- }
977-
978- mpu_irq_cfg = get_irq_config (sscape -> type , mpu_irq [dev ]);
979- if (mpu_irq_cfg == INVALID_IRQ ) {
980- dev_err (card -> dev , "sscape: Invalid IRQ %d\n" , mpu_irq [dev ]);
981- return - ENXIO ;
982- }
1062+ name , sscape -> io_base , sscape -> irq , sscape -> dma1 );
9831063
9841064 /*
9851065 * Tell the on-board devices where their resources are (I think -
9861066 * I can't be sure without a datasheet ... So many magic values!)
9871067 */
988- scoped_guard (spinlock_irqsave , & sscape -> lock ) {
989-
990- sscape_write_unsafe (sscape -> io_base , GA_SMCFGA_REG , 0x2e );
991- sscape_write_unsafe (sscape -> io_base , GA_SMCFGB_REG , 0x00 );
992-
993- /*
994- * Enable and configure the DMA channels ...
995- */
996- sscape_write_unsafe (sscape -> io_base , GA_DMACFG_REG , 0x50 );
997- dma_cfg = (sscape -> ic_type == IC_OPUS ? 0x40 : 0x70 );
998- sscape_write_unsafe (sscape -> io_base , GA_DMAA_REG , dma_cfg );
999- sscape_write_unsafe (sscape -> io_base , GA_DMAB_REG , 0x20 );
1000-
1001- mpu_irq_cfg |= mpu_irq_cfg << 2 ;
1002- val = sscape_read_unsafe (sscape -> io_base , GA_HMCTL_REG ) & 0xF7 ;
1003- if (joystick [dev ])
1004- val |= 8 ;
1005- sscape_write_unsafe (sscape -> io_base , GA_HMCTL_REG , val | 0x10 );
1006- sscape_write_unsafe (sscape -> io_base , GA_INTCFG_REG , 0xf0 | mpu_irq_cfg );
1007- sscape_write_unsafe (sscape -> io_base ,
1008- GA_CDCFG_REG , 0x09 | DMA_8BIT
1009- | (dma [dev ] << 4 ) | (irq_cfg << 1 ));
1010- /*
1011- * Enable the master IRQ ...
1012- */
1013- sscape_write_unsafe (sscape -> io_base , GA_INTENA_REG , 0x80 );
1014-
1068+ err = sscape_configure_board (sscape );
1069+ if (err < 0 ) {
1070+ dev_err (card -> dev , "sscape: Invalid IRQ configuration\n" );
1071+ return err ;
10151072 }
10161073
10171074 /*
10181075 * We have now enabled the codec chip, and so we should
10191076 * detect the AD1845 device ...
10201077 */
1021- err = create_ad1845 (card , wss_port [ dev ], irq [ dev ] ,
1022- dma [ dev ], dma2 [ dev ] );
1078+ err = create_ad1845 (card , sscape -> wss_base , sscape -> irq ,
1079+ sscape -> dma1 , sscape -> dma2 );
10231080 if (err < 0 ) {
10241081 dev_err (card -> dev ,
10251082 "sscape: No AD1845 device at 0x%lx, IRQ %d\n" ,
1026- wss_port [ dev ], irq [ dev ] );
1083+ sscape -> wss_base , sscape -> irq );
10271084 return err ;
10281085 }
10291086 strscpy (card -> driver , "SoundScape" );
@@ -1040,35 +1097,21 @@ static int create_sscape(int dev, struct snd_card *card)
10401097 err = sscape_upload_microcode (card , err );
10411098
10421099 if (err == 0 ) {
1043- err = create_mpu401 (card , MIDI_DEVNUM , port [ dev ] ,
1044- mpu_irq [ dev ] );
1100+ err = create_mpu401 (card , MIDI_DEVNUM , sscape -> io_base ,
1101+ sscape -> mpu_irq );
10451102 if (err < 0 ) {
10461103 dev_err (card -> dev ,
10471104 "sscape: Failed to create MPU-401 device at 0x%lx\n" ,
1048- port [ dev ] );
1105+ ( unsigned long ) sscape -> io_base );
10491106 return err ;
10501107 }
10511108
1052- /*
1053- * Initialize mixer
1054- */
1055- guard (spinlock_irqsave )(& sscape -> lock );
10561109 sscape -> midi_vol = 0 ;
1057- host_write_ctrl_unsafe (sscape -> io_base ,
1058- CMD_SET_MIDI_VOL , 100 );
1059- host_write_ctrl_unsafe (sscape -> io_base ,
1060- sscape -> midi_vol , 100 );
1061- host_write_ctrl_unsafe (sscape -> io_base ,
1062- CMD_XXX_MIDI_VOL , 100 );
1063- host_write_ctrl_unsafe (sscape -> io_base ,
1064- sscape -> midi_vol , 100 );
1065- host_write_ctrl_unsafe (sscape -> io_base ,
1066- CMD_SET_EXTMIDI , 100 );
1067- host_write_ctrl_unsafe (sscape -> io_base ,
1068- 0 , 100 );
1069- host_write_ctrl_unsafe (sscape -> io_base , CMD_ACK , 100 );
1070-
1071- set_midi_mode_unsafe (sscape -> io_base );
1110+ err = sscape_restore_midi_state (sscape );
1111+ if (err < 0 )
1112+ dev_warn (card -> dev ,
1113+ "sscape: MIDI init incomplete: %d\n" ,
1114+ err );
10721115 }
10731116 }
10741117
@@ -1111,8 +1154,9 @@ static int snd_sscape_probe(struct device *pdev, unsigned int dev)
11111154 sscape -> type = SSCAPE ;
11121155
11131156 dma [dev ] &= 0x03 ;
1157+ sscape_store_settings (sscape , dev );
11141158
1115- ret = create_sscape (dev , card );
1159+ ret = create_sscape (card );
11161160 if (ret < 0 )
11171161 return ret ;
11181162
@@ -1130,7 +1174,6 @@ static int snd_sscape_probe(struct device *pdev, unsigned int dev)
11301174static struct isa_driver snd_sscape_driver = {
11311175 .match = snd_sscape_match ,
11321176 .probe = snd_sscape_probe ,
1133- /* FIXME: suspend/resume */
11341177 .driver = {
11351178 .name = DEV_NAME
11361179 },
@@ -1211,8 +1254,9 @@ static int sscape_pnp_detect(struct pnp_card_link *pcard,
12111254 wss_port [idx ] = pnp_port_start (dev , 1 );
12121255 dma2 [idx ] = pnp_dma (dev , 1 );
12131256 }
1257+ sscape_store_settings (sscape , idx );
12141258
1215- ret = create_sscape (idx , card );
1259+ ret = create_sscape (card );
12161260 if (ret < 0 )
12171261 return ret ;
12181262
0 commit comments