blob: 3b5dc0d38dbb6c0c327e65705130a6fe0b017044 [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 *
152 * ** FIXME **
153 *
154 * Reserved area are considered as "mute".
155 * -> min = -79.5 dB
156 */
157static const DECLARE_TLV_DB_SCALE(hp_out_tlv, -7950, 150, 1);
158
159static const struct snd_kcontrol_new da7210_snd_controls[] = {
160
161 SOC_DOUBLE_R_TLV("HeadPhone Playback Volume",
162 DA7210_HP_L_VOL, DA7210_HP_R_VOL,
163 0, 0x3F, 0, hp_out_tlv),
164};
165
Kuninori Morimoto98615452009-12-14 13:21:56 +0900166/* Codec private data */
167struct da7210_priv {
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000168 enum snd_soc_control_type control_type;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900169};
170
Kuninori Morimoto98615452009-12-14 13:21:56 +0900171/*
172 * Register cache
173 */
174static const u8 da7210_reg[] = {
175 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */
177 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */
178 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */
179 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */
180 0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */
181 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */
182 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */
187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */
188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */
189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */
190 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */
191 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */
192 0x00, /* R88 */
193};
194
Axel Lin40a49712011-10-12 07:16:25 +0800195static int da7210_volatile_register(struct snd_soc_codec *codec,
196 unsigned int reg)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900197{
Axel Lin40a49712011-10-12 07:16:25 +0800198 switch (reg) {
199 case DA7210_STATUS:
200 return 1;
201 default:
202 return 0;
203 }
Kuninori Morimoto98615452009-12-14 13:21:56 +0900204}
Kuninori Morimoto98615452009-12-14 13:21:56 +0900205static int da7210_startup(struct snd_pcm_substream *substream,
206 struct snd_soc_dai *dai)
207{
208 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
209 struct snd_soc_codec *codec = dai->codec;
210
211 if (is_play) {
Kuninori Morimoto98615452009-12-14 13:21:56 +0900212 /* Enable Out */
213 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10);
214 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10);
215
216 } else {
217 /* Volume 7 */
218 snd_soc_update_bits(codec, DA7210_MIC_L, 0x7, 0x7);
219 snd_soc_update_bits(codec, DA7210_MIC_R, 0x7, 0x7);
220
221 /* Enable Mic */
222 snd_soc_update_bits(codec, DA7210_INMIX_L, 0x1F, 0x1);
223 snd_soc_update_bits(codec, DA7210_INMIX_R, 0x1F, 0x1);
224 }
225
226 return 0;
227}
228
229/*
230 * Set PCM DAI word length.
231 */
232static int da7210_hw_params(struct snd_pcm_substream *substream,
233 struct snd_pcm_hw_params *params,
234 struct snd_soc_dai *dai)
235{
236 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000237 struct snd_soc_codec *codec = rtd->codec;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900238 u32 dai_cfg1;
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900239 u32 hpf_reg, hpf_mask, hpf_value;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900240 u32 fs, bypass;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900241
242 /* set DAI source to Left and Right ADC */
Axel Lin40a49712011-10-12 07:16:25 +0800243 snd_soc_write(codec, DA7210_DAI_SRC_SEL,
Kuninori Morimoto98615452009-12-14 13:21:56 +0900244 DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC);
245
246 /* Enable DAI */
Axel Lin40a49712011-10-12 07:16:25 +0800247 snd_soc_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900248
Axel Lin40a49712011-10-12 07:16:25 +0800249 dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900250
251 switch (params_format(params)) {
252 case SNDRV_PCM_FORMAT_S16_LE:
253 dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
254 break;
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530255 case SNDRV_PCM_FORMAT_S20_3LE:
256 dai_cfg1 |= DA7210_DAI_WORD_S20_3LE;
257 break;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900258 case SNDRV_PCM_FORMAT_S24_LE:
259 dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
260 break;
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530261 case SNDRV_PCM_FORMAT_S32_LE:
262 dai_cfg1 |= DA7210_DAI_WORD_S32_LE;
263 break;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900264 default:
265 return -EINVAL;
266 }
267
Axel Lin40a49712011-10-12 07:16:25 +0800268 snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900269
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900270 hpf_reg = (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) ?
271 DA7210_DAC_HPF : DA7210_ADC_HPF;
272
Kuninori Morimoto98615452009-12-14 13:21:56 +0900273 switch (params_rate(params)) {
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900274 case 8000:
275 fs = DA7210_PLL_FS_8000;
276 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
277 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900278 bypass = DA7210_PLL_BYP;
279 break;
280 case 11025:
281 fs = DA7210_PLL_FS_11025;
282 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
283 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
284 bypass = 0;
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900285 break;
286 case 12000:
287 fs = DA7210_PLL_FS_12000;
288 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
289 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900290 bypass = DA7210_PLL_BYP;
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900291 break;
292 case 16000:
293 fs = DA7210_PLL_FS_16000;
294 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
295 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900296 bypass = DA7210_PLL_BYP;
297 break;
298 case 22050:
299 fs = DA7210_PLL_FS_22050;
300 hpf_mask = DA7210_VOICE_EN;
301 hpf_value = 0;
302 bypass = 0;
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900303 break;
304 case 32000:
305 fs = DA7210_PLL_FS_32000;
306 hpf_mask = DA7210_VOICE_EN;
307 hpf_value = 0;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900308 bypass = DA7210_PLL_BYP;
309 break;
310 case 44100:
311 fs = DA7210_PLL_FS_44100;
312 hpf_mask = DA7210_VOICE_EN;
313 hpf_value = 0;
314 bypass = 0;
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900315 break;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900316 case 48000:
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900317 fs = DA7210_PLL_FS_48000;
318 hpf_mask = DA7210_VOICE_EN;
319 hpf_value = 0;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900320 bypass = DA7210_PLL_BYP;
321 break;
322 case 88200:
323 fs = DA7210_PLL_FS_88200;
324 hpf_mask = DA7210_VOICE_EN;
325 hpf_value = 0;
326 bypass = 0;
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900327 break;
328 case 96000:
329 fs = DA7210_PLL_FS_96000;
330 hpf_mask = DA7210_VOICE_EN;
331 hpf_value = 0;
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900332 bypass = DA7210_PLL_BYP;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900333 break;
334 default:
335 return -EINVAL;
336 }
337
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900338 /* Disable active mode */
339 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
340
Kuninori Morimoto3a9d6202010-03-01 10:10:43 +0900341 snd_soc_update_bits(codec, hpf_reg, hpf_mask, hpf_value);
342 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900343 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass);
344
345 /* Enable active mode */
346 snd_soc_update_bits(codec, DA7210_STARTUP1,
347 DA7210_SC_MST_EN, DA7210_SC_MST_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900348
349 return 0;
350}
351
352/*
353 * Set DAI mode and Format
354 */
355static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
356{
357 struct snd_soc_codec *codec = codec_dai->codec;
358 u32 dai_cfg1;
359 u32 dai_cfg3;
360
Axel Lin40a49712011-10-12 07:16:25 +0800361 dai_cfg1 = 0x7f & snd_soc_read(codec, DA7210_DAI_CFG1);
362 dai_cfg3 = 0xfc & snd_soc_read(codec, DA7210_DAI_CFG3);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900363
364 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
365 case SND_SOC_DAIFMT_CBM_CFM:
366 dai_cfg1 |= DA7210_DAI_MODE_MASTER;
367 break;
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530368 case SND_SOC_DAIFMT_CBS_CFS:
369 dai_cfg1 |= DA7210_DAI_MODE_SLAVE;
370 break;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900371 default:
372 return -EINVAL;
373 }
374
375 /* FIXME
376 *
377 * It support I2S only now
378 */
379 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
380 case SND_SOC_DAIFMT_I2S:
381 dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE;
382 break;
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530383 case SND_SOC_DAIFMT_LEFT_J:
384 dai_cfg3 |= DA7210_DAI_FORMAT_LEFT_J;
385 break;
386 case SND_SOC_DAIFMT_RIGHT_J:
387 dai_cfg3 |= DA7210_DAI_FORMAT_RIGHT_J;
388 break;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900389 default:
390 return -EINVAL;
391 }
392
393 /* FIXME
394 *
395 * It support 64bit data transmission only now
396 */
397 dai_cfg1 |= DA7210_DAI_FLEN_64BIT;
398
Axel Lin40a49712011-10-12 07:16:25 +0800399 snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
400 snd_soc_write(codec, DA7210_DAI_CFG3, dai_cfg3);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900401
402 return 0;
403}
404
Ashish Chavan0f8ea582011-10-12 20:33:21 +0530405#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
406 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900407
408/* DAI operations */
409static struct snd_soc_dai_ops da7210_dai_ops = {
410 .startup = da7210_startup,
411 .hw_params = da7210_hw_params,
412 .set_fmt = da7210_set_dai_fmt,
413};
414
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000415static struct snd_soc_dai_driver da7210_dai = {
416 .name = "da7210-hifi",
Kuninori Morimoto98615452009-12-14 13:21:56 +0900417 /* playback capabilities */
418 .playback = {
419 .stream_name = "Playback",
420 .channels_min = 1,
421 .channels_max = 2,
422 .rates = SNDRV_PCM_RATE_8000_96000,
423 .formats = DA7210_FORMATS,
424 },
425 /* capture capabilities */
426 .capture = {
427 .stream_name = "Capture",
428 .channels_min = 1,
429 .channels_max = 2,
430 .rates = SNDRV_PCM_RATE_8000_96000,
431 .formats = DA7210_FORMATS,
432 },
433 .ops = &da7210_dai_ops,
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900434 .symmetric_rates = 1,
Kuninori Morimoto98615452009-12-14 13:21:56 +0900435};
Kuninori Morimoto98615452009-12-14 13:21:56 +0900436
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000437static int da7210_probe(struct snd_soc_codec *codec)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900438{
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000439 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
Axel Lin40a49712011-10-12 07:16:25 +0800440 int ret;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900441
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000442 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900443
Axel Lin40a49712011-10-12 07:16:25 +0800444 ret = snd_soc_codec_set_cache_io(codec, 8, 8, da7210->control_type);
445 if (ret < 0) {
446 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
447 return ret;
448 }
Kuninori Morimoto98615452009-12-14 13:21:56 +0900449
450 /* FIXME
451 *
452 * This driver use fixed value here
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900453 * And below settings expects MCLK = 12.288MHz
454 *
455 * When you select different MCLK, please check...
456 * DA7210_PLL_DIV1 val
457 * DA7210_PLL_DIV2 val
458 * DA7210_PLL_DIV3 val
459 * DA7210_PLL_DIV3 :: DA7210_MCLK_RANGExxx
Kuninori Morimoto98615452009-12-14 13:21:56 +0900460 */
461
462 /*
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900463 * make sure that DA7210 use bypass mode before start up
464 */
Axel Lin40a49712011-10-12 07:16:25 +0800465 snd_soc_write(codec, DA7210_STARTUP1, 0);
466 snd_soc_write(codec, DA7210_PLL_DIV3,
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900467 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
468
469 /*
Kuninori Morimoto98615452009-12-14 13:21:56 +0900470 * ADC settings
471 */
472
473 /* Enable Left & Right MIC PGA and Mic Bias */
Axel Lin40a49712011-10-12 07:16:25 +0800474 snd_soc_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
475 snd_soc_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900476
477 /* Enable Left and Right input PGA */
Axel Lin40a49712011-10-12 07:16:25 +0800478 snd_soc_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN);
479 snd_soc_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900480
481 /* Enable Left and Right ADC */
Axel Lin40a49712011-10-12 07:16:25 +0800482 snd_soc_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900483
484 /*
485 * DAC settings
486 */
487
488 /* Enable Left and Right DAC */
Axel Lin40a49712011-10-12 07:16:25 +0800489 snd_soc_write(codec, DA7210_DAC_SEL,
Kuninori Morimoto98615452009-12-14 13:21:56 +0900490 DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN |
491 DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN);
492
493 /* Enable Left and Right out PGA */
Axel Lin40a49712011-10-12 07:16:25 +0800494 snd_soc_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
495 snd_soc_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900496
497 /* Enable Left and Right HeadPhone PGA */
Axel Lin40a49712011-10-12 07:16:25 +0800498 snd_soc_write(codec, DA7210_HP_CFG,
Kuninori Morimoto98615452009-12-14 13:21:56 +0900499 DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN |
500 DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN);
501
502 /* Diable PLL and bypass it */
Axel Lin40a49712011-10-12 07:16:25 +0800503 snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900504
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900505 /*
506 * If 48kHz sound came, it use bypass mode,
507 * and when it is 44.1kHz, it use PLL.
508 *
509 * This time, this driver sets PLL always ON
510 * and controls bypass/PLL mode by switching
511 * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit.
512 * see da7210_hw_params
513 */
Axel Lin40a49712011-10-12 07:16:25 +0800514 snd_soc_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */
515 snd_soc_write(codec, DA7210_PLL_DIV2, 0x99);
516 snd_soc_write(codec, DA7210_PLL_DIV3, 0x0A |
Kuninori Morimoto98615452009-12-14 13:21:56 +0900517 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
Kuninori Morimoto960b3b42010-03-11 11:37:44 +0900518 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
519
520 /* As suggested by Dialog */
Axel Lin40a49712011-10-12 07:16:25 +0800521 snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */
522 snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0xB4);
523 snd_soc_write(codec, DA7210_A_PLL1, 0x01);
524 snd_soc_write(codec, DA7210_A_CP_MODE, 0x7C);
525 snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */
526 snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0x00);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900527
528 /* Activate all enabled subsystem */
Axel Lin40a49712011-10-12 07:16:25 +0800529 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900530
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000531 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900532
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000533 return 0;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900534}
535
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000536static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
Kuninori Morimoto4c62ed92010-09-16 13:07:06 +0900537 .probe = da7210_probe,
Kuninori Morimoto4c62ed92010-09-16 13:07:06 +0900538 .reg_cache_size = ARRAY_SIZE(da7210_reg),
539 .reg_word_size = sizeof(u8),
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000540 .reg_cache_default = da7210_reg,
Axel Lin40a49712011-10-12 07:16:25 +0800541 .volatile_register = da7210_volatile_register,
Mark Browna6f096f2011-10-14 20:18:49 +0100542
543 .controls = da7210_snd_controls,
544 .num_controls = ARRAY_SIZE(da7210_snd_controls),
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000545};
546
Kuninori Morimoto98615452009-12-14 13:21:56 +0900547#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
Mark Brown735fe4c2010-01-12 14:13:00 +0000548static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
549 const struct i2c_device_id *id)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900550{
551 struct da7210_priv *da7210;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900552 int ret;
553
554 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
555 if (!da7210)
556 return -ENOMEM;
557
Kuninori Morimoto98615452009-12-14 13:21:56 +0900558 i2c_set_clientdata(i2c, da7210);
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000559 da7210->control_type = SND_SOC_I2C;
Kuninori Morimoto98615452009-12-14 13:21:56 +0900560
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000561 ret = snd_soc_register_codec(&i2c->dev,
562 &soc_codec_dev_da7210, &da7210_dai, 1);
563 if (ret < 0)
Axel Lin085efd22010-07-23 05:53:45 +0000564 kfree(da7210);
Kuninori Morimoto98615452009-12-14 13:21:56 +0900565
566 return ret;
567}
568
Mark Brown735fe4c2010-01-12 14:13:00 +0000569static int __devexit da7210_i2c_remove(struct i2c_client *client)
Kuninori Morimoto98615452009-12-14 13:21:56 +0900570{
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000571 snd_soc_unregister_codec(&client->dev);
572 kfree(i2c_get_clientdata(client));
Kuninori Morimoto98615452009-12-14 13:21:56 +0900573 return 0;
574}
575
576static const struct i2c_device_id da7210_i2c_id[] = {
577 { "da7210", 0 },
578 { }
579};
580MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
581
582/* I2C codec control layer */
583static struct i2c_driver da7210_i2c_driver = {
584 .driver = {
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000585 .name = "da7210-codec",
Kuninori Morimoto98615452009-12-14 13:21:56 +0900586 .owner = THIS_MODULE,
587 },
Kuninori Morimoto4c62ed92010-09-16 13:07:06 +0900588 .probe = da7210_i2c_probe,
589 .remove = __devexit_p(da7210_i2c_remove),
590 .id_table = da7210_i2c_id,
Kuninori Morimoto98615452009-12-14 13:21:56 +0900591};
592#endif
593
Kuninori Morimoto98615452009-12-14 13:21:56 +0900594static int __init da7210_modinit(void)
595{
596 int ret = 0;
597#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
598 ret = i2c_add_driver(&da7210_i2c_driver);
599#endif
600 return ret;
601}
602module_init(da7210_modinit);
603
604static void __exit da7210_exit(void)
605{
606#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
607 i2c_del_driver(&da7210_i2c_driver);
608#endif
609}
610module_exit(da7210_exit);
611
612MODULE_DESCRIPTION("ASoC DA7210 driver");
613MODULE_AUTHOR("David Chen, Kuninori Morimoto");
614MODULE_LICENSE("GPL");