Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cs42l52.c
Go to the documentation of this file.
1 /*
2  * cs42l52.c -- CS42L52 ALSA SoC audio driver
3  *
4  * Copyright 2012 CirrusLogic, Inc.
5  *
6  * Author: Georgi Vlaev <[email protected]>
7  * Author: Brian Austin <[email protected]>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  *
13  */
14 
15 #include <linux/module.h>
16 #include <linux/moduleparam.h>
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/delay.h>
20 #include <linux/pm.h>
21 #include <linux/i2c.h>
22 #include <linux/input.h>
23 #include <linux/regmap.h>
24 #include <linux/slab.h>
25 #include <linux/workqueue.h>
26 #include <linux/platform_device.h>
27 #include <sound/core.h>
28 #include <sound/pcm.h>
29 #include <sound/pcm_params.h>
30 #include <sound/soc.h>
31 #include <sound/soc-dapm.h>
32 #include <sound/initval.h>
33 #include <sound/tlv.h>
34 #include <sound/cs42l52.h>
35 #include "cs42l52.h"
36 
37 struct sp_config {
40 };
41 
43  struct regmap *regmap;
45  struct device *dev;
46  struct sp_config config;
52 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
53  struct input_dev *beep;
54  struct work_struct beep_work;
55  int beep_rate;
56 #endif
57 };
58 
59 static const struct reg_default cs42l52_reg_defaults[] = {
60  { CS42L52_PWRCTL1, 0x9F }, /* r02 PWRCTL 1 */
61  { CS42L52_PWRCTL2, 0x07 }, /* r03 PWRCTL 2 */
62  { CS42L52_PWRCTL3, 0xFF }, /* r04 PWRCTL 3 */
63  { CS42L52_CLK_CTL, 0xA0 }, /* r05 Clocking Ctl */
64  { CS42L52_IFACE_CTL1, 0x00 }, /* r06 Interface Ctl 1 */
65  { CS42L52_ADC_PGA_A, 0x80 }, /* r08 Input A Select */
66  { CS42L52_ADC_PGA_B, 0x80 }, /* r09 Input B Select */
67  { CS42L52_ANALOG_HPF_CTL, 0xA5 }, /* r0A Analog HPF Ctl */
68  { CS42L52_ADC_HPF_FREQ, 0x00 }, /* r0B ADC HPF Corner Freq */
69  { CS42L52_ADC_MISC_CTL, 0x00 }, /* r0C Misc. ADC Ctl */
70  { CS42L52_PB_CTL1, 0x60 }, /* r0D Playback Ctl 1 */
71  { CS42L52_MISC_CTL, 0x02 }, /* r0E Misc. Ctl */
72  { CS42L52_PB_CTL2, 0x00 }, /* r0F Playback Ctl 2 */
73  { CS42L52_MICA_CTL, 0x00 }, /* r10 MICA Amp Ctl */
74  { CS42L52_MICB_CTL, 0x00 }, /* r11 MICB Amp Ctl */
75  { CS42L52_PGAA_CTL, 0x00 }, /* r12 PGAA Vol, Misc. */
76  { CS42L52_PGAB_CTL, 0x00 }, /* r13 PGAB Vol, Misc. */
77  { CS42L52_PASSTHRUA_VOL, 0x00 }, /* r14 Bypass A Vol */
78  { CS42L52_PASSTHRUB_VOL, 0x00 }, /* r15 Bypass B Vol */
79  { CS42L52_ADCA_VOL, 0x00 }, /* r16 ADCA Volume */
80  { CS42L52_ADCB_VOL, 0x00 }, /* r17 ADCB Volume */
81  { CS42L52_ADCA_MIXER_VOL, 0x80 }, /* r18 ADCA Mixer Volume */
82  { CS42L52_ADCB_MIXER_VOL, 0x80 }, /* r19 ADCB Mixer Volume */
83  { CS42L52_PCMA_MIXER_VOL, 0x00 }, /* r1A PCMA Mixer Volume */
84  { CS42L52_PCMB_MIXER_VOL, 0x00 }, /* r1B PCMB Mixer Volume */
85  { CS42L52_BEEP_FREQ, 0x00 }, /* r1C Beep Freq on Time */
86  { CS42L52_BEEP_VOL, 0x00 }, /* r1D Beep Volume off Time */
87  { CS42L52_BEEP_TONE_CTL, 0x00 }, /* r1E Beep Tone Cfg. */
88  { CS42L52_TONE_CTL, 0x00 }, /* r1F Tone Ctl */
89  { CS42L52_MASTERA_VOL, 0x88 }, /* r20 Master A Volume */
90  { CS42L52_MASTERB_VOL, 0x00 }, /* r21 Master B Volume */
91  { CS42L52_HPA_VOL, 0x00 }, /* r22 Headphone A Volume */
92  { CS42L52_HPB_VOL, 0x00 }, /* r23 Headphone B Volume */
93  { CS42L52_SPKA_VOL, 0x00 }, /* r24 Speaker A Volume */
94  { CS42L52_SPKB_VOL, 0x00 }, /* r25 Speaker B Volume */
95  { CS42L52_ADC_PCM_MIXER, 0x00 }, /* r26 Channel Mixer and Swap */
96  { CS42L52_LIMITER_CTL1, 0x00 }, /* r27 Limit Ctl 1 Thresholds */
97  { CS42L52_LIMITER_CTL2, 0x7F }, /* r28 Limit Ctl 2 Release Rate */
98  { CS42L52_LIMITER_AT_RATE, 0xC0 }, /* r29 Limiter Attack Rate */
99  { CS42L52_ALC_CTL, 0x00 }, /* r2A ALC Ctl 1 Attack Rate */
100  { CS42L52_ALC_RATE, 0x3F }, /* r2B ALC Release Rate */
101  { CS42L52_ALC_THRESHOLD, 0x3f }, /* r2C ALC Thresholds */
102  { CS42L52_NOISE_GATE_CTL, 0x00 }, /* r2D Noise Gate Ctl */
103  { CS42L52_CLK_STATUS, 0x00 }, /* r2E Overflow and Clock Status */
104  { CS42L52_BATT_COMPEN, 0x00 }, /* r2F battery Compensation */
105  { CS42L52_BATT_LEVEL, 0x00 }, /* r30 VP Battery Level */
106  { CS42L52_SPK_STATUS, 0x00 }, /* r31 Speaker Status */
107  { CS42L52_TEM_CTL, 0x3B }, /* r32 Temp Ctl */
108  { CS42L52_THE_FOLDBACK, 0x00 }, /* r33 Foldback */
109 };
110 
111 static bool cs42l52_readable_register(struct device *dev, unsigned int reg)
112 {
113  switch (reg) {
114  case CS42L52_CHIP:
115  case CS42L52_PWRCTL1:
116  case CS42L52_PWRCTL2:
117  case CS42L52_PWRCTL3:
118  case CS42L52_CLK_CTL:
119  case CS42L52_IFACE_CTL1:
120  case CS42L52_IFACE_CTL2:
121  case CS42L52_ADC_PGA_A:
122  case CS42L52_ADC_PGA_B:
126  case CS42L52_PB_CTL1:
127  case CS42L52_MISC_CTL:
128  case CS42L52_PB_CTL2:
129  case CS42L52_MICA_CTL:
130  case CS42L52_MICB_CTL:
131  case CS42L52_PGAA_CTL:
132  case CS42L52_PGAB_CTL:
135  case CS42L52_ADCA_VOL:
136  case CS42L52_ADCB_VOL:
141  case CS42L52_BEEP_FREQ:
142  case CS42L52_BEEP_VOL:
144  case CS42L52_TONE_CTL:
145  case CS42L52_MASTERA_VOL:
146  case CS42L52_MASTERB_VOL:
147  case CS42L52_HPA_VOL:
148  case CS42L52_HPB_VOL:
149  case CS42L52_SPKA_VOL:
150  case CS42L52_SPKB_VOL:
155  case CS42L52_ALC_CTL:
156  case CS42L52_ALC_RATE:
159  case CS42L52_CLK_STATUS:
160  case CS42L52_BATT_COMPEN:
161  case CS42L52_BATT_LEVEL:
162  case CS42L52_SPK_STATUS:
163  case CS42L52_TEM_CTL:
165  case CS42L52_CHARGE_PUMP:
166  return true;
167  default:
168  return false;
169  }
170 }
171 
172 static bool cs42l52_volatile_register(struct device *dev, unsigned int reg)
173 {
174  switch (reg) {
175  case CS42L52_IFACE_CTL2:
176  case CS42L52_CLK_STATUS:
177  case CS42L52_BATT_LEVEL:
178  case CS42L52_SPK_STATUS:
179  case CS42L52_CHARGE_PUMP:
180  return 1;
181  default:
182  return 0;
183  }
184 }
185 
186 static DECLARE_TLV_DB_SCALE(hl_tlv, -10200, 50, 0);
187 
188 static DECLARE_TLV_DB_SCALE(hpd_tlv, -9600, 50, 1);
189 
190 static DECLARE_TLV_DB_SCALE(ipd_tlv, -9600, 100, 0);
191 
192 static DECLARE_TLV_DB_SCALE(mic_tlv, 1600, 100, 0);
193 
194 static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
195 
196 static const unsigned int limiter_tlv[] = {
198  0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
199  3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0),
200 };
201 
202 static const char * const cs42l52_adca_text[] = {
203  "Input1A", "Input2A", "Input3A", "Input4A", "PGA Input Left"};
204 
205 static const char * const cs42l52_adcb_text[] = {
206  "Input1B", "Input2B", "Input3B", "Input4B", "PGA Input Right"};
207 
208 static const struct soc_enum adca_enum =
210  ARRAY_SIZE(cs42l52_adca_text), cs42l52_adca_text);
211 
212 static const struct soc_enum adcb_enum =
214  ARRAY_SIZE(cs42l52_adcb_text), cs42l52_adcb_text);
215 
216 static const struct snd_kcontrol_new adca_mux =
217  SOC_DAPM_ENUM("Left ADC Input Capture Mux", adca_enum);
218 
219 static const struct snd_kcontrol_new adcb_mux =
220  SOC_DAPM_ENUM("Right ADC Input Capture Mux", adcb_enum);
221 
222 static const char * const mic_bias_level_text[] = {
223  "0.5 +VA", "0.6 +VA", "0.7 +VA",
224  "0.8 +VA", "0.83 +VA", "0.91 +VA"
225 };
226 
227 static const struct soc_enum mic_bias_level_enum =
229  ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text);
230 
231 static const char * const cs42l52_mic_text[] = { "Single", "Differential" };
232 
233 static const struct soc_enum mica_enum =
235  ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text);
236 
237 static const struct soc_enum micb_enum =
239  ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text);
240 
241 static const struct snd_kcontrol_new mica_mux =
242  SOC_DAPM_ENUM("Left Mic Input Capture Mux", mica_enum);
243 
244 static const struct snd_kcontrol_new micb_mux =
245  SOC_DAPM_ENUM("Right Mic Input Capture Mux", micb_enum);
246 
247 static const char * const digital_output_mux_text[] = {"ADC", "DSP"};
248 
249 static const struct soc_enum digital_output_mux_enum =
251  ARRAY_SIZE(digital_output_mux_text),
252  digital_output_mux_text);
253 
254 static const struct snd_kcontrol_new digital_output_mux =
255  SOC_DAPM_ENUM("Digital Output Mux", digital_output_mux_enum);
256 
257 static const char * const hp_gain_num_text[] = {
258  "0.3959", "0.4571", "0.5111", "0.6047",
259  "0.7099", "0.8399", "1.000", "1.1430"
260 };
261 
262 static const struct soc_enum hp_gain_enum =
264  ARRAY_SIZE(hp_gain_num_text), hp_gain_num_text);
265 
266 static const char * const beep_pitch_text[] = {
267  "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5",
268  "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7"
269 };
270 
271 static const struct soc_enum beep_pitch_enum =
273  ARRAY_SIZE(beep_pitch_text), beep_pitch_text);
274 
275 static const char * const beep_ontime_text[] = {
276  "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s",
277  "1.80 s", "2.20 s", "2.50 s", "2.80 s", "3.20 s",
278  "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s"
279 };
280 
281 static const struct soc_enum beep_ontime_enum =
283  ARRAY_SIZE(beep_ontime_text), beep_ontime_text);
284 
285 static const char * const beep_offtime_text[] = {
286  "1.23 s", "2.58 s", "3.90 s", "5.20 s",
287  "6.60 s", "8.05 s", "9.35 s", "10.80 s"
288 };
289 
290 static const struct soc_enum beep_offtime_enum =
292  ARRAY_SIZE(beep_offtime_text), beep_offtime_text);
293 
294 static const char * const beep_config_text[] = {
295  "Off", "Single", "Multiple", "Continuous"
296 };
297 
298 static const struct soc_enum beep_config_enum =
300  ARRAY_SIZE(beep_config_text), beep_config_text);
301 
302 static const char * const beep_bass_text[] = {
303  "50 Hz", "100 Hz", "200 Hz", "250 Hz"
304 };
305 
306 static const struct soc_enum beep_bass_enum =
308  ARRAY_SIZE(beep_bass_text), beep_bass_text);
309 
310 static const char * const beep_treble_text[] = {
311  "5 kHz", "7 kHz", "10 kHz", " 15 kHz"
312 };
313 
314 static const struct soc_enum beep_treble_enum =
316  ARRAY_SIZE(beep_treble_text), beep_treble_text);
317 
318 static const char * const ng_threshold_text[] = {
319  "-34dB", "-37dB", "-40dB", "-43dB",
320  "-46dB", "-52dB", "-58dB", "-64dB"
321 };
322 
323 static const struct soc_enum ng_threshold_enum =
325  ARRAY_SIZE(ng_threshold_text), ng_threshold_text);
326 
327 static const char * const cs42l52_ng_delay_text[] = {
328  "50ms", "100ms", "150ms", "200ms"};
329 
330 static const struct soc_enum ng_delay_enum =
332  ARRAY_SIZE(cs42l52_ng_delay_text), cs42l52_ng_delay_text);
333 
334 static const char * const cs42l52_ng_type_text[] = {
335  "Apply Specific", "Apply All"
336 };
337 
338 static const struct soc_enum ng_type_enum =
340  ARRAY_SIZE(cs42l52_ng_type_text), cs42l52_ng_type_text);
341 
342 static const char * const left_swap_text[] = {
343  "Left", "LR 2", "Right"};
344 
345 static const char * const right_swap_text[] = {
346  "Right", "LR 2", "Left"};
347 
348 static const unsigned int swap_values[] = { 0, 1, 3 };
349 
350 static const struct soc_enum adca_swap_enum =
352  ARRAY_SIZE(left_swap_text),
353  left_swap_text,
354  swap_values);
355 
356 static const struct snd_kcontrol_new adca_mixer =
357  SOC_DAPM_ENUM("Route", adca_swap_enum);
358 
359 static const struct soc_enum pcma_swap_enum =
361  ARRAY_SIZE(left_swap_text),
362  left_swap_text,
363  swap_values);
364 
365 static const struct snd_kcontrol_new pcma_mixer =
366  SOC_DAPM_ENUM("Route", pcma_swap_enum);
367 
368 static const struct soc_enum adcb_swap_enum =
370  ARRAY_SIZE(right_swap_text),
371  right_swap_text,
372  swap_values);
373 
374 static const struct snd_kcontrol_new adcb_mixer =
375  SOC_DAPM_ENUM("Route", adcb_swap_enum);
376 
377 static const struct soc_enum pcmb_swap_enum =
379  ARRAY_SIZE(right_swap_text),
380  right_swap_text,
381  swap_values);
382 
383 static const struct snd_kcontrol_new pcmb_mixer =
384  SOC_DAPM_ENUM("Route", pcmb_swap_enum);
385 
386 
387 static const struct snd_kcontrol_new passthrul_ctl =
388  SOC_DAPM_SINGLE("Switch", CS42L52_MISC_CTL, 6, 1, 0);
389 
390 static const struct snd_kcontrol_new passthrur_ctl =
391  SOC_DAPM_SINGLE("Switch", CS42L52_MISC_CTL, 7, 1, 0);
392 
393 static const struct snd_kcontrol_new spkl_ctl =
394  SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 0, 1, 1);
395 
396 static const struct snd_kcontrol_new spkr_ctl =
397  SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 2, 1, 1);
398 
399 static const struct snd_kcontrol_new hpl_ctl =
400  SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 4, 1, 1);
401 
402 static const struct snd_kcontrol_new hpr_ctl =
403  SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 6, 1, 1);
404 
405 static const struct snd_kcontrol_new cs42l52_snd_controls[] = {
406 
407  SOC_DOUBLE_R_SX_TLV("Master Volume", CS42L52_MASTERA_VOL,
408  CS42L52_MASTERB_VOL, 0, 0x34, 0xE4, hl_tlv),
409 
410  SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L52_HPA_VOL,
411  CS42L52_HPB_VOL, 0, 0x34, 0xCC, hpd_tlv),
412 
413  SOC_ENUM("Headphone Analog Gain", hp_gain_enum),
414 
415  SOC_DOUBLE_R_SX_TLV("Speaker Volume", CS42L52_SPKA_VOL,
416  CS42L52_SPKB_VOL, 7, 0x1, 0xff, hl_tlv),
417 
419  CS42L52_PASSTHRUB_VOL, 6, 0x18, 0x90, pga_tlv),
420 
421  SOC_DOUBLE("Bypass Mute", CS42L52_MISC_CTL, 4, 5, 1, 0),
422 
423  SOC_DOUBLE_R_TLV("MIC Gain Volume", CS42L52_MICA_CTL,
424  CS42L52_MICB_CTL, 0, 0x10, 0, mic_tlv),
425 
426  SOC_ENUM("MIC Bias Level", mic_bias_level_enum),
427 
429  CS42L52_ADCB_VOL, 7, 0x80, 0xA0, ipd_tlv),
430  SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
432  6, 0x7f, 0x19, ipd_tlv),
433 
434  SOC_DOUBLE("ADC Switch", CS42L52_ADC_MISC_CTL, 0, 1, 1, 0),
435 
436  SOC_DOUBLE_R("ADC Mixer Switch", CS42L52_ADCA_MIXER_VOL,
437  CS42L52_ADCB_MIXER_VOL, 7, 1, 1),
438 
440  CS42L52_PGAB_CTL, 0, 0x28, 0x30, pga_tlv),
441 
442  SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume",
444  6, 0x7f, 0x19, hl_tlv),
445  SOC_DOUBLE_R("PCM Mixer Switch",
447 
448  SOC_ENUM("Beep Config", beep_config_enum),
449  SOC_ENUM("Beep Pitch", beep_pitch_enum),
450  SOC_ENUM("Beep on Time", beep_ontime_enum),
451  SOC_ENUM("Beep off Time", beep_offtime_enum),
452  SOC_SINGLE_TLV("Beep Volume", CS42L52_BEEP_VOL, 0, 0x1f, 0x07, hl_tlv),
453  SOC_SINGLE("Beep Mixer Switch", CS42L52_BEEP_TONE_CTL, 5, 1, 1),
454  SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum),
455  SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum),
456 
457  SOC_SINGLE("Tone Control Switch", CS42L52_BEEP_TONE_CTL, 0, 1, 1),
458  SOC_SINGLE_TLV("Treble Gain Volume",
459  CS42L52_TONE_CTL, 4, 15, 1, hl_tlv),
460  SOC_SINGLE_TLV("Bass Gain Volume",
461  CS42L52_TONE_CTL, 0, 15, 1, hl_tlv),
462 
463  /* Limiter */
464  SOC_SINGLE_TLV("Limiter Max Threshold Volume",
465  CS42L52_LIMITER_CTL1, 5, 7, 0, limiter_tlv),
466  SOC_SINGLE_TLV("Limiter Cushion Threshold Volume",
467  CS42L52_LIMITER_CTL1, 2, 7, 0, limiter_tlv),
468  SOC_SINGLE_TLV("Limiter Release Rate Volume",
469  CS42L52_LIMITER_CTL2, 0, 63, 0, limiter_tlv),
470  SOC_SINGLE_TLV("Limiter Attack Rate Volume",
471  CS42L52_LIMITER_AT_RATE, 0, 63, 0, limiter_tlv),
472 
473  SOC_SINGLE("Limiter SR Switch", CS42L52_LIMITER_CTL1, 1, 1, 0),
474  SOC_SINGLE("Limiter ZC Switch", CS42L52_LIMITER_CTL1, 0, 1, 0),
475  SOC_SINGLE("Limiter Switch", CS42L52_LIMITER_CTL2, 7, 1, 0),
476 
477  /* ALC */
478  SOC_SINGLE_TLV("ALC Attack Rate Volume", CS42L52_ALC_CTL,
479  0, 63, 0, limiter_tlv),
480  SOC_SINGLE_TLV("ALC Release Rate Volume", CS42L52_ALC_RATE,
481  0, 63, 0, limiter_tlv),
482  SOC_SINGLE_TLV("ALC Max Threshold Volume", CS42L52_ALC_THRESHOLD,
483  5, 7, 0, limiter_tlv),
484  SOC_SINGLE_TLV("ALC Min Threshold Volume", CS42L52_ALC_THRESHOLD,
485  2, 7, 0, limiter_tlv),
486 
487  SOC_DOUBLE_R("ALC SR Capture Switch", CS42L52_PGAA_CTL,
488  CS42L52_PGAB_CTL, 7, 1, 1),
489  SOC_DOUBLE_R("ALC ZC Capture Switch", CS42L52_PGAA_CTL,
490  CS42L52_PGAB_CTL, 6, 1, 1),
491  SOC_DOUBLE("ALC Capture Switch", CS42L52_ALC_CTL, 6, 7, 1, 0),
492 
493  /* Noise gate */
494  SOC_ENUM("NG Type Switch", ng_type_enum),
495  SOC_SINGLE("NG Enable Switch", CS42L52_NOISE_GATE_CTL, 6, 1, 0),
496  SOC_SINGLE("NG Boost Switch", CS42L52_NOISE_GATE_CTL, 5, 1, 1),
497  SOC_ENUM("NG Threshold", ng_threshold_enum),
498  SOC_ENUM("NG Delay", ng_delay_enum),
499 
500  SOC_DOUBLE("HPF Switch", CS42L52_ANALOG_HPF_CTL, 5, 7, 1, 0),
501 
502  SOC_DOUBLE("Analog SR Switch", CS42L52_ANALOG_HPF_CTL, 1, 3, 1, 1),
503  SOC_DOUBLE("Analog ZC Switch", CS42L52_ANALOG_HPF_CTL, 0, 2, 1, 1),
504  SOC_SINGLE("Digital SR Switch", CS42L52_MISC_CTL, 1, 1, 0),
505  SOC_SINGLE("Digital ZC Switch", CS42L52_MISC_CTL, 0, 1, 0),
506  SOC_SINGLE("Deemphasis Switch", CS42L52_MISC_CTL, 2, 1, 0),
507 
508  SOC_SINGLE("Batt Compensation Switch", CS42L52_BATT_COMPEN, 7, 1, 0),
509  SOC_SINGLE("Batt VP Monitor Switch", CS42L52_BATT_COMPEN, 6, 1, 0),
510  SOC_SINGLE("Batt VP ref", CS42L52_BATT_COMPEN, 0, 0x0f, 0),
511 
512  SOC_SINGLE("PGA AIN1L Switch", CS42L52_ADC_PGA_A, 0, 1, 0),
513  SOC_SINGLE("PGA AIN1R Switch", CS42L52_ADC_PGA_B, 0, 1, 0),
514  SOC_SINGLE("PGA AIN2L Switch", CS42L52_ADC_PGA_A, 1, 1, 0),
515  SOC_SINGLE("PGA AIN2R Switch", CS42L52_ADC_PGA_B, 1, 1, 0),
516 
517  SOC_SINGLE("PGA AIN3L Switch", CS42L52_ADC_PGA_A, 2, 1, 0),
518  SOC_SINGLE("PGA AIN3R Switch", CS42L52_ADC_PGA_B, 2, 1, 0),
519 
520  SOC_SINGLE("PGA AIN4L Switch", CS42L52_ADC_PGA_A, 3, 1, 0),
521  SOC_SINGLE("PGA AIN4R Switch", CS42L52_ADC_PGA_B, 3, 1, 0),
522 
523  SOC_SINGLE("PGA MICA Switch", CS42L52_ADC_PGA_A, 4, 1, 0),
524  SOC_SINGLE("PGA MICB Switch", CS42L52_ADC_PGA_B, 4, 1, 0),
525 
526 };
527 
528 static const struct snd_soc_dapm_widget cs42l52_dapm_widgets[] = {
529 
530  SND_SOC_DAPM_INPUT("AIN1L"),
531  SND_SOC_DAPM_INPUT("AIN1R"),
532  SND_SOC_DAPM_INPUT("AIN2L"),
533  SND_SOC_DAPM_INPUT("AIN2R"),
534  SND_SOC_DAPM_INPUT("AIN3L"),
535  SND_SOC_DAPM_INPUT("AIN3R"),
536  SND_SOC_DAPM_INPUT("AIN4L"),
537  SND_SOC_DAPM_INPUT("AIN4R"),
538  SND_SOC_DAPM_INPUT("MICA"),
539  SND_SOC_DAPM_INPUT("MICB"),
540  SND_SOC_DAPM_SIGGEN("Beep"),
541 
542  SND_SOC_DAPM_AIF_OUT("AIFOUTL", NULL, 0,
543  SND_SOC_NOPM, 0, 0),
544  SND_SOC_DAPM_AIF_OUT("AIFOUTR", NULL, 0,
545  SND_SOC_NOPM, 0, 0),
546 
547  SND_SOC_DAPM_MUX("MICA Mux", SND_SOC_NOPM, 0, 0, &mica_mux),
548  SND_SOC_DAPM_MUX("MICB Mux", SND_SOC_NOPM, 0, 0, &micb_mux),
549 
550  SND_SOC_DAPM_ADC("ADC Left", NULL, CS42L52_PWRCTL1, 1, 1),
551  SND_SOC_DAPM_ADC("ADC Right", NULL, CS42L52_PWRCTL1, 2, 1),
552  SND_SOC_DAPM_PGA("PGA Left", CS42L52_PWRCTL1, 3, 1, NULL, 0),
553  SND_SOC_DAPM_PGA("PGA Right", CS42L52_PWRCTL1, 4, 1, NULL, 0),
554 
555  SND_SOC_DAPM_MUX("ADC Left Mux", SND_SOC_NOPM, 0, 0, &adca_mux),
556  SND_SOC_DAPM_MUX("ADC Right Mux", SND_SOC_NOPM, 0, 0, &adcb_mux),
557 
558  SND_SOC_DAPM_MUX("ADC Left Swap", SND_SOC_NOPM,
559  0, 0, &adca_mixer),
560  SND_SOC_DAPM_MUX("ADC Right Swap", SND_SOC_NOPM,
561  0, 0, &adcb_mixer),
562 
563  SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM,
564  0, 0, &digital_output_mux),
565 
566  SND_SOC_DAPM_PGA("PGA MICA", CS42L52_PWRCTL2, 1, 1, NULL, 0),
567  SND_SOC_DAPM_PGA("PGA MICB", CS42L52_PWRCTL2, 2, 1, NULL, 0),
568 
569  SND_SOC_DAPM_SUPPLY("Mic Bias", CS42L52_PWRCTL2, 0, 1, NULL, 0),
570  SND_SOC_DAPM_SUPPLY("Charge Pump", CS42L52_PWRCTL1, 7, 1, NULL, 0),
571 
572  SND_SOC_DAPM_AIF_IN("AIFINL", NULL, 0,
573  SND_SOC_NOPM, 0, 0),
574  SND_SOC_DAPM_AIF_IN("AIFINR", NULL, 0,
575  SND_SOC_NOPM, 0, 0),
576 
577  SND_SOC_DAPM_DAC("DAC Left", NULL, SND_SOC_NOPM, 0, 0),
578  SND_SOC_DAPM_DAC("DAC Right", NULL, SND_SOC_NOPM, 0, 0),
579 
580  SND_SOC_DAPM_SWITCH("Bypass Left", CS42L52_MISC_CTL,
581  6, 0, &passthrul_ctl),
582  SND_SOC_DAPM_SWITCH("Bypass Right", CS42L52_MISC_CTL,
583  7, 0, &passthrur_ctl),
584 
585  SND_SOC_DAPM_MUX("PCM Left Swap", SND_SOC_NOPM,
586  0, 0, &pcma_mixer),
587  SND_SOC_DAPM_MUX("PCM Right Swap", SND_SOC_NOPM,
588  0, 0, &pcmb_mixer),
589 
590  SND_SOC_DAPM_SWITCH("HP Left Amp", SND_SOC_NOPM, 0, 0, &hpl_ctl),
591  SND_SOC_DAPM_SWITCH("HP Right Amp", SND_SOC_NOPM, 0, 0, &hpr_ctl),
592 
593  SND_SOC_DAPM_SWITCH("SPK Left Amp", SND_SOC_NOPM, 0, 0, &spkl_ctl),
594  SND_SOC_DAPM_SWITCH("SPK Right Amp", SND_SOC_NOPM, 0, 0, &spkr_ctl),
595 
596  SND_SOC_DAPM_OUTPUT("HPOUTA"),
597  SND_SOC_DAPM_OUTPUT("HPOUTB"),
598  SND_SOC_DAPM_OUTPUT("SPKOUTA"),
599  SND_SOC_DAPM_OUTPUT("SPKOUTB"),
600 
601 };
602 
603 static const struct snd_soc_dapm_route cs42l52_audio_map[] = {
604 
605  {"Capture", NULL, "AIFOUTL"},
606  {"Capture", NULL, "AIFOUTL"},
607 
608  {"AIFOUTL", NULL, "Output Mux"},
609  {"AIFOUTR", NULL, "Output Mux"},
610 
611  {"Output Mux", "ADC", "ADC Left"},
612  {"Output Mux", "ADC", "ADC Right"},
613 
614  {"ADC Left", NULL, "Charge Pump"},
615  {"ADC Right", NULL, "Charge Pump"},
616 
617  {"Charge Pump", NULL, "ADC Left Mux"},
618  {"Charge Pump", NULL, "ADC Right Mux"},
619 
620  {"ADC Left Mux", "Input1A", "AIN1L"},
621  {"ADC Right Mux", "Input1B", "AIN1R"},
622  {"ADC Left Mux", "Input2A", "AIN2L"},
623  {"ADC Right Mux", "Input2B", "AIN2R"},
624  {"ADC Left Mux", "Input3A", "AIN3L"},
625  {"ADC Right Mux", "Input3B", "AIN3R"},
626  {"ADC Left Mux", "Input4A", "AIN4L"},
627  {"ADC Right Mux", "Input4B", "AIN4R"},
628  {"ADC Left Mux", "PGA Input Left", "PGA Left"},
629  {"ADC Right Mux", "PGA Input Right" , "PGA Right"},
630 
631  {"PGA Left", "Switch", "AIN1L"},
632  {"PGA Right", "Switch", "AIN1R"},
633  {"PGA Left", "Switch", "AIN2L"},
634  {"PGA Right", "Switch", "AIN2R"},
635  {"PGA Left", "Switch", "AIN3L"},
636  {"PGA Right", "Switch", "AIN3R"},
637  {"PGA Left", "Switch", "AIN4L"},
638  {"PGA Right", "Switch", "AIN4R"},
639 
640  {"PGA Left", "Switch", "PGA MICA"},
641  {"PGA MICA", NULL, "MICA"},
642 
643  {"PGA Right", "Switch", "PGA MICB"},
644  {"PGA MICB", NULL, "MICB"},
645 
646  {"HPOUTA", NULL, "HP Left Amp"},
647  {"HPOUTB", NULL, "HP Right Amp"},
648  {"HP Left Amp", NULL, "Bypass Left"},
649  {"HP Right Amp", NULL, "Bypass Right"},
650  {"Bypass Left", "Switch", "PGA Left"},
651  {"Bypass Right", "Switch", "PGA Right"},
652  {"HP Left Amp", "Switch", "DAC Left"},
653  {"HP Right Amp", "Switch", "DAC Right"},
654 
655  {"SPKOUTA", NULL, "SPK Left Amp"},
656  {"SPKOUTB", NULL, "SPK Right Amp"},
657 
658  {"SPK Left Amp", NULL, "Beep"},
659  {"SPK Right Amp", NULL, "Beep"},
660  {"SPK Left Amp", "Switch", "Playback"},
661  {"SPK Right Amp", "Switch", "Playback"},
662 
663  {"DAC Left", NULL, "Beep"},
664  {"DAC Right", NULL, "Beep"},
665  {"DAC Left", NULL, "Playback"},
666  {"DAC Right", NULL, "Playback"},
667 
668  {"Output Mux", "DSP", "Playback"},
669  {"Output Mux", "DSP", "Playback"},
670 
671  {"AIFINL", NULL, "Playback"},
672  {"AIFINR", NULL, "Playback"},
673 
674 };
675 
684 };
685 
686 static const struct cs42l52_clk_para clk_map_table[] = {
687  /*8k*/
688  {12288000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
689  {18432000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
690  {12000000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 0},
691  {24000000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 1},
692  {27000000, 8000, CLK_QS_MODE, CLK_32K, CLK_27M_MCLK, CLK_R_125, 0},
693 
694  /*11.025k*/
695  {11289600, 11025, CLK_QS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
696  {16934400, 11025, CLK_QS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
697 
698  /*16k*/
699  {12288000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
700  {18432000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
701  {12000000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 0},
702  {24000000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 1},
703  {27000000, 16000, CLK_HS_MODE, CLK_32K, CLK_27M_MCLK, CLK_R_125, 1},
704 
705  /*22.05k*/
706  {11289600, 22050, CLK_HS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
707  {16934400, 22050, CLK_HS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
708 
709  /* 32k */
710  {12288000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
711  {18432000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
712  {12000000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 0},
713  {24000000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 1},
714  {27000000, 32000, CLK_SS_MODE, CLK_32K, CLK_27M_MCLK, CLK_R_125, 0},
715 
716  /* 44.1k */
717  {11289600, 44100, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
718  {16934400, 44100, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
719 
720  /* 48k */
721  {12288000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
722  {18432000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
723  {12000000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 0},
724  {24000000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 1},
725  {27000000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_27M_MCLK, CLK_R_125, 1},
726 
727  /* 88.2k */
728  {11289600, 88200, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
729  {16934400, 88200, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
730 
731  /* 96k */
732  {12288000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
733  {18432000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
734  {12000000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 0},
735  {24000000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 1},
736 };
737 
738 static int cs42l52_get_clk(int mclk, int rate)
739 {
740  int i, ret = 0;
741  u_int mclk1, mclk2 = 0;
742 
743  for (i = 0; i < ARRAY_SIZE(clk_map_table); i++) {
744  if (clk_map_table[i].rate == rate) {
745  mclk1 = clk_map_table[i].mclk;
746  if (abs(mclk - mclk1) < abs(mclk - mclk2)) {
747  mclk2 = mclk1;
748  ret = i;
749  }
750  }
751  }
752  if (ret > ARRAY_SIZE(clk_map_table))
753  return -EINVAL;
754  return ret;
755 }
756 
757 static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai,
758  int clk_id, unsigned int freq, int dir)
759 {
760  struct snd_soc_codec *codec = codec_dai->codec;
761  struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
762 
763  if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) {
764  cs42l52->sysclk = freq;
765  } else {
766  dev_err(codec->dev, "Invalid freq parameter\n");
767  return -EINVAL;
768  }
769  return 0;
770 }
771 
772 static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
773 {
774  struct snd_soc_codec *codec = codec_dai->codec;
775  struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
776  u8 iface = 0;
777 
778  switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
781  break;
783  iface = CS42L52_IFACE_CTL1_SLAVE;
784  break;
785  default:
786  return -EINVAL;
787  }
788 
789  /* interface format */
790  switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
791  case SND_SOC_DAIFMT_I2S:
794  break;
797  break;
801  break;
804  break;
806  break;
807  default:
808  return -EINVAL;
809  }
810 
811  /* clock inversion */
812  switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
814  break;
817  break;
820  break;
822  break;
823  default:
824  return -EINVAL;
825  }
826  cs42l52->config.format = iface;
827  snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format);
828 
829  return 0;
830 }
831 
832 static int cs42l52_digital_mute(struct snd_soc_dai *dai, int mute)
833 {
834  struct snd_soc_codec *codec = dai->codec;
835 
836  if (mute)
840  else
844 
845  return 0;
846 }
847 
848 static int cs42l52_pcm_hw_params(struct snd_pcm_substream *substream,
849  struct snd_pcm_hw_params *params,
850  struct snd_soc_dai *dai)
851 {
852  struct snd_soc_codec *codec = dai->codec;
853  struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
854  u32 clk = 0;
855  int index;
856 
857  index = cs42l52_get_clk(cs42l52->sysclk, params_rate(params));
858  if (index >= 0) {
859  cs42l52->sysclk = clk_map_table[index].mclk;
860 
861  clk |= (clk_map_table[index].speed << CLK_SPEED_SHIFT) |
862  (clk_map_table[index].group << CLK_32K_SR_SHIFT) |
863  (clk_map_table[index].videoclk << CLK_27M_MCLK_SHIFT) |
864  (clk_map_table[index].ratio << CLK_RATIO_SHIFT) |
865  clk_map_table[index].mclkdiv2;
866 
867  snd_soc_write(codec, CS42L52_CLK_CTL, clk);
868  } else {
869  dev_err(codec->dev, "can't get correct mclk\n");
870  return -EINVAL;
871  }
872 
873  return 0;
874 }
875 
876 static int cs42l52_set_bias_level(struct snd_soc_codec *codec,
878 {
879  struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
880 
881  switch (level) {
882  case SND_SOC_BIAS_ON:
883  break;
887  break;
889  if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
890  regcache_cache_only(cs42l52->regmap, false);
891  regcache_sync(cs42l52->regmap);
892  }
894  break;
895  case SND_SOC_BIAS_OFF:
897  regcache_cache_only(cs42l52->regmap, true);
898  break;
899  }
900  codec->dapm.bias_level = level;
901 
902  return 0;
903 }
904 
905 #define CS42L52_RATES (SNDRV_PCM_RATE_8000_96000)
906 
907 #define CS42L52_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
908  SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE | \
909  SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
910  SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE)
911 
912 static struct snd_soc_dai_ops cs42l52_ops = {
913  .hw_params = cs42l52_pcm_hw_params,
914  .digital_mute = cs42l52_digital_mute,
915  .set_fmt = cs42l52_set_fmt,
916  .set_sysclk = cs42l52_set_sysclk,
917 };
918 
919 static struct snd_soc_dai_driver cs42l52_dai = {
920  .name = "cs42l52",
921  .playback = {
922  .stream_name = "Playback",
923  .channels_min = 1,
924  .channels_max = 2,
925  .rates = CS42L52_RATES,
926  .formats = CS42L52_FORMATS,
927  },
928  .capture = {
929  .stream_name = "Capture",
930  .channels_min = 1,
931  .channels_max = 2,
932  .rates = CS42L52_RATES,
933  .formats = CS42L52_FORMATS,
934  },
935  .ops = &cs42l52_ops,
936 };
937 
938 static int cs42l52_suspend(struct snd_soc_codec *codec)
939 {
940  cs42l52_set_bias_level(codec, SND_SOC_BIAS_OFF);
941 
942  return 0;
943 }
944 
945 static int cs42l52_resume(struct snd_soc_codec *codec)
946 {
947  cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
948 
949  return 0;
950 }
951 
952 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
953 static int beep_rates[] = {
954  261, 522, 585, 667, 706, 774, 889, 1000,
955  1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
956 };
957 
958 static void cs42l52_beep_work(struct work_struct *work)
959 {
960  struct cs42l52_private *cs42l52 =
961  container_of(work, struct cs42l52_private, beep_work);
962  struct snd_soc_codec *codec = cs42l52->codec;
963  struct snd_soc_dapm_context *dapm = &codec->dapm;
964  int i;
965  int val = 0;
966  int best = 0;
967 
968  if (cs42l52->beep_rate) {
969  for (i = 0; i < ARRAY_SIZE(beep_rates); i++) {
970  if (abs(cs42l52->beep_rate - beep_rates[i]) <
971  abs(cs42l52->beep_rate - beep_rates[best]))
972  best = i;
973  }
974 
975  dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n",
976  beep_rates[best], cs42l52->beep_rate);
977 
978  val = (best << CS42L52_BEEP_RATE_SHIFT);
979 
980  snd_soc_dapm_enable_pin(dapm, "Beep");
981  } else {
982  dev_dbg(codec->dev, "Disabling beep\n");
983  snd_soc_dapm_disable_pin(dapm, "Beep");
984  }
985 
988 
989  snd_soc_dapm_sync(dapm);
990 }
991 
992 /* For usability define a way of injecting beep events for the device -
993  * many systems will not have a keyboard.
994  */
995 static int cs42l52_beep_event(struct input_dev *dev, unsigned int type,
996  unsigned int code, int hz)
997 {
998  struct snd_soc_codec *codec = input_get_drvdata(dev);
999  struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
1000 
1001  dev_dbg(codec->dev, "Beep event %x %x\n", code, hz);
1002 
1003  switch (code) {
1004  case SND_BELL:
1005  if (hz)
1006  hz = 261;
1007  case SND_TONE:
1008  break;
1009  default:
1010  return -1;
1011  }
1012 
1013  /* Kick the beep from a workqueue */
1014  cs42l52->beep_rate = hz;
1015  schedule_work(&cs42l52->beep_work);
1016  return 0;
1017 }
1018 
1019 static ssize_t cs42l52_beep_set(struct device *dev,
1020  struct device_attribute *attr,
1021  const char *buf, size_t count)
1022 {
1023  struct cs42l52_private *cs42l52 = dev_get_drvdata(dev);
1024  long int time;
1025  int ret;
1026 
1027  ret = kstrtol(buf, 10, &time);
1028  if (ret != 0)
1029  return ret;
1030 
1031  input_event(cs42l52->beep, EV_SND, SND_TONE, time);
1032 
1033  return count;
1034 }
1035 
1036 static DEVICE_ATTR(beep, 0200, NULL, cs42l52_beep_set);
1037 
1038 static void cs42l52_init_beep(struct snd_soc_codec *codec)
1039 {
1040  struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
1041  int ret;
1042 
1043  cs42l52->beep = input_allocate_device();
1044  if (!cs42l52->beep) {
1045  dev_err(codec->dev, "Failed to allocate beep device\n");
1046  return;
1047  }
1048 
1049  INIT_WORK(&cs42l52->beep_work, cs42l52_beep_work);
1050  cs42l52->beep_rate = 0;
1051 
1052  cs42l52->beep->name = "CS42L52 Beep Generator";
1053  cs42l52->beep->phys = dev_name(codec->dev);
1054  cs42l52->beep->id.bustype = BUS_I2C;
1055 
1056  cs42l52->beep->evbit[0] = BIT_MASK(EV_SND);
1057  cs42l52->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
1058  cs42l52->beep->event = cs42l52_beep_event;
1059  cs42l52->beep->dev.parent = codec->dev;
1060  input_set_drvdata(cs42l52->beep, codec);
1061 
1062  ret = input_register_device(cs42l52->beep);
1063  if (ret != 0) {
1064  input_free_device(cs42l52->beep);
1065  cs42l52->beep = NULL;
1066  dev_err(codec->dev, "Failed to register beep device\n");
1067  }
1068 
1069  ret = device_create_file(codec->dev, &dev_attr_beep);
1070  if (ret != 0) {
1071  dev_err(codec->dev, "Failed to create keyclick file: %d\n",
1072  ret);
1073  }
1074 }
1075 
1076 static void cs42l52_free_beep(struct snd_soc_codec *codec)
1077 {
1078  struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
1079 
1080  device_remove_file(codec->dev, &dev_attr_beep);
1081  input_unregister_device(cs42l52->beep);
1082  cancel_work_sync(&cs42l52->beep_work);
1083  cs42l52->beep = NULL;
1084 
1087 }
1088 #else
1089 static void cs42l52_init_beep(struct snd_soc_codec *codec)
1090 {
1091 }
1092 
1093 static void cs42l52_free_beep(struct snd_soc_codec *codec)
1094 {
1095 }
1096 #endif
1097 
1098 static int cs42l52_probe(struct snd_soc_codec *codec)
1099 {
1100  struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
1101  int ret;
1102 
1103  codec->control_data = cs42l52->regmap;
1104  ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
1105  if (ret < 0) {
1106  dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1107  return ret;
1108  }
1109  regcache_cache_only(cs42l52->regmap, true);
1110 
1111  cs42l52_init_beep(codec);
1112 
1113  cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1114 
1115  cs42l52->sysclk = CS42L52_DEFAULT_CLK;
1116  cs42l52->config.format = CS42L52_DEFAULT_FORMAT;
1117 
1118  /* Set Platform MICx CFG */
1121  cs42l52->pdata.mica_cfg <<
1123 
1126  cs42l52->pdata.micb_cfg <<
1128 
1129  /* if Single Ended, Get Mic_Select */
1130  if (cs42l52->pdata.mica_cfg)
1133  cs42l52->pdata.mica_sel <<
1135  if (cs42l52->pdata.micb_cfg)
1138  cs42l52->pdata.micb_sel <<
1140 
1141  /* Set Platform Charge Pump Freq */
1144  cs42l52->pdata.chgfreq <<
1146 
1147  /* Set Platform Bias Level */
1150  cs42l52->pdata.micbias_lvl);
1151 
1152  return ret;
1153 }
1154 
1155 static int cs42l52_remove(struct snd_soc_codec *codec)
1156 {
1157  cs42l52_free_beep(codec);
1158  cs42l52_set_bias_level(codec, SND_SOC_BIAS_OFF);
1159 
1160  return 0;
1161 }
1162 
1163 static struct snd_soc_codec_driver soc_codec_dev_cs42l52 = {
1164  .probe = cs42l52_probe,
1165  .remove = cs42l52_remove,
1166  .suspend = cs42l52_suspend,
1167  .resume = cs42l52_resume,
1168  .set_bias_level = cs42l52_set_bias_level,
1169 
1170  .dapm_widgets = cs42l52_dapm_widgets,
1171  .num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets),
1172  .dapm_routes = cs42l52_audio_map,
1173  .num_dapm_routes = ARRAY_SIZE(cs42l52_audio_map),
1174 
1175  .controls = cs42l52_snd_controls,
1176  .num_controls = ARRAY_SIZE(cs42l52_snd_controls),
1177 };
1178 
1179 /* Current and threshold powerup sequence Pg37 */
1180 static const struct reg_default cs42l52_threshold_patch[] = {
1181 
1182  { 0x00, 0x99 },
1183  { 0x3E, 0xBA },
1184  { 0x47, 0x80 },
1185  { 0x32, 0xBB },
1186  { 0x32, 0x3B },
1187  { 0x00, 0x00 },
1188 
1189 };
1190 
1191 static struct regmap_config cs42l52_regmap = {
1192  .reg_bits = 8,
1193  .val_bits = 8,
1194 
1195  .max_register = CS42L52_MAX_REGISTER,
1196  .reg_defaults = cs42l52_reg_defaults,
1197  .num_reg_defaults = ARRAY_SIZE(cs42l52_reg_defaults),
1198  .readable_reg = cs42l52_readable_register,
1199  .volatile_reg = cs42l52_volatile_register,
1200  .cache_type = REGCACHE_RBTREE,
1201 };
1202 
1203 static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
1204  const struct i2c_device_id *id)
1205 {
1206  struct cs42l52_private *cs42l52;
1207  int ret;
1208  unsigned int devid = 0;
1209  unsigned int reg;
1210 
1211  cs42l52 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l52_private),
1212  GFP_KERNEL);
1213  if (cs42l52 == NULL)
1214  return -ENOMEM;
1215  cs42l52->dev = &i2c_client->dev;
1216 
1217  cs42l52->regmap = devm_regmap_init_i2c(i2c_client, &cs42l52_regmap);
1218  if (IS_ERR(cs42l52->regmap)) {
1219  ret = PTR_ERR(cs42l52->regmap);
1220  dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1221  return ret;
1222  }
1223 
1224  i2c_set_clientdata(i2c_client, cs42l52);
1225 
1226  if (dev_get_platdata(&i2c_client->dev))
1227  memcpy(&cs42l52->pdata, dev_get_platdata(&i2c_client->dev),
1228  sizeof(cs42l52->pdata));
1229 
1230  ret = regmap_register_patch(cs42l52->regmap, cs42l52_threshold_patch,
1231  ARRAY_SIZE(cs42l52_threshold_patch));
1232  if (ret != 0)
1233  dev_warn(cs42l52->dev, "Failed to apply regmap patch: %d\n",
1234  ret);
1235 
1236  ret = regmap_read(cs42l52->regmap, CS42L52_CHIP, &reg);
1237  devid = reg & CS42L52_CHIP_ID_MASK;
1238  if (devid != CS42L52_CHIP_ID) {
1239  ret = -ENODEV;
1240  dev_err(&i2c_client->dev,
1241  "CS42L52 Device ID (%X). Expected %X\n",
1242  devid, CS42L52_CHIP_ID);
1243  return ret;
1244  }
1245 
1246  regcache_cache_only(cs42l52->regmap, true);
1247 
1248  ret = snd_soc_register_codec(&i2c_client->dev,
1249  &soc_codec_dev_cs42l52, &cs42l52_dai, 1);
1250  if (ret < 0)
1251  return ret;
1252  return 0;
1253 }
1254 
1255 static int cs42l52_i2c_remove(struct i2c_client *client)
1256 {
1257  snd_soc_unregister_codec(&client->dev);
1258  return 0;
1259 }
1260 
1261 static const struct i2c_device_id cs42l52_id[] = {
1262  { "cs42l52", 0 },
1263  { }
1264 };
1265 MODULE_DEVICE_TABLE(i2c, cs42l52_id);
1266 
1267 static struct i2c_driver cs42l52_i2c_driver = {
1268  .driver = {
1269  .name = "cs42l52",
1270  .owner = THIS_MODULE,
1271  },
1272  .id_table = cs42l52_id,
1273  .probe = cs42l52_i2c_probe,
1274  .remove = __devexit_p(cs42l52_i2c_remove),
1275 };
1276 
1277 module_i2c_driver(cs42l52_i2c_driver);
1278 
1279 MODULE_DESCRIPTION("ASoC CS42L52 driver");
1280 MODULE_AUTHOR("Georgi Vlaev, Nucleus Systems Ltd, <[email protected]>");
1281 MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <[email protected]>");
1282 MODULE_LICENSE("GPL");