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

Commit afeacfd5 authored by Krzysztof Helt's avatar Krzysztof Helt Committed by Jaroslav Kysela
Browse files

[ALSA] dbri: conversion to OpenFirmware framework



This patch converts the dbri driver to use OF framework.

Signed-off-by: default avatarKrzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent f545714e
Loading
Loading
Loading
Loading
+69 −74
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@
#include <sound/control.h>
#include <sound/initval.h>

#include <asm/prom.h>
#include <asm/sbus.h>
#include <asm/atomic.h>

@@ -296,8 +297,6 @@ struct dbri_streaminfo {

/* This structure holds the information for both chips (DBRI & CS4215) */
struct snd_dbri {
	struct snd_card *card;	/* ALSA card */

	int regs_size, irq;	/* Needed for unload */
	struct sbus_dev *sdev;	/* SBUS device info */
	spinlock_t lock;
@@ -318,8 +317,6 @@ struct snd_dbri {
	struct cs4215 mm;	/* mmcodec special info */
				/* per stream (playback/record) info */
	struct dbri_streaminfo stream_info[DBRI_NO_STREAMS];

	struct snd_dbri *next;
};

#define DBRI_MAX_VOLUME		63	/* Output volume */
@@ -571,8 +568,6 @@ struct snd_dbri {
#define DBRI_STREAM(dbri, substream)	\
		&dbri->stream_info[DBRI_STREAMNO(substream)]

static struct snd_dbri *dbri_list;	/* All DBRI devices */

/*
 * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr.
 * So we have to reverse the bits. Note: not all bit lengths are supported
@@ -748,7 +743,7 @@ static void dbri_reset(struct snd_dbri *dbri)
}

/* Lock must not be held before calling this */
static void __init dbri_initialize(struct snd_dbri *dbri)
static void __devinit dbri_initialize(struct snd_dbri *dbri)
{
	s32 *cmd;
	u32 dma_addr;
@@ -1308,7 +1303,7 @@ to the DBRI via the CHI interface and few of the DBRI's PIO pins.
 * Lock must not be held before calling it.

*/
static __init void cs4215_setup_pipes(struct snd_dbri *dbri)
static __devinit void cs4215_setup_pipes(struct snd_dbri *dbri)
{
	unsigned long flags;

@@ -1341,7 +1336,7 @@ static __init void cs4215_setup_pipes(struct snd_dbri *dbri)
	dbri_cmdwait(dbri);
}

static __init int cs4215_init_data(struct cs4215 *mm)
static __devinit int cs4215_init_data(struct cs4215 *mm)
{
	/*
	 * No action, memory resetting only.
@@ -1633,7 +1628,7 @@ static int cs4215_prepare(struct snd_dbri *dbri, unsigned int rate,
/*
 *
 */
static __init int cs4215_init(struct snd_dbri *dbri)
static __devinit int cs4215_init(struct snd_dbri *dbri)
{
	u32 reg2 = sbus_readl(dbri->regs + REG2);
	dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2);
@@ -2218,12 +2213,12 @@ static struct snd_pcm_ops snd_dbri_ops = {
	.pointer = snd_dbri_pointer,
};

static int __devinit snd_dbri_pcm(struct snd_dbri *dbri)
static int __devinit snd_dbri_pcm(struct snd_card *card)
{
	struct snd_pcm *pcm;
	int err;

	if ((err = snd_pcm_new(dbri->card,
	if ((err = snd_pcm_new(card,
			       /* ID */		    "sun_dbri",
			       /* device */	    0,
			       /* playback count */ 1,
@@ -2234,9 +2229,9 @@ static int __devinit snd_dbri_pcm(struct snd_dbri *dbri)
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops);
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops);

	pcm->private_data = dbri;
	pcm->private_data = card->private_data;
	pcm->info_flags = 0;
	strcpy(pcm->name, dbri->card->shortname);
	strcpy(pcm->name, card->shortname);

	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm,
			SNDRV_DMA_TYPE_CONTINUOUS,
@@ -2422,14 +2417,14 @@ static struct snd_kcontrol_new dbri_controls[] __devinitdata = {
	CS4215_SINGLE("Mic boost", 4, 4, 1, 1)
};

static int __init snd_dbri_mixer(struct snd_dbri *dbri)
static int __devinit snd_dbri_mixer(struct snd_card *card)
{
	struct snd_card *card;
	int idx, err;
	struct snd_dbri *dbri;

	snd_assert(dbri != NULL && dbri->card != NULL, return -EINVAL);
	snd_assert(card != NULL && card->private_data != NULL, return -EINVAL);
	dbri = card->private_data;

	card = dbri->card;
	strcpy(card->mixername, card->shortname);

	for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) {
@@ -2485,15 +2480,16 @@ static void dbri_debug_read(struct snd_info_entry *entry,
}
#endif

void snd_dbri_proc(struct snd_dbri *dbri)
void __devinit snd_dbri_proc(struct snd_card *card)
{
	struct snd_dbri *dbri = card->private_data;
	struct snd_info_entry *entry;

	if (!snd_card_proc_new(dbri->card, "regs", &entry))
	if (!snd_card_proc_new(card, "regs", &entry))
		snd_info_set_text_ops(entry, dbri, dbri_regs_read);

#ifdef DBRI_DEBUG
	if (!snd_card_proc_new(dbri->card, "debug", &entry)) {
	if (!snd_card_proc_new(card, "debug", &entry)) {
		snd_info_set_text_ops(entry, dbri, dbri_debug_read);
		entry->mode = S_IFREG | S_IRUGO;	/* Readable only. */
	}
@@ -2507,17 +2503,16 @@ void snd_dbri_proc(struct snd_dbri *dbri)
*/
static void snd_dbri_free(struct snd_dbri *dbri);

static int __init snd_dbri_create(struct snd_card *card,
static int __devinit snd_dbri_create(struct snd_card *card,
				  struct sbus_dev *sdev,
				  struct linux_prom_irqs *irq, int dev)
				  int irq, int dev)
{
	struct snd_dbri *dbri = card->private_data;
	int err;

	spin_lock_init(&dbri->lock);
	dbri->card = card;
	dbri->sdev = sdev;
	dbri->irq = irq->pri;
	dbri->irq = irq;

	dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma),
					  &dbri->dma_dvma);
@@ -2555,9 +2550,6 @@ static int __init snd_dbri_create(struct snd_card *card,
		return err;
	}

	dbri->next = dbri_list;
	dbri_list = dbri;

	return 0;
}

@@ -2577,20 +2569,19 @@ static void snd_dbri_free(struct snd_dbri *dbri)
				     (void *)dbri->dma, dbri->dma_dvma);
}

static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
static int __devinit dbri_probe(struct of_device *of_dev,
				const struct of_device_id *match)
{
	struct sbus_dev *sdev = to_sbus_device(&of_dev->dev);
	struct snd_dbri *dbri;
	struct linux_prom_irqs irq;
	int irq;
	struct resource *rp;
	struct snd_card *card;
	static int dev = 0;
	int err;

	if (sdev->prom_name[9] < 'e') {
		printk(KERN_ERR "DBRI: unsupported chip version %c found.\n",
		       sdev->prom_name[9]);
		return -EIO;
	}
	dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n",
		sdev->prom_name, sdev->slot);

	if (dev >= SNDRV_CARDS)
		return -ENODEV;
@@ -2599,10 +2590,9 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
		return -ENOENT;
	}

	err = prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq));
	if (err < 0) {
		printk(KERN_ERR "DBRI-%d: Firmware node lacks IRQ property.\n",
			dev);
	irq = sdev->irqs[0];
	if (irq <= 0) {
		printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev);
		return -ENODEV;
	}

@@ -2616,24 +2606,26 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
	rp = &sdev->resource[0];
	sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d",
		card->shortname,
		rp->flags & 0xffL, (unsigned long long)rp->start, irq.pri);
		rp->flags & 0xffL, (unsigned long long)rp->start, irq);

	if ((err = snd_dbri_create(card, sdev, &irq, dev)) < 0) {
	err = snd_dbri_create(card, sdev, irq, dev);
	if (err < 0) {
		snd_card_free(card);
		return err;
	}

	dbri = card->private_data;
	err = snd_dbri_pcm(dbri);
	err = snd_dbri_pcm(card);
	if (err < 0)
		goto _err;

	err = snd_dbri_mixer(dbri);
	err = snd_dbri_mixer(card);
	if (err < 0)
		goto _err;

	/* /proc file handling */
	snd_dbri_proc(dbri);
	snd_dbri_proc(card);
	dev_set_drvdata(&of_dev->dev, card);

	err = snd_card_register(card);
	if (err < 0)
@@ -2652,43 +2644,46 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
	return err;
}

/* Probe for the dbri chip and then attach the driver. */
static int __init dbri_init(void)
static int __devexit dbri_remove(struct of_device *dev)
{
	struct sbus_bus *sbus;
	struct sbus_dev *sdev;
	int found = 0;
	struct snd_card *card = dev_get_drvdata(&dev->dev);

	/* Probe each SBUS for the DBRI chip(s). */
	for_all_sbusdev(sdev, sbus) {
		/*
		 * The version is coded in the last character
		 */
		if (!strncmp(sdev->prom_name, "SUNW,DBRI", 9)) {
			dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n",
				sdev->prom_name, sdev->slot);
	snd_dbri_free(card->private_data);
	snd_card_free(card);

			if (dbri_attach(sdev->prom_node, sdev) == 0)
				found++;
		}
	}
	dev_set_drvdata(&dev->dev, NULL);

	return (found > 0) ? 0 : -EIO;
	return 0;
}

static void __exit dbri_exit(void)
static struct of_device_id dbri_match[] = {
	{
		.name = "SUNW,DBRIe",
	},
	{
	struct snd_dbri *this = dbri_list;
		.name = "SUNW,DBRIf",
	},
	{},
};

	while (this != NULL) {
		struct snd_dbri *next = this->next;
		struct snd_card *card = this->card;
MODULE_DEVICE_TABLE(of, dbri_match);

		snd_dbri_free(this);
		snd_card_free(card);
		this = next;
static struct of_platform_driver dbri_sbus_driver = {
	.name		= "dbri",
	.match_table	= dbri_match,
	.probe		= dbri_probe,
	.remove		= __devexit_p(dbri_remove),
};

/* Probe for the dbri chip and then attach the driver. */
static int __init dbri_init(void)
{
	return of_register_driver(&dbri_sbus_driver, &sbus_bus_type);
}
	dbri_list = NULL;

static void __exit dbri_exit(void)
{
	of_unregister_driver(&dbri_sbus_driver);
}

module_init(dbri_init);