Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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, (1 << 5));
461                         snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
462                                 CS4265_SPDIF_CTL2_DIF, (1 << 7));
463                 } else {
464                         snd_soc_update_bits(codec, CS4265_DAC_CTL,
465                                 CS4265_DAC_CTL_DIF, (3 << 5));
466                         snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
467                                 CS4265_SPDIF_CTL2_DIF, (1 << 7));
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, (1 << 6));
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         codec->dapm.bias_level = level;
507         return 0;
508 }
509
510 #define CS4265_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
511                         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
512                         SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
513                         SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
514
515 #define CS4265_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
516                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE)
517
518 static const struct snd_soc_dai_ops cs4265_ops = {
519         .hw_params      = cs4265_pcm_hw_params,
520         .digital_mute   = cs4265_digital_mute,
521         .set_fmt        = cs4265_set_fmt,
522         .set_sysclk     = cs4265_set_sysclk,
523 };
524
525 static struct snd_soc_dai_driver cs4265_dai[] = {
526         {
527                 .name = "cs4265-dai1",
528                 .playback = {
529                         .stream_name = "DAI1 Playback",
530                         .channels_min = 1,
531                         .channels_max = 2,
532                         .rates = CS4265_RATES,
533                         .formats = CS4265_FORMATS,
534                 },
535                 .capture = {
536                         .stream_name = "DAI1 Capture",
537                         .channels_min = 1,
538                         .channels_max = 2,
539                         .rates = CS4265_RATES,
540                         .formats = CS4265_FORMATS,
541                 },
542                 .ops = &cs4265_ops,
543         },
544         {
545                 .name = "cs4265-dai2",
546                 .playback = {
547                         .stream_name = "DAI2 Playback",
548                         .channels_min = 1,
549                         .channels_max = 2,
550                         .rates = CS4265_RATES,
551                         .formats = CS4265_FORMATS,
552                 },
553                 .capture = {
554                         .stream_name = "DAI2 Capture",
555                         .channels_min = 1,
556                         .channels_max = 2,
557                         .rates = CS4265_RATES,
558                         .formats = CS4265_FORMATS,
559                 },
560                 .ops = &cs4265_ops,
561         },
562 };
563
564 static const struct snd_soc_codec_driver soc_codec_cs4265 = {
565         .set_bias_level = cs4265_set_bias_level,
566
567         .dapm_widgets = cs4265_dapm_widgets,
568         .num_dapm_widgets = ARRAY_SIZE(cs4265_dapm_widgets),
569         .dapm_routes = cs4265_audio_map,
570         .num_dapm_routes = ARRAY_SIZE(cs4265_audio_map),
571
572         .controls = cs4265_snd_controls,
573         .num_controls = ARRAY_SIZE(cs4265_snd_controls),
574 };
575
576 static const struct regmap_config cs4265_regmap = {
577         .reg_bits = 8,
578         .val_bits = 8,
579
580         .max_register = CS4265_MAX_REGISTER,
581         .reg_defaults = cs4265_reg_defaults,
582         .num_reg_defaults = ARRAY_SIZE(cs4265_reg_defaults),
583         .readable_reg = cs4265_readable_register,
584         .volatile_reg = cs4265_volatile_register,
585         .cache_type = REGCACHE_RBTREE,
586 };
587
588 static int cs4265_i2c_probe(struct i2c_client *i2c_client,
589                              const struct i2c_device_id *id)
590 {
591         struct cs4265_private *cs4265;
592         int ret = 0;
593         unsigned int devid = 0;
594         unsigned int reg;
595
596         cs4265 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4265_private),
597                                GFP_KERNEL);
598         if (cs4265 == NULL)
599                 return -ENOMEM;
600
601         cs4265->regmap = devm_regmap_init_i2c(i2c_client, &cs4265_regmap);
602         if (IS_ERR(cs4265->regmap)) {
603                 ret = PTR_ERR(cs4265->regmap);
604                 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
605                 return ret;
606         }
607
608         cs4265->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
609                 "reset", GPIOD_OUT_LOW);
610         if (IS_ERR(cs4265->reset_gpio))
611                 return PTR_ERR(cs4265->reset_gpio);
612
613         if (cs4265->reset_gpio) {
614                 mdelay(1);
615                 gpiod_set_value_cansleep(cs4265->reset_gpio, 1);
616         }
617
618         i2c_set_clientdata(i2c_client, cs4265);
619
620         ret = regmap_read(cs4265->regmap, CS4265_CHIP_ID, &reg);
621         devid = reg & CS4265_CHIP_ID_MASK;
622         if (devid != CS4265_CHIP_ID_VAL) {
623                 ret = -ENODEV;
624                 dev_err(&i2c_client->dev,
625                         "CS4265 Device ID (%X). Expected %X\n",
626                         devid, CS4265_CHIP_ID);
627                 return ret;
628         }
629         dev_info(&i2c_client->dev,
630                 "CS4265 Version %x\n",
631                         reg & CS4265_REV_ID_MASK);
632
633         regmap_write(cs4265->regmap, CS4265_PWRCTL, 0x0F);
634
635         ret =  snd_soc_register_codec(&i2c_client->dev,
636                         &soc_codec_cs4265, cs4265_dai,
637                         ARRAY_SIZE(cs4265_dai));
638         return ret;
639 }
640
641 static int cs4265_i2c_remove(struct i2c_client *client)
642 {
643         snd_soc_unregister_codec(&client->dev);
644         return 0;
645 }
646
647 static const struct of_device_id cs4265_of_match[] = {
648         { .compatible = "cirrus,cs4265", },
649         { }
650 };
651 MODULE_DEVICE_TABLE(of, cs4265_of_match);
652
653 static const struct i2c_device_id cs4265_id[] = {
654         { "cs4265", 0 },
655         { }
656 };
657 MODULE_DEVICE_TABLE(i2c, cs4265_id);
658
659 static struct i2c_driver cs4265_i2c_driver = {
660         .driver = {
661                 .name = "cs4265",
662                 .owner = THIS_MODULE,
663                 .of_match_table = cs4265_of_match,
664         },
665         .id_table = cs4265_id,
666         .probe =    cs4265_i2c_probe,
667         .remove =   cs4265_i2c_remove,
668 };
669
670 module_i2c_driver(cs4265_i2c_driver);
671
672 MODULE_DESCRIPTION("ASoC CS4265 driver");
673 MODULE_AUTHOR("Paul Handrigan, Cirrus Logic Inc, <paul.handrigan@cirrus.com>");
674 MODULE_LICENSE("GPL");