/* sb16pnp.c: SB16 PnP interface */
/*
 * $Header: /root/pnp/module/RCS/sb16pnp.c,v 1.1 1996/06/12 18:56:34 root Exp root $
 *
 * $Log: sb16pnp.c,v $
 * Revision 1.1  1996/06/12  18:56:34  root
 * standard internal i/f & BIOS read/query
 *
 *
 */

/*
 * (c) Copyright 1996  D.W.Howells <dwh@nexor.co.uk>,
 */

#include <linux/config.h>
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#else
#define MOD_INC_USE_COUNT
#define MOD_DEC_USE_COUNT
#endif

#include <linux/config.h>
#include <linux/mm.h>
#include <linux/malloc.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/bitops.h>
#include <linux/pnp.h>


static int sb16pnp_attach(pnp_device *, int);
static int sb16pnp_control(pnp_device *, PNP_DRV_CTRL);
static int sb16pnp_reconfigure(pnp_device *, const pnp_possibility *,
			       pnp_config *);

static pnp_driver sb16_pnp = {
    NULL,
    "SB16",
    PNPDRVID('C','T','L',0x003,1), { 0, 0 },
    &sb16pnp_attach,
    &sb16pnp_control,
    &sb16pnp_reconfigure
};

/*****************************************************************************/
/* initialize sb16pnp */
int init_module()
{
    return pnp_register(&sb16_pnp);
}

/* remove sb16pnp */
void cleanup_module(void)
{
    pnp_unregister(&sb16_pnp);
}

/*****************************************************************************/
/* attach/detach driver */
static int sb16pnp_attach(pnp_device *device, int attach)
{
    pnp_config conf;

    if (attach) {
	printk("sb16pnp_attach: attach device (%02x,%02x)\n",
	       device->pd_card->pc_csn,
	       device->pd_dev
	       );
	if (pnp_dev_current(device,&conf)==0)
	    sb16pnp_reconfigure(device,NULL,&conf);
	else
	    printk("sb16pnp: unable to get current conf\n");
    } else {
	printk("sb16pnp_attach: detach device (%02x,%02x)\n",
	       device->pd_card->pc_csn,
	       device->pd_dev
	       );
    }

    return 0;
}

/*****************************************************************************/
/* control driver (during device config) */
static int sb16pnp_control(pnp_device *device, PNP_DRV_CTRL req)
{
    switch (req) {
     case PNPDC_ACTIVATE:
	printk("sb16pnp: activate\n");
	break;
     case PNPDC_DEACTIVATE:
	printk("sb16pnp: deactivate\n");
	break;
     case PNPDC_RELEASE_RES:
	printk("sb16pnp: release resources\n");
	break;
     case PNPDC_LOCK:
	printk("sb16pnp: lock\n");
	break;
     case PNPDC_UNLOCK:
	printk("sb16pnp: unlock\n");
	break;
     default:
	printk("sb16pnp: unknown control\n");
	break;
    }
    return 0;
}

/*****************************************************************************/
/* request reconfigure */
static int sb16pnp_reconfigure(pnp_device *device, const pnp_possibility *poss,
			       pnp_config *conf)
{
    int loop;

    if (test_bit(0,&conf->pc_s.irq))
	printk("selected irq[0]: %d\n",conf->pc_irq[0].num);
    if (test_bit(1,&conf->pc_s.irq))
	printk("selected irq[1]: %d\n",conf->pc_irq[1].num);

    if (test_bit(0,&conf->pc_s.dma))
	printk("selected dma[0]: %d\n",conf->pc_dma[0].chan);
    if (test_bit(1,&conf->pc_s.dma))
	printk("selected dma[1]: %d\n",conf->pc_dma[1].chan);

    for (loop=0; loop<8; loop++)
	if (test_bit(loop,&conf->pc_s.io))
	    printk("selected io[%d]: %04x\n",loop,conf->pc_io[loop].base);

    return 0;
}
