^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // ALSA SoC Audio Layer - Samsung I2S Controller driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (c) 2010 Samsung Electronics Co. Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // Jaswinder Singh <jassisinghbrar@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <dt-bindings/sound/samsung-i2s.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/platform_data/asoc-s3c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "dma.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "idma.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "i2s.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "i2s-regs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define SAMSUNG_I2S_ID_PRIMARY 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define SAMSUNG_I2S_ID_SECONDARY 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct samsung_i2s_variant_regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned int bfs_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned int rfs_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) unsigned int sdf_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned int txr_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) unsigned int rclksrc_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned int mss_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned int cdclkcon_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned int lrp_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) unsigned int bfs_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned int rfs_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned int ftx0cnt_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct samsung_i2s_dai_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) u32 quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) unsigned int pcm_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) const struct samsung_i2s_variant_regs *i2s_variant_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct i2s_dai {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* Platform device for this DAI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* Frame clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned frmclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * Specifically requested RCLK, BCLK by machine driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * 0 indicates CPU driver is free to choose any value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned rfs, bfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct i2s_dai *pri_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct i2s_dai *sec_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define DAI_OPENED (1 << 0) /* DAI is opened */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define DAI_MANAGER (1 << 1) /* DAI is the manager */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* Driver for this DAI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct snd_soc_dai_driver *drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* DMA parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct snd_dmaengine_dai_dma_data dma_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct snd_dmaengine_dai_dma_data dma_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct snd_dmaengine_dai_dma_data idma_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) dma_filter_fn filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct samsung_i2s_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct samsung_i2s_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct platform_device *pdev_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* Lock for cross interface checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) spinlock_t pcm_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* CPU DAIs and their corresponding drivers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct i2s_dai *dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct snd_soc_dai_driver *dai_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int num_dais;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* The I2S controller's core clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* Clock for generating I2S signals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct clk *op_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* Rate of RCLK source clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned long rclk_srcrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Cache of selected I2S registers for system suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u32 suspend_i2smod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u32 suspend_i2scon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) u32 suspend_i2spsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) const struct samsung_i2s_variant_regs *variant_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u32 quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* The clock provider's data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct clk *clk_table[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct clk_onecell_data clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Spinlock protecting member fields below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Memory mapped SFR region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) void __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* A flag indicating the I2S slave mode operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) bool slave_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Returns true if this is the 'overlay' stereo DAI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static inline bool is_secondary(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return i2s->drv->id == SAMSUNG_I2S_ID_SECONDARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* If this interface of the controller is transmitting data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static inline bool tx_active(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u32 active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) active = readl(i2s->priv->addr + I2SCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (is_secondary(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) active &= CON_TXSDMA_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) active &= CON_TXDMA_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return active ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* Return pointer to the other DAI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static inline struct i2s_dai *get_other_dai(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return i2s->pri_dai ? : i2s->sec_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* If the other interface of the controller is transmitting data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static inline bool other_tx_active(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct i2s_dai *other = get_other_dai(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return tx_active(other);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* If any interface of the controller is transmitting data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static inline bool any_tx_active(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return tx_active(i2s) || other_tx_active(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* If this interface of the controller is receiving data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static inline bool rx_active(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u32 active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (!i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) active = readl(i2s->priv->addr + I2SCON) & CON_RXDMA_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return active ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* If the other interface of the controller is receiving data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static inline bool other_rx_active(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct i2s_dai *other = get_other_dai(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return rx_active(other);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* If any interface of the controller is receiving data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static inline bool any_rx_active(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return rx_active(i2s) || other_rx_active(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* If the other DAI is transmitting or receiving data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static inline bool other_active(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return other_rx_active(i2s) || other_tx_active(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* If this DAI is transmitting or receiving data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static inline bool this_active(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return tx_active(i2s) || rx_active(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /* If the controller is active anyway */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static inline bool any_active(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return this_active(i2s) || other_active(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static inline struct i2s_dai *to_info(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return &priv->dai[dai->id - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static inline bool is_opened(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (i2s && (i2s->mode & DAI_OPENED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static inline bool is_manager(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (is_opened(i2s) && (i2s->mode & DAI_MANAGER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* Read RCLK of I2S (in multiples of LRCLK) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static inline unsigned get_rfs(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct samsung_i2s_priv *priv = i2s->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) u32 rfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) rfs = readl(priv->addr + I2SMOD) >> priv->variant_regs->rfs_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) rfs &= priv->variant_regs->rfs_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) switch (rfs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) case 7: return 192;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case 6: return 96;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case 5: return 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) case 4: return 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case 3: return 768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) case 2: return 384;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) case 1: return 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) default: return 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* Write RCLK of I2S (in multiples of LRCLK) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct samsung_i2s_priv *priv = i2s->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u32 mod = readl(priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int rfs_shift = priv->variant_regs->rfs_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) mod &= ~(priv->variant_regs->rfs_mask << rfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) switch (rfs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case 192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mod |= (EXYNOS7_MOD_RCLK_192FS << rfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) case 96:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) mod |= (EXYNOS7_MOD_RCLK_96FS << rfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) case 128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) mod |= (EXYNOS7_MOD_RCLK_128FS << rfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) case 64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) mod |= (EXYNOS7_MOD_RCLK_64FS << rfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) case 768:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) mod |= (MOD_RCLK_768FS << rfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) case 512:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) mod |= (MOD_RCLK_512FS << rfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) case 384:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) mod |= (MOD_RCLK_384FS << rfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) mod |= (MOD_RCLK_256FS << rfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) writel(mod, priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* Read bit-clock of I2S (in multiples of LRCLK) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static inline unsigned get_bfs(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct samsung_i2s_priv *priv = i2s->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) u32 bfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) bfs = readl(priv->addr + I2SMOD) >> priv->variant_regs->bfs_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) bfs &= priv->variant_regs->bfs_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) switch (bfs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) case 8: return 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case 7: return 192;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) case 6: return 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) case 5: return 96;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) case 4: return 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) case 3: return 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) case 2: return 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case 1: return 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) default: return 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* Write bit-clock of I2S (in multiples of LRCLK) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct samsung_i2s_priv *priv = i2s->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) u32 mod = readl(priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) int tdm = priv->quirks & QUIRK_SUPPORTS_TDM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int bfs_shift = priv->variant_regs->bfs_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* Non-TDM I2S controllers do not support BCLK > 48 * FS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (!tdm && bfs > 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) dev_err(&i2s->pdev->dev, "Unsupported BCLK divider\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) mod &= ~(priv->variant_regs->bfs_mask << bfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) switch (bfs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) case 48:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) mod |= (MOD_BCLK_48FS << bfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) mod |= (MOD_BCLK_32FS << bfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) mod |= (MOD_BCLK_24FS << bfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) mod |= (MOD_BCLK_16FS << bfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) case 64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) mod |= (EXYNOS5420_MOD_BCLK_64FS << bfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case 96:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) mod |= (EXYNOS5420_MOD_BCLK_96FS << bfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case 128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) mod |= (EXYNOS5420_MOD_BCLK_128FS << bfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case 192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) mod |= (EXYNOS5420_MOD_BCLK_192FS << bfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) case 256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) mod |= (EXYNOS5420_MOD_BCLK_256FS << bfs_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) writel(mod, priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* Sample size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static inline int get_blc(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) int blc = readl(i2s->priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) blc = (blc >> 13) & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) switch (blc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) case 2: return 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) case 1: return 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) default: return 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /* TX channel control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static void i2s_txctrl(struct i2s_dai *i2s, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct samsung_i2s_priv *priv = i2s->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) void __iomem *addr = priv->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) int txr_off = priv->variant_regs->txr_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) u32 con = readl(addr + I2SCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) u32 mod = readl(addr + I2SMOD) & ~(3 << txr_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) con |= CON_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) con &= ~CON_TXCH_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (is_secondary(i2s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) con |= CON_TXSDMA_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) con &= ~CON_TXSDMA_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) con |= CON_TXDMA_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) con &= ~CON_TXDMA_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (any_rx_active(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) mod |= 2 << txr_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) mod |= 0 << txr_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (is_secondary(i2s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) con |= CON_TXSDMA_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) con &= ~CON_TXSDMA_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) con |= CON_TXDMA_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) con &= ~CON_TXDMA_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (other_tx_active(i2s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) writel(con, addr + I2SCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) con |= CON_TXCH_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (any_rx_active(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) mod |= 1 << txr_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) con &= ~CON_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) writel(mod, addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) writel(con, addr + I2SCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /* RX Channel Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static void i2s_rxctrl(struct i2s_dai *i2s, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct samsung_i2s_priv *priv = i2s->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) void __iomem *addr = priv->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int txr_off = priv->variant_regs->txr_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) u32 con = readl(addr + I2SCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) u32 mod = readl(addr + I2SMOD) & ~(3 << txr_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) con |= CON_RXDMA_ACTIVE | CON_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (any_tx_active(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) mod |= 2 << txr_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) mod |= 1 << txr_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) con |= CON_RXDMA_PAUSE | CON_RXCH_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) con &= ~CON_RXDMA_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (any_tx_active(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) mod |= 0 << txr_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) con &= ~CON_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) writel(mod, addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) writel(con, addr + I2SCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /* Flush FIFO of an interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) void __iomem *fic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (!i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (is_secondary(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) fic = i2s->priv->addr + I2SFICS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) fic = i2s->priv->addr + I2SFIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* Flush the FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) writel(readl(fic) | flush, fic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /* Be patient */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) val = msecs_to_loops(1) / 1000; /* 1 usec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) while (--val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) writel(readl(fic) & ~flush, fic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static int i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int rfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct i2s_dai *i2s = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct i2s_dai *other = get_other_dai(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) const struct samsung_i2s_variant_regs *i2s_regs = priv->variant_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) u32 mod, mask, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) pm_runtime_get_sync(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) mod = readl(priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) switch (clk_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) case SAMSUNG_I2S_OPCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) mask = MOD_OPCLK_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) val = (dir << MOD_OPCLK_SHIFT) & MOD_OPCLK_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) case SAMSUNG_I2S_CDCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) mask = 1 << i2s_regs->cdclkcon_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* Shouldn't matter in GATING(CLOCK_IN) mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (dir == SND_SOC_CLOCK_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) rfs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if ((rfs && other && other->rfs && (other->rfs != rfs)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) (any_active(i2s) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) (((dir == SND_SOC_CLOCK_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) && !(mod & cdcon_mask)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) ((dir == SND_SOC_CLOCK_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) && (mod & cdcon_mask))))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) dev_err(&i2s->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) "%s:%d Other DAI busy\n", __func__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (dir == SND_SOC_CLOCK_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) val = 1 << i2s_regs->cdclkcon_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) i2s->rfs = rfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) mask = 1 << i2s_regs->rclksrc_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if ((priv->quirks & QUIRK_NO_MUXPSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) || (clk_id == SAMSUNG_I2S_RCLKSRC_0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) clk_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) clk_id = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (!any_active(i2s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (priv->op_clk && !IS_ERR(priv->op_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if ((clk_id && !(mod & rsrc_mask)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) (!clk_id && (mod & rsrc_mask))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) clk_disable_unprepare(priv->op_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) clk_put(priv->op_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) priv->rclk_srcrate =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) clk_get_rate(priv->op_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (clk_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) priv->op_clk = clk_get(&i2s->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) "i2s_opclk1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) priv->op_clk = clk_get(&i2s->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) "i2s_opclk0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (WARN_ON(IS_ERR(priv->op_clk))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) ret = PTR_ERR(priv->op_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) priv->op_clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ret = clk_prepare_enable(priv->op_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) clk_put(priv->op_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) priv->op_clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) priv->rclk_srcrate = clk_get_rate(priv->op_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) } else if ((!clk_id && (mod & rsrc_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) || (clk_id && !(mod & rsrc_mask))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) dev_err(&i2s->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) "%s:%d Other DAI busy\n", __func__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* Call can't be on the active DAI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (clk_id == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) val = 1 << i2s_regs->rclksrc_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) dev_err(&i2s->pdev->dev, "We don't serve that!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) mod = readl(priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) mod = (mod & ~mask) | val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) writel(mod, priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) pm_runtime_put(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) pm_runtime_put(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static int i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct i2s_dai *i2s = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) u32 mod, tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) lrp_shift = priv->variant_regs->lrp_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) sdf_shift = priv->variant_regs->sdf_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) mod_slave = 1 << priv->variant_regs->mss_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) sdf_mask = MOD_SDF_MASK << sdf_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) lrp_rlow = MOD_LR_RLOW << lrp_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /* Format is priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) case SND_SOC_DAIFMT_RIGHT_J:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) tmp |= lrp_rlow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) tmp |= (MOD_SDF_MSB << sdf_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) case SND_SOC_DAIFMT_LEFT_J:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) tmp |= lrp_rlow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) tmp |= (MOD_SDF_LSB << sdf_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) case SND_SOC_DAIFMT_I2S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) tmp |= (MOD_SDF_IIS << sdf_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) dev_err(&i2s->pdev->dev, "Format not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * INV flag is relative to the FORMAT flag - if set it simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * flips the polarity specified by the Standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) case SND_SOC_DAIFMT_NB_NF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) case SND_SOC_DAIFMT_NB_IF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (tmp & lrp_rlow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) tmp &= ~lrp_rlow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) tmp |= lrp_rlow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) dev_err(&i2s->pdev->dev, "Polarity not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) case SND_SOC_DAIFMT_CBM_CFM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) tmp |= mod_slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) case SND_SOC_DAIFMT_CBS_CFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * Set default source clock in Master mode, only when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * CLK_I2S_RCLK_SRC clock is not exposed so we ensure any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * clock configuration assigned in DT is not overwritten.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (priv->rclk_srcrate == 0 && priv->clk_data.clks == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 0, SND_SOC_CLOCK_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) dev_err(&i2s->pdev->dev, "master/slave format not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) pm_runtime_get_sync(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) mod = readl(priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * Don't change the I2S mode if any controller is active on this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (any_active(i2s) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ((mod & (sdf_mask | lrp_rlow | mod_slave)) != tmp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) pm_runtime_put(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) dev_err(&i2s->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) "%s:%d Other DAI busy\n", __func__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) mod &= ~(sdf_mask | lrp_rlow | mod_slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) mod |= tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) writel(mod, priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) priv->slave_mode = (mod & mod_slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) pm_runtime_put(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static int i2s_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) struct i2s_dai *i2s = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) u32 mod, mask = 0, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct clk *rclksrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) WARN_ON(!pm_runtime_active(dai->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (!is_secondary(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) mask |= (MOD_DC2_EN | MOD_DC1_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) switch (params_channels(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) val |= MOD_DC2_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) val |= MOD_DC1_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) i2s->dma_playback.addr_width = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) i2s->dma_capture.addr_width = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) i2s->dma_playback.addr_width = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) i2s->dma_capture.addr_width = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) dev_err(&i2s->pdev->dev, "%d channels not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) params_channels(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (is_secondary(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) mask |= MOD_BLCS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) mask |= MOD_BLCP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (is_manager(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) mask |= MOD_BLC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) switch (params_width(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (is_secondary(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) val |= MOD_BLCS_8BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) val |= MOD_BLCP_8BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (is_manager(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) val |= MOD_BLC_8BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (is_secondary(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) val |= MOD_BLCS_16BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) val |= MOD_BLCP_16BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (is_manager(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) val |= MOD_BLC_16BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (is_secondary(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) val |= MOD_BLCS_24BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) val |= MOD_BLCP_24BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (is_manager(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) val |= MOD_BLC_24BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) dev_err(&i2s->pdev->dev, "Format(%d) not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) params_format(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) mod = readl(priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) mod = (mod & ~mask) | val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) writel(mod, priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) i2s->frmclk = params_rate(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) rclksrc = priv->clk_table[CLK_I2S_RCLK_SRC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (rclksrc && !IS_ERR(rclksrc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) priv->rclk_srcrate = clk_get_rate(rclksrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* We set constraints on the substream according to the version of I2S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static int i2s_startup(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) struct i2s_dai *i2s = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) struct i2s_dai *other = get_other_dai(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) pm_runtime_get_sync(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) spin_lock_irqsave(&priv->pcm_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) i2s->mode |= DAI_OPENED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (is_manager(other))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) i2s->mode &= ~DAI_MANAGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) i2s->mode |= DAI_MANAGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (!any_active(i2s) && (priv->quirks & QUIRK_NEED_RSTCLR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) writel(CON_RSTCLR, i2s->priv->addr + I2SCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) spin_unlock_irqrestore(&priv->pcm_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static void i2s_shutdown(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct i2s_dai *i2s = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct i2s_dai *other = get_other_dai(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) spin_lock_irqsave(&priv->pcm_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) i2s->mode &= ~DAI_OPENED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) i2s->mode &= ~DAI_MANAGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (is_opened(other))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) other->mode |= DAI_MANAGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) /* Reset any constraint on RFS and BFS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) i2s->rfs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) i2s->bfs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) spin_unlock_irqrestore(&priv->pcm_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) pm_runtime_put(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static int config_setup(struct i2s_dai *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct samsung_i2s_priv *priv = i2s->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) struct i2s_dai *other = get_other_dai(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) unsigned rfs, bfs, blc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) u32 psr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) blc = get_blc(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) bfs = i2s->bfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (!bfs && other)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) bfs = other->bfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) /* Select least possible multiple(2) if no constraint set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (!bfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) bfs = blc * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) rfs = i2s->rfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (!rfs && other)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) rfs = other->rfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if ((rfs == 256 || rfs == 512) && (blc == 24)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) dev_err(&i2s->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) "%d-RFS not supported for 24-blc\n", rfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (!rfs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (bfs == 16 || bfs == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) rfs = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) rfs = 384;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /* If already setup and running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (any_active(i2s) && (get_rfs(i2s) != rfs || get_bfs(i2s) != bfs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) dev_err(&i2s->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) "%s:%d Other DAI busy\n", __func__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) set_bfs(i2s, bfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) set_rfs(i2s, rfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) /* Don't bother with PSR in Slave mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (priv->slave_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (!(priv->quirks & QUIRK_NO_MUXPSR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) psr = priv->rclk_srcrate / i2s->frmclk / rfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) writel(((psr - 1) << 8) | PSR_PSREN, priv->addr + I2SPSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) dev_dbg(&i2s->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) "RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) priv->rclk_srcrate, psr, rfs, bfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static int i2s_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) int cmd, struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct i2s_dai *i2s = to_info(asoc_rtd_to_cpu(rtd, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) pm_runtime_get_sync(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (config_setup(i2s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (capture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) i2s_rxctrl(i2s, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) i2s_txctrl(i2s, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (capture) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) i2s_rxctrl(i2s, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) i2s_fifo(i2s, FIC_RXFLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) i2s_txctrl(i2s, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) i2s_fifo(i2s, FIC_TXFLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) pm_runtime_put(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) static int i2s_set_clkdiv(struct snd_soc_dai *dai,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) int div_id, int div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) struct i2s_dai *i2s = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) struct i2s_dai *other = get_other_dai(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) switch (div_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) case SAMSUNG_I2S_DIV_BCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) pm_runtime_get_sync(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if ((any_active(i2s) && div && (get_bfs(i2s) != div))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) || (other && other->bfs && (other->bfs != div))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) pm_runtime_put(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) dev_err(&i2s->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) "%s:%d Other DAI busy\n", __func__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) i2s->bfs = div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) pm_runtime_put(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) dev_err(&i2s->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) "Invalid clock divider(%d)\n", div_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) static snd_pcm_sframes_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) struct i2s_dai *i2s = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) u32 reg = readl(priv->addr + I2SFIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) snd_pcm_sframes_t delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) WARN_ON(!pm_runtime_active(dai->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) delay = FIC_RXCOUNT(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) else if (is_secondary(i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) delay = FICS_TXCOUNT(readl(priv->addr + I2SFICS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) delay = (reg >> priv->variant_regs->ftx0cnt_off) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static int i2s_suspend(struct snd_soc_component *component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return pm_runtime_force_suspend(component->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static int i2s_resume(struct snd_soc_component *component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) return pm_runtime_force_resume(component->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) #define i2s_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) #define i2s_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) struct i2s_dai *i2s = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) struct i2s_dai *other = get_other_dai(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) pm_runtime_get_sync(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (is_secondary(i2s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) /* If this is probe on the secondary DAI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) snd_soc_dai_init_dma_data(dai, &i2s->dma_playback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) &i2s->dma_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (priv->quirks & QUIRK_NEED_RSTCLR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) writel(CON_RSTCLR, priv->addr + I2SCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (priv->quirks & QUIRK_SUPPORTS_IDMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) idma_reg_addr_init(priv->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) other->idma_playback.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) /* Reset any constraint on RFS and BFS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) i2s->rfs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) i2s->bfs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) i2s_txctrl(i2s, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) i2s_rxctrl(i2s, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) i2s_fifo(i2s, FIC_TXFLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) i2s_fifo(other, FIC_TXFLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) i2s_fifo(i2s, FIC_RXFLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) /* Gate CDCLK by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (!is_opened(other))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 0, SND_SOC_CLOCK_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) pm_runtime_put(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) struct i2s_dai *i2s = to_info(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) pm_runtime_get_sync(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (!is_secondary(i2s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (priv->quirks & QUIRK_NEED_RSTCLR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) writel(0, priv->addr + I2SCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) pm_runtime_put(dai->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) static const struct snd_soc_dai_ops samsung_i2s_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) .trigger = i2s_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) .hw_params = i2s_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) .set_fmt = i2s_set_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) .set_clkdiv = i2s_set_clkdiv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .set_sysclk = i2s_set_sysclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .startup = i2s_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) .shutdown = i2s_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) .delay = i2s_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) static const struct snd_soc_dapm_widget samsung_i2s_widgets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) /* Backend DAI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) SND_SOC_DAPM_AIF_OUT("Mixer DAI TX", NULL, 0, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) SND_SOC_DAPM_AIF_IN("Mixer DAI RX", NULL, 0, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* Playback Mixer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) SND_SOC_DAPM_MIXER("Playback Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) static const struct snd_soc_dapm_route samsung_i2s_dapm_routes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) { "Playback Mixer", NULL, "Primary Playback" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) { "Playback Mixer", NULL, "Secondary Playback" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) { "Mixer DAI TX", NULL, "Playback Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) { "Primary Capture", NULL, "Mixer DAI RX" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static const struct snd_soc_component_driver samsung_i2s_component = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) .name = "samsung-i2s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) .dapm_widgets = samsung_i2s_widgets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) .num_dapm_widgets = ARRAY_SIZE(samsung_i2s_widgets),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) .dapm_routes = samsung_i2s_dapm_routes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) .num_dapm_routes = ARRAY_SIZE(samsung_i2s_dapm_routes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) .suspend = i2s_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) .resume = i2s_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) #define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) SNDRV_PCM_FMTBIT_S24_LE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) static int i2s_alloc_dais(struct samsung_i2s_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) const struct samsung_i2s_dai_data *i2s_dai_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) int num_dais)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static const char *dai_names[] = { "samsung-i2s", "samsung-i2s-sec" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) static const char *stream_names[] = { "Primary Playback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) "Secondary Playback" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) struct snd_soc_dai_driver *dai_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct i2s_dai *dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) priv->dai = devm_kcalloc(&priv->pdev->dev, num_dais,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) sizeof(*dai), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (!priv->dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) priv->dai_drv = devm_kcalloc(&priv->pdev->dev, num_dais,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) sizeof(*dai_drv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (!priv->dai_drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) for (i = 0; i < num_dais; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) dai_drv = &priv->dai_drv[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) dai_drv->probe = samsung_i2s_dai_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) dai_drv->remove = samsung_i2s_dai_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) dai_drv->symmetric_rates = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) dai_drv->ops = &samsung_i2s_dai_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) dai_drv->playback.channels_min = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) dai_drv->playback.channels_max = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) dai_drv->playback.rates = i2s_dai_data->pcm_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) dai_drv->playback.formats = SAMSUNG_I2S_FMTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) dai_drv->playback.stream_name = stream_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) dai_drv->id = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) dai_drv->name = dai_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) priv->dai[i].drv = &priv->dai_drv[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) priv->dai[i].pdev = priv->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /* Initialize capture only for the primary DAI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) dai_drv = &priv->dai_drv[SAMSUNG_I2S_ID_PRIMARY - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) dai_drv->capture.channels_min = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) dai_drv->capture.channels_max = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) dai_drv->capture.rates = i2s_dai_data->pcm_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) dai_drv->capture.formats = SAMSUNG_I2S_FMTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) dai_drv->capture.stream_name = "Primary Capture";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) static int i2s_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) priv->suspend_i2smod = readl(priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) priv->suspend_i2scon = readl(priv->addr + I2SCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) priv->suspend_i2spsr = readl(priv->addr + I2SPSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if (priv->op_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) clk_disable_unprepare(priv->op_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) clk_disable_unprepare(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) static int i2s_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) ret = clk_prepare_enable(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (priv->op_clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) ret = clk_prepare_enable(priv->op_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) clk_disable_unprepare(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) writel(priv->suspend_i2scon, priv->addr + I2SCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) writel(priv->suspend_i2smod, priv->addr + I2SMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) writel(priv->suspend_i2spsr, priv->addr + I2SPSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static void i2s_unregister_clocks(struct samsung_i2s_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) for (i = 0; i < priv->clk_data.clk_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) if (!IS_ERR(priv->clk_table[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) clk_unregister(priv->clk_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) static void i2s_unregister_clock_provider(struct samsung_i2s_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) of_clk_del_provider(priv->pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) i2s_unregister_clocks(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) static int i2s_register_clock_provider(struct samsung_i2s_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) const char * const i2s_clk_desc[] = { "cdclk", "rclk_src", "prescaler" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) const char *clk_name[2] = { "i2s_opclk0", "i2s_opclk1" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) const char *p_names[2] = { NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) struct device *dev = &priv->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) const struct samsung_i2s_variant_regs *reg_info = priv->variant_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) const char *i2s_clk_name[ARRAY_SIZE(i2s_clk_desc)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) struct clk *rclksrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) /* Register the clock provider only if it's expected in the DTB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) if (!of_find_property(dev->of_node, "#clock-cells", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) /* Get the RCLKSRC mux clock parent clock names */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) for (i = 0; i < ARRAY_SIZE(p_names); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) rclksrc = clk_get(dev, clk_name[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (IS_ERR(rclksrc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) p_names[i] = __clk_get_name(rclksrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) clk_put(rclksrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) for (i = 0; i < ARRAY_SIZE(i2s_clk_desc); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) i2s_clk_name[i] = devm_kasprintf(dev, GFP_KERNEL, "%s_%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) dev_name(dev), i2s_clk_desc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (!i2s_clk_name[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (!(priv->quirks & QUIRK_NO_MUXPSR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) /* Activate the prescaler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) u32 val = readl(priv->addr + I2SPSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) writel(val | PSR_PSREN, priv->addr + I2SPSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) priv->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) i2s_clk_name[CLK_I2S_RCLK_SRC], p_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) ARRAY_SIZE(p_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) priv->addr + I2SMOD, reg_info->rclksrc_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 1, 0, &priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) priv->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) i2s_clk_name[CLK_I2S_RCLK_PSR],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) i2s_clk_name[CLK_I2S_RCLK_SRC],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) CLK_SET_RATE_PARENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) priv->addr + I2SPSR, 8, 6, 0, &priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) p_names[0] = i2s_clk_name[CLK_I2S_RCLK_PSR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) priv->clk_data.clk_num = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) priv->clk_table[CLK_I2S_CDCLK] = clk_register_gate(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) i2s_clk_name[CLK_I2S_CDCLK], p_names[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) CLK_SET_RATE_PARENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) priv->addr + I2SMOD, reg_info->cdclkcon_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) CLK_GATE_SET_TO_DISABLE, &priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) priv->clk_data.clk_num += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) priv->clk_data.clks = priv->clk_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) &priv->clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) dev_err(dev, "failed to add clock provider: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) i2s_unregister_clocks(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) /* Create platform device for the secondary PCM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) static int i2s_create_secondary_device(struct samsung_i2s_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) struct platform_device *pdev_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) const char *devname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) devname = devm_kasprintf(&priv->pdev->dev, GFP_KERNEL, "%s-sec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) dev_name(&priv->pdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (!devname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) pdev_sec = platform_device_alloc(devname, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) if (!pdev_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) pdev_sec->driver_override = kstrdup("samsung-i2s", GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) ret = platform_device_add(pdev_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) platform_device_put(pdev_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) ret = device_attach(&pdev_sec->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (ret <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) platform_device_unregister(priv->pdev_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) dev_info(&pdev_sec->dev, "device_attach() failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) priv->pdev_sec = pdev_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) static void i2s_delete_secondary_device(struct samsung_i2s_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) platform_device_unregister(priv->pdev_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) priv->pdev_sec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) static int samsung_i2s_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) struct i2s_dai *pri_dai, *sec_dai = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) u32 regs_base, idma_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) const struct samsung_i2s_dai_data *i2s_dai_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) const struct platform_device_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) struct samsung_i2s_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) int num_dais, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) i2s_dai_data = of_device_get_match_data(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) id = platform_get_device_id(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) /* Nothing to do if it is the secondary device probe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) i2s_dai_data = (struct samsung_i2s_dai_data *)id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) priv->quirks = i2s_dai_data->quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (!i2s_pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) dev_err(&pdev->dev, "Missing platform data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) priv->quirks = i2s_pdata->type.quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) num_dais = (priv->quirks & QUIRK_SEC_DAI) ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) priv->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) priv->variant_regs = i2s_dai_data->i2s_variant_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) ret = i2s_alloc_dais(priv, i2s_dai_data, num_dais);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) pri_dai = &priv->dai[SAMSUNG_I2S_ID_PRIMARY - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) spin_lock_init(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) spin_lock_init(&priv->pcm_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) pri_dai->dma_playback.filter_data = i2s_pdata->dma_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) pri_dai->dma_capture.filter_data = i2s_pdata->dma_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) pri_dai->filter = i2s_pdata->dma_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) idma_addr = i2s_pdata->type.idma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) if (of_property_read_u32(np, "samsung,idma-addr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) &idma_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (priv->quirks & QUIRK_SUPPORTS_IDMA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) dev_info(&pdev->dev, "idma address is not"\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) "specified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) priv->addr = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) if (IS_ERR(priv->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) return PTR_ERR(priv->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) regs_base = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) priv->clk = devm_clk_get(&pdev->dev, "iis");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) if (IS_ERR(priv->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) dev_err(&pdev->dev, "Failed to get iis clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) return PTR_ERR(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) ret = clk_prepare_enable(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) pri_dai->dma_playback.addr = regs_base + I2STXD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) pri_dai->dma_capture.addr = regs_base + I2SRXD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) pri_dai->dma_playback.chan_name = "tx";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) pri_dai->dma_capture.chan_name = "rx";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) pri_dai->dma_playback.addr_width = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) pri_dai->dma_capture.addr_width = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) pri_dai->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) if (priv->quirks & QUIRK_PRI_6CHAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) pri_dai->drv->playback.channels_max = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) "tx", "rx", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) goto err_disable_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (priv->quirks & QUIRK_SEC_DAI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) sec_dai = &priv->dai[SAMSUNG_I2S_ID_SECONDARY - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) sec_dai->dma_playback.addr = regs_base + I2STXDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) sec_dai->dma_playback.chan_name = "tx-sec";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) sec_dai->dma_playback.filter_data = i2s_pdata->dma_play_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) sec_dai->filter = i2s_pdata->dma_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) sec_dai->dma_playback.addr_width = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) sec_dai->idma_playback.addr = idma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) sec_dai->pri_dai = pri_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) sec_dai->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) pri_dai->sec_dai = sec_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) ret = i2s_create_secondary_device(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) goto err_disable_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) ret = samsung_asoc_dma_platform_register(&priv->pdev_sec->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) sec_dai->filter, "tx-sec", NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) goto err_del_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) dev_err(&pdev->dev, "Unable to configure gpio\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) goto err_del_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) dev_set_drvdata(&pdev->dev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) ret = devm_snd_soc_register_component(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) &samsung_i2s_component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) priv->dai_drv, num_dais);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) goto err_del_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) pm_runtime_set_active(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) ret = i2s_register_clock_provider(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) goto err_disable_pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) priv->op_clk = clk_get_parent(priv->clk_table[CLK_I2S_RCLK_SRC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) err_disable_pm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) err_del_sec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) i2s_delete_secondary_device(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) err_disable_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) clk_disable_unprepare(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) static int samsung_i2s_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) struct samsung_i2s_priv *priv = dev_get_drvdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) /* The secondary device has no driver data assigned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) pm_runtime_get_sync(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) i2s_unregister_clock_provider(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) i2s_delete_secondary_device(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) clk_disable_unprepare(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) pm_runtime_put_noidle(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) static const struct samsung_i2s_variant_regs i2sv3_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) .bfs_off = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) .rfs_off = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) .sdf_off = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) .txr_off = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) .rclksrc_off = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) .mss_off = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) .cdclkcon_off = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) .lrp_off = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) .bfs_mask = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) .rfs_mask = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) .ftx0cnt_off = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static const struct samsung_i2s_variant_regs i2sv6_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) .bfs_off = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) .rfs_off = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) .sdf_off = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) .txr_off = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) .rclksrc_off = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) .mss_off = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) .cdclkcon_off = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) .lrp_off = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) .bfs_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) .rfs_mask = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) .ftx0cnt_off = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) static const struct samsung_i2s_variant_regs i2sv7_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) .bfs_off = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) .rfs_off = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) .sdf_off = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) .txr_off = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) .rclksrc_off = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) .mss_off = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) .cdclkcon_off = 22,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) .lrp_off = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) .bfs_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) .rfs_mask = 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) .ftx0cnt_off = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) static const struct samsung_i2s_variant_regs i2sv5_i2s1_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) .bfs_off = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) .rfs_off = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) .sdf_off = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) .txr_off = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) .rclksrc_off = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) .mss_off = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) .cdclkcon_off = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) .lrp_off = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) .bfs_mask = 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) .rfs_mask = 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) .ftx0cnt_off = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) static const struct samsung_i2s_dai_data i2sv3_dai_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) .quirks = QUIRK_NO_MUXPSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) .pcm_rates = SNDRV_PCM_RATE_8000_96000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) .i2s_variant_regs = &i2sv3_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) static const struct samsung_i2s_dai_data i2sv5_dai_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) QUIRK_SUPPORTS_IDMA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) .pcm_rates = SNDRV_PCM_RATE_8000_96000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) .i2s_variant_regs = &i2sv3_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) static const struct samsung_i2s_dai_data i2sv6_dai_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) .pcm_rates = SNDRV_PCM_RATE_8000_96000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) .i2s_variant_regs = &i2sv6_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) static const struct samsung_i2s_dai_data i2sv7_dai_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) QUIRK_SUPPORTS_TDM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) .pcm_rates = SNDRV_PCM_RATE_8000_192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) .i2s_variant_regs = &i2sv7_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) .quirks = QUIRK_PRI_6CHAN | QUIRK_NEED_RSTCLR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) .pcm_rates = SNDRV_PCM_RATE_8000_96000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) .i2s_variant_regs = &i2sv5_i2s1_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) static const struct platform_device_id samsung_i2s_driver_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) .name = "samsung-i2s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) .driver_data = (kernel_ulong_t)&i2sv3_dai_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) MODULE_DEVICE_TABLE(platform, samsung_i2s_driver_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) static const struct of_device_id exynos_i2s_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) .compatible = "samsung,s3c6410-i2s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) .data = &i2sv3_dai_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) .compatible = "samsung,s5pv210-i2s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) .data = &i2sv5_dai_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) .compatible = "samsung,exynos5420-i2s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) .data = &i2sv6_dai_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) .compatible = "samsung,exynos7-i2s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) .data = &i2sv7_dai_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) .compatible = "samsung,exynos7-i2s1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) .data = &i2sv5_dai_type_i2s1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) MODULE_DEVICE_TABLE(of, exynos_i2s_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) static const struct dev_pm_ops samsung_i2s_pm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) SET_RUNTIME_PM_OPS(i2s_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) i2s_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) pm_runtime_force_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) static struct platform_driver samsung_i2s_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) .probe = samsung_i2s_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) .remove = samsung_i2s_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) .id_table = samsung_i2s_driver_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) .name = "samsung-i2s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) .of_match_table = of_match_ptr(exynos_i2s_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) .pm = &samsung_i2s_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) module_platform_driver(samsung_i2s_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) /* Module information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) MODULE_DESCRIPTION("Samsung I2S Interface");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) MODULE_ALIAS("platform:samsung-i2s");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) MODULE_LICENSE("GPL");