···1919 - renesas,r9a07g043-ssi # RZ/G2UL and RZ/Five2020 - renesas,r9a07g044-ssi # RZ/G2{L,LC}2121 - renesas,r9a07g054-ssi # RZ/V2L2222+ - renesas,r9a08g045-ssi # RZ/G3S2223 - const: renesas,rz-ssi23242425 reg:···5857 dmas:5958 minItems: 16059 maxItems: 26161- description:6262- The first cell represents a phandle to dmac.6363- The second cell specifies the encoded MID/RID values of the SSI port6464- connected to the DMA client and the slave channel configuration6565- parameters.6666- bits[0:9] - Specifies MID/RID value of a SSI channel as below6767- MID/RID value of SSI rx0 = 0x2566868- MID/RID value of SSI tx0 = 0x2556969- MID/RID value of SSI rx1 = 0x25a7070- MID/RID value of SSI tx1 = 0x2597171- MID/RID value of SSI rt2 = 0x25f7272- MID/RID value of SSI rx3 = 0x2627373- MID/RID value of SSI tx3 = 0x2617474- bit[10] - HIEN = 1, Detects a request in response to the rising edge7575- of the signal7676- bit[11] - LVL = 0, Detects based on the edge7777- bits[12:14] - AM = 2, Bus cycle mode7878- bit[15] - TM = 0, Single transfer mode79608061 dma-names:8162 oneOf:
+138-88
sound/soc/renesas/rz-ssi.c
···99#include <linux/clk.h>1010#include <linux/dmaengine.h>1111#include <linux/io.h>1212+#include <linux/iopoll.h>1213#include <linux/module.h>1314#include <linux/pm_runtime.h>1415#include <linux/reset.h>···7271#define PREALLOC_BUFFER (SZ_32K)7372#define PREALLOC_BUFFER_MAX (SZ_32K)74737575-#define SSI_RATES SNDRV_PCM_RATE_8000_48000 /* 8k-44.1kHz */7474+#define SSI_RATES SNDRV_PCM_RATE_8000_48000 /* 8k-48kHz */7675#define SSI_FMTS SNDRV_PCM_FMTBIT_S16_LE7776#define SSI_CHAN_MIN 27877#define SSI_CHAN_MAX 2···10099101100struct rz_ssi_priv {102101 void __iomem *base;103103- struct platform_device *pdev;104102 struct reset_control *rstc;105103 struct device *dev;106104 struct clk *sfr_clk;···163163 writel(val, (priv->base + reg));164164}165165166166-static inline struct snd_soc_dai *167167-rz_ssi_get_dai(struct snd_pcm_substream *substream)168168-{169169- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);170170-171171- return snd_soc_rtd_to_cpu(rtd, 0);172172-}173173-174174-static inline bool rz_ssi_stream_is_play(struct rz_ssi_priv *ssi,175175- struct snd_pcm_substream *substream)166166+static inline bool rz_ssi_stream_is_play(struct snd_pcm_substream *substream)176167{177168 return substream->stream == SNDRV_PCM_STREAM_PLAYBACK;178169}···235244static void rz_ssi_stream_quit(struct rz_ssi_priv *ssi,236245 struct rz_ssi_stream *strm)237246{238238- struct snd_soc_dai *dai = rz_ssi_get_dai(strm->substream);247247+ struct device *dev = ssi->dev;239248240249 rz_ssi_set_substream(strm, NULL);241250242251 if (strm->oerr_num > 0)243243- dev_info(dai->dev, "overrun = %d\n", strm->oerr_num);252252+ dev_info(dev, "overrun = %d\n", strm->oerr_num);244253245254 if (strm->uerr_num > 0)246246- dev_info(dai->dev, "underrun = %d\n", strm->uerr_num);255255+ dev_info(dev, "underrun = %d\n", strm->uerr_num);247256}248257249258static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, unsigned int rate,250259 unsigned int channels)251260{252252- static s8 ckdv[16] = { 1, 2, 4, 8, 16, 32, 64, 128,253253- 6, 12, 24, 48, 96, -1, -1, -1 };261261+ static u8 ckdv[] = { 1, 2, 4, 8, 16, 32, 64, 128, 6, 12, 24, 48, 96 };254262 unsigned int channel_bits = 32; /* System Word Length */255263 unsigned long bclk_rate = rate * channels * channel_bits;256264 unsigned int div;···308318309319static void rz_ssi_set_idle(struct rz_ssi_priv *ssi)310320{311311- int timeout;321321+ u32 tmp;322322+ int ret;312323313324 /* Disable irqs */314325 rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TUIEN | SSICR_TOIEN |···322331 SSISR_RUIRQ), 0);323332324333 /* Wait for idle */325325- timeout = 100;326326- while (--timeout) {327327- if (rz_ssi_reg_readl(ssi, SSISR) & SSISR_IIRQ)328328- break;329329- udelay(1);330330- }331331-332332- if (!timeout)333333- dev_info(ssi->dev, "timeout waiting for SSI idle\n");334334+ ret = readl_poll_timeout_atomic(ssi->base + SSISR, tmp, (tmp & SSISR_IIRQ), 1, 100);335335+ if (ret)336336+ dev_warn_ratelimited(ssi->dev, "timeout waiting for SSI idle\n");334337335338 /* Hold FIFOs in reset */336339 rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, SSIFCR_FIFO_RST);···332347333348static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)334349{335335- bool is_play = rz_ssi_stream_is_play(ssi, strm->substream);350350+ bool is_play = rz_ssi_stream_is_play(strm->substream);336351 bool is_full_duplex;337352 u32 ssicr, ssifcr;338353···388403 return 0;389404}390405406406+static int rz_ssi_swreset(struct rz_ssi_priv *ssi)407407+{408408+ u32 tmp;409409+410410+ rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, SSIFCR_SSIRST);411411+ rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, 0);412412+ return readl_poll_timeout_atomic(ssi->base + SSIFCR, tmp, !(tmp & SSIFCR_SSIRST), 1, 5);413413+}414414+391415static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)392416{393417 strm->running = 0;···409415 rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TEN | SSICR_REN, 0);410416411417 /* Cancel all remaining DMA transactions */412412- if (rz_ssi_is_dma_enabled(ssi))413413- dmaengine_terminate_async(strm->dma_ch);418418+ if (rz_ssi_is_dma_enabled(ssi)) {419419+ if (ssi->playback.dma_ch)420420+ dmaengine_terminate_async(ssi->playback.dma_ch);421421+ if (ssi->capture.dma_ch)422422+ dmaengine_terminate_async(ssi->capture.dma_ch);423423+ }414424415425 rz_ssi_set_idle(ssi);416426···678680 */679681 return 0;680682681681- dir = rz_ssi_stream_is_play(ssi, substream) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;683683+ dir = rz_ssi_stream_is_play(substream) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;682684683685 /* Always transfer 1 period */684686 amount = runtime->period_size;···782784 return -ENODEV;783785}784786787787+static int rz_ssi_trigger_resume(struct rz_ssi_priv *ssi)788788+{789789+ int ret;790790+791791+ if (rz_ssi_is_stream_running(&ssi->playback) ||792792+ rz_ssi_is_stream_running(&ssi->capture))793793+ return 0;794794+795795+ ret = rz_ssi_swreset(ssi);796796+ if (ret)797797+ return ret;798798+799799+ return rz_ssi_clk_setup(ssi, ssi->hw_params_cache.rate,800800+ ssi->hw_params_cache.channels);801801+}802802+803803+static void rz_ssi_streams_suspend(struct rz_ssi_priv *ssi)804804+{805805+ if (rz_ssi_is_stream_running(&ssi->playback) ||806806+ rz_ssi_is_stream_running(&ssi->capture))807807+ return;808808+809809+ ssi->playback.dma_buffer_pos = 0;810810+ ssi->capture.dma_buffer_pos = 0;811811+}812812+785813static int rz_ssi_dai_trigger(struct snd_pcm_substream *substream, int cmd,786814 struct snd_soc_dai *dai)787815{···816792 int ret = 0, i, num_transfer = 1;817793818794 switch (cmd) {819819- case SNDRV_PCM_TRIGGER_START:820820- /* Soft Reset */821821- if (!rz_ssi_is_stream_running(&ssi->playback) &&822822- !rz_ssi_is_stream_running(&ssi->capture)) {823823- rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, SSIFCR_SSIRST);824824- rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, 0);825825- udelay(5);826826- }795795+ case SNDRV_PCM_TRIGGER_RESUME:796796+ ret = rz_ssi_trigger_resume(ssi);797797+ if (ret)798798+ return ret;827799828828- rz_ssi_stream_init(strm, substream);800800+ fallthrough;801801+802802+ case SNDRV_PCM_TRIGGER_START:803803+ if (cmd == SNDRV_PCM_TRIGGER_START)804804+ rz_ssi_stream_init(strm, substream);829805830806 if (ssi->dma_rt) {831807 bool is_playback;832808833833- is_playback = rz_ssi_stream_is_play(ssi, substream);809809+ is_playback = rz_ssi_stream_is_play(substream);834810 ret = rz_ssi_dma_slave_config(ssi, ssi->playback.dma_ch,835811 is_playback);836812 /* Fallback to pio */···853829854830 ret = rz_ssi_start(ssi, strm);855831 break;832832+833833+ case SNDRV_PCM_TRIGGER_SUSPEND:834834+ rz_ssi_stop(ssi, strm);835835+ rz_ssi_streams_suspend(ssi);836836+ break;837837+856838 case SNDRV_PCM_TRIGGER_STOP:857839 rz_ssi_stop(ssi, strm);858840 rz_ssi_stream_quit(ssi, strm);···955925 SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;956926 unsigned int channels = params_channels(params);957927 unsigned int rate = params_rate(params);928928+ int ret;958929959930 if (sample_bits != 16) {960931 dev_err(ssi->dev, "Unsupported sample width: %d\n",···982951 rz_ssi_cache_hw_params(ssi, rate, channels, strm->sample_width,983952 sample_bits);984953954954+ ret = rz_ssi_swreset(ssi);955955+ if (ret)956956+ return ret;957957+985958 return rz_ssi_clk_setup(ssi, rate, channels);986959}987960···998963static const struct snd_pcm_hardware rz_ssi_pcm_hardware = {999964 .info = SNDRV_PCM_INFO_INTERLEAVED |1000965 SNDRV_PCM_INFO_MMAP |10011001- SNDRV_PCM_INFO_MMAP_VALID,966966+ SNDRV_PCM_INFO_MMAP_VALID |967967+ SNDRV_PCM_INFO_RESUME,1002968 .buffer_bytes_max = PREALLOC_BUFFER,1003969 .period_bytes_min = 32,1004970 .period_bytes_max = 8192,···1022986static snd_pcm_uframes_t rz_ssi_pcm_pointer(struct snd_soc_component *component,1023987 struct snd_pcm_substream *substream)1024988{10251025- struct snd_soc_dai *dai = rz_ssi_get_dai(substream);989989+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);990990+ struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);1026991 struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai);1027992 struct rz_ssi_stream *strm = rz_ssi_stream_get(ssi, substream);1028993···1068103110691032static int rz_ssi_probe(struct platform_device *pdev)10701033{10341034+ struct device *dev = &pdev->dev;10711035 struct rz_ssi_priv *ssi;10721036 struct clk *audio_clk;10731037 struct resource *res;10741038 int ret;1075103910761076- ssi = devm_kzalloc(&pdev->dev, sizeof(*ssi), GFP_KERNEL);10401040+ ssi = devm_kzalloc(dev, sizeof(*ssi), GFP_KERNEL);10771041 if (!ssi)10781042 return -ENOMEM;1079104310801080- ssi->pdev = pdev;10811081- ssi->dev = &pdev->dev;10441044+ ssi->dev = dev;10821045 ssi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);10831046 if (IS_ERR(ssi->base))10841047 return PTR_ERR(ssi->base);1085104810861049 ssi->phys = res->start;10871087- ssi->clk = devm_clk_get(&pdev->dev, "ssi");10501050+ ssi->clk = devm_clk_get(dev, "ssi");10881051 if (IS_ERR(ssi->clk))10891052 return PTR_ERR(ssi->clk);1090105310911091- ssi->sfr_clk = devm_clk_get(&pdev->dev, "ssi_sfr");10541054+ ssi->sfr_clk = devm_clk_get(dev, "ssi_sfr");10921055 if (IS_ERR(ssi->sfr_clk))10931056 return PTR_ERR(ssi->sfr_clk);1094105710951095- audio_clk = devm_clk_get(&pdev->dev, "audio_clk1");10581058+ audio_clk = devm_clk_get(dev, "audio_clk1");10961059 if (IS_ERR(audio_clk))10971060 return dev_err_probe(&pdev->dev, PTR_ERR(audio_clk),10981061 "no audio clk1");1099106211001063 ssi->audio_clk_1 = clk_get_rate(audio_clk);11011101- audio_clk = devm_clk_get(&pdev->dev, "audio_clk2");10641064+ audio_clk = devm_clk_get(dev, "audio_clk2");11021065 if (IS_ERR(audio_clk))11031066 return dev_err_probe(&pdev->dev, PTR_ERR(audio_clk),11041067 "no audio clk2");···11111074 ssi->audio_mck = ssi->audio_clk_1 ? ssi->audio_clk_1 : ssi->audio_clk_2;1112107511131076 /* Detect DMA support */11141114- ret = rz_ssi_dma_request(ssi, &pdev->dev);10771077+ ret = rz_ssi_dma_request(ssi, dev);11151078 if (ret < 0) {11161116- dev_warn(&pdev->dev, "DMA not available, using PIO\n");10791079+ dev_warn(dev, "DMA not available, using PIO\n");11171080 ssi->playback.transfer = rz_ssi_pio_send;11181081 ssi->capture.transfer = rz_ssi_pio_recv;11191082 } else {11201120- dev_info(&pdev->dev, "DMA enabled");10831083+ dev_info(dev, "DMA enabled");11211084 ssi->playback.transfer = rz_ssi_dma_transfer;11221085 ssi->capture.transfer = rz_ssi_dma_transfer;11231086 }···11261089 ssi->capture.priv = ssi;1127109011281091 spin_lock_init(&ssi->lock);11291129- dev_set_drvdata(&pdev->dev, ssi);10921092+ dev_set_drvdata(dev, ssi);1130109311311094 /* Error Interrupt */11321095 ssi->irq_int = platform_get_irq_byname(pdev, "int_req");11331096 if (ssi->irq_int < 0) {11341134- rz_ssi_release_dma_channels(ssi);11351135- return ssi->irq_int;10971097+ ret = ssi->irq_int;10981098+ goto err_release_dma_chs;11361099 }1137110011381138- ret = devm_request_irq(&pdev->dev, ssi->irq_int, &rz_ssi_interrupt,11391139- 0, dev_name(&pdev->dev), ssi);11011101+ ret = devm_request_irq(dev, ssi->irq_int, &rz_ssi_interrupt,11021102+ 0, dev_name(dev), ssi);11401103 if (ret < 0) {11411141- rz_ssi_release_dma_channels(ssi);11421142- return dev_err_probe(&pdev->dev, ret,11431143- "irq request error (int_req)\n");11041104+ dev_err_probe(dev, ret, "irq request error (int_req)\n");11051105+ goto err_release_dma_chs;11441106 }1145110711461108 if (!rz_ssi_is_dma_enabled(ssi)) {···11511115 if (ssi->irq_rt < 0)11521116 return ssi->irq_rt;1153111711541154- ret = devm_request_irq(&pdev->dev, ssi->irq_rt,11181118+ ret = devm_request_irq(dev, ssi->irq_rt,11551119 &rz_ssi_interrupt, 0,11561156- dev_name(&pdev->dev), ssi);11201120+ dev_name(dev), ssi);11571121 if (ret < 0)11581158- return dev_err_probe(&pdev->dev, ret,11221122+ return dev_err_probe(dev, ret,11591123 "irq request error (dma_rt)\n");11601124 } else {11611125 if (ssi->irq_tx < 0)···11641128 if (ssi->irq_rx < 0)11651129 return ssi->irq_rx;1166113011671167- ret = devm_request_irq(&pdev->dev, ssi->irq_tx,11311131+ ret = devm_request_irq(dev, ssi->irq_tx,11681132 &rz_ssi_interrupt, 0,11691169- dev_name(&pdev->dev), ssi);11331133+ dev_name(dev), ssi);11701134 if (ret < 0)11711171- return dev_err_probe(&pdev->dev, ret,11351135+ return dev_err_probe(dev, ret,11721136 "irq request error (dma_tx)\n");1173113711741174- ret = devm_request_irq(&pdev->dev, ssi->irq_rx,11381138+ ret = devm_request_irq(dev, ssi->irq_rx,11751139 &rz_ssi_interrupt, 0,11761176- dev_name(&pdev->dev), ssi);11401140+ dev_name(dev), ssi);11771141 if (ret < 0)11781178- return dev_err_probe(&pdev->dev, ret,11421142+ return dev_err_probe(dev, ret,11791143 "irq request error (dma_rx)\n");11801144 }11811145 }1182114611831183- ssi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);11471147+ ssi->rstc = devm_reset_control_get_exclusive(dev, NULL);11841148 if (IS_ERR(ssi->rstc)) {11851149 ret = PTR_ERR(ssi->rstc);11861186- goto err_reset;11501150+ goto err_release_dma_chs;11871151 }1188115211891189- reset_control_deassert(ssi->rstc);11901190- pm_runtime_enable(&pdev->dev);11911191- ret = pm_runtime_resume_and_get(&pdev->dev);11531153+ /* Default 0 for power saving. Can be overridden via sysfs. */11541154+ pm_runtime_set_autosuspend_delay(dev, 0);11551155+ pm_runtime_use_autosuspend(dev);11561156+ ret = devm_pm_runtime_enable(dev);11921157 if (ret < 0) {11931193- dev_err(&pdev->dev, "pm_runtime_resume_and_get failed\n");11941194- goto err_pm;11581158+ dev_err(dev, "Failed to enable runtime PM!\n");11591159+ goto err_release_dma_chs;11951160 }1196116111971197- ret = devm_snd_soc_register_component(&pdev->dev, &rz_ssi_soc_component,11621162+ ret = devm_snd_soc_register_component(dev, &rz_ssi_soc_component,11981163 rz_ssi_soc_dai,11991164 ARRAY_SIZE(rz_ssi_soc_dai));12001165 if (ret < 0) {12011201- dev_err(&pdev->dev, "failed to register snd component\n");12021202- goto err_snd_soc;11661166+ dev_err(dev, "failed to register snd component\n");11671167+ goto err_release_dma_chs;12031168 }1204116912051170 return 0;1206117112071207-err_snd_soc:12081208- pm_runtime_put(ssi->dev);12091209-err_pm:12101210- pm_runtime_disable(ssi->dev);12111211- reset_control_assert(ssi->rstc);12121212-err_reset:11721172+err_release_dma_chs:12131173 rz_ssi_release_dma_channels(ssi);1214117412151175 return ret;···1217118512181186 rz_ssi_release_dma_channels(ssi);1219118712201220- pm_runtime_put(ssi->dev);12211221- pm_runtime_disable(ssi->dev);12221188 reset_control_assert(ssi->rstc);12231189}12241190···12261196};12271197MODULE_DEVICE_TABLE(of, rz_ssi_of_match);1228119811991199+static int rz_ssi_runtime_suspend(struct device *dev)12001200+{12011201+ struct rz_ssi_priv *ssi = dev_get_drvdata(dev);12021202+12031203+ return reset_control_assert(ssi->rstc);12041204+}12051205+12061206+static int rz_ssi_runtime_resume(struct device *dev)12071207+{12081208+ struct rz_ssi_priv *ssi = dev_get_drvdata(dev);12091209+12101210+ return reset_control_deassert(ssi->rstc);12111211+}12121212+12131213+static const struct dev_pm_ops rz_ssi_pm_ops = {12141214+ RUNTIME_PM_OPS(rz_ssi_runtime_suspend, rz_ssi_runtime_resume, NULL)12151215+ SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)12161216+};12171217+12291218static struct platform_driver rz_ssi_driver = {12301219 .driver = {12311220 .name = "rz-ssi-pcm-audio",12321221 .of_match_table = rz_ssi_of_match,12221222+ .pm = pm_ptr(&rz_ssi_pm_ops),12331223 },12341224 .probe = rz_ssi_probe,12351225 .remove = rz_ssi_remove,