~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/cs42l56.c

Version: ~ [ linux-5.12-rc1 ] ~ [ linux-5.11.2 ] ~ [ linux-5.10.19 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.101 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.177 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.222 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.258 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.258 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * cs42l56.c -- CS42L56 ALSA SoC audio driver
  4  *
  5  * Copyright 2014 CirrusLogic, Inc.
  6  *
  7  * Author: Brian Austin <brian.austin@cirrus.com>
  8  */
  9 
 10 #include <linux/module.h>
 11 #include <linux/moduleparam.h>
 12 #include <linux/kernel.h>
 13 #include <linux/init.h>
 14 #include <linux/delay.h>
 15 #include <linux/pm.h>
 16 #include <linux/i2c.h>
 17 #include <linux/input.h>
 18 #include <linux/regmap.h>
 19 #include <linux/slab.h>
 20 #include <linux/workqueue.h>
 21 #include <linux/platform_device.h>
 22 #include <linux/regulator/consumer.h>
 23 #include <linux/of_device.h>
 24 #include <linux/of_gpio.h>
 25 #include <sound/core.h>
 26 #include <sound/pcm.h>
 27 #include <sound/pcm_params.h>
 28 #include <sound/soc.h>
 29 #include <sound/soc-dapm.h>
 30 #include <sound/initval.h>
 31 #include <sound/tlv.h>
 32 #include <sound/cs42l56.h>
 33 #include "cs42l56.h"
 34 
 35 #define CS42L56_NUM_SUPPLIES 3
 36 static const char *const cs42l56_supply_names[CS42L56_NUM_SUPPLIES] = {
 37         "VA",
 38         "VCP",
 39         "VLDO",
 40 };
 41 
 42 struct  cs42l56_private {
 43         struct regmap *regmap;
 44         struct snd_soc_component *component;
 45         struct device *dev;
 46         struct cs42l56_platform_data pdata;
 47         struct regulator_bulk_data supplies[CS42L56_NUM_SUPPLIES];
 48         u32 mclk;
 49         u8 mclk_prediv;
 50         u8 mclk_div2;
 51         u8 mclk_ratio;
 52         u8 iface;
 53         u8 iface_fmt;
 54         u8 iface_inv;
 55 #if IS_ENABLED(CONFIG_INPUT)
 56         struct input_dev *beep;
 57         struct work_struct beep_work;
 58         int beep_rate;
 59 #endif
 60 };
 61 
 62 static const struct reg_default cs42l56_reg_defaults[] = {
 63         { 3, 0x7f },    /* r03  - Power Ctl 1 */
 64         { 4, 0xff },    /* r04  - Power Ctl 2 */
 65         { 5, 0x00 },    /* ro5  - Clocking Ctl 1 */
 66         { 6, 0x0b },    /* r06  - Clocking Ctl 2 */
 67         { 7, 0x00 },    /* r07  - Serial Format */
 68         { 8, 0x05 },    /* r08  - Class H Ctl */
 69         { 9, 0x0c },    /* r09  - Misc Ctl */
 70         { 10, 0x80 },   /* r0a  - INT Status */
 71         { 11, 0x00 },   /* r0b  - Playback Ctl */
 72         { 12, 0x0c },   /* r0c  - DSP Mute Ctl */
 73         { 13, 0x00 },   /* r0d  - ADCA Mixer Volume */
 74         { 14, 0x00 },   /* r0e  - ADCB Mixer Volume */
 75         { 15, 0x00 },   /* r0f  - PCMA Mixer Volume */
 76         { 16, 0x00 },   /* r10  - PCMB Mixer Volume */
 77         { 17, 0x00 },   /* r11  - Analog Input Advisory Volume */
 78         { 18, 0x00 },   /* r12  - Digital Input Advisory Volume */
 79         { 19, 0x00 },   /* r13  - Master A Volume */
 80         { 20, 0x00 },   /* r14  - Master B Volume */
 81         { 21, 0x00 },   /* r15  - Beep Freq / On Time */
 82         { 22, 0x00 },   /* r16  - Beep Volume / Off Time */
 83         { 23, 0x00 },   /* r17  - Beep Tone Ctl */
 84         { 24, 0x88 },   /* r18  - Tone Ctl */
 85         { 25, 0x00 },   /* r19  - Channel Mixer & Swap */
 86         { 26, 0x00 },   /* r1a  - AIN Ref Config / ADC Mux */
 87         { 27, 0xa0 },   /* r1b  - High-Pass Filter Ctl */
 88         { 28, 0x00 },   /* r1c  - Misc ADC Ctl */
 89         { 29, 0x00 },   /* r1d  - Gain & Bias Ctl */
 90         { 30, 0x00 },   /* r1e  - PGAA Mux & Volume */
 91         { 31, 0x00 },   /* r1f  - PGAB Mux & Volume */
 92         { 32, 0x00 },   /* r20  - ADCA Attenuator */
 93         { 33, 0x00 },   /* r21  - ADCB Attenuator */
 94         { 34, 0x00 },   /* r22  - ALC Enable & Attack Rate */
 95         { 35, 0xbf },   /* r23  - ALC Release Rate */
 96         { 36, 0x00 },   /* r24  - ALC Threshold */
 97         { 37, 0x00 },   /* r25  - Noise Gate Ctl */
 98         { 38, 0x00 },   /* r26  - ALC, Limiter, SFT, ZeroCross */
 99         { 39, 0x00 },   /* r27  - Analog Mute, LO & HP Mux */
100         { 40, 0x00 },   /* r28  - HP A Volume */
101         { 41, 0x00 },   /* r29  - HP B Volume */
102         { 42, 0x00 },   /* r2a  - LINEOUT A Volume */
103         { 43, 0x00 },   /* r2b  - LINEOUT B Volume */
104         { 44, 0x00 },   /* r2c  - Limit Threshold Ctl */
105         { 45, 0x7f },   /* r2d  - Limiter Ctl & Release Rate */
106         { 46, 0x00 },   /* r2e  - Limiter Attack Rate */
107 };
108 
109 static bool cs42l56_readable_register(struct device *dev, unsigned int reg)
110 {
111         switch (reg) {
112         case CS42L56_CHIP_ID_1 ... CS42L56_LIM_ATTACK_RATE:
113                 return true;
114         default:
115                 return false;
116         }
117 }
118 
119 static bool cs42l56_volatile_register(struct device *dev, unsigned int reg)
120 {
121         switch (reg) {
122         case CS42L56_INT_STATUS:
123                 return true;
124         default:
125                 return false;
126         }
127 }
128 
129 static DECLARE_TLV_DB_SCALE(beep_tlv, -5000, 200, 0);
130 static DECLARE_TLV_DB_SCALE(hl_tlv, -6000, 50, 0);
131 static DECLARE_TLV_DB_SCALE(adv_tlv, -10200, 50, 0);
132 static DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 100, 0);
133 static DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
134 static DECLARE_TLV_DB_SCALE(preamp_tlv, 0, 1000, 0);
135 static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
136 
137 static const DECLARE_TLV_DB_RANGE(ngnb_tlv,
138         0, 1, TLV_DB_SCALE_ITEM(-8200, 600, 0),
139         2, 5, TLV_DB_SCALE_ITEM(-7600, 300, 0)
140 );
141 static const DECLARE_TLV_DB_RANGE(ngb_tlv,
142         0, 2, TLV_DB_SCALE_ITEM(-6400, 600, 0),
143         3, 7, TLV_DB_SCALE_ITEM(-4600, 300, 0)
144 );
145 static const DECLARE_TLV_DB_RANGE(alc_tlv,
146         0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
147         3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0)
148 );
149 
150 static const char * const beep_config_text[] = {
151         "Off", "Single", "Multiple", "Continuous"
152 };
153 
154 static const struct soc_enum beep_config_enum =
155         SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 6,
156                         ARRAY_SIZE(beep_config_text), beep_config_text);
157 
158 static const char * const beep_pitch_text[] = {
159         "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5",
160         "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7"
161 };
162 
163 static const struct soc_enum beep_pitch_enum =
164         SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_ONTIME, 4,
165                         ARRAY_SIZE(beep_pitch_text), beep_pitch_text);
166 
167 static const char * const beep_ontime_text[] = {
168         "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s",
169         "1.80 s", "2.20 s", "2.50 s", "2.80 s", "3.20 s",
170         "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s"
171 };
172 
173 static const struct soc_enum beep_ontime_enum =
174         SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_ONTIME, 0,
175                         ARRAY_SIZE(beep_ontime_text), beep_ontime_text);
176 
177 static const char * const beep_offtime_text[] = {
178         "1.23 s", "2.58 s", "3.90 s", "5.20 s",
179         "6.60 s", "8.05 s", "9.35 s", "10.80 s"
180 };
181 
182 static const struct soc_enum beep_offtime_enum =
183         SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_OFFTIME, 5,
184                         ARRAY_SIZE(beep_offtime_text), beep_offtime_text);
185 
186 static const char * const beep_treble_text[] = {
187         "5kHz", "7kHz", "10kHz", "15kHz"
188 };
189 
190 static const struct soc_enum beep_treble_enum =
191         SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 3,
192                         ARRAY_SIZE(beep_treble_text), beep_treble_text);
193 
194 static const char * const beep_bass_text[] = {
195         "50Hz", "100Hz", "200Hz", "250Hz"
196 };
197 
198 static const struct soc_enum beep_bass_enum =
199         SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 1,
200                         ARRAY_SIZE(beep_bass_text), beep_bass_text);
201 
202 static const char * const adc_swap_text[] = {
203         "None", "A+B/2", "A-B/2", "Swap"
204 };
205 
206 static const struct soc_enum adc_swap_enum =
207         SOC_ENUM_SINGLE(CS42L56_MISC_ADC_CTL, 3,
208                         ARRAY_SIZE(adc_swap_text), adc_swap_text);
209 
210 static const char * const pgaa_mux_text[] = {
211         "AIN1A", "AIN2A", "AIN3A"};
212 
213 static const struct soc_enum pgaa_mux_enum =
214         SOC_ENUM_SINGLE(CS42L56_PGAA_MUX_VOLUME, 0,
215                               ARRAY_SIZE(pgaa_mux_text),
216                               pgaa_mux_text);
217 
218 static const struct snd_kcontrol_new pgaa_mux =
219         SOC_DAPM_ENUM("Route", pgaa_mux_enum);
220 
221 static const char * const pgab_mux_text[] = {
222         "AIN1B", "AIN2B", "AIN3B"};
223 
224 static const struct soc_enum pgab_mux_enum =
225         SOC_ENUM_SINGLE(CS42L56_PGAB_MUX_VOLUME, 0,
226                               ARRAY_SIZE(pgab_mux_text),
227                               pgab_mux_text);
228 
229 static const struct snd_kcontrol_new pgab_mux =
230         SOC_DAPM_ENUM("Route", pgab_mux_enum);
231 
232 static const char * const adca_mux_text[] = {
233         "PGAA", "AIN1A", "AIN2A", "AIN3A"};
234 
235 static const struct soc_enum adca_mux_enum =
236         SOC_ENUM_SINGLE(CS42L56_AIN_REFCFG_ADC_MUX, 0,
237                               ARRAY_SIZE(adca_mux_text),
238                               adca_mux_text);
239 
240 static const struct snd_kcontrol_new adca_mux =
241         SOC_DAPM_ENUM("Route", adca_mux_enum);
242 
243 static const char * const adcb_mux_text[] = {
244         "PGAB", "AIN1B", "AIN2B", "AIN3B"};
245 
246 static const struct soc_enum adcb_mux_enum =
247         SOC_ENUM_SINGLE(CS42L56_AIN_REFCFG_ADC_MUX, 2,
248                               ARRAY_SIZE(adcb_mux_text),
249                               adcb_mux_text);
250 
251 static const struct snd_kcontrol_new adcb_mux =
252         SOC_DAPM_ENUM("Route", adcb_mux_enum);
253 
254 static const char * const left_swap_text[] = {
255         "Left", "LR 2", "Right"};
256 
257 static const char * const right_swap_text[] = {
258         "Right", "LR 2", "Left"};
259 
260 static const unsigned int swap_values[] = { 0, 1, 3 };
261 
262 static const struct soc_enum adca_swap_enum =
263         SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 0, 3,
264                               ARRAY_SIZE(left_swap_text),
265                               left_swap_text,
266                               swap_values);
267 static const struct snd_kcontrol_new adca_swap_mux =
268         SOC_DAPM_ENUM("Route", adca_swap_enum);
269 
270 static const struct soc_enum pcma_swap_enum =
271         SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 4, 3,
272                               ARRAY_SIZE(left_swap_text),
273                               left_swap_text,
274                               swap_values);
275 static const struct snd_kcontrol_new pcma_swap_mux =
276         SOC_DAPM_ENUM("Route", pcma_swap_enum);
277 
278 static const struct soc_enum adcb_swap_enum =
279         SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 2, 3,
280                               ARRAY_SIZE(right_swap_text),
281                               right_swap_text,
282                               swap_values);
283 static const struct snd_kcontrol_new adcb_swap_mux =
284         SOC_DAPM_ENUM("Route", adcb_swap_enum);
285 
286 static const struct soc_enum pcmb_swap_enum =
287         SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 6, 3,
288                               ARRAY_SIZE(right_swap_text),
289                               right_swap_text,
290                               swap_values);
291 static const struct snd_kcontrol_new pcmb_swap_mux =
292         SOC_DAPM_ENUM("Route", pcmb_swap_enum);
293 
294 static const struct snd_kcontrol_new hpa_switch =
295         SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 6, 1, 1);
296 
297 static const struct snd_kcontrol_new hpb_switch =
298         SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 4, 1, 1);
299 
300 static const struct snd_kcontrol_new loa_switch =
301         SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 2, 1, 1);
302 
303 static const struct snd_kcontrol_new lob_switch =
304         SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 0, 1, 1);
305 
306 static const char * const hploa_input_text[] = {
307         "DACA", "PGAA"};
308 
309 static const struct soc_enum lineouta_input_enum =
310         SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 2,
311                               ARRAY_SIZE(hploa_input_text),
312                               hploa_input_text);
313 
314 static const struct snd_kcontrol_new lineouta_input =
315         SOC_DAPM_ENUM("Route", lineouta_input_enum);
316 
317 static const struct soc_enum hpa_input_enum =
318         SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 0,
319                               ARRAY_SIZE(hploa_input_text),
320                               hploa_input_text);
321 
322 static const struct snd_kcontrol_new hpa_input =
323         SOC_DAPM_ENUM("Route", hpa_input_enum);
324 
325 static const char * const hplob_input_text[] = {
326         "DACB", "PGAB"};
327 
328 static const struct soc_enum lineoutb_input_enum =
329         SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 3,
330                               ARRAY_SIZE(hplob_input_text),
331                               hplob_input_text);
332 
333 static const struct snd_kcontrol_new lineoutb_input =
334         SOC_DAPM_ENUM("Route", lineoutb_input_enum);
335 
336 static const struct soc_enum hpb_input_enum =
337         SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 1,
338                               ARRAY_SIZE(hplob_input_text),
339                               hplob_input_text);
340 
341 static const struct snd_kcontrol_new hpb_input =
342         SOC_DAPM_ENUM("Route", hpb_input_enum);
343 
344 static const char * const dig_mux_text[] = {
345         "ADC", "DSP"};
346 
347 static const struct soc_enum dig_mux_enum =
348         SOC_ENUM_SINGLE(CS42L56_MISC_CTL, 7,
349                               ARRAY_SIZE(dig_mux_text),
350                               dig_mux_text);
351 
352 static const struct snd_kcontrol_new dig_mux =
353         SOC_DAPM_ENUM("Route", dig_mux_enum);
354 
355 static const char * const hpf_freq_text[] = {
356         "1.8Hz", "119Hz", "236Hz", "464Hz"
357 };
358 
359 static const struct soc_enum hpfa_freq_enum =
360         SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 0,
361                         ARRAY_SIZE(hpf_freq_text), hpf_freq_text);
362 
363 static const struct soc_enum hpfb_freq_enum =
364         SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 2,
365                         ARRAY_SIZE(hpf_freq_text), hpf_freq_text);
366 
367 static const char * const ng_delay_text[] = {
368         "50ms", "100ms", "150ms", "200ms"
369 };
370 
371 static const struct soc_enum ng_delay_enum =
372         SOC_ENUM_SINGLE(CS42L56_NOISE_GATE_CTL, 0,
373                         ARRAY_SIZE(ng_delay_text), ng_delay_text);
374 
375 static const struct snd_kcontrol_new cs42l56_snd_controls[] = {
376 
377         SOC_DOUBLE_R_SX_TLV("Master Volume", CS42L56_MASTER_A_VOLUME,
378                               CS42L56_MASTER_B_VOLUME, 0, 0x34, 0xE4, adv_tlv),
379         SOC_DOUBLE("Master Mute Switch", CS42L56_DSP_MUTE_CTL, 0, 1, 1, 1),
380 
381         SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", CS42L56_ADCA_MIX_VOLUME,
382                               CS42L56_ADCB_MIX_VOLUME, 0, 0x88, 0x90, hl_tlv),
383         SOC_DOUBLE("ADC Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 6, 7, 1, 1),
384 
385         SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume", CS42L56_PCMA_MIX_VOLUME,
386                               CS42L56_PCMB_MIX_VOLUME, 0, 0x88, 0x90, hl_tlv),
387         SOC_DOUBLE("PCM Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 4, 5, 1, 1),
388 
389         SOC_SINGLE_TLV("Analog Advisory Volume",
390                           CS42L56_ANAINPUT_ADV_VOLUME, 0, 0x00, 1, adv_tlv),
391         SOC_SINGLE_TLV("Digital Advisory Volume",
392                           CS42L56_DIGINPUT_ADV_VOLUME, 0, 0x00, 1, adv_tlv),
393 
394         SOC_DOUBLE_R_SX_TLV("PGA Volume", CS42L56_PGAA_MUX_VOLUME,
395                               CS42L56_PGAB_MUX_VOLUME, 0, 0x34, 0x24, pga_tlv),
396         SOC_DOUBLE_R_TLV("ADC Volume", CS42L56_ADCA_ATTENUATOR,
397                               CS42L56_ADCB_ATTENUATOR, 0, 0x00, 1, adc_tlv),
398         SOC_DOUBLE("ADC Mute Switch", CS42L56_MISC_ADC_CTL, 2, 3, 1, 1),
399         SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1),
400 
401         SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME,
402                               CS42L56_HPB_VOLUME, 0, 0x84, 0x48, hl_tlv),
403         SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME,
404                               CS42L56_LOB_VOLUME, 0, 0x84, 0x48, hl_tlv),
405 
406         SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL,
407                         0, 0x00, 1, tone_tlv),
408         SOC_SINGLE_TLV("Treble Shelving Volume", CS42L56_TONE_CTL,
409                         4, 0x00, 1, tone_tlv),
410 
411         SOC_DOUBLE_TLV("PGA Preamp Volume", CS42L56_GAIN_BIAS_CTL,
412                         4, 6, 0x02, 1, preamp_tlv),
413 
414         SOC_SINGLE("DSP Switch", CS42L56_PLAYBACK_CTL, 7, 1, 1),
415         SOC_SINGLE("Gang Playback Switch", CS42L56_PLAYBACK_CTL, 4, 1, 1),
416         SOC_SINGLE("Gang ADC Switch", CS42L56_MISC_ADC_CTL, 7, 1, 1),
417         SOC_SINGLE("Gang PGA Switch", CS42L56_MISC_ADC_CTL, 6, 1, 1),
418 
419         SOC_SINGLE("PCMA Invert", CS42L56_PLAYBACK_CTL, 2, 1, 1),
420         SOC_SINGLE("PCMB Invert", CS42L56_PLAYBACK_CTL, 3, 1, 1),
421         SOC_SINGLE("ADCA Invert", CS42L56_MISC_ADC_CTL, 2, 1, 1),
422         SOC_SINGLE("ADCB Invert", CS42L56_MISC_ADC_CTL, 3, 1, 1),
423 
424         SOC_DOUBLE("HPF Switch", CS42L56_HPF_CTL, 5, 7, 1, 1),
425         SOC_DOUBLE("HPF Freeze Switch", CS42L56_HPF_CTL, 4, 6, 1, 1),
426         SOC_ENUM("HPFA Corner Freq", hpfa_freq_enum),
427         SOC_ENUM("HPFB Corner Freq", hpfb_freq_enum),
428 
429         SOC_SINGLE("Analog Soft Ramp", CS42L56_MISC_CTL, 4, 1, 1),
430         SOC_DOUBLE("Analog Soft Ramp Disable", CS42L56_ALC_LIM_SFT_ZC,
431                 7, 5, 1, 1),
432         SOC_SINGLE("Analog Zero Cross", CS42L56_MISC_CTL, 3, 1, 1),
433         SOC_DOUBLE("Analog Zero Cross Disable", CS42L56_ALC_LIM_SFT_ZC,
434                 6, 4, 1, 1),
435         SOC_SINGLE("Digital Soft Ramp", CS42L56_MISC_CTL, 2, 1, 1),
436         SOC_SINGLE("Digital Soft Ramp Disable", CS42L56_ALC_LIM_SFT_ZC,
437                 3, 1, 1),
438 
439         SOC_SINGLE("HL Deemphasis", CS42L56_PLAYBACK_CTL, 6, 1, 1),
440 
441         SOC_SINGLE("ALC Switch", CS42L56_ALC_EN_ATTACK_RATE, 6, 1, 1),
442         SOC_SINGLE("ALC Limit All Switch", CS42L56_ALC_RELEASE_RATE, 7, 1, 1),
443         SOC_SINGLE_RANGE("ALC Attack", CS42L56_ALC_EN_ATTACK_RATE,
444                         0, 0, 0x3f, 0),
445         SOC_SINGLE_RANGE("ALC Release", CS42L56_ALC_RELEASE_RATE,
446                         0, 0x3f, 0, 0),
447         SOC_SINGLE_TLV("ALC MAX", CS42L56_ALC_THRESHOLD,
448                         5, 0x07, 1, alc_tlv),
449         SOC_SINGLE_TLV("ALC MIN", CS42L56_ALC_THRESHOLD,
450                         2, 0x07, 1, alc_tlv),
451 
452         SOC_SINGLE("Limiter Switch", CS42L56_LIM_CTL_RELEASE_RATE, 7, 1, 1),
453         SOC_SINGLE("Limit All Switch", CS42L56_LIM_CTL_RELEASE_RATE, 6, 1, 1),
454         SOC_SINGLE_RANGE("Limiter Attack", CS42L56_LIM_ATTACK_RATE,
455                         0, 0, 0x3f, 0),
456         SOC_SINGLE_RANGE("Limiter Release", CS42L56_LIM_CTL_RELEASE_RATE,
457                         0, 0x3f, 0, 0),
458         SOC_SINGLE_TLV("Limiter MAX", CS42L56_LIM_THRESHOLD_CTL,
459                         5, 0x07, 1, alc_tlv),
460         SOC_SINGLE_TLV("Limiter Cushion", CS42L56_ALC_THRESHOLD,
461                         2, 0x07, 1, alc_tlv),
462 
463         SOC_SINGLE("NG Switch", CS42L56_NOISE_GATE_CTL, 6, 1, 1),
464         SOC_SINGLE("NG All Switch", CS42L56_NOISE_GATE_CTL, 7, 1, 1),
465         SOC_SINGLE("NG Boost Switch", CS42L56_NOISE_GATE_CTL, 5, 1, 1),
466         SOC_SINGLE_TLV("NG Unboost Threshold", CS42L56_NOISE_GATE_CTL,
467                         2, 0x07, 1, ngnb_tlv),
468         SOC_SINGLE_TLV("NG Boost Threshold", CS42L56_NOISE_GATE_CTL,
469                         2, 0x07, 1, ngb_tlv),
470         SOC_ENUM("NG Delay", ng_delay_enum),
471 
472         SOC_ENUM("Beep Config", beep_config_enum),
473         SOC_ENUM("Beep Pitch", beep_pitch_enum),
474         SOC_ENUM("Beep on Time", beep_ontime_enum),
475         SOC_ENUM("Beep off Time", beep_offtime_enum),
476         SOC_SINGLE_SX_TLV("Beep Volume", CS42L56_BEEP_FREQ_OFFTIME,
477                         0, 0x07, 0x23, beep_tlv),
478         SOC_SINGLE("Beep Tone Ctl Switch", CS42L56_BEEP_TONE_CFG, 0, 1, 1),
479         SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum),
480         SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum),
481 
482 };
483 
484 static const struct snd_soc_dapm_widget cs42l56_dapm_widgets[] = {
485 
486         SND_SOC_DAPM_SIGGEN("Beep"),
487         SND_SOC_DAPM_SUPPLY("VBUF", CS42L56_PWRCTL_1, 5, 1, NULL, 0),
488         SND_SOC_DAPM_MICBIAS("MIC1 Bias", CS42L56_PWRCTL_1, 4, 1),
489         SND_SOC_DAPM_SUPPLY("Charge Pump", CS42L56_PWRCTL_1, 3, 1, NULL, 0),
490 
491         SND_SOC_DAPM_INPUT("AIN1A"),
492         SND_SOC_DAPM_INPUT("AIN2A"),
493         SND_SOC_DAPM_INPUT("AIN1B"),
494         SND_SOC_DAPM_INPUT("AIN2B"),
495         SND_SOC_DAPM_INPUT("AIN3A"),
496         SND_SOC_DAPM_INPUT("AIN3B"),
497 
498         SND_SOC_DAPM_AIF_OUT("SDOUT", NULL,  0,
499                         SND_SOC_NOPM, 0, 0),
500 
501         SND_SOC_DAPM_AIF_IN("SDIN", NULL,  0,
502                         SND_SOC_NOPM, 0, 0),
503 
504         SND_SOC_DAPM_MUX("Digital Output Mux", SND_SOC_NOPM,
505                          0, 0, &dig_mux),
506 
507         SND_SOC_DAPM_PGA("PGAA", SND_SOC_NOPM, 0, 0, NULL, 0),
508         SND_SOC_DAPM_PGA("PGAB", SND_SOC_NOPM, 0, 0, NULL, 0),
509         SND_SOC_DAPM_MUX("PGAA Input Mux",
510                         SND_SOC_NOPM, 0, 0, &pgaa_mux),
511         SND_SOC_DAPM_MUX("PGAB Input Mux",
512                         SND_SOC_NOPM, 0, 0, &pgab_mux),
513 
514         SND_SOC_DAPM_MUX("ADCA Mux", SND_SOC_NOPM,
515                          0, 0, &adca_mux),
516         SND_SOC_DAPM_MUX("ADCB Mux", SND_SOC_NOPM,
517                          0, 0, &adcb_mux),
518 
519         SND_SOC_DAPM_ADC("ADCA", NULL, CS42L56_PWRCTL_1, 1, 1),
520         SND_SOC_DAPM_ADC("ADCB", NULL, CS42L56_PWRCTL_1, 2, 1),
521 
522         SND_SOC_DAPM_MUX("ADCA Swap Mux", SND_SOC_NOPM, 0, 0,
523                 &adca_swap_mux),
524         SND_SOC_DAPM_MUX("ADCB Swap Mux", SND_SOC_NOPM, 0, 0,
525                 &adcb_swap_mux),
526 
527         SND_SOC_DAPM_MUX("PCMA Swap Mux", SND_SOC_NOPM, 0, 0,
528                 &pcma_swap_mux),
529         SND_SOC_DAPM_MUX("PCMB Swap Mux", SND_SOC_NOPM, 0, 0,
530                 &pcmb_swap_mux),
531 
532         SND_SOC_DAPM_DAC("DACA", NULL, SND_SOC_NOPM, 0, 0),
533         SND_SOC_DAPM_DAC("DACB", NULL, SND_SOC_NOPM, 0, 0),
534 
535         SND_SOC_DAPM_OUTPUT("HPA"),
536         SND_SOC_DAPM_OUTPUT("LOA"),
537         SND_SOC_DAPM_OUTPUT("HPB"),
538         SND_SOC_DAPM_OUTPUT("LOB"),
539 
540         SND_SOC_DAPM_SWITCH("Headphone Right",
541                             CS42L56_PWRCTL_2, 4, 1, &hpb_switch),
542         SND_SOC_DAPM_SWITCH("Headphone Left",
543                             CS42L56_PWRCTL_2, 6, 1, &hpa_switch),
544 
545         SND_SOC_DAPM_SWITCH("Lineout Right",
546                             CS42L56_PWRCTL_2, 0, 1, &lob_switch),
547         SND_SOC_DAPM_SWITCH("Lineout Left",
548                             CS42L56_PWRCTL_2, 2, 1, &loa_switch),
549 
550         SND_SOC_DAPM_MUX("LINEOUTA Input Mux", SND_SOC_NOPM,
551                          0, 0, &lineouta_input),
552         SND_SOC_DAPM_MUX("LINEOUTB Input Mux", SND_SOC_NOPM,
553                          0, 0, &lineoutb_input),
554         SND_SOC_DAPM_MUX("HPA Input Mux", SND_SOC_NOPM,
555                          0, 0, &hpa_input),
556         SND_SOC_DAPM_MUX("HPB Input Mux", SND_SOC_NOPM,
557                          0, 0, &hpb_input),
558 
559 };
560 
561 static const struct snd_soc_dapm_route cs42l56_audio_map[] = {
562 
563         {"HiFi Capture", "DSP", "Digital Output Mux"},
564         {"HiFi Capture", "ADC", "Digital Output Mux"},
565 
566         {"Digital Output Mux", NULL, "ADCA"},
567         {"Digital Output Mux", NULL, "ADCB"},
568 
569         {"ADCB", NULL, "ADCB Swap Mux"},
570         {"ADCA", NULL, "ADCA Swap Mux"},
571 
572         {"ADCA Swap Mux", NULL, "ADCA"},
573         {"ADCB Swap Mux", NULL, "ADCB"},
574 
575         {"DACA", "Left", "ADCA Swap Mux"},
576         {"DACA", "LR 2", "ADCA Swap Mux"},
577         {"DACA", "Right", "ADCA Swap Mux"},
578 
579         {"DACB", "Left", "ADCB Swap Mux"},
580         {"DACB", "LR 2", "ADCB Swap Mux"},
581         {"DACB", "Right", "ADCB Swap Mux"},
582 
583         {"ADCA Mux", NULL, "AIN3A"},
584         {"ADCA Mux", NULL, "AIN2A"},
585         {"ADCA Mux", NULL, "AIN1A"},
586         {"ADCA Mux", NULL, "PGAA"},
587         {"ADCB Mux", NULL, "AIN3B"},
588         {"ADCB Mux", NULL, "AIN2B"},
589         {"ADCB Mux", NULL, "AIN1B"},
590         {"ADCB Mux", NULL, "PGAB"},
591 
592         {"PGAA", "AIN1A", "PGAA Input Mux"},
593         {"PGAA", "AIN2A", "PGAA Input Mux"},
594         {"PGAA", "AIN3A", "PGAA Input Mux"},
595         {"PGAB", "AIN1B", "PGAB Input Mux"},
596         {"PGAB", "AIN2B", "PGAB Input Mux"},
597         {"PGAB", "AIN3B", "PGAB Input Mux"},
598 
599         {"PGAA Input Mux", NULL, "AIN1A"},
600         {"PGAA Input Mux", NULL, "AIN2A"},
601         {"PGAA Input Mux", NULL, "AIN3A"},
602         {"PGAB Input Mux", NULL, "AIN1B"},
603         {"PGAB Input Mux", NULL, "AIN2B"},
604         {"PGAB Input Mux", NULL, "AIN3B"},
605 
606         {"LOB", "Switch", "LINEOUTB Input Mux"},
607         {"LOA", "Switch", "LINEOUTA Input Mux"},
608 
609         {"LINEOUTA Input Mux", "PGAA", "PGAA"},
610         {"LINEOUTB Input Mux", "PGAB", "PGAB"},
611         {"LINEOUTA Input Mux", "DACA", "DACA"},
612         {"LINEOUTB Input Mux", "DACB", "DACB"},
613 
614         {"HPA", "Switch", "HPB Input Mux"},
615         {"HPB", "Switch", "HPA Input Mux"},
616 
617         {"HPA Input Mux", "PGAA", "PGAA"},
618         {"HPB Input Mux", "PGAB", "PGAB"},
619         {"HPA Input Mux", "DACA", "DACA"},
620         {"HPB Input Mux", "DACB", "DACB"},
621 
622         {"DACA", NULL, "PCMA Swap Mux"},
623         {"DACB", NULL, "PCMB Swap Mux"},
624 
625         {"PCMB Swap Mux", "Left", "HiFi Playback"},
626         {"PCMB Swap Mux", "LR 2", "HiFi Playback"},
627         {"PCMB Swap Mux", "Right", "HiFi Playback"},
628 
629         {"PCMA Swap Mux", "Left", "HiFi Playback"},
630         {"PCMA Swap Mux", "LR 2", "HiFi Playback"},
631         {"PCMA Swap Mux", "Right", "HiFi Playback"},
632 
633 };
634 
635 struct cs42l56_clk_para {
636         u32 mclk;
637         u32 srate;
638         u8 ratio;
639 };
640 
641 static const struct cs42l56_clk_para clk_ratio_table[] = {
642         /* 8k */
643         { 6000000, 8000, CS42L56_MCLK_LRCLK_768 },
644         { 6144000, 8000, CS42L56_MCLK_LRCLK_750 },
645         { 12000000, 8000, CS42L56_MCLK_LRCLK_768 },
646         { 12288000, 8000, CS42L56_MCLK_LRCLK_750 },
647         { 24000000, 8000, CS42L56_MCLK_LRCLK_768 },
648         { 24576000, 8000, CS42L56_MCLK_LRCLK_750 },
649         /* 11.025k */
650         { 5644800, 11025, CS42L56_MCLK_LRCLK_512},
651         { 11289600, 11025, CS42L56_MCLK_LRCLK_512},
652         { 22579200, 11025, CS42L56_MCLK_LRCLK_512 },
653         /* 11.0294k */
654         { 6000000, 110294, CS42L56_MCLK_LRCLK_544 },
655         { 12000000, 110294, CS42L56_MCLK_LRCLK_544 },
656         { 24000000, 110294, CS42L56_MCLK_LRCLK_544 },
657         /* 12k */
658         { 6000000, 12000, CS42L56_MCLK_LRCLK_500 },
659         { 6144000, 12000, CS42L56_MCLK_LRCLK_512 },
660         { 12000000, 12000, CS42L56_MCLK_LRCLK_500 },
661         { 12288000, 12000, CS42L56_MCLK_LRCLK_512 },
662         { 24000000, 12000, CS42L56_MCLK_LRCLK_500 },
663         { 24576000, 12000, CS42L56_MCLK_LRCLK_512 },
664         /* 16k */
665         { 6000000, 16000, CS42L56_MCLK_LRCLK_375 },
666         { 6144000, 16000, CS42L56_MCLK_LRCLK_384 },
667         { 12000000, 16000, CS42L56_MCLK_LRCLK_375 },
668         { 12288000, 16000, CS42L56_MCLK_LRCLK_384 },
669         { 24000000, 16000, CS42L56_MCLK_LRCLK_375 },
670         { 24576000, 16000, CS42L56_MCLK_LRCLK_384 },
671         /* 22.050k */
672         { 5644800, 22050, CS42L56_MCLK_LRCLK_256 },
673         { 11289600, 22050, CS42L56_MCLK_LRCLK_256 },
674         { 22579200, 22050, CS42L56_MCLK_LRCLK_256 },
675         /* 22.0588k */
676         { 6000000, 220588, CS42L56_MCLK_LRCLK_272 },
677         { 12000000, 220588, CS42L56_MCLK_LRCLK_272 },
678         { 24000000, 220588, CS42L56_MCLK_LRCLK_272 },
679         /* 24k */
680         { 6000000, 24000, CS42L56_MCLK_LRCLK_250 },
681         { 6144000, 24000, CS42L56_MCLK_LRCLK_256 },
682         { 12000000, 24000, CS42L56_MCLK_LRCLK_250 },
683         { 12288000, 24000, CS42L56_MCLK_LRCLK_256 },
684         { 24000000, 24000, CS42L56_MCLK_LRCLK_250 },
685         { 24576000, 24000, CS42L56_MCLK_LRCLK_256 },
686         /* 32k */
687         { 6000000, 32000, CS42L56_MCLK_LRCLK_187P5 },
688         { 6144000, 32000, CS42L56_MCLK_LRCLK_192 },
689         { 12000000, 32000, CS42L56_MCLK_LRCLK_187P5 },
690         { 12288000, 32000, CS42L56_MCLK_LRCLK_192 },
691         { 24000000, 32000, CS42L56_MCLK_LRCLK_187P5 },
692         { 24576000, 32000, CS42L56_MCLK_LRCLK_192 },
693         /* 44.118k */
694         { 6000000, 44118, CS42L56_MCLK_LRCLK_136 },
695         { 12000000, 44118, CS42L56_MCLK_LRCLK_136 },
696         { 24000000, 44118, CS42L56_MCLK_LRCLK_136 },
697         /* 44.1k */
698         { 5644800, 44100, CS42L56_MCLK_LRCLK_128 },
699         { 11289600, 44100, CS42L56_MCLK_LRCLK_128 },
700         { 22579200, 44100, CS42L56_MCLK_LRCLK_128 },
701         /* 48k */
702         { 6000000, 48000, CS42L56_MCLK_LRCLK_125 },
703         { 6144000, 48000, CS42L56_MCLK_LRCLK_128 },
704         { 12000000, 48000, CS42L56_MCLK_LRCLK_125 },
705         { 12288000, 48000, CS42L56_MCLK_LRCLK_128 },
706         { 24000000, 48000, CS42L56_MCLK_LRCLK_125 },
707         { 24576000, 48000, CS42L56_MCLK_LRCLK_128 },
708 };
709 
710 static int cs42l56_get_mclk_ratio(int mclk, int rate)
711 {
712         int i;
713 
714         for (i = 0; i < ARRAY_SIZE(clk_ratio_table); i++) {
715                 if (clk_ratio_table[i].mclk == mclk &&
716                     clk_ratio_table[i].srate == rate)
717                         return clk_ratio_table[i].ratio;
718         }
719         return -EINVAL;
720 }
721 
722 static int cs42l56_set_sysclk(struct snd_soc_dai *codec_dai,
723                         int clk_id, unsigned int freq, int dir)
724 {
725         struct snd_soc_component *component = codec_dai->component;
726         struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
727 
728         switch (freq) {
729         case CS42L56_MCLK_5P6448MHZ:
730         case CS42L56_MCLK_6MHZ:
731         case CS42L56_MCLK_6P144MHZ:
732                 cs42l56->mclk_div2 = 0;
733                 cs42l56->mclk_prediv = 0;
734                 break;
735         case CS42L56_MCLK_11P2896MHZ:
736         case CS42L56_MCLK_12MHZ:
737         case CS42L56_MCLK_12P288MHZ:
738                 cs42l56->mclk_div2 = CS42L56_MCLK_DIV2;
739                 cs42l56->mclk_prediv = 0;
740                 break;
741         case CS42L56_MCLK_22P5792MHZ:
742         case CS42L56_MCLK_24MHZ:
743         case CS42L56_MCLK_24P576MHZ:
744                 cs42l56->mclk_div2 = CS42L56_MCLK_DIV2;
745                 cs42l56->mclk_prediv = CS42L56_MCLK_PREDIV;
746                 break;
747         default:
748                 return -EINVAL;
749         }
750         cs42l56->mclk = freq;
751 
752         snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
753                             CS42L56_MCLK_PREDIV_MASK,
754                                 cs42l56->mclk_prediv);
755         snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
756                             CS42L56_MCLK_DIV2_MASK,
757                                 cs42l56->mclk_div2);
758 
759         return 0;
760 }
761 
762 static int cs42l56_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
763 {
764         struct snd_soc_component *component = codec_dai->component;
765         struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
766 
767         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
768         case SND_SOC_DAIFMT_CBM_CFM:
769                 cs42l56->iface = CS42L56_MASTER_MODE;
770                 break;
771         case SND_SOC_DAIFMT_CBS_CFS:
772                 cs42l56->iface = CS42L56_SLAVE_MODE;
773                 break;
774         default:
775                 return -EINVAL;
776         }
777 
778          /* interface format */
779         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
780         case SND_SOC_DAIFMT_I2S:
781                 cs42l56->iface_fmt = CS42L56_DIG_FMT_I2S;
782                 break;
783         case SND_SOC_DAIFMT_LEFT_J:
784                 cs42l56->iface_fmt = CS42L56_DIG_FMT_LEFT_J;
785                 break;
786         default:
787                 return -EINVAL;
788         }
789 
790         /* sclk inversion */
791         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
792         case SND_SOC_DAIFMT_NB_NF:
793                 cs42l56->iface_inv = 0;
794                 break;
795         case SND_SOC_DAIFMT_IB_NF:
796                 cs42l56->iface_inv = CS42L56_SCLK_INV;
797                 break;
798         default:
799                 return -EINVAL;
800         }
801 
802         snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
803                             CS42L56_MS_MODE_MASK, cs42l56->iface);
804         snd_soc_component_update_bits(component, CS42L56_SERIAL_FMT,
805                             CS42L56_DIG_FMT_MASK, cs42l56->iface_fmt);
806         snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
807                             CS42L56_SCLK_INV_MASK, cs42l56->iface_inv);
808         return 0;
809 }
810 
811 static int cs42l56_digital_mute(struct snd_soc_dai *dai, int mute)
812 {
813         struct snd_soc_component *component = dai->component;
814 
815         if (mute) {
816                 /* Hit the DSP Mixer first */
817                 snd_soc_component_update_bits(component, CS42L56_DSP_MUTE_CTL,
818                                     CS42L56_ADCAMIX_MUTE_MASK |
819                                     CS42L56_ADCBMIX_MUTE_MASK |
820                                     CS42L56_PCMAMIX_MUTE_MASK |
821                                     CS42L56_PCMBMIX_MUTE_MASK |
822                                     CS42L56_MSTB_MUTE_MASK |
823                                     CS42L56_MSTA_MUTE_MASK,
824                                     CS42L56_MUTE_ALL);
825                 /* Mute ADC's */
826                 snd_soc_component_update_bits(component, CS42L56_MISC_ADC_CTL,
827                                     CS42L56_ADCA_MUTE_MASK |
828                                     CS42L56_ADCB_MUTE_MASK,
829                                     CS42L56_MUTE_ALL);
830                 /* HP And LO */
831                 snd_soc_component_update_bits(component, CS42L56_HPA_VOLUME,
832                                     CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
833                 snd_soc_component_update_bits(component, CS42L56_HPB_VOLUME,
834                                     CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
835                 snd_soc_component_update_bits(component, CS42L56_LOA_VOLUME,
836                                     CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
837                 snd_soc_component_update_bits(component, CS42L56_LOB_VOLUME,
838                                     CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
839         } else {
840                 snd_soc_component_update_bits(component, CS42L56_DSP_MUTE_CTL,
841                                     CS42L56_ADCAMIX_MUTE_MASK |
842                                     CS42L56_ADCBMIX_MUTE_MASK |
843                                     CS42L56_PCMAMIX_MUTE_MASK |
844                                     CS42L56_PCMBMIX_MUTE_MASK |
845                                     CS42L56_MSTB_MUTE_MASK |
846                                     CS42L56_MSTA_MUTE_MASK,
847                                     CS42L56_UNMUTE);
848 
849                 snd_soc_component_update_bits(component, CS42L56_MISC_ADC_CTL,
850                                     CS42L56_ADCA_MUTE_MASK |
851                                     CS42L56_ADCB_MUTE_MASK,
852                                     CS42L56_UNMUTE);
853 
854                 snd_soc_component_update_bits(component, CS42L56_HPA_VOLUME,
855                                     CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
856                 snd_soc_component_update_bits(component, CS42L56_HPB_VOLUME,
857                                     CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
858                 snd_soc_component_update_bits(component, CS42L56_LOA_VOLUME,
859                                     CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
860                 snd_soc_component_update_bits(component, CS42L56_LOB_VOLUME,
861                                     CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
862         }
863         return 0;
864 }
865 
866 static int cs42l56_pcm_hw_params(struct snd_pcm_substream *substream,
867                                      struct snd_pcm_hw_params *params,
868                                      struct snd_soc_dai *dai)
869 {
870         struct snd_soc_component *component = dai->component;
871         struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
872         int ratio;
873 
874         ratio = cs42l56_get_mclk_ratio(cs42l56->mclk, params_rate(params));
875         if (ratio >= 0) {
876                 snd_soc_component_update_bits(component, CS42L56_CLKCTL_2,
877                                     CS42L56_CLK_RATIO_MASK, ratio);
878         } else {
879                 dev_err(component->dev, "unsupported mclk/sclk/lrclk ratio\n");
880                 return -EINVAL;
881         }
882 
883         return 0;
884 }
885 
886 static int cs42l56_set_bias_level(struct snd_soc_component *component,
887                                         enum snd_soc_bias_level level)
888 {
889         struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
890         int ret;
891 
892         switch (level) {
893         case SND_SOC_BIAS_ON:
894                 break;
895         case SND_SOC_BIAS_PREPARE:
896                 snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
897                                     CS42L56_MCLK_DIS_MASK, 0);
898                 snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
899                                     CS42L56_PDN_ALL_MASK, 0);
900                 break;
901         case SND_SOC_BIAS_STANDBY:
902                 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
903                         regcache_cache_only(cs42l56->regmap, false);
904                         regcache_sync(cs42l56->regmap);
905                         ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
906                                                     cs42l56->supplies);
907                         if (ret != 0) {
908                                 dev_err(cs42l56->dev,
909                                         "Failed to enable regulators: %d\n",
910                                         ret);
911                                 return ret;
912                         }
913                 }
914                 snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
915                                     CS42L56_PDN_ALL_MASK, 1);
916                 break;
917         case SND_SOC_BIAS_OFF:
918                 snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
919                                     CS42L56_PDN_ALL_MASK, 1);
920                 snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
921                                     CS42L56_MCLK_DIS_MASK, 1);
922                 regcache_cache_only(cs42l56->regmap, true);
923                 regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
924                                                     cs42l56->supplies);
925                 break;
926         }
927 
928         return 0;
929 }
930 
931 #define CS42L56_RATES (SNDRV_PCM_RATE_8000_48000)
932 
933 #define CS42L56_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \
934                         SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE | \
935                         SNDRV_PCM_FMTBIT_S32_LE)
936 
937 
938 static const struct snd_soc_dai_ops cs42l56_ops = {
939         .hw_params      = cs42l56_pcm_hw_params,
940         .digital_mute   = cs42l56_digital_mute,
941         .set_fmt        = cs42l56_set_dai_fmt,
942         .set_sysclk     = cs42l56_set_sysclk,
943 };
944 
945 static struct snd_soc_dai_driver cs42l56_dai = {
946                 .name = "cs42l56",
947                 .playback = {
948                         .stream_name = "HiFi Playback",
949                         .channels_min = 1,
950                         .channels_max = 2,
951                         .rates = CS42L56_RATES,
952                         .formats = CS42L56_FORMATS,
953                 },
954                 .capture = {
955                         .stream_name = "HiFi Capture",
956                         .channels_min = 1,
957                         .channels_max = 2,
958                         .rates = CS42L56_RATES,
959                         .formats = CS42L56_FORMATS,
960                 },
961                 .ops = &cs42l56_ops,
962 };
963 
964 static int beep_freq[] = {
965         261, 522, 585, 667, 706, 774, 889, 1000,
966         1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
967 };
968 
969 static void cs42l56_beep_work(struct work_struct *work)
970 {
971         struct cs42l56_private *cs42l56 =
972                 container_of(work, struct cs42l56_private, beep_work);
973         struct snd_soc_component *component = cs42l56->component;
974         struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
975         int i;
976         int val = 0;
977         int best = 0;
978 
979         if (cs42l56->beep_rate) {
980                 for (i = 0; i < ARRAY_SIZE(beep_freq); i++) {
981                         if (abs(cs42l56->beep_rate - beep_freq[i]) <
982                             abs(cs42l56->beep_rate - beep_freq[best]))
983                                 best = i;
984                 }
985 
986                 dev_dbg(component->dev, "Set beep rate %dHz for requested %dHz\n",
987                         beep_freq[best], cs42l56->beep_rate);
988 
989                 val = (best << CS42L56_BEEP_RATE_SHIFT);
990 
991                 snd_soc_dapm_enable_pin(dapm, "Beep");
992         } else {
993                 dev_dbg(component->dev, "Disabling beep\n");
994                 snd_soc_dapm_disable_pin(dapm, "Beep");
995         }
996 
997         snd_soc_component_update_bits(component, CS42L56_BEEP_FREQ_ONTIME,
998                             CS42L56_BEEP_FREQ_MASK, val);
999 
1000         snd_soc_dapm_sync(dapm);
1001 }
1002 
1003 /* For usability define a way of injecting beep events for the device -
1004  * many systems will not have a keyboard.
1005  */
1006 static int cs42l56_beep_event(struct input_dev *dev, unsigned int type,
1007                              unsigned int code, int hz)
1008 {
1009         struct snd_soc_component *component = input_get_drvdata(dev);
1010         struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
1011 
1012         dev_dbg(component->dev, "Beep event %x %x\n", code, hz);
1013 
1014         switch (code) {
1015         case SND_BELL:
1016                 if (hz)
1017                         hz = 261;
1018         case SND_TONE:
1019                 break;
1020         default:
1021                 return -1;
1022         }
1023 
1024         /* Kick the beep from a workqueue */
1025         cs42l56->beep_rate = hz;
1026         schedule_work(&cs42l56->beep_work);
1027         return 0;
1028 }
1029 
1030 static ssize_t cs42l56_beep_set(struct device *dev,
1031                                struct device_attribute *attr,
1032                                const char *buf, size_t count)
1033 {
1034         struct cs42l56_private *cs42l56 = dev_get_drvdata(dev);
1035         long int time;
1036         int ret;
1037 
1038         ret = kstrtol(buf, 10, &time);
1039         if (ret != 0)
1040                 return ret;
1041 
1042         input_event(cs42l56->beep, EV_SND, SND_TONE, time);
1043 
1044         return count;
1045 }
1046 
1047 static DEVICE_ATTR(beep, 0200, NULL, cs42l56_beep_set);
1048 
1049 static void cs42l56_init_beep(struct snd_soc_component *component)
1050 {
1051         struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
1052         int ret;
1053 
1054         cs42l56->beep = devm_input_allocate_device(component->dev);
1055         if (!cs42l56->beep) {
1056                 dev_err(component->dev, "Failed to allocate beep device\n");
1057                 return;
1058         }
1059 
1060         INIT_WORK(&cs42l56->beep_work, cs42l56_beep_work);
1061         cs42l56->beep_rate = 0;
1062 
1063         cs42l56->beep->name = "CS42L56 Beep Generator";
1064         cs42l56->beep->phys = dev_name(component->dev);
1065         cs42l56->beep->id.bustype = BUS_I2C;
1066 
1067         cs42l56->beep->evbit[0] = BIT_MASK(EV_SND);
1068         cs42l56->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
1069         cs42l56->beep->event = cs42l56_beep_event;
1070         cs42l56->beep->dev.parent = component->dev;
1071         input_set_drvdata(cs42l56->beep, component);
1072 
1073         ret = input_register_device(cs42l56->beep);
1074         if (ret != 0) {
1075                 cs42l56->beep = NULL;
1076                 dev_err(component->dev, "Failed to register beep device\n");
1077         }
1078 
1079         ret = device_create_file(component->dev, &dev_attr_beep);
1080         if (ret != 0) {
1081                 dev_err(component->dev, "Failed to create keyclick file: %d\n",
1082                         ret);
1083         }
1084 }
1085 
1086 static void cs42l56_free_beep(struct snd_soc_component *component)
1087 {
1088         struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
1089 
1090         device_remove_file(component->dev, &dev_attr_beep);
1091         cancel_work_sync(&cs42l56->beep_work);
1092         cs42l56->beep = NULL;
1093 
1094         snd_soc_component_update_bits(component, CS42L56_BEEP_TONE_CFG,
1095                             CS42L56_BEEP_EN_MASK, 0);
1096 }
1097 
1098 static int cs42l56_probe(struct snd_soc_component *component)
1099 {
1100         cs42l56_init_beep(component);
1101 
1102         return 0;
1103 }
1104 
1105 static void cs42l56_remove(struct snd_soc_component *component)
1106 {
1107         cs42l56_free_beep(component);
1108 }
1109 
1110 static const struct snd_soc_component_driver soc_component_dev_cs42l56 = {
1111         .probe                  = cs42l56_probe,
1112         .remove                 = cs42l56_remove,
1113         .set_bias_level         = cs42l56_set_bias_level,
1114         .controls               = cs42l56_snd_controls,
1115         .num_controls           = ARRAY_SIZE(cs42l56_snd_controls),
1116         .dapm_widgets           = cs42l56_dapm_widgets,
1117         .num_dapm_widgets       = ARRAY_SIZE(cs42l56_dapm_widgets),
1118         .dapm_routes            = cs42l56_audio_map,
1119         .num_dapm_routes        = ARRAY_SIZE(cs42l56_audio_map),
1120         .suspend_bias_off       = 1,
1121         .idle_bias_on           = 1,
1122         .use_pmdown_time        = 1,
1123         .endianness             = 1,
1124         .non_legacy_dai_naming  = 1,
1125 };
1126 
1127 static const struct regmap_config cs42l56_regmap = {
1128         .reg_bits = 8,
1129         .val_bits = 8,
1130 
1131         .max_register = CS42L56_MAX_REGISTER,
1132         .reg_defaults = cs42l56_reg_defaults,
1133         .num_reg_defaults = ARRAY_SIZE(cs42l56_reg_defaults),
1134         .readable_reg = cs42l56_readable_register,
1135         .volatile_reg = cs42l56_volatile_register,
1136         .cache_type = REGCACHE_RBTREE,
1137 };
1138 
1139 static int cs42l56_handle_of_data(struct i2c_client *i2c_client,
1140                                     struct cs42l56_platform_data *pdata)
1141 {
1142         struct device_node *np = i2c_client->dev.of_node;
1143         u32 val32;
1144 
1145         if (of_property_read_bool(np, "cirrus,ain1a-reference-cfg"))
1146                 pdata->ain1a_ref_cfg = true;
1147 
1148         if (of_property_read_bool(np, "cirrus,ain2a-reference-cfg"))
1149                 pdata->ain2a_ref_cfg = true;
1150 
1151         if (of_property_read_bool(np, "cirrus,ain1b-reference-cfg"))
1152                 pdata->ain1b_ref_cfg = true;
1153 
1154         if (of_property_read_bool(np, "cirrus,ain2b-reference-cfg"))
1155                 pdata->ain2b_ref_cfg = true;
1156 
1157         if (of_property_read_u32(np, "cirrus,micbias-lvl", &val32) >= 0)
1158                 pdata->micbias_lvl = val32;
1159 
1160         if (of_property_read_u32(np, "cirrus,chgfreq-divisor", &val32) >= 0)
1161                 pdata->chgfreq = val32;
1162 
1163         if (of_property_read_u32(np, "cirrus,adaptive-pwr-cfg", &val32) >= 0)
1164                 pdata->adaptive_pwr = val32;
1165 
1166         if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0)
1167                 pdata->hpfa_freq = val32;
1168 
1169         if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0)
1170                 pdata->hpfb_freq = val32;
1171 
1172         pdata->gpio_nreset = of_get_named_gpio(np, "cirrus,gpio-nreset", 0);
1173 
1174         return 0;
1175 }
1176 
1177 static int cs42l56_i2c_probe(struct i2c_client *i2c_client,
1178                              const struct i2c_device_id *id)
1179 {
1180         struct cs42l56_private *cs42l56;
1181         struct cs42l56_platform_data *pdata =
1182                 dev_get_platdata(&i2c_client->dev);
1183         int ret, i;
1184         unsigned int devid = 0;
1185         unsigned int alpha_rev, metal_rev;
1186         unsigned int reg;
1187 
1188         cs42l56 = devm_kzalloc(&i2c_client->dev, sizeof(*cs42l56), GFP_KERNEL);
1189         if (cs42l56 == NULL)
1190                 return -ENOMEM;
1191         cs42l56->dev = &i2c_client->dev;
1192 
1193         cs42l56->regmap = devm_regmap_init_i2c(i2c_client, &cs42l56_regmap);
1194         if (IS_ERR(cs42l56->regmap)) {
1195                 ret = PTR_ERR(cs42l56->regmap);
1196                 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1197                 return ret;
1198         }
1199 
1200         if (pdata) {
1201                 cs42l56->pdata = *pdata;
1202         } else {
1203                 pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata),
1204                                      GFP_KERNEL);
1205                 if (!pdata)
1206                         return -ENOMEM;
1207 
1208                 if (i2c_client->dev.of_node) {
1209                         ret = cs42l56_handle_of_data(i2c_client,
1210                                                      &cs42l56->pdata);
1211                         if (ret != 0)
1212                                 return ret;
1213                 }
1214                 cs42l56->pdata = *pdata;
1215         }
1216 
1217         if (cs42l56->pdata.gpio_nreset) {
1218                 ret = gpio_request_one(cs42l56->pdata.gpio_nreset,
1219                                        GPIOF_OUT_INIT_HIGH, "CS42L56 /RST");
1220                 if (ret < 0) {
1221                         dev_err(&i2c_client->dev,
1222                                 "Failed to request /RST %d: %d\n",
1223                                 cs42l56->pdata.gpio_nreset, ret);
1224                         return ret;
1225                 }
1226                 gpio_set_value_cansleep(cs42l56->pdata.gpio_nreset, 0);
1227                 gpio_set_value_cansleep(cs42l56->pdata.gpio_nreset, 1);
1228         }
1229 
1230 
1231         i2c_set_clientdata(i2c_client, cs42l56);
1232 
1233         for (i = 0; i < ARRAY_SIZE(cs42l56->supplies); i++)
1234                 cs42l56->supplies[i].supply = cs42l56_supply_names[i];
1235 
1236         ret = devm_regulator_bulk_get(&i2c_client->dev,
1237                                       ARRAY_SIZE(cs42l56->supplies),
1238                                       cs42l56->supplies);
1239         if (ret != 0) {
1240                 dev_err(&i2c_client->dev,
1241                         "Failed to request supplies: %d\n", ret);
1242                 return ret;
1243         }
1244 
1245         ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
1246                                     cs42l56->supplies);
1247         if (ret != 0) {
1248                 dev_err(&i2c_client->dev,
1249                         "Failed to enable supplies: %d\n", ret);
1250                 return ret;
1251         }
1252 
1253         ret = regmap_read(cs42l56->regmap, CS42L56_CHIP_ID_1, &reg);
1254         devid = reg & CS42L56_CHIP_ID_MASK;
1255         if (devid != CS42L56_DEVID) {
1256                 dev_err(&i2c_client->dev,
1257                         "CS42L56 Device ID (%X). Expected %X\n",
1258                         devid, CS42L56_DEVID);
1259                 goto err_enable;
1260         }
1261         alpha_rev = reg & CS42L56_AREV_MASK;
1262         metal_rev = reg & CS42L56_MTLREV_MASK;
1263 
1264         dev_info(&i2c_client->dev, "Cirrus Logic CS42L56 ");
1265         dev_info(&i2c_client->dev, "Alpha Rev %X Metal Rev %X\n",
1266                  alpha_rev, metal_rev);
1267 
1268         if (cs42l56->pdata.ain1a_ref_cfg)
1269                 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1270                                    CS42L56_AIN1A_REF_MASK,
1271                                    CS42L56_AIN1A_REF_MASK);
1272 
1273         if (cs42l56->pdata.ain1b_ref_cfg)
1274                 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1275                                    CS42L56_AIN1B_REF_MASK,
1276                                    CS42L56_AIN1B_REF_MASK);
1277 
1278         if (cs42l56->pdata.ain2a_ref_cfg)
1279                 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1280                                    CS42L56_AIN2A_REF_MASK,
1281                                    CS42L56_AIN2A_REF_MASK);
1282 
1283         if (cs42l56->pdata.ain2b_ref_cfg)
1284                 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1285                                    CS42L56_AIN2B_REF_MASK,
1286                                    CS42L56_AIN2B_REF_MASK);
1287 
1288         if (cs42l56->pdata.micbias_lvl)
1289                 regmap_update_bits(cs42l56->regmap, CS42L56_GAIN_BIAS_CTL,
1290                                    CS42L56_MIC_BIAS_MASK,
1291                                 cs42l56->pdata.micbias_lvl);
1292 
1293         if (cs42l56->pdata.chgfreq)
1294                 regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL,
1295                                    CS42L56_CHRG_FREQ_MASK,
1296                                 cs42l56->pdata.chgfreq);
1297 
1298         if (cs42l56->pdata.hpfb_freq)
1299                 regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL,
1300                                    CS42L56_HPFB_FREQ_MASK,
1301                                 cs42l56->pdata.hpfb_freq);
1302 
1303         if (cs42l56->pdata.hpfa_freq)
1304                 regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL,
1305                                    CS42L56_HPFA_FREQ_MASK,
1306                                 cs42l56->pdata.hpfa_freq);
1307 
1308         if (cs42l56->pdata.adaptive_pwr)
1309                 regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL,
1310                                    CS42L56_ADAPT_PWR_MASK,
1311                                 cs42l56->pdata.adaptive_pwr);
1312 
1313         ret =  devm_snd_soc_register_component(&i2c_client->dev,
1314                         &soc_component_dev_cs42l56, &cs42l56_dai, 1);
1315         if (ret < 0)
1316                 return ret;
1317 
1318         return 0;
1319 
1320 err_enable:
1321         regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
1322                                cs42l56->supplies);
1323         return ret;
1324 }
1325 
1326 static int cs42l56_i2c_remove(struct i2c_client *client)
1327 {
1328         struct cs42l56_private *cs42l56 = i2c_get_clientdata(client);
1329 
1330         regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
1331                                cs42l56->supplies);
1332         return 0;
1333 }
1334 
1335 static const struct of_device_id cs42l56_of_match[] = {
1336         { .compatible = "cirrus,cs42l56", },
1337         { }
1338 };
1339 MODULE_DEVICE_TABLE(of, cs42l56_of_match);
1340 
1341 
1342 static const struct i2c_device_id cs42l56_id[] = {
1343         { "cs42l56", 0 },
1344         { }
1345 };
1346 MODULE_DEVICE_TABLE(i2c, cs42l56_id);
1347 
1348 static struct i2c_driver cs42l56_i2c_driver = {
1349         .driver = {
1350                 .name = "cs42l56",
1351                 .of_match_table = cs42l56_of_match,
1352         },
1353         .id_table = cs42l56_id,
1354         .probe =    cs42l56_i2c_probe,
1355         .remove =   cs42l56_i2c_remove,
1356 };
1357 
1358 module_i2c_driver(cs42l56_i2c_driver);
1359 
1360 MODULE_DESCRIPTION("ASoC CS42L56 driver");
1361 MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
1362 MODULE_LICENSE("GPL");
1363 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp