// SPDX-License-Identifier: GPL-2.0-only
/*
 * wm0010.c  --  WM0010 DSP Driver
 *
 * Copyright 2012 Wolfson Microelectronics PLC.
 *
 * Authors: Mark Brown <broonie@opensource.wolfsonmicro.com>
 *          Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
 *          Scott Ling <sl@opensource.wolfsonmicro.com>
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/init.h>
#include <linux/spi/spi.h>
#include <linux/firmware.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>

#include <sound/soc.h>
#include <sound/wm0010.h>

#define DEVICE_ID_WM0010	10

/* We only support v1 of the .dfw INFO record */
#define INFO_VERSION		1

enum dfw_cmd {
	DFW_CMD_FUSE = 0x01,
	DFW_CMD_CODE_HDR,
	DFW_CMD_CODE_DATA,
	DFW_CMD_PLL,
	DFW_CMD_INFO = 0xff
};

struct dfw_binrec {
	u8 command;
	u32 length:24;
	u32 address;
	uint8_t data[0];
} __packed;

struct dfw_inforec {
	u8 info_version;
	u8 tool_major_version;
	u8 tool_minor_version;
	u8 dsp_target;
};

struct dfw_pllrec {
	u8 command;
	u32 length:24;
	u32 address;
	u32 clkctrl1;
	u32 clkctrl2;
	u32 clkctrl3;
	u32 ldetctrl;
	u32 uart_div;
	u32 spi_div;
} __packed;

static struct pll_clock_map {
	int max_sysclk;
	int max_pll_spi_speed;
	u32 pll_clkctrl1;
} pll_clock_map[] = {			   /* Dividers */
	{ 22000000, 26000000, 0x00201f11 }, /* 2,32,2  */
	{ 18000000, 26000000, 0x00203f21 }, /* 2,64,4  */
	{ 14000000, 26000000, 0x00202620 }, /* 1,39,4  */
	{ 10000000, 22000000, 0x00203120 }, /* 1,50,4  */
	{  6500000, 22000000, 0x00204520 }, /* 1,70,4  */
	{  5500000, 22000000, 0x00103f10 }, /* 1,64,2  */
};

enum wm0010_state {
	WM0010_POWER_OFF,
	WM0010_OUT_OF_RESET,
	WM0010_BOOTROM,
	WM0010_STAGE2,
	WM0010_FIRMWARE,
};

struct wm0010_priv {
	struct snd_soc_component *component;

	struct mutex lock;
	struct device *dev;

	struct wm0010_pdata pdata;

	int gpio_reset;
	int gpio_reset_value;

	struct regulator_bulk_data core_supplies[2];
	struct regulator *dbvdd;

	int sysclk;

	enum wm0010_state state;
	bool boot_failed;
	bool ready;
	bool pll_running;
	int max_spi_freq;
	int board_max_spi_speed;
	u32 pll_clkctrl1;

	spinlock_t irq_lock;
	int irq;

	struct completion boot_completion;
};

struct wm0010_spi_msg {
	struct spi_message m;
	struct spi_transfer t;
	u8 *tx_buf;
	u8 *rx_buf;
	size_t len;
};

static const struct snd_soc_dapm_widget wm0010_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("CLKIN",  SND_SOC_NOPM, 0, 0, NULL, 0),
};

static const struct snd_soc_dapm_route wm0010_dapm_routes[] = {
	{ "SDI2 Capture", NULL, "SDI1 Playback" },
	{ "SDI1 Capture", NULL, "SDI2 Playback" },

	{ "SDI1 Capture", NULL, "CLKIN" },
	{ "SDI2 Capture", NULL, "CLKIN" },
	{ "SDI1 Playback", NULL, "CLKIN" },
	{ "SDI2 Playback", NULL, "CLKIN" },
};

static const char *wm0010_state_to_str(enum wm0010_state state)
{
	static const char * const state_to_str[] = {
		"Power off",
		"Out of reset",
		"Boot ROM",
		"Stage2",
		"Firmware"
	};

	if (state < 0 || state >= ARRAY_SIZE(state_to_str))
		return "null";
	return state_to_str[state];
}

/* Called with wm0010->lock held */
static void wm0010_halt(struct snd_soc_component *component)
{
	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
	unsigned long flags;
	enum wm0010_state state;

	/* Fetch the wm0010 state */
	spin_lock_irqsave(&wm0010->irq_lock, flags);
	state = wm0010->state;
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

	switch (state) {
	case WM0010_POWER_OFF:
		/* If there's nothing to do, bail out */
		return;
	case WM0010_OUT_OF_RESET:
	case WM0010_BOOTROM:
	case WM0010_STAGE2:
	case WM0010_FIRMWARE:
		/* Remember to put chip back into reset */
		gpio_set_value_cansleep(wm0010->gpio_reset,
					wm0010->gpio_reset_value);
		/* Disable the regulators */
		regulator_disable(wm0010->dbvdd);
		regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies),
				       wm0010->core_supplies);
		break;
	}

	spin_lock_irqsave(&wm0010->irq_lock, flags);
	wm0010->state = WM0010_POWER_OFF;
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);
}

struct wm0010_boot_xfer {
	struct list_head list;
	struct snd_soc_component *component;
	struct completion *done;
	struct spi_message m;
	struct spi_transfer t;
};

/* Called with wm0010->lock held */
static void wm0010_mark_boot_failure(struct wm0010_priv *wm0010)
{
	enum wm0010_state state;
	unsigned long flags;

	spin_lock_irqsave(&wm0010->irq_lock, flags);
	state = wm0010->state;
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

	dev_err(wm0010->dev, "Failed to transition from `%s' state to `%s' state\n",
		wm0010_state_to_str(state), wm0010_state_to_str(state + 1));

	wm0010->boot_failed = true;
}

static void wm0010_boot_xfer_complete(void *data)
{
	struct wm0010_boot_xfer *xfer = data;
	struct snd_soc_component *component = xfer->component;
	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
	u32 *out32 = xfer->t.rx_buf;
	int i;

	if (xfer->m.status != 0) {
		dev_err(component->dev, "SPI transfer failed: %d\n",
			xfer->m.status);
		wm0010_mark_boot_failure(wm0010);
		if (xfer->done)
			complete(xfer->done);
		return;
	}

	for (i = 0; i < xfer->t.len / 4; i++) {
		dev_dbg(component->dev, "%d: %04x\n", i, out32[i]);

		switch (be32_to_cpu(out32[i])) {
		case 0xe0e0e0e0:
			dev_err(component->dev,
				"%d: ROM error reported in stage 2\n", i);
			wm0010_mark_boot_failure(wm0010);
			break;

		case 0x55555555:
			if (wm0010->state < WM0010_STAGE2)
				break;
			dev_err(component->dev,
				"%d: ROM bootloader running in stage 2\n", i);
			wm0010_mark_boot_failure(wm0010);
			break;

		case 0x0fed0000:
			dev_dbg(component->dev, "Stage2 loader running\n");
			break;

		case 0x0fed0007:
			dev_dbg(component->dev, "CODE_HDR packet received\n");
			break;

		case 0x0fed0008:
			dev_dbg(component->dev, "CODE_DATA packet received\n");
			break;

		case 0x0fed0009:
			dev_dbg(component->dev, "Download complete\n");
			break;

		case 0x0fed000c:
			dev_dbg(component->dev, "Application start\n");
			break;

		case 0x0fed000e:
			dev_dbg(component->dev, "PLL packet received\n");
			wm0010->pll_running = true;
			break;

		case 0x0fed0025:
			dev_err(component->dev, "Device reports image too long\n");
			wm0010_mark_boot_failure(wm0010);
			break;

		case 0x0fed002c:
			dev_err(component->dev, "Device reports bad SPI packet\n");
			wm0010_mark_boot_failure(wm0010);
			break;

		case 0x0fed0031:
			dev_err(component->dev, "Device reports SPI read overflow\n");
			wm0010_mark_boot_failure(wm0010);
			break;

		case 0x0fed0032:
			dev_err(component->dev, "Device reports SPI underclock\n");
			wm0010_mark_boot_failure(wm0010);
			break;

		case 0x0fed0033:
			dev_err(component->dev, "Device reports bad header packet\n");
			wm0010_mark_boot_failure(wm0010);
			break;

		case 0x0fed0034:
			dev_err(component->dev, "Device reports invalid packet type\n");
			wm0010_mark_boot_failure(wm0010);
			break;

		case 0x0fed0035:
			dev_err(component->dev, "Device reports data before header error\n");
			wm0010_mark_boot_failure(wm0010);
			break;

		case 0x0fed0038:
			dev_err(component->dev, "Device reports invalid PLL packet\n");
			break;

		case 0x0fed003a:
			dev_err(component->dev, "Device reports packet alignment error\n");
			wm0010_mark_boot_failure(wm0010);
			break;

		default:
			dev_err(component->dev, "Unrecognised return 0x%x\n",
			    be32_to_cpu(out32[i]));
			wm0010_mark_boot_failure(wm0010);
			break;
		}

		if (wm0010->boot_failed)
			break;
	}

	if (xfer->done)
		complete(xfer->done);
}

static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len)
{
	int i;

	for (i = 0; i < len / 8; i++)
		data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i]));
}

static int wm0010_firmware_load(const char *name, struct snd_soc_component *component)
{
	struct spi_device *spi = to_spi_device(component->dev);
	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
	struct list_head xfer_list;
	struct wm0010_boot_xfer *xfer;
	int ret;
	struct completion done;
	const struct firmware *fw;
	const struct dfw_binrec *rec;
	const struct dfw_inforec *inforec;
	u64 *img;
	u8 *out, dsp;
	u32 len, offset;

	INIT_LIST_HEAD(&xfer_list);

	ret = request_firmware(&fw, name, component->dev);
	if (ret != 0) {
		dev_err(component->dev, "Failed to request application(%s): %d\n",
			name, ret);
		return ret;
	}

	rec = (const struct dfw_binrec *)fw->data;
	inforec = (const struct dfw_inforec *)rec->data;
	offset = 0;
	dsp = inforec->dsp_target;
	wm0010->boot_failed = false;
	if (WARN_ON(!list_empty(&xfer_list)))
		return -EINVAL;
	init_completion(&done);

	/* First record should be INFO */
	if (rec->command != DFW_CMD_INFO) {
		dev_err(component->dev, "First record not INFO\r\n");
		ret = -EINVAL;
		goto abort;
	}

	if (inforec->info_version != INFO_VERSION) {
		dev_err(component->dev,
			"Unsupported version (%02d) of INFO record\r\n",
			inforec->info_version);
		ret = -EINVAL;
		goto abort;
	}

	dev_dbg(component->dev, "Version v%02d INFO record found\r\n",
		inforec->info_version);

	/* Check it's a DSP file */
	if (dsp != DEVICE_ID_WM0010) {
		dev_err(component->dev, "Not a WM0010 firmware file.\r\n");
		ret = -EINVAL;
		goto abort;
	}

	/* Skip the info record as we don't need to send it */
	offset += ((rec->length) + 8);
	rec = (void *)&rec->data[rec->length];

	while (offset < fw->size) {
		dev_dbg(component->dev,
			"Packet: command %d, data length = 0x%x\r\n",
			rec->command, rec->length);
		len = rec->length + 8;

		xfer = kzalloc(sizeof(*xfer), GFP_KERNEL);
		if (!xfer) {
			ret = -ENOMEM;
			goto abort;
		}

		xfer->component = component;
		list_add_tail(&xfer->list, &xfer_list);

		out = kzalloc(len, GFP_KERNEL | GFP_DMA);
		if (!out) {
			ret = -ENOMEM;
			goto abort1;
		}
		xfer->t.rx_buf = out;

		img = kzalloc(len, GFP_KERNEL | GFP_DMA);
		if (!img) {
			ret = -ENOMEM;
			goto abort1;
		}
		xfer->t.tx_buf = img;

		byte_swap_64((u64 *)&rec->command, img, len);

		spi_message_init(&xfer->m);
		xfer->m.complete = wm0010_boot_xfer_complete;
		xfer->m.context = xfer;
		xfer->t.len = len;
		xfer->t.bits_per_word = 8;

		if (!wm0010->pll_running) {
			xfer->t.speed_hz = wm0010->sysclk / 6;
		} else {
			xfer->t.speed_hz = wm0010->max_spi_freq;

			if (wm0010->board_max_spi_speed &&
			   (wm0010->board_max_spi_speed < wm0010->max_spi_freq))
					xfer->t.speed_hz = wm0010->board_max_spi_speed;
		}

		/* Store max usable spi frequency for later use */
		wm0010->max_spi_freq = xfer->t.speed_hz;

		spi_message_add_tail(&xfer->t, &xfer->m);

		offset += ((rec->length) + 8);
		rec = (void *)&rec->data[rec->length];

		if (offset >= fw->size) {
			dev_dbg(component->dev, "All transfers scheduled\n");
			xfer->done = &done;
		}

		ret = spi_async(spi, &xfer->m);
		if (ret != 0) {
			dev_err(component->dev, "Write failed: %d\n", ret);
			goto abort1;
		}

		if (wm0010->boot_failed) {
			dev_dbg(component->dev, "Boot fail!\n");
			ret = -EINVAL;
			goto abort1;
		}
	}

	wait_for_completion(&done);

	ret = 0;

abort1:
	while (!list_empty(&xfer_list)) {
		xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer,
					list);
		kfree(xfer->t.rx_buf);
		kfree(xfer->t.tx_buf);
		list_del(&xfer->list);
		kfree(xfer);
	}

abort:
	release_firmware(fw);
	return ret;
}

static int wm0010_stage2_load(struct snd_soc_component *component)
{
	struct spi_device *spi = to_spi_device(component->dev);
	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
	const struct firmware *fw;
	struct spi_message m;
	struct spi_transfer t;
	u32 *img;
	u8 *out;
	int i;
	int ret = 0;

	ret = request_firmware(&fw, "wm0010_stage2.bin", component->dev);
	if (ret != 0) {
		dev_err(component->dev, "Failed to request stage2 loader: %d\n",
			ret);
		return ret;
	}

	dev_dbg(component->dev, "Downloading %zu byte stage 2 loader\n", fw->size);

	/* Copy to local buffer first as vmalloc causes problems for dma */
	img = kzalloc(fw->size, GFP_KERNEL | GFP_DMA);
	if (!img) {
		ret = -ENOMEM;
		goto abort2;
	}

	out = kzalloc(fw->size, GFP_KERNEL | GFP_DMA);
	if (!out) {
		ret = -ENOMEM;
		goto abort1;
	}

	memcpy(img, &fw->data[0], fw->size);

	spi_message_init(&m);
	memset(&t, 0, sizeof(t));
	t.rx_buf = out;
	t.tx_buf = img;
	t.len = fw->size;
	t.bits_per_word = 8;
	t.speed_hz = wm0010->sysclk / 10;
	spi_message_add_tail(&t, &m);

	dev_dbg(component->dev, "Starting initial download at %dHz\n",
		t.speed_hz);

	ret = spi_sync(spi, &m);
	if (ret != 0) {
		dev_err(component->dev, "Initial download failed: %d\n", ret);
		goto abort;
	}

	/* Look for errors from the boot ROM */
	for (i = 0; i < fw->size; i++) {
		if (out[i] != 0x55) {
			dev_err(component->dev, "Boot ROM error: %x in %d\n",
				out[i], i);
			wm0010_mark_boot_failure(wm0010);
			ret = -EBUSY;
			goto abort;
		}
	}
abort:
	kfree(out);
abort1:
	kfree(img);
abort2:
	release_firmware(fw);

	return ret;
}

static int wm0010_boot(struct snd_soc_component *component)
{
	struct spi_device *spi = to_spi_device(component->dev);
	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
	unsigned long flags;
	int ret;
	struct spi_message m;
	struct spi_transfer t;
	struct dfw_pllrec pll_rec;
	u32 *p, len;
	u64 *img_swap;
	u8 *out;
	int i;

	spin_lock_irqsave(&wm0010->irq_lock, flags);
	if (wm0010->state != WM0010_POWER_OFF)
		dev_warn(wm0010->dev, "DSP already powered up!\n");
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

	if (wm0010->sysclk > 26000000) {
		dev_err(component->dev, "Max DSP clock frequency is 26MHz\n");
		ret = -ECANCELED;
		goto err;
	}

	mutex_lock(&wm0010->lock);
	wm0010->pll_running = false;

	dev_dbg(component->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq);

	ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies),
				    wm0010->core_supplies);
	if (ret != 0) {
		dev_err(&spi->dev, "Failed to enable core supplies: %d\n",
			ret);
		mutex_unlock(&wm0010->lock);
		goto err;
	}

	ret = regulator_enable(wm0010->dbvdd);
	if (ret != 0) {
		dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret);
		goto err_core;
	}

	/* Release reset */
	gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value);
	spin_lock_irqsave(&wm0010->irq_lock, flags);
	wm0010->state = WM0010_OUT_OF_RESET;
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

	if (!wait_for_completion_timeout(&wm0010->boot_completion,
					 msecs_to_jiffies(20)))
		dev_err(component->dev, "Failed to get interrupt from DSP\n");

	spin_lock_irqsave(&wm0010->irq_lock, flags);
	wm0010->state = WM0010_BOOTROM;
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

	ret = wm0010_stage2_load(component);
	if (ret)
		goto abort;

	if (!wait_for_completion_timeout(&wm0010->boot_completion,
					 msecs_to_jiffies(20)))
		dev_err(component->dev, "Failed to get interrupt from DSP loader.\n");

	spin_lock_irqsave(&wm0010->irq_lock, flags);
	wm0010->state = WM0010_STAGE2;
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

	/* Only initialise PLL if max_spi_freq initialised */
	if (wm0010->max_spi_freq) {

		/* Initialise a PLL record */
		memset(&pll_rec, 0, sizeof(pll_rec));
		pll_rec.command = DFW_CMD_PLL;
		pll_rec.length = (sizeof(pll_rec) - 8);

		/* On wm0010 only the CLKCTRL1 value is used */
		pll_rec.clkctrl1 = wm0010->pll_clkctrl1;

		ret = -ENOMEM;
		len = pll_rec.length + 8;
		out = kzalloc(len, GFP_KERNEL | GFP_DMA);
		if (!out)
			goto abort;

		img_swap = kzalloc(len, GFP_KERNEL | GFP_DMA);
		if (!img_swap)
			goto abort_out;

		/* We need to re-order for 0010 */
		byte_swap_64((u64 *)&pll_rec, img_swap, len);

		spi_message_init(&m);
		memset(&t, 0, sizeof(t));
		t.rx_buf = out;
		t.tx_buf = img_swap;
		t.len = len;
		t.bits_per_word = 8;
		t.speed_hz = wm0010->sysclk / 6;
		spi_message_add_tail(&t, &m);

		ret = spi_sync(spi, &m);
		if (ret) {
			dev_err(component->dev, "First PLL write failed: %d\n", ret);
			goto abort_swap;
		}

		/* Use a second send of the message to get the return status */
		ret = spi_sync(spi, &m);
		if (ret) {
			dev_err(component->dev, "Second PLL write failed: %d\n", ret);
			goto abort_swap;
		}

		p = (u32 *)out;

		/* Look for PLL active code from the DSP */
		for (i = 0; i < len / 4; i++) {
			if (*p == 0x0e00ed0f) {
				dev_dbg(component->dev, "PLL packet received\n");
				wm0010->pll_running = true;
				break;
			}
			p++;
		}

		kfree(img_swap);
		kfree(out);
	} else
		dev_dbg(component->dev, "Not enabling DSP PLL.");

	ret = wm0010_firmware_load("wm0010.dfw", component);

	if (ret != 0)
		goto abort;

	spin_lock_irqsave(&wm0010->irq_lock, flags);
	wm0010->state = WM0010_FIRMWARE;
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

	mutex_unlock(&wm0010->lock);

	return 0;

abort_swap:
	kfree(img_swap);
abort_out:
	kfree(out);
abort:
	/* Put the chip back into reset */
	wm0010_halt(component);
	mutex_unlock(&wm0010->lock);
	return ret;

err_core:
	mutex_unlock(&wm0010->lock);
	regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies),
			       wm0010->core_supplies);
err:
	return ret;
}

static int wm0010_set_bias_level(struct snd_soc_component *component,
				 enum snd_soc_bias_level level)
{
	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);

	switch (level) {
	case SND_SOC_BIAS_ON:
		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE)
			wm0010_boot(component);
		break;
	case SND_SOC_BIAS_PREPARE:
		break;
	case SND_SOC_BIAS_STANDBY:
		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) {
			mutex_lock(&wm0010->lock);
			wm0010_halt(component);
			mutex_unlock(&wm0010->lock);
		}
		break;
	case SND_SOC_BIAS_OFF:
		break;
	}

	return 0;
}

static int wm0010_set_sysclk(struct snd_soc_component *component, int source,
			     int clk_id, unsigned int freq, int dir)
{
	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
	unsigned int i;

	wm0010->sysclk = freq;

	if (freq < pll_clock_map[ARRAY_SIZE(pll_clock_map)-1].max_sysclk) {
		wm0010->max_spi_freq = 0;
	} else {
		for (i = 0; i < ARRAY_SIZE(pll_clock_map); i++)
			if (freq >= pll_clock_map[i].max_sysclk) {
				wm0010->max_spi_freq = pll_clock_map[i].max_pll_spi_speed;
				wm0010->pll_clkctrl1 = pll_clock_map[i].pll_clkctrl1;
				break;
			}
	}

	return 0;
}

static int wm0010_probe(struct snd_soc_component *component);

static const struct snd_soc_component_driver soc_component_dev_wm0010 = {
	.probe			= wm0010_probe,
	.set_bias_level		= wm0010_set_bias_level,
	.set_sysclk		= wm0010_set_sysclk,
	.dapm_widgets		= wm0010_dapm_widgets,
	.num_dapm_widgets	= ARRAY_SIZE(wm0010_dapm_widgets),
	.dapm_routes		= wm0010_dapm_routes,
	.num_dapm_routes	= ARRAY_SIZE(wm0010_dapm_routes),
	.use_pmdown_time	= 1,
	.endianness		= 1,
	.non_legacy_dai_naming	= 1,
};

#define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
#define WM0010_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
			SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
			SNDRV_PCM_FMTBIT_S32_LE)

static struct snd_soc_dai_driver wm0010_dai[] = {
	{
		.name = "wm0010-sdi1",
		.playback = {
			.stream_name = "SDI1 Playback",
			.channels_min = 1,
			.channels_max = 2,
			.rates = WM0010_RATES,
			.formats = WM0010_FORMATS,
		},
		.capture = {
			 .stream_name = "SDI1 Capture",
			 .channels_min = 1,
			 .channels_max = 2,
			 .rates = WM0010_RATES,
			 .formats = WM0010_FORMATS,
		 },
	},
	{
		.name = "wm0010-sdi2",
		.playback = {
			.stream_name = "SDI2 Playback",
			.channels_min = 1,
			.channels_max = 2,
			.rates = WM0010_RATES,
			.formats = WM0010_FORMATS,
		},
		.capture = {
			 .stream_name = "SDI2 Capture",
			 .channels_min = 1,
			 .channels_max = 2,
			 .rates = WM0010_RATES,
			 .formats = WM0010_FORMATS,
		 },
	},
};

static irqreturn_t wm0010_irq(int irq, void *data)
{
	struct wm0010_priv *wm0010 = data;

	switch (wm0010->state) {
	case WM0010_OUT_OF_RESET:
	case WM0010_BOOTROM:
	case WM0010_STAGE2:
		spin_lock(&wm0010->irq_lock);
		complete(&wm0010->boot_completion);
		spin_unlock(&wm0010->irq_lock);
		return IRQ_HANDLED;
	default:
		return IRQ_NONE;
	}

	return IRQ_NONE;
}

static int wm0010_probe(struct snd_soc_component *component)
{
	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);

	wm0010->component = component;

	return 0;
}

static int wm0010_spi_probe(struct spi_device *spi)
{
	unsigned long gpio_flags;
	int ret;
	int trigger;
	int irq;
	struct wm0010_priv *wm0010;

	wm0010 = devm_kzalloc(&spi->dev, sizeof(*wm0010),
			      GFP_KERNEL);
	if (!wm0010)
		return -ENOMEM;

	mutex_init(&wm0010->lock);
	spin_lock_init(&wm0010->irq_lock);

	spi_set_drvdata(spi, wm0010);
	wm0010->dev = &spi->dev;

	if (dev_get_platdata(&spi->dev))
		memcpy(&wm0010->pdata, dev_get_platdata(&spi->dev),
		       sizeof(wm0010->pdata));

	init_completion(&wm0010->boot_completion);

	wm0010->core_supplies[0].supply = "AVDD";
	wm0010->core_supplies[1].supply = "DCVDD";
	ret = devm_regulator_bulk_get(wm0010->dev, ARRAY_SIZE(wm0010->core_supplies),
				      wm0010->core_supplies);
	if (ret != 0) {
		dev_err(wm0010->dev, "Failed to obtain core supplies: %d\n",
			ret);
		return ret;
	}

	wm0010->dbvdd = devm_regulator_get(wm0010->dev, "DBVDD");
	if (IS_ERR(wm0010->dbvdd)) {
		ret = PTR_ERR(wm0010->dbvdd);
		dev_err(wm0010->dev, "Failed to obtain DBVDD: %d\n", ret);
		return ret;
	}

	if (wm0010->pdata.gpio_reset) {
		wm0010->gpio_reset = wm0010->pdata.gpio_reset;

		if (wm0010->pdata.reset_active_high)
			wm0010->gpio_reset_value = 1;
		else
			wm0010->gpio_reset_value = 0;

		if (wm0010->gpio_reset_value)
			gpio_flags = GPIOF_OUT_INIT_HIGH;
		else
			gpio_flags = GPIOF_OUT_INIT_LOW;

		ret = devm_gpio_request_one(wm0010->dev, wm0010->gpio_reset,
					    gpio_flags, "wm0010 reset");
		if (ret < 0) {
			dev_err(wm0010->dev,
				"Failed to request GPIO for DSP reset: %d\n",
				ret);
			return ret;
		}
	} else {
		dev_err(wm0010->dev, "No reset GPIO configured\n");
		return -EINVAL;
	}

	wm0010->state = WM0010_POWER_OFF;

	irq = spi->irq;
	if (wm0010->pdata.irq_flags)
		trigger = wm0010->pdata.irq_flags;
	else
		trigger = IRQF_TRIGGER_FALLING;
	trigger |= IRQF_ONESHOT;

	ret = request_threaded_irq(irq, NULL, wm0010_irq, trigger,
				   "wm0010", wm0010);
	if (ret) {
		dev_err(wm0010->dev, "Failed to request IRQ %d: %d\n",
			irq, ret);
		return ret;
	}
	wm0010->irq = irq;

	ret = irq_set_irq_wake(irq, 1);
	if (ret) {
		dev_err(wm0010->dev, "Failed to set IRQ %d as wake source: %d\n",
			irq, ret);
		return ret;
	}

	if (spi->max_speed_hz)
		wm0010->board_max_spi_speed = spi->max_speed_hz;
	else
		wm0010->board_max_spi_speed = 0;

	ret = devm_snd_soc_register_component(&spi->dev,
				     &soc_component_dev_wm0010, wm0010_dai,
				     ARRAY_SIZE(wm0010_dai));
	if (ret < 0)
		return ret;

	return 0;
}

static int wm0010_spi_remove(struct spi_device *spi)
{
	struct wm0010_priv *wm0010 = spi_get_drvdata(spi);

	gpio_set_value_cansleep(wm0010->gpio_reset,
				wm0010->gpio_reset_value);

	irq_set_irq_wake(wm0010->irq, 0);

	if (wm0010->irq)
		free_irq(wm0010->irq, wm0010);

	return 0;
}

static struct spi_driver wm0010_spi_driver = {
	.driver = {
		.name	= "wm0010",
	},
	.probe		= wm0010_spi_probe,
	.remove		= wm0010_spi_remove,
};

module_spi_driver(wm0010_spi_driver);

MODULE_DESCRIPTION("ASoC WM0010 driver");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_LICENSE("GPL");
