cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mchp-spdiftx.c (22543B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// Driver for Microchip S/PDIF TX Controller
      4//
      5// Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
      6//
      7// Author: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
      8
      9#include <linux/clk.h>
     10#include <linux/io.h>
     11#include <linux/module.h>
     12#include <linux/spinlock.h>
     13
     14#include <sound/asoundef.h>
     15#include <sound/dmaengine_pcm.h>
     16#include <sound/pcm_params.h>
     17#include <sound/soc.h>
     18
     19/*
     20 * ---- S/PDIF Transmitter Controller Register map ----
     21 */
     22#define SPDIFTX_CR			0x00	/* Control Register */
     23#define SPDIFTX_MR			0x04	/* Mode Register */
     24#define SPDIFTX_CDR			0x0C	/* Common Data Register */
     25
     26#define SPDIFTX_IER			0x14	/* Interrupt Enable Register */
     27#define SPDIFTX_IDR			0x18	/* Interrupt Disable Register */
     28#define SPDIFTX_IMR			0x1C	/* Interrupt Mask Register */
     29#define SPDIFTX_ISR			0x20	/* Interrupt Status Register */
     30
     31#define SPDIFTX_CH1UD(reg)	(0x50 + (reg) * 4)	/* User Data 1 Register x */
     32#define SPDIFTX_CH1S(reg)	(0x80 + (reg) * 4)	/* Channel Status 1 Register x */
     33
     34#define SPDIFTX_VERSION			0xF0
     35
     36/*
     37 * ---- Control Register (Write-only) ----
     38 */
     39#define SPDIFTX_CR_SWRST		BIT(0)	/* Software Reset */
     40#define SPDIFTX_CR_FCLR			BIT(1)	/* FIFO clear */
     41
     42/*
     43 * ---- Mode Register (Read/Write) ----
     44 */
     45/* Transmit Enable */
     46#define SPDIFTX_MR_TXEN_MASK		GENMASK(0, 0)
     47#define SPDIFTX_MR_TXEN_DISABLE		(0 << 0)
     48#define SPDIFTX_MR_TXEN_ENABLE		(1 << 0)
     49
     50/* Multichannel Transfer */
     51#define SPDIFTX_MR_MULTICH_MASK		GENAMSK(1, 1)
     52#define SPDIFTX_MR_MULTICH_MONO		(0 << 1)
     53#define SPDIFTX_MR_MULTICH_DUAL		(1 << 1)
     54
     55/* Data Word Endian Mode */
     56#define SPDIFTX_MR_ENDIAN_MASK		GENMASK(2, 2)
     57#define SPDIFTX_MR_ENDIAN_LITTLE	(0 << 2)
     58#define SPDIFTX_MR_ENDIAN_BIG		(1 << 2)
     59
     60/* Data Justification */
     61#define SPDIFTX_MR_JUSTIFY_MASK		GENMASK(3, 3)
     62#define SPDIFTX_MR_JUSTIFY_LSB		(0 << 3)
     63#define SPDIFTX_MR_JUSTIFY_MSB		(1 << 3)
     64
     65/* Common Audio Register Transfer Mode */
     66#define SPDIFTX_MR_CMODE_MASK			GENMASK(5, 4)
     67#define SPDIFTX_MR_CMODE_INDEX_ACCESS		(0 << 4)
     68#define SPDIFTX_MR_CMODE_TOGGLE_ACCESS		(1 << 4)
     69#define SPDIFTX_MR_CMODE_INTERLVD_ACCESS	(2 << 4)
     70
     71/* Valid Bits per Sample */
     72#define SPDIFTX_MR_VBPS_MASK		GENMASK(13, 8)
     73#define SPDIFTX_MR_VBPS(bps)		(((bps) << 8) & SPDIFTX_MR_VBPS_MASK)
     74
     75/* Chunk Size */
     76#define SPDIFTX_MR_CHUNK_MASK		GENMASK(19, 16)
     77#define SPDIFTX_MR_CHUNK(size)		(((size) << 16) & SPDIFTX_MR_CHUNK_MASK)
     78
     79/* Validity Bits for Channels 1 and 2 */
     80#define SPDIFTX_MR_VALID1			BIT(24)
     81#define SPDIFTX_MR_VALID2			BIT(25)
     82
     83/* Disable Null Frame on underrun */
     84#define SPDIFTX_MR_DNFR_MASK		GENMASK(27, 27)
     85#define SPDIFTX_MR_DNFR_INVALID		(0 << 27)
     86#define SPDIFTX_MR_DNFR_VALID		(1 << 27)
     87
     88/* Bytes per Sample */
     89#define SPDIFTX_MR_BPS_MASK		GENMASK(29, 28)
     90#define SPDIFTX_MR_BPS(bytes) \
     91	((((bytes) - 1) << 28) & SPDIFTX_MR_BPS_MASK)
     92
     93/*
     94 * ---- Interrupt Enable/Disable/Mask/Status Register (Write/Read-only) ----
     95 */
     96#define SPDIFTX_IR_TXRDY		BIT(0)
     97#define SPDIFTX_IR_TXEMPTY		BIT(1)
     98#define SPDIFTX_IR_TXFULL		BIT(2)
     99#define SPDIFTX_IR_TXCHUNK		BIT(3)
    100#define SPDIFTX_IR_TXUDR		BIT(4)
    101#define SPDIFTX_IR_TXOVR		BIT(5)
    102#define SPDIFTX_IR_CSRDY		BIT(6)
    103#define SPDIFTX_IR_UDRDY		BIT(7)
    104#define SPDIFTX_IR_TXRDYCH(ch)		BIT((ch) + 8)
    105#define SPDIFTX_IR_SECE			BIT(10)
    106#define SPDIFTX_IR_TXUDRCH(ch)		BIT((ch) + 11)
    107#define SPDIFTX_IR_BEND			BIT(13)
    108
    109static bool mchp_spdiftx_readable_reg(struct device *dev, unsigned int reg)
    110{
    111	switch (reg) {
    112	case SPDIFTX_MR:
    113	case SPDIFTX_IMR:
    114	case SPDIFTX_ISR:
    115	case SPDIFTX_CH1UD(0):
    116	case SPDIFTX_CH1UD(1):
    117	case SPDIFTX_CH1UD(2):
    118	case SPDIFTX_CH1UD(3):
    119	case SPDIFTX_CH1UD(4):
    120	case SPDIFTX_CH1UD(5):
    121	case SPDIFTX_CH1S(0):
    122	case SPDIFTX_CH1S(1):
    123	case SPDIFTX_CH1S(2):
    124	case SPDIFTX_CH1S(3):
    125	case SPDIFTX_CH1S(4):
    126	case SPDIFTX_CH1S(5):
    127		return true;
    128	default:
    129		return false;
    130	}
    131}
    132
    133static bool mchp_spdiftx_writeable_reg(struct device *dev, unsigned int reg)
    134{
    135	switch (reg) {
    136	case SPDIFTX_CR:
    137	case SPDIFTX_MR:
    138	case SPDIFTX_CDR:
    139	case SPDIFTX_IER:
    140	case SPDIFTX_IDR:
    141	case SPDIFTX_CH1UD(0):
    142	case SPDIFTX_CH1UD(1):
    143	case SPDIFTX_CH1UD(2):
    144	case SPDIFTX_CH1UD(3):
    145	case SPDIFTX_CH1UD(4):
    146	case SPDIFTX_CH1UD(5):
    147	case SPDIFTX_CH1S(0):
    148	case SPDIFTX_CH1S(1):
    149	case SPDIFTX_CH1S(2):
    150	case SPDIFTX_CH1S(3):
    151	case SPDIFTX_CH1S(4):
    152	case SPDIFTX_CH1S(5):
    153		return true;
    154	default:
    155		return false;
    156	}
    157}
    158
    159static bool mchp_spdiftx_precious_reg(struct device *dev, unsigned int reg)
    160{
    161	switch (reg) {
    162	case SPDIFTX_CDR:
    163	case SPDIFTX_ISR:
    164		return true;
    165	default:
    166		return false;
    167	}
    168}
    169
    170static const struct regmap_config mchp_spdiftx_regmap_config = {
    171	.reg_bits = 32,
    172	.reg_stride = 4,
    173	.val_bits = 32,
    174	.max_register = SPDIFTX_VERSION,
    175	.readable_reg = mchp_spdiftx_readable_reg,
    176	.writeable_reg = mchp_spdiftx_writeable_reg,
    177	.precious_reg = mchp_spdiftx_precious_reg,
    178};
    179
    180#define SPDIFTX_GCLK_RATIO	128
    181
    182#define SPDIFTX_CS_BITS		192
    183#define SPDIFTX_UD_BITS		192
    184
    185struct mchp_spdiftx_mixer_control {
    186	unsigned char				ch_stat[SPDIFTX_CS_BITS / 8];
    187	unsigned char				user_data[SPDIFTX_UD_BITS / 8];
    188	spinlock_t				lock; /* exclusive access to control data */
    189};
    190
    191struct mchp_spdiftx_dev {
    192	struct mchp_spdiftx_mixer_control	control;
    193	struct snd_dmaengine_dai_dma_data	playback;
    194	struct device				*dev;
    195	struct regmap				*regmap;
    196	struct clk				*pclk;
    197	struct clk				*gclk;
    198	unsigned int				fmt;
    199	const struct mchp_i2s_caps		*caps;
    200	int					gclk_enabled:1;
    201};
    202
    203static inline int mchp_spdiftx_is_running(struct mchp_spdiftx_dev *dev)
    204{
    205	u32 mr;
    206
    207	regmap_read(dev->regmap, SPDIFTX_MR, &mr);
    208	return !!(mr & SPDIFTX_MR_TXEN_ENABLE);
    209}
    210
    211static void mchp_spdiftx_channel_status_write(struct mchp_spdiftx_dev *dev)
    212{
    213	struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
    214	u32 val;
    215	int i;
    216
    217	for (i = 0; i < ARRAY_SIZE(ctrl->ch_stat) / 4; i++) {
    218		val = (ctrl->ch_stat[(i * 4) + 0] << 0) |
    219		      (ctrl->ch_stat[(i * 4) + 1] << 8) |
    220		      (ctrl->ch_stat[(i * 4) + 2] << 16) |
    221		      (ctrl->ch_stat[(i * 4) + 3] << 24);
    222
    223		regmap_write(dev->regmap, SPDIFTX_CH1S(i), val);
    224	}
    225}
    226
    227static void mchp_spdiftx_user_data_write(struct mchp_spdiftx_dev *dev)
    228{
    229	struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
    230	u32 val;
    231	int i;
    232
    233	for (i = 0; i < ARRAY_SIZE(ctrl->user_data) / 4; i++) {
    234		val = (ctrl->user_data[(i * 4) + 0] << 0) |
    235		      (ctrl->user_data[(i * 4) + 1] << 8) |
    236		      (ctrl->user_data[(i * 4) + 2] << 16) |
    237		      (ctrl->user_data[(i * 4) + 3] << 24);
    238
    239		regmap_write(dev->regmap, SPDIFTX_CH1UD(i), val);
    240	}
    241}
    242
    243static irqreturn_t mchp_spdiftx_interrupt(int irq, void *dev_id)
    244{
    245	struct mchp_spdiftx_dev *dev = dev_id;
    246	struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
    247	u32 sr, imr, pending, idr = 0;
    248
    249	regmap_read(dev->regmap, SPDIFTX_ISR, &sr);
    250	regmap_read(dev->regmap, SPDIFTX_IMR, &imr);
    251	pending = sr & imr;
    252
    253	if (!pending)
    254		return IRQ_NONE;
    255
    256	if (pending & SPDIFTX_IR_TXUDR) {
    257		dev_warn(dev->dev, "underflow detected\n");
    258		idr |= SPDIFTX_IR_TXUDR;
    259	}
    260
    261	if (pending & SPDIFTX_IR_TXOVR) {
    262		dev_warn(dev->dev, "overflow detected\n");
    263		idr |= SPDIFTX_IR_TXOVR;
    264	}
    265
    266	if (pending & SPDIFTX_IR_UDRDY) {
    267		spin_lock(&ctrl->lock);
    268		mchp_spdiftx_user_data_write(dev);
    269		spin_unlock(&ctrl->lock);
    270		idr |= SPDIFTX_IR_UDRDY;
    271	}
    272
    273	if (pending & SPDIFTX_IR_CSRDY) {
    274		spin_lock(&ctrl->lock);
    275		mchp_spdiftx_channel_status_write(dev);
    276		spin_unlock(&ctrl->lock);
    277		idr |= SPDIFTX_IR_CSRDY;
    278	}
    279
    280	regmap_write(dev->regmap, SPDIFTX_IDR, idr);
    281
    282	return IRQ_HANDLED;
    283}
    284
    285static int mchp_spdiftx_dai_startup(struct snd_pcm_substream *substream,
    286				    struct snd_soc_dai *dai)
    287{
    288	struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
    289
    290	/* Software reset the IP */
    291	regmap_write(dev->regmap, SPDIFTX_CR,
    292		     SPDIFTX_CR_SWRST | SPDIFTX_CR_FCLR);
    293
    294	return 0;
    295}
    296
    297static void mchp_spdiftx_dai_shutdown(struct snd_pcm_substream *substream,
    298				      struct snd_soc_dai *dai)
    299{
    300	struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
    301
    302	/* Disable interrupts */
    303	regmap_write(dev->regmap, SPDIFTX_IDR, 0xffffffff);
    304}
    305
    306static int mchp_spdiftx_trigger(struct snd_pcm_substream *substream, int cmd,
    307				struct snd_soc_dai *dai)
    308{
    309	struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
    310	struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
    311	u32 mr;
    312	int running;
    313	int ret;
    314
    315	/* do not start/stop while channel status or user data is updated */
    316	spin_lock(&ctrl->lock);
    317	regmap_read(dev->regmap, SPDIFTX_MR, &mr);
    318	running = !!(mr & SPDIFTX_MR_TXEN_ENABLE);
    319
    320	switch (cmd) {
    321	case SNDRV_PCM_TRIGGER_START:
    322	case SNDRV_PCM_TRIGGER_RESUME:
    323	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
    324		if (!running) {
    325			mr &= ~SPDIFTX_MR_TXEN_MASK;
    326			mr |= SPDIFTX_MR_TXEN_ENABLE;
    327		}
    328		break;
    329	case SNDRV_PCM_TRIGGER_STOP:
    330	case SNDRV_PCM_TRIGGER_SUSPEND:
    331	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
    332		if (running) {
    333			mr &= ~SPDIFTX_MR_TXEN_MASK;
    334			mr |= SPDIFTX_MR_TXEN_DISABLE;
    335		}
    336		break;
    337	default:
    338		spin_unlock(&ctrl->lock);
    339		return -EINVAL;
    340	}
    341
    342	ret = regmap_write(dev->regmap, SPDIFTX_MR, mr);
    343	spin_unlock(&ctrl->lock);
    344	if (ret) {
    345		dev_err(dev->dev, "unable to disable TX: %d\n", ret);
    346		return ret;
    347	}
    348
    349	return 0;
    350}
    351
    352static int mchp_spdiftx_hw_params(struct snd_pcm_substream *substream,
    353				  struct snd_pcm_hw_params *params,
    354				  struct snd_soc_dai *dai)
    355{
    356	unsigned long flags;
    357	struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
    358	struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
    359	u32 mr;
    360	unsigned int bps = params_physical_width(params) / 8;
    361	int ret;
    362
    363	dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u\n",
    364		__func__, params_rate(params), params_format(params),
    365		params_width(params), params_channels(params));
    366
    367	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
    368		dev_err(dev->dev, "Capture is not supported\n");
    369		return -EINVAL;
    370	}
    371
    372	regmap_read(dev->regmap, SPDIFTX_MR, &mr);
    373
    374	if (mr & SPDIFTX_MR_TXEN_ENABLE) {
    375		dev_err(dev->dev, "PCM already running\n");
    376		return -EBUSY;
    377	}
    378
    379	/* Defaults: Toggle mode, justify to LSB, chunksize 1 */
    380	mr = SPDIFTX_MR_CMODE_TOGGLE_ACCESS | SPDIFTX_MR_JUSTIFY_LSB;
    381	dev->playback.maxburst = 1;
    382	switch (params_channels(params)) {
    383	case 1:
    384		mr |= SPDIFTX_MR_MULTICH_MONO;
    385		break;
    386	case 2:
    387		mr |= SPDIFTX_MR_MULTICH_DUAL;
    388		if (bps > 2)
    389			dev->playback.maxburst = 2;
    390		break;
    391	default:
    392		dev_err(dev->dev, "unsupported number of channels: %d\n",
    393			params_channels(params));
    394		return -EINVAL;
    395	}
    396	mr |= SPDIFTX_MR_CHUNK(dev->playback.maxburst);
    397
    398	switch (params_format(params)) {
    399	case SNDRV_PCM_FORMAT_S8:
    400		mr |= SPDIFTX_MR_VBPS(8);
    401		break;
    402	case SNDRV_PCM_FORMAT_S16_BE:
    403		mr |= SPDIFTX_MR_ENDIAN_BIG;
    404		fallthrough;
    405	case SNDRV_PCM_FORMAT_S16_LE:
    406		mr |= SPDIFTX_MR_VBPS(16);
    407		break;
    408	case SNDRV_PCM_FORMAT_S18_3BE:
    409		mr |= SPDIFTX_MR_ENDIAN_BIG;
    410		fallthrough;
    411	case SNDRV_PCM_FORMAT_S18_3LE:
    412		mr |= SPDIFTX_MR_VBPS(18);
    413		break;
    414	case SNDRV_PCM_FORMAT_S20_3BE:
    415		mr |= SPDIFTX_MR_ENDIAN_BIG;
    416		fallthrough;
    417	case SNDRV_PCM_FORMAT_S20_3LE:
    418		mr |= SPDIFTX_MR_VBPS(20);
    419		break;
    420	case SNDRV_PCM_FORMAT_S24_3BE:
    421		mr |= SPDIFTX_MR_ENDIAN_BIG;
    422		fallthrough;
    423	case SNDRV_PCM_FORMAT_S24_3LE:
    424		mr |= SPDIFTX_MR_VBPS(24);
    425		break;
    426	case SNDRV_PCM_FORMAT_S24_BE:
    427		mr |= SPDIFTX_MR_ENDIAN_BIG;
    428		fallthrough;
    429	case SNDRV_PCM_FORMAT_S24_LE:
    430		mr |= SPDIFTX_MR_VBPS(24);
    431		break;
    432	case SNDRV_PCM_FORMAT_S32_BE:
    433		mr |= SPDIFTX_MR_ENDIAN_BIG;
    434		fallthrough;
    435	case SNDRV_PCM_FORMAT_S32_LE:
    436		mr |= SPDIFTX_MR_VBPS(32);
    437		break;
    438	default:
    439		dev_err(dev->dev, "unsupported PCM format: %d\n",
    440			params_format(params));
    441		return -EINVAL;
    442	}
    443
    444	mr |= SPDIFTX_MR_BPS(bps);
    445
    446	spin_lock_irqsave(&ctrl->lock, flags);
    447	ctrl->ch_stat[3] &= ~IEC958_AES3_CON_FS;
    448	switch (params_rate(params)) {
    449	case 22050:
    450		ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_22050;
    451		break;
    452	case 24000:
    453		ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_24000;
    454		break;
    455	case 32000:
    456		ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_32000;
    457		break;
    458	case 44100:
    459		ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_44100;
    460		break;
    461	case 48000:
    462		ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_48000;
    463		break;
    464	case 88200:
    465		ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_88200;
    466		break;
    467	case 96000:
    468		ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_96000;
    469		break;
    470	case 176400:
    471		ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_176400;
    472		break;
    473	case 192000:
    474		ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_192000;
    475		break;
    476	case 8000:
    477	case 11025:
    478	case 16000:
    479	case 64000:
    480		ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_NOTID;
    481		break;
    482	default:
    483		dev_err(dev->dev, "unsupported sample frequency: %u\n",
    484			params_rate(params));
    485		spin_unlock_irqrestore(&ctrl->lock, flags);
    486		return -EINVAL;
    487	}
    488	mchp_spdiftx_channel_status_write(dev);
    489	spin_unlock_irqrestore(&ctrl->lock, flags);
    490
    491	if (dev->gclk_enabled) {
    492		clk_disable_unprepare(dev->gclk);
    493		dev->gclk_enabled = 0;
    494	}
    495	ret = clk_set_rate(dev->gclk, params_rate(params) *
    496				      SPDIFTX_GCLK_RATIO);
    497	if (ret) {
    498		dev_err(dev->dev,
    499			"unable to change gclk rate to: rate %u * ratio %u\n",
    500			params_rate(params), SPDIFTX_GCLK_RATIO);
    501		return ret;
    502	}
    503	ret = clk_prepare_enable(dev->gclk);
    504	if (ret) {
    505		dev_err(dev->dev, "unable to enable gclk: %d\n", ret);
    506		return ret;
    507	}
    508	dev->gclk_enabled = 1;
    509	dev_dbg(dev->dev, "%s(): GCLK set to %d\n", __func__,
    510		params_rate(params) * SPDIFTX_GCLK_RATIO);
    511
    512	/* Enable interrupts */
    513	regmap_write(dev->regmap, SPDIFTX_IER,
    514		     SPDIFTX_IR_TXUDR | SPDIFTX_IR_TXOVR);
    515
    516	regmap_write(dev->regmap, SPDIFTX_MR, mr);
    517
    518	return 0;
    519}
    520
    521static int mchp_spdiftx_hw_free(struct snd_pcm_substream *substream,
    522				struct snd_soc_dai *dai)
    523{
    524	struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
    525
    526	regmap_write(dev->regmap, SPDIFTX_IDR,
    527		     SPDIFTX_IR_TXUDR | SPDIFTX_IR_TXOVR);
    528	if (dev->gclk_enabled) {
    529		clk_disable_unprepare(dev->gclk);
    530		dev->gclk_enabled = 0;
    531	}
    532
    533	return regmap_write(dev->regmap, SPDIFTX_CR,
    534			    SPDIFTX_CR_SWRST | SPDIFTX_CR_FCLR);
    535}
    536
    537static const struct snd_soc_dai_ops mchp_spdiftx_dai_ops = {
    538	.startup	= mchp_spdiftx_dai_startup,
    539	.shutdown	= mchp_spdiftx_dai_shutdown,
    540	.trigger	= mchp_spdiftx_trigger,
    541	.hw_params	= mchp_spdiftx_hw_params,
    542	.hw_free	= mchp_spdiftx_hw_free,
    543};
    544
    545#define MCHP_SPDIFTX_RATES	SNDRV_PCM_RATE_8000_192000
    546
    547#define MCHP_SPDIFTX_FORMATS	(SNDRV_PCM_FMTBIT_S8 |		\
    548				 SNDRV_PCM_FMTBIT_S16_LE |	\
    549				 SNDRV_PCM_FMTBIT_U16_BE |	\
    550				 SNDRV_PCM_FMTBIT_S18_3LE |	\
    551				 SNDRV_PCM_FMTBIT_S18_3BE |	\
    552				 SNDRV_PCM_FMTBIT_S20_3LE |	\
    553				 SNDRV_PCM_FMTBIT_S20_3BE |	\
    554				 SNDRV_PCM_FMTBIT_S24_3LE |	\
    555				 SNDRV_PCM_FMTBIT_S24_3BE |	\
    556				 SNDRV_PCM_FMTBIT_S24_LE |	\
    557				 SNDRV_PCM_FMTBIT_S24_BE |	\
    558				 SNDRV_PCM_FMTBIT_S32_LE |	\
    559				 SNDRV_PCM_FMTBIT_S32_BE	\
    560				 )
    561
    562static int mchp_spdiftx_info(struct snd_kcontrol *kcontrol,
    563			     struct snd_ctl_elem_info *uinfo)
    564{
    565	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
    566	uinfo->count = 1;
    567
    568	return 0;
    569}
    570
    571static int mchp_spdiftx_cs_get(struct snd_kcontrol *kcontrol,
    572			       struct snd_ctl_elem_value *uvalue)
    573{
    574	unsigned long flags;
    575	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
    576	struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
    577	struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
    578
    579	spin_lock_irqsave(&ctrl->lock, flags);
    580	memcpy(uvalue->value.iec958.status, ctrl->ch_stat,
    581	       sizeof(ctrl->ch_stat));
    582	spin_unlock_irqrestore(&ctrl->lock, flags);
    583
    584	return 0;
    585}
    586
    587static int mchp_spdiftx_cs_put(struct snd_kcontrol *kcontrol,
    588			       struct snd_ctl_elem_value *uvalue)
    589{
    590	unsigned long flags;
    591	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
    592	struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
    593	struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
    594	int changed = 0;
    595	int i;
    596
    597	spin_lock_irqsave(&ctrl->lock, flags);
    598	for (i = 0; i < ARRAY_SIZE(ctrl->ch_stat); i++) {
    599		if (ctrl->ch_stat[i] != uvalue->value.iec958.status[i])
    600			changed = 1;
    601		ctrl->ch_stat[i] = uvalue->value.iec958.status[i];
    602	}
    603
    604	if (changed) {
    605		/* don't enable IP while we copy the channel status */
    606		if (mchp_spdiftx_is_running(dev)) {
    607			/*
    608			 * if SPDIF is running, wait for interrupt to write
    609			 * channel status
    610			 */
    611			regmap_write(dev->regmap, SPDIFTX_IER,
    612				     SPDIFTX_IR_CSRDY);
    613		} else {
    614			mchp_spdiftx_channel_status_write(dev);
    615		}
    616	}
    617	spin_unlock_irqrestore(&ctrl->lock, flags);
    618
    619	return changed;
    620}
    621
    622static int mchp_spdiftx_cs_mask(struct snd_kcontrol *kcontrol,
    623				struct snd_ctl_elem_value *uvalue)
    624{
    625	memset(uvalue->value.iec958.status, 0xff,
    626	       sizeof(uvalue->value.iec958.status));
    627
    628	return 0;
    629}
    630
    631static int mchp_spdiftx_subcode_get(struct snd_kcontrol *kcontrol,
    632				    struct snd_ctl_elem_value *uvalue)
    633{
    634	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
    635	struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
    636	struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
    637	unsigned long flags;
    638
    639	spin_lock_irqsave(&ctrl->lock, flags);
    640	memcpy(uvalue->value.iec958.subcode, ctrl->user_data,
    641	       sizeof(ctrl->user_data));
    642	spin_unlock_irqrestore(&ctrl->lock, flags);
    643
    644	return 0;
    645}
    646
    647static int mchp_spdiftx_subcode_put(struct snd_kcontrol *kcontrol,
    648				    struct snd_ctl_elem_value *uvalue)
    649{
    650	unsigned long flags;
    651	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
    652	struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
    653	struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
    654	int changed = 0;
    655	int i;
    656
    657	spin_lock_irqsave(&ctrl->lock, flags);
    658	for (i = 0; i < ARRAY_SIZE(ctrl->user_data); i++) {
    659		if (ctrl->user_data[i] != uvalue->value.iec958.subcode[i])
    660			changed = 1;
    661
    662		ctrl->user_data[i] = uvalue->value.iec958.subcode[i];
    663	}
    664	if (changed) {
    665		if (mchp_spdiftx_is_running(dev)) {
    666			/*
    667			 * if SPDIF is running, wait for interrupt to write
    668			 * user data
    669			 */
    670			regmap_write(dev->regmap, SPDIFTX_IER,
    671				     SPDIFTX_IR_UDRDY);
    672		} else {
    673			mchp_spdiftx_user_data_write(dev);
    674		}
    675	}
    676	spin_unlock_irqrestore(&ctrl->lock, flags);
    677
    678	return changed;
    679}
    680
    681static struct snd_kcontrol_new mchp_spdiftx_ctrls[] = {
    682	/* Channel status controller */
    683	{
    684		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
    685		.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
    686		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
    687			SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    688		.info = mchp_spdiftx_info,
    689		.get = mchp_spdiftx_cs_get,
    690		.put = mchp_spdiftx_cs_put,
    691	},
    692	{
    693		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
    694		.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
    695		.access = SNDRV_CTL_ELEM_ACCESS_READ,
    696			SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    697		.info = mchp_spdiftx_info,
    698		.get = mchp_spdiftx_cs_mask,
    699	},
    700	/* User bits controller */
    701	{
    702		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
    703		.name = "IEC958 Subcode Playback Default",
    704		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
    705		.info = mchp_spdiftx_info,
    706		.get = mchp_spdiftx_subcode_get,
    707		.put = mchp_spdiftx_subcode_put,
    708	},
    709};
    710
    711static int mchp_spdiftx_dai_probe(struct snd_soc_dai *dai)
    712{
    713	struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
    714	int ret;
    715
    716	snd_soc_dai_init_dma_data(dai, &dev->playback, NULL);
    717
    718	ret = clk_prepare_enable(dev->pclk);
    719	if (ret) {
    720		dev_err(dev->dev,
    721			"failed to enable the peripheral clock: %d\n", ret);
    722		return ret;
    723	}
    724
    725	/* Add controls */
    726	snd_soc_add_dai_controls(dai, mchp_spdiftx_ctrls,
    727				 ARRAY_SIZE(mchp_spdiftx_ctrls));
    728
    729	return 0;
    730}
    731
    732static int mchp_spdiftx_dai_remove(struct snd_soc_dai *dai)
    733{
    734	struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
    735
    736	clk_disable_unprepare(dev->pclk);
    737
    738	return 0;
    739}
    740
    741static struct snd_soc_dai_driver mchp_spdiftx_dai = {
    742	.name = "mchp-spdiftx",
    743	.probe	= mchp_spdiftx_dai_probe,
    744	.remove	= mchp_spdiftx_dai_remove,
    745	.playback = {
    746		.stream_name = "S/PDIF Playback",
    747		.channels_min = 1,
    748		.channels_max = 2,
    749		.rates = MCHP_SPDIFTX_RATES,
    750		.formats = MCHP_SPDIFTX_FORMATS,
    751	},
    752	.ops = &mchp_spdiftx_dai_ops,
    753};
    754
    755static const struct snd_soc_component_driver mchp_spdiftx_component = {
    756	.name		= "mchp-spdiftx",
    757};
    758
    759static const struct of_device_id mchp_spdiftx_dt_ids[] = {
    760	{
    761		.compatible = "microchip,sama7g5-spdiftx",
    762	},
    763	{ /* sentinel */ }
    764};
    765
    766MODULE_DEVICE_TABLE(of, mchp_spdiftx_dt_ids);
    767static int mchp_spdiftx_probe(struct platform_device *pdev)
    768{
    769	struct device_node *np = pdev->dev.of_node;
    770	const struct of_device_id *match;
    771	struct mchp_spdiftx_dev *dev;
    772	struct resource *mem;
    773	struct regmap *regmap;
    774	void __iomem *base;
    775	struct mchp_spdiftx_mixer_control *ctrl;
    776	int irq;
    777	int err;
    778
    779	/* Get memory for driver data. */
    780	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
    781	if (!dev)
    782		return -ENOMEM;
    783
    784	/* Get hardware capabilities. */
    785	match = of_match_node(mchp_spdiftx_dt_ids, np);
    786	if (match)
    787		dev->caps = match->data;
    788
    789	/* Map I/O registers. */
    790	base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
    791	if (IS_ERR(base))
    792		return PTR_ERR(base);
    793
    794	regmap = devm_regmap_init_mmio(&pdev->dev, base,
    795				       &mchp_spdiftx_regmap_config);
    796	if (IS_ERR(regmap))
    797		return PTR_ERR(regmap);
    798
    799	/* Request IRQ */
    800	irq = platform_get_irq(pdev, 0);
    801	if (irq < 0)
    802		return irq;
    803
    804	err = devm_request_irq(&pdev->dev, irq, mchp_spdiftx_interrupt, 0,
    805			       dev_name(&pdev->dev), dev);
    806	if (err)
    807		return err;
    808
    809	/* Get the peripheral clock */
    810	dev->pclk = devm_clk_get(&pdev->dev, "pclk");
    811	if (IS_ERR(dev->pclk)) {
    812		err = PTR_ERR(dev->pclk);
    813		dev_err(&pdev->dev,
    814			"failed to get the peripheral clock: %d\n", err);
    815		return err;
    816	}
    817
    818	/* Get the generic clock */
    819	dev->gclk = devm_clk_get(&pdev->dev, "gclk");
    820	if (IS_ERR(dev->gclk)) {
    821		err = PTR_ERR(dev->gclk);
    822		dev_err(&pdev->dev,
    823			"failed to get the PMC generic clock: %d\n", err);
    824		return err;
    825	}
    826
    827	ctrl = &dev->control;
    828	spin_lock_init(&ctrl->lock);
    829
    830	/* Init channel status */
    831	ctrl->ch_stat[0] = IEC958_AES0_CON_NOT_COPYRIGHT |
    832			   IEC958_AES0_CON_EMPHASIS_NONE;
    833
    834	dev->dev = &pdev->dev;
    835	dev->regmap = regmap;
    836	platform_set_drvdata(pdev, dev);
    837
    838	dev->playback.addr = (dma_addr_t)mem->start + SPDIFTX_CDR;
    839	dev->playback.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
    840
    841	err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
    842	if (err) {
    843		dev_err(&pdev->dev, "failed to register PMC: %d\n", err);
    844		return err;
    845	}
    846
    847	err = devm_snd_soc_register_component(&pdev->dev,
    848					      &mchp_spdiftx_component,
    849					      &mchp_spdiftx_dai, 1);
    850	if (err) {
    851		dev_err(&pdev->dev, "failed to register component: %d\n", err);
    852		return err;
    853	}
    854
    855	return 0;
    856}
    857
    858static struct platform_driver mchp_spdiftx_driver = {
    859	.probe	= mchp_spdiftx_probe,
    860	.driver	= {
    861		.name	= "mchp_spdiftx",
    862		.of_match_table = of_match_ptr(mchp_spdiftx_dt_ids),
    863	},
    864};
    865
    866module_platform_driver(mchp_spdiftx_driver);
    867
    868MODULE_AUTHOR("Codrin Ciubotariu <codrin.ciubotariu@microchip.com>");
    869MODULE_DESCRIPTION("Microchip S/PDIF TX Controller Driver");
    870MODULE_LICENSE("GPL v2");