Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit efe3cd10 authored by Dominik Brodowski's avatar Dominik Brodowski
Browse files

[PATCH] pcmcia: fix sound drivers



Update the PCMCIA sound drivers to handle the recent changes to the PCMCIA
core. A part of this merge was done by Takashi Iwai <tiwai@suse.de>.

Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent f8cfa618
Loading
Loading
Loading
Loading
+60 −94
Original line number Diff line number Diff line
@@ -52,16 +52,13 @@ MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
/*
 */

static dev_info_t dev_info = "snd-pdaudiocf";
static struct snd_card *card_list[SNDRV_CARDS];
static dev_link_t *dev_list;

/*
 * prototypes
 */
static void pdacf_config(dev_link_t *link);
static int pdacf_event(event_t event, int priority, event_callback_args_t *args);
static void snd_pdacf_detach(dev_link_t *link);
static void snd_pdacf_detach(struct pcmcia_device *p_dev);

static void pdacf_release(dev_link_t *link)
{
@@ -83,10 +80,6 @@ static int snd_pdacf_free(struct snd_pdacf *pdacf)

	pdacf_release(link);

	/* Break the link with Card Services */
	if (link->handle)
		pcmcia_deregister_client(link->handle);

	card_list[pdacf->index] = NULL;
	pdacf->card = NULL;

@@ -103,11 +96,10 @@ static int snd_pdacf_dev_free(struct snd_device *device)
/*
 * snd_pdacf_attach - attach callback for cs
 */
static dev_link_t *snd_pdacf_attach(void)
static int snd_pdacf_attach(struct pcmcia_device *p_dev)
{
	client_reg_t client_reg;	/* Register with cardmgr */
	int i;
	dev_link_t *link;               /* Info for cardmgr */
	int i, ret;
	struct snd_pdacf *pdacf;
	struct snd_card *card;
	static struct snd_device_ops ops = {
@@ -122,26 +114,26 @@ static dev_link_t *snd_pdacf_attach(void)
	}
	if (i >= SNDRV_CARDS) {
		snd_printk(KERN_ERR "pdacf: too many cards found\n");
		return NULL;
		return -EINVAL;
	}
	if (! enable[i])
		return NULL; /* disabled explicitly */
		return -ENODEV; /* disabled explicitly */

	/* ok, create a card instance */
	card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
	if (card == NULL) {
		snd_printk(KERN_ERR "pdacf: cannot create a card instance\n");
		return NULL;
		return -ENOMEM;
	}

	pdacf = snd_pdacf_create(card);
	if (! pdacf)
		return NULL;
		return -EIO;

	if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops) < 0) {
		kfree(pdacf);
		snd_card_free(card);
		return NULL;
		return -ENODEV;
	}

	pdacf->index = i;
@@ -165,22 +157,12 @@ static dev_link_t *snd_pdacf_attach(void)
	link->conf.Present = PRESENT_OPTION;

	/* Chain drivers */
	link->next = dev_list;
	dev_list = link;

	/* Register with Card Services */
	client_reg.dev_info = &dev_info;
	client_reg.Version = 0x0210;
	client_reg.event_callback_args.client_data = link;

	ret = pcmcia_register_client(&link->handle, &client_reg);
	if (ret != CS_SUCCESS) {
		cs_error(link->handle, RegisterClient, ret);
		snd_pdacf_detach(link);
		return NULL;
	}
	link->next = NULL;

	return link;
	link->handle = p_dev;
	pdacf_config(link);

	return 0;
}


@@ -227,21 +209,13 @@ static int snd_pdacf_assign_resources(struct snd_pdacf *pdacf, int port, int irq
/*
 * snd_pdacf_detach - detach callback for cs
 */
static void snd_pdacf_detach(dev_link_t *link)
static void snd_pdacf_detach(struct pcmcia_device *p_dev)
{
	dev_link_t *link = dev_to_instance(p_dev);
	struct snd_pdacf *chip = link->priv;

	snd_printdd(KERN_DEBUG "pdacf_detach called\n");
	/* Remove the interface data from the linked list */
	{
		dev_link_t **linkp;
		/* Locate device structure */
		for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
			if (*linkp == link)
				break;
		if (*linkp)
			*linkp = link->next;
	}

	if (chip->chip_status & PDAUDIOCF_STAT_IS_CONFIGURED)
		snd_pdacf_powerdown(chip);
	chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */
@@ -310,46 +284,35 @@ static void pdacf_config(dev_link_t *link)
	pcmcia_release_irq(link->handle, &link->irq);
}

/*
 * event callback
 */
static int pdacf_event(event_t event, int priority, event_callback_args_t *args)
#ifdef CONFIG_PM

static int pdacf_suspend(struct pcmcia_device *dev)
{
	dev_link_t *link = args->client_data;
	dev_link_t *link = dev_to_instance(dev);
	struct snd_pdacf *chip = link->priv;

	switch (event) {
	case CS_EVENT_CARD_REMOVAL:
		snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n");
		link->state &= ~DEV_PRESENT;
		if (link->state & DEV_CONFIG) {
			chip->chip_status |= PDAUDIOCF_STAT_IS_STALE;
		}
		break;
	case CS_EVENT_CARD_INSERTION:
		snd_printdd(KERN_DEBUG "CARD_INSERTION..\n");
		link->state |= DEV_PRESENT;
		pdacf_config(link);
		break;
#ifdef CONFIG_PM
	case CS_EVENT_PM_SUSPEND:
	snd_printdd(KERN_DEBUG "SUSPEND\n");
	link->state |= DEV_SUSPEND;
	if (chip) {
		snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n");
		snd_pdacf_suspend(chip, PMSG_SUSPEND);
	}
		/* Fall through... */
	case CS_EVENT_RESET_PHYSICAL:

	snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
	if (link->state & DEV_CONFIG)
		pcmcia_release_configuration(link->handle);
		break;
	case CS_EVENT_PM_RESUME:

	return 0;
}

static int pdacf_resume(struct pcmcia_device *dev)
{
	dev_link_t *link = dev_to_instance(dev);
	struct snd_pdacf *chip = link->priv;

	snd_printdd(KERN_DEBUG "RESUME\n");
	link->state &= ~DEV_SUSPEND;
		/* Fall through... */
	case CS_EVENT_CARD_RESET:

	snd_printdd(KERN_DEBUG "CARD_RESET\n");
	if (DEV_OK(link)) {
		snd_printdd(KERN_DEBUG "requestconfig...\n");
@@ -360,12 +323,12 @@ static int pdacf_event(event_t event, int priority, event_callback_args_t *args)
		}
	}
	snd_printdd(KERN_DEBUG "resume done!\n");
		break;
#endif
	}

	return 0;
}

#endif

/*
 * Module entry points
 */
@@ -380,10 +343,14 @@ static struct pcmcia_driver pdacf_cs_driver = {
	.drv		= {
		.name	= "snd-pdaudiocf",
	},
	.attach		= snd_pdacf_attach,
	.event		= pdacf_event,
	.detach		= snd_pdacf_detach,
	.probe		= snd_pdacf_attach,
	.remove		= snd_pdacf_detach,
	.id_table	= snd_pdacf_ids,
#ifdef CONFIG_PM
	.suspend	= pdacf_suspend,
	.resume		= pdacf_resume,
#endif

};

static int __init init_pdacf(void)
@@ -394,7 +361,6 @@ static int __init init_pdacf(void)
static void __exit exit_pdacf(void)
{
	pcmcia_unregister_driver(&pdacf_cs_driver);
	BUG_ON(dev_list != NULL);
}

module_init(init_pdacf);
+55 −100
Original line number Diff line number Diff line
@@ -55,11 +55,6 @@ MODULE_PARM_DESC(ibl, "Capture IBL size for VXPocket soundcard.");
 */

static unsigned int card_alloc;
static dev_link_t *dev_list;		/* Linked list of devices */
static dev_info_t dev_info = "snd-vxpocket";


static int vxpocket_event(event_t event, int priority, event_callback_args_t *args);


/*
@@ -73,11 +68,6 @@ static void vxpocket_release(dev_link_t *link)
		pcmcia_release_irq(link->handle, &link->irq);
		link->state &= ~DEV_CONFIG;
	}
	if (link->handle) {
		/* Break the link with Card Services */
		pcmcia_deregister_client(link->handle);
		link->handle = NULL;
	}
}

/*
@@ -144,11 +134,9 @@ static struct snd_vx_hardware vxp440_hw = {
 */
static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)
{
	client_reg_t client_reg;	/* Register with cardmgr */
	dev_link_t *link;		/* Info for cardmgr */
	struct vx_core *chip;
	struct snd_vxpocket *vxp;
	int ret;
	static struct snd_device_ops ops = {
		.dev_free =	snd_vxpocket_dev_free,
	};
@@ -184,26 +172,6 @@ static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)
	link->conf.ConfigIndex = 1;
	link->conf.Present = PRESENT_OPTION;

	/* Register with Card Services */
	memset(&client_reg, 0, sizeof(client_reg));
	client_reg.dev_info = &dev_info;
	client_reg.EventMask = 
		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL
#ifdef CONFIG_PM
		| CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET
		| CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME
#endif
		;
	client_reg.event_handler = &vxpocket_event;
	client_reg.Version = 0x0210;
	client_reg.event_callback_args.client_data = link;

	ret = pcmcia_register_client(&link->handle, &client_reg);
	if (ret != CS_SUCCESS) {
		cs_error(link->handle, RegisterClient, ret);
		return NULL;
	}

	return vxp;
}

@@ -317,46 +285,34 @@ static void vxpocket_config(dev_link_t *link)
	kfree(parse);
}

#ifdef CONFIG_PM

/*
 * event callback
 */
static int vxpocket_event(event_t event, int priority, event_callback_args_t *args)
static int vxp_suspend(struct pcmcia_device *dev)
{
	dev_link_t *link = args->client_data;
	dev_link_t *link = dev_to_instance(dev);
	struct vx_core *chip = link->priv;

	switch (event) {
	case CS_EVENT_CARD_REMOVAL:
		snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n");
		link->state &= ~DEV_PRESENT;
		if (link->state & DEV_CONFIG)
			chip->chip_status |= VX_STAT_IS_STALE;
		break;
	case CS_EVENT_CARD_INSERTION:
		snd_printdd(KERN_DEBUG "CARD_INSERTION..\n");
		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
		vxpocket_config(link);
		break;
#ifdef CONFIG_PM
	case CS_EVENT_PM_SUSPEND:
	snd_printdd(KERN_DEBUG "SUSPEND\n");
	link->state |= DEV_SUSPEND;
	if (chip) {
		snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
		snd_vx_suspend(chip, PMSG_SUSPEND);
	}
		/* Fall through... */
	case CS_EVENT_RESET_PHYSICAL:
	snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
	if (link->state & DEV_CONFIG)
		pcmcia_release_configuration(link->handle);
		break;
	case CS_EVENT_PM_RESUME:

	return 0;
}

static int vxp_resume(struct pcmcia_device *dev)
{
	dev_link_t *link = dev_to_instance(dev);
	struct vx_core *chip = link->priv;

	snd_printdd(KERN_DEBUG "RESUME\n");
	link->state &= ~DEV_SUSPEND;
		/* Fall through... */
	case CS_EVENT_CARD_RESET:

	snd_printdd(KERN_DEBUG "CARD_RESET\n");
	if (DEV_OK(link)) {
		//struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
@@ -368,16 +324,16 @@ static int vxpocket_event(event_t event, int priority, event_callback_args_t *ar
		}
	}
	snd_printdd(KERN_DEBUG "resume done!\n");
		break;
#endif
	}

	return 0;
}

#endif


/*
 */
static dev_link_t *vxpocket_attach(void)
static int vxpocket_attach(struct pcmcia_device *p_dev)
{
	struct snd_card *card;
	struct snd_vxpocket *vxp;
@@ -390,22 +346,22 @@ static dev_link_t *vxpocket_attach(void)
	}
	if (i >= SNDRV_CARDS) {
		snd_printk(KERN_ERR "vxpocket: too many cards found\n");
		return NULL;
		return -EINVAL;
	}
	if (! enable[i])
		return NULL; /* disabled explicitly */
		return -ENODEV; /* disabled explicitly */

	/* ok, create a card instance */
	card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
	if (card == NULL) {
		snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n");
		return NULL;
		return -ENOMEM;
	}

	vxp = snd_vxpocket_new(card, ibl[i]);
	if (! vxp) {
		snd_card_free(card);
		return NULL;
		return -ENODEV;
	}
	card->private_data = vxp;

@@ -413,17 +369,21 @@ static dev_link_t *vxpocket_attach(void)
	card_alloc |= 1 << i;

	/* Chain drivers */
	vxp->link.next = dev_list;
	dev_list = &vxp->link;
	vxp->link.next = NULL;

	return &vxp->link;
	vxp->link.handle = p_dev;
	vxp->link.state |= DEV_PRESENT | DEV_CONFIG_PENDING;
	p_dev->instance = &vxp->link;
	vxpocket_config(&vxp->link);

	return 0;
}

static void vxpocket_detach(dev_link_t *link)
static void vxpocket_detach(struct pcmcia_device *p_dev)
{
	dev_link_t *link = dev_to_instance(p_dev);
	struct snd_vxpocket *vxp;
	struct vx_core *chip;
	dev_link_t **linkp;

	if (! link)
		return;
@@ -432,13 +392,6 @@ static void vxpocket_detach(dev_link_t *link)
	chip = (struct vx_core *)vxp;
	card_alloc &= ~(1 << vxp->index);

	/* Remove the interface data from the linked list */
	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
		if (*linkp == link) {
			*linkp = link->next;
			break;
		}

	chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */
	snd_card_disconnect(chip->card);
	vxpocket_release(link);
@@ -460,10 +413,13 @@ static struct pcmcia_driver vxp_cs_driver = {
	.drv		= {
		.name	= "snd-vxpocket",
	},
	.attach		= vxpocket_attach,
	.detach		= vxpocket_detach,
	.event		= vxpocket_event,
	.probe		= vxpocket_attach,
	.remove		= vxpocket_detach,
	.id_table	= vxp_ids,
#ifdef CONFIG_PM
	.suspend	= vxp_suspend,
	.resume		= vxp_resume,
#endif
};

static int __init init_vxpocket(void)
@@ -474,7 +430,6 @@ static int __init init_vxpocket(void)
static void __exit exit_vxpocket(void)
{
	pcmcia_unregister_driver(&vxp_cs_driver);
	BUG_ON(dev_list != NULL);
}

module_init(init_vxpocket);