blob: 902fa58619014209d8f31e1cee860e772fe57e35 [file] [log] [blame]
Kuninori Morimoto98615452009-12-14 13:21:56 +09001/*
2 * DA7210 ALSA Soc codec driver
3 *
4 * Copyright (c) 2009 Dialog Semiconductor
5 * Written by David Chen <Dajun.chen@diasemi.com>
6 *
7 * Copyright (C) 2009 Renesas Solutions Corp.
8 * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
9 *
10 * Tested on SuperH Ecovec24 board with S16/S24 LE in 48KHz using I2S
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17
Kuninori Morimoto98615452009-12-14 13:21:56 +090018#include <linux/delay.h>
Kuninori Morimoto98615452009-12-14 13:21:56 +090019#include <linux/i2c.h>
20#include <linux/platform_device.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090021#include <linux/slab.h>
Kuninori Morimoto98615452009-12-14 13:21:56 +090022#include <sound/pcm.h>
23#include <sound/pcm_params.h>
Liam Girdwoodce6120c2010-11-05 15:53:46 +020024#include <sound/soc.h>
Kuninori Morimoto98615452009-12-14 13:21:56 +090025#include <sound/initval.h>
Kuninori Morimotoa7e7cd52010-07-21 14:12:16 +090026#include <sound/tlv.h>
Kuninori Morimoto98615452009-12-14 13:21:56 +090027
Kuninori Morimoto98615452009-12-14 13:21:56 +090028/* DA7210 register space */
29#define DA7210_STATUS 0x02
30#define DA7210_STARTUP1 0x03
31#define DA7210_MIC_L 0x07
32#define DA7210_MIC_R 0x08
33#define DA7210_INMIX_L 0x0D
34#define DA7210_INMIX_R 0x0E
35#define DA7210_ADC_HPF 0x0F
36#define DA7210_ADC 0x10
37#define DA7210_DAC_HPF 0x14
38#define DA7210_DAC_L 0x15
39#define DA7210_DAC_R 0x16
40#define DA7210_DAC_SEL 0x17
41#define DA7210_OUTMIX_L 0x1C
42#define DA7210_OUTMIX_R 0x1D
43#define DA7210_HP_L_VOL 0x21
44#define DA7210_HP_R_VOL 0x22
45#define DA7210_HP_CFG 0x23
46#define DA7210_DAI_SRC_SEL 0x25
47#define DA7210_DAI_CFG1 0x26
48#define DA7210_DAI_CFG3 0x28
Kuninori Morimoto960b3b42010-03-11 11:37:44 +090049#define DA7210_PLL_DIV1 0x29
50#define DA7210_PLL_DIV2 0x2A
Kuninori Morimoto98615452009-12-14 13:21:56 +090051#define DA7210_PLL_DIV3 0x2B
52#define DA7210_PLL 0x2C
Kuninori Morimoto960b3b42010-03-11 11:37:44 +090053#define DA7210_A_HID_UNLOCK 0x8A
54#define DA7210_A_TEST_UNLOCK 0x8B
55#define DA7210_A_PLL1 0x90
56#define DA7210_A_CP_MODE 0xA7
Kuninori Morimoto98615452009-12-14 13:21:56 +090057
58/* STARTUP1 bit fields */
59#define DA7210_SC_MST_EN (1 << 0)
60
61/* MIC_L bit fields */
62#define DA7210_MICBIAS_EN (1 << 6)
63#define DA7210_MIC_L_EN (1 << 7)
64
65/* MIC_R bit fields */
66#define DA7210_MIC_R_EN (1 << 7)
67
68/* INMIX_L bit fields */
69#define DA7210_IN_L_EN (1 << 7)
70
71/* INMIX_R bit fields */
72#define DA7210_IN_R_EN (1 << 7)
73
Kuninori Morimoto98615452009-12-14 13:21:56 +090074/* ADC bit fields */
75#define DA7210_ADC_L_EN (1 << 3)
76#define DA7210_ADC_R_EN (1 << 7)
77
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +090078/* DAC/ADC HPF fields */
79#define DA7210_VOICE_F0_MASK (0x7 << 4)
80#define DA7210_VOICE_F0_25 (1 << 4)
81#define DA7210_VOICE_EN (1 << 7)
Mark Brownc2151432009-12-16 20:36:37 +000082
Kuninori Morimoto98615452009-12-14 13:21:56 +090083/* DAC_SEL bit fields */
84#define DA7210_DAC_L_SRC_DAI_L (4 << 0)
85#define DA7210_DAC_L_EN (1 << 3)
86#define DA7210_DAC_R_SRC_DAI_R (5 << 4)
87#define DA7210_DAC_R_EN (1 << 7)
88
89/* OUTMIX_L bit fields */
90#define DA7210_OUT_L_EN (1 << 7)
91
92/* OUTMIX_R bit fields */
93#define DA7210_OUT_R_EN (1 << 7)
94
95/* HP_CFG bit fields */
96#define DA7210_HP_2CAP_MODE (1 << 1)
97#define DA7210_HP_SENSE_EN (1 << 2)
98#define DA7210_HP_L_EN (1 << 3)
99#define DA7210_HP_MODE (1 << 6)
100#define DA7210_HP_R_EN (1 << 7)
101
102/* DAI_SRC_SEL bit fields */
103#define DA7210_DAI_OUT_L_SRC (6 << 0)
104#define DA7210_DAI_OUT_R_SRC (7 << 4)
105
106/* DAI_CFG1 bit fields */
107#define DA7210_DAI_WORD_S16_LE (0 << 0)
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530108#define DA7210_DAI_WORD_S20_3LE (1 << 0)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900109#define DA7210_DAI_WORD_S24_LE (2 << 0)
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530110#define DA7210_DAI_WORD_S32_LE (3 << 0)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900111#define DA7210_DAI_FLEN_64BIT (1 << 2)
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530112#define DA7210_DAI_MODE_SLAVE (0 << 7)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900113#define DA7210_DAI_MODE_MASTER (1 << 7)
114
115/* DAI_CFG3 bit fields */
116#define DA7210_DAI_FORMAT_I2SMODE (0 << 0)
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530117#define DA7210_DAI_FORMAT_LEFT_J (1 << 0)
118#define DA7210_DAI_FORMAT_RIGHT_J (2 << 0)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900119#define DA7210_DAI_OE (1 << 3)
120#define DA7210_DAI_EN (1 << 7)
121
122/*PLL_DIV3 bit fields */
123#define DA7210_MCLK_RANGE_10_20_MHZ (1 << 4)
124#define DA7210_PLL_BYP (1 << 6)
125
126/* PLL bit fields */
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900127#define DA7210_PLL_FS_MASK (0xF << 0)
128#define DA7210_PLL_FS_8000 (0x1 << 0)
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900129#define DA7210_PLL_FS_11025 (0x2 << 0)
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900130#define DA7210_PLL_FS_12000 (0x3 << 0)
131#define DA7210_PLL_FS_16000 (0x5 << 0)
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900132#define DA7210_PLL_FS_22050 (0x6 << 0)
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900133#define DA7210_PLL_FS_24000 (0x7 << 0)
134#define DA7210_PLL_FS_32000 (0x9 << 0)
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900135#define DA7210_PLL_FS_44100 (0xA << 0)
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900136#define DA7210_PLL_FS_48000 (0xB << 0)
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900137#define DA7210_PLL_FS_88200 (0xE << 0)
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900138#define DA7210_PLL_FS_96000 (0xF << 0)
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900139#define DA7210_PLL_EN (0x1 << 7)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900140
141#define DA7210_VERSION "0.0.1"
142
Kuninori Morimotoa7e7cd52010-07-21 14:12:16 +0900143/*
144 * Playback Volume
145 *
146 * max : 0x3F (+15.0 dB)
147 * (1.5 dB step)
148 * min : 0x11 (-54.0 dB)
149 * mute : 0x10
150 * reserved : 0x00 - 0x0F
151 *
Kuninori Morimotoa7e7cd52010-07-21 14:12:16 +0900152 * Reserved area are considered as "mute".
Kuninori Morimotoa7e7cd52010-07-21 14:12:16 +0900153 */
Ashish Chavan7a0e67b2011-10-14 16:25:25 +0530154static const unsigned int hp_out_tlv[] = {
155 TLV_DB_RANGE_HEAD(2),
156 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
157 /* -54 dB to +15 dB */
158 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0),
159};
Kuninori Morimotoa7e7cd52010-07-21 14:12:16 +0900160
161static const struct snd_kcontrol_new da7210_snd_controls[] = {
162
163 SOC_DOUBLE_R_TLV("HeadPhone Playback Volume",
164 DA7210_HP_L_VOL, DA7210_HP_R_VOL,
165 0, 0x3F, 0, hp_out_tlv),
166};
167
Kuninori Morimoto98615452009-12-14 13:21:56 +0900168/* Codec private data */
169struct da7210_priv {
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000170 enum snd_soc_control_type control_type;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900171};
172
Kuninori Morimoto98615452009-12-14 13:21:56 +0900173/*
174 * Register cache
175 */
176static const u8 da7210_reg[] = {
177 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */
179 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */
180 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */
181 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */
182 0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */
183 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */
184 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */
187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */
188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */
189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */
190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */
191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */
193 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */
194 0x00, /* R88 */
195};
196
Axel Lin40a49712011-10-12 07:16:25 +0800197static int da7210_volatile_register(struct snd_soc_codec *codec,
198 unsigned int reg)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900199{
Axel Lin40a49712011-10-12 07:16:25 +0800200 switch (reg) {
201 case DA7210_STATUS:
202 return 1;
203 default:
204 return 0;
205 }
Kuninori Morimoto98615452009-12-14 13:21:56 +0900206}
Kuninori Morimoto98615452009-12-14 13:21:56 +0900207static int da7210_startup(struct snd_pcm_substream *substream,
208 struct snd_soc_dai *dai)
209{
210 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
211 struct snd_soc_codec *codec = dai->codec;
212
213 if (is_play) {
Kuninori Morimoto98615452009-12-14 13:21:56 +0900214 /* Enable Out */
215 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10);
216 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10);
217
218 } else {
219 /* Volume 7 */
220 snd_soc_update_bits(codec, DA7210_MIC_L, 0x7, 0x7);
221 snd_soc_update_bits(codec, DA7210_MIC_R, 0x7, 0x7);
222
223 /* Enable Mic */
224 snd_soc_update_bits(codec, DA7210_INMIX_L, 0x1F, 0x1);
225 snd_soc_update_bits(codec, DA7210_INMIX_R, 0x1F, 0x1);
226 }
227
228 return 0;
229}
230
231/*
232 * Set PCM DAI word length.
233 */
234static int da7210_hw_params(struct snd_pcm_substream *substream,
235 struct snd_pcm_hw_params *params,
236 struct snd_soc_dai *dai)
237{
238 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000239 struct snd_soc_codec *codec = rtd->codec;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900240 u32 dai_cfg1;
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900241 u32 hpf_reg, hpf_mask, hpf_value;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900242 u32 fs, bypass;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900243
244 /* set DAI source to Left and Right ADC */
Axel Lin40a49712011-10-12 07:16:25 +0800245 snd_soc_write(codec, DA7210_DAI_SRC_SEL,
Kuninori Morimoto98615452009-12-14 13:21:56 +0900246 DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC);
247
248 /* Enable DAI */
Axel Lin40a49712011-10-12 07:16:25 +0800249 snd_soc_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900250
Axel Lin40a49712011-10-12 07:16:25 +0800251 dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900252
253 switch (params_format(params)) {
254 case SNDRV_PCM_FORMAT_S16_LE:
255 dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
256 break;
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530257 case SNDRV_PCM_FORMAT_S20_3LE:
258 dai_cfg1 |= DA7210_DAI_WORD_S20_3LE;
259 break;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900260 case SNDRV_PCM_FORMAT_S24_LE:
261 dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
262 break;
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530263 case SNDRV_PCM_FORMAT_S32_LE:
264 dai_cfg1 |= DA7210_DAI_WORD_S32_LE;
265 break;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900266 default:
267 return -EINVAL;
268 }
269
Axel Lin40a49712011-10-12 07:16:25 +0800270 snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900271
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900272 hpf_reg = (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) ?
273 DA7210_DAC_HPF : DA7210_ADC_HPF;
274
Kuninori Morimoto98615452009-12-14 13:21:56 +0900275 switch (params_rate(params)) {
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900276 case 8000:
277 fs = DA7210_PLL_FS_8000;
278 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
279 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900280 bypass = DA7210_PLL_BYP;
281 break;
282 case 11025:
283 fs = DA7210_PLL_FS_11025;
284 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
285 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
286 bypass = 0;
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900287 break;
288 case 12000:
289 fs = DA7210_PLL_FS_12000;
290 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
291 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900292 bypass = DA7210_PLL_BYP;
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900293 break;
294 case 16000:
295 fs = DA7210_PLL_FS_16000;
296 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
297 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900298 bypass = DA7210_PLL_BYP;
299 break;
300 case 22050:
301 fs = DA7210_PLL_FS_22050;
302 hpf_mask = DA7210_VOICE_EN;
303 hpf_value = 0;
304 bypass = 0;
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900305 break;
306 case 32000:
307 fs = DA7210_PLL_FS_32000;
308 hpf_mask = DA7210_VOICE_EN;
309 hpf_value = 0;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900310 bypass = DA7210_PLL_BYP;
311 break;
312 case 44100:
313 fs = DA7210_PLL_FS_44100;
314 hpf_mask = DA7210_VOICE_EN;
315 hpf_value = 0;
316 bypass = 0;
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900317 break;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900318 case 48000:
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900319 fs = DA7210_PLL_FS_48000;
320 hpf_mask = DA7210_VOICE_EN;
321 hpf_value = 0;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900322 bypass = DA7210_PLL_BYP;
323 break;
324 case 88200:
325 fs = DA7210_PLL_FS_88200;
326 hpf_mask = DA7210_VOICE_EN;
327 hpf_value = 0;
328 bypass = 0;
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900329 break;
330 case 96000:
331 fs = DA7210_PLL_FS_96000;
332 hpf_mask = DA7210_VOICE_EN;
333 hpf_value = 0;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900334 bypass = DA7210_PLL_BYP;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900335 break;
336 default:
337 return -EINVAL;
338 }
339
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900340 /* Disable active mode */
341 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
342
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900343 snd_soc_update_bits(codec, hpf_reg, hpf_mask, hpf_value);
344 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900345 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass);
346
347 /* Enable active mode */
348 snd_soc_update_bits(codec, DA7210_STARTUP1,
349 DA7210_SC_MST_EN, DA7210_SC_MST_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900350
351 return 0;
352}
353
354/*
355 * Set DAI mode and Format
356 */
357static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
358{
359 struct snd_soc_codec *codec = codec_dai->codec;
360 u32 dai_cfg1;
361 u32 dai_cfg3;
362
Axel Lin40a49712011-10-12 07:16:25 +0800363 dai_cfg1 = 0x7f & snd_soc_read(codec, DA7210_DAI_CFG1);
364 dai_cfg3 = 0xfc & snd_soc_read(codec, DA7210_DAI_CFG3);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900365
366 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
367 case SND_SOC_DAIFMT_CBM_CFM:
368 dai_cfg1 |= DA7210_DAI_MODE_MASTER;
369 break;
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530370 case SND_SOC_DAIFMT_CBS_CFS:
371 dai_cfg1 |= DA7210_DAI_MODE_SLAVE;
372 break;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900373 default:
374 return -EINVAL;
375 }
376
377 /* FIXME
378 *
379 * It support I2S only now
380 */
381 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
382 case SND_SOC_DAIFMT_I2S:
383 dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE;
384 break;
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530385 case SND_SOC_DAIFMT_LEFT_J:
386 dai_cfg3 |= DA7210_DAI_FORMAT_LEFT_J;
387 break;
388 case SND_SOC_DAIFMT_RIGHT_J:
389 dai_cfg3 |= DA7210_DAI_FORMAT_RIGHT_J;
390 break;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900391 default:
392 return -EINVAL;
393 }
394
395 /* FIXME
396 *
397 * It support 64bit data transmission only now
398 */
399 dai_cfg1 |= DA7210_DAI_FLEN_64BIT;
400
Axel Lin40a49712011-10-12 07:16:25 +0800401 snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
402 snd_soc_write(codec, DA7210_DAI_CFG3, dai_cfg3);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900403
404 return 0;
405}
406
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530407#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
408 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900409
410/* DAI operations */
411static struct snd_soc_dai_ops da7210_dai_ops = {
412 .startup = da7210_startup,
413 .hw_params = da7210_hw_params,
414 .set_fmt = da7210_set_dai_fmt,
415};
416
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000417static struct snd_soc_dai_driver da7210_dai = {
418 .name = "da7210-hifi",
Kuninori Morimoto98615452009-12-14 13:21:56 +0900419 /* playback capabilities */
420 .playback = {
421 .stream_name = "Playback",
422 .channels_min = 1,
423 .channels_max = 2,
424 .rates = SNDRV_PCM_RATE_8000_96000,
425 .formats = DA7210_FORMATS,
426 },
427 /* capture capabilities */
428 .capture = {
429 .stream_name = "Capture",
430 .channels_min = 1,
431 .channels_max = 2,
432 .rates = SNDRV_PCM_RATE_8000_96000,
433 .formats = DA7210_FORMATS,
434 },
435 .ops = &da7210_dai_ops,
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900436 .symmetric_rates = 1,
Kuninori Morimoto98615452009-12-14 13:21:56 +0900437};
Kuninori Morimoto98615452009-12-14 13:21:56 +0900438
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000439static int da7210_probe(struct snd_soc_codec *codec)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900440{
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000441 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
Axel Lin40a49712011-10-12 07:16:25 +0800442 int ret;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900443
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000444 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900445
Axel Lin40a49712011-10-12 07:16:25 +0800446 ret = snd_soc_codec_set_cache_io(codec, 8, 8, da7210->control_type);
447 if (ret < 0) {
448 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
449 return ret;
450 }
Kuninori Morimoto98615452009-12-14 13:21:56 +0900451
452 /* FIXME
453 *
454 * This driver use fixed value here
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900455 * And below settings expects MCLK = 12.288MHz
456 *
457 * When you select different MCLK, please check...
458 * DA7210_PLL_DIV1 val
459 * DA7210_PLL_DIV2 val
460 * DA7210_PLL_DIV3 val
461 * DA7210_PLL_DIV3 :: DA7210_MCLK_RANGExxx
Kuninori Morimoto98615452009-12-14 13:21:56 +0900462 */
463
464 /*
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900465 * make sure that DA7210 use bypass mode before start up
466 */
Axel Lin40a49712011-10-12 07:16:25 +0800467 snd_soc_write(codec, DA7210_STARTUP1, 0);
468 snd_soc_write(codec, DA7210_PLL_DIV3,
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900469 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
470
471 /*
Kuninori Morimoto98615452009-12-14 13:21:56 +0900472 * ADC settings
473 */
474
475 /* Enable Left & Right MIC PGA and Mic Bias */
Axel Lin40a49712011-10-12 07:16:25 +0800476 snd_soc_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
477 snd_soc_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900478
479 /* Enable Left and Right input PGA */
Axel Lin40a49712011-10-12 07:16:25 +0800480 snd_soc_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN);
481 snd_soc_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900482
483 /* Enable Left and Right ADC */
Axel Lin40a49712011-10-12 07:16:25 +0800484 snd_soc_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900485
486 /*
487 * DAC settings
488 */
489
490 /* Enable Left and Right DAC */
Axel Lin40a49712011-10-12 07:16:25 +0800491 snd_soc_write(codec, DA7210_DAC_SEL,
Kuninori Morimoto98615452009-12-14 13:21:56 +0900492 DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN |
493 DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN);
494
495 /* Enable Left and Right out PGA */
Axel Lin40a49712011-10-12 07:16:25 +0800496 snd_soc_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
497 snd_soc_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900498
499 /* Enable Left and Right HeadPhone PGA */
Axel Lin40a49712011-10-12 07:16:25 +0800500 snd_soc_write(codec, DA7210_HP_CFG,
Kuninori Morimoto98615452009-12-14 13:21:56 +0900501 DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN |
502 DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN);
503
504 /* Diable PLL and bypass it */
Axel Lin40a49712011-10-12 07:16:25 +0800505 snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900506
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900507 /*
508 * If 48kHz sound came, it use bypass mode,
509 * and when it is 44.1kHz, it use PLL.
510 *
511 * This time, this driver sets PLL always ON
512 * and controls bypass/PLL mode by switching
513 * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit.
514 * see da7210_hw_params
515 */
Axel Lin40a49712011-10-12 07:16:25 +0800516 snd_soc_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */
517 snd_soc_write(codec, DA7210_PLL_DIV2, 0x99);
518 snd_soc_write(codec, DA7210_PLL_DIV3, 0x0A |
Kuninori Morimoto98615452009-12-14 13:21:56 +0900519 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900520 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
521
522 /* As suggested by Dialog */
Axel Lin40a49712011-10-12 07:16:25 +0800523 snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */
524 snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0xB4);
525 snd_soc_write(codec, DA7210_A_PLL1, 0x01);
526 snd_soc_write(codec, DA7210_A_CP_MODE, 0x7C);
527 snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */
528 snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0x00);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900529
530 /* Activate all enabled subsystem */
Axel Lin40a49712011-10-12 07:16:25 +0800531 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900532
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000533 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900534
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000535 return 0;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900536}
537
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000538static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
Kuninori Morimoto4c62ed92010-09-16 13:07:06 +0900539 .probe = da7210_probe,
Kuninori Morimoto4c62ed92010-09-16 13:07:06 +0900540 .reg_cache_size = ARRAY_SIZE(da7210_reg),
541 .reg_word_size = sizeof(u8),
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000542 .reg_cache_default = da7210_reg,
Axel Lin40a49712011-10-12 07:16:25 +0800543 .volatile_register = da7210_volatile_register,
Mark Browna6f096f2011-10-14 20:18:49 +0100544
545 .controls = da7210_snd_controls,
546 .num_controls = ARRAY_SIZE(da7210_snd_controls),
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000547};
548
Kuninori Morimoto98615452009-12-14 13:21:56 +0900549#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
Mark Brown735fe4c2010-01-12 14:13:00 +0000550static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
551 const struct i2c_device_id *id)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900552{
553 struct da7210_priv *da7210;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900554 int ret;
555
556 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
557 if (!da7210)
558 return -ENOMEM;
559
Kuninori Morimoto98615452009-12-14 13:21:56 +0900560 i2c_set_clientdata(i2c, da7210);
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000561 da7210->control_type = SND_SOC_I2C;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900562
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000563 ret = snd_soc_register_codec(&i2c->dev,
564 &soc_codec_dev_da7210, &da7210_dai, 1);
565 if (ret < 0)
Axel Lin085efd22010-07-23 05:53:45 +0000566 kfree(da7210);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900567
568 return ret;
569}
570
Mark Brown735fe4c2010-01-12 14:13:00 +0000571static int __devexit da7210_i2c_remove(struct i2c_client *client)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900572{
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000573 snd_soc_unregister_codec(&client->dev);
574 kfree(i2c_get_clientdata(client));
Kuninori Morimoto98615452009-12-14 13:21:56 +0900575 return 0;
576}
577
578static const struct i2c_device_id da7210_i2c_id[] = {
579 { "da7210", 0 },
580 { }
581};
582MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
583
584/* I2C codec control layer */
585static struct i2c_driver da7210_i2c_driver = {
586 .driver = {
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000587 .name = "da7210-codec",
Kuninori Morimoto98615452009-12-14 13:21:56 +0900588 .owner = THIS_MODULE,
589 },
Kuninori Morimoto4c62ed92010-09-16 13:07:06 +0900590 .probe = da7210_i2c_probe,
591 .remove = __devexit_p(da7210_i2c_remove),
592 .id_table = da7210_i2c_id,
Kuninori Morimoto98615452009-12-14 13:21:56 +0900593};
594#endif
595
Kuninori Morimoto98615452009-12-14 13:21:56 +0900596static int __init da7210_modinit(void)
597{
598 int ret = 0;
599#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
600 ret = i2c_add_driver(&da7210_i2c_driver);
601#endif
602 return ret;
603}
604module_init(da7210_modinit);
605
606static void __exit da7210_exit(void)
607{
608#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
609 i2c_del_driver(&da7210_i2c_driver);
610#endif
611}
612module_exit(da7210_exit);
613
614MODULE_DESCRIPTION("ASoC DA7210 driver");
615MODULE_AUTHOR("David Chen, Kuninori Morimoto");
616MODULE_LICENSE("GPL");