// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  ALSA interface to cx18 PCM capture streams
 *
 *  Copyright (C) 2009  Andy Walls <awalls@md.metrocast.net>
 *  Copyright (C) 2009  Devin Heitmueller <dheitmueller@kernellabs.com>
 *
 *  Portions of this work were sponsored by ONELAN Limited.
 */

#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/spinlock.h>

#include <media/v4l2-device.h>

#include <sound/core.h>
#include <sound/initval.h>

#include "cx18-driver.h"
#include "cx18-version.h"
#include "cx18-alsa.h"
#include "cx18-alsa-pcm.h"

int cx18_alsa_debug;

#define CX18_DEBUG_ALSA_INFO(fmt, arg...) \
	do { \
		if (cx18_alsa_debug & 2) \
			printk(KERN_INFO "%s: " fmt, "cx18-alsa", ## arg); \
	} while (0);

module_param_named(debug, cx18_alsa_debug, int, 0644);
MODULE_PARM_DESC(debug,
		 "Debug level (bitmask). Default: 0\n"
		 "\t\t\t  1/0x0001: warning\n"
		 "\t\t\t  2/0x0002: info\n");

MODULE_AUTHOR("Andy Walls");
MODULE_DESCRIPTION("CX23418 ALSA Interface");
MODULE_LICENSE("GPL");

MODULE_VERSION(CX18_VERSION);

static inline
struct snd_cx18_card *to_snd_cx18_card(struct v4l2_device *v4l2_dev)
{
	return to_cx18(v4l2_dev)->alsa;
}

static inline
struct snd_cx18_card *p_to_snd_cx18_card(struct v4l2_device **v4l2_dev)
{
	return container_of(v4l2_dev, struct snd_cx18_card, v4l2_dev);
}

static void snd_cx18_card_free(struct snd_cx18_card *cxsc)
{
	if (cxsc == NULL)
		return;

	if (cxsc->v4l2_dev != NULL)
		to_cx18(cxsc->v4l2_dev)->alsa = NULL;

	/* FIXME - take any other stopping actions needed */

	kfree(cxsc);
}

static void snd_cx18_card_private_free(struct snd_card *sc)
{
	if (sc == NULL)
		return;
	snd_cx18_card_free(sc->private_data);
	sc->private_data = NULL;
	sc->private_free = NULL;
}

static int snd_cx18_card_create(struct v4l2_device *v4l2_dev,
				       struct snd_card *sc,
				       struct snd_cx18_card **cxsc)
{
	*cxsc = kzalloc(sizeof(struct snd_cx18_card), GFP_KERNEL);
	if (*cxsc == NULL)
		return -ENOMEM;

	(*cxsc)->v4l2_dev = v4l2_dev;
	(*cxsc)->sc = sc;

	sc->private_data = *cxsc;
	sc->private_free = snd_cx18_card_private_free;

	return 0;
}

static int snd_cx18_card_set_names(struct snd_cx18_card *cxsc)
{
	struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
	struct snd_card *sc = cxsc->sc;

	/* sc->driver is used by alsa-lib's configurator: simple, unique */
	strscpy(sc->driver, "CX23418", sizeof(sc->driver));

	/* sc->shortname is a symlink in /proc/asound: CX18-M -> cardN */
	snprintf(sc->shortname,  sizeof(sc->shortname), "CX18-%d",
		 cx->instance);

	/* sc->longname is read from /proc/asound/cards */
	snprintf(sc->longname, sizeof(sc->longname),
		 "CX23418 #%d %s TV/FM Radio/Line-In Capture",
		 cx->instance, cx->card_name);

	return 0;
}

static int snd_cx18_init(struct v4l2_device *v4l2_dev)
{
	struct cx18 *cx = to_cx18(v4l2_dev);
	struct snd_card *sc = NULL;
	struct snd_cx18_card *cxsc;
	int ret;

	/* Numbrs steps from "Writing an ALSA Driver" by Takashi Iwai */

	/* (1) Check and increment the device index */
	/* This is a no-op for us.  We'll use the cx->instance */

	/* (2) Create a card instance */
	ret = snd_card_new(&cx->pci_dev->dev,
			   SNDRV_DEFAULT_IDX1, /* use first available id */
			   SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
			   THIS_MODULE, 0, &sc);
	if (ret) {
		CX18_ALSA_ERR("%s: snd_card_new() failed with err %d\n",
			      __func__, ret);
		goto err_exit;
	}

	/* (3) Create a main component */
	ret = snd_cx18_card_create(v4l2_dev, sc, &cxsc);
	if (ret) {
		CX18_ALSA_ERR("%s: snd_cx18_card_create() failed with err %d\n",
			      __func__, ret);
		goto err_exit_free;
	}

	/* (4) Set the driver ID and name strings */
	snd_cx18_card_set_names(cxsc);


	ret = snd_cx18_pcm_create(cxsc);
	if (ret) {
		CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
			      __func__, ret);
		goto err_exit_free;
	}
	/* FIXME - proc files */

	/* (7) Set the driver data and return 0 */
	/* We do this out of normal order for PCI drivers to avoid races */
	cx->alsa = cxsc;

	/* (6) Register the card instance */
	ret = snd_card_register(sc);
	if (ret) {
		cx->alsa = NULL;
		CX18_ALSA_ERR("%s: snd_card_register() failed with err %d\n",
			      __func__, ret);
		goto err_exit_free;
	}

	return 0;

err_exit_free:
	if (sc != NULL)
		snd_card_free(sc);
	kfree(cxsc);
err_exit:
	return ret;
}

static int cx18_alsa_load(struct cx18 *cx)
{
	struct v4l2_device *v4l2_dev = &cx->v4l2_dev;
	struct cx18_stream *s;

	if (v4l2_dev == NULL) {
		printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
		       __func__);
		return 0;
	}

	cx = to_cx18(v4l2_dev);
	if (cx == NULL) {
		printk(KERN_ERR "cx18-alsa cx is NULL\n");
		return 0;
	}

	s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
	if (s->video_dev.v4l2_dev == NULL) {
		CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - skipping\n",
				     __func__);
		return 0;
	}

	if (cx->alsa != NULL) {
		CX18_ALSA_ERR("%s: struct snd_cx18_card * already exists\n",
			      __func__);
		return 0;
	}

	if (snd_cx18_init(v4l2_dev)) {
		CX18_ALSA_ERR("%s: failed to create struct snd_cx18_card\n",
			      __func__);
	} else {
		CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance\n",
				     __func__);
	}
	return 0;
}

static int __init cx18_alsa_init(void)
{
	printk(KERN_INFO "cx18-alsa: module loading...\n");
	cx18_ext_init = &cx18_alsa_load;
	return 0;
}

static void __exit snd_cx18_exit(struct snd_cx18_card *cxsc)
{
	struct cx18 *cx = to_cx18(cxsc->v4l2_dev);

	/* FIXME - pointer checks & shutdown cxsc */

	snd_card_free(cxsc->sc);
	cx->alsa = NULL;
}

static int __exit cx18_alsa_exit_callback(struct device *dev, void *data)
{
	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
	struct snd_cx18_card *cxsc;

	if (v4l2_dev == NULL) {
		printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
		       __func__);
		return 0;
	}

	cxsc = to_snd_cx18_card(v4l2_dev);
	if (cxsc == NULL) {
		CX18_ALSA_WARN("%s: struct snd_cx18_card * is NULL\n",
			       __func__);
		return 0;
	}

	snd_cx18_exit(cxsc);
	return 0;
}

static void __exit cx18_alsa_exit(void)
{
	struct device_driver *drv;
	int ret;

	printk(KERN_INFO "cx18-alsa: module unloading...\n");

	drv = driver_find("cx18", &pci_bus_type);
	ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback);
	(void)ret;	/* suppress compiler warning */

	cx18_ext_init = NULL;
	printk(KERN_INFO "cx18-alsa: module unload complete\n");
}

module_init(cx18_alsa_init);
module_exit(cx18_alsa_exit);
