ASoC: sigmadsp: uninitialized variable in sigmadsp_activate_ctrl()
[firefly-linux-kernel-4.4.55.git] / sound / soc / codecs / cs4265.c
1 /*
2  * cs4265.c -- CS4265 ALSA SoC audio driver
3  *
4  * Copyright 2014 Cirrus Logic, Inc.
5  *
6  * Author: Paul Handrigan <paul.handrigan@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/gpio/consumer.h>
18 #include <linux/init.h>
19 #include <linux/delay.h>
20 #include <linux/i2c.h>
21 #include <linux/input.h>
22 #include <linux/regmap.h>
23 #include <linux/slab.h>
24 #include <linux/platform_device.h>
25 #include <sound/core.h>
26 #include <sound/pcm.h>
27 #include <sound/pcm_params.h>
28 #include <sound/soc.h>
29 #include <sound/soc-dapm.h>
30 #include <sound/initval.h>
31 #include <sound/tlv.h>
32 #include "cs4265.h"
33
34 struct cs4265_private {
35         struct device *dev;
36         struct regmap *regmap;
37         struct gpio_desc *reset_gpio;
38         u8 format;
39         u32 sysclk;
40 };
41
42 static const struct reg_default cs4265_reg_defaults[] = {
43         { CS4265_PWRCTL, 0x0F },
44         { CS4265_DAC_CTL, 0x08 },
45         { CS4265_ADC_CTL, 0x00 },
46         { CS4265_MCLK_FREQ, 0x00 },
47         { CS4265_SIG_SEL, 0x40 },
48         { CS4265_CHB_PGA_CTL, 0x00 },
49         { CS4265_CHA_PGA_CTL, 0x00 },
50         { CS4265_ADC_CTL2, 0x19 },
51         { CS4265_DAC_CHA_VOL, 0x00 },
52         { CS4265_DAC_CHB_VOL, 0x00 },
53         { CS4265_DAC_CTL2, 0xC0 },
54         { CS4265_SPDIF_CTL1, 0x00 },
55         { CS4265_SPDIF_CTL2, 0x00 },
56         { CS4265_INT_MASK, 0x00 },
57         { CS4265_STATUS_MODE_MSB, 0x00 },
58         { CS4265_STATUS_MODE_LSB, 0x00 },
59 };
60
61 static bool cs4265_readable_register(struct device *dev, unsigned int reg)
62 {
63         switch (reg) {
64         case CS4265_PWRCTL:
65         case CS4265_DAC_CTL:
66         case CS4265_ADC_CTL:
67         case CS4265_MCLK_FREQ:
68         case CS4265_SIG_SEL:
69         case CS4265_CHB_PGA_CTL:
70         case CS4265_CHA_PGA_CTL:
71         case CS4265_ADC_CTL2:
72         case CS4265_DAC_CHA_VOL:
73         case CS4265_DAC_CHB_VOL:
74         case CS4265_DAC_CTL2:
75         case CS4265_SPDIF_CTL1:
76         case CS4265_SPDIF_CTL2:
77         case CS4265_INT_MASK:
78         case CS4265_STATUS_MODE_MSB:
79         case CS4265_STATUS_MODE_LSB:
80         case CS4265_CHIP_ID:
81                 return true;
82         default:
83                 return false;
84         }
85 }
86
87 static bool cs4265_volatile_register(struct device *dev, unsigned int reg)
88 {
89         switch (reg) {
90         case CS4265_INT_STATUS:
91                 return true;
92         default:
93                 return false;
94         }
95 }
96
97 static DECLARE_TLV_DB_SCALE(pga_tlv, -1200, 50, 0);
98
99 static DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 0);
100
101 static const char * const digital_input_mux_text[] = {
102         "SDIN1", "SDIN2"
103 };
104
105 static SOC_ENUM_SINGLE_DECL(digital_input_mux_enum, CS4265_SIG_SEL, 7,
106                 digital_input_mux_text);
107
108 static const struct snd_kcontrol_new digital_input_mux =
109         SOC_DAPM_ENUM("Digital Input Mux", digital_input_mux_enum);
110
111 static const char * const mic_linein_text[] = {
112         "MIC", "LINEIN"
113 };
114
115 static SOC_ENUM_SINGLE_DECL(mic_linein_enum, CS4265_ADC_CTL2, 0,
116                 mic_linein_text);
117
118 static const char * const cam_mode_text[] = {
119         "One Byte", "Two Byte"
120 };
121
122 static SOC_ENUM_SINGLE_DECL(cam_mode_enum, CS4265_SPDIF_CTL1, 5,
123                 cam_mode_text);
124
125 static const char * const cam_mono_stereo_text[] = {
126         "Stereo", "Mono"
127 };
128
129 static SOC_ENUM_SINGLE_DECL(spdif_mono_stereo_enum, CS4265_SPDIF_CTL2, 2,
130                 cam_mono_stereo_text);
131
132 static const char * const mono_select_text[] = {
133         "Channel A", "Channel B"
134 };
135
136 static SOC_ENUM_SINGLE_DECL(spdif_mono_select_enum, CS4265_SPDIF_CTL2, 0,
137                 mono_select_text);
138
139 static const struct snd_kcontrol_new mic_linein_mux =
140         SOC_DAPM_ENUM("ADC Input Capture Mux", mic_linein_enum);
141
142 static const struct snd_kcontrol_new loopback_ctl =
143         SOC_DAPM_SINGLE("Switch", CS4265_SIG_SEL, 1, 1, 0);
144
145 static const struct snd_kcontrol_new spdif_switch =
146         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 0, 0);
147
148 static const struct snd_kcontrol_new dac_switch =
149         SOC_DAPM_SINGLE("Switch", CS4265_PWRCTL, 1, 1, 0);
150
151 static const struct snd_kcontrol_new cs4265_snd_controls[] = {
152
153         SOC_DOUBLE_R_SX_TLV("PGA Volume", CS4265_CHA_PGA_CTL,
154                               CS4265_CHB_PGA_CTL, 0, 0x28, 0x30, pga_tlv),
155         SOC_DOUBLE_R_TLV("DAC Volume", CS4265_DAC_CHA_VOL,
156                       CS4265_DAC_CHB_VOL, 0, 0xFF, 1, dac_tlv),
157         SOC_SINGLE("De-emp 44.1kHz Switch", CS4265_DAC_CTL, 1,
158                                 1, 0),
159         SOC_SINGLE("DAC INV Switch", CS4265_DAC_CTL2, 5,
160                                 1, 0),
161         SOC_SINGLE("DAC Zero Cross Switch", CS4265_DAC_CTL2, 6,
162                                 1, 0),
163         SOC_SINGLE("DAC Soft Ramp Switch", CS4265_DAC_CTL2, 7,
164                                 1, 0),
165         SOC_SINGLE("ADC HPF Switch", CS4265_ADC_CTL, 1,
166                                 1, 0),
167         SOC_SINGLE("ADC Zero Cross Switch", CS4265_ADC_CTL2, 3,
168                                 1, 1),
169         SOC_SINGLE("ADC Soft Ramp Switch", CS4265_ADC_CTL2, 7,
170                                 1, 0),
171         SOC_SINGLE("E to F Buffer Disable Switch", CS4265_SPDIF_CTL1,
172                                 6, 1, 0),
173         SOC_ENUM("C Data Access", cam_mode_enum),
174         SOC_SINGLE("Validity Bit Control Switch", CS4265_SPDIF_CTL2,
175                                 3, 1, 0),
176         SOC_ENUM("SPDIF Mono/Stereo", spdif_mono_stereo_enum),
177         SOC_SINGLE("MMTLR Data Switch", 0,
178                                 1, 1, 0),
179         SOC_ENUM("Mono Channel Select", spdif_mono_select_enum),
180         SND_SOC_BYTES("C Data Buffer", CS4265_C_DATA_BUFF, 24),
181 };
182
183 static const struct snd_soc_dapm_widget cs4265_dapm_widgets[] = {
184
185         SND_SOC_DAPM_INPUT("LINEINL"),
186         SND_SOC_DAPM_INPUT("LINEINR"),
187         SND_SOC_DAPM_INPUT("MICL"),
188         SND_SOC_DAPM_INPUT("MICR"),
189
190         SND_SOC_DAPM_AIF_OUT("DOUT", NULL,  0,
191                         SND_SOC_NOPM, 0, 0),
192         SND_SOC_DAPM_AIF_OUT("SPDIFOUT", NULL,  0,
193                         SND_SOC_NOPM, 0, 0),
194
195         SND_SOC_DAPM_MUX("ADC Mux", SND_SOC_NOPM, 0, 0, &mic_linein_mux),
196
197         SND_SOC_DAPM_ADC("ADC", NULL, CS4265_PWRCTL, 2, 1),
198         SND_SOC_DAPM_PGA("Pre-amp MIC", CS4265_PWRCTL, 3,
199                         1, NULL, 0),
200
201         SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM,
202                          0, 0, &digital_input_mux),
203
204         SND_SOC_DAPM_MIXER("SDIN1 Input Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
205         SND_SOC_DAPM_MIXER("SDIN2 Input Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
206         SND_SOC_DAPM_MIXER("SPDIF Transmitter", SND_SOC_NOPM, 0, 0, NULL, 0),
207
208         SND_SOC_DAPM_SWITCH("Loopback", SND_SOC_NOPM, 0, 0,
209                         &loopback_ctl),
210         SND_SOC_DAPM_SWITCH("SPDIF", SND_SOC_NOPM, 0, 0,
211                         &spdif_switch),
212         SND_SOC_DAPM_SWITCH("DAC", CS4265_PWRCTL, 1, 1,
213                         &dac_switch),
214
215         SND_SOC_DAPM_AIF_IN("DIN1", NULL,  0,
216                         SND_SOC_NOPM, 0, 0),
217         SND_SOC_DAPM_AIF_IN("DIN2", NULL,  0,
218                         SND_SOC_NOPM, 0, 0),
219         SND_SOC_DAPM_AIF_IN("TXIN", NULL,  0,
220                         CS4265_SPDIF_CTL2, 5, 1),
221
222         SND_SOC_DAPM_OUTPUT("LINEOUTL"),
223         SND_SOC_DAPM_OUTPUT("LINEOUTR"),
224
225 };
226
227 static const struct snd_soc_dapm_route cs4265_audio_map[] = {
228
229         {"DIN1", NULL, "DAI1 Playback"},
230         {"DIN2", NULL, "DAI2 Playback"},
231         {"SDIN1 Input Mixer", NULL, "DIN1"},
232         {"SDIN2 Input Mixer", NULL, "DIN2"},
233         {"Input Mux", "SDIN1", "SDIN1 Input Mixer"},
234         {"Input Mux", "SDIN2", "SDIN2 Input Mixer"},
235         {"DAC", "Switch", "Input Mux"},
236         {"SPDIF", "Switch", "Input Mux"},
237         {"LINEOUTL", NULL, "DAC"},
238         {"LINEOUTR", NULL, "DAC"},
239         {"SPDIFOUT", NULL, "SPDIF"},
240
241         {"ADC Mux", "LINEIN", "LINEINL"},
242         {"ADC Mux", "LINEIN", "LINEINR"},
243         {"ADC Mux", "MIC", "MICL"},
244         {"ADC Mux", "MIC", "MICR"},
245         {"ADC", NULL, "ADC Mux"},
246         {"DOUT", NULL, "ADC"},
247         {"DAI1 Capture", NULL, "DOUT"},
248         {"DAI2 Capture", NULL, "DOUT"},
249
250         /* Loopback */
251         {"Loopback", "Switch", "ADC"},
252         {"DAC", NULL, "Loopback"},
253 };
254
255 struct cs4265_clk_para {
256         u32 mclk;
257         u32 rate;
258         u8 fm_mode; /* values 1, 2, or 4 */
259         u8 mclkdiv;
260 };
261
262 static const struct cs4265_clk_para clk_map_table[] = {
263         /*32k*/
264         {8192000, 32000, 0, 0},
265         {12288000, 32000, 0, 1},
266         {16384000, 32000, 0, 2},
267         {24576000, 32000, 0, 3},
268         {32768000, 32000, 0, 4},
269
270         /*44.1k*/
271         {11289600, 44100, 0, 0},
272         {16934400, 44100, 0, 1},
273         {22579200, 44100, 0, 2},
274         {33868000, 44100, 0, 3},
275         {45158400, 44100, 0, 4},
276
277         /*48k*/
278         {12288000, 48000, 0, 0},
279         {18432000, 48000, 0, 1},
280         {24576000, 48000, 0, 2},
281         {36864000, 48000, 0, 3},
282         {49152000, 48000, 0, 4},
283
284         /*64k*/
285         {8192000, 64000, 1, 0},
286         {12288000, 64000, 1, 1},
287         {16934400, 64000, 1, 2},
288         {24576000, 64000, 1, 3},
289         {32768000, 64000, 1, 4},
290
291         /* 88.2k */
292         {11289600, 88200, 1, 0},
293         {16934400, 88200, 1, 1},
294         {22579200, 88200, 1, 2},
295         {33868000, 88200, 1, 3},
296         {45158400, 88200, 1, 4},
297
298         /* 96k */
299         {12288000, 96000, 1, 0},
300         {18432000, 96000, 1, 1},
301         {24576000, 96000, 1, 2},
302         {36864000, 96000, 1, 3},
303         {49152000, 96000, 1, 4},
304
305         /* 128k */
306         {8192000, 128000, 2, 0},
307         {12288000, 128000, 2, 1},
308         {16934400, 128000, 2, 2},
309         {24576000, 128000, 2, 3},
310         {32768000, 128000, 2, 4},
311
312         /* 176.4k */
313         {11289600, 176400, 2, 0},
314         {16934400, 176400, 2, 1},
315         {22579200, 176400, 2, 2},
316         {33868000, 176400, 2, 3},
317         {49152000, 176400, 2, 4},
318
319         /* 192k */
320         {12288000, 192000, 2, 0},
321         {18432000, 192000, 2, 1},
322         {24576000, 192000, 2, 2},
323         {36864000, 192000, 2, 3},
324         {49152000, 192000, 2, 4},
325 };
326
327 static int cs4265_get_clk_index(int mclk, int rate)
328 {
329         int i;
330
331         for (i = 0; i < ARRAY_SIZE(clk_map_table); i++) {
332                 if (clk_map_table[i].rate == rate &&
333                                 clk_map_table[i].mclk == mclk)
334                         return i;
335         }
336         return -EINVAL;
337 }
338
339 static int cs4265_set_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
340                         unsigned int freq, int dir)
341 {
342         struct snd_soc_codec *codec = codec_dai->codec;
343         struct cs4265_private *cs4265 = snd_soc_codec_get_drvdata(codec);
344         int i;
345
346         if (clk_id != 0) {
347                 dev_err(codec->dev, "Invalid clk_id %d\n", clk_id);
348                 return -EINVAL;
349         }
350         for (i = 0; i < ARRAY_SIZE(clk_map_table); i++) {
351                 if (clk_map_table[i].mclk == freq) {
352                         cs4265->sysclk = freq;
353                         return 0;
354                 }
355         }
356         cs4265->sysclk = 0;
357         dev_err(codec->dev, "Invalid freq parameter %d\n", freq);
358         return -EINVAL;
359 }
360
361 static int cs4265_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
362 {
363         struct snd_soc_codec *codec = codec_dai->codec;
364         struct cs4265_private *cs4265 = snd_soc_codec_get_drvdata(codec);
365         u8 iface = 0;
366
367         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
368         case SND_SOC_DAIFMT_CBM_CFM:
369                 snd_soc_update_bits(codec, CS4265_ADC_CTL,
370                                 CS4265_ADC_MASTER,
371                                 CS4265_ADC_MASTER);
372                 break;
373         case SND_SOC_DAIFMT_CBS_CFS:
374                 snd_soc_update_bits(codec, CS4265_ADC_CTL,
375                                 CS4265_ADC_MASTER,
376                                 0);
377                 break;
378         default:
379                 return -EINVAL;
380         }
381
382          /* interface format */
383         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
384         case SND_SOC_DAIFMT_I2S:
385                 iface |= SND_SOC_DAIFMT_I2S;
386                 break;
387         case SND_SOC_DAIFMT_RIGHT_J:
388                 iface |= SND_SOC_DAIFMT_RIGHT_J;
389                 break;
390         case SND_SOC_DAIFMT_LEFT_J:
391                 iface |= SND_SOC_DAIFMT_LEFT_J;
392                 break;
393         default:
394                 return -EINVAL;
395         }
396
397         cs4265->format = iface;
398         return 0;
399 }
400
401 static int cs4265_digital_mute(struct snd_soc_dai *dai, int mute)
402 {
403         struct snd_soc_codec *codec = dai->codec;
404
405         if (mute) {
406                 snd_soc_update_bits(codec, CS4265_DAC_CTL,
407                         CS4265_DAC_CTL_MUTE,
408                         CS4265_DAC_CTL_MUTE);
409                 snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
410                         CS4265_SPDIF_CTL2_MUTE,
411                         CS4265_SPDIF_CTL2_MUTE);
412         } else {
413                 snd_soc_update_bits(codec, CS4265_DAC_CTL,
414                         CS4265_DAC_CTL_MUTE,
415                         0);
416                 snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
417                         CS4265_SPDIF_CTL2_MUTE,
418                         0);
419         }
420         return 0;
421 }
422
423 static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream,
424                                      struct snd_pcm_hw_params *params,
425                                      struct snd_soc_dai *dai)
426 {
427         struct snd_soc_codec *codec = dai->codec;
428         struct cs4265_private *cs4265 = snd_soc_codec_get_drvdata(codec);
429         int index;
430
431         if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
432                 ((cs4265->format & SND_SOC_DAIFMT_FORMAT_MASK)
433                 == SND_SOC_DAIFMT_RIGHT_J))
434                 return -EINVAL;
435
436         index = cs4265_get_clk_index(cs4265->sysclk, params_rate(params));
437         if (index >= 0) {
438                 snd_soc_update_bits(codec, CS4265_ADC_CTL,
439                         CS4265_ADC_FM, clk_map_table[index].fm_mode << 6);
440                 snd_soc_update_bits(codec, CS4265_MCLK_FREQ,
441                         CS4265_MCLK_FREQ_MASK,
442                         clk_map_table[index].mclkdiv << 4);
443
444         } else {
445                 dev_err(codec->dev, "can't get correct mclk\n");
446                 return -EINVAL;
447         }
448
449         switch (cs4265->format & SND_SOC_DAIFMT_FORMAT_MASK) {
450         case SND_SOC_DAIFMT_I2S:
451                 snd_soc_update_bits(codec, CS4265_DAC_CTL,
452                         CS4265_DAC_CTL_DIF, (1 << 4));
453                 snd_soc_update_bits(codec, CS4265_ADC_CTL,
454                         CS4265_ADC_DIF, (1 << 4));
455                 snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
456                         CS4265_SPDIF_CTL2_DIF, (1 << 6));
457                 break;
458         case SND_SOC_DAIFMT_RIGHT_J:
459                 if (params_width(params) == 16) {
460                         snd_soc_update_bits(codec, CS4265_DAC_CTL,
461                                 CS4265_DAC_CTL_DIF, (1 << 5));
462                         snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
463                                 CS4265_SPDIF_CTL2_DIF, (1 << 7));
464                 } else {
465                         snd_soc_update_bits(codec, CS4265_DAC_CTL,
466                                 CS4265_DAC_CTL_DIF, (3 << 5));
467                         snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
468                                 CS4265_SPDIF_CTL2_DIF, (1 << 7));
469                 }
470                 break;
471         case SND_SOC_DAIFMT_LEFT_J:
472                 snd_soc_update_bits(codec, CS4265_DAC_CTL,
473                         CS4265_DAC_CTL_DIF, 0);
474                 snd_soc_update_bits(codec, CS4265_ADC_CTL,
475                         CS4265_ADC_DIF, 0);
476                 snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
477                         CS4265_SPDIF_CTL2_DIF, (1 << 6));
478
479                 break;
480         default:
481                 return -EINVAL;
482         }
483         return 0;
484 }
485
486 static int cs4265_set_bias_level(struct snd_soc_codec *codec,
487                                         enum snd_soc_bias_level level)
488 {
489         switch (level) {
490         case SND_SOC_BIAS_ON:
491                 break;
492         case SND_SOC_BIAS_PREPARE:
493                 snd_soc_update_bits(codec, CS4265_PWRCTL,
494                         CS4265_PWRCTL_PDN, 0);
495                 break;
496         case SND_SOC_BIAS_STANDBY:
497                 snd_soc_update_bits(codec, CS4265_PWRCTL,
498                         CS4265_PWRCTL_PDN,
499                         CS4265_PWRCTL_PDN);
500                 break;
501         case SND_SOC_BIAS_OFF:
502                 snd_soc_update_bits(codec, CS4265_PWRCTL,
503                         CS4265_PWRCTL_PDN,
504                         CS4265_PWRCTL_PDN);
505                 break;
506         }
507         codec->dapm.bias_level = level;
508         return 0;
509 }
510
511 #define CS4265_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
512                         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
513                         SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
514                         SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
515
516 #define CS4265_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
517                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE)
518
519 static const struct snd_soc_dai_ops cs4265_ops = {
520         .hw_params      = cs4265_pcm_hw_params,
521         .digital_mute   = cs4265_digital_mute,
522         .set_fmt        = cs4265_set_fmt,
523         .set_sysclk     = cs4265_set_sysclk,
524 };
525
526 static struct snd_soc_dai_driver cs4265_dai[] = {
527         {
528                 .name = "cs4265-dai1",
529                 .playback = {
530                         .stream_name = "DAI1 Playback",
531                         .channels_min = 1,
532                         .channels_max = 2,
533                         .rates = CS4265_RATES,
534                         .formats = CS4265_FORMATS,
535                 },
536                 .capture = {
537                         .stream_name = "DAI1 Capture",
538                         .channels_min = 1,
539                         .channels_max = 2,
540                         .rates = CS4265_RATES,
541                         .formats = CS4265_FORMATS,
542                 },
543                 .ops = &cs4265_ops,
544         },
545         {
546                 .name = "cs4265-dai2",
547                 .playback = {
548                         .stream_name = "DAI2 Playback",
549                         .channels_min = 1,
550                         .channels_max = 2,
551                         .rates = CS4265_RATES,
552                         .formats = CS4265_FORMATS,
553                 },
554                 .capture = {
555                         .stream_name = "DAI2 Capture",
556                         .channels_min = 1,
557                         .channels_max = 2,
558                         .rates = CS4265_RATES,
559                         .formats = CS4265_FORMATS,
560                 },
561                 .ops = &cs4265_ops,
562         },
563 };
564
565 static const struct snd_soc_codec_driver soc_codec_cs4265 = {
566         .set_bias_level = cs4265_set_bias_level,
567
568         .dapm_widgets = cs4265_dapm_widgets,
569         .num_dapm_widgets = ARRAY_SIZE(cs4265_dapm_widgets),
570         .dapm_routes = cs4265_audio_map,
571         .num_dapm_routes = ARRAY_SIZE(cs4265_audio_map),
572
573         .controls = cs4265_snd_controls,
574         .num_controls = ARRAY_SIZE(cs4265_snd_controls),
575 };
576
577 static const struct regmap_config cs4265_regmap = {
578         .reg_bits = 8,
579         .val_bits = 8,
580
581         .max_register = CS4265_MAX_REGISTER,
582         .reg_defaults = cs4265_reg_defaults,
583         .num_reg_defaults = ARRAY_SIZE(cs4265_reg_defaults),
584         .readable_reg = cs4265_readable_register,
585         .volatile_reg = cs4265_volatile_register,
586         .cache_type = REGCACHE_RBTREE,
587 };
588
589 static int cs4265_i2c_probe(struct i2c_client *i2c_client,
590                              const struct i2c_device_id *id)
591 {
592         struct cs4265_private *cs4265;
593         int ret = 0;
594         unsigned int devid = 0;
595         unsigned int reg;
596
597         cs4265 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4265_private),
598                                GFP_KERNEL);
599         if (cs4265 == NULL)
600                 return -ENOMEM;
601         cs4265->dev = &i2c_client->dev;
602
603         cs4265->regmap = devm_regmap_init_i2c(i2c_client, &cs4265_regmap);
604         if (IS_ERR(cs4265->regmap)) {
605                 ret = PTR_ERR(cs4265->regmap);
606                 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
607                 return ret;
608         }
609
610         cs4265->reset_gpio = devm_gpiod_get(&i2c_client->dev,
611                 "reset-gpios");
612         if (IS_ERR(cs4265->reset_gpio)) {
613                 ret = PTR_ERR(cs4265->reset_gpio);
614                 if (ret != -ENOENT && ret != -ENOSYS)
615                         return ret;
616
617                 cs4265->reset_gpio = NULL;
618         } else {
619                 ret = gpiod_direction_output(cs4265->reset_gpio, 0);
620                 if (ret)
621                         return ret;
622                 mdelay(1);
623                 gpiod_set_value_cansleep(cs4265->reset_gpio, 1);
624
625         }
626
627         i2c_set_clientdata(i2c_client, cs4265);
628
629         ret = regmap_read(cs4265->regmap, CS4265_CHIP_ID, &reg);
630         devid = reg & CS4265_CHIP_ID_MASK;
631         if (devid != CS4265_CHIP_ID_VAL) {
632                 ret = -ENODEV;
633                 dev_err(&i2c_client->dev,
634                         "CS4265 Device ID (%X). Expected %X\n",
635                         devid, CS4265_CHIP_ID);
636                 return ret;
637         }
638         dev_info(&i2c_client->dev,
639                 "CS4265 Version %x\n",
640                         reg & CS4265_REV_ID_MASK);
641
642         regmap_write(cs4265->regmap, CS4265_PWRCTL, 0x0F);
643
644         ret =  snd_soc_register_codec(&i2c_client->dev,
645                         &soc_codec_cs4265, cs4265_dai,
646                         ARRAY_SIZE(cs4265_dai));
647         return ret;
648 }
649
650 static int cs4265_i2c_remove(struct i2c_client *client)
651 {
652         snd_soc_unregister_codec(&client->dev);
653         return 0;
654 }
655
656 static const struct of_device_id cs4265_of_match[] = {
657         { .compatible = "cirrus,cs4265", },
658         { }
659 };
660 MODULE_DEVICE_TABLE(of, cs4265_of_match);
661
662 static const struct i2c_device_id cs4265_id[] = {
663         { "cs4265", 0 },
664         { }
665 };
666 MODULE_DEVICE_TABLE(i2c, cs4265_id);
667
668 static struct i2c_driver cs4265_i2c_driver = {
669         .driver = {
670                 .name = "cs4265",
671                 .owner = THIS_MODULE,
672                 .of_match_table = cs4265_of_match,
673         },
674         .id_table = cs4265_id,
675         .probe =    cs4265_i2c_probe,
676         .remove =   cs4265_i2c_remove,
677 };
678
679 module_i2c_driver(cs4265_i2c_driver);
680
681 MODULE_DESCRIPTION("ASoC CS4265 driver");
682 MODULE_AUTHOR("Paul Handrigan, Cirrus Logic Inc, <paul.handrigan@cirrus.com>");
683 MODULE_LICENSE("GPL");