···18801880 */18811881bool regmap_can_raw_write(struct regmap *map)18821882{18831883- return map->bus && map->bus->write && map->format.format_val &&18841884- map->format.format_reg;18831883+ return map->write && map->format.format_val && map->format.format_reg;18851884}18861885EXPORT_SYMBOL_GPL(regmap_can_raw_write);18871886···21542155 size_t write_len;21552156 int ret;2156215721572157- if (!map->bus)21582158- return -EINVAL;21592159- if (!map->bus->write)21582158+ if (!map->write)21602159 return -ENOTSUPP;21602160+21612161 if (val_len % map->format.val_bytes)21622162 return -EINVAL;21632163 if (!IS_ALIGNED(reg, map->reg_stride))···22982300 * Some devices don't support bulk write, for them we have a series of22992301 * single write operations.23002302 */23012301- if (!map->bus || !map->format.parse_inplace) {23032303+ if (!map->write || !map->format.parse_inplace) {23022304 map->lock(map->lock_arg);23032305 for (i = 0; i < val_count; i++) {23042306 unsigned int ival;···29242926 size_t read_len;29252927 int ret;2926292829292929+ if (!map->read)29302930+ return -ENOTSUPP;29312931+29272932 if (val_len % map->format.val_bytes)29282933 return -EINVAL;29292934 if (!IS_ALIGNED(reg, map->reg_stride))···30403039 if (val_count == 0)30413040 return -EINVAL;3042304130433043- if (map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) {30423042+ if (map->read && map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) {30443043 ret = regmap_raw_read(map, reg, val, val_bytes * val_count);30453044 if (ret != 0)30463045 return ret;
···1313#include <linux/of_gpio.h>1414#include <linux/of_device.h>1515#include <linux/clk.h>1616+#include <linux/pinctrl/consumer.h>1617#include <linux/pm_runtime.h>1718#include <linux/regmap.h>1819#include <linux/spinlock.h>···5554 const struct rk_i2s_pins *pins;5655 unsigned int bclk_ratio;5756 spinlock_t lock; /* tx/rx lock */5757+ struct pinctrl *pinctrl;5858+ struct pinctrl_state *bclk_on;5959+ struct pinctrl_state *bclk_off;5860};6161+6262+static int i2s_pinctrl_select_bclk_on(struct rk_i2s_dev *i2s)6363+{6464+ int ret = 0;6565+6666+ if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_on))6767+ ret = pinctrl_select_state(i2s->pinctrl,6868+ i2s->bclk_on);6969+7070+ if (ret)7171+ dev_err(i2s->dev, "bclk enable failed %d\n", ret);7272+7373+ return ret;7474+}7575+7676+static int i2s_pinctrl_select_bclk_off(struct rk_i2s_dev *i2s)7777+{7878+7979+ int ret = 0;8080+8181+ if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_off))8282+ ret = pinctrl_select_state(i2s->pinctrl,8383+ i2s->bclk_off);8484+8585+ if (ret)8686+ dev_err(i2s->dev, "bclk disable failed %d\n", ret);8787+8888+ return ret;8989+}59906091static int i2s_runtime_suspend(struct device *dev)6192{···12592 return snd_soc_dai_get_drvdata(dai);12693}12794128128-static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)9595+static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)12996{13097 unsigned int val = 0;13198 int retry = 10;9999+ int ret = 0;132100133101 spin_lock(&i2s->lock);134102 if (on) {135135- regmap_update_bits(i2s->regmap, I2S_DMACR,136136- I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);103103+ ret = regmap_update_bits(i2s->regmap, I2S_DMACR,104104+ I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);105105+ if (ret < 0)106106+ goto end;137107138138- regmap_update_bits(i2s->regmap, I2S_XFER,139139- I2S_XFER_TXS_START | I2S_XFER_RXS_START,140140- I2S_XFER_TXS_START | I2S_XFER_RXS_START);108108+ ret = regmap_update_bits(i2s->regmap, I2S_XFER,109109+ I2S_XFER_TXS_START | I2S_XFER_RXS_START,110110+ I2S_XFER_TXS_START | I2S_XFER_RXS_START);111111+ if (ret < 0)112112+ goto end;141113142114 i2s->tx_start = true;143115 } else {144116 i2s->tx_start = false;145117146146- regmap_update_bits(i2s->regmap, I2S_DMACR,147147- I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);118118+ ret = regmap_update_bits(i2s->regmap, I2S_DMACR,119119+ I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);120120+ if (ret < 0)121121+ goto end;148122149123 if (!i2s->rx_start) {150150- regmap_update_bits(i2s->regmap, I2S_XFER,151151- I2S_XFER_TXS_START |152152- I2S_XFER_RXS_START,153153- I2S_XFER_TXS_STOP |154154- I2S_XFER_RXS_STOP);124124+ ret = regmap_update_bits(i2s->regmap, I2S_XFER,125125+ I2S_XFER_TXS_START |126126+ I2S_XFER_RXS_START,127127+ I2S_XFER_TXS_STOP |128128+ I2S_XFER_RXS_STOP);129129+ if (ret < 0)130130+ goto end;155131156132 udelay(150);157157- regmap_update_bits(i2s->regmap, I2S_CLR,158158- I2S_CLR_TXC | I2S_CLR_RXC,159159- I2S_CLR_TXC | I2S_CLR_RXC);133133+ ret = regmap_update_bits(i2s->regmap, I2S_CLR,134134+ I2S_CLR_TXC | I2S_CLR_RXC,135135+ I2S_CLR_TXC | I2S_CLR_RXC);136136+ if (ret < 0)137137+ goto end;160138161139 regmap_read(i2s->regmap, I2S_CLR, &val);162140···182138 }183139 }184140 }141141+end:185142 spin_unlock(&i2s->lock);143143+ if (ret < 0)144144+ dev_err(i2s->dev, "lrclk update failed\n");145145+146146+ return ret;186147}187148188188-static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)149149+static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)189150{190151 unsigned int val = 0;191152 int retry = 10;153153+ int ret = 0;192154193155 spin_lock(&i2s->lock);194156 if (on) {195195- regmap_update_bits(i2s->regmap, I2S_DMACR,157157+ ret = regmap_update_bits(i2s->regmap, I2S_DMACR,196158 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);159159+ if (ret < 0)160160+ goto end;197161198198- regmap_update_bits(i2s->regmap, I2S_XFER,162162+ ret = regmap_update_bits(i2s->regmap, I2S_XFER,199163 I2S_XFER_TXS_START | I2S_XFER_RXS_START,200164 I2S_XFER_TXS_START | I2S_XFER_RXS_START);165165+ if (ret < 0)166166+ goto end;201167202168 i2s->rx_start = true;203169 } else {204170 i2s->rx_start = false;205171206206- regmap_update_bits(i2s->regmap, I2S_DMACR,172172+ ret = regmap_update_bits(i2s->regmap, I2S_DMACR,207173 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE);174174+ if (ret < 0)175175+ goto end;208176209177 if (!i2s->tx_start) {210210- regmap_update_bits(i2s->regmap, I2S_XFER,178178+ ret = regmap_update_bits(i2s->regmap, I2S_XFER,211179 I2S_XFER_TXS_START |212180 I2S_XFER_RXS_START,213181 I2S_XFER_TXS_STOP |214182 I2S_XFER_RXS_STOP);215215-183183+ if (ret < 0)184184+ goto end;216185 udelay(150);217217- regmap_update_bits(i2s->regmap, I2S_CLR,186186+ ret = regmap_update_bits(i2s->regmap, I2S_CLR,218187 I2S_CLR_TXC | I2S_CLR_RXC,219188 I2S_CLR_TXC | I2S_CLR_RXC);220220-189189+ if (ret < 0)190190+ goto end;221191 regmap_read(i2s->regmap, I2S_CLR, &val);222222-223192 /* Should wait for clear operation to finish */224193 while (val) {225194 regmap_read(i2s->regmap, I2S_CLR, &val);···244187 }245188 }246189 }190190+end:247191 spin_unlock(&i2s->lock);192192+ if (ret < 0)193193+ dev_err(i2s->dev, "lrclk update failed\n");194194+195195+ return ret;248196}249197250198static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,···487425 case SNDRV_PCM_TRIGGER_RESUME:488426 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:489427 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)490490- rockchip_snd_rxctrl(i2s, 1);428428+ ret = rockchip_snd_rxctrl(i2s, 1);491429 else492492- rockchip_snd_txctrl(i2s, 1);430430+ ret = rockchip_snd_txctrl(i2s, 1);431431+ /* Do not turn on bclk if lrclk open fails. */432432+ if (ret < 0)433433+ return ret;434434+ i2s_pinctrl_select_bclk_on(i2s);493435 break;494436 case SNDRV_PCM_TRIGGER_SUSPEND:495437 case SNDRV_PCM_TRIGGER_STOP:496438 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:497497- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)498498- rockchip_snd_rxctrl(i2s, 0);499499- else500500- rockchip_snd_txctrl(i2s, 0);439439+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {440440+ if (!i2s->tx_start)441441+ i2s_pinctrl_select_bclk_off(i2s);442442+ ret = rockchip_snd_rxctrl(i2s, 0);443443+ } else {444444+ if (!i2s->rx_start)445445+ i2s_pinctrl_select_bclk_off(i2s);446446+ ret = rockchip_snd_txctrl(i2s, 0);447447+ }501448 break;502449 default:503450 ret = -EINVAL;···807736 }808737809738 i2s->bclk_ratio = 64;739739+ i2s->pinctrl = devm_pinctrl_get(&pdev->dev);740740+ if (IS_ERR(i2s->pinctrl))741741+ dev_err(&pdev->dev, "failed to find i2s pinctrl\n");742742+743743+ i2s->bclk_on = pinctrl_lookup_state(i2s->pinctrl,744744+ "bclk_on");745745+ if (IS_ERR_OR_NULL(i2s->bclk_on))746746+ dev_err(&pdev->dev, "failed to find i2s default state\n");747747+ else748748+ dev_dbg(&pdev->dev, "find i2s bclk state\n");749749+750750+ i2s->bclk_off = pinctrl_lookup_state(i2s->pinctrl,751751+ "bclk_off");752752+ if (IS_ERR_OR_NULL(i2s->bclk_off))753753+ dev_err(&pdev->dev, "failed to find i2s gpio state\n");754754+ else755755+ dev_dbg(&pdev->dev, "find i2s bclk_off state\n");756756+757757+ i2s_pinctrl_select_bclk_off(i2s);758758+759759+ i2s->playback_dma_data.addr = res->start + I2S_TXDR;760760+ i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;761761+ i2s->playback_dma_data.maxburst = 4;762762+763763+ i2s->capture_dma_data.addr = res->start + I2S_RXDR;764764+ i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;765765+ i2s->capture_dma_data.maxburst = 4;810766811767 dev_set_drvdata(&pdev->dev, i2s);812768
+2-1
sound/soc/sof/intel/hda-loader.c
···395395 struct snd_dma_buffer dmab;396396 int ret, ret1, i;397397398398- if (hda->imrboot_supported && !sdev->first_boot) {398398+ if (sdev->system_suspend_target < SOF_SUSPEND_S4 &&399399+ hda->imrboot_supported && !sdev->first_boot) {399400 dev_dbg(sdev->dev, "IMR restore supported, booting from IMR directly\n");400401 hda->boot_iteration = 0;401402 ret = hda_dsp_boot_imr(sdev);
+1-73
sound/soc/sof/intel/hda-pcm.c
···192192 goto found;193193 }194194195195- switch (sof_hda_position_quirk) {196196- case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY:197197- /*198198- * This legacy code, inherited from the Skylake driver,199199- * mixes DPIB registers and DPIB DDR updates and200200- * does not seem to follow any known hardware recommendations.201201- * It's not clear e.g. why there is a different flow202202- * for capture and playback, the only information that matters is203203- * what traffic class is used, and on all SOF-enabled platforms204204- * only VC0 is supported so the work-around was likely not necessary205205- * and quite possibly wrong.206206- */207207-208208- /* DPIB/posbuf position mode:209209- * For Playback, Use DPIB register from HDA space which210210- * reflects the actual data transferred.211211- * For Capture, Use the position buffer for pointer, as DPIB212212- * is not accurate enough, its update may be completed213213- * earlier than the data written to DDR.214214- */215215- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {216216- pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,217217- AZX_REG_VS_SDXDPIB_XBASE +218218- (AZX_REG_VS_SDXDPIB_XINTERVAL *219219- hstream->index));220220- } else {221221- /*222222- * For capture stream, we need more workaround to fix the223223- * position incorrect issue:224224- *225225- * 1. Wait at least 20us before reading position buffer after226226- * the interrupt generated(IOC), to make sure position update227227- * happens on frame boundary i.e. 20.833uSec for 48KHz.228228- * 2. Perform a dummy Read to DPIB register to flush DMA229229- * position value.230230- * 3. Read the DMA Position from posbuf. Now the readback231231- * value should be >= period boundary.232232- */233233- usleep_range(20, 21);234234- snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,235235- AZX_REG_VS_SDXDPIB_XBASE +236236- (AZX_REG_VS_SDXDPIB_XINTERVAL *237237- hstream->index));238238- pos = snd_hdac_stream_get_pos_posbuf(hstream);239239- }240240- break;241241- case SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS:242242- /*243243- * In case VC1 traffic is disabled this is the recommended option244244- */245245- pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,246246- AZX_REG_VS_SDXDPIB_XBASE +247247- (AZX_REG_VS_SDXDPIB_XINTERVAL *248248- hstream->index));249249- break;250250- case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE:251251- /*252252- * This is the recommended option when VC1 is enabled.253253- * While this isn't needed for SOF platforms it's added for254254- * consistency and debug.255255- */256256- pos = snd_hdac_stream_get_pos_posbuf(hstream);257257- break;258258- default:259259- dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n",260260- sof_hda_position_quirk);261261- pos = 0;262262- break;263263- }264264-265265- if (pos >= hstream->bufsize)266266- pos = 0;267267-195195+ pos = hda_dsp_stream_get_position(hstream, substream->stream, true);268196found:269197 pos = bytes_to_frames(substream->runtime, pos);270198
+90-4
sound/soc/sof/intel/hda-stream.c
···707707}708708709709static void710710-hda_dsp_set_bytes_transferred(struct hdac_stream *hstream, u64 buffer_size)710710+hda_dsp_compr_bytes_transferred(struct hdac_stream *hstream, int direction)711711{712712+ u64 buffer_size = hstream->bufsize;712713 u64 prev_pos, pos, num_bytes;713714714715 div64_u64_rem(hstream->curr_pos, buffer_size, &prev_pos);715715- pos = snd_hdac_stream_get_pos_posbuf(hstream);716716+ pos = hda_dsp_stream_get_position(hstream, direction, false);716717717718 if (pos < prev_pos)718719 num_bytes = (buffer_size - prev_pos) + pos;···749748 if (s->substream && sof_hda->no_ipc_position) {750749 snd_sof_pcm_period_elapsed(s->substream);751750 } else if (s->cstream) {752752- hda_dsp_set_bytes_transferred(s,753753- s->cstream->runtime->buffer_size);751751+ hda_dsp_compr_bytes_transferred(s, s->cstream->direction);754752 snd_compr_fragment_elapsed(s->cstream);755753 }756754 }···10081008 hext_stream);10091009 devm_kfree(sdev->dev, hda_stream);10101010 }10111011+}10121012+10131013+snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream,10141014+ int direction, bool can_sleep)10151015+{10161016+ struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);10171017+ struct sof_intel_hda_stream *hda_stream = hstream_to_sof_hda_stream(hext_stream);10181018+ struct snd_sof_dev *sdev = hda_stream->sdev;10191019+ snd_pcm_uframes_t pos;10201020+10211021+ switch (sof_hda_position_quirk) {10221022+ case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY:10231023+ /*10241024+ * This legacy code, inherited from the Skylake driver,10251025+ * mixes DPIB registers and DPIB DDR updates and10261026+ * does not seem to follow any known hardware recommendations.10271027+ * It's not clear e.g. why there is a different flow10281028+ * for capture and playback, the only information that matters is10291029+ * what traffic class is used, and on all SOF-enabled platforms10301030+ * only VC0 is supported so the work-around was likely not necessary10311031+ * and quite possibly wrong.10321032+ */10331033+10341034+ /* DPIB/posbuf position mode:10351035+ * For Playback, Use DPIB register from HDA space which10361036+ * reflects the actual data transferred.10371037+ * For Capture, Use the position buffer for pointer, as DPIB10381038+ * is not accurate enough, its update may be completed10391039+ * earlier than the data written to DDR.10401040+ */10411041+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {10421042+ pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,10431043+ AZX_REG_VS_SDXDPIB_XBASE +10441044+ (AZX_REG_VS_SDXDPIB_XINTERVAL *10451045+ hstream->index));10461046+ } else {10471047+ /*10481048+ * For capture stream, we need more workaround to fix the10491049+ * position incorrect issue:10501050+ *10511051+ * 1. Wait at least 20us before reading position buffer after10521052+ * the interrupt generated(IOC), to make sure position update10531053+ * happens on frame boundary i.e. 20.833uSec for 48KHz.10541054+ * 2. Perform a dummy Read to DPIB register to flush DMA10551055+ * position value.10561056+ * 3. Read the DMA Position from posbuf. Now the readback10571057+ * value should be >= period boundary.10581058+ */10591059+ if (can_sleep)10601060+ usleep_range(20, 21);10611061+10621062+ snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,10631063+ AZX_REG_VS_SDXDPIB_XBASE +10641064+ (AZX_REG_VS_SDXDPIB_XINTERVAL *10651065+ hstream->index));10661066+ pos = snd_hdac_stream_get_pos_posbuf(hstream);10671067+ }10681068+ break;10691069+ case SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS:10701070+ /*10711071+ * In case VC1 traffic is disabled this is the recommended option10721072+ */10731073+ pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,10741074+ AZX_REG_VS_SDXDPIB_XBASE +10751075+ (AZX_REG_VS_SDXDPIB_XINTERVAL *10761076+ hstream->index));10771077+ break;10781078+ case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE:10791079+ /*10801080+ * This is the recommended option when VC1 is enabled.10811081+ * While this isn't needed for SOF platforms it's added for10821082+ * consistency and debug.10831083+ */10841084+ pos = snd_hdac_stream_get_pos_posbuf(hstream);10851085+ break;10861086+ default:10871087+ dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n",10881088+ sof_hda_position_quirk);10891089+ pos = 0;10901090+ break;10911091+ }10921092+10931093+ if (pos >= hstream->bufsize)10941094+ pos = 0;10951095+10961096+ return pos;10111097}
+3
sound/soc/sof/intel/hda.h
···565565bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev);566566bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev);567567568568+snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream,569569+ int direction, bool can_sleep);570570+568571struct hdac_ext_stream *569572 hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags);570573int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag);
+1-1
sound/soc/sof/mediatek/mt8186/mt8186.c
···392392 PLATFORM_DEVID_NONE,393393 pdev, sizeof(*pdev));394394 if (IS_ERR(priv->ipc_dev)) {395395- ret = IS_ERR(priv->ipc_dev);395395+ ret = PTR_ERR(priv->ipc_dev);396396 dev_err(sdev->dev, "failed to create mtk-adsp-ipc device\n");397397 goto err_adsp_off;398398 }
+20-1
sound/soc/sof/pm.c
···2323 u32 target_dsp_state;24242525 switch (sdev->system_suspend_target) {2626+ case SOF_SUSPEND_S5:2727+ case SOF_SUSPEND_S4:2828+ /* DSP should be in D3 if the system is suspending to S3+ */2629 case SOF_SUSPEND_S3:2730 /* DSP should be in D3 if the system is suspending to S3 */2831 target_dsp_state = SOF_DSP_PM_D3;···338335 return 0;339336340337#if defined(CONFIG_ACPI)341341- if (acpi_target_system_state() == ACPI_STATE_S0)338338+ switch (acpi_target_system_state()) {339339+ case ACPI_STATE_S0:342340 sdev->system_suspend_target = SOF_SUSPEND_S0IX;341341+ break;342342+ case ACPI_STATE_S1:343343+ case ACPI_STATE_S2:344344+ case ACPI_STATE_S3:345345+ sdev->system_suspend_target = SOF_SUSPEND_S3;346346+ break;347347+ case ACPI_STATE_S4:348348+ sdev->system_suspend_target = SOF_SUSPEND_S4;349349+ break;350350+ case ACPI_STATE_S5:351351+ sdev->system_suspend_target = SOF_SUSPEND_S5;352352+ break;353353+ default:354354+ break;355355+ }343356#endif344357345358 return 0;