/*
 *  PCI support functions
 *  Copyright (c) by Jaroslav Kysela <perex@jcu.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 <stddef.h>

int snd_pci_find_device(int vendor, int device, unsigned int index, struct snd_pci_dev *dev)
{
	struct pci_dev_info pci_dev;
	int idx, hdl;
	void *handle;
	
	if (!dev || index < 0)
		return -EINVAL;

	if (( hdl = pci_attach(0)) >= 0) {
		memset(&pci_dev, 0, sizeof(pci_dev));
		pci_dev.VendorId = vendor;
		pci_dev.DeviceId = device;
		if ((handle = pci_attach_device( NULL, PCI_SEARCH_VENDEV | PCI_INIT_ALL, index, &pci_dev )) != NULL ) {
			memset(dev, 0, sizeof(struct snd_pci_dev));
			dev->bus = pci_dev.BusNumber;
			dev->devfn = pci_dev.DevFunc;
			dev->vendor = vendor;
			dev->device = device;
			dev->class = pci_dev.Class;
			dev->irq = pci_dev.Irq;
			dev->handle = handle;
			for (idx = 0; idx < 6; idx++)
				dev->base_address[idx] = pci_dev.CpuBaseAddress[idx];
			return 0;
		}
		pci_detach(hdl);
	}
	return -ENODEV;
}

int snd_pci_write_config_word(struct snd_pci_dev *pci, int index, unsigned short value) 
{
	return pci_write_config(pci->handle, index, 1, sizeof(value), &value);
}

int snd_pci_read_config_word(struct snd_pci_dev *pci, int index, unsigned short *value) 
{
	return pci_read_config(pci->handle, index, 1, sizeof(*value), value);
}

int snd_pci_write_config_dword(struct snd_pci_dev *pci, int index, unsigned long value) 
{
	return pci_write_config(pci->handle, index, 1, sizeof(value), &value);
}

int snd_pci_read_config_dword(struct snd_pci_dev *pci, int index, unsigned long *value)
{
	return pci_read_config(pci->handle, index, 1, sizeof(*value), value);
}

int snd_pci_write_config_byte(struct snd_pci_dev *pci, int index, unsigned char value)
{
	return pci_write_config(pci->handle, index, 1, sizeof(value), &value);
}

int snd_pci_read_config_byte(struct snd_pci_dev *pci, int index, unsigned char *value)
{
	return pci_write_config(pci->handle, index, 1, sizeof(*value), value);
}
