aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/samsung/i2s.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 13:20:50 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 13:20:50 -0800
commitbae41e45b7400496b9bf0c70c6004419d9987819 (patch)
treecf22a65d119da1c414dbc79518857800fbe7a24b /sound/soc/samsung/i2s.c
parentMerge tag 'devicetree-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/glikely/linux (diff)
parentALSA: pcxhr: NULL dereference on probe failure (diff)
downloadlinux-dev-bae41e45b7400496b9bf0c70c6004419d9987819.tar.xz
linux-dev-bae41e45b7400496b9bf0c70c6004419d9987819.zip
Merge tag 'sound-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "This became a fairly large pull request. In addition to the usual driver updates / fixes, there have been a high amount of cleanups in ASoC area, as well as control API helpers and kernel documentations fixes touching through the whole tree. In the driver side, the biggest changes are the support for new Intel SoC found on new x86 machines, and the updates of FireWire dice and oxfw drivers. Some remarkable items are below: ALSA core: - PCM mmap code cleanup, removal of arch-dependent codes - PCM xrun injection support - PCM hwptr tracepoint support - Refactoring of snd_pcm_action(), simplification of PCM locking - Robustified sequecner auto-load functionality - New control API helpers and lots of cleanups along with them - Lots of kerneldoc fixes and cleanups USB-audio: - The mixer resume code was largely rewritten, and the devices with quirks are resumed properly. - New hardware support: Focusrite Scarlett, Digidesign Mbox1, Denon/Marantz DACs, Zoom R16/24 FireWire: - DICE driver updates with better duplex and sync support, including MIDI support - New OXFW driver for Oxford Semiconductor FW970/971 chipset, including the previous LaCie Speakers device. Fullduplex and MIDI support included as well as DICE driver. HD-audio: - Refactoring the driver-caps quirk handling in snd-hda-intel - More consistent control names representing the topology better - Fixups: HP mute LED with ALC268 codec, Ideapad S210 built-in mic fix, ASUS Z99He laptop EAPD ASoC: - Conversion of AC'97 drivers to use regmap, bringing us closer to the removal of the ASoC level I/O code - Clean up a lot of old drivers that were open coding things that have subsequently been implemented in the core - Some DAPM performance improvements - Removal of the now seldom used CODEC mutex - Lots of updates for the newer Intel SoC support, including support for the DSP and some Cherrytrail and Braswell machine drivers - Support for Samsung boards using rt5631 as the CODEC - Removal of the obsolete AFEB9260 machine driver - Driver support for the TI TS3A227E headset driver used in some Chrombeooks Others: - ASIHPI driver update and cleanups - Lots of dev_*() printk conversions - Lots of trivial cleanups for the codes spotted by Coccinelle" * tag 'sound-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (594 commits) ALSA: pcxhr: NULL dereference on probe failure ALSA: lola: NULL dereference on probe failure ALSA: hda - Add "eapd" model string for AD1986A codec ALSA: hda - Add EAPD fixup for ASUS Z99He laptop ALSA: oxfw: Add hwdep interface ALSA: oxfw: Add support for capture/playback MIDI messages ALSA: oxfw: add support for capturing PCM samples ALSA: oxfw: Add support AMDTP in-stream ALSA: oxfw: Add support for Behringer/Mackie devices ALSA: oxfw: Change the way to start stream ALSA: oxfw: Add proc interface for debugging purpose ALSA: oxfw: Change the way to make PCM rules/constraints ALSA: oxfw: Add support for AV/C stream format command to get/set supported stream formation ALSA: oxfw: Change the way to name card ALSA: dice: Add support for MIDI capture/playback ALSA: dice: Add support for capturing PCM samples ALSA: dice: Support for non SYT-Match sampling clock source mode ALSA: dice: Add support for duplex streams with synchronization ALSA: dice: Change the way to start stream ALSA: jack: Add dummy snd_jack_set_key() definition ...
Diffstat (limited to 'sound/soc/samsung/i2s.c')
-rw-r--r--sound/soc/samsung/i2s.c244
1 files changed, 174 insertions, 70 deletions
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 9d513473b300..c7aafcd95de3 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -36,9 +36,24 @@ enum samsung_dai_type {
TYPE_SEC,
};
+struct samsung_i2s_variant_regs {
+ unsigned int bfs_off;
+ unsigned int rfs_off;
+ unsigned int sdf_off;
+ unsigned int txr_off;
+ unsigned int rclksrc_off;
+ unsigned int mss_off;
+ unsigned int cdclkcon_off;
+ unsigned int lrp_off;
+ unsigned int bfs_mask;
+ unsigned int rfs_mask;
+ unsigned int ftx0cnt_off;
+};
+
struct samsung_i2s_dai_data {
int dai_type;
u32 quirks;
+ const struct samsung_i2s_variant_regs *i2s_variant_regs;
};
struct i2s_dai {
@@ -81,6 +96,7 @@ struct i2s_dai {
u32 suspend_i2scon;
u32 suspend_i2spsr;
unsigned long gpios[7]; /* i2s gpio line numbers */
+ const struct samsung_i2s_variant_regs *variant_regs;
};
/* Lock for cross i/f checks */
@@ -95,7 +111,8 @@ static inline bool is_secondary(struct i2s_dai *i2s)
/* If operating in SoC-Slave mode */
static inline bool is_slave(struct i2s_dai *i2s)
{
- return (readl(i2s->addr + I2SMOD) & MOD_SLAVE) ? true : false;
+ u32 mod = readl(i2s->addr + I2SMOD);
+ return (mod & (1 << i2s->variant_regs->mss_off)) ? true : false;
}
/* If this interface of the controller is transmitting data */
@@ -200,14 +217,14 @@ static inline bool is_manager(struct i2s_dai *i2s)
static inline unsigned get_rfs(struct i2s_dai *i2s)
{
u32 rfs;
-
- if (i2s->quirks & QUIRK_SUPPORTS_TDM)
- rfs = readl(i2s->addr + I2SMOD) >> EXYNOS5420_MOD_RCLK_SHIFT;
- else
- rfs = (readl(i2s->addr + I2SMOD) >> MOD_RCLK_SHIFT);
- rfs &= MOD_RCLK_MASK;
+ rfs = readl(i2s->addr + I2SMOD) >> i2s->variant_regs->rfs_off;
+ rfs &= i2s->variant_regs->rfs_mask;
switch (rfs) {
+ case 7: return 192;
+ case 6: return 96;
+ case 5: return 128;
+ case 4: return 64;
case 3: return 768;
case 2: return 384;
case 1: return 512;
@@ -219,15 +236,23 @@ static inline unsigned get_rfs(struct i2s_dai *i2s)
static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
{
u32 mod = readl(i2s->addr + I2SMOD);
- int rfs_shift;
+ int rfs_shift = i2s->variant_regs->rfs_off;
- if (i2s->quirks & QUIRK_SUPPORTS_TDM)
- rfs_shift = EXYNOS5420_MOD_RCLK_SHIFT;
- else
- rfs_shift = MOD_RCLK_SHIFT;
- mod &= ~(MOD_RCLK_MASK << rfs_shift);
+ mod &= ~(i2s->variant_regs->rfs_mask << rfs_shift);
switch (rfs) {
+ case 192:
+ mod |= (EXYNOS7_MOD_RCLK_192FS << rfs_shift);
+ break;
+ case 96:
+ mod |= (EXYNOS7_MOD_RCLK_96FS << rfs_shift);
+ break;
+ case 128:
+ mod |= (EXYNOS7_MOD_RCLK_128FS << rfs_shift);
+ break;
+ case 64:
+ mod |= (EXYNOS7_MOD_RCLK_64FS << rfs_shift);
+ break;
case 768:
mod |= (MOD_RCLK_768FS << rfs_shift);
break;
@@ -249,14 +274,8 @@ static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
static inline unsigned get_bfs(struct i2s_dai *i2s)
{
u32 bfs;
-
- if (i2s->quirks & QUIRK_SUPPORTS_TDM) {
- bfs = readl(i2s->addr + I2SMOD) >> EXYNOS5420_MOD_BCLK_SHIFT;
- bfs &= EXYNOS5420_MOD_BCLK_MASK;
- } else {
- bfs = readl(i2s->addr + I2SMOD) >> MOD_BCLK_SHIFT;
- bfs &= MOD_BCLK_MASK;
- }
+ bfs = readl(i2s->addr + I2SMOD) >> i2s->variant_regs->bfs_off;
+ bfs &= i2s->variant_regs->bfs_mask;
switch (bfs) {
case 8: return 256;
@@ -275,16 +294,8 @@ static inline unsigned get_bfs(struct i2s_dai *i2s)
static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
{
u32 mod = readl(i2s->addr + I2SMOD);
- int bfs_shift;
int tdm = i2s->quirks & QUIRK_SUPPORTS_TDM;
-
- if (i2s->quirks & QUIRK_SUPPORTS_TDM) {
- bfs_shift = EXYNOS5420_MOD_BCLK_SHIFT;
- mod &= ~(EXYNOS5420_MOD_BCLK_MASK << bfs_shift);
- } else {
- bfs_shift = MOD_BCLK_SHIFT;
- mod &= ~(MOD_BCLK_MASK << bfs_shift);
- }
+ int bfs_shift = i2s->variant_regs->bfs_off;
/* Non-TDM I2S controllers do not support BCLK > 48 * FS */
if (!tdm && bfs > 48) {
@@ -292,6 +303,8 @@ static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
return;
}
+ mod &= ~(i2s->variant_regs->bfs_mask << bfs_shift);
+
switch (bfs) {
case 48:
mod |= (MOD_BCLK_48FS << bfs_shift);
@@ -346,8 +359,9 @@ static inline int get_blc(struct i2s_dai *i2s)
static void i2s_txctrl(struct i2s_dai *i2s, int on)
{
void __iomem *addr = i2s->addr;
+ int txr_off = i2s->variant_regs->txr_off;
u32 con = readl(addr + I2SCON);
- u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
+ u32 mod = readl(addr + I2SMOD) & ~(3 << txr_off);
if (on) {
con |= CON_ACTIVE;
@@ -362,9 +376,9 @@ static void i2s_txctrl(struct i2s_dai *i2s, int on)
}
if (any_rx_active(i2s))
- mod |= MOD_TXRX;
+ mod |= 2 << txr_off;
else
- mod |= MOD_TXONLY;
+ mod |= 0 << txr_off;
} else {
if (is_secondary(i2s)) {
con |= CON_TXSDMA_PAUSE;
@@ -382,7 +396,7 @@ static void i2s_txctrl(struct i2s_dai *i2s, int on)
con |= CON_TXCH_PAUSE;
if (any_rx_active(i2s))
- mod |= MOD_RXONLY;
+ mod |= 1 << txr_off;
else
con &= ~CON_ACTIVE;
}
@@ -395,23 +409,24 @@ static void i2s_txctrl(struct i2s_dai *i2s, int on)
static void i2s_rxctrl(struct i2s_dai *i2s, int on)
{
void __iomem *addr = i2s->addr;
+ int txr_off = i2s->variant_regs->txr_off;
u32 con = readl(addr + I2SCON);
- u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
+ u32 mod = readl(addr + I2SMOD) & ~(3 << txr_off);
if (on) {
con |= CON_RXDMA_ACTIVE | CON_ACTIVE;
con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE);
if (any_tx_active(i2s))
- mod |= MOD_TXRX;
+ mod |= 2 << txr_off;
else
- mod |= MOD_RXONLY;
+ mod |= 1 << txr_off;
} else {
con |= CON_RXDMA_PAUSE | CON_RXCH_PAUSE;
con &= ~CON_RXDMA_ACTIVE;
if (any_tx_active(i2s))
- mod |= MOD_TXONLY;
+ mod |= 0 << txr_off;
else
con &= ~CON_ACTIVE;
}
@@ -451,6 +466,9 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
struct i2s_dai *i2s = to_info(dai);
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
u32 mod = readl(i2s->addr + I2SMOD);
+ const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs;
+ unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off;
+ unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off;
switch (clk_id) {
case SAMSUNG_I2S_OPCLK:
@@ -465,18 +483,18 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
if ((rfs && other && other->rfs && (other->rfs != rfs)) ||
(any_active(i2s) &&
(((dir == SND_SOC_CLOCK_IN)
- && !(mod & MOD_CDCLKCON)) ||
+ && !(mod & cdcon_mask)) ||
((dir == SND_SOC_CLOCK_OUT)
- && (mod & MOD_CDCLKCON))))) {
+ && (mod & cdcon_mask))))) {
dev_err(&i2s->pdev->dev,
"%s:%d Other DAI busy\n", __func__, __LINE__);
return -EAGAIN;
}
if (dir == SND_SOC_CLOCK_IN)
- mod |= MOD_CDCLKCON;
+ mod |= 1 << i2s_regs->cdclkcon_off;
else
- mod &= ~MOD_CDCLKCON;
+ mod &= ~(1 << i2s_regs->cdclkcon_off);
i2s->rfs = rfs;
break;
@@ -491,8 +509,8 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
if (!any_active(i2s)) {
if (i2s->op_clk && !IS_ERR(i2s->op_clk)) {
- if ((clk_id && !(mod & MOD_IMS_SYSMUX)) ||
- (!clk_id && (mod & MOD_IMS_SYSMUX))) {
+ if ((clk_id && !(mod & rsrc_mask)) ||
+ (!clk_id && (mod & rsrc_mask))) {
clk_disable_unprepare(i2s->op_clk);
clk_put(i2s->op_clk);
} else {
@@ -520,8 +538,8 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
other->op_clk = i2s->op_clk;
other->rclk_srcrate = i2s->rclk_srcrate;
}
- } else if ((!clk_id && (mod & MOD_IMS_SYSMUX))
- || (clk_id && !(mod & MOD_IMS_SYSMUX))) {
+ } else if ((!clk_id && (mod & rsrc_mask))
+ || (clk_id && !(mod & rsrc_mask))) {
dev_err(&i2s->pdev->dev,
"%s:%d Other DAI busy\n", __func__, __LINE__);
return -EAGAIN;
@@ -533,11 +551,11 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
}
if (clk_id == 0)
- mod &= ~MOD_IMS_SYSMUX;
+ mod &= ~(1 << i2s_regs->rclksrc_off);
else
- mod |= MOD_IMS_SYSMUX;
- break;
+ mod |= 1 << i2s_regs->rclksrc_off;
+ break;
default:
dev_err(&i2s->pdev->dev, "We don't serve that!\n");
return -EINVAL;
@@ -553,16 +571,12 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
{
struct i2s_dai *i2s = to_info(dai);
u32 mod = readl(i2s->addr + I2SMOD);
- int lrp_shift, sdf_shift, sdf_mask, lrp_rlow;
+ int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave;
u32 tmp = 0;
- if (i2s->quirks & QUIRK_SUPPORTS_TDM) {
- lrp_shift = EXYNOS5420_MOD_LRP_SHIFT;
- sdf_shift = EXYNOS5420_MOD_SDF_SHIFT;
- } else {
- lrp_shift = MOD_LRP_SHIFT;
- sdf_shift = MOD_SDF_SHIFT;
- }
+ lrp_shift = i2s->variant_regs->lrp_off;
+ sdf_shift = i2s->variant_regs->sdf_off;
+ mod_slave = 1 << i2s->variant_regs->mss_off;
sdf_mask = MOD_SDF_MASK << sdf_shift;
lrp_rlow = MOD_LR_RLOW << lrp_shift;
@@ -605,7 +619,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
- tmp |= MOD_SLAVE;
+ tmp |= mod_slave;
break;
case SND_SOC_DAIFMT_CBS_CFS:
/* Set default source clock in Master mode */
@@ -623,13 +637,13 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
* channel.
*/
if (any_active(i2s) &&
- ((mod & (sdf_mask | lrp_rlow | MOD_SLAVE)) != tmp)) {
+ ((mod & (sdf_mask | lrp_rlow | mod_slave)) != tmp)) {
dev_err(&i2s->pdev->dev,
"%s:%d Other DAI busy\n", __func__, __LINE__);
return -EAGAIN;
}
- mod &= ~(sdf_mask | lrp_rlow | MOD_SLAVE);
+ mod &= ~(sdf_mask | lrp_rlow | mod_slave);
mod |= tmp;
writel(mod, i2s->addr + I2SMOD);
@@ -751,6 +765,7 @@ static void i2s_shutdown(struct snd_pcm_substream *substream,
struct i2s_dai *i2s = to_info(dai);
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
unsigned long flags;
+ const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs;
spin_lock_irqsave(&lock, flags);
@@ -761,7 +776,7 @@ static void i2s_shutdown(struct snd_pcm_substream *substream,
other->mode |= DAI_MANAGER;
} else {
u32 mod = readl(i2s->addr + I2SMOD);
- i2s->cdclk_out = !(mod & MOD_CDCLKCON);
+ i2s->cdclk_out = !(mod & (1 << i2s_regs->cdclkcon_off));
if (other)
other->cdclk_out = i2s->cdclk_out;
}
@@ -914,13 +929,14 @@ i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
struct i2s_dai *i2s = to_info(dai);
u32 reg = readl(i2s->addr + I2SFIC);
snd_pcm_sframes_t delay;
+ const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
delay = FIC_RXCOUNT(reg);
else if (is_secondary(i2s))
delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS));
else
- delay = FIC_TXCOUNT(reg);
+ delay = (reg >> i2s_regs->ftx0cnt_off) & 0x7f;
return delay;
}
@@ -956,6 +972,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
{
struct i2s_dai *i2s = to_info(dai);
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+ int ret;
if (other && other->clk) { /* If this is probe on secondary */
samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback,
@@ -973,9 +990,14 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
if (IS_ERR(i2s->clk)) {
dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n");
iounmap(i2s->addr);
- return -ENOENT;
+ return PTR_ERR(i2s->clk);
+ }
+
+ ret = clk_prepare_enable(i2s->clk);
+ if (ret != 0) {
+ dev_err(&i2s->pdev->dev, "failed to enable clock: %d\n", ret);
+ return ret;
}
- clk_prepare_enable(i2s->clk);
samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
@@ -987,7 +1009,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
if (i2s->quirks & QUIRK_NEED_RSTCLR)
writel(CON_RSTCLR, i2s->addr + I2SCON);
- if (i2s->quirks & QUIRK_SEC_DAI)
+ if (i2s->quirks & QUIRK_SUPPORTS_IDMA)
idma_reg_addr_init(i2s->addr,
i2s->sec_dai->idma_playback.dma_addr);
@@ -1199,10 +1221,9 @@ static int samsung_i2s_probe(struct platform_device *pdev)
quirks = i2s_dai_data->quirks;
if (of_property_read_u32(np, "samsung,idma-addr",
&idma_addr)) {
- if (quirks & QUIRK_SEC_DAI) {
- dev_err(&pdev->dev, "idma address is not"\
+ if (quirks & QUIRK_SUPPORTS_IDMA) {
+ dev_info(&pdev->dev, "idma address is not"\
"specified");
- return -EINVAL;
}
}
}
@@ -1228,6 +1249,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
pri_dai->dma_capture.dma_size = 4;
pri_dai->base = regs_base;
pri_dai->quirks = quirks;
+ pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs;
if (quirks & QUIRK_PRI_6CHAN)
pri_dai->i2s_dai_drv.playback.channels_max = 6;
@@ -1302,20 +1324,93 @@ static int samsung_i2s_remove(struct platform_device *pdev)
return 0;
}
+static const struct samsung_i2s_variant_regs i2sv3_regs = {
+ .bfs_off = 1,
+ .rfs_off = 3,
+ .sdf_off = 5,
+ .txr_off = 8,
+ .rclksrc_off = 10,
+ .mss_off = 11,
+ .cdclkcon_off = 12,
+ .lrp_off = 7,
+ .bfs_mask = 0x3,
+ .rfs_mask = 0x3,
+ .ftx0cnt_off = 8,
+};
+
+static const struct samsung_i2s_variant_regs i2sv6_regs = {
+ .bfs_off = 0,
+ .rfs_off = 4,
+ .sdf_off = 6,
+ .txr_off = 8,
+ .rclksrc_off = 10,
+ .mss_off = 11,
+ .cdclkcon_off = 12,
+ .lrp_off = 15,
+ .bfs_mask = 0xf,
+ .rfs_mask = 0x3,
+ .ftx0cnt_off = 8,
+};
+
+static const struct samsung_i2s_variant_regs i2sv7_regs = {
+ .bfs_off = 0,
+ .rfs_off = 4,
+ .sdf_off = 7,
+ .txr_off = 9,
+ .rclksrc_off = 11,
+ .mss_off = 12,
+ .cdclkcon_off = 22,
+ .lrp_off = 15,
+ .bfs_mask = 0xf,
+ .rfs_mask = 0x7,
+ .ftx0cnt_off = 0,
+};
+
+static const struct samsung_i2s_variant_regs i2sv5_i2s1_regs = {
+ .bfs_off = 0,
+ .rfs_off = 3,
+ .sdf_off = 6,
+ .txr_off = 8,
+ .rclksrc_off = 10,
+ .mss_off = 11,
+ .cdclkcon_off = 12,
+ .lrp_off = 15,
+ .bfs_mask = 0x7,
+ .rfs_mask = 0x7,
+ .ftx0cnt_off = 8,
+};
+
static const struct samsung_i2s_dai_data i2sv3_dai_type = {
.dai_type = TYPE_PRI,
.quirks = QUIRK_NO_MUXPSR,
+ .i2s_variant_regs = &i2sv3_regs,
};
static const struct samsung_i2s_dai_data i2sv5_dai_type = {
.dai_type = TYPE_PRI,
- .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR,
+ .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
+ QUIRK_SUPPORTS_IDMA,
+ .i2s_variant_regs = &i2sv3_regs,
};
static const struct samsung_i2s_dai_data i2sv6_dai_type = {
.dai_type = TYPE_PRI,
.quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
+ QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA,
+ .i2s_variant_regs = &i2sv6_regs,
+};
+
+static const struct samsung_i2s_dai_data i2sv7_dai_type = {
+ .dai_type = TYPE_PRI,
+ .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
QUIRK_SUPPORTS_TDM,
+ .i2s_variant_regs = &i2sv7_regs,
+};
+
+static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = {
+ .dai_type = TYPE_PRI,
+ .quirks = QUIRK_PRI_6CHAN | QUIRK_NEED_RSTCLR,
+ .i2s_variant_regs = &i2sv5_i2s1_regs,
};
static const struct samsung_i2s_dai_data samsung_dai_type_pri = {
@@ -1329,10 +1424,13 @@ static const struct samsung_i2s_dai_data samsung_dai_type_sec = {
static struct platform_device_id samsung_i2s_driver_ids[] = {
{
.name = "samsung-i2s",
- .driver_data = (kernel_ulong_t)&samsung_dai_type_pri,
+ .driver_data = (kernel_ulong_t)&i2sv3_dai_type,
}, {
.name = "samsung-i2s-sec",
.driver_data = (kernel_ulong_t)&samsung_dai_type_sec,
+ }, {
+ .name = "samsung-i2sv4",
+ .driver_data = (kernel_ulong_t)&i2sv5_dai_type,
},
{},
};
@@ -1349,6 +1447,12 @@ static const struct of_device_id exynos_i2s_match[] = {
}, {
.compatible = "samsung,exynos5420-i2s",
.data = &i2sv6_dai_type,
+ }, {
+ .compatible = "samsung,exynos7-i2s",
+ .data = &i2sv7_dai_type,
+ }, {
+ .compatible = "samsung,exynos7-i2s1",
+ .data = &i2sv5_dai_type_i2s1,
},
{},
};