/*
 *  The driver for the Cirrus Logic's Sound Fusion CS461X based soundcards
 *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
 *
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include "driver.h"
#include "sndpci.h"
#include "cs461x.h"
#include "initval.h"


int snd_card_cs461x_detect(snd_card_t * card, struct snd_pci_dev *pci,
				  unsigned short device, int ndx)
{
	if (snd_pci_find_device(PCI_VENDOR_ID_CIRRUS,
				device, ndx, pci) < 0)
		return -ENODEV;
#if 0
	for (idx = 0; idx < SND_CARDS; idx++) {
		if (snd_cards[idx]) {
			if (snd_cs461x_cards[idx]->pci.base_address[0] == scard->pci.base_address[0])
				return -EBUSY;
		}
	}
#endif
	return 0;
}


/* snd_cs461x_cmdline() -- Oct 25th, 1999
 * Used by audiotrap for detecting commandline options
 * All drivers use exactly the same function prototype.
 * Don't add any more options to this function or change
 * its behaviour without changing the others too.
 */
int snd_cs461x_cmdline( int *count, char **cmdline, int verbose )
{
        int dev, cards;
        struct snd_pci_dev *pci = NULL;

        *count = 0;

	for (dev = cards = 0; dev < SND_CARDS; dev++) {
		if (!pci)
			pci = (struct snd_pci_dev *)
				snd_malloc(sizeof(struct snd_pci_dev));
		if (!pci)
			continue;
		memset(pci, 0, sizeof(struct snd_pci_dev));
		if (snd_card_cs461x_detect( NULL, pci, PCI_DEVICE_ID_CIRRUS_4612, dev ) == 0) {
                 	if( verbose > 2 ) snd_printd("cs461x: Found CS4612 @IO 0x%X\n",
						(unsigned int) PCI_IO_ADDR(pci->base_address[0]));
#ifdef __QNXNTO__
			if( pci_detach_device( pci->handle ) != PCI_SUCCESS )
        			snd_printk("cs461x: Unable to detach PCI device.\n");
#endif
			cards++;
		} else
			break;  
//		if ( cards > SND_CARDS)
//			return 0;
	}
	for (dev = 0; dev < SND_CARDS; dev++) {
		if (!pci)
			pci = (struct snd_pci_dev *)
				snd_malloc(sizeof(struct snd_pci_dev));
		if (!pci)
			continue;
		memset(pci, 0, sizeof(struct snd_pci_dev));
		if (snd_card_cs461x_detect( NULL, pci, PCI_DEVICE_ID_CIRRUS_4610, dev ) == 0) {
                	if( verbose > 2 ) snd_printd("cs461x: Found CS4610 @IO 0x%X\n",
						(unsigned int) PCI_IO_ADDR(pci->base_address[0]));
#ifdef __QNXNTO__
			if( pci_detach_device( pci->handle ) != PCI_SUCCESS )
        			snd_printk("cs461x: Unable to detach PCI device.\n");
#endif
			cards++;
		} else
			break;
//		if ( cards > SND_CARDS)
//			return 0;
	}
	for (dev = 0; dev < SND_CARDS; dev++) {
		if (!pci)
			pci = (struct snd_pci_dev *)
				snd_malloc(sizeof(struct snd_pci_dev));
		if (!pci)
			continue;
		memset(pci, 0, sizeof(struct snd_pci_dev));
		if (snd_card_cs461x_detect( NULL, pci, PCI_DEVICE_ID_CIRRUS_4615, dev ) == 0) {
                        if( verbose > 2 ) snd_printd("cs461x: Found CS4615 @IO 0x%X\n",
						(unsigned int) PCI_IO_ADDR(pci->base_address[0]));
#ifdef __QNXNTO__
			if( pci_detach_device( pci->handle ) != PCI_SUCCESS )
        			snd_printk("cs461x: Unable to detach PCI device.\n");
#endif
			cards++;
		} else
			break;
//		if ( cards > SND_CARDS)
//			return 0;
	}
	snd_free(pci, sizeof(struct snd_pci_dev));

	if (!cards) {
		if( verbose > 1 ) snd_printk("cs461x: Sound Fusion CS461x interface not found or device busy\n");
		return -ENODEV;
	}
        *count = cards;

        /* Since there are no options, no matter how many cards we find we only have to return one
         * simple commandline
         */
        if( cards ) {
                int idx = 0;
                cmdline[idx] = (char*) malloc( PATH_MAX );
                if( !cmdline[idx] )
                        return -ENOMEM;
                sprintf( cmdline[idx], "deva-cs461x" );
                *count = idx + 1;
        }
	return 0;
}
