Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
		
			
				
	
	
		
			219 lines
		
	
	
	
		
			4.1 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
	
		
			4.1 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 *	PCI sound skeleton example
 | 
						|
 *
 | 
						|
 *	(c) 1998 Red Hat Software
 | 
						|
 *
 | 
						|
 *	This software may be used and distributed according to the 
 | 
						|
 *	terms of the GNU General Public License, incorporated herein by 
 | 
						|
 *	reference.
 | 
						|
 *
 | 
						|
 *	This example is designed to be built in the linux/drivers/sound
 | 
						|
 *	directory as part of a kernel build. The example is modular only
 | 
						|
 *	drop me a note once you have a working modular driver and want
 | 
						|
 *	to integrate it with the main code.
 | 
						|
 *		-- Alan <alan@redhat.com>
 | 
						|
 *
 | 
						|
 *	This is a first draft. Please report any errors, corrections or
 | 
						|
 *	improvements to me.
 | 
						|
 */
 | 
						|
 | 
						|
#include <linux/module.h>
 | 
						|
#include <linux/delay.h>
 | 
						|
#include <linux/errno.h>
 | 
						|
#include <linux/fs.h>
 | 
						|
#include <linux/kernel.h>
 | 
						|
#include <linux/pci.h>
 | 
						|
 | 
						|
#include <asm/io.h>
 | 
						|
 | 
						|
#include "sound_config.h"
 | 
						|
 | 
						|
/*
 | 
						|
 *	Define our PCI vendor ID here
 | 
						|
 */
 | 
						|
 
 | 
						|
#ifndef PCI_VENDOR_MYIDENT
 | 
						|
#define PCI_VENDOR_MYIDENT			0x125D
 | 
						|
 | 
						|
/*
 | 
						|
 *	PCI identity for the card.
 | 
						|
 */
 | 
						|
 
 | 
						|
#define PCI_DEVICE_ID_MYIDENT_MYCARD1		0x1969
 | 
						|
#endif
 | 
						|
 | 
						|
#define CARD_NAME	"ExampleWave 3D Pro Ultra ThingyWotsit"
 | 
						|
 | 
						|
#define MAX_CARDS	8
 | 
						|
 | 
						|
/*
 | 
						|
 *	Each address_info object holds the information about one of
 | 
						|
 *	our card resources. In this case the MSS emulation of our
 | 
						|
 *	ficticious card. Its used to manage and attach things.
 | 
						|
 */
 | 
						|
 
 | 
						|
static struct address_info	mss_data[MAX_CARDS];
 | 
						|
static int 			cards;
 | 
						|
 | 
						|
/*
 | 
						|
 *	Install the actual card. This is an example
 | 
						|
 */
 | 
						|
 | 
						|
static int mycard_install(struct pci_dev *pcidev)
 | 
						|
{
 | 
						|
	int iobase;
 | 
						|
	int mssbase;
 | 
						|
	int mpubase;
 | 
						|
	u8 x;
 | 
						|
	u16 w;
 | 
						|
	u32 v;
 | 
						|
	int i;
 | 
						|
	int dma;
 | 
						|
 | 
						|
	/*
 | 
						|
	 *	Our imaginary code has its I/O on PCI address 0, a
 | 
						|
	 *	MSS on PCI address 1 and an MPU on address 2
 | 
						|
	 *
 | 
						|
	 *	For the example we will only initialise the MSS
 | 
						|
	 */
 | 
						|
	 	
 | 
						|
	iobase = pci_resource_start(pcidev, 0);
 | 
						|
	mssbase = pci_resource_start(pcidev, 1);
 | 
						|
	mpubase = pci_resource_start(pcidev, 2);
 | 
						|
	
 | 
						|
	/*
 | 
						|
	 *	Reset the board
 | 
						|
	 */
 | 
						|
	 
 | 
						|
	/*
 | 
						|
	 *	Wait for completion. udelay() waits in microseconds
 | 
						|
	 */
 | 
						|
	 
 | 
						|
	udelay(100);
 | 
						|
	
 | 
						|
	/*
 | 
						|
	 *	Ok card ready. Begin setup proper. You might for example
 | 
						|
	 *	load the firmware here
 | 
						|
	 */
 | 
						|
	
 | 
						|
	dma = card_specific_magic(ioaddr);
 | 
						|
	
 | 
						|
	/*
 | 
						|
	 *	Turn on legacy mode (example), There are also byte and
 | 
						|
	 *	dword (32bit) PCI configuration function calls
 | 
						|
	 */
 | 
						|
 | 
						|
	pci_read_config_word(pcidev, 0x40, &w);
 | 
						|
	w&=~(1<<15);			/* legacy decode on */
 | 
						|
	w|=(1<<14);			/* Reserved write as 1 in this case */
 | 
						|
	w|=(1<<3)|(1<<1)|(1<<0);	/* SB on , FM on, MPU on */
 | 
						|
	pci_write_config_word(pcidev, 0x40, w);
 | 
						|
	
 | 
						|
	/*
 | 
						|
	 *	Let the user know we found his toy.
 | 
						|
	 */
 | 
						|
	 
 | 
						|
	printk(KERN_INFO "Programmed "CARD_NAME" at 0x%X to legacy mode.\n",
 | 
						|
		iobase);
 | 
						|
		
 | 
						|
	/*
 | 
						|
	 *	Now set it up the description of the card
 | 
						|
	 */
 | 
						|
	 
 | 
						|
	mss_data[cards].io_base = mssbase;
 | 
						|
	mss_data[cards].irq = pcidev->irq;
 | 
						|
	mss_data[cards].dma = dma;
 | 
						|
	
 | 
						|
	/*
 | 
						|
	 *	Check there is an MSS present
 | 
						|
	 */
 | 
						|
 | 
						|
	if(ad1848_detect(mssbase, NULL, mss_data[cards].osp)==0)
 | 
						|
		return 0;
 | 
						|
		
 | 
						|
	/*
 | 
						|
	 *	Initialize it
 | 
						|
	 */
 | 
						|
	 
 | 
						|
	mss_data[cards].slots[3] = ad1848_init("MyCard MSS 16bit", 
 | 
						|
			mssbase,
 | 
						|
			mss_data[cards].irq,
 | 
						|
			mss_data[cards].dma,
 | 
						|
			mss_data[cards].dma,
 | 
						|
			0,
 | 
						|
			0,
 | 
						|
			THIS_MODULE);
 | 
						|
 | 
						|
	cards++;	
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * 	This loop walks the PCI configuration database and finds where
 | 
						|
 *	the sound cards are.
 | 
						|
 */
 | 
						|
 
 | 
						|
int init_mycard(void)
 | 
						|
{
 | 
						|
	struct pci_dev *pcidev=NULL;
 | 
						|
	int count=0;
 | 
						|
		
 | 
						|
	while((pcidev = pci_find_device(PCI_VENDOR_MYIDENT, PCI_DEVICE_ID_MYIDENT_MYCARD1, pcidev))!=NULL)
 | 
						|
	{
 | 
						|
		if (pci_enable_device(pcidev))
 | 
						|
			continue;
 | 
						|
		count+=mycard_install(pcidev);
 | 
						|
		if(count)
 | 
						|
			return 0;
 | 
						|
		if(count==MAX_CARDS)
 | 
						|
			break;
 | 
						|
	}
 | 
						|
	
 | 
						|
	if(count==0)
 | 
						|
		return -ENODEV;
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 *	This function is called when the user or kernel loads the 
 | 
						|
 *	module into memory.
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
int init_module(void)
 | 
						|
{
 | 
						|
	if(init_mycard()<0)
 | 
						|
	{
 | 
						|
		printk(KERN_ERR "No "CARD_NAME" cards found.\n");
 | 
						|
		return -ENODEV;
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 *	This is called when it is removed. It will only be removed 
 | 
						|
 *	when its use count is 0.
 | 
						|
 */
 | 
						|
 
 | 
						|
void cleanup_module(void)
 | 
						|
{
 | 
						|
	for(i=0;i< cards; i++)
 | 
						|
	{
 | 
						|
		/*
 | 
						|
		 *	Free attached resources
 | 
						|
		 */
 | 
						|
		 
 | 
						|
		ad1848_unload(mss_data[i].io_base,
 | 
						|
			      mss_data[i].irq,
 | 
						|
			      mss_data[i].dma,
 | 
						|
			      mss_data[i].dma,
 | 
						|
			      0);
 | 
						|
		/*
 | 
						|
		 *	And disconnect the device from the kernel
 | 
						|
		 */
 | 
						|
		sound_unload_audiodevice(mss_data[i].slots[3]);
 | 
						|
	}
 | 
						|
}
 | 
						|
 |