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

~ [ 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