blob: c32eadebb7627f0049b5ccc10eb7d47aca1b55ed [file] [log] [blame]
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +02001/*
2* alc5632.c -- ALC5632 ALSA SoC Audio Codec
3*
4* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
5*
6* Authors: Leon Romanovsky <leon@leon.nu>
7* Andrey Danin <danindrey@mail.ru>
8* Ilya Petrov <ilya.muromec@gmail.com>
9* Marc Dietrich <marvin24@gmx.de>
10*
11* Based on alc5623.c by Arnaud Patard
12*
13* This program is free software; you can redistribute it and/or modify
14* it under the terms of the GNU General Public License version 2 as
15* published by the Free Software Foundation.
16*/
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/pm.h>
23#include <linux/i2c.h>
24#include <linux/slab.h>
Leon Romanovskybb397532011-11-16 12:06:58 +020025#include <linux/regmap.h>
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +020026#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/tlv.h>
30#include <sound/soc.h>
31#include <sound/initval.h>
32
33#include "alc5632.h"
34
35/*
36 * ALC5632 register cache
37 */
Leon Romanovskybb397532011-11-16 12:06:58 +020038static struct reg_default alc5632_reg_defaults[] = {
Leon Romanovsky43fa8e52011-11-17 12:01:28 +020039 { 0, 0x59B4 }, /* R0 - Reset */
40 { 2, 0x8080 }, /* R2 - Speaker Output Volume */
41 { 4, 0x8080 }, /* R4 - Headphone Output Volume */
42 { 6, 0x8080 }, /* R6 - AUXOUT Volume */
43 { 8, 0xC800 }, /* R8 - Phone Input */
44 { 10, 0xE808 }, /* R10 - LINE_IN Volume */
45 { 12, 0x1010 }, /* R12 - STEREO DAC Input Volume */
46 { 14, 0x0808 }, /* R14 - MIC Input Volume */
47 { 16, 0xEE0F }, /* R16 - Stereo DAC and MIC Routing Control */
48 { 18, 0xCBCB }, /* R18 - ADC Record Gain */
49 { 20, 0x7F7F }, /* R20 - ADC Record Mixer Control */
50 { 24, 0xE010 }, /* R24 - Voice DAC Volume */
51 { 28, 0x8008 }, /* R28 - Output Mixer Control */
52 { 34, 0x0000 }, /* R34 - Microphone Control */
53 { 36, 0x00C0 }, /* R36 - Codec Digital MIC/Digital Boost
54 Control */
55 { 38, 0xEF00 }, /* R38 - Power Down Control/Status */
56 { 46, 0x0000 }, /* R46 - Stereo DAC/Voice DAC/Stereo ADC
57 Function Select */
58 { 52, 0x8000 }, /* R52 - Main Serial Data Port Control
59 (Stereo I2S) */
60 { 54, 0x0000 }, /* R54 - Extend Serial Data Port Control
61 (VoDAC_I2S/PCM) */
62 { 58, 0x0000 }, /* R58 - Power Management Addition 1 */
63 { 60, 0x0000 }, /* R60 - Power Management Addition 2 */
64 { 62, 0x8000 }, /* R62 - Power Management Addition 3 */
65 { 64, 0x0C0A }, /* R64 - General Purpose Control Register 1 */
66 { 66, 0x0000 }, /* R66 - General Purpose Control Register 2 */
67 { 68, 0x0000 }, /* R68 - PLL1 Control */
68 { 70, 0x0000 }, /* R70 - PLL2 Control */
69 { 76, 0xBE3E }, /* R76 - GPIO Pin Configuration */
70 { 78, 0xBE3E }, /* R78 - GPIO Pin Polarity */
71 { 80, 0x0000 }, /* R80 - GPIO Pin Sticky */
72 { 82, 0x0000 }, /* R82 - GPIO Pin Wake Up */
73 { 84, 0x803A }, /* R84 - GPIO Pin Status */
74 { 86, 0x0000 }, /* R86 - Pin Sharing */
75 { 88, 0x0000 }, /* R88 - Over-Temp/Current Status */
76 { 90, 0x0009 }, /* R90 - Soft Volume Control Setting */
77 { 92, 0x0000 }, /* R92 - GPIO_Output Pin Control */
78 { 94, 0x3000 }, /* R94 - MISC Control */
79 { 96, 0x3075 }, /* R96 - Stereo DAC Clock Control_1 */
80 { 98, 0x1010 }, /* R98 - Stereo DAC Clock Control_2 */
81 { 100, 0x3110 }, /* R100 - VoDAC_PCM Clock Control_1 */
82 { 104, 0x0553 }, /* R104 - Pseudo Stereo and Spatial Effect
83 Block Control */
84 { 106, 0x0000 }, /* R106 - Private Register Address */
85 { 108, 0x0000 }, /* R108 - Private Register Data */
86 { 110, 0x0000 }, /* R110 - EQ Control and Status/ADC
87 HPF Control */
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +020088};
89
90/* codec private data */
91struct alc5632_priv {
Leon Romanovskybb397532011-11-16 12:06:58 +020092 struct regmap *regmap;
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +020093 u8 id;
94 unsigned int sysclk;
95};
96
Leon Romanovskybb397532011-11-16 12:06:58 +020097static bool alc5632_volatile_register(struct device *dev,
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +020098 unsigned int reg)
99{
100 switch (reg) {
101 case ALC5632_RESET:
102 case ALC5632_PWR_DOWN_CTRL_STATUS:
103 case ALC5632_GPIO_PIN_STATUS:
104 case ALC5632_OVER_CURR_STATUS:
105 case ALC5632_HID_CTRL_DATA:
106 case ALC5632_EQ_CTRL:
Leon Romanovsky9b4156c2011-11-17 12:01:29 +0200107 case ALC5632_VENDOR_ID1:
108 case ALC5632_VENDOR_ID2:
Leon Romanovskybb397532011-11-16 12:06:58 +0200109 return true;
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200110
111 default:
112 break;
113 }
114
Leon Romanovskybb397532011-11-16 12:06:58 +0200115 return false;
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200116}
117
Leon Romanovskybb397532011-11-16 12:06:58 +0200118static inline int alc5632_reset(struct regmap *map)
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200119{
Leon Romanovskybb397532011-11-16 12:06:58 +0200120 return regmap_write(map, ALC5632_RESET, 0x59B4);
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200121}
122
123static int amp_mixer_event(struct snd_soc_dapm_widget *w,
124 struct snd_kcontrol *kcontrol, int event)
125{
126 /* to power-on/off class-d amp generators/speaker */
127 /* need to write to 'index-46h' register : */
128 /* so write index num (here 0x46) to reg 0x6a */
129 /* and then 0xffff/0 to reg 0x6c */
130 snd_soc_write(w->codec, ALC5632_HID_CTRL_INDEX, 0x46);
131
132 switch (event) {
133 case SND_SOC_DAPM_PRE_PMU:
134 snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0xFFFF);
135 break;
136 case SND_SOC_DAPM_POST_PMD:
137 snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0);
138 break;
139 }
140
141 return 0;
142}
143
144/*
145 * ALC5632 Controls
146 */
147
148/* -34.5db min scale, 1.5db steps, no mute */
149static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0);
150/* -46.5db min scale, 1.5db steps, no mute */
151static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
152/* -16.5db min scale, 1.5db steps, no mute */
153static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
154static const unsigned int boost_tlv[] = {
155 TLV_DB_RANGE_HEAD(3),
156 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
157 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
158 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
159};
160/* 0db min scale, 6 db steps, no mute */
161static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
162/* 0db min scalem 0.75db steps, no mute */
163static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 075, 0);
164
165static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = {
166 /* left starts at bit 8, right at bit 0 */
167 /* 31 steps (5 bit), -46.5db scale */
Andrey Danin1a083252011-11-13 21:53:13 +0200168 SOC_DOUBLE_TLV("Speaker Playback Volume",
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200169 ALC5632_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
170 /* bit 15 mutes left, bit 7 right */
Andrey Danin1a083252011-11-13 21:53:13 +0200171 SOC_DOUBLE("Speaker Playback Switch",
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200172 ALC5632_SPK_OUT_VOL, 15, 7, 1, 1),
173 SOC_DOUBLE_TLV("Headphone Playback Volume",
174 ALC5632_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
175 SOC_DOUBLE("Headphone Playback Switch",
176 ALC5632_HP_OUT_VOL, 15, 7, 1, 1),
177};
178
179static const struct snd_kcontrol_new alc5632_snd_controls[] = {
180 SOC_DOUBLE_TLV("Auxout Playback Volume",
181 ALC5632_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv),
182 SOC_DOUBLE("Auxout Playback Switch",
183 ALC5632_AUX_OUT_VOL, 15, 7, 1, 1),
184 SOC_SINGLE_TLV("Voice DAC Playback Volume",
185 ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv),
186 SOC_SINGLE_TLV("Phone Capture Volume",
187 ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv),
188 SOC_DOUBLE_TLV("LineIn Capture Volume",
189 ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
Andrey Danin1a083252011-11-13 21:53:13 +0200190 SOC_DOUBLE_TLV("Master Playback Volume",
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200191 ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv),
Andrey Danin1a083252011-11-13 21:53:13 +0200192 SOC_DOUBLE("Master Playback Switch",
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200193 ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1),
194 SOC_SINGLE_TLV("Mic1 Capture Volume",
195 ALC5632_MIC_VOL, 8, 31, 1, vol_tlv),
196 SOC_SINGLE_TLV("Mic2 Capture Volume",
197 ALC5632_MIC_VOL, 0, 31, 1, vol_tlv),
198 SOC_DOUBLE_TLV("Rec Capture Volume",
199 ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv),
200 SOC_SINGLE_TLV("Mic 1 Boost Volume",
201 ALC5632_MIC_CTRL, 10, 2, 0, boost_tlv),
202 SOC_SINGLE_TLV("Mic 2 Boost Volume",
203 ALC5632_MIC_CTRL, 8, 2, 0, boost_tlv),
204 SOC_SINGLE_TLV("Digital Boost Volume",
205 ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv),
206};
207
208/*
209 * DAPM Controls
210 */
211static const struct snd_kcontrol_new alc5632_hp_mixer_controls[] = {
212SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5632_LINE_IN_VOL, 15, 1, 1),
213SOC_DAPM_SINGLE("PHONE2HP Playback Switch", ALC5632_PHONE_IN_VOL, 15, 1, 1),
214SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 15, 1, 1),
215SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 11, 1, 1),
216SOC_DAPM_SINGLE("VOICE2HP Playback Switch", ALC5632_VOICE_DAC_VOL, 15, 1, 1),
217};
218
219static const struct snd_kcontrol_new alc5632_hpl_mixer_controls[] = {
220SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5632_ADC_REC_GAIN, 15, 1, 1),
221SOC_DAPM_SINGLE("DACL2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 3, 1, 1),
222};
223
224static const struct snd_kcontrol_new alc5632_hpr_mixer_controls[] = {
225SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5632_ADC_REC_GAIN, 7, 1, 1),
226SOC_DAPM_SINGLE("DACR2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 2, 1, 1),
227};
228
229static const struct snd_kcontrol_new alc5632_mono_mixer_controls[] = {
230SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5632_ADC_REC_GAIN, 14, 1, 1),
231SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5632_ADC_REC_GAIN, 6, 1, 1),
232SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5632_LINE_IN_VOL, 13, 1, 1),
233SOC_DAPM_SINGLE("MIC12MONO Playback Switch",
234 ALC5632_MIC_ROUTING_CTRL, 13, 1, 1),
235SOC_DAPM_SINGLE("MIC22MONO Playback Switch",
236 ALC5632_MIC_ROUTING_CTRL, 9, 1, 1),
237SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5632_MIC_ROUTING_CTRL, 0, 1, 1),
238SOC_DAPM_SINGLE("VOICE2MONO Playback Switch", ALC5632_VOICE_DAC_VOL, 13, 1, 1),
239};
240
241static const struct snd_kcontrol_new alc5632_speaker_mixer_controls[] = {
242SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5632_LINE_IN_VOL, 14, 1, 1),
243SOC_DAPM_SINGLE("PHONE2SPK Playback Switch", ALC5632_PHONE_IN_VOL, 14, 1, 1),
244SOC_DAPM_SINGLE("MIC12SPK Playback Switch",
245 ALC5632_MIC_ROUTING_CTRL, 14, 1, 1),
246SOC_DAPM_SINGLE("MIC22SPK Playback Switch",
247 ALC5632_MIC_ROUTING_CTRL, 10, 1, 1),
248SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5632_MIC_ROUTING_CTRL, 1, 1, 1),
249SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1),
250};
251
252/* Left Record Mixer */
253static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = {
254SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),
255SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),
256SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),
257SOC_DAPM_SINGLE("Left Phone Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),
258SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),
259SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),
260SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),
261};
262
263/* Right Record Mixer */
264static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = {
265SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),
266SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),
267SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),
268SOC_DAPM_SINGLE("Right Phone Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),
269SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),
270SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),
271SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),
272};
273
274static const char *alc5632_spk_n_sour_sel[] = {
275 "RN/-R", "RP/+R", "LN/-R", "Mute"};
276static const char *alc5632_hpl_out_input_sel[] = {
277 "Vmid", "HP Left Mix"};
278static const char *alc5632_hpr_out_input_sel[] = {
279 "Vmid", "HP Right Mix"};
280static const char *alc5632_spkout_input_sel[] = {
281 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
282static const char *alc5632_aux_out_input_sel[] = {
283 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
284
285/* auxout output mux */
286static const struct soc_enum alc5632_aux_out_input_enum =
287SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 6, 4, alc5632_aux_out_input_sel);
288static const struct snd_kcontrol_new alc5632_auxout_mux_controls =
289SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum);
290
291/* speaker output mux */
292static const struct soc_enum alc5632_spkout_input_enum =
293SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 10, 4, alc5632_spkout_input_sel);
294static const struct snd_kcontrol_new alc5632_spkout_mux_controls =
295SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum);
296
297/* headphone left output mux */
298static const struct soc_enum alc5632_hpl_out_input_enum =
299SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 9, 2, alc5632_hpl_out_input_sel);
300static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls =
301SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum);
302
303/* headphone right output mux */
304static const struct soc_enum alc5632_hpr_out_input_enum =
305SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 8, 2, alc5632_hpr_out_input_sel);
306static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls =
307SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum);
308
309/* speaker output N select */
310static const struct soc_enum alc5632_spk_n_sour_enum =
311SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 14, 4, alc5632_spk_n_sour_sel);
312static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls =
313SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum);
314
315/* speaker amplifier */
316static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"};
317static const struct soc_enum alc5632_amp_enum =
318 SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 13, 2, alc5632_amp_names);
319static const struct snd_kcontrol_new alc5632_amp_mux_controls =
320 SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);
321
322
323static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = {
324/* Muxes */
325SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0,
326 &alc5632_auxout_mux_controls),
327SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0,
328 &alc5632_spkout_mux_controls),
329SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,
330 &alc5632_hpl_out_mux_controls),
331SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
332 &alc5632_hpr_out_mux_controls),
333SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
334 &alc5632_spkoutn_mux_controls),
335
336/* output mixers */
337SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
338 &alc5632_hp_mixer_controls[0],
339 ARRAY_SIZE(alc5632_hp_mixer_controls)),
340SND_SOC_DAPM_MIXER("HPR Mix", ALC5632_PWR_MANAG_ADD2, 4, 0,
341 &alc5632_hpr_mixer_controls[0],
342 ARRAY_SIZE(alc5632_hpr_mixer_controls)),
343SND_SOC_DAPM_MIXER("HPL Mix", ALC5632_PWR_MANAG_ADD2, 5, 0,
344 &alc5632_hpl_mixer_controls[0],
345 ARRAY_SIZE(alc5632_hpl_mixer_controls)),
346SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
347SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0,
348 &alc5632_mono_mixer_controls[0],
349 ARRAY_SIZE(alc5632_mono_mixer_controls)),
350SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0,
351 &alc5632_speaker_mixer_controls[0],
352 ARRAY_SIZE(alc5632_speaker_mixer_controls)),
353
354/* input mixers */
355SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0,
356 &alc5632_captureL_mixer_controls[0],
357 ARRAY_SIZE(alc5632_captureL_mixer_controls)),
358SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0,
359 &alc5632_captureR_mixer_controls[0],
360 ARRAY_SIZE(alc5632_captureR_mixer_controls)),
361
362SND_SOC_DAPM_DAC("Left DAC", "HiFi Playback",
363 ALC5632_PWR_MANAG_ADD2, 9, 0),
364SND_SOC_DAPM_DAC("Right DAC", "HiFi Playback",
365 ALC5632_PWR_MANAG_ADD2, 8, 0),
366SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0),
367SND_SOC_DAPM_MIXER("DAC Right Channel",
368 ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0),
369SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0),
370SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
371SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
372SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture",
373 ALC5632_PWR_MANAG_ADD2, 7, 0),
374SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture",
375 ALC5632_PWR_MANAG_ADD2, 6, 0),
376SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0),
377SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0),
378SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0),
379SND_SOC_DAPM_PGA("Right Speaker", ALC5632_PWR_MANAG_ADD3, 12, 0, NULL, 0),
380SND_SOC_DAPM_PGA("Aux Out", ALC5632_PWR_MANAG_ADD3, 14, 0, NULL, 0),
381SND_SOC_DAPM_PGA("Left LineIn", ALC5632_PWR_MANAG_ADD3, 7, 0, NULL, 0),
382SND_SOC_DAPM_PGA("Right LineIn", ALC5632_PWR_MANAG_ADD3, 6, 0, NULL, 0),
383SND_SOC_DAPM_PGA("Phone", ALC5632_PWR_MANAG_ADD3, 5, 0, NULL, 0),
384SND_SOC_DAPM_PGA("Phone ADMix", ALC5632_PWR_MANAG_ADD3, 4, 0, NULL, 0),
385SND_SOC_DAPM_PGA("MIC1 PGA", ALC5632_PWR_MANAG_ADD3, 3, 0, NULL, 0),
386SND_SOC_DAPM_PGA("MIC2 PGA", ALC5632_PWR_MANAG_ADD3, 2, 0, NULL, 0),
387SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5632_PWR_MANAG_ADD3, 1, 0, NULL, 0),
388SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5632_PWR_MANAG_ADD3, 0, 0, NULL, 0),
389SND_SOC_DAPM_SUPPLY("Mic Bias1", ALC5632_PWR_MANAG_ADD1, 3, 0, NULL, 0),
390SND_SOC_DAPM_SUPPLY("Mic Bias2", ALC5632_PWR_MANAG_ADD1, 2, 0, NULL, 0),
391
392SND_SOC_DAPM_PGA_E("D Amp", ALC5632_PWR_MANAG_ADD2, 14, 0, NULL, 0,
393 amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
394SND_SOC_DAPM_PGA("AB Amp", ALC5632_PWR_MANAG_ADD2, 15, 0, NULL, 0),
395SND_SOC_DAPM_MUX("AB-D Amp Mux", ALC5632_PWR_MANAG_ADD1, 10, 0,
396 &alc5632_amp_mux_controls),
397
398SND_SOC_DAPM_OUTPUT("AUXOUT"),
399SND_SOC_DAPM_OUTPUT("HPL"),
400SND_SOC_DAPM_OUTPUT("HPR"),
401SND_SOC_DAPM_OUTPUT("SPKOUT"),
402SND_SOC_DAPM_OUTPUT("SPKOUTN"),
403SND_SOC_DAPM_INPUT("LINEINL"),
404SND_SOC_DAPM_INPUT("LINEINR"),
405SND_SOC_DAPM_INPUT("PHONEP"),
406SND_SOC_DAPM_INPUT("PHONEN"),
407SND_SOC_DAPM_INPUT("MIC1"),
408SND_SOC_DAPM_INPUT("MIC2"),
409SND_SOC_DAPM_VMID("Vmid"),
410};
411
412
413static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
414 /* virtual mixer - mixes left & right channels */
415 {"I2S Mix", NULL, "Left DAC"},
416 {"I2S Mix", NULL, "Right DAC"},
417 {"Line Mix", NULL, "Right LineIn"},
418 {"Line Mix", NULL, "Left LineIn"},
419 {"Phone Mix", NULL, "Phone"},
420 {"Phone Mix", NULL, "Phone ADMix"},
421 {"AUXOUT", NULL, "Aux Out"},
422
423 /* DAC */
424 {"DAC Right Channel", NULL, "I2S Mix"},
425 {"DAC Left Channel", NULL, "I2S Mix"},
426
427 /* HP mixer */
428 {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"},
429 {"HPL Mix", NULL, "HP Mix"},
430 {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"},
431 {"HPR Mix", NULL, "HP Mix"},
432 {"HP Mix", "LI2HP Playback Switch", "Line Mix"},
433 {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"},
434 {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
435 {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
436
437 {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"},
438 {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"},
439
440 /* speaker mixer */
441 {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
442 {"Speaker Mix", "PHONE2SPK Playback Switch", "Phone Mix"},
443 {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
444 {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
445 {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"},
446
447
448
449 /* mono mixer */
450 {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
451 {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
452 {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
453 {"Mono Mix", "VOICE2MONO Playback Switch", "Phone Mix"},
454 {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
455 {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
456 {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"},
457
458 /* Left record mixer */
459 {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"},
460 {"Left Capture Mix", "Left Phone Capture Switch", "PHONEN"},
461 {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
462 {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
463 {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"},
464 {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
465 {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
466
467 /*Right record mixer */
468 {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"},
469 {"Right Capture Mix", "Right Phone Capture Switch", "PHONEP"},
470 {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
471 {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
472 {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"},
473 {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
474 {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
475
476 /* headphone left mux */
477 {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
478 {"Left Headphone Mux", "Vmid", "Vmid"},
479
480 /* headphone right mux */
481 {"Right Headphone Mux", "HP Right Mix", "HPR Mix"},
482 {"Right Headphone Mux", "Vmid", "Vmid"},
483
484 /* speaker out mux */
485 {"SpeakerOut Mux", "Vmid", "Vmid"},
486 {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"},
487 {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"},
488 {"SpeakerOut Mux", "Mono Mix", "Mono Mix"},
489
490 /* Mono/Aux Out mux */
491 {"AuxOut Mux", "Vmid", "Vmid"},
492 {"AuxOut Mux", "HPOut Mix", "HPOut Mix"},
493 {"AuxOut Mux", "Speaker Mix", "Speaker Mix"},
494 {"AuxOut Mux", "Mono Mix", "Mono Mix"},
495
496 /* output pga */
497 {"HPL", NULL, "Left Headphone"},
498 {"Left Headphone", NULL, "Left Headphone Mux"},
499 {"HPR", NULL, "Right Headphone"},
500 {"Right Headphone", NULL, "Right Headphone Mux"},
501 {"Aux Out", NULL, "AuxOut Mux"},
502
503 /* input pga */
504 {"Left LineIn", NULL, "LINEINL"},
505 {"Right LineIn", NULL, "LINEINR"},
506 {"Phone", NULL, "PHONEP"},
507 {"MIC1 Pre Amp", NULL, "MIC1"},
508 {"MIC2 Pre Amp", NULL, "MIC2"},
509 {"MIC1 PGA", NULL, "MIC1 Pre Amp"},
510 {"MIC2 PGA", NULL, "MIC2 Pre Amp"},
511
512 /* left ADC */
513 {"Left ADC", NULL, "Left Capture Mix"},
514
515 /* right ADC */
516 {"Right ADC", NULL, "Right Capture Mix"},
517
518 {"SpeakerOut N Mux", "RN/-R", "Left Speaker"},
519 {"SpeakerOut N Mux", "RP/+R", "Left Speaker"},
520 {"SpeakerOut N Mux", "LN/-R", "Left Speaker"},
521 {"SpeakerOut N Mux", "Mute", "Vmid"},
522
523 {"SpeakerOut N Mux", "RN/-R", "Right Speaker"},
524 {"SpeakerOut N Mux", "RP/+R", "Right Speaker"},
525 {"SpeakerOut N Mux", "LN/-R", "Right Speaker"},
526 {"SpeakerOut N Mux", "Mute", "Vmid"},
527
528 {"AB Amp", NULL, "SpeakerOut Mux"},
529 {"D Amp", NULL, "SpeakerOut Mux"},
530 {"AB-D Amp Mux", "AB Amp", "AB Amp"},
531 {"AB-D Amp Mux", "D Amp", "D Amp"},
532 {"Left Speaker", NULL, "AB-D Amp Mux"},
533 {"Right Speaker", NULL, "AB-D Amp Mux"},
534
535 {"SPKOUT", NULL, "Left Speaker"},
536 {"SPKOUT", NULL, "Right Speaker"},
537
538 {"SPKOUTN", NULL, "SpeakerOut N Mux"},
539
540};
541
542/* PLL divisors */
543struct _pll_div {
544 u32 pll_in;
545 u32 pll_out;
546 u16 regvalue;
547};
548
549/* Note : pll code from original alc5632 driver. Not sure of how good it is */
550/* usefull only for master mode */
551static const struct _pll_div codec_master_pll_div[] = {
552
553 { 2048000, 8192000, 0x0ea0},
554 { 3686400, 8192000, 0x4e27},
555 { 12000000, 8192000, 0x456b},
556 { 13000000, 8192000, 0x495f},
557 { 13100000, 8192000, 0x0320},
558 { 2048000, 11289600, 0xf637},
559 { 3686400, 11289600, 0x2f22},
560 { 12000000, 11289600, 0x3e2f},
561 { 13000000, 11289600, 0x4d5b},
562 { 13100000, 11289600, 0x363b},
563 { 2048000, 16384000, 0x1ea0},
564 { 3686400, 16384000, 0x9e27},
565 { 12000000, 16384000, 0x452b},
566 { 13000000, 16384000, 0x542f},
567 { 13100000, 16384000, 0x03a0},
568 { 2048000, 16934400, 0xe625},
569 { 3686400, 16934400, 0x9126},
570 { 12000000, 16934400, 0x4d2c},
571 { 13000000, 16934400, 0x742f},
572 { 13100000, 16934400, 0x3c27},
573 { 2048000, 22579200, 0x2aa0},
574 { 3686400, 22579200, 0x2f20},
575 { 12000000, 22579200, 0x7e2f},
576 { 13000000, 22579200, 0x742f},
577 { 13100000, 22579200, 0x3c27},
578 { 2048000, 24576000, 0x2ea0},
579 { 3686400, 24576000, 0xee27},
580 { 12000000, 24576000, 0x2915},
581 { 13000000, 24576000, 0x772e},
582 { 13100000, 24576000, 0x0d20},
583};
584
585/* FOUT = MCLK*(N+2)/((M+2)*(K+2))
586 N: bit 15:8 (div 2 .. div 257)
587 K: bit 6:4 typical 2
588 M: bit 3:0 (div 2 .. div 17)
589
590 same as for 5623 - thanks!
591*/
592
593static const struct _pll_div codec_slave_pll_div[] = {
594
595 { 1024000, 16384000, 0x3ea0},
596 { 1411200, 22579200, 0x3ea0},
597 { 1536000, 24576000, 0x3ea0},
598 { 2048000, 16384000, 0x1ea0},
599 { 2822400, 22579200, 0x1ea0},
600 { 3072000, 24576000, 0x1ea0},
601
602};
603
604static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
605 int source, unsigned int freq_in, unsigned int freq_out)
606{
607 int i;
608 struct snd_soc_codec *codec = codec_dai->codec;
609 int gbl_clk = 0, pll_div = 0;
610 u16 reg;
611
612 if (pll_id < ALC5632_PLL_FR_MCLK || pll_id > ALC5632_PLL_FR_VBCLK)
613 return -EINVAL;
614
615 /* Disable PLL power */
616 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
617 ALC5632_PWR_ADD2_PLL1,
618 0);
619 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
620 ALC5632_PWR_ADD2_PLL2,
621 0);
622
623 /* pll is not used in slave mode */
624 reg = snd_soc_read(codec, ALC5632_DAI_CONTROL);
625 if (reg & ALC5632_DAI_SDP_SLAVE_MODE)
626 return 0;
627
628 if (!freq_in || !freq_out)
629 return 0;
630
631 switch (pll_id) {
632 case ALC5632_PLL_FR_MCLK:
633 for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) {
634 if (codec_master_pll_div[i].pll_in == freq_in
635 && codec_master_pll_div[i].pll_out == freq_out) {
636 /* PLL source from MCLK */
637 pll_div = codec_master_pll_div[i].regvalue;
638 break;
639 }
640 }
641 break;
642 case ALC5632_PLL_FR_BCLK:
643 for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
644 if (codec_slave_pll_div[i].pll_in == freq_in
645 && codec_slave_pll_div[i].pll_out == freq_out) {
646 /* PLL source from Bitclk */
647 gbl_clk = ALC5632_PLL_FR_BCLK;
648 pll_div = codec_slave_pll_div[i].regvalue;
649 break;
650 }
651 }
652 break;
653 case ALC5632_PLL_FR_VBCLK:
654 for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
655 if (codec_slave_pll_div[i].pll_in == freq_in
656 && codec_slave_pll_div[i].pll_out == freq_out) {
657 /* PLL source from voice clock */
658 gbl_clk = ALC5632_PLL_FR_VBCLK;
659 pll_div = codec_slave_pll_div[i].regvalue;
660 break;
661 }
662 }
663 break;
664 default:
665 return -EINVAL;
666 }
667
668 if (!pll_div)
669 return -EINVAL;
670
671 /* choose MCLK/BCLK/VBCLK */
672 snd_soc_write(codec, ALC5632_GPCR2, gbl_clk);
673 /* choose PLL1 clock rate */
674 snd_soc_write(codec, ALC5632_PLL1_CTRL, pll_div);
675 /* enable PLL1 */
676 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
677 ALC5632_PWR_ADD2_PLL1,
678 ALC5632_PWR_ADD2_PLL1);
679 /* enable PLL2 */
680 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
681 ALC5632_PWR_ADD2_PLL2,
682 ALC5632_PWR_ADD2_PLL2);
683 /* use PLL1 as main SYSCLK */
684 snd_soc_update_bits(codec, ALC5632_GPCR1,
685 ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1,
686 ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1);
687
688 return 0;
689}
690
691struct _coeff_div {
692 u16 fs;
693 u16 regvalue;
694};
695
696/* codec hifi mclk (after PLL) clock divider coefficients */
697/* values inspired from column BCLK=32Fs of Appendix A table */
698static const struct _coeff_div coeff_div[] = {
699 {512*1, 0x3075},
700};
701
702static int get_coeff(struct snd_soc_codec *codec, int rate)
703{
704 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
705 int i;
706
707 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
708 if (coeff_div[i].fs * rate == alc5632->sysclk)
709 return i;
710 }
711 return -EINVAL;
712}
713
714/*
715 * Clock after PLL and dividers
716 */
717static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
718 int clk_id, unsigned int freq, int dir)
719{
720 struct snd_soc_codec *codec = codec_dai->codec;
721 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
722
723 switch (freq) {
724 case 8192000:
725 case 11289600:
726 case 12288000:
727 case 16384000:
728 case 16934400:
729 case 18432000:
730 case 22579200:
731 case 24576000:
732 alc5632->sysclk = freq;
733 return 0;
734 }
735 return -EINVAL;
736}
737
738static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai,
739 unsigned int fmt)
740{
741 struct snd_soc_codec *codec = codec_dai->codec;
742 u16 iface = 0;
743
744 /* set master/slave audio interface */
745 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
746 case SND_SOC_DAIFMT_CBM_CFM:
747 iface = ALC5632_DAI_SDP_MASTER_MODE;
748 break;
749 case SND_SOC_DAIFMT_CBS_CFS:
750 iface = ALC5632_DAI_SDP_SLAVE_MODE;
751 break;
752 default:
753 return -EINVAL;
754 }
755
756 /* interface format */
757 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
758 case SND_SOC_DAIFMT_I2S:
759 iface |= ALC5632_DAI_I2S_DF_I2S;
760 break;
761 case SND_SOC_DAIFMT_LEFT_J:
762 iface |= ALC5632_DAI_I2S_DF_LEFT;
763 break;
764 case SND_SOC_DAIFMT_DSP_A:
765 iface |= ALC5632_DAI_I2S_DF_PCM_A;
766 break;
767 case SND_SOC_DAIFMT_DSP_B:
768 iface |= ALC5632_DAI_I2S_DF_PCM_B;
769 break;
770 default:
771 return -EINVAL;
772 }
773
774 /* clock inversion */
775 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
776 case SND_SOC_DAIFMT_NB_NF:
777 break;
778 case SND_SOC_DAIFMT_IB_IF:
779 iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL;
780 break;
781 case SND_SOC_DAIFMT_IB_NF:
782 iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL;
783 break;
784 case SND_SOC_DAIFMT_NB_IF:
785 break;
786 default:
787 return -EINVAL;
788 }
789
790 return snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
791}
792
793static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
794 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
795{
796 struct snd_soc_pcm_runtime *rtd = substream->private_data;
797 struct snd_soc_codec *codec = rtd->codec;
798 int coeff, rate;
799 u16 iface;
800
801 iface = snd_soc_read(codec, ALC5632_DAI_CONTROL);
802 iface &= ~ALC5632_DAI_I2S_DL_MASK;
803
804 /* bit size */
805 switch (params_format(params)) {
806 case SNDRV_PCM_FORMAT_S16_LE:
807 iface |= ALC5632_DAI_I2S_DL_16;
808 break;
809 case SNDRV_PCM_FORMAT_S20_3LE:
810 iface |= ALC5632_DAI_I2S_DL_20;
811 break;
812 case SNDRV_PCM_FORMAT_S24_LE:
813 iface |= ALC5632_DAI_I2S_DL_24;
814 break;
815 default:
816 return -EINVAL;
817 }
818
819 /* set iface & srate */
820 snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
821 rate = params_rate(params);
822 coeff = get_coeff(codec, rate);
823 if (coeff < 0)
824 return -EINVAL;
825
826 coeff = coeff_div[coeff].regvalue;
827 snd_soc_write(codec, ALC5632_DAC_CLK_CTRL1, coeff);
828
829 return 0;
830}
831
832static int alc5632_mute(struct snd_soc_dai *dai, int mute)
833{
834 struct snd_soc_codec *codec = dai->codec;
Leon Romanovsky88c494b2011-11-10 21:22:16 +0200835 u16 hp_mute = ALC5632_MISC_HP_DEPOP_MUTE_L
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200836 |ALC5632_MISC_HP_DEPOP_MUTE_R;
837 u16 mute_reg = snd_soc_read(codec, ALC5632_MISC_CTRL) & ~hp_mute;
838
839 if (mute)
840 mute_reg |= hp_mute;
841
842 return snd_soc_write(codec, ALC5632_MISC_CTRL, mute_reg);
843}
844
845#define ALC5632_ADD2_POWER_EN (ALC5632_PWR_ADD2_VREF)
846
847#define ALC5632_ADD3_POWER_EN (ALC5632_PWR_ADD3_MIC1_BOOST_AD)
848
849#define ALC5632_ADD1_POWER_EN \
850 (ALC5632_PWR_ADD1_DAC_REF \
851 | ALC5632_PWR_ADD1_SOFTGEN_EN \
852 | ALC5632_PWR_ADD1_HP_OUT_AMP \
853 | ALC5632_PWR_ADD1_HP_OUT_ENH_AMP \
854 | ALC5632_PWR_ADD1_MAIN_BIAS)
855
856static void enable_power_depop(struct snd_soc_codec *codec)
857{
858 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
859 ALC5632_PWR_ADD1_SOFTGEN_EN,
860 ALC5632_PWR_ADD1_SOFTGEN_EN);
861
862 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
863 ALC5632_ADD3_POWER_EN,
864 ALC5632_ADD3_POWER_EN);
865
866 snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
867 ALC5632_MISC_HP_DEPOP_MODE2_EN,
868 ALC5632_MISC_HP_DEPOP_MODE2_EN);
869
870 /* "normal" mode: 0 @ 26 */
871 /* set all PR0-7 mixers to 0 */
872 snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
873 ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
874 0);
875
876 msleep(500);
877
878 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
879 ALC5632_ADD2_POWER_EN,
880 ALC5632_ADD2_POWER_EN);
881
882 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
883 ALC5632_ADD1_POWER_EN,
884 ALC5632_ADD1_POWER_EN);
885
886 /* disable HP Depop2 */
887 snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
888 ALC5632_MISC_HP_DEPOP_MODE2_EN,
889 0);
890
891}
892
893static int alc5632_set_bias_level(struct snd_soc_codec *codec,
894 enum snd_soc_bias_level level)
895{
896 switch (level) {
897 case SND_SOC_BIAS_ON:
898 enable_power_depop(codec);
899 break;
900 case SND_SOC_BIAS_PREPARE:
901 break;
902 case SND_SOC_BIAS_STANDBY:
903 /* everything off except vref/vmid, */
904 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
905 ALC5632_PWR_MANAG_ADD1_MASK,
906 ALC5632_PWR_ADD1_MAIN_BIAS);
907 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
908 ALC5632_PWR_MANAG_ADD2_MASK,
909 ALC5632_PWR_ADD2_VREF);
910 /* "normal" mode: 0 @ 26 */
911 snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
912 ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
913 0xffff ^ (ALC5632_PWR_VREF_PR3
914 | ALC5632_PWR_VREF_PR2));
915 break;
916 case SND_SOC_BIAS_OFF:
917 /* everything off, dac mute, inactive */
918 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
919 ALC5632_PWR_MANAG_ADD2_MASK, 0);
920 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
921 ALC5632_PWR_MANAG_ADD3_MASK, 0);
922 snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
923 ALC5632_PWR_MANAG_ADD1_MASK, 0);
924 break;
925 }
926 codec->dapm.bias_level = level;
927 return 0;
928}
929
930#define ALC5632_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \
931 | SNDRV_PCM_FMTBIT_S24_LE \
932 | SNDRV_PCM_FMTBIT_S32_LE)
933
934static struct snd_soc_dai_ops alc5632_dai_ops = {
935 .hw_params = alc5632_pcm_hw_params,
936 .digital_mute = alc5632_mute,
937 .set_fmt = alc5632_set_dai_fmt,
938 .set_sysclk = alc5632_set_dai_sysclk,
939 .set_pll = alc5632_set_dai_pll,
940};
941
942static struct snd_soc_dai_driver alc5632_dai = {
943 .name = "alc5632-hifi",
944 .playback = {
945 .stream_name = "HiFi Playback",
946 .channels_min = 1,
947 .channels_max = 2,
948 .rate_min = 8000,
949 .rate_max = 48000,
950 .rates = SNDRV_PCM_RATE_8000_48000,
951 .formats = ALC5632_FORMATS,},
952 .capture = {
953 .stream_name = "HiFi Capture",
954 .channels_min = 1,
955 .channels_max = 2,
956 .rate_min = 8000,
957 .rate_max = 48000,
958 .rates = SNDRV_PCM_RATE_8000_48000,
959 .formats = ALC5632_FORMATS,},
960
961 .ops = &alc5632_dai_ops,
962 .symmetric_rates = 1,
963};
964
Leon Romanovskyc9be8422011-11-16 12:07:00 +0200965#ifdef CONFIG_PM
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200966static int alc5632_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
967{
968 alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF);
969 return 0;
970}
971
972static int alc5632_resume(struct snd_soc_codec *codec)
973{
Leon Romanovskybb397532011-11-16 12:06:58 +0200974 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200975
Leon Romanovskybb397532011-11-16 12:06:58 +0200976 regcache_sync(alc5632->regmap);
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200977
978 alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
979 return 0;
980}
Leon Romanovskyc9be8422011-11-16 12:07:00 +0200981#else
982#define alc5632_suspend NULL
983#define alc5632_resume NULL
984#endif
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200985
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200986static int alc5632_probe(struct snd_soc_codec *codec)
987{
988 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
989 int ret;
990
Leon Romanovskybb397532011-11-16 12:06:58 +0200991 codec->control_data = alc5632->regmap;
992
993 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
994 if (ret != 0) {
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200995 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
996 return ret;
997 }
998
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +0200999 /* power on device */
1000 alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1001
1002 switch (alc5632->id) {
1003 case 0x5c:
1004 snd_soc_add_controls(codec, alc5632_vol_snd_controls,
1005 ARRAY_SIZE(alc5632_vol_snd_controls));
1006 break;
1007 default:
1008 return -EINVAL;
1009 }
1010
1011 return ret;
1012}
1013
1014/* power down chip */
1015static int alc5632_remove(struct snd_soc_codec *codec)
1016{
1017 alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF);
1018 return 0;
1019}
1020
1021static struct snd_soc_codec_driver soc_codec_device_alc5632 = {
1022 .probe = alc5632_probe,
1023 .remove = alc5632_remove,
1024 .suspend = alc5632_suspend,
1025 .resume = alc5632_resume,
1026 .set_bias_level = alc5632_set_bias_level,
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +02001027 .controls = alc5632_snd_controls,
1028 .num_controls = ARRAY_SIZE(alc5632_snd_controls),
1029 .dapm_widgets = alc5632_dapm_widgets,
1030 .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets),
1031 .dapm_routes = alc5632_dapm_routes,
1032 .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes),
1033};
1034
Leon Romanovskybb397532011-11-16 12:06:58 +02001035static struct regmap_config alc5632_regmap = {
1036 .reg_bits = 8,
1037 .val_bits = 16,
1038
1039 .max_register = ALC5632_MAX_REGISTER,
1040 .reg_defaults = alc5632_reg_defaults,
1041 .num_reg_defaults = ARRAY_SIZE(alc5632_reg_defaults),
1042 .volatile_reg = alc5632_volatile_register,
1043 .cache_type = REGCACHE_RBTREE,
1044};
1045
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +02001046/*
1047 * alc5632 2 wire address is determined by A1 pin
1048 * state during powerup.
1049 * low = 0x1a
1050 * high = 0x1b
1051 */
Leon Romanovskybb397532011-11-16 12:06:58 +02001052static __devinit int alc5632_i2c_probe(struct i2c_client *client,
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +02001053 const struct i2c_device_id *id)
1054{
1055 struct alc5632_priv *alc5632;
Leon Romanovsky277c01b2011-11-17 12:01:30 +02001056 int ret, ret1, ret2;
1057 unsigned int vid1, vid2;
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +02001058
1059 alc5632 = devm_kzalloc(&client->dev,
1060 sizeof(struct alc5632_priv), GFP_KERNEL);
1061 if (alc5632 == NULL)
1062 return -ENOMEM;
1063
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +02001064 i2c_set_clientdata(client, alc5632);
Leon Romanovskybb397532011-11-16 12:06:58 +02001065
1066 alc5632->regmap = regmap_init_i2c(client, &alc5632_regmap);
1067 if (IS_ERR(alc5632->regmap)) {
1068 ret = PTR_ERR(alc5632->regmap);
1069 dev_err(&client->dev, "regmap_init() failed: %d\n", ret);
1070 return ret;
1071 }
1072
Leon Romanovsky277c01b2011-11-17 12:01:30 +02001073 ret1 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID1, &vid1);
1074 ret2 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID2, &vid2);
1075 if (ret1 != 0 || ret2 != 0) {
1076 dev_err(&client->dev,
1077 "Failed to read chip ID: ret1=%d, ret2=%d\n", ret1, ret2);
1078 regmap_exit(alc5632->regmap);
1079 return -EIO;
1080 }
1081
1082 vid2 >>= 8;
1083
1084 if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) {
1085 dev_err(&client->dev,
1086 "Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2);
1087 regmap_exit(alc5632->regmap);
1088 return -EINVAL;
1089 }
1090
Leon Romanovskybb397532011-11-16 12:06:58 +02001091 ret = alc5632_reset(alc5632->regmap);
1092 if (ret < 0) {
1093 dev_err(&client->dev, "Failed to issue reset\n");
1094 regmap_exit(alc5632->regmap);
1095 return ret;
1096 }
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +02001097
Leon Romanovsky277c01b2011-11-17 12:01:30 +02001098 alc5632->id = vid2;
1099 switch (alc5632->id) {
1100 case 0x5c:
1101 alc5632_dai.name = "alc5632-hifi";
1102 break;
1103 default:
1104 return -EINVAL;
1105 }
1106
1107 ret = snd_soc_register_codec(&client->dev,
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +02001108 &soc_codec_device_alc5632, &alc5632_dai, 1);
Leon Romanovskybb397532011-11-16 12:06:58 +02001109
1110 if (ret < 0) {
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +02001111 dev_err(&client->dev, "Failed to register codec: %d\n", ret);
Leon Romanovskybb397532011-11-16 12:06:58 +02001112 regmap_exit(alc5632->regmap);
1113 return ret;
1114 }
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +02001115
1116 return ret;
1117}
1118
1119static int alc5632_i2c_remove(struct i2c_client *client)
1120{
Leon Romanovskybb397532011-11-16 12:06:58 +02001121 struct alc5632_priv *alc5632 = i2c_get_clientdata(client);
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +02001122 snd_soc_unregister_codec(&client->dev);
Leon Romanovskybb397532011-11-16 12:06:58 +02001123 regmap_exit(alc5632->regmap);
Leon Romanovsky94d5f7c2011-11-05 12:38:02 +02001124 return 0;
1125}
1126
1127static const struct i2c_device_id alc5632_i2c_table[] = {
1128 {"alc5632", 0x5c},
1129 {}
1130};
1131MODULE_DEVICE_TABLE(i2c, alc5632_i2c_table);
1132
1133/* i2c codec control layer */
1134static struct i2c_driver alc5632_i2c_driver = {
1135 .driver = {
1136 .name = "alc5632",
1137 .owner = THIS_MODULE,
1138 },
1139 .probe = alc5632_i2c_probe,
1140 .remove = __devexit_p(alc5632_i2c_remove),
1141 .id_table = alc5632_i2c_table,
1142};
1143
1144static int __init alc5632_modinit(void)
1145{
1146 int ret;
1147
1148 ret = i2c_add_driver(&alc5632_i2c_driver);
1149 if (ret != 0) {
1150 printk(KERN_ERR "%s: can't add i2c driver", __func__);
1151 return ret;
1152 }
1153
1154 return ret;
1155}
1156module_init(alc5632_modinit);
1157
1158static void __exit alc5632_modexit(void)
1159{
1160 i2c_del_driver(&alc5632_i2c_driver);
1161}
1162module_exit(alc5632_modexit);
1163
1164MODULE_DESCRIPTION("ASoC ALC5632 driver");
1165MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>");
1166MODULE_LICENSE("GPL");