2 * Copyright (C) 2007 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 /*******************************************************************************
24 * Audio Driver Kernel Function
28 * Audio fmtx data1 playback
34 *------------------------------------------------------------------------------
40 *******************************************************************************/
43 /*****************************************************************************
44 * C O M P I L E R F L A G S
45 *****************************************************************************/
48 /*****************************************************************************
49 * E X T E R N A L R E F E R E N C E S
50 *****************************************************************************/
52 #include <linux/dma-mapping.h>
53 #include "AudDrv_Common.h"
54 #include "AudDrv_Def.h"
55 #include "AudDrv_Afe.h"
56 #include "AudDrv_Ana.h"
57 #include "AudDrv_Clk.h"
58 #include "AudDrv_Kernel.h"
59 #include "mt_soc_afe_control.h"
60 #include "mt_soc_digital_type.h"
61 #include "mt_soc_pcm_common.h"
64 //#include <mach/mtk_wcn_cmb_stub.h>
65 //extern int mtk_wcn_cmb_stub_audio_ctrl(CMB_STUB_AIF_X state);
68 static AFE_MEM_CONTROL_T
*pMemControl
= NULL
;
69 static bool fake_buffer
= 1;
70 static struct snd_dma_buffer
*FMTX_Playback_dma_buf
= NULL
;
71 static unsigned int mPlaybackSramState
= SRAM_STATE_FREE
;
73 static DEFINE_SPINLOCK(auddrv_FMTxCtl_lock
);
75 static struct device
*mDev
= NULL
;
78 * function implementation
81 void StartAudioPcmHardware(void);
82 void StopAudioPcmHardware(void);
83 static int mtk_fmtx_probe(struct platform_device
*pdev
);
84 static int mtk_pcm_fmtx_close(struct snd_pcm_substream
*substream
);
85 static int mtk_asoc_pcm_fmtx_new(struct snd_soc_pcm_runtime
*rtd
);
86 static int mtk_afe_fmtx_probe(struct snd_soc_platform
*platform
);
88 static int fmtx_hdoutput_control
= true;
90 static const char *fmtx_HD_output
[] = {"Off", "On"};
92 static const struct soc_enum Audio_fmtx_Enum
[] =
94 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(fmtx_HD_output
), fmtx_HD_output
),
98 static int Audio_fmtx_hdoutput_Get(struct snd_kcontrol
*kcontrol
,
99 struct snd_ctl_elem_value
*ucontrol
)
101 printk("Audio_AmpR_Get = %d\n", fmtx_hdoutput_control
);
102 ucontrol
->value
.integer
.value
[0] = fmtx_hdoutput_control
;
106 static int Audio_fmtx_hdoutput_Set(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
108 printk("%s()\n", __func__
);
109 if (ucontrol
->value
.enumerated
.item
[0] > ARRAY_SIZE(fmtx_HD_output
))
111 printk("return -EINVAL\n");
114 fmtx_hdoutput_control
= ucontrol
->value
.integer
.value
[0];
115 if (fmtx_hdoutput_control
)
117 // set APLL clock setting
120 EnableI2SDivPower(AUDIO_APLL1_DIV0
, true);
121 EnableI2SDivPower(AUDIO_APLL2_DIV0
, true);
122 AudDrv_APLL1Tuner_Clk_On();
123 AudDrv_APLL2Tuner_Clk_On();
127 // set APLL clock setting
130 EnableI2SDivPower(AUDIO_APLL1_DIV0
, false);
131 EnableI2SDivPower(AUDIO_APLL2_DIV0
, false);
132 AudDrv_APLL1Tuner_Clk_Off();
133 AudDrv_APLL2Tuner_Clk_Off();
139 static const struct snd_kcontrol_new Audio_snd_fmtx_controls
[] =
141 SOC_ENUM_EXT("Audio_FMTX_hd_Switch", Audio_fmtx_Enum
[0], Audio_fmtx_hdoutput_Get
, Audio_fmtx_hdoutput_Set
),
145 static struct snd_pcm_hardware mtk_fmtx_hardware
=
147 .info
= (SNDRV_PCM_INFO_MMAP
|
148 SNDRV_PCM_INFO_INTERLEAVED
|
149 SNDRV_PCM_INFO_RESUME
|
150 SNDRV_PCM_INFO_MMAP_VALID
),
151 .formats
= SND_SOC_ADV_MT_FMTS
,
152 .rates
= SOC_HIGH_USE_RATE
,
153 .rate_min
= SOC_HIGH_USE_RATE_MIN
,
154 .rate_max
= SOC_NORMAL_USE_RATE_MAX
,
155 .channels_min
= SOC_NORMAL_USE_CHANNELS_MIN
,
156 .channels_max
= SOC_NORMAL_USE_CHANNELS_MAX
,
157 .buffer_bytes_max
= Dl1_MAX_BUFFER_SIZE
,
158 .period_bytes_max
= MAX_PERIOD_SIZE
,
159 .periods_min
= MIN_PERIOD_SIZE
,
160 .periods_max
= MAX_PERIOD_SIZE
,
164 static int mtk_pcm_fmtx_stop(struct snd_pcm_substream
*substream
)
166 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
168 //AFE_BLOCK_T *Afe_Block = &(pMemControl->rBlock);
169 PRINTK_AUD_FMTX("mtk_pcm_fmtx_stop \n");
171 SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE
, false);
173 // here to turn off digital part
174 SetConnection(Soc_Aud_InterCon_DisConnect
, Soc_Aud_InterConnectionInput_I05
, Soc_Aud_InterConnectionOutput_O00
);
175 SetConnection(Soc_Aud_InterCon_DisConnect
, Soc_Aud_InterConnectionInput_I06
, Soc_Aud_InterConnectionOutput_O01
);
177 // if (GetMrgI2SEnable() == false)
179 SetMrgI2SEnable(false, runtime
->rate
);
182 SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1
, false);
184 SetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT
, false);
186 Set2ndI2SOutEnable(false);
190 RemoveMemifSubStream(Soc_Aud_Digital_Block_MEM_DL1
, substream
);
196 static kal_int32 Previous_Hw_cur
= 0;
197 static snd_pcm_uframes_t
mtk_pcm_fmtx_pointer(struct snd_pcm_substream
*substream
)
199 kal_int32 HW_memory_index
= 0;
200 kal_int32 HW_Cur_ReadIdx
= 0;
201 kal_uint32 Frameidx
= 0;
202 kal_int32 Afe_consumed_bytes
= 0;
204 AFE_BLOCK_T
*Afe_Block
= &pMemControl
->rBlock
;
205 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_pointer] Afe_Block->u4DMAReadIdx = 0x%x\n", Afe_Block
->u4DMAReadIdx
);
207 Auddrv_Dl1_Spinlock_lock();
209 if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1
) == true)
211 HW_Cur_ReadIdx
= Afe_Get_Reg(AFE_DL1_CUR
);
212 if (HW_Cur_ReadIdx
== 0)
214 PRINTK_AUD_FMTX("[Auddrv] HW_Cur_ReadIdx ==0 \n");
215 HW_Cur_ReadIdx
= Afe_Block
->pucPhysBufAddr
;
217 HW_memory_index
= (HW_Cur_ReadIdx
- Afe_Block
->pucPhysBufAddr
);
218 if (HW_memory_index
>= Afe_Block
->u4DMAReadIdx
)
220 Afe_consumed_bytes
= HW_memory_index
- Afe_Block
->u4DMAReadIdx
;
224 Afe_consumed_bytes
= Afe_Block
->u4BufferSize
+ HW_memory_index
- Afe_Block
->u4DMAReadIdx
;
227 Afe_consumed_bytes
= Align64ByteSize(Afe_consumed_bytes
);
229 Afe_Block
->u4DataRemained
-= Afe_consumed_bytes
;
230 Afe_Block
->u4DMAReadIdx
+= Afe_consumed_bytes
;
231 Afe_Block
->u4DMAReadIdx
%= Afe_Block
->u4BufferSize
;
232 PRINTK_AUD_DL1("[Auddrv] HW_Cur_ReadIdx =0x%x HW_memory_index = 0x%x Afe_consumed_bytes = 0x%x\n", HW_Cur_ReadIdx
, HW_memory_index
, Afe_consumed_bytes
);
233 Auddrv_Dl1_Spinlock_unlock();
234 return audio_bytes_to_frame(substream
, Afe_Block
->u4DMAReadIdx
);
238 Frameidx
= audio_bytes_to_frame(substream
, Afe_Block
->u4DMAReadIdx
);
239 Auddrv_Dl1_Spinlock_unlock();
245 static void SetFMTXBuffer(struct snd_pcm_substream
*substream
,
246 struct snd_pcm_hw_params
*hw_params
)
248 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
249 AFE_BLOCK_T
*pblock
= &pMemControl
->rBlock
;
250 pblock
->pucPhysBufAddr
= runtime
->dma_addr
;
251 pblock
->pucVirtBufAddr
= runtime
->dma_area
;
252 pblock
->u4BufferSize
= runtime
->dma_bytes
;
253 pblock
->u4SampleNumMask
= 0x001f; // 32 byte align
254 pblock
->u4WriteIdx
= 0;
255 pblock
->u4DMAReadIdx
= 0;
256 pblock
->u4DataRemained
= 0;
257 pblock
->u4fsyncflag
= false;
258 pblock
->uResetFlag
= true;
259 printk("SetFMTXBuffer u4BufferSize = %d pucVirtBufAddr = %p pucPhysBufAddr = 0x%x\n",
260 pblock
->u4BufferSize
, pblock
->pucVirtBufAddr
, pblock
->pucPhysBufAddr
);
261 // set dram address top hardware
262 Afe_Set_Reg(AFE_DL1_BASE
, pblock
->pucPhysBufAddr
, 0xffffffff);
263 Afe_Set_Reg(AFE_DL1_END
, pblock
->pucPhysBufAddr
+ (pblock
->u4BufferSize
- 1), 0xffffffff);
264 memset((void *)pblock
->pucVirtBufAddr
, 0, pblock
->u4BufferSize
);
269 static int mtk_pcm_fmtx_hw_params(struct snd_pcm_substream
*substream
,
270 struct snd_pcm_hw_params
*hw_params
)
273 substream
->runtime
->dma_bytes
= params_buffer_bytes(hw_params
);
274 if (mPlaybackSramState
== SRAM_STATE_PLAYBACKFULL
)
276 //substream->runtime->dma_bytes = AFE_INTERNAL_SRAM_SIZE;
277 substream
->runtime
->dma_area
= (unsigned char *)Get_Afe_SramBase_Pointer();
278 substream
->runtime
->dma_addr
= AFE_INTERNAL_SRAM_PHY_BASE
;
279 AudDrv_Allocate_DL1_Buffer(mDev
, substream
->runtime
->dma_bytes
);
283 substream
->runtime
->dma_bytes
= params_buffer_bytes(hw_params
);
284 substream
->runtime
->dma_area
= FMTX_Playback_dma_buf
->area
;
285 substream
->runtime
->dma_addr
= FMTX_Playback_dma_buf
->addr
;
286 SetFMTXBuffer(substream
, hw_params
);
288 // -------------------------------------------------------
289 printk("1 dma_bytes = %zu dma_area = %p dma_addr = 0x%lx\n",
290 substream
->runtime
->dma_bytes
, substream
->runtime
->dma_area
, (long)substream
->runtime
->dma_addr
);
298 static int mtk_pcm_fmtx_hw_params(struct snd_pcm_substream
*substream
,
299 struct snd_pcm_hw_params
*hw_params
)
301 struct snd_dma_buffer
*dma_buf
= &substream
->dma_buffer
;
303 PRINTK_AUD_FMTX("mtk_pcm_fmtx_hw_params \n");
306 /* runtime->dma_bytes has to be set manually to allow mmap */
307 substream
->runtime
->dma_bytes
= params_buffer_bytes(hw_params
);
309 // here to allcoate sram to hardware ---------------------------
310 AudDrv_Allocate_mem_Buffer(mDev
, Soc_Aud_Digital_Block_MEM_DL1
, substream
->runtime
->dma_bytes
);
311 substream
->runtime
->dma_area
= (unsigned char *)Get_Afe_SramBase_Pointer();
312 substream
->runtime
->dma_addr
= AFE_INTERNAL_SRAM_PHY_BASE
;
314 // -------------------------------------------------------
315 PRINTK_AUD_FMTX("1 dma_bytes = %d dma_area = %p dma_addr = 0x%x\n",
316 substream
->runtime
->dma_bytes
, substream
->runtime
->dma_area
, substream
->runtime
->dma_addr
);
321 dma_buf
->dev
.type
= SNDRV_DMA_TYPE_DEV
;
322 dma_buf
->dev
.dev
= substream
->pcm
->card
->dev
;
323 dma_buf
->private_data
= NULL
;
324 ret
= snd_pcm_lib_malloc_pages(substream
, params_buffer_bytes(hw_params
));
326 PRINTK_AUD_FMTX("2 dma_bytes = %d dma_area = %p dma_addr = 0x%x\n",
327 substream
->runtime
->dma_bytes
, substream
->runtime
->dma_area
, substream
->runtime
->dma_addr
);
333 static int mtk_pcm_fmtx_hw_free(struct snd_pcm_substream
*substream
)
335 PRINTK_AUD_FMTX("mtk_pcm_fmtx_hw_free \n");
340 return snd_pcm_lib_free_pages(substream
);
344 static struct snd_pcm_hw_constraint_list constraints_fmtx_sample_rates
=
346 .count
= ARRAY_SIZE(soc_fm_supported_sample_rates
),
347 .list
= soc_fm_supported_sample_rates
,
352 static int mtk_pcm_fmtx_open(struct snd_pcm_substream
*substream
)
355 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
356 PRINTK_AUD_FMTX("mtk_pcm_fmtx_open\n");
359 // get dl1 memconptrol and record substream
360 pMemControl
= Get_Mem_ControlT(Soc_Aud_Digital_Block_MEM_DL1
);
361 runtime
->hw
= mtk_fmtx_hardware
;
362 memcpy((void *)(&(runtime
->hw
)), (void *)&mtk_fmtx_hardware
, sizeof(struct snd_pcm_hardware
));
364 //PRINTK_AUDDRV("runtime->hw->rates= 0x%x mtk_pcm_hardware = = 0x%x\n ", runtime->hw.rates, &mtk_pcm_hardware);
366 ret
= snd_pcm_hw_constraint_list(runtime
, 0, SNDRV_PCM_HW_PARAM_RATE
,
367 &constraints_fmtx_sample_rates
);
368 ret
= snd_pcm_hw_constraint_integer(runtime
, SNDRV_PCM_HW_PARAM_PERIODS
);
372 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_open]snd_pcm_hw_constraint_integer failed\n");
374 //print for hw pcm information
375 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_open] runtime rate = %d channels = %d substream->pcm->device = %d\n",
376 runtime
->rate
, runtime
->channels
, substream
->pcm
->device
);
378 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
380 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_open]SNDRV_PCM_FMTX_PLAYBACK mtkalsa_playback_constraints\n");
389 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_open]mtk_pcm_fmtx_close\n");
390 mtk_pcm_fmtx_close(substream
);
393 //PRINTK_AUDDRV("mtk_pcm_open return\n");
398 static int mtk_pcm_fmtx_open(struct snd_pcm_substream
*substream
)
401 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
402 AfeControlSramLock();
403 if (GetSramState() == SRAM_STATE_FREE
)
405 mtk_fmtx_hardware
.buffer_bytes_max
= GetPLaybackSramFullSize();
406 mPlaybackSramState
= SRAM_STATE_PLAYBACKFULL
;
407 SetSramState(mPlaybackSramState
);
411 mtk_fmtx_hardware
.buffer_bytes_max
= GetPLaybackDramSize();
412 mPlaybackSramState
= SRAM_STATE_PLAYBACKDRAM
;
414 AfeControlSramUnLock();
415 if (mPlaybackSramState
== SRAM_STATE_PLAYBACKDRAM
)
420 printk("mtk_I2S0dl1_hardware.buffer_bytes_max = %zu mPlaybackSramState = %d\n", mtk_fmtx_hardware
.buffer_bytes_max
, mPlaybackSramState
);
421 runtime
->hw
= mtk_fmtx_hardware
;
424 memcpy((void *)(&(runtime
->hw
)), (void *)&mtk_fmtx_hardware
, sizeof(struct snd_pcm_hardware
));
425 pMemControl
= Get_Mem_ControlT(Soc_Aud_Digital_Block_MEM_DL1
);
427 ret
= snd_pcm_hw_constraint_list(runtime
, 0, SNDRV_PCM_HW_PARAM_RATE
,
428 &constraints_fmtx_sample_rates
);
432 printk("snd_pcm_hw_constraint_integer failed\n");
435 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
437 printk("SNDRV_PCM_STREAM_PLAYBACK mtkalsa_fmtx_playback_constraints\n");
441 printk("SNDRV_PCM_STREAM_CAPTURE mtkalsa_fmtx_playback_constraints\n");
446 printk("ret < 0 mtkalsa_fmtx_playback close\n");
447 mtk_pcm_fmtx_close(substream
);
450 //printk("mtk_pcm_I2S0dl1_open return\n");
456 static int mtk_pcm_fmtx_close(struct snd_pcm_substream
*substream
)
458 PRINTK_AUD_FMTX("%s \n", __func__
);
459 // mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X)CMB_STUB_AIF_0);
461 if (mPlaybackSramState
== SRAM_STATE_PLAYBACKDRAM
)
463 AudDrv_Emi_Clk_Off();
465 AfeControlSramLock();
466 ClearSramState(mPlaybackSramState
);
467 mPlaybackSramState
= GetSramState();
468 AfeControlSramUnLock();
474 static int mtk_pcm_fmtx_prepare(struct snd_pcm_substream
*substream
)
479 static int mtk_pcm_fmtx_start(struct snd_pcm_substream
*substream
)
481 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
484 // mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X)CMB_STUB_AIF_2);
486 SetMemifSubStream(Soc_Aud_Digital_Block_MEM_DL1
, substream
);
487 if (runtime
->format
== SNDRV_PCM_FORMAT_S32_LE
|| runtime
->format
== SNDRV_PCM_FORMAT_U32_LE
)
489 SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL1
, AFE_WLEN_32_BIT_ALIGN_8BIT_0_24BIT_DATA
);
490 SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL2
, AFE_WLEN_32_BIT_ALIGN_8BIT_0_24BIT_DATA
);
491 SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT
, Soc_Aud_InterConnectionOutput_O00
); // FM Tx only support 16 bit
492 SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT
, Soc_Aud_InterConnectionOutput_O01
); // FM Tx only support 16 bit
496 SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL1
, AFE_WLEN_16_BIT
);
497 SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL2
, AFE_WLEN_16_BIT
);
498 SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT
, Soc_Aud_InterConnectionOutput_O00
);
499 SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT
, Soc_Aud_InterConnectionOutput_O01
);
502 // here start digital part
503 SetConnection(Soc_Aud_InterCon_Connection
, Soc_Aud_InterConnectionInput_I05
, Soc_Aud_InterConnectionOutput_O00
);
504 SetConnection(Soc_Aud_InterCon_Connection
, Soc_Aud_InterConnectionInput_I06
, Soc_Aud_InterConnectionOutput_O01
);
506 // set dl1 sample ratelimit_state
507 SetSampleRate(Soc_Aud_Digital_Block_MEM_DL1
, runtime
->rate
);
508 SetChannels(Soc_Aud_Digital_Block_MEM_DL1
, runtime
->channels
);
511 SetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT
, true);
512 SetMrgI2SEnable(true, runtime
->rate
) ;
516 Set2ndI2SOutAttribute(runtime
->rate
) ;
517 Set2ndI2SOutEnable(true);
519 SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1
, true);
521 // here to set interrupt
522 SetIrqMcuCounter(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE
, (runtime
->period_size
* 2 / 3));
523 SetIrqMcuSampleRate(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE
, runtime
->rate
);
524 SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE
, true);
531 static int mtk_pcm_fmtx_trigger(struct snd_pcm_substream
*substream
, int cmd
)
533 printk("mtk_pcm_fmtx_trigger cmd = %d\n", cmd
);
536 case SNDRV_PCM_TRIGGER_START
:
537 case SNDRV_PCM_TRIGGER_RESUME
:
538 return mtk_pcm_fmtx_start(substream
);
539 case SNDRV_PCM_TRIGGER_STOP
:
540 case SNDRV_PCM_TRIGGER_SUSPEND
:
541 return mtk_pcm_fmtx_stop(substream
);
546 static int mtk_pcm_fmtx_copy(struct snd_pcm_substream
*substream
,
547 int channel
, snd_pcm_uframes_t pos
,
548 void __user
*dst
, snd_pcm_uframes_t count
)
550 AFE_BLOCK_T
*Afe_Block
= NULL
;
552 char *data_w_ptr
= (char *)dst
;
553 int copy_size
= 0, Afe_WriteIdx_tmp
;
555 // get total bytes to copy
556 count
= audio_frame_to_bytes(substream
, count
);
558 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] pos = %lu count = %lu\n ", pos
, count
);
560 // check which memif nned to be write
561 Afe_Block
= &pMemControl
->rBlock
;
563 // handle for buffer management
565 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy]AudDrv_write WriteIdx=0x%x, ReadIdx=0x%x, DataRemained=0x%x \n",
566 Afe_Block
->u4WriteIdx
, Afe_Block
->u4DMAReadIdx
, Afe_Block
->u4DataRemained
);
568 if (Afe_Block
->u4BufferSize
== 0)
570 printk("AudDrv_write: u4BufferSize=0 Error");
574 spin_lock_irqsave(&auddrv_FMTxCtl_lock
, flags
);
575 copy_size
= Afe_Block
->u4BufferSize
- Afe_Block
->u4DataRemained
; // free space of the buffer
576 spin_unlock_irqrestore(&auddrv_FMTxCtl_lock
, flags
);
577 if (count
<= copy_size
)
589 copy_size
= Align64ByteSize(copy_size
);
590 PRINTK_AUD_DL1("copy_size=0x%x, count=0x%x \n", copy_size
, (unsigned int)count
);
594 spin_lock_irqsave(&auddrv_FMTxCtl_lock
, flags
);
595 Afe_WriteIdx_tmp
= Afe_Block
->u4WriteIdx
;
596 spin_unlock_irqrestore(&auddrv_FMTxCtl_lock
, flags
);
598 if (Afe_WriteIdx_tmp
+ copy_size
< Afe_Block
->u4BufferSize
) // copy once
600 if (!access_ok(VERIFY_READ
, data_w_ptr
, copy_size
))
602 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] 0ptr invalid data_w_ptr=0x%x, size=%d", (kal_uint32
)data_w_ptr
, copy_size
);
603 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] u4BufferSize=%d, u4DataRemained=%d", Afe_Block
->u4BufferSize
, Afe_Block
->u4DataRemained
);
607 PRINTK_AUD_FMTX("memcpy Afe_Block->pucVirtBufAddr+Afe_WriteIdx= %p data_w_ptr = %p copy_size = 0x%x\n",
608 Afe_Block
->pucVirtBufAddr
+ Afe_WriteIdx_tmp
, data_w_ptr
, copy_size
);
609 if (copy_from_user((Afe_Block
->pucVirtBufAddr
+ Afe_WriteIdx_tmp
), data_w_ptr
, copy_size
))
611 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] Fail copy from user \n");
616 spin_lock_irqsave(&auddrv_FMTxCtl_lock
, flags
);
617 Afe_Block
->u4DataRemained
+= copy_size
;
618 Afe_Block
->u4WriteIdx
= Afe_WriteIdx_tmp
+ copy_size
;
619 Afe_Block
->u4WriteIdx
%= Afe_Block
->u4BufferSize
;
620 spin_unlock_irqrestore(&auddrv_FMTxCtl_lock
, flags
);
621 data_w_ptr
+= copy_size
;
624 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] finish1, copy_size:%x, WriteIdx:%x, ReadIdx=%x, DataRemained:%x, count=%x \r\n",
625 copy_size
, Afe_Block
->u4WriteIdx
, Afe_Block
->u4DMAReadIdx
, Afe_Block
->u4DataRemained
, count
);
630 kal_uint32 size_1
= 0, size_2
= 0;
631 size_1
= Align64ByteSize((Afe_Block
->u4BufferSize
- Afe_WriteIdx_tmp
));
632 size_2
= Align64ByteSize((copy_size
- size_1
));
633 PRINTK_AUD_DL1("size_1=0x%x, size_2=0x%x \n", size_1
, size_2
);
634 if (!access_ok(VERIFY_READ
, data_w_ptr
, size_1
))
636 printk("[mtk_pcm_fmtx_copy] 1ptr invalid data_w_ptr=%p, size_1=%d", data_w_ptr
, size_1
);
637 printk("[mtk_pcm_fmtx_copy] u4BufferSize=%d, u4DataRemained=%d", Afe_Block
->u4BufferSize
, Afe_Block
->u4DataRemained
);
642 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy]mcmcpy Afe_Block->pucVirtBufAddr+Afe_WriteIdx= %x data_w_ptr = %p size_1 = %x\n",
643 Afe_Block
->pucVirtBufAddr
+ Afe_WriteIdx_tmp
, data_w_ptr
, size_1
);
644 if ((copy_from_user((Afe_Block
->pucVirtBufAddr
+ Afe_WriteIdx_tmp
), data_w_ptr
, size_1
)))
646 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] Fail 1 copy from user");
650 spin_lock_irqsave(&auddrv_FMTxCtl_lock
, flags
);
651 Afe_Block
->u4DataRemained
+= size_1
;
652 Afe_Block
->u4WriteIdx
= Afe_WriteIdx_tmp
+ size_1
;
653 Afe_Block
->u4WriteIdx
%= Afe_Block
->u4BufferSize
;
654 Afe_WriteIdx_tmp
= Afe_Block
->u4WriteIdx
;
655 spin_unlock_irqrestore(&auddrv_FMTxCtl_lock
, flags
);
657 if (!access_ok(VERIFY_READ
, data_w_ptr
+ size_1
, size_2
))
659 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] 2ptr invalid data_w_ptr=%x, size_1=%d, size_2=%d", (kal_uint32
)data_w_ptr
, size_1
, size_2
);
660 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] u4BufferSize=%d, u4DataRemained=%d", Afe_Block
->u4BufferSize
, Afe_Block
->u4DataRemained
);
665 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy]mcmcpy Afe_Block->pucVirtBufAddr+Afe_WriteIdx= %x data_w_ptr+size_1 = %p size_2 = %x\n",
666 Afe_Block
->pucVirtBufAddr
+ Afe_WriteIdx_tmp
, data_w_ptr
+ size_1
, size_2
);
667 if ((copy_from_user((Afe_Block
->pucVirtBufAddr
+ Afe_WriteIdx_tmp
), (data_w_ptr
+ size_1
), size_2
)))
669 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] Fail 2 copy from user");
673 spin_lock_irqsave(&auddrv_FMTxCtl_lock
, flags
);
675 Afe_Block
->u4DataRemained
+= size_2
;
676 Afe_Block
->u4WriteIdx
= Afe_WriteIdx_tmp
+ size_2
;
677 Afe_Block
->u4WriteIdx
%= Afe_Block
->u4BufferSize
;
678 spin_unlock_irqrestore(&auddrv_FMTxCtl_lock
, flags
);
680 data_w_ptr
+= copy_size
;
682 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] finish2, copy size:%x, WriteIdx:%x,ReadIdx=%x DataRemained:%x \r\n",
683 copy_size
, Afe_Block
->u4WriteIdx
, Afe_Block
->u4DMAReadIdx
, Afe_Block
->u4DataRemained
);
689 static int mtk_pcm_fmtx_silence(struct snd_pcm_substream
*substream
,
690 int channel
, snd_pcm_uframes_t pos
,
691 snd_pcm_uframes_t count
)
693 PRINTK_AUD_FMTX("%s \n", __func__
);
694 return 0; /* do nothing */
697 static void *dummy_page
[2];
699 static struct page
*mtk_pcm_fmtx_page(struct snd_pcm_substream
*substream
,
700 unsigned long offset
)
702 PRINTK_AUD_FMTX("%s \n", __func__
);
703 return virt_to_page(dummy_page
[substream
->stream
]); /* the same page */
706 static struct snd_pcm_ops mtk_fmtx_ops
=
708 .open
= mtk_pcm_fmtx_open
,
709 .close
= mtk_pcm_fmtx_close
,
710 .ioctl
= snd_pcm_lib_ioctl
,
711 .hw_params
= mtk_pcm_fmtx_hw_params
,
712 .hw_free
= mtk_pcm_fmtx_hw_free
,
713 .prepare
= mtk_pcm_fmtx_prepare
,
714 .trigger
= mtk_pcm_fmtx_trigger
,
715 .pointer
= mtk_pcm_fmtx_pointer
,
716 .copy
= mtk_pcm_fmtx_copy
,
717 .silence
= mtk_pcm_fmtx_silence
,
718 .page
= mtk_pcm_fmtx_page
,
721 static struct snd_soc_platform_driver mtk_fmtx_soc_platform
=
723 .ops
= &mtk_fmtx_ops
,
724 .pcm_new
= mtk_asoc_pcm_fmtx_new
,
725 .probe
= mtk_afe_fmtx_probe
,
728 static int mtk_fmtx_probe(struct platform_device
*pdev
)
731 PRINTK_AUD_FMTX("%s \n", __func__
);
733 pdev
->dev
.coherent_dma_mask
= DMA_BIT_MASK(64);
734 if (!pdev
->dev
.dma_mask
)
736 pdev
->dev
.dma_mask
= &pdev
->dev
.coherent_dma_mask
;
739 if (pdev
->dev
.of_node
)
741 dev_set_name(&pdev
->dev
, "%s", MT_SOC_FM_MRGTX_PCM
);
744 PRINTK_AUD_FMTX("%s: dev name %s\n", __func__
, dev_name(&pdev
->dev
));
748 return snd_soc_register_platform(&pdev
->dev
,
749 &mtk_fmtx_soc_platform
);
752 static int mtk_asoc_pcm_fmtx_new(struct snd_soc_pcm_runtime
*rtd
)
755 PRINTK_AUD_FMTX("%s\n", __func__
);
759 static int mtk_afe_fmtx_probe(struct snd_soc_platform
*platform
)
761 PRINTK_AUD_FMTX("mtk_afe_afe_probe\n");
762 snd_soc_add_platform_controls(platform
, Audio_snd_fmtx_controls
,
763 ARRAY_SIZE(Audio_snd_fmtx_controls
));
764 AudDrv_Allocate_mem_Buffer(platform
->dev
, Soc_Aud_Digital_Block_MEM_DL1
, Dl1_MAX_BUFFER_SIZE
);
765 FMTX_Playback_dma_buf
= Get_Mem_Buffer(Soc_Aud_Digital_Block_MEM_DL1
);
770 static int mtk_fmtx_remove(struct platform_device
*pdev
)
772 PRINTK_AUD_FMTX("%s \n", __func__
);
773 snd_soc_unregister_platform(&pdev
->dev
);
778 static const struct of_device_id mt_soc_pcm_fmtx_of_ids
[] =
780 { .compatible
= "mediatek,mt_soc_pcm_fmtx", },
785 static struct platform_driver mtk_fmtx_driver
=
788 .name
= MT_SOC_FM_MRGTX_PCM
,
789 .owner
= THIS_MODULE
,
791 .of_match_table
= mt_soc_pcm_fmtx_of_ids
,
794 .probe
= mtk_fmtx_probe
,
795 .remove
= mtk_fmtx_remove
,
799 static struct platform_device
*soc_mtkfmtx_dev
;
802 static int __init
mtk_soc_platform_init(void)
805 PRINTK_AUD_FMTX("%s \n", __func__
);
807 soc_mtkfmtx_dev
= platform_device_alloc(MT_SOC_FM_MRGTX_PCM
, -1);
808 if (!soc_mtkfmtx_dev
)
813 ret
= platform_device_add(soc_mtkfmtx_dev
);
816 platform_device_put(soc_mtkfmtx_dev
);
820 ret
= platform_driver_register(&mtk_fmtx_driver
);
824 module_init(mtk_soc_platform_init
);
826 static void __exit
mtk_soc_platform_exit(void)
828 PRINTK_AUD_FMTX("%s \n", __func__
);
830 platform_driver_unregister(&mtk_fmtx_driver
);
832 module_exit(mtk_soc_platform_exit
);
834 MODULE_DESCRIPTION("AFE PCM module platform driver");
835 MODULE_LICENSE("GPL");