2 * ak4535.c -- AK4535 ALSA Soc Audio driver
4 * Copyright 2005 Openedhand Ltd.
6 * Author: Richard Purdie <richard@openedhand.com>
8 * Based on wm8753.c by Liam Girdwood
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 #include <linux/module.h>
16 #include <linux/moduleparam.h>
17 #include <linux/init.h>
18 #include <linux/delay.h>
20 #include <linux/i2c.h>
21 #include <linux/regmap.h>
22 #include <linux/slab.h>
23 #include <sound/core.h>
24 #include <sound/pcm.h>
25 #include <sound/pcm_params.h>
26 #include <sound/soc.h>
27 #include <sound/initval.h>
31 /* codec private data */
33 struct regmap
*regmap
;
38 * ak4535 register cache
40 static const struct reg_default ak4535_reg_defaults
[] = {
58 static bool ak4535_volatile(struct device
*dev
, unsigned int reg
)
68 static const char *ak4535_mono_gain
[] = {"+6dB", "-17dB"};
69 static const char *ak4535_mono_out
[] = {"(L + R)/2", "Hi-Z"};
70 static const char *ak4535_hp_out
[] = {"Stereo", "Mono"};
71 static const char *ak4535_deemp
[] = {"44.1kHz", "Off", "48kHz", "32kHz"};
72 static const char *ak4535_mic_select
[] = {"Internal", "External"};
74 static const struct soc_enum ak4535_enum
[] = {
75 SOC_ENUM_SINGLE(AK4535_SIG1
, 7, 2, ak4535_mono_gain
),
76 SOC_ENUM_SINGLE(AK4535_SIG1
, 6, 2, ak4535_mono_out
),
77 SOC_ENUM_SINGLE(AK4535_MODE2
, 2, 2, ak4535_hp_out
),
78 SOC_ENUM_SINGLE(AK4535_DAC
, 0, 4, ak4535_deemp
),
79 SOC_ENUM_SINGLE(AK4535_MIC
, 1, 2, ak4535_mic_select
),
82 static const struct snd_kcontrol_new ak4535_snd_controls
[] = {
83 SOC_SINGLE("ALC2 Switch", AK4535_SIG1
, 1, 1, 0),
84 SOC_ENUM("Mono 1 Output", ak4535_enum
[1]),
85 SOC_ENUM("Mono 1 Gain", ak4535_enum
[0]),
86 SOC_ENUM("Headphone Output", ak4535_enum
[2]),
87 SOC_ENUM("Playback Deemphasis", ak4535_enum
[3]),
88 SOC_SINGLE("Bass Volume", AK4535_DAC
, 2, 3, 0),
89 SOC_SINGLE("Mic Boost (+20dB) Switch", AK4535_MIC
, 0, 1, 0),
90 SOC_ENUM("Mic Select", ak4535_enum
[4]),
91 SOC_SINGLE("ALC Operation Time", AK4535_TIMER
, 0, 3, 0),
92 SOC_SINGLE("ALC Recovery Time", AK4535_TIMER
, 2, 3, 0),
93 SOC_SINGLE("ALC ZC Time", AK4535_TIMER
, 4, 3, 0),
94 SOC_SINGLE("ALC 1 Switch", AK4535_ALC1
, 5, 1, 0),
95 SOC_SINGLE("ALC 2 Switch", AK4535_ALC1
, 6, 1, 0),
96 SOC_SINGLE("ALC Volume", AK4535_ALC2
, 0, 127, 0),
97 SOC_SINGLE("Capture Volume", AK4535_PGA
, 0, 127, 0),
98 SOC_SINGLE("Left Playback Volume", AK4535_LATT
, 0, 127, 1),
99 SOC_SINGLE("Right Playback Volume", AK4535_RATT
, 0, 127, 1),
100 SOC_SINGLE("AUX Bypass Volume", AK4535_VOL
, 0, 15, 0),
101 SOC_SINGLE("Mic Sidetone Volume", AK4535_VOL
, 4, 7, 0),
105 static const struct snd_kcontrol_new ak4535_mono1_mixer_controls
[] = {
106 SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG1
, 4, 1, 0),
107 SOC_DAPM_SINGLE("Mono Playback Switch", AK4535_SIG1
, 5, 1, 0),
111 static const struct snd_kcontrol_new ak4535_stereo_mixer_controls
[] = {
112 SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG2
, 4, 1, 0),
113 SOC_DAPM_SINGLE("Playback Switch", AK4535_SIG2
, 7, 1, 0),
114 SOC_DAPM_SINGLE("Aux Bypass Switch", AK4535_SIG2
, 5, 1, 0),
118 static const struct snd_kcontrol_new ak4535_input_mixer_controls
[] = {
119 SOC_DAPM_SINGLE("Mic Capture Switch", AK4535_MIC
, 2, 1, 0),
120 SOC_DAPM_SINGLE("Aux Capture Switch", AK4535_MIC
, 5, 1, 0),
124 static const struct snd_kcontrol_new ak4535_input_mux_control
=
125 SOC_DAPM_ENUM("Input Select", ak4535_enum
[4]);
128 static const struct snd_kcontrol_new ak4535_hpl_control
=
129 SOC_DAPM_SINGLE("Switch", AK4535_SIG2
, 1, 1, 1);
132 static const struct snd_kcontrol_new ak4535_hpr_control
=
133 SOC_DAPM_SINGLE("Switch", AK4535_SIG2
, 0, 1, 1);
136 static const struct snd_kcontrol_new ak4535_mono2_control
=
137 SOC_DAPM_SINGLE("Switch", AK4535_SIG1
, 0, 1, 0);
139 /* Line out switch */
140 static const struct snd_kcontrol_new ak4535_line_control
=
141 SOC_DAPM_SINGLE("Switch", AK4535_SIG2
, 6, 1, 0);
143 /* ak4535 dapm widgets */
144 static const struct snd_soc_dapm_widget ak4535_dapm_widgets
[] = {
145 SND_SOC_DAPM_MIXER("Stereo Mixer", SND_SOC_NOPM
, 0, 0,
146 &ak4535_stereo_mixer_controls
[0],
147 ARRAY_SIZE(ak4535_stereo_mixer_controls
)),
148 SND_SOC_DAPM_MIXER("Mono1 Mixer", SND_SOC_NOPM
, 0, 0,
149 &ak4535_mono1_mixer_controls
[0],
150 ARRAY_SIZE(ak4535_mono1_mixer_controls
)),
151 SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM
, 0, 0,
152 &ak4535_input_mixer_controls
[0],
153 ARRAY_SIZE(ak4535_input_mixer_controls
)),
154 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM
, 0, 0,
155 &ak4535_input_mux_control
),
156 SND_SOC_DAPM_DAC("DAC", "Playback", AK4535_PM2
, 0, 0),
157 SND_SOC_DAPM_SWITCH("Mono 2 Enable", SND_SOC_NOPM
, 0, 0,
158 &ak4535_mono2_control
),
159 /* speaker powersave bit */
160 SND_SOC_DAPM_PGA("Speaker Enable", AK4535_MODE2
, 0, 0, NULL
, 0),
161 SND_SOC_DAPM_SWITCH("Line Out Enable", SND_SOC_NOPM
, 0, 0,
162 &ak4535_line_control
),
163 SND_SOC_DAPM_SWITCH("Left HP Enable", SND_SOC_NOPM
, 0, 0,
164 &ak4535_hpl_control
),
165 SND_SOC_DAPM_SWITCH("Right HP Enable", SND_SOC_NOPM
, 0, 0,
166 &ak4535_hpr_control
),
167 SND_SOC_DAPM_OUTPUT("LOUT"),
168 SND_SOC_DAPM_OUTPUT("HPL"),
169 SND_SOC_DAPM_OUTPUT("ROUT"),
170 SND_SOC_DAPM_OUTPUT("HPR"),
171 SND_SOC_DAPM_OUTPUT("SPP"),
172 SND_SOC_DAPM_OUTPUT("SPN"),
173 SND_SOC_DAPM_OUTPUT("MOUT1"),
174 SND_SOC_DAPM_OUTPUT("MOUT2"),
175 SND_SOC_DAPM_OUTPUT("MICOUT"),
176 SND_SOC_DAPM_ADC("ADC", "Capture", AK4535_PM1
, 0, 0),
177 SND_SOC_DAPM_PGA("Spk Amp", AK4535_PM2
, 3, 0, NULL
, 0),
178 SND_SOC_DAPM_PGA("HP R Amp", AK4535_PM2
, 1, 0, NULL
, 0),
179 SND_SOC_DAPM_PGA("HP L Amp", AK4535_PM2
, 2, 0, NULL
, 0),
180 SND_SOC_DAPM_PGA("Mic", AK4535_PM1
, 1, 0, NULL
, 0),
181 SND_SOC_DAPM_PGA("Line Out", AK4535_PM1
, 4, 0, NULL
, 0),
182 SND_SOC_DAPM_PGA("Mono Out", AK4535_PM1
, 3, 0, NULL
, 0),
183 SND_SOC_DAPM_PGA("AUX In", AK4535_PM1
, 2, 0, NULL
, 0),
185 SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4535_MIC
, 3, 0),
186 SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4535_MIC
, 4, 0),
187 SND_SOC_DAPM_INPUT("MICIN"),
188 SND_SOC_DAPM_INPUT("MICEXT"),
189 SND_SOC_DAPM_INPUT("AUX"),
190 SND_SOC_DAPM_INPUT("MIN"),
191 SND_SOC_DAPM_INPUT("AIN"),
194 static const struct snd_soc_dapm_route ak4535_audio_map
[] = {
196 {"Stereo Mixer", "Playback Switch", "DAC"},
197 {"Stereo Mixer", "Mic Sidetone Switch", "Mic"},
198 {"Stereo Mixer", "Aux Bypass Switch", "AUX In"},
201 {"Mono1 Mixer", "Mic Sidetone Switch", "Mic"},
202 {"Mono1 Mixer", "Mono Playback Switch", "DAC"},
205 {"Mic", NULL
, "AIN"},
206 {"Input Mux", "Internal", "Mic Int Bias"},
207 {"Input Mux", "External", "Mic Ext Bias"},
208 {"Mic Int Bias", NULL
, "MICIN"},
209 {"Mic Ext Bias", NULL
, "MICEXT"},
210 {"MICOUT", NULL
, "Input Mux"},
213 {"LOUT", NULL
, "Line Out Enable"},
214 {"ROUT", NULL
, "Line Out Enable"},
215 {"Line Out Enable", "Switch", "Line Out"},
216 {"Line Out", NULL
, "Stereo Mixer"},
219 {"MOUT1", NULL
, "Mono Out"},
220 {"Mono Out", NULL
, "Mono1 Mixer"},
223 {"HPL", NULL
, "Left HP Enable"},
224 {"Left HP Enable", "Switch", "HP L Amp"},
225 {"HP L Amp", NULL
, "Stereo Mixer"},
228 {"HPR", NULL
, "Right HP Enable"},
229 {"Right HP Enable", "Switch", "HP R Amp"},
230 {"HP R Amp", NULL
, "Stereo Mixer"},
233 {"SPP", NULL
, "Speaker Enable"},
234 {"SPN", NULL
, "Speaker Enable"},
235 {"Speaker Enable", "Switch", "Spk Amp"},
236 {"Spk Amp", NULL
, "MIN"},
239 {"MOUT2", NULL
, "Mono 2 Enable"},
240 {"Mono 2 Enable", "Switch", "Stereo Mixer"},
243 {"Aux In", NULL
, "AUX"},
246 {"ADC", NULL
, "Input Mixer"},
247 {"Input Mixer", "Mic Capture Switch", "Mic"},
248 {"Input Mixer", "Aux Capture Switch", "Aux In"},
251 static int ak4535_set_dai_sysclk(struct snd_soc_dai
*codec_dai
,
252 int clk_id
, unsigned int freq
, int dir
)
254 struct snd_soc_codec
*codec
= codec_dai
->codec
;
255 struct ak4535_priv
*ak4535
= snd_soc_codec_get_drvdata(codec
);
257 ak4535
->sysclk
= freq
;
261 static int ak4535_hw_params(struct snd_pcm_substream
*substream
,
262 struct snd_pcm_hw_params
*params
,
263 struct snd_soc_dai
*dai
)
265 struct snd_soc_codec
*codec
= dai
->codec
;
266 struct ak4535_priv
*ak4535
= snd_soc_codec_get_drvdata(codec
);
267 u8 mode2
= snd_soc_read(codec
, AK4535_MODE2
) & ~(0x3 << 5);
268 int rate
= params_rate(params
), fs
= 256;
271 fs
= ak4535
->sysclk
/ rate
;
286 snd_soc_write(codec
, AK4535_MODE2
, mode2
);
290 static int ak4535_set_dai_fmt(struct snd_soc_dai
*codec_dai
,
293 struct snd_soc_codec
*codec
= codec_dai
->codec
;
296 /* interface format */
297 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
298 case SND_SOC_DAIFMT_I2S
:
301 case SND_SOC_DAIFMT_LEFT_J
:
308 /* use 32 fs for BCLK to save power */
311 snd_soc_write(codec
, AK4535_MODE1
, mode1
);
315 static int ak4535_mute(struct snd_soc_dai
*dai
, int mute
)
317 struct snd_soc_codec
*codec
= dai
->codec
;
318 u16 mute_reg
= snd_soc_read(codec
, AK4535_DAC
);
320 snd_soc_write(codec
, AK4535_DAC
, mute_reg
& ~0x20);
322 snd_soc_write(codec
, AK4535_DAC
, mute_reg
| 0x20);
326 static int ak4535_set_bias_level(struct snd_soc_codec
*codec
,
327 enum snd_soc_bias_level level
)
330 case SND_SOC_BIAS_ON
:
331 snd_soc_update_bits(codec
, AK4535_DAC
, 0x20, 0);
333 case SND_SOC_BIAS_PREPARE
:
334 snd_soc_update_bits(codec
, AK4535_DAC
, 0x20, 0x20);
336 case SND_SOC_BIAS_STANDBY
:
337 snd_soc_update_bits(codec
, AK4535_PM1
, 0x80, 0x80);
338 snd_soc_update_bits(codec
, AK4535_PM2
, 0x80, 0);
340 case SND_SOC_BIAS_OFF
:
341 snd_soc_update_bits(codec
, AK4535_PM1
, 0x80, 0);
347 #define AK4535_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
348 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
349 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
351 static const struct snd_soc_dai_ops ak4535_dai_ops
= {
352 .hw_params
= ak4535_hw_params
,
353 .set_fmt
= ak4535_set_dai_fmt
,
354 .digital_mute
= ak4535_mute
,
355 .set_sysclk
= ak4535_set_dai_sysclk
,
358 static struct snd_soc_dai_driver ak4535_dai
= {
359 .name
= "ak4535-hifi",
361 .stream_name
= "Playback",
364 .rates
= AK4535_RATES
,
365 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,},
367 .stream_name
= "Capture",
370 .rates
= AK4535_RATES
,
371 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,},
372 .ops
= &ak4535_dai_ops
,
375 static int ak4535_resume(struct snd_soc_codec
*codec
)
377 snd_soc_cache_sync(codec
);
381 static const struct regmap_config ak4535_regmap
= {
385 .max_register
= AK4535_STATUS
,
386 .volatile_reg
= ak4535_volatile
,
388 .cache_type
= REGCACHE_RBTREE
,
389 .reg_defaults
= ak4535_reg_defaults
,
390 .num_reg_defaults
= ARRAY_SIZE(ak4535_reg_defaults
),
393 static const struct snd_soc_codec_driver soc_codec_dev_ak4535
= {
394 .resume
= ak4535_resume
,
395 .set_bias_level
= ak4535_set_bias_level
,
396 .suspend_bias_off
= true,
398 .component_driver
= {
399 .controls
= ak4535_snd_controls
,
400 .num_controls
= ARRAY_SIZE(ak4535_snd_controls
),
401 .dapm_widgets
= ak4535_dapm_widgets
,
402 .num_dapm_widgets
= ARRAY_SIZE(ak4535_dapm_widgets
),
403 .dapm_routes
= ak4535_audio_map
,
404 .num_dapm_routes
= ARRAY_SIZE(ak4535_audio_map
),
408 static int ak4535_i2c_probe(struct i2c_client
*i2c
,
409 const struct i2c_device_id
*id
)
411 struct ak4535_priv
*ak4535
;
414 ak4535
= devm_kzalloc(&i2c
->dev
, sizeof(struct ak4535_priv
),
419 ak4535
->regmap
= devm_regmap_init_i2c(i2c
, &ak4535_regmap
);
420 if (IS_ERR(ak4535
->regmap
)) {
421 ret
= PTR_ERR(ak4535
->regmap
);
422 dev_err(&i2c
->dev
, "Failed to init regmap: %d\n", ret
);
426 i2c_set_clientdata(i2c
, ak4535
);
428 ret
= snd_soc_register_codec(&i2c
->dev
,
429 &soc_codec_dev_ak4535
, &ak4535_dai
, 1);
434 static int ak4535_i2c_remove(struct i2c_client
*client
)
436 snd_soc_unregister_codec(&client
->dev
);
440 static const struct i2c_device_id ak4535_i2c_id
[] = {
444 MODULE_DEVICE_TABLE(i2c
, ak4535_i2c_id
);
446 static struct i2c_driver ak4535_i2c_driver
= {
450 .probe
= ak4535_i2c_probe
,
451 .remove
= ak4535_i2c_remove
,
452 .id_table
= ak4535_i2c_id
,
455 module_i2c_driver(ak4535_i2c_driver
);
457 MODULE_DESCRIPTION("Soc AK4535 driver");
458 MODULE_AUTHOR("Richard Purdie");
459 MODULE_LICENSE("GPL");