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

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

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

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