import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / sound / soc / mediatek / mt_soc_audio_v2 / mt_soc_pcm_hp_impedance.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_hp_impedance.c
21 *
22 * Project:
23 * --------
24 * Audio Driver Kernel Function
25 *
26 * Description:
27 * ------------
28 * Audio dl1 impedance setting
29 *
30 * Author:
31 * -------
32 * Chipeng Chang
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 "AudDrv_Common.h"
53 #include "AudDrv_Def.h"
54 #include "AudDrv_Afe.h"
55 #include "AudDrv_Ana.h"
56 #include "AudDrv_Clk.h"
57 #include "AudDrv_Kernel.h"
58 #include "mt_soc_afe_control.h"
59 #include "mt_soc_digital_type.h"
60 #include "mt_soc_pcm_common.h"
61 #include "mt_soc_codec_63xx.h"
62
63 #include <mach/upmu_sw.h>
64 #include <mach/upmu_hw.h>
65 #include <mach/mt_pmic_wrap.h>
66 #include <mach/mt_gpio.h>
67 #include <linux/time.h>
68 #include <mach/pmic_mt6325_sw.h>
69 #include <cust_pmic.h>
70 #include <cust_battery_meter.h>
71 #include <linux/dma-mapping.h>
72
73 static AFE_MEM_CONTROL_T *pHp_impedance_MemControl = NULL;
74 static const int DCoffsetDefault = 1500; //95: 1622
75 static const int DCoffsetVariance = 2; //95: 90 // 5%
76
77 static const int mDcRangestep = 7;
78 static const int HpImpedancePhase1Step = 150;
79 static const int HpImpedancePhase2Step = 400;
80 static const int HpImpedancePhase1AdcValue = 1200;
81 static const int HpImpedancePhase2AdcValue = 7200;
82 static struct snd_dma_buffer *Dl1_Playback_dma_buf = NULL;
83
84 extern int PMIC_IMM_GetOneChannelValue(int dwChannel, int deCount, int trimd);
85
86 /*
87 * function implementation
88 */
89
90 void StartAudioPcmHardware(void);
91 void StopAudioPcmHardware(void);
92 static int mtk_soc_hp_impedance_probe(struct platform_device *pdev);
93 static int mtk_soc_pcm_hp_impedance_close(struct snd_pcm_substream *substream);
94 static int mtk_asoc_pcm_hp_impedance_new(struct snd_soc_pcm_runtime *rtd);
95 static int mtk_asoc_dhp_impedance_probe(struct snd_soc_platform *platform);
96
97 static struct snd_pcm_hardware mtk_pcm_hp_impedance_hardware =
98 {
99 .info = (SNDRV_PCM_INFO_MMAP |
100 SNDRV_PCM_INFO_INTERLEAVED |
101 SNDRV_PCM_INFO_RESUME |
102 SNDRV_PCM_INFO_MMAP_VALID),
103 .formats = SND_SOC_ADV_MT_FMTS,
104 .rates = SOC_HIGH_USE_RATE,
105 .rate_min = SOC_HIGH_USE_RATE_MIN,
106 .rate_max = SOC_HIGH_USE_RATE_MAX,
107 .channels_min = SOC_NORMAL_USE_CHANNELS_MIN,
108 .channels_max = SOC_NORMAL_USE_CHANNELS_MAX,
109 .buffer_bytes_max = Dl1_MAX_BUFFER_SIZE,
110 .period_bytes_max = MAX_PERIOD_SIZE,
111 .periods_min = SOC_NORMAL_USE_PERIODS_MIN,
112 .periods_max = SOC_NORMAL_USE_PERIODS_MAX,
113 .fifo_size = 0,
114 };
115
116 #if 0 //not used
117 static int mtk_pcm_hp_impedance_stop(struct snd_pcm_substream *substream)
118 {
119 PRINTK_AUDDRV("mtk_pcm_hp_impedance_stop \n");
120 return 0;
121 }
122
123 static int mtk_pcm_hp_impedance_start(struct snd_pcm_substream *substream)
124 {
125 return 0;
126 }
127 #endif
128
129 static snd_pcm_uframes_t mtk_pcm_hp_impedance_pointer(struct snd_pcm_substream *substream)
130 {
131 return 0;
132 }
133
134 static void SetDL1Buffer(struct snd_pcm_substream *substream,
135 struct snd_pcm_hw_params *hw_params)
136 {
137 struct snd_pcm_runtime *runtime = substream->runtime;
138 AFE_BLOCK_T *pblock = &pHp_impedance_MemControl->rBlock;
139 pblock->pucPhysBufAddr = runtime->dma_addr;
140 pblock->pucVirtBufAddr = runtime->dma_area;
141 pblock->u4BufferSize = runtime->dma_bytes;
142 pblock->u4SampleNumMask = 0x001f; // 32 byte align
143 pblock->u4WriteIdx = 0;
144 pblock->u4DMAReadIdx = 0;
145 pblock->u4DataRemained = 0;
146 pblock->u4fsyncflag = false;
147 pblock->uResetFlag = true;
148 printk("SetDL1Buffer u4BufferSize = %d pucVirtBufAddr = %p pucPhysBufAddr = 0x%x\n",
149 pblock->u4BufferSize, pblock->pucVirtBufAddr, pblock->pucPhysBufAddr);
150 // set dram address top hardware
151 Afe_Set_Reg(AFE_DL1_BASE , pblock->pucPhysBufAddr , 0xffffffff);
152 Afe_Set_Reg(AFE_DL1_END , pblock->pucPhysBufAddr + (pblock->u4BufferSize - 1), 0xffffffff);
153 memset((void *)pblock->pucVirtBufAddr, 0, pblock->u4BufferSize);
154
155 }
156
157
158 static int mtk_pcm_hp_impedance_params(struct snd_pcm_substream *substream,
159 struct snd_pcm_hw_params *hw_params)
160 {
161 int ret = 0;
162 printk("mtk_pcm_hp_impedance_params \n");
163
164 /* runtime->dma_bytes has to be set manually to allow mmap */
165 substream->runtime->dma_bytes = params_buffer_bytes(hw_params);
166
167 substream->runtime->dma_area = Dl1_Playback_dma_buf->area;
168 substream->runtime->dma_addr = Dl1_Playback_dma_buf->addr;
169 SetDL1Buffer(substream, hw_params);
170
171 PRINTK_AUDDRV("dma_bytes = %zu dma_area = %p dma_addr = 0x%lx\n",
172 substream->runtime->dma_bytes, substream->runtime->dma_area, (long)substream->runtime->dma_addr);
173 return ret;
174 }
175
176 static int mtk_pcm_hp_impedance_hw_free(struct snd_pcm_substream *substream)
177 {
178 PRINTK_AUDDRV("mtk_pcm_hp_impedance_hw_free \n");
179 return 0;
180 }
181
182
183 static struct snd_pcm_hw_constraint_list constraints_hp_impedance_sample_rates =
184 {
185 .count = ARRAY_SIZE(soc_high_supported_sample_rates),
186 .list = soc_high_supported_sample_rates,
187 .mask = 0,
188 };
189
190 static int mtk_pcm_hp_impedance_open(struct snd_pcm_substream *substream)
191 {
192 int ret = 0;
193 struct snd_pcm_runtime *runtime = substream->runtime;
194 PRINTK_AUDDRV("mtk_pcm_hp_impedance_open\n");
195 AudDrv_Clk_On();
196 AudDrv_Emi_Clk_On();
197 pHp_impedance_MemControl = Get_Mem_ControlT(Soc_Aud_Digital_Block_MEM_DL1);
198 runtime->hw = mtk_pcm_hp_impedance_hardware;
199 memcpy((void *)(&(runtime->hw)), (void *)&mtk_pcm_hp_impedance_hardware , sizeof(struct snd_pcm_hardware));
200
201 ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
202 &constraints_hp_impedance_sample_rates);
203
204 if (ret < 0)
205 {
206 PRINTK_AUDDRV("snd_pcm_hw_constraint_integer failed\n");
207 }
208
209
210 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
211 {
212 PRINTK_AUDDRV("SNDRV_PCM_STREAM_PLAYBACK mtkalsa_playback_constraints\n");
213 }
214 else
215 {
216
217 }
218
219 if (ret < 0)
220 {
221 PRINTK_AUDDRV("mtk_soc_pcm_hp_impedance_close\n");
222 mtk_soc_pcm_hp_impedance_close(substream);
223 return ret;
224 }
225 return 0;
226 }
227
228
229 bool mPrepareDone = false;
230 static int mtk_pcm_hp_impedance_prepare(struct snd_pcm_substream *substream)
231 {
232 bool mI2SWLen;
233 struct snd_pcm_runtime *runtime = substream->runtime;
234 printk("mtk_pcm_hp_impedance_prepare \n");
235 if (mPrepareDone == false)
236 {
237 if (runtime->format == SNDRV_PCM_FORMAT_S32_LE || runtime->format == SNDRV_PCM_FORMAT_U32_LE)
238 {
239 SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL1, AFE_WLEN_32_BIT_ALIGN_8BIT_0_24BIT_DATA);
240 SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL2, AFE_WLEN_32_BIT_ALIGN_8BIT_0_24BIT_DATA);
241 SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O03);
242 SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O04);
243 mI2SWLen = Soc_Aud_I2S_WLEN_WLEN_32BITS;
244 }
245 else
246 {
247 SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL1, AFE_WLEN_16_BIT);
248 SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL2, AFE_WLEN_16_BIT);
249 SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O03);
250 SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O04);
251 mI2SWLen = Soc_Aud_I2S_WLEN_WLEN_16BITS;
252 }
253 SetSampleRate(Soc_Aud_Digital_Block_MEM_I2S, runtime->rate);
254 if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC) == false)
255 {
256 SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
257 SetI2SDacOut(substream->runtime->rate, false, mI2SWLen);
258 SetI2SDacEnable(true);
259 }
260 else
261 {
262 SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
263 }
264
265 SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I05, Soc_Aud_InterConnectionOutput_O03);
266 SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I06, Soc_Aud_InterConnectionOutput_O04);
267
268 SetSampleRate(Soc_Aud_Digital_Block_MEM_DL1, runtime->rate);
269 SetChannels(Soc_Aud_Digital_Block_MEM_DL1, runtime->channels);
270 SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1, true);
271
272 EnableAfe(true);
273 mPrepareDone = true;
274 }
275 return 0;
276 }
277
278
279 static int mtk_soc_pcm_hp_impedance_close(struct snd_pcm_substream *substream)
280 {
281 //struct snd_pcm_runtime *runtime = substream->runtime;
282 printk("%s \n", __func__);
283 if (mPrepareDone == true)
284 {
285 mPrepareDone = false;
286 SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, false);
287 SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1, false);
288 EnableAfe(false);
289 }
290 AudDrv_Emi_Clk_Off();
291 AudDrv_Clk_Off();
292 return 0;
293 }
294
295 static int mtk_pcm_hp_impedance_trigger(struct snd_pcm_substream *substream, int cmd)
296 {
297 PRINTK_AUDDRV("mtk_pcm_hp_impedance_trigger cmd = %d\n", cmd);
298 switch (cmd)
299 {
300 case SNDRV_PCM_TRIGGER_START:
301 case SNDRV_PCM_TRIGGER_RESUME:
302 case SNDRV_PCM_TRIGGER_STOP:
303 case SNDRV_PCM_TRIGGER_SUSPEND:
304 break;
305 }
306 return -EINVAL;
307 }
308
309 static int mtk_pcm_hp_impedance_copy(struct snd_pcm_substream *substream,
310 int channel, snd_pcm_uframes_t pos,
311 void __user *dst, snd_pcm_uframes_t count)
312 {
313 return 0;
314 }
315
316 static int mtk_pcm_hp_impedance_silence(struct snd_pcm_substream *substream,
317 int channel, snd_pcm_uframes_t pos,
318 snd_pcm_uframes_t count)
319 {
320 PRINTK_AUDDRV("%s \n", __func__);
321 return 0; /* do nothing */
322 }
323
324 static void *dummy_page[2];
325
326 static struct page *mtk_pcm_hp_impedance_page(struct snd_pcm_substream *substream,
327 unsigned long offset)
328 {
329 PRINTK_AUDDRV("%s \n", __func__);
330 return virt_to_page(dummy_page[substream->stream]); /* the same page */
331 }
332
333
334 static unsigned short mhp_impedance = 0;
335 static unsigned short mAuxAdc_Offset = 0;
336 static int Audio_HP_ImpeDance_Set(struct snd_kcontrol *kcontrol,
337 struct snd_ctl_elem_value *ucontrol)
338 {
339 const int off_counter = 20;
340 printk("%s \n", __func__);
341 AudDrv_Clk_On();
342 // set dc value to hardware
343 mhp_impedance = ucontrol->value.integer.value[0];
344 msleep(1 * 1000);
345 printk("3 %s \n", __func__);
346 // start get adc value
347 if (mAuxAdc_Offset == 0)
348 {
349 OpenAnalogTrimHardware(true);
350 setOffsetTrimMux(AUDIO_OFFSET_TRIM_MUX_GROUND);
351 setOffsetTrimBufferGain(3);
352 EnableTrimbuffer(true);
353 msleep(5);
354 mAuxAdc_Offset = PMIC_IMM_GetOneChannelValue(AUX_HP_AP, off_counter, 0);
355 printk("mAuxAdc_Offset= %d \n", mAuxAdc_Offset);
356
357 memset((void *)Get_Afe_SramBase_Pointer(), ucontrol->value.integer.value[0], AFE_INTERNAL_SRAM_SIZE);
358 msleep(5 * 1000);
359 printk("4 %s \n", __func__);
360
361 EnableTrimbuffer(false);
362 OpenAnalogTrimHardware(false);
363 }
364
365 if (mhp_impedance == 1)
366 {
367 printk("start open hp impedance setting\n");
368 OpenHeadPhoneImpedanceSetting(true);
369 setOffsetTrimMux(AUDIO_OFFSET_TRIM_MUX_HPR);
370 setOffsetTrimBufferGain(3);
371 EnableTrimbuffer(true);
372 setHpGainZero();
373 memset((void *)Get_Afe_SramBase_Pointer(), ucontrol->value.integer.value[0], AFE_INTERNAL_SRAM_SIZE);
374 msleep(5 * 1000);
375 printk("5 %s \n", __func__);
376 }
377 else if (mhp_impedance == 0)
378 {
379 printk("stop hp impedance setting\n");
380 OpenHeadPhoneImpedanceSetting(false);
381 setOffsetTrimMux(AUDIO_OFFSET_TRIM_MUX_GROUND);
382 EnableTrimbuffer(false);
383 SetSdmLevel(AUDIO_SDM_LEVEL_NORMAL);
384 }
385 else
386 {
387 unsigned short value = 0;
388 for (value = 0; value < 10000 ; value += 200)
389 {
390 unsigned short temp = value;
391 static unsigned short dcoffset;
392 volatile unsigned short *Sramdata;
393 int i = 0;
394 printk("set sram to dc value = %d \n", temp);
395 Sramdata = Get_Afe_SramBase_Pointer();
396 for (i = 0; i < AFE_INTERNAL_SRAM_SIZE >> 1 ; i ++)
397 {
398 *Sramdata = temp;
399 Sramdata++;
400 }
401 Sramdata = Get_Afe_SramBase_Pointer();
402 printk("Sramdata = %p \n", Sramdata);
403 printk("Sramdata = 0x%x Sramdata+1 = 0x%x Sramdata+2 = 0x%x Sramdata+3 = 0x%x\n", *Sramdata, *(Sramdata + 1), *(Sramdata + 2), *(Sramdata + 3));
404 Sramdata += 4;
405 printk("Sramdata = %p \n", Sramdata);
406 printk("Sramdata = 0x%x Sramdata+1 = 0x%x Sramdata+2 = 0x%x Sramdata+3 = 0x%x\n", *Sramdata, *(Sramdata + 1), *(Sramdata + 2), *(Sramdata + 3));
407 //memset((void *)Get_Afe_SramBase_Pointer(), ucontrol->value.integer.value[0], AFE_INTERNAL_SRAM_SIZE);
408 msleep(20);
409 dcoffset = 0;
410 dcoffset = PMIC_IMM_GetOneChannelValue(AUX_HP_AP, off_counter, 0);
411 printk("dcoffset= %d \n", dcoffset);
412 msleep(3 * 1000);
413 }
414 }
415
416 AudDrv_Clk_Off();
417 return 0;
418 }
419
420 static int phase1table[] = {7, 13};
421 static unsigned short Phase1Check(unsigned short adcvalue, unsigned int adcoffset)
422 {
423 unsigned int AdcDiff = adcvalue - adcoffset;
424 if (adcvalue < adcoffset)
425 {
426 return 0;
427 }
428 if (AdcDiff > 300)
429 {
430 return AUDIO_HP_IMPEDANCE32;
431 }
432 else if (AdcDiff >= phase1table[1])
433 {
434 return AUDIO_HP_IMPEDANCE256;
435 }
436 else if ((AdcDiff >= phase1table[0]) && (AdcDiff <= phase1table[1]))
437 {
438 return AUDIO_HP_IMPEDANCE128;
439 }
440 else
441 {
442 return 0;
443 }
444 }
445
446 static int phase2table[] = {10, 24};
447 static unsigned short Phase2Check(unsigned short adcvalue, unsigned int adcoffset)
448 {
449 unsigned int AdcDiff = adcvalue - adcoffset;
450 if (adcvalue < adcoffset)
451 {
452 return AUDIO_HP_IMPEDANCE16;
453 }
454 if (AdcDiff < phase2table[0])
455 {
456 return AUDIO_HP_IMPEDANCE16;
457 }
458 else if (AdcDiff >= phase2table[1])
459 {
460 return AUDIO_HP_IMPEDANCE64;
461 }
462 else
463 {
464 return AUDIO_HP_IMPEDANCE32;
465 }
466 }
467
468 static void FillDatatoDlmemory(volatile unsigned int *memorypointer, unsigned int fillsize, unsigned short value)
469 {
470 int addr = 0;
471 unsigned int tempvalue = value;
472 tempvalue = tempvalue << 16;
473 tempvalue |= value;
474 // set memory to DC value
475 for (addr = 0; addr < (fillsize >> 2) ; addr++)
476 {
477 *memorypointer = tempvalue;
478 memorypointer++;
479 }
480 }
481
482 static unsigned short dcinit_value = 0;
483 static void CheckDcinitValue(void)
484 {
485 if (dcinit_value > (DCoffsetDefault + DCoffsetVariance))
486 {
487 printk("%s dcinit_value = %d\n", __func__, dcinit_value);
488 dcinit_value = DCoffsetDefault;
489 }
490 else if (dcinit_value < (DCoffsetDefault - DCoffsetVariance))
491 {
492 printk("%s dcinit_value = %d\n", __func__, dcinit_value);
493 dcinit_value = DCoffsetDefault;
494 }
495 }
496
497 static void ApplyDctoDl(void)
498 {
499 unsigned short value = 0 , average = 0;
500 unsigned short dcoffset , dcoffset2, dcoffset3;
501 printk("%s\n", __func__);
502
503 dcinit_value = DCoffsetDefault;
504 for (value = 0; value <= (HpImpedancePhase2AdcValue + HpImpedancePhase2Step) ; value += HpImpedancePhase1Step)
505 {
506 volatile unsigned int *Sramdata = (unsigned int *)(Dl1_Playback_dma_buf->area);
507 FillDatatoDlmemory(Sramdata , Dl1_Playback_dma_buf->bytes , value);
508 // apply to dram
509
510 // add dcvalue for phase boost
511 if (value > HpImpedancePhase1AdcValue)
512 {
513 value += HpImpedancePhase1Step;
514 }
515
516 // save for DC =0 offset
517 if (value == 0)
518 {
519 //get adc value
520 msleep(1);
521 dcoffset = PMIC_IMM_GetOneChannelValue(AUX_HP_AP, 5, 0);
522 dcoffset2 = PMIC_IMM_GetOneChannelValue(AUX_HP_AP, 5, 0);
523 dcoffset3 = PMIC_IMM_GetOneChannelValue(AUX_HP_AP, 5, 0);
524 average = (dcoffset + dcoffset2 + dcoffset3) / 3;
525 dcinit_value = average;
526 CheckDcinitValue();
527 printk("dcinit_value = %d average = %d value = %d \n", dcinit_value, average, value);
528 }
529
530 // start checking
531 if (value == HpImpedancePhase1AdcValue)
532 {
533 //get adc value
534 msleep(1);
535 dcoffset = PMIC_IMM_GetOneChannelValue(AUX_HP_AP, 5, 0);
536 dcoffset2 = PMIC_IMM_GetOneChannelValue(AUX_HP_AP, 5, 0);
537 dcoffset3 = PMIC_IMM_GetOneChannelValue(AUX_HP_AP, 5, 0);
538 average = (dcoffset + dcoffset2 + dcoffset3) / 3;
539 mhp_impedance = Phase1Check(average, dcinit_value);
540 printk("value = %d average = %d dcinit_value = %d mhp_impedance = %d \n ", value, average, dcinit_value, mhp_impedance);
541 if (mhp_impedance)
542 {
543 break;
544 }
545 }
546 else if (value >= HpImpedancePhase2AdcValue)
547 {
548 //get adc value
549 msleep(1);
550 dcoffset = PMIC_IMM_GetOneChannelValue(AUX_HP_AP, 5, 0);
551 dcoffset2 = PMIC_IMM_GetOneChannelValue(AUX_HP_AP, 5, 0);
552 dcoffset3 = PMIC_IMM_GetOneChannelValue(AUX_HP_AP, 5, 0);
553 average = (dcoffset + dcoffset2 + dcoffset3) / 3;
554 mhp_impedance = Phase2Check(average, dcinit_value);
555 printk("value = %d average = %d dcinit_value = %d \n ", value, average, dcinit_value);
556 break;
557 }
558 }
559 }
560
561 static int Audio_HP_ImpeDance_Get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
562 {
563 printk("+ %s()\n", __func__);
564 AudDrv_Clk_On();
565 if (OpenHeadPhoneImpedanceSetting(true) == true)
566 {
567 setOffsetTrimMux(AUDIO_OFFSET_TRIM_MUX_HPR);
568 setOffsetTrimBufferGain(2);
569 EnableTrimbuffer(true);
570 setHpGainZero();
571 ApplyDctoDl();
572 SetSdmLevel(AUDIO_SDM_LEVEL_MUTE);
573 msleep(1);
574 OpenHeadPhoneImpedanceSetting(false);
575 setOffsetTrimMux(AUDIO_OFFSET_TRIM_MUX_GROUND);
576 EnableTrimbuffer(false);
577 SetSdmLevel(AUDIO_SDM_LEVEL_NORMAL);
578 }
579 else
580 {
581 printk("Audio_HP_ImpeDance_Get just do nothing \n");
582 }
583 AudDrv_Clk_Off();
584 ucontrol->value.integer.value[0] = mhp_impedance;
585 printk("- %s()\n", __func__);
586 return 0;
587 }
588
589 static const struct snd_kcontrol_new Audio_snd_hp_impedance_controls[] =
590 {
591 SOC_SINGLE_EXT("Audio HP ImpeDance Setting", SND_SOC_NOPM, 0, 65536, 0, Audio_HP_ImpeDance_Get, Audio_HP_ImpeDance_Set),
592 };
593
594
595 static struct snd_pcm_ops mtk_hp_impedance_ops =
596 {
597 .open = mtk_pcm_hp_impedance_open,
598 .close = mtk_soc_pcm_hp_impedance_close,
599 .ioctl = snd_pcm_lib_ioctl,
600 .hw_params = mtk_pcm_hp_impedance_params,
601 .hw_free = mtk_pcm_hp_impedance_hw_free,
602 .prepare = mtk_pcm_hp_impedance_prepare,
603 .trigger = mtk_pcm_hp_impedance_trigger,
604 .pointer = mtk_pcm_hp_impedance_pointer,
605 .copy = mtk_pcm_hp_impedance_copy,
606 .silence = mtk_pcm_hp_impedance_silence,
607 .page = mtk_pcm_hp_impedance_page,
608 };
609
610 static struct snd_soc_platform_driver mtk_soc_platform =
611 {
612 .ops = &mtk_hp_impedance_ops,
613 .pcm_new = mtk_asoc_pcm_hp_impedance_new,
614 .probe = mtk_asoc_dhp_impedance_probe,
615 };
616
617 static int mtk_soc_hp_impedance_probe(struct platform_device *pdev)
618 {
619 PRINTK_AUDDRV("%s \n", __func__);
620
621 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
622 if (!pdev->dev.dma_mask)
623 {
624 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
625 }
626
627 if (pdev->dev.of_node)
628 {
629 dev_set_name(&pdev->dev, "%s", MT_SOC_HP_IMPEDANCE_PCM);
630 }
631 PRINTK_AUDDRV("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
632 return snd_soc_register_platform(&pdev->dev,
633 &mtk_soc_platform);
634 }
635
636 static int mtk_asoc_pcm_hp_impedance_new(struct snd_soc_pcm_runtime *rtd)
637 {
638 int ret = 0;
639 PRINTK_AUDDRV("%s\n", __func__);
640 return ret;
641 }
642
643
644 static int mtk_asoc_dhp_impedance_probe(struct snd_soc_platform *platform)
645 {
646 PRINTK_AUDDRV("mtk_asoc_dhp_impedance_probe\n");
647 //add controls
648 snd_soc_add_platform_controls(platform, Audio_snd_hp_impedance_controls,
649 ARRAY_SIZE(Audio_snd_hp_impedance_controls));
650 // allocate dram
651 AudDrv_Allocate_mem_Buffer(platform->dev, Soc_Aud_Digital_Block_MEM_DL1, Dl1_MAX_BUFFER_SIZE);
652 Dl1_Playback_dma_buf = Get_Mem_Buffer(Soc_Aud_Digital_Block_MEM_DL1);
653 return 0;
654 }
655
656 static int mtk_hp_impedance_remove(struct platform_device *pdev)
657 {
658 PRINTK_AUDDRV("%s \n", __func__);
659 snd_soc_unregister_platform(&pdev->dev);
660 return 0;
661 }
662
663 #ifdef CONFIG_OF
664 static const struct of_device_id Mt_soc_pcm_hp_impedance_of_ids[] =
665 {
666 { .compatible = "mediatek,Mt_soc_pcm_hp_impedance", },
667 {}
668 };
669 #endif
670
671 static struct platform_driver mtk_hp_impedance_driver =
672 {
673 .driver = {
674 .name = MT_SOC_HP_IMPEDANCE_PCM,
675 .owner = THIS_MODULE,
676 #ifdef CONFIG_OF
677 .of_match_table = Mt_soc_pcm_hp_impedance_of_ids,
678 #endif
679 },
680 .probe = mtk_soc_hp_impedance_probe,
681 .remove = mtk_hp_impedance_remove,
682 };
683
684 #ifndef CONFIG_OF
685 static struct platform_device *soc_mtk_hp_impedance_dev;
686 #endif
687
688 static int __init mtk_soc_hp_impedance_platform_init(void)
689 {
690 int ret;
691 PRINTK_AUDDRV("%s \n", __func__);
692 #ifndef CONFIG_OF
693 soc_mtk_hp_impedance_dev = platform_device_alloc(MT_SOC_HP_IMPEDANCE_PCM, -1);
694 if (!soc_mtk_hp_impedance_dev)
695 {
696 return -ENOMEM;
697 }
698
699 ret = platform_device_add(soc_mtk_hp_impedance_dev);
700 if (ret != 0)
701 {
702 platform_device_put(soc_mtk_hp_impedance_dev);
703 return ret;
704 }
705 #endif
706 ret = platform_driver_register(&mtk_hp_impedance_driver);
707 return ret;
708
709 }
710 module_init(mtk_soc_hp_impedance_platform_init);
711
712 static void __exit mtk_soc_hp_impedance_platform_exit(void)
713 {
714 PRINTK_AUDDRV("%s \n", __func__);
715
716 platform_driver_unregister(&mtk_hp_impedance_driver);
717 }
718 module_exit(mtk_soc_hp_impedance_platform_exit);
719
720 MODULE_DESCRIPTION("hp impedance module platform driver");
721 MODULE_LICENSE("GPL");
722
723