import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / sound / soc / mediatek / mt_soc_audio_v3 / mt_soc_pcm_fmtx.c
1 /*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16 /*******************************************************************************
17 *
18 * Filename:
19 * ---------
20 * mt_soc_pcm_fmtx.c
21 *
22 * Project:
23 * --------
24 * Audio Driver Kernel Function
25 *
26 * Description:
27 * ------------
28 * Audio fmtx data1 playback
29 *
30 * Author:
31 * -------
32 *
33 *
34 *------------------------------------------------------------------------------
35 * $Revision: #1 $
36 * $Modtime:$
37 * $Log:$
38 *
39 *
40 *******************************************************************************/
41
42
43 /*****************************************************************************
44 * C O M P I L E R F L A G S
45 *****************************************************************************/
46
47
48 /*****************************************************************************
49 * E X T E R N A L R E F E R E N C E S
50 *****************************************************************************/
51
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"
62
63
64 //#include <mach/mtk_wcn_cmb_stub.h>
65 //extern int mtk_wcn_cmb_stub_audio_ctrl(CMB_STUB_AIF_X state);
66
67
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;
72
73 static DEFINE_SPINLOCK(auddrv_FMTxCtl_lock);
74
75 static struct device *mDev = NULL;
76
77 /*
78 * function implementation
79 */
80
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);
87
88 static int fmtx_hdoutput_control = true;
89
90 static const char *fmtx_HD_output[] = {"Off", "On"};
91
92 static const struct soc_enum Audio_fmtx_Enum[] =
93 {
94 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(fmtx_HD_output), fmtx_HD_output),
95 };
96
97
98 static int Audio_fmtx_hdoutput_Get(struct snd_kcontrol *kcontrol,
99 struct snd_ctl_elem_value *ucontrol)
100 {
101 printk("Audio_AmpR_Get = %d\n", fmtx_hdoutput_control);
102 ucontrol->value.integer.value[0] = fmtx_hdoutput_control;
103 return 0;
104 }
105
106 static int Audio_fmtx_hdoutput_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
107 {
108 printk("%s()\n", __func__);
109 if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(fmtx_HD_output))
110 {
111 printk("return -EINVAL\n");
112 return -EINVAL;
113 }
114 fmtx_hdoutput_control = ucontrol->value.integer.value[0];
115 if (fmtx_hdoutput_control)
116 {
117 // set APLL clock setting
118 EnableApll1(true);
119 EnableApll2(true);
120 EnableI2SDivPower(AUDIO_APLL1_DIV0, true);
121 EnableI2SDivPower(AUDIO_APLL2_DIV0, true);
122 AudDrv_APLL1Tuner_Clk_On();
123 AudDrv_APLL2Tuner_Clk_On();
124 }
125 else
126 {
127 // set APLL clock setting
128 EnableApll1(false);
129 EnableApll2(false);
130 EnableI2SDivPower(AUDIO_APLL1_DIV0, false);
131 EnableI2SDivPower(AUDIO_APLL2_DIV0, false);
132 AudDrv_APLL1Tuner_Clk_Off();
133 AudDrv_APLL2Tuner_Clk_Off();
134 }
135 return 0;
136 }
137
138
139 static const struct snd_kcontrol_new Audio_snd_fmtx_controls[] =
140 {
141 SOC_ENUM_EXT("Audio_FMTX_hd_Switch", Audio_fmtx_Enum[0], Audio_fmtx_hdoutput_Get, Audio_fmtx_hdoutput_Set),
142 };
143
144
145 static struct snd_pcm_hardware mtk_fmtx_hardware =
146 {
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,
161 .fifo_size = 0,
162 };
163
164 static int mtk_pcm_fmtx_stop(struct snd_pcm_substream *substream)
165 {
166 struct snd_pcm_runtime *runtime = substream->runtime;
167
168 //AFE_BLOCK_T *Afe_Block = &(pMemControl->rBlock);
169 PRINTK_AUD_FMTX("mtk_pcm_fmtx_stop \n");
170
171 SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, false);
172
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);
176
177 // if (GetMrgI2SEnable() == false)
178 // {
179 SetMrgI2SEnable(false, runtime->rate);
180 // }
181
182 SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1, false);
183
184 SetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT, false);
185
186 Set2ndI2SOutEnable(false);
187
188 EnableAfe(false);
189
190 RemoveMemifSubStream(Soc_Aud_Digital_Block_MEM_DL1, substream);
191 AudDrv_Clk_Off();
192
193 return 0;
194 }
195
196 static kal_int32 Previous_Hw_cur = 0;
197 static snd_pcm_uframes_t mtk_pcm_fmtx_pointer(struct snd_pcm_substream *substream)
198 {
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;
203
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);
206
207 Auddrv_Dl1_Spinlock_lock();
208
209 if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1) == true)
210 {
211 HW_Cur_ReadIdx = Afe_Get_Reg(AFE_DL1_CUR);
212 if (HW_Cur_ReadIdx == 0)
213 {
214 PRINTK_AUD_FMTX("[Auddrv] HW_Cur_ReadIdx ==0 \n");
215 HW_Cur_ReadIdx = Afe_Block->pucPhysBufAddr;
216 }
217 HW_memory_index = (HW_Cur_ReadIdx - Afe_Block->pucPhysBufAddr);
218 if (HW_memory_index >= Afe_Block->u4DMAReadIdx)
219 {
220 Afe_consumed_bytes = HW_memory_index - Afe_Block->u4DMAReadIdx;
221 }
222 else
223 {
224 Afe_consumed_bytes = Afe_Block->u4BufferSize + HW_memory_index - Afe_Block->u4DMAReadIdx ;
225 }
226
227 Afe_consumed_bytes = Align64ByteSize(Afe_consumed_bytes);
228
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);
235 }
236 else
237 {
238 Frameidx = audio_bytes_to_frame(substream , Afe_Block->u4DMAReadIdx);
239 Auddrv_Dl1_Spinlock_unlock();
240 return Frameidx;
241 }
242 }
243
244
245 static void SetFMTXBuffer(struct snd_pcm_substream *substream,
246 struct snd_pcm_hw_params *hw_params)
247 {
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);
265
266 }
267
268
269 static int mtk_pcm_fmtx_hw_params(struct snd_pcm_substream *substream,
270 struct snd_pcm_hw_params *hw_params)
271 {
272 int ret = 0;
273 substream->runtime->dma_bytes = params_buffer_bytes(hw_params);
274 if (mPlaybackSramState == SRAM_STATE_PLAYBACKFULL)
275 {
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);
280 }
281 else
282 {
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);
287 }
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);
291
292 return ret;
293 }
294
295
296
297 #if 0
298 static int mtk_pcm_fmtx_hw_params(struct snd_pcm_substream *substream,
299 struct snd_pcm_hw_params *hw_params)
300 {
301 struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
302 int ret = 0;
303 PRINTK_AUD_FMTX("mtk_pcm_fmtx_hw_params \n");
304 if (fake_buffer)
305 {
306 /* runtime->dma_bytes has to be set manually to allow mmap */
307 substream->runtime->dma_bytes = params_buffer_bytes(hw_params);
308
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;
313
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);
317 return 0;
318 }
319 else
320 {
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));
325 }
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);
328 return ret;
329 }
330 #endif
331
332
333 static int mtk_pcm_fmtx_hw_free(struct snd_pcm_substream *substream)
334 {
335 PRINTK_AUD_FMTX("mtk_pcm_fmtx_hw_free \n");
336 if (fake_buffer)
337 {
338 return 0;
339 }
340 return snd_pcm_lib_free_pages(substream);
341 }
342
343
344 static struct snd_pcm_hw_constraint_list constraints_fmtx_sample_rates =
345 {
346 .count = ARRAY_SIZE(soc_fm_supported_sample_rates),
347 .list = soc_fm_supported_sample_rates,
348 .mask = 0,
349 };
350
351 #if 0
352 static int mtk_pcm_fmtx_open(struct snd_pcm_substream *substream)
353 {
354 int ret = 0;
355 struct snd_pcm_runtime *runtime = substream->runtime;
356 PRINTK_AUD_FMTX("mtk_pcm_fmtx_open\n");
357 AudDrv_Clk_On();
358
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));
363
364 //PRINTK_AUDDRV("runtime->hw->rates= 0x%x mtk_pcm_hardware = = 0x%x\n ", runtime->hw.rates, &mtk_pcm_hardware);
365
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);
369
370 if (ret < 0)
371 {
372 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_open]snd_pcm_hw_constraint_integer failed\n");
373 }
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);
377
378 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
379 {
380 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_open]SNDRV_PCM_FMTX_PLAYBACK mtkalsa_playback_constraints\n");
381 }
382 else
383 {
384
385 }
386
387 if (ret < 0)
388 {
389 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_open]mtk_pcm_fmtx_close\n");
390 mtk_pcm_fmtx_close(substream);
391 return ret;
392 }
393 //PRINTK_AUDDRV("mtk_pcm_open return\n");
394 return 0;
395 }
396 #endif
397
398 static int mtk_pcm_fmtx_open(struct snd_pcm_substream *substream)
399 {
400 int ret = 0;
401 struct snd_pcm_runtime *runtime = substream->runtime;
402 AfeControlSramLock();
403 if (GetSramState() == SRAM_STATE_FREE)
404 {
405 mtk_fmtx_hardware.buffer_bytes_max = GetPLaybackSramFullSize();
406 mPlaybackSramState = SRAM_STATE_PLAYBACKFULL;
407 SetSramState(mPlaybackSramState);
408 }
409 else
410 {
411 mtk_fmtx_hardware.buffer_bytes_max = GetPLaybackDramSize();
412 mPlaybackSramState = SRAM_STATE_PLAYBACKDRAM;
413 }
414 AfeControlSramUnLock();
415 if (mPlaybackSramState == SRAM_STATE_PLAYBACKDRAM)
416 {
417 AudDrv_Emi_Clk_On();
418 }
419
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;
422
423 AudDrv_Clk_On();
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);
426
427 ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
428 &constraints_fmtx_sample_rates);
429
430 if (ret < 0)
431 {
432 printk("snd_pcm_hw_constraint_integer failed\n");
433 }
434
435 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
436 {
437 printk("SNDRV_PCM_STREAM_PLAYBACK mtkalsa_fmtx_playback_constraints\n");
438 }
439 else
440 {
441 printk("SNDRV_PCM_STREAM_CAPTURE mtkalsa_fmtx_playback_constraints\n");
442 }
443
444 if (ret < 0)
445 {
446 printk("ret < 0 mtkalsa_fmtx_playback close\n");
447 mtk_pcm_fmtx_close(substream);
448 return ret;
449 }
450 //printk("mtk_pcm_I2S0dl1_open return\n");
451 return 0;
452 }
453
454
455
456 static int mtk_pcm_fmtx_close(struct snd_pcm_substream *substream)
457 {
458 PRINTK_AUD_FMTX("%s \n", __func__);
459 // mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X)CMB_STUB_AIF_0);
460
461 if (mPlaybackSramState == SRAM_STATE_PLAYBACKDRAM)
462 {
463 AudDrv_Emi_Clk_Off();
464 }
465 AfeControlSramLock();
466 ClearSramState(mPlaybackSramState);
467 mPlaybackSramState = GetSramState();
468 AfeControlSramUnLock();
469
470 AudDrv_Clk_Off();
471 return 0;
472 }
473
474 static int mtk_pcm_fmtx_prepare(struct snd_pcm_substream *substream)
475 {
476 return 0;
477 }
478
479 static int mtk_pcm_fmtx_start(struct snd_pcm_substream *substream)
480 {
481 struct snd_pcm_runtime *runtime = substream->runtime;
482 AudDrv_Clk_On();
483
484 // mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X)CMB_STUB_AIF_2);
485
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)
488 {
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
493 }
494 else
495 {
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);
500 }
501
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);
505
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);
509
510 // start MRG I2S Out
511 SetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT, true);
512 SetMrgI2SEnable(true, runtime->rate) ;
513
514 // start 2nd I2S Out
515
516 Set2ndI2SOutAttribute(runtime->rate) ;
517 Set2ndI2SOutEnable(true);
518
519 SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1, true);
520
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);
525
526 EnableAfe(true);
527
528 return 0;
529 }
530
531 static int mtk_pcm_fmtx_trigger(struct snd_pcm_substream *substream, int cmd)
532 {
533 printk("mtk_pcm_fmtx_trigger cmd = %d\n", cmd);
534 switch (cmd)
535 {
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);
542 }
543 return -EINVAL;
544 }
545
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)
549 {
550 AFE_BLOCK_T *Afe_Block = NULL;
551 unsigned long flags;
552 char *data_w_ptr = (char *)dst;
553 int copy_size = 0, Afe_WriteIdx_tmp;
554
555 // get total bytes to copy
556 count = audio_frame_to_bytes(substream , count);
557
558 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] pos = %lu count = %lu\n ", pos, count);
559
560 // check which memif nned to be write
561 Afe_Block = &pMemControl->rBlock;
562
563 // handle for buffer management
564
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);
567
568 if (Afe_Block->u4BufferSize == 0)
569 {
570 printk("AudDrv_write: u4BufferSize=0 Error");
571 return 0;
572 }
573
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)
578 {
579 if (copy_size < 0)
580 {
581 copy_size = 0;
582 }
583 else
584 {
585 copy_size = count;
586 }
587 }
588
589 copy_size = Align64ByteSize(copy_size);
590 PRINTK_AUD_DL1("copy_size=0x%x, count=0x%x \n", copy_size, (unsigned int)count);
591
592 if (copy_size != 0)
593 {
594 spin_lock_irqsave(&auddrv_FMTxCtl_lock, flags);
595 Afe_WriteIdx_tmp = Afe_Block->u4WriteIdx;
596 spin_unlock_irqrestore(&auddrv_FMTxCtl_lock, flags);
597
598 if (Afe_WriteIdx_tmp + copy_size < Afe_Block->u4BufferSize) // copy once
599 {
600 if (!access_ok(VERIFY_READ, data_w_ptr, copy_size))
601 {
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);
604 }
605 else
606 {
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))
610 {
611 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] Fail copy from user \n");
612 return -1;
613 }
614 }
615
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;
622 count -= copy_size;
623
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);
626
627 }
628 else // copy twice
629 {
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))
635 {
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);
638 }
639 else
640 {
641
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)))
645 {
646 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] Fail 1 copy from user");
647 return -1;
648 }
649 }
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);
656
657 if (!access_ok(VERIFY_READ, data_w_ptr + size_1, size_2))
658 {
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);
661 }
662 else
663 {
664
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)))
668 {
669 PRINTK_AUD_FMTX("[mtk_pcm_fmtx_copy] Fail 2 copy from user");
670 return -1;
671 }
672 }
673 spin_lock_irqsave(&auddrv_FMTxCtl_lock, flags);
674
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);
679 count -= copy_size;
680 data_w_ptr += copy_size;
681
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);
684 }
685 }
686 return 0;
687 }
688
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)
692 {
693 PRINTK_AUD_FMTX("%s \n", __func__);
694 return 0; /* do nothing */
695 }
696
697 static void *dummy_page[2];
698
699 static struct page *mtk_pcm_fmtx_page(struct snd_pcm_substream *substream,
700 unsigned long offset)
701 {
702 PRINTK_AUD_FMTX("%s \n", __func__);
703 return virt_to_page(dummy_page[substream->stream]); /* the same page */
704 }
705
706 static struct snd_pcm_ops mtk_fmtx_ops =
707 {
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,
719 };
720
721 static struct snd_soc_platform_driver mtk_fmtx_soc_platform =
722 {
723 .ops = &mtk_fmtx_ops,
724 .pcm_new = mtk_asoc_pcm_fmtx_new,
725 .probe = mtk_afe_fmtx_probe,
726 };
727
728 static int mtk_fmtx_probe(struct platform_device *pdev)
729 {
730 //int ret = 0;
731 PRINTK_AUD_FMTX("%s \n", __func__);
732
733 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
734 if (!pdev->dev.dma_mask)
735 {
736 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
737 }
738
739 if (pdev->dev.of_node)
740 {
741 dev_set_name(&pdev->dev, "%s", MT_SOC_FM_MRGTX_PCM);
742 }
743
744 PRINTK_AUD_FMTX("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
745
746 mDev = &pdev->dev;
747
748 return snd_soc_register_platform(&pdev->dev,
749 &mtk_fmtx_soc_platform);
750 }
751
752 static int mtk_asoc_pcm_fmtx_new(struct snd_soc_pcm_runtime *rtd)
753 {
754 int ret = 0;
755 PRINTK_AUD_FMTX("%s\n", __func__);
756 return ret;
757 }
758
759 static int mtk_afe_fmtx_probe(struct snd_soc_platform *platform)
760 {
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);
766
767 return 0;
768 }
769
770 static int mtk_fmtx_remove(struct platform_device *pdev)
771 {
772 PRINTK_AUD_FMTX("%s \n", __func__);
773 snd_soc_unregister_platform(&pdev->dev);
774 return 0;
775 }
776
777 #ifdef CONFIG_OF
778 static const struct of_device_id mt_soc_pcm_fmtx_of_ids[] =
779 {
780 { .compatible = "mediatek,mt_soc_pcm_fmtx", },
781 {}
782 };
783 #endif
784
785 static struct platform_driver mtk_fmtx_driver =
786 {
787 .driver = {
788 .name = MT_SOC_FM_MRGTX_PCM,
789 .owner = THIS_MODULE,
790 #ifdef CONFIG_OF
791 .of_match_table = mt_soc_pcm_fmtx_of_ids,
792 #endif
793 },
794 .probe = mtk_fmtx_probe,
795 .remove = mtk_fmtx_remove,
796 };
797
798 #ifndef CONFIG_OF
799 static struct platform_device *soc_mtkfmtx_dev;
800 #endif
801
802 static int __init mtk_soc_platform_init(void)
803 {
804 int ret;
805 PRINTK_AUD_FMTX("%s \n", __func__);
806 #ifndef CONFIG_OF
807 soc_mtkfmtx_dev = platform_device_alloc(MT_SOC_FM_MRGTX_PCM, -1);
808 if (!soc_mtkfmtx_dev)
809 {
810 return -ENOMEM;
811 }
812
813 ret = platform_device_add(soc_mtkfmtx_dev);
814 if (ret != 0)
815 {
816 platform_device_put(soc_mtkfmtx_dev);
817 return ret;
818 }
819 #endif
820 ret = platform_driver_register(&mtk_fmtx_driver);
821 return ret;
822
823 }
824 module_init(mtk_soc_platform_init);
825
826 static void __exit mtk_soc_platform_exit(void)
827 {
828 PRINTK_AUD_FMTX("%s \n", __func__);
829
830 platform_driver_unregister(&mtk_fmtx_driver);
831 }
832 module_exit(mtk_soc_platform_exit);
833
834 MODULE_DESCRIPTION("AFE PCM module platform driver");
835 MODULE_LICENSE("GPL");
836
837