Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * mtk-afe-fe-dais.c  --  Mediatek afe fe dai operator
0004  *
0005  * Copyright (c) 2016 MediaTek Inc.
0006  * Author: Garlic Tseng <garlic.tseng@mediatek.com>
0007  */
0008 
0009 #include <linux/io.h>
0010 #include <linux/module.h>
0011 #include <linux/pm_runtime.h>
0012 #include <linux/regmap.h>
0013 #include <sound/soc.h>
0014 #include "mtk-afe-platform-driver.h"
0015 #include <sound/pcm_params.h>
0016 #include "mtk-afe-fe-dai.h"
0017 #include "mtk-base-afe.h"
0018 
0019 #define AFE_BASE_END_OFFSET 8
0020 
0021 static int mtk_regmap_update_bits(struct regmap *map, int reg,
0022                unsigned int mask,
0023                unsigned int val, int shift)
0024 {
0025     if (reg < 0 || WARN_ON_ONCE(shift < 0))
0026         return 0;
0027     return regmap_update_bits(map, reg, mask << shift, val << shift);
0028 }
0029 
0030 static int mtk_regmap_write(struct regmap *map, int reg, unsigned int val)
0031 {
0032     if (reg < 0)
0033         return 0;
0034     return regmap_write(map, reg, val);
0035 }
0036 
0037 int mtk_afe_fe_startup(struct snd_pcm_substream *substream,
0038                struct snd_soc_dai *dai)
0039 {
0040     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0041     struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0042     struct snd_pcm_runtime *runtime = substream->runtime;
0043     int memif_num = asoc_rtd_to_cpu(rtd, 0)->id;
0044     struct mtk_base_afe_memif *memif = &afe->memif[memif_num];
0045     const struct snd_pcm_hardware *mtk_afe_hardware = afe->mtk_afe_hardware;
0046     int ret;
0047 
0048     memif->substream = substream;
0049 
0050     snd_pcm_hw_constraint_step(substream->runtime, 0,
0051                    SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16);
0052     /* enable agent */
0053     mtk_regmap_update_bits(afe->regmap, memif->data->agent_disable_reg,
0054                    1, 0, memif->data->agent_disable_shift);
0055 
0056     snd_soc_set_runtime_hwparams(substream, mtk_afe_hardware);
0057 
0058     /*
0059      * Capture cannot use ping-pong buffer since hw_ptr at IRQ may be
0060      * smaller than period_size due to AFE's internal buffer.
0061      * This easily leads to overrun when avail_min is period_size.
0062      * One more period can hold the possible unread buffer.
0063      */
0064     if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
0065         int periods_max = mtk_afe_hardware->periods_max;
0066 
0067         ret = snd_pcm_hw_constraint_minmax(runtime,
0068                            SNDRV_PCM_HW_PARAM_PERIODS,
0069                            3, periods_max);
0070         if (ret < 0) {
0071             dev_err(afe->dev, "hw_constraint_minmax failed\n");
0072             return ret;
0073         }
0074     }
0075 
0076     ret = snd_pcm_hw_constraint_integer(runtime,
0077                         SNDRV_PCM_HW_PARAM_PERIODS);
0078     if (ret < 0)
0079         dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n");
0080 
0081     /* dynamic allocate irq to memif */
0082     if (memif->irq_usage < 0) {
0083         int irq_id = mtk_dynamic_irq_acquire(afe);
0084 
0085         if (irq_id != afe->irqs_size) {
0086             /* link */
0087             memif->irq_usage = irq_id;
0088         } else {
0089             dev_err(afe->dev, "%s() error: no more asys irq\n",
0090                 __func__);
0091             ret = -EBUSY;
0092         }
0093     }
0094     return ret;
0095 }
0096 EXPORT_SYMBOL_GPL(mtk_afe_fe_startup);
0097 
0098 void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream,
0099              struct snd_soc_dai *dai)
0100 {
0101     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0102     struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0103     struct mtk_base_afe_memif *memif = &afe->memif[asoc_rtd_to_cpu(rtd, 0)->id];
0104     int irq_id;
0105 
0106     irq_id = memif->irq_usage;
0107 
0108     mtk_regmap_update_bits(afe->regmap, memif->data->agent_disable_reg,
0109                    1, 1, memif->data->agent_disable_shift);
0110 
0111     if (!memif->const_irq) {
0112         mtk_dynamic_irq_release(afe, irq_id);
0113         memif->irq_usage = -1;
0114         memif->substream = NULL;
0115     }
0116 }
0117 EXPORT_SYMBOL_GPL(mtk_afe_fe_shutdown);
0118 
0119 int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
0120              struct snd_pcm_hw_params *params,
0121              struct snd_soc_dai *dai)
0122 {
0123     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0124     struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0125     int id = asoc_rtd_to_cpu(rtd, 0)->id;
0126     struct mtk_base_afe_memif *memif = &afe->memif[id];
0127     int ret;
0128     unsigned int channels = params_channels(params);
0129     unsigned int rate = params_rate(params);
0130     snd_pcm_format_t format = params_format(params);
0131 
0132     if (afe->request_dram_resource)
0133         afe->request_dram_resource(afe->dev);
0134 
0135     dev_dbg(afe->dev, "%s(), %s, ch %d, rate %d, fmt %d, dma_addr %pad, dma_area %p, dma_bytes 0x%zx\n",
0136         __func__, memif->data->name,
0137         channels, rate, format,
0138         &substream->runtime->dma_addr,
0139         substream->runtime->dma_area,
0140         substream->runtime->dma_bytes);
0141 
0142     memset_io((void __force __iomem *)substream->runtime->dma_area, 0,
0143           substream->runtime->dma_bytes);
0144 
0145     /* set addr */
0146     ret = mtk_memif_set_addr(afe, id,
0147                  substream->runtime->dma_area,
0148                  substream->runtime->dma_addr,
0149                  substream->runtime->dma_bytes);
0150     if (ret) {
0151         dev_err(afe->dev, "%s(), error, id %d, set addr, ret %d\n",
0152             __func__, id, ret);
0153         return ret;
0154     }
0155 
0156     /* set channel */
0157     ret = mtk_memif_set_channel(afe, id, channels);
0158     if (ret) {
0159         dev_err(afe->dev, "%s(), error, id %d, set channel %d, ret %d\n",
0160             __func__, id, channels, ret);
0161         return ret;
0162     }
0163 
0164     /* set rate */
0165     ret = mtk_memif_set_rate_substream(substream, id, rate);
0166     if (ret) {
0167         dev_err(afe->dev, "%s(), error, id %d, set rate %d, ret %d\n",
0168             __func__, id, rate, ret);
0169         return ret;
0170     }
0171 
0172     /* set format */
0173     ret = mtk_memif_set_format(afe, id, format);
0174     if (ret) {
0175         dev_err(afe->dev, "%s(), error, id %d, set format %d, ret %d\n",
0176             __func__, id, format, ret);
0177         return ret;
0178     }
0179 
0180     return 0;
0181 }
0182 EXPORT_SYMBOL_GPL(mtk_afe_fe_hw_params);
0183 
0184 int mtk_afe_fe_hw_free(struct snd_pcm_substream *substream,
0185                struct snd_soc_dai *dai)
0186 {
0187     struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0188 
0189     if (afe->release_dram_resource)
0190         afe->release_dram_resource(afe->dev);
0191 
0192     return 0;
0193 }
0194 EXPORT_SYMBOL_GPL(mtk_afe_fe_hw_free);
0195 
0196 int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,
0197                struct snd_soc_dai *dai)
0198 {
0199     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0200     struct snd_pcm_runtime * const runtime = substream->runtime;
0201     struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0202     int id = asoc_rtd_to_cpu(rtd, 0)->id;
0203     struct mtk_base_afe_memif *memif = &afe->memif[id];
0204     struct mtk_base_afe_irq *irqs = &afe->irqs[memif->irq_usage];
0205     const struct mtk_base_irq_data *irq_data = irqs->irq_data;
0206     unsigned int counter = runtime->period_size;
0207     int fs;
0208     int ret;
0209 
0210     dev_dbg(afe->dev, "%s %s cmd=%d\n", __func__, memif->data->name, cmd);
0211 
0212     switch (cmd) {
0213     case SNDRV_PCM_TRIGGER_START:
0214     case SNDRV_PCM_TRIGGER_RESUME:
0215         ret = mtk_memif_set_enable(afe, id);
0216         if (ret) {
0217             dev_err(afe->dev, "%s(), error, id %d, memif enable, ret %d\n",
0218                 __func__, id, ret);
0219             return ret;
0220         }
0221 
0222         /* set irq counter */
0223         mtk_regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
0224                        irq_data->irq_cnt_maskbit, counter,
0225                        irq_data->irq_cnt_shift);
0226 
0227         /* set irq fs */
0228         fs = afe->irq_fs(substream, runtime->rate);
0229 
0230         if (fs < 0)
0231             return -EINVAL;
0232 
0233         mtk_regmap_update_bits(afe->regmap, irq_data->irq_fs_reg,
0234                        irq_data->irq_fs_maskbit, fs,
0235                        irq_data->irq_fs_shift);
0236 
0237         /* enable interrupt */
0238         mtk_regmap_update_bits(afe->regmap, irq_data->irq_en_reg,
0239                        1, 1, irq_data->irq_en_shift);
0240 
0241         return 0;
0242     case SNDRV_PCM_TRIGGER_STOP:
0243     case SNDRV_PCM_TRIGGER_SUSPEND:
0244         ret = mtk_memif_set_disable(afe, id);
0245         if (ret) {
0246             dev_err(afe->dev, "%s(), error, id %d, memif enable, ret %d\n",
0247                 __func__, id, ret);
0248         }
0249 
0250         /* disable interrupt */
0251         mtk_regmap_update_bits(afe->regmap, irq_data->irq_en_reg,
0252                        1, 0, irq_data->irq_en_shift);
0253         /* and clear pending IRQ */
0254         mtk_regmap_write(afe->regmap, irq_data->irq_clr_reg,
0255                  1 << irq_data->irq_clr_shift);
0256         return ret;
0257     default:
0258         return -EINVAL;
0259     }
0260 }
0261 EXPORT_SYMBOL_GPL(mtk_afe_fe_trigger);
0262 
0263 int mtk_afe_fe_prepare(struct snd_pcm_substream *substream,
0264                struct snd_soc_dai *dai)
0265 {
0266     struct snd_soc_pcm_runtime *rtd  = asoc_substream_to_rtd(substream);
0267     struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0268     int id = asoc_rtd_to_cpu(rtd, 0)->id;
0269     int pbuf_size;
0270 
0271     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0272         if (afe->get_memif_pbuf_size) {
0273             pbuf_size = afe->get_memif_pbuf_size(substream);
0274             mtk_memif_set_pbuf_size(afe, id, pbuf_size);
0275         }
0276     }
0277     return 0;
0278 }
0279 EXPORT_SYMBOL_GPL(mtk_afe_fe_prepare);
0280 
0281 const struct snd_soc_dai_ops mtk_afe_fe_ops = {
0282     .startup    = mtk_afe_fe_startup,
0283     .shutdown   = mtk_afe_fe_shutdown,
0284     .hw_params  = mtk_afe_fe_hw_params,
0285     .hw_free    = mtk_afe_fe_hw_free,
0286     .prepare    = mtk_afe_fe_prepare,
0287     .trigger    = mtk_afe_fe_trigger,
0288 };
0289 EXPORT_SYMBOL_GPL(mtk_afe_fe_ops);
0290 
0291 int mtk_dynamic_irq_acquire(struct mtk_base_afe *afe)
0292 {
0293     int i;
0294 
0295     mutex_lock(&afe->irq_alloc_lock);
0296     for (i = 0; i < afe->irqs_size; ++i) {
0297         if (afe->irqs[i].irq_occupyed == 0) {
0298             afe->irqs[i].irq_occupyed = 1;
0299             mutex_unlock(&afe->irq_alloc_lock);
0300             return i;
0301         }
0302     }
0303     mutex_unlock(&afe->irq_alloc_lock);
0304     return afe->irqs_size;
0305 }
0306 EXPORT_SYMBOL_GPL(mtk_dynamic_irq_acquire);
0307 
0308 int mtk_dynamic_irq_release(struct mtk_base_afe *afe, int irq_id)
0309 {
0310     mutex_lock(&afe->irq_alloc_lock);
0311     if (irq_id >= 0 && irq_id < afe->irqs_size) {
0312         afe->irqs[irq_id].irq_occupyed = 0;
0313         mutex_unlock(&afe->irq_alloc_lock);
0314         return 0;
0315     }
0316     mutex_unlock(&afe->irq_alloc_lock);
0317     return -EINVAL;
0318 }
0319 EXPORT_SYMBOL_GPL(mtk_dynamic_irq_release);
0320 
0321 int mtk_afe_suspend(struct snd_soc_component *component)
0322 {
0323     struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
0324     struct device *dev = afe->dev;
0325     struct regmap *regmap = afe->regmap;
0326     int i;
0327 
0328     if (pm_runtime_status_suspended(dev) || afe->suspended)
0329         return 0;
0330 
0331     if (!afe->reg_back_up)
0332         afe->reg_back_up =
0333             devm_kcalloc(dev, afe->reg_back_up_list_num,
0334                      sizeof(unsigned int), GFP_KERNEL);
0335 
0336     if (afe->reg_back_up) {
0337         for (i = 0; i < afe->reg_back_up_list_num; i++)
0338             regmap_read(regmap, afe->reg_back_up_list[i],
0339                     &afe->reg_back_up[i]);
0340     }
0341 
0342     afe->suspended = true;
0343     afe->runtime_suspend(dev);
0344     return 0;
0345 }
0346 EXPORT_SYMBOL_GPL(mtk_afe_suspend);
0347 
0348 int mtk_afe_resume(struct snd_soc_component *component)
0349 {
0350     struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
0351     struct device *dev = afe->dev;
0352     struct regmap *regmap = afe->regmap;
0353     int i;
0354 
0355     if (pm_runtime_status_suspended(dev) || !afe->suspended)
0356         return 0;
0357 
0358     afe->runtime_resume(dev);
0359 
0360     if (!afe->reg_back_up) {
0361         dev_dbg(dev, "%s no reg_backup\n", __func__);
0362     } else {
0363         for (i = 0; i < afe->reg_back_up_list_num; i++)
0364             mtk_regmap_write(regmap, afe->reg_back_up_list[i],
0365                      afe->reg_back_up[i]);
0366     }
0367 
0368     afe->suspended = false;
0369     return 0;
0370 }
0371 EXPORT_SYMBOL_GPL(mtk_afe_resume);
0372 
0373 int mtk_memif_set_enable(struct mtk_base_afe *afe, int id)
0374 {
0375     struct mtk_base_afe_memif *memif = &afe->memif[id];
0376 
0377     if (memif->data->enable_shift < 0) {
0378         dev_warn(afe->dev, "%s(), error, id %d, enable_shift < 0\n",
0379              __func__, id);
0380         return 0;
0381     }
0382     return mtk_regmap_update_bits(afe->regmap, memif->data->enable_reg,
0383                       1, 1, memif->data->enable_shift);
0384 }
0385 EXPORT_SYMBOL_GPL(mtk_memif_set_enable);
0386 
0387 int mtk_memif_set_disable(struct mtk_base_afe *afe, int id)
0388 {
0389     struct mtk_base_afe_memif *memif = &afe->memif[id];
0390 
0391     if (memif->data->enable_shift < 0) {
0392         dev_warn(afe->dev, "%s(), error, id %d, enable_shift < 0\n",
0393              __func__, id);
0394         return 0;
0395     }
0396     return mtk_regmap_update_bits(afe->regmap, memif->data->enable_reg,
0397                       1, 0, memif->data->enable_shift);
0398 }
0399 EXPORT_SYMBOL_GPL(mtk_memif_set_disable);
0400 
0401 int mtk_memif_set_addr(struct mtk_base_afe *afe, int id,
0402                unsigned char *dma_area,
0403                dma_addr_t dma_addr,
0404                size_t dma_bytes)
0405 {
0406     struct mtk_base_afe_memif *memif = &afe->memif[id];
0407     int msb_at_bit33 = upper_32_bits(dma_addr) ? 1 : 0;
0408     unsigned int phys_buf_addr = lower_32_bits(dma_addr);
0409     unsigned int phys_buf_addr_upper_32 = upper_32_bits(dma_addr);
0410 
0411     memif->dma_area = dma_area;
0412     memif->dma_addr = dma_addr;
0413     memif->dma_bytes = dma_bytes;
0414 
0415     /* start */
0416     mtk_regmap_write(afe->regmap, memif->data->reg_ofs_base,
0417              phys_buf_addr);
0418     /* end */
0419     if (memif->data->reg_ofs_end)
0420         mtk_regmap_write(afe->regmap,
0421                  memif->data->reg_ofs_end,
0422                  phys_buf_addr + dma_bytes - 1);
0423     else
0424         mtk_regmap_write(afe->regmap,
0425                  memif->data->reg_ofs_base +
0426                  AFE_BASE_END_OFFSET,
0427                  phys_buf_addr + dma_bytes - 1);
0428 
0429     /* set start, end, upper 32 bits */
0430     if (memif->data->reg_ofs_base_msb) {
0431         mtk_regmap_write(afe->regmap, memif->data->reg_ofs_base_msb,
0432                  phys_buf_addr_upper_32);
0433         mtk_regmap_write(afe->regmap,
0434                  memif->data->reg_ofs_end_msb,
0435                  phys_buf_addr_upper_32);
0436     }
0437 
0438     /*
0439      * set MSB to 33-bit, for memif address
0440      * only for memif base address, if msb_end_reg exists
0441      */
0442     if (memif->data->msb_reg)
0443         mtk_regmap_update_bits(afe->regmap, memif->data->msb_reg,
0444                        1, msb_at_bit33, memif->data->msb_shift);
0445 
0446     /* set MSB to 33-bit, for memif end address */
0447     if (memif->data->msb_end_reg)
0448         mtk_regmap_update_bits(afe->regmap, memif->data->msb_end_reg,
0449                        1, msb_at_bit33,
0450                        memif->data->msb_end_shift);
0451 
0452     return 0;
0453 }
0454 EXPORT_SYMBOL_GPL(mtk_memif_set_addr);
0455 
0456 int mtk_memif_set_channel(struct mtk_base_afe *afe,
0457               int id, unsigned int channel)
0458 {
0459     struct mtk_base_afe_memif *memif = &afe->memif[id];
0460     unsigned int mono;
0461 
0462     if (memif->data->mono_shift < 0)
0463         return 0;
0464 
0465     if (memif->data->quad_ch_mask) {
0466         unsigned int quad_ch = (channel == 4) ? 1 : 0;
0467 
0468         mtk_regmap_update_bits(afe->regmap, memif->data->quad_ch_reg,
0469                        memif->data->quad_ch_mask,
0470                        quad_ch, memif->data->quad_ch_shift);
0471     }
0472 
0473     if (memif->data->mono_invert)
0474         mono = (channel == 1) ? 0 : 1;
0475     else
0476         mono = (channel == 1) ? 1 : 0;
0477 
0478     /* for specific configuration of memif mono mode */
0479     if (memif->data->int_odd_flag_reg)
0480         mtk_regmap_update_bits(afe->regmap,
0481                        memif->data->int_odd_flag_reg,
0482                        1, mono,
0483                        memif->data->int_odd_flag_shift);
0484 
0485     return mtk_regmap_update_bits(afe->regmap, memif->data->mono_reg,
0486                       1, mono, memif->data->mono_shift);
0487 }
0488 EXPORT_SYMBOL_GPL(mtk_memif_set_channel);
0489 
0490 static int mtk_memif_set_rate_fs(struct mtk_base_afe *afe,
0491                  int id, int fs)
0492 {
0493     struct mtk_base_afe_memif *memif = &afe->memif[id];
0494 
0495     if (memif->data->fs_shift >= 0)
0496         mtk_regmap_update_bits(afe->regmap, memif->data->fs_reg,
0497                        memif->data->fs_maskbit,
0498                        fs, memif->data->fs_shift);
0499 
0500     return 0;
0501 }
0502 
0503 int mtk_memif_set_rate(struct mtk_base_afe *afe,
0504                int id, unsigned int rate)
0505 {
0506     int fs = 0;
0507 
0508     if (!afe->get_dai_fs) {
0509         dev_err(afe->dev, "%s(), error, afe->get_dai_fs == NULL\n",
0510             __func__);
0511         return -EINVAL;
0512     }
0513 
0514     fs = afe->get_dai_fs(afe, id, rate);
0515 
0516     if (fs < 0)
0517         return -EINVAL;
0518 
0519     return mtk_memif_set_rate_fs(afe, id, fs);
0520 }
0521 EXPORT_SYMBOL_GPL(mtk_memif_set_rate);
0522 
0523 int mtk_memif_set_rate_substream(struct snd_pcm_substream *substream,
0524                  int id, unsigned int rate)
0525 {
0526     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0527     struct snd_soc_component *component =
0528         snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
0529     struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
0530 
0531     int fs = 0;
0532 
0533     if (!afe->memif_fs) {
0534         dev_err(afe->dev, "%s(), error, afe->memif_fs == NULL\n",
0535             __func__);
0536         return -EINVAL;
0537     }
0538 
0539     fs = afe->memif_fs(substream, rate);
0540 
0541     if (fs < 0)
0542         return -EINVAL;
0543 
0544     return mtk_memif_set_rate_fs(afe, id, fs);
0545 }
0546 EXPORT_SYMBOL_GPL(mtk_memif_set_rate_substream);
0547 
0548 int mtk_memif_set_format(struct mtk_base_afe *afe,
0549              int id, snd_pcm_format_t format)
0550 {
0551     struct mtk_base_afe_memif *memif = &afe->memif[id];
0552     int hd_audio = 0;
0553     int hd_align = 0;
0554 
0555     /* set hd mode */
0556     switch (format) {
0557     case SNDRV_PCM_FORMAT_S16_LE:
0558     case SNDRV_PCM_FORMAT_U16_LE:
0559         hd_audio = 0;
0560         break;
0561     case SNDRV_PCM_FORMAT_S32_LE:
0562     case SNDRV_PCM_FORMAT_U32_LE:
0563         if (afe->memif_32bit_supported) {
0564             hd_audio = 2;
0565             hd_align = 0;
0566         } else {
0567             hd_audio = 1;
0568             hd_align = 1;
0569         }
0570         break;
0571     case SNDRV_PCM_FORMAT_S24_LE:
0572     case SNDRV_PCM_FORMAT_U24_LE:
0573         hd_audio = 1;
0574         break;
0575     default:
0576         dev_err(afe->dev, "%s() error: unsupported format %d\n",
0577             __func__, format);
0578         break;
0579     }
0580 
0581     mtk_regmap_update_bits(afe->regmap, memif->data->hd_reg,
0582                    0x3, hd_audio, memif->data->hd_shift);
0583 
0584     mtk_regmap_update_bits(afe->regmap, memif->data->hd_align_reg,
0585                    0x1, hd_align, memif->data->hd_align_mshift);
0586 
0587     return 0;
0588 }
0589 EXPORT_SYMBOL_GPL(mtk_memif_set_format);
0590 
0591 int mtk_memif_set_pbuf_size(struct mtk_base_afe *afe,
0592                 int id, int pbuf_size)
0593 {
0594     const struct mtk_base_memif_data *memif_data = afe->memif[id].data;
0595 
0596     if (memif_data->pbuf_mask == 0 || memif_data->minlen_mask == 0)
0597         return 0;
0598 
0599     mtk_regmap_update_bits(afe->regmap, memif_data->pbuf_reg,
0600                    memif_data->pbuf_mask,
0601                    pbuf_size, memif_data->pbuf_shift);
0602 
0603     mtk_regmap_update_bits(afe->regmap, memif_data->minlen_reg,
0604                    memif_data->minlen_mask,
0605                    pbuf_size, memif_data->minlen_shift);
0606     return 0;
0607 }
0608 EXPORT_SYMBOL_GPL(mtk_memif_set_pbuf_size);
0609 
0610 MODULE_DESCRIPTION("Mediatek simple fe dai operator");
0611 MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
0612 MODULE_LICENSE("GPL v2");