blob: ff07416fc94569aa3a0870210c11663016743e89 [file] [log] [blame]
xf.lied996a22025-03-13 23:49:05 -07001/*
2 * zx297520v3_es8312.c -- zx298501-dummycodec ALSA SoC Audio board driver
3 *
4 * Copyright (C) 2022, ZTE Corporation.
5 *
6 * Based on smdk_wm8994.c
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <sound/pcm_params.h>
14#include <sound/soc.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_device.h>
18
19
20
21#include <linux/clk.h>
22#include <linux/gpio.h>
23#include <linux/module.h>
24#include <linux/delay.h>
25//#include <sound/tlv.h>
26//#include <sound/soc.h>
27//#include <sound/jack.h>
28//#include <sound/zx29_snd_platform.h>
29//#include <mach/iomap.h>
30//#include <mach/board.h>
31#include <linux/of_gpio.h>
32
33#include <linux/i2c.h>
34#include <linux/of_gpio.h>
35#include <linux/regmap.h>
36
37
38#include "i2s.h"
xf.li6b423c72025-03-14 00:07:42 -070039#include "pub_debug_info.h"
xf.lied996a22025-03-13 23:49:05 -070040
41#define ZX29_I2S_TOP_LOOP_REG 0x60
42
43
44#if 1
45
46#define ZXIC_MCLK 26000000
47#define ZX29_AK4940_FREQ 26000000
48
49#define ZXIC_PLL_CLKIN_MCLK 0
50
51
52#define zx_reg_sync_write(v, a) \
53 do { \
54 iowrite32(v, a); \
55 } while (0)
56
57#define zx_read_reg(addr) \
58 ioread32(addr)
59
60#define zx_write_reg(addr, val) \
61 zx_reg_sync_write(val, addr)
62
63
64
65struct zx29_board_data {
66 const char *name;
67 struct device *dev;
68
69 int codec_refclk;
70 int gpio_pwen;
71 int gpio_pdn;
72 void __iomem *sys_base_va;
73};
74
75//#define AON_WIFI_BT_CLK_CFG2 ((volatile unsigned int *)(ZX_TOP_CRM_BASE + 0x94))
76 /* Default ZX29s */
77static struct zx29_board_data zx29_platform_data = {
78 .codec_refclk = ZX29_AK4940_FREQ,
79};
80 static struct platform_device *zx29_snd_device;
81
82 static DEFINE_RAW_SPINLOCK(codec_pa_lock);
83
84 static int set_path_stauts_switch(struct snd_kcontrol *kcontrol,
85 struct snd_ctl_elem_value *ucontrol);
86 static int get_path_stauts_switch(struct snd_kcontrol *kcontrol,
87 struct snd_ctl_elem_value *ucontrol);
88
89
90#ifdef USE_ALSA_VOICE_FUNC
91 extern int zDrv_Audio_Printf(void *pFormat, ...);
92 extern int zDrvVp_GetVol_Wrap(void);
93 extern int zDrvVp_SetVol_Wrap(int volume);
94 extern int zDrvVp_GetPath_Wrap(void);
95 extern int zDrvVp_SetPath_Wrap(int path);
96 extern int zDrvVp_SetMute_Wrap(bool enable);
97 extern bool zDrvVp_GetMute_Wrap(void);
98 extern int zDrvVp_SetTone_Wrap(int toneNum);
99
100 static int vp_GetPath(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
101 static int vp_SetPath(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
102 static int vp_SetVol(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
103 static int vp_GetVol(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
104 static int vp_SetMute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
105 static int vp_GetMute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
106 static int vp_SetTone(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
107 static int vp_getTone(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
108
109 static int audio_GetPath(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
110 static int audio_SetPath(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
111
112
113 //static const DECLARE_TLV_DB_SCALE(vp_path_tlv, 0, 300, 0);
114
115 static const char * const vpath_in_text[] = {
116 "handset", "speak", "headset", "bluetooth",
117 };
118
119 static const char *tone_class[] = {
120 "Lowpower", "Sms", "Callstd", "Alarm", "Calltime",
121 };
122
123 static const struct soc_enum vpath_in_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(vpath_in_text), vpath_in_text);
124
125 static const struct soc_enum tone_class_enum[] = {
126 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tone_class), tone_class),
127 };
128
129 static const struct snd_kcontrol_new vp_snd_controls[] = {
130 SOC_ENUM_EXT("voice processing path select",vpath_in_enum,vp_GetPath,vp_SetPath),
131 //SOC_SINGLE_EXT_TLV("voice processing path Volume",0, 5, 5, 0,vp_GetVol, vp_SetVol,vp_path_tlv),
132 SOC_SINGLE_EXT("voice processing path Volume",0, 5, 5, 0,vp_GetVol, vp_SetVol),
133 SOC_SINGLE_EXT("voice uplink mute", 0, 1, 1, 0,vp_GetMute, vp_SetMute),
134 SOC_ENUM_EXT("voice tone sel", tone_class_enum[0], vp_getTone, vp_SetTone),
135 SOC_SINGLE_BOOL_EXT("path stauts dump", 0,get_path_stauts_switch, set_path_stauts_switch),
136 SOC_ENUM_EXT("audio path select",vpath_in_enum,audio_GetPath,audio_SetPath),
137 };
138
139 static int curtonetype = 0;
140 static int vp_getTone(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
141 {
142 ucontrol->value.integer.value[0] = curtonetype;
143 return 0;
144 }
145
146 static int vp_SetTone(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
147 {
148 int vol = 0,ret = 0, tonenum;
149 tonenum = ucontrol->value.integer.value[0];
150 curtonetype = tonenum;
151 //printk("Alsa vp_SetTone tonenum=%d\n", tonenum);
152 //ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetTone_Wrap)(tonenum);
153 if(ret < 0)
154 {
155 printk(KERN_ERR "vp_SetTone fail = %d\n", tonenum);
156 return ret;
157 }
158 return 0;
159 }
160
161 static int vp_SetMute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
162 {
163 int enable = 0,ret = 0;
164 enable = ucontrol->value.integer.value[0];
165 //ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetMute_Wrap)(enable);
166 if(ret < 0)
167 {
168 printk(KERN_ERR "vp_SetMute fail = %d\n",enable);
169 return ret;
170 }
171 return 0;
172 }
173
174 static int vp_GetMute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
175 {
176 //ucontrol->value.integer.value[0] = CPPS_FUNC(cpps_callbacks, zDrvVp_GetMute_Wrap)();
177 return 0;
178 }
179
180 static int vp_SetVol(struct snd_kcontrol *kcontrol,
181 struct snd_ctl_elem_value *ucontrol)
182 {
183 int vol = 0,ret = 0;
184 vol = ucontrol->value.integer.value[0];
185 //ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetVol_Wrap)(vol);
186 if(ret < 0)
187 {
188 printk(KERN_ERR "vp_SetVol fail = %d\n",vol);
189 return ret;
190 }
191 return 0;
192 }
193 static int vp_GetVol(struct snd_kcontrol *kcontrol,
194 struct snd_ctl_elem_value *ucontrol)
195 {
196 //ucontrol->value.integer.value[0] = CPPS_FUNC(cpps_callbacks, zDrvVp_GetVol_Wrap)();
197 return 0;
198 }
199 static int vp_GetPath(struct snd_kcontrol *kcontrol,
200 struct snd_ctl_elem_value *ucontrol)
201 {
202 //ucontrol->value.enumerated.item[0] = CPPS_FUNC(cpps_callbacks, zDrvVp_GetPath_Wrap)();
203 return 0;
204 }
205 static int vp_SetPath(struct snd_kcontrol *kcontrol,
206 struct snd_ctl_elem_value *ucontrol)
207 {
208 int ret = 0,path = 0;
209 unsigned long flags;
210 path = ucontrol->value.enumerated.item[0];
211
212 //ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetPath_Wrap)(path);
213 if(ret < 0)
214 {
215 printk(KERN_ERR "vp_SetPath fail = %d\n",path);
216 return ret;
217 }
218#ifdef _USE_7520V3_PHONE_TYPE_C31F
219 switch (path) {
220 case 0:
221 gpio_set_value(ZX29_GPIO_39, GPIO_LOW);
222 mdelay(1);
223 gpio_set_value(ZX29_GPIO_40, GPIO_LOW);
224 break;
225 case 1:
226 gpio_set_value(ZX29_GPIO_39, GPIO_LOW);
227 mdelay(1);
228 raw_spin_lock_irqsave(&codec_pa_lock, flags);
229 gpio_set_value(ZX29_GPIO_39, GPIO_HIGH);
230 udelay(2);
231 gpio_set_value(ZX29_GPIO_39, GPIO_LOW);
232 udelay(2);
233 gpio_set_value(ZX29_GPIO_39, GPIO_HIGH);
234 raw_spin_unlock_irqrestore(&codec_pa_lock, flags);
235 gpio_set_value(ZX29_GPIO_40, GPIO_HIGH);
236 break;
237 case 2:
238 break;
239 case 3:
240 break;
241 default:
242 break;
243 }
244#endif
245 return 0;
246 }
247
248 static int curpath = 0;
249 static int audio_GetPath(struct snd_kcontrol *kcontrol,
250 struct snd_ctl_elem_value *ucontrol)
251 {
252 ucontrol->value.enumerated.item[0] = curpath;
253 return 0;
254 }
255
256 static int audio_SetPath(struct snd_kcontrol *kcontrol,
257 struct snd_ctl_elem_value *ucontrol)
258 {
259 int ret = 0,path = 0;
260 unsigned long flags;
261
262 path = ucontrol->value.enumerated.item[0];
263 curpath = path;
264#ifdef _USE_7520V3_PHONE_TYPE_C31F
265 switch (path) {
266 case 0:
267 gpio_set_value(ZX29_GPIO_39, GPIO_LOW);
268 mdelay(1);
269 gpio_set_value(ZX29_GPIO_40, GPIO_LOW);
270 break;
271 case 1:
272 gpio_set_value(ZX29_GPIO_39, GPIO_LOW);
273 mdelay(1);
274 raw_spin_lock_irqsave(&codec_pa_lock, flags);
275 gpio_set_value(ZX29_GPIO_39, GPIO_HIGH);
276 udelay(2);
277 gpio_set_value(ZX29_GPIO_39, GPIO_LOW);
278 udelay(2);
279 gpio_set_value(ZX29_GPIO_39, GPIO_HIGH);
280 raw_spin_unlock_irqrestore(&codec_pa_lock, flags);
281 gpio_set_value(ZX29_GPIO_40, GPIO_HIGH);
282 break;
283 case 2:
284 break;
285 case 3:
286 break;
287 default:
288 break;
289 }
290#endif
291 return 0;
292 }
293
294 typedef enum
295 {
296 VP_PATH_HANDSET =0,
297 VP_PATH_SPEAKER,
298 VP_PATH_HEADSET,
299 VP_PATH_BLUETOOTH,
300 VP_PATH_BLUETOOTH_NO_NR,
301 VP_PATH_HSANDSPK,
302
303 VP_PATH_OFF = 255,
304
305 MAX_VP_PATH = VP_PATH_OFF
306 }T_ZDrv_VpPath;
307
308 extern int zDrvVp_Loop(T_ZDrv_VpPath path);
309
310
311//#else
312 static const struct snd_kcontrol_new machine_snd_controls[] = {
313 SOC_SINGLE_BOOL_EXT("path stauts dump", 0,get_path_stauts_switch, set_path_stauts_switch),
314 };
315
316
317
318 //extern int rt5670_hs_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
319
320 int path_stauts_switch = 0;
321 static int set_path_stauts_switch(struct snd_kcontrol *kcontrol,
322 struct snd_ctl_elem_value *ucontrol)
323 {
324 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
325 struct snd_soc_dapm_path *p;
326
327 int path_stauts_switch = ucontrol->value.integer.value[0];
328
329
330 if (path_stauts_switch == 1)
331 {
332 list_for_each_entry(p, &card->paths, list){
333
334 //print_audio("Alsa path name (%s),longname (%s),sink (%s),source (%s),connect %d \n", p->name,p->long_name,p->sink->name,p->source->name,p->connect);
335 //printk("Alsa path longname %s,sink %s,source %s,connect %d \n", p->long_name,p->sink->name,p->source->name,p->connect);
336
337 }
338 }
339 return 0;
340 }
341
342 static int get_path_stauts_switch(struct snd_kcontrol *kcontrol,
343 struct snd_ctl_elem_value *ucontrol)
344 {
345
346 ucontrol->value.integer.value[0] = path_stauts_switch;
347 return 0;
348 };
349#endif
350
351#ifdef CONFIG_SND_SOC_JACK_DECTEC
352
353 static struct snd_soc_jack codec_headset;
354
355 /* Headset jack detection DAPM pins */
356 static struct snd_soc_jack_pin codec_headset_pins[] = {
357 {
358 .pin = "Headphone",
359 .mask = SND_JACK_HEADPHONE,
360 },
361 };
362
363#endif
364
xf.li6b423c72025-03-14 00:07:42 -0700365/* Started by AICoder, pid:53525s2951m0dfb1406409962017998611b17cc1 */
366static int zx29startup(struct snd_pcm_substream *substream)
367{
368 //int ret = 0;
369 print_audio("Alsa Entered func %s\n", __func__);
370 //CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa: zx29_startup device=%d,stream=%d\n", substream->pcm->device, substream->stream);
371
372 struct snd_pcm *pcmC0D0p = snd_lookup_minor_data(16, SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
373 struct snd_pcm *pcmC0D1p = snd_lookup_minor_data(17, SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
374 struct snd_pcm *pcmC0D2p = snd_lookup_minor_data(18, SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
375 struct snd_pcm *pcmC0D3p = snd_lookup_minor_data(19, SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
376 //struct snd_pcm *pcmC0D4p = snd_lookup_minor_data(20, SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
xf.lied996a22025-03-13 23:49:05 -0700377
xf.li6b423c72025-03-14 00:07:42 -0700378 struct snd_pcm *pcmC0D0c = snd_lookup_minor_data(24, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
379 struct snd_pcm *pcmC0D1c = snd_lookup_minor_data(25, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
380 struct snd_pcm *pcmC0D2c = snd_lookup_minor_data(26, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
381 struct snd_pcm *pcmC0D3c = snd_lookup_minor_data(27, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
382 //struct snd_pcm *pcmC0D4c = snd_lookup_minor_data(28, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
383
384 if ((pcmC0D0p == NULL) || (pcmC0D1p == NULL) || (pcmC0D2p == NULL) || (pcmC0D3p == NULL))
385 {
386 print_audio("Alsa Entered func %s, pcmC0D0p=%p, pcmC0D1p=%p, pcmC0D2p=%p, pcmC0D3p=%p\n", __func__,
387 pcmC0D0p, pcmC0D1p, pcmC0D2p, pcmC0D3p);
388 return -EINVAL;
389 }
390 if ((pcmC0D0p->streams[0].substream_opened && pcmC0D1p->streams[0].substream_opened) ||
391 (pcmC0D0p->streams[0].substream_opened && pcmC0D2p->streams[0].substream_opened) ||
392 (pcmC0D0p->streams[0].substream_opened && pcmC0D3p->streams[0].substream_opened) ||
393 (pcmC0D1p->streams[0].substream_opened && pcmC0D2p->streams[0].substream_opened) ||
394 (pcmC0D1p->streams[0].substream_opened && pcmC0D3p->streams[0].substream_opened) ||
395 (pcmC0D2p->streams[0].substream_opened && pcmC0D3p->streams[0].substream_opened))
396 {
397 print_audio("Alsa Entered func %s error busy, pcmC0D0p.opened=%d, pcmC0D1p.opened=%d, pcmC0D2p.opened=%d, pcmC0D3p.opened=%d\n",
398 __func__, pcmC0D0p->streams[0].substream_opened, pcmC0D1p->streams[0].substream_opened,
399 pcmC0D2p->streams[0].substream_opened, pcmC0D3p->streams[0].substream_opened);
400 sc_debug_info_record(MODULE_ID_CAP_AUDIO, "Alsa %s err, opened value pcmC0D0p=%d, pcmC0D1p=%d, pcmC0D2p=%d, pcmC0D3p=%d\n",
401 __func__, pcmC0D0p->streams[0].substream_opened, pcmC0D1p->streams[0].substream_opened,
402 pcmC0D2p->streams[0].substream_opened, pcmC0D3p->streams[0].substream_opened);
403
404 return -EBUSY;
405 //BUG();
406 }
407
408 if ((pcmC0D0c == NULL) || (pcmC0D1c == NULL) || (pcmC0D2c == NULL) || (pcmC0D3c == NULL))
409 {
410 print_audio("Alsa Entered func %s, pcmC0D0c=%p, pcmC0D1c=%p, pcmC0D2c=%p, pcmC0D3c=%p\n", __func__,
411 pcmC0D0c, pcmC0D1c, pcmC0D2c, pcmC0D3c);
412 return -EINVAL;
413 }
414 if ((pcmC0D0c->streams[1].substream_opened && pcmC0D1c->streams[1].substream_opened) ||
415 (pcmC0D0c->streams[1].substream_opened && pcmC0D2c->streams[1].substream_opened) ||
416 (pcmC0D0c->streams[1].substream_opened && pcmC0D3c->streams[1].substream_opened) ||
417 (pcmC0D1c->streams[1].substream_opened && pcmC0D2c->streams[1].substream_opened) ||
418 (pcmC0D1c->streams[1].substream_opened && pcmC0D3c->streams[1].substream_opened) ||
419 (pcmC0D2c->streams[1].substream_opened && pcmC0D3c->streams[1].substream_opened))
420 {
421 print_audio("Alsa Entered func %s error busy, pcmC0D0c.opened=%d, pcmC0D1c.opened=%d, pcmC0D2c.opened=%d,pcmC0D3c.opened=%d\n",
422 __func__, pcmC0D0c->streams[1].substream_opened, pcmC0D1c->streams[1].substream_opened,
423 pcmC0D2c->streams[1].substream_opened, pcmC0D3c->streams[1].substream_opened);
424 sc_debug_info_record(MODULE_ID_CAP_AUDIO, "Alsa %s err, opened value pcmC0D0c=%d, pcmC0D1c=%d, pcmC0D2c=%d, pcmC0D3c=%d\n",
425 __func__, pcmC0D0c->streams[1].substream_opened, pcmC0D1c->streams[1].substream_opened,
426 pcmC0D2c->streams[1].substream_opened, pcmC0D3c->streams[1].substream_opened);
427
428 return -EBUSY;
429 //BUG();
430 }
431
xf.lied996a22025-03-13 23:49:05 -0700432#if 0
xf.li6b423c72025-03-14 00:07:42 -0700433 unsigned long flags;
434 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
435 gpio_set_value(ZX29_GPIO_125, GPIO_LOW);
436 mdelay(1);
437
438 raw_spin_lock_irqsave(&codec_pa_lock, flags);
439 gpio_set_value(ZX29_GPIO_125, GPIO_HIGH);
440 udelay(2);
441 gpio_set_value(ZX29_GPIO_125, GPIO_LOW);
442 udelay(2);
443 gpio_set_value(ZX29_GPIO_125, GPIO_HIGH);
444 udelay(2);
445 gpio_set_value(ZX29_GPIO_125, GPIO_LOW);
446 udelay(2);
447 gpio_set_value(ZX29_GPIO_125, GPIO_HIGH);
448 raw_spin_unlock_irqrestore(&codec_pa_lock, flags);
449 }
xf.lied996a22025-03-13 23:49:05 -0700450#endif
xf.li6b423c72025-03-14 00:07:42 -0700451
452 unsigned int armRegBit = 0;
453 //armRegBit = zx_read_reg(AON_WIFI_BT_CLK_CFG2);
454 //armRegBit &= 0xfffffffe;
455 //armRegBit |= 0x1;
456 //zx_write_reg(AON_WIFI_BT_CLK_CFG2, armRegBit);
457
458 return 0;
459}
460/* Ended by AICoder, pid:53525s2951m0dfb1406409962017998611b17cc1 */
xf.lied996a22025-03-13 23:49:05 -0700461
462 static void zx29_shutdown(struct snd_pcm_substream *substream)
463 {
464 //CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa: zx297520xx_shutdown device=%d, stream=%d\n", substream->pcm->device, substream->stream);
465 // print_audio("Alsa Entered func %s, stream=%d\n", __func__, substream->stream);
466 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
467 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
468 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
469#ifdef _USE_7520V3_PHONE_TYPE_C31F
470 gpio_set_value(ZX29_GPIO_39, GPIO_LOW);
471 mdelay(1);
472 gpio_set_value(ZX29_GPIO_40, GPIO_LOW);
473#endif
474 }
475
476 if (snd_soc_dai_active(cpu_dai))
477 return;
478
479 u32 armRegBit;
480 //armRegBit = zx_read_reg(AON_WIFI_BT_CLK_CFG2);
481 //armRegBit &= 0xfffffffe;
482 //armRegBit |= 0x0;
483 //zx_write_reg(AON_WIFI_BT_CLK_CFG2, armRegBit);
484
485 }
486
487 static void zx29_shutdown2(struct snd_pcm_substream *substream)
488 {
489 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
490 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
491 //CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa: zx29_shutdown2 device=%d, stream=%d\n", substream->pcm->device, substream->stream);
492 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
493#ifdef _USE_7520V3_PHONE_TYPE_C31F
494 gpio_set_value(ZX29_GPIO_39, GPIO_LOW);
495 mdelay(1);
496 gpio_set_value(ZX29_GPIO_40, GPIO_LOW);
497#endif
498#ifdef USE_ALSA_VOICE_FUNC
499 //CPPS_FUNC(cpps_callbacks, zDrvVp_Loop)(VP_PATH_OFF);
500#endif
501 }
502
503 if (snd_soc_dai_active(cpu_dai))
504 return;
505
506 u32 armRegBit;
507 //armRegBit = zx_read_reg(AON_WIFI_BT_CLK_CFG2);
508 //armRegBit &= 0xfffffffe;
509 //armRegBit |= 0x0;
510 //zx_write_reg(AON_WIFI_BT_CLK_CFG2, armRegBit);
511 }
512 static int zx29_init_paiftx(struct snd_soc_pcm_runtime *rtd)
513 {
514 //struct snd_soc_codec *codec = rtd->codec;
515 //struct snd_soc_dapm_context *dapm = &codec->dapm;
516
517 //snd_soc_dapm_enable_pin(dapm, "HPOL");
518 //snd_soc_dapm_enable_pin(dapm, "HPOR");
519
520 /* Other pins NC */
521 // snd_soc_dapm_nc_pin(dapm, "HPOUT2P");
522
523 // print_audio("Alsa Entered func %s\n", __func__);
524
525 return 0;
526 }
527 static int zx29_hw_params(struct snd_pcm_substream *substream,
528 struct snd_pcm_hw_params *params)
529 {
530 print_audio("Alsa: Entered func %s\n", __func__);
531 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
532 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
533 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
534
535 int ret;
536 int rfs = 0, frq_out = 0;
537 switch (params_rate(params)) {
538 case 8000:
539 case 16000:
540 case 11025:
541 case 22050:
542 case 24000:
543 case 32000:
544 case 44100:
545 case 48000:
546 rfs = 32;
547 break;
548 default:
549 {
550 ret = -EINVAL;
551 print_audio("Alsa: rate=%d not support,ret=%d!\n", params_rate(params),ret);
552 return ret;
553 }
554 }
555
556 frq_out = params_rate(params) * rfs * 2;
557
558 /* Set the Codec DAI configuration */
559 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
560 | SND_SOC_DAIFMT_NB_NF
561 | SND_SOC_DAIFMT_CBS_CFS);
562 if (ret < 0){
563
564 print_audio("Alsa: codec dai snd_soc_dai_set_fmt fail,ret=%d!\n",ret);
565 return ret;
566 }
567
568
569 /* Set the AP DAI configuration */
570 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
571 | SND_SOC_DAIFMT_NB_NF
572 | SND_SOC_DAIFMT_CBS_CFS);
573 if (ret < 0){
574
575 print_audio("Alsa: ap dai snd_soc_dai_set_fmt fail,ret=%d!\n",ret);
576 return ret;
577 }
578
579 /* Set the Codec DAI clk */
580 /*ret =snd_soc_dai_set_pll(codec_dai, 0, RT5670_PLL1_S_BCLK1,
581 fs*datawidth*2, 256*fs);
582 if (ret < 0){
583
584 print_audio("Alsa: codec dai clk snd_soc_dai_set_pll fail,ret=%d!\n",ret);
585 return ret;
586 }
587 */
588
589 //ret = snd_soc_dai_set_sysclk(codec_dai, AK4940_CLKID_BCLK,ZXIC_MCLK, SND_SOC_CLOCK_IN);
590 //if (ret < 0){
591 // print_audio("Alsa: codec dai snd_soc_dai_set_sysclk fail,ret=%d!\n",ret);
592 // return ret;
593 // }
594
595 /* Set the AP DAI clk */
596 ret = snd_soc_dai_set_sysclk(cpu_dai, ZX29_I2S_WCLK_SEL,ZX29_I2S_WCLK_FREQ_122M88, SND_SOC_CLOCK_IN);
597 //ret = snd_soc_dai_set_sysclk(cpu_dai, ZX29_I2S_WCLK_SEL,ZX29_I2S_WCLK_FREQ_26M, SND_SOC_CLOCK_IN);
598
599 if (ret < 0){
600 print_audio("Alsa: cpu dai snd_soc_dai_set_sysclk fail,ret=%d!\n",ret);
601 return ret;
602 }
603 print_audio("Alsa: Entered func %s end\n", __func__);
604
605 return 0;
606 }
607
608static int zx29_hw_params_lp(struct snd_pcm_substream *substream,
609 struct snd_pcm_hw_params *params)
610{
611 print_audio("Alsa: Entered func %s\n", __func__);
612 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
613 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
614 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
615
616 int ret;
617 int rfs = 0, frq_out = 0;
618 switch (params_rate(params)) {
619 case 8000:
620 case 16000:
621 case 11025:
622 case 22050:
623 case 24000:
624 case 32000:
625 case 44100:
626 case 48000:
627 rfs = 32;
628 break;
629 default:
630 {
631 ret = -EINVAL;
632 print_audio("Alsa: rate=%d not support,ret=%d!\n", params_rate(params),ret);
633 return ret;
634 }
635 }
636
637 frq_out = params_rate(params) * rfs * 2;
638
639 /* Set the Codec DAI configuration */
640 /*
641
642 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
643 | SND_SOC_DAIFMT_NB_NF
644 | SND_SOC_DAIFMT_CBS_CFS);
645 if (ret < 0){
646
647 print_audio("Alsa: codec dai snd_soc_dai_set_fmt fail,ret=%d!\n",ret);
648 return ret;
649 }
650 */
651
652
653 /* Set the AP DAI configuration */
654 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
655 | SND_SOC_DAIFMT_NB_NF
656 | SND_SOC_DAIFMT_CBS_CFS);
657 if (ret < 0){
658
659 print_audio("Alsa: ap dai snd_soc_dai_set_fmt fail,ret=%d!\n",ret);
660 return ret;
661 }
662
663 /* Set the Codec DAI clk */
664 /*ret =snd_soc_dai_set_pll(codec_dai, 0, RT5670_PLL1_S_BCLK1,
665 fs*datawidth*2, 256*fs);
666 if (ret < 0){
667
668 print_audio("Alsa: codec dai clk snd_soc_dai_set_pll fail,ret=%d!\n",ret);
669 return ret;
670 }
671 */
672 /*
673 ret = snd_soc_dai_set_sysclk(codec_dai, ES8312_CLKID_MCLK,ZXIC_MCLK, SND_SOC_CLOCK_IN);
674 if (ret < 0){
675 print_audio("Alsa: codec dai snd_soc_dai_set_sysclk fail,ret=%d!\n",ret);
676 return ret;
677 }
678 */
679 /* Set the AP DAI clk */
680 ret = snd_soc_dai_set_sysclk(cpu_dai, ZX29_I2S_WCLK_SEL,ZX29_I2S_WCLK_FREQ_26M, SND_SOC_CLOCK_IN);
681
682 if (ret < 0){
683 print_audio("Alsa: cpu dai snd_soc_dai_set_sysclk fail,ret=%d!\n",ret);
684 return ret;
685 }
686 print_audio("Alsa: Entered func %s end\n", __func__);
687
688 return 0;
689}
690
691
692
693
694
695
696 static int zx29_hw_params_voice(struct snd_pcm_substream *substream,
697 struct snd_pcm_hw_params *params)
698 {
699 print_audio("Alsa: Entered func %s\n", __func__);
700 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
701 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
702 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
703
704 int ret;
705 int rfs = 0, frq_out = 0;
706 switch (params_rate(params)) {
707 case 8000:
708 case 16000:
709 case 11025:
710 case 22050:
711 case 24000:
712 case 32000:
713 case 44100:
714 case 48000:
715 rfs = 32;
716 break;
717 default:
718 {
719 ret = -EINVAL;
720 print_audio("Alsa: rate=%d not support,ret=%d!\n", params_rate(params),ret);
721 return ret;
722 }
723 }
724
725 frq_out = params_rate(params) * rfs * 2;
726
727 /* Set the Codec DAI configuration */
728 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
729 | SND_SOC_DAIFMT_NB_NF
730 | SND_SOC_DAIFMT_CBS_CFS);
731 if (ret < 0){
732
733 print_audio("Alsa: codec dai snd_soc_dai_set_fmt fail,ret=%d!\n",ret);
734 return ret;
735 }
736
737
738
739 /* Set the Codec DAI clk */
740 /*ret =snd_soc_dai_set_pll(codec_dai, 0, RT5670_PLL1_S_BCLK1,
741 fs*datawidth*2, 256*fs);
742 if (ret < 0){
743
744 print_audio("Alsa: codec dai clk snd_soc_dai_set_pll fail,ret=%d!\n",ret);
745 return ret;
746 }
747
748
749 ret = snd_soc_dai_set_sysclk(codec_dai, AK4940_CLKID_BCLK,ZXIC_MCLK, SND_SOC_CLOCK_IN);
750 if (ret < 0){
751 print_audio("Alsa: codec dai snd_soc_dai_set_sysclk fail,ret=%d!\n",ret);
752 return ret;
753 }
754
755 */
756
757 print_audio("Alsa: Entered func %s end\n", __func__);
758
759 return 0;
760 }
761
762
763 int zx29_prepare2(struct snd_pcm_substream *substream)
764 {
765 int path, ret;
766 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
767 //ret = CPPS_FUNC(cpps_callbacks, zDrvVp_Loop)(VP_PATH_SPEAKER);
768 if (ret < 0)
769 return -1;
770 }
771
772 return 0;
773 }
774 static void zx29_i2s_top_reg_cfg(void)
775 {
776 unsigned int i2s_top_reg;
777 int ret = 0;
778
779#ifdef CONFIG_USE_PIN_I2S0
780 ret = gpio_request(PIN_I2S0_WS, "i2s0_ws");
781 if (ret < 0)
782 BUG();
783 ret = gpio_request(PIN_I2S0_CLK, "i2s0_clk");
784 if (ret < 0)
785 BUG();
786 ret = gpio_request(PIN_I2S0_DIN, "i2s0_din");
787 if (ret < 0)
788 BUG();
789 ret = gpio_request(PIN_I2S0_DOUT, "i2s0_dout");
790 if (ret < 0)
791 BUG();
792 zx29_gpio_config(PIN_I2S0_WS, FUN_I2S0_WS);
793 zx29_gpio_config(PIN_I2S0_CLK, FUN_I2S0_CLK);
794 zx29_gpio_config(PIN_I2S0_DIN, FUN_I2S0_DIN);
795 zx29_gpio_config(PIN_I2S0_DOUT, FUN_I2S0_DOUT);
796
797 //top i2s1 cfg
798 i2s_top_reg = zx_read_reg(ZX29_I2S_LOOP_CFG);
799 i2s_top_reg &= 0xfffffff8;
800 i2s_top_reg |= 0x00000001; // inter arm_i2s1--top i2s1
801 zx_write_reg(ZX29_I2S_LOOP_CFG, i2s_top_reg);
802#elif defined (CONFIG_USE_PIN_I2S1)
803
804
805 ret = gpio_request(PIN_I2S1_WS,"i2s1_ws");
806 if(ret < 0)
807 BUG();
808 ret = gpio_request(PIN_I2S1_CLK,"i2s1_clk");
809 if(ret < 0)
810 BUG();
811 ret = gpio_request(PIN_I2S1_DIN,"i2s1_din");
812 if(ret < 0)
813 BUG();
814 ret = gpio_request(PIN_I2S1_DOUT,"i2s1_dout");
815 if(ret < 0)
816 BUG();
817 zx29_gpio_config(PIN_I2S1_WS, FUN_I2S1_WS);
818 zx29_gpio_config(PIN_I2S1_CLK, FUN_I2S1_CLK);
819 zx29_gpio_config(PIN_I2S1_DIN, FUN_I2S1_DIN);
820 zx29_gpio_config(PIN_I2S1_DOUT, FUN_I2S1_DOUT);
821
822 //top i2s2 cfg
823 i2s_top_reg = zx_read_reg(ZX29_I2S_LOOP_CFG);
824 i2s_top_reg &= 0xfff8ffff;
825 i2s_top_reg |= 0x00010000; // inter arm_i2s1--top i2s2
826 zx_write_reg(ZX29_I2S_LOOP_CFG, i2s_top_reg);
827#endif
828
829 // inter loop
830 //i2s_top_reg = zx_read_reg(ZX29_I2S_LOOP_CFG);
831 //i2s_top_reg &= 0xfffffe07;
832 //i2s_top_reg |= 0x000000a8; // inter arm_i2s2--afe i2s
833 //zx_write_reg(ZX29_I2S_LOOP_CFG, i2s_top_reg);
834
835 // print_audio("Alsa %s i2s loop cfg reg=%x\n",__func__, zx_read_reg(ZX29_I2S_LOOP_CFG));
836 }
837
838 static int zx29_late_probe(struct snd_soc_card *card)
839 {
840 //struct snd_soc_codec *codec = card->rtd[0].codec;
841 //struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
842 int ret;
843 // print_audio("Alsa zx29_late_probe entry!\n");
844
845#ifdef CONFIG_SND_SOC_JACK_DECTEC
846
847 ret = snd_soc_jack_new(codec, "Headset",
848 SND_JACK_HEADSET |SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
849 &codec_headset);
850 if (ret)
851 return ret;
852
853 ret = snd_soc_jack_add_pins(&codec_headset,
854 ARRAY_SIZE(codec_headset_pins),
855 codec_headset_pins);
856 if (ret)
857 return ret;
858 #ifdef CONFIG_SND_SOC_codec
859 //rt5670_hs_detect(codec, &codec_headset);
860 #endif
861#endif
862
863 return 0;
864 }
865
866 static struct snd_soc_ops zx29_ops = {
867 //.startup = zx29_startup,
868 .shutdown = zx29_shutdown,
869 .hw_params = zx29_hw_params,
870 };
871 static struct snd_soc_ops zx29_ops_lp = {
872 //.startup = zx29_startup,
873 .shutdown = zx29_shutdown,
874 .hw_params = zx29_hw_params_lp,
875 };
876 static struct snd_soc_ops zx29_ops1 = {
877 //.startup = zx29_startup,
878 .shutdown = zx29_shutdown,
879 //.hw_params = zx29_hw_params1,
880 };
881
882 static struct snd_soc_ops zx29_ops2 = {
883 //.startup = zx29_startup,
884 .shutdown = zx29_shutdown2,
885 //.hw_params = zx29_hw_params1,
886 .prepare = zx29_prepare2,
887 };
888 static struct snd_soc_ops voice_ops = {
889 //.startup = zx29_startup,
890 //.shutdown = zx29_shutdown2,
891 .hw_params = zx29_hw_params_voice,
892 //.prepare = zx29_prepare2,
893 };
894
895
896 enum {
897 MERR_DPCM_AUDIO = 0,
898 MERR_DPCM_DEEP_BUFFER,
899 MERR_DPCM_COMPR,
900 };
901
902
903#if 0
904
905 static struct snd_soc_card zxic_soc_card = {
906 .name = "zx298501_ak4940",
907 .owner = THIS_MODULE,
908 .dai_link = &zxic_dai_link,
909 .num_links = ARRAY_SIZE(zxic_dai_link),
910#ifdef USE_ALSA_VOICE_FUNC
911 .controls = vp_snd_controls,
912 .num_controls = ARRAY_SIZE(vp_snd_controls),
913#endif
914
915 // .late_probe = zx29_late_probe,
916
917 };
918#endif
919 //static struct zx298501_ak4940_pdata *zx29_platform_data;
920
921 static int zx29_setup_pins(struct zx29_board_data *codec_pins, char *fun)
922 {
923 int ret;
924
925 //ret = gpio_request(codec_pins->codec_refclk, "codec_refclk");
926 if (ret < 0) {
927 printk(KERN_ERR "zx297520xx SoC Audio: %s pin already in use\n", fun);
928 return ret;
929 }
930 //zx29_gpio_config(codec_pins->codec_refclk, GPIO17_CLK_OUT2);
931
932#ifdef _USE_7520V3_PHONE_TYPE_C31F
933 ret = gpio_request_one(ZX29_GPIO_39, GPIOF_OUT_INIT_LOW, "codec_pa");
934 if (ret < 0) {
935 printk(KERN_ERR "zx297520xx SoC Audio: codec_pa in use\n");
936 return ret;
937 }
938
939 ret = gpio_request_one(ZX29_GPIO_40, GPIOF_OUT_INIT_LOW, "codec_sw");
940 if (ret < 0) {
941 printk(KERN_ERR "zx297520xx SoC Audio: codec_sw in use\n");
942 return ret;
943 }
944#endif
945
946 return 0;
947 }
948#endif
949
950
951 static int zx29_remove(struct platform_device *pdev)
952 {
953 gpio_free(zx29_platform_data.codec_refclk);
954 platform_device_unregister(zx29_snd_device);
955 return 0;
956 }
957
958
959
960#if 0
961
962 /*
963 * Default CFG switch settings to use this driver:
964 * ZX29
965 */
966
967 /*
968 * Configure audio route as :-
969 * $ amixer sset 'DAC1' on,on
970 * $ amixer sset 'Right Headphone Mux' 'DAC'
971 * $ amixer sset 'Left Headphone Mux' 'DAC'
972 * $ amixer sset 'DAC1R Mixer AIF1.1' on
973 * $ amixer sset 'DAC1L Mixer AIF1.1' on
974 * $ amixer sset 'IN2L' on
975 * $ amixer sset 'IN2L PGA IN2LN' on
976 * $ amixer sset 'MIXINL IN2L' on
977 * $ amixer sset 'AIF1ADC1L Mixer ADC/DMIC' on
978 * $ amixer sset 'IN2R' on
979 * $ amixer sset 'IN2R PGA IN2RN' on
980 * $ amixer sset 'MIXINR IN2R' on
981 * $ amixer sset 'AIF1ADC1R Mixer ADC/DMIC' on
982 */
983
984/* ZX29 has a 16.934MHZ crystal attached to ak4940 */
985#define ZX29_AK4940_FREQ 16934000
986
987
988
989
990
991static int zx29_hw_params(struct snd_pcm_substream *substream,
992 struct snd_pcm_hw_params *params)
993{
994 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
995 struct snd_soc_dai *codec_dai = rtd->codec_dai;
996 unsigned int pll_out;
997 int ret;
998
999 /* AIF1CLK should be >=3MHz for optimal performance */
1000 if (params_width(params) == 24)
1001 pll_out = params_rate(params) * 384;
1002 else if (params_rate(params) == 8000 || params_rate(params) == 11025)
1003 pll_out = params_rate(params) * 512;
1004 else
1005 pll_out = params_rate(params) * 256;
1006
1007 ret = snd_soc_dai_set_pll(codec_dai, AK4940_FLL1, AK4940_FLL_SRC_MCLK1,
1008 ZX29_AK4940_FREQ, pll_out);
1009 if (ret < 0)
1010 return ret;
1011
1012 ret = snd_soc_dai_set_sysclk(codec_dai, AK4940_SYSCLK_FLL1,
1013 pll_out, SND_SOC_CLOCK_IN);
1014 if (ret < 0)
1015 return ret;
1016
1017 return 0;
1018}
1019
1020/*
1021 * ZX29 AK4940 DAI operations.
1022 */
1023static struct snd_soc_ops zx29_ops = {
1024 .hw_params = smdk_hw_params,
1025};
1026
1027static int zx29_ak4940_init_paiftx(struct snd_soc_pcm_runtime *rtd)
1028{
1029 struct snd_soc_dapm_context *dapm = &rtd->card->dapm;
1030
1031 /* Other pins NC */
1032 snd_soc_dapm_nc_pin(dapm, "HPOUT2P");
1033 snd_soc_dapm_nc_pin(dapm, "HPOUT2N");
1034 snd_soc_dapm_nc_pin(dapm, "SPKOUTLN");
1035 snd_soc_dapm_nc_pin(dapm, "SPKOUTLP");
1036 snd_soc_dapm_nc_pin(dapm, "SPKOUTRP");
1037 snd_soc_dapm_nc_pin(dapm, "SPKOUTRN");
1038 snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
1039 snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
1040 snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
1041 snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
1042 snd_soc_dapm_nc_pin(dapm, "IN1LP");
1043 snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
1044 snd_soc_dapm_nc_pin(dapm, "IN1RP");
1045 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
1046
1047 return 0;
1048}
1049#endif
1050
1051
1052
1053
1054enum {
1055 AUDIO_DL_MEDIA = 0,
1056 AUDIO_DL_VOICE,
1057 AUDIO_DL_2G_AND_3G_VOICE,
1058 AUDIO_DL_VP_LOOP,
1059 AUDIO_DL_3G_VOICE,
1060
1061 AUDIO_DL_MAX,
1062};
1063SND_SOC_DAILINK_DEF(dummy, \
1064 DAILINK_COMP_ARRAY(COMP_DUMMY()));
1065
1066//SND_SOC_DAILINK_DEF(cpu_i2s0, \
1067// DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
1068SND_SOC_DAILINK_DEF(cpu_i2s0, \
1069 DAILINK_COMP_ARRAY(COMP_CPU("E1D02000.i2s")));
1070
1071
1072SND_SOC_DAILINK_DEF(voice_cpu, \
1073 DAILINK_COMP_ARRAY(COMP_CPU("soc:voice_audio")));
1074
1075SND_SOC_DAILINK_DEF(voice_2g_3g, \
1076 DAILINK_COMP_ARRAY(COMP_CPU("voice_2g_3g-dai")));
1077
1078SND_SOC_DAILINK_DEF(voice_3g, \
1079 DAILINK_COMP_ARRAY(COMP_CPU("voice_3g-dai")));
1080
1081
1082
1083//SND_SOC_DAILINK_DEF(ak4940, \
1084// DAILINK_COMP_ARRAY(COMP_CODEC("ak4940.1-0012", "ak4940-aif")));
1085SND_SOC_DAILINK_DEF(dummy_cpu, \
1086 DAILINK_COMP_ARRAY(COMP_CPU("soc:zx29_snd_dummy")));
1087//SND_SOC_DAILINK_DEF(dummy_platform, \
1088// DAILINK_COMP_ARRAY(COMP_PLATFORM("soc:zx29_snd_dummy")));
1089
1090SND_SOC_DAILINK_DEF(dummy_codec, \
1091 DAILINK_COMP_ARRAY(COMP_CODEC("soc:zx29_snd_dummy", "zx29_snd_dummy_dai")));
1092SND_SOC_DAILINK_DEF(ti3100_codec, \
1093 DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic31xx-codec.1-0012", "tlv320aic31xx-hifi")));
1094
1095
1096//SND_SOC_DAILINK_DEF(media_platform, \
1097// DAILINK_COMP_ARRAY(COMP_PLATFORM("zx29-pcm-audio")));
1098SND_SOC_DAILINK_DEF(media_platform, \
1099 DAILINK_COMP_ARRAY(COMP_PLATFORM("E1D02000.i2s")));
1100//SND_SOC_DAILINK_DEF(voice_cpu, \
1101// DAILINK_COMP_ARRAY(COMP_CPU("E1D02000.i2s")));
1102
1103SND_SOC_DAILINK_DEF(voice_platform, \
1104 DAILINK_COMP_ARRAY(COMP_PLATFORM("soc:voice_audio")));
1105
1106
1107//static struct snd_soc_dai_link zx29_dai_link[] = {
1108struct snd_soc_dai_link zx29_dai_link[] = {
1109
1110
1111
1112
1113 {
1114 .name = "zx29_snd_dummy",//codec name
1115 .stream_name = "zx29_snd_dumy",
1116 //.nonatomic = true,
1117 //.dynamic = 1,
1118 //.dpcm_playback = 1,
1119 .ops = &zx29_ops_lp,
1120 .init = zx29_init_paiftx,
1121 SND_SOC_DAILINK_REG(cpu_i2s0, dummy_codec, media_platform),
1122
1123},
1124{
1125 .name = "media",//codec name
1126 .stream_name = "MultiMedia",
1127 //.nonatomic = true,
1128 //.dynamic = 1,
1129 //.dpcm_playback = 1,
1130 .ops = &zx29_ops,
1131
1132 .init = zx29_init_paiftx,
1133
1134
1135 SND_SOC_DAILINK_REG(cpu_i2s0, dummy_codec, media_platform),
1136
1137},
1138{
1139 .name = "voice",//codec name
1140 .stream_name = "voice",
1141 //.nonatomic = true,
1142 //.dynamic = 1,
1143 //.dpcm_playback = 1,
1144 .ops = &voice_ops,
1145
1146 //.init = zx29_init_paiftx,
1147
1148
1149
1150 SND_SOC_DAILINK_REG(voice_cpu, dummy_codec, voice_platform),
1151
1152},
1153{
1154 .name = "voice_2g3g_teak",//codec name
1155 .stream_name = "voice_2g3g_teak",
1156 //.nonatomic = true,
1157 //.dynamic = 1,
1158 //.dpcm_playback = 1,
1159 .ops = &voice_ops,
1160
1161 //.init = zx29_init_paiftx,
1162
1163
1164 SND_SOC_DAILINK_REG(voice_cpu, dummy_codec, voice_platform),
1165
1166},
1167
1168{
1169 .name = "voice_3g",//codec name
1170 .stream_name = "voice_3g",
1171 //.nonatomic = true,
1172 //.dynamic = 1,
1173 //.dpcm_playback = 1,
1174 .ops = &voice_ops,
1175
1176 //.init = zx29_init_paiftx,
1177
1178
1179 SND_SOC_DAILINK_REG(voice_cpu, dummy_codec, voice_platform),
1180
1181},
1182
1183{
1184 .name = "loop_test",//codec name
1185 .stream_name = "loop_test",
1186 //.nonatomic = true,
1187 //.dynamic = 1,
1188 //.dpcm_playback = 1,
1189 .ops = &zx29_ops,
1190
1191 .init = zx29_init_paiftx,
1192
1193
1194 SND_SOC_DAILINK_REG(cpu_i2s0, dummy_codec, dummy),
1195
1196},
1197
1198};
1199
1200
1201
1202static struct snd_soc_card zx29_soc_card = {
1203 .name = "zx29-sound-card",
1204 .owner = THIS_MODULE,
1205 .dai_link = zx29_dai_link,
1206 .num_links = ARRAY_SIZE(zx29_dai_link),
1207#ifdef USE_ALSA_VOICE_FUNC
1208 .controls = vp_snd_controls,
1209 .num_controls = ARRAY_SIZE(vp_snd_controls),
1210#endif
1211};
1212
1213static const struct of_device_id zx29_dummycodec_of_match[] = {
1214 { .compatible = "zxic,zx29_dummycodec", .data = &zx29_platform_data },
1215 {},
1216};
1217MODULE_DEVICE_TABLE(of, zx29_dummycodec_of_match);
1218
1219static void zx29_i2s_top_pin_cfg(struct platform_device *pdev)
1220{
1221 struct device *dev = &pdev->dev;
1222 struct pinctrl *p;
1223 struct pinctrl_state *s;
1224 int ret = 0;
1225
1226
1227 struct resource *res;
1228 void __iomem *reg_base;
1229 unsigned int val;
1230
1231
1232
1233 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "soc_sys");
1234 if (!res) {
1235 dev_err(dev, "Reg region missing (%s)\n", "soc_sys");
1236 //return -ENXIO;
1237 }
1238
1239 #if 0
1240 reg_base = devm_ioremap_resource(dev, res);
1241 if (IS_ERR(reg_base )) {
1242 dev_err(dev, "Reg region ioremap (%s) err=%li\n", "soc_sys",PTR_ERR(reg_base ));
1243 //return PTR_ERR(reg_base );
1244 }
1245
1246 #else
1247 reg_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
1248 #endif
1249
1250//#if 1 //CONFIG_USE_PIN_I2S0
1251#ifdef CONFIG_USE_TOP_I2S0
1252
1253 dev_info(dev, "%s: arm i2s1 to top i2s0!!\n", __func__);
1254 //9300
1255
1256 //top i2s1 cfg
1257 val = zx_read_reg(reg_base+ZX29_I2S_TOP_LOOP_REG);
1258 val &= ~(0x7<<0);
1259 val |= 0x1<<0; // inter arm_i2s1--top i2s1
1260 zx_write_reg(reg_base+ZX29_I2S_TOP_LOOP_REG, val);
1261#else //(CONFIG_USE_PIN_I2S1)
1262 //8501evb
1263
1264 dev_info(dev, "%s: arm i2s1 to top i2s1!\n", __func__);
1265
1266 //top i2s2 cfg
1267 val = zx_read_reg(reg_base+ZX29_I2S_TOP_LOOP_REG);
1268 //val &= 0xfffffff8;
1269 val &= ~(0x7<<16);
1270 val |= 0x1<<16;// inter arm_i2s1--top i2s2
1271 zx_write_reg(reg_base+ZX29_I2S_TOP_LOOP_REG, val);
1272#endif
1273
1274
1275
1276 p = devm_pinctrl_get(dev);
1277 if (IS_ERR(p)) {
1278 dev_err(dev, "%s: pinctrl get failure ,p=0x%llx,dev=0x%llx!!\n", __func__,p,dev);
1279 return;
1280 }
1281
1282 dev_info(dev, "%s: get pinctrl ,p=0x%llx,dev=0x%llx!!\n", __func__,p,dev);
1283
1284 s = pinctrl_lookup_state(p, "top_i2s");
1285 if (IS_ERR(s)) {
1286 devm_pinctrl_put(p);
1287 dev_err(dev, " get state failure!!\n");
1288 return;
1289 }
1290 ret = pinctrl_select_state(p, s);
1291 if (ret < 0) {
1292 devm_pinctrl_put(p);
1293 dev_err(dev, " select state failure!!\n");
1294 return;
1295 }
1296 dev_info(dev, "%s: set pinctrl end!\n", __func__);
1297
1298
1299
1300
1301}
1302
1303
1304static int zx29_audio_probe(struct platform_device *pdev)
1305{
1306 int ret;
1307 struct device_node *np = pdev->dev.of_node;
1308 struct snd_soc_card *card = &zx29_soc_card;
1309 struct zx29_board_data *board;
1310 const struct of_device_id *id;
1311 enum of_gpio_flags flags;
1312 unsigned int idx;
1313
1314 struct device *dev = &pdev->dev;
1315 dev_info(&pdev->dev,"zx29_audio_probe start!\n");
1316
1317 card->dev = &pdev->dev;
1318
1319 board = devm_kzalloc(&pdev->dev, sizeof(*board), GFP_KERNEL);
1320 if (!board)
1321 return -ENOMEM;
1322 board->name = "zx29_dummycodec";
1323 board->dev = &pdev->dev;
1324
1325 if (np) {
1326 zx29_dai_link[0].cpus->dai_name = NULL;
1327 zx29_dai_link[0].cpus->of_node = of_parse_phandle(np,
1328 "zxic,i2s-controller", 0);
1329 if (!zx29_dai_link[0].cpus->of_node) {
1330 dev_err(&pdev->dev,
1331 "Property 'zxic,i2s-controller' missing or invalid\n");
1332 ret = -EINVAL;
1333 }
1334
1335 zx29_dai_link[0].platforms->name = NULL;
1336 zx29_dai_link[0].platforms->of_node = zx29_dai_link[0].cpus->of_node;
1337
1338
1339#if 0
1340 zx29_dai_link[0].codecs->of_node = of_parse_phandle(np,
1341 "zxic,audio-codec", 0);
1342 if (!zx29_dai_link[0].codecs->of_node) {
1343 dev_err(&pdev->dev,
1344 "Property 'zxic,audio-codec' missing or invalid\n");
1345 return -EINVAL;
1346 }
1347#endif
1348 }
1349
1350
1351
1352
1353
1354
1355 id = of_match_device(of_match_ptr(zx29_dummycodec_of_match), &pdev->dev);
1356 if (id)
1357 *board = *((struct zx29_board_data *)id->data);
1358
1359 //platform_set_drvdata(pdev, board);
1360
1361
1362
1363 ret = devm_snd_soc_register_card(&pdev->dev, card);
1364
1365 if (ret){
1366 dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret);
1367 return ret;
1368 }
1369 zx29_i2s_top_pin_cfg(pdev);
1370
1371
1372 //codec_power_on(board,1);
1373 dev_info(&pdev->dev,"zx29_audio_probe end!\n");
1374
1375 return ret;
1376}
1377
1378static struct platform_driver zx29_platform_driver = {
1379 .driver = {
1380 .name = "zx29_dummycodec",
1381 .of_match_table = of_match_ptr(zx29_dummycodec_of_match),
1382 .pm = &snd_soc_pm_ops,
1383 },
1384 .probe = zx29_audio_probe,
1385 //.remove = zx29_remove,
1386};
1387
1388
1389
1390
1391
1392module_platform_driver(zx29_platform_driver);
1393
1394MODULE_DESCRIPTION("zx29 ALSA SoC audio driver");
1395MODULE_LICENSE("GPL");
1396MODULE_ALIAS("platform:zx29-audio-dummycodec");