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