diff options
author | anish kumar <yesanishhere@gmail.com> | 2016-04-27 18:39:05 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-04-28 13:16:04 -0400 |
commit | ca2cd6bc6663314ba7fbf66ba7b14e099671420e (patch) | |
tree | 7a44a8426f3b4d6d96e9cc50c474234478ed4325 | |
parent | f55532a0c0b8bb6148f4e07853b876ef73bc69ca (diff) |
ASoC: Add max98371 codec driver
Signed-off-by: anish kumar <yesanishhere@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | Documentation/devicetree/bindings/sound/max98371.txt | 17 | ||||
-rw-r--r-- | sound/soc/codecs/Kconfig | 4 | ||||
-rw-r--r-- | sound/soc/codecs/Makefile | 1 | ||||
-rw-r--r-- | sound/soc/codecs/max98371.c | 442 | ||||
-rw-r--r-- | sound/soc/codecs/max98371.h | 67 |
5 files changed, 531 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/max98371.txt b/Documentation/devicetree/bindings/sound/max98371.txt new file mode 100644 index 000000000000..6c285235e64b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/max98371.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | max98371 codec | ||
2 | |||
3 | This device supports I2C mode only. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "maxim,max98371" | ||
8 | - reg : The chip select number on the I2C bus | ||
9 | |||
10 | Example: | ||
11 | |||
12 | &i2c { | ||
13 | max98371: max98371@0x31 { | ||
14 | compatible = "maxim,max98371"; | ||
15 | reg = <0x31>; | ||
16 | }; | ||
17 | }; | ||
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 649e92a252ae..d764f1329042 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -79,6 +79,7 @@ config SND_SOC_ALL_CODECS | |||
79 | select SND_SOC_MAX98090 if I2C | 79 | select SND_SOC_MAX98090 if I2C |
80 | select SND_SOC_MAX98095 if I2C | 80 | select SND_SOC_MAX98095 if I2C |
81 | select SND_SOC_MAX98357A if GPIOLIB | 81 | select SND_SOC_MAX98357A if GPIOLIB |
82 | select SND_SOC_MAX98371 if I2C | ||
82 | select SND_SOC_MAX9867 if I2C | 83 | select SND_SOC_MAX9867 if I2C |
83 | select SND_SOC_MAX98925 if I2C | 84 | select SND_SOC_MAX98925 if I2C |
84 | select SND_SOC_MAX98926 if I2C | 85 | select SND_SOC_MAX98926 if I2C |
@@ -522,6 +523,9 @@ config SND_SOC_MAX98095 | |||
522 | config SND_SOC_MAX98357A | 523 | config SND_SOC_MAX98357A |
523 | tristate | 524 | tristate |
524 | 525 | ||
526 | config SND_SOC_MAX98371 | ||
527 | tristate | ||
528 | |||
525 | config SND_SOC_MAX9867 | 529 | config SND_SOC_MAX9867 |
526 | tristate | 530 | tristate |
527 | 531 | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 185a712a7fe7..92ef8719c311 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -74,6 +74,7 @@ snd-soc-max98088-objs := max98088.o | |||
74 | snd-soc-max98090-objs := max98090.o | 74 | snd-soc-max98090-objs := max98090.o |
75 | snd-soc-max98095-objs := max98095.o | 75 | snd-soc-max98095-objs := max98095.o |
76 | snd-soc-max98357a-objs := max98357a.o | 76 | snd-soc-max98357a-objs := max98357a.o |
77 | snd-soc-max98371-objs := max98371.o | ||
77 | snd-soc-max9867-objs := max9867.o | 78 | snd-soc-max9867-objs := max9867.o |
78 | snd-soc-max98925-objs := max98925.o | 79 | snd-soc-max98925-objs := max98925.o |
79 | snd-soc-max98926-objs := max98926.o | 80 | snd-soc-max98926-objs := max98926.o |
diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c new file mode 100644 index 000000000000..21fae0932137 --- /dev/null +++ b/sound/soc/codecs/max98371.c | |||
@@ -0,0 +1,442 @@ | |||
1 | /* | ||
2 | * max98371.c -- ALSA SoC Stereo MAX98371 driver | ||
3 | * | ||
4 | * Copyright 2015-16 Maxim Integrated Products | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/i2c.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/regmap.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <sound/pcm.h> | ||
16 | #include <sound/pcm_params.h> | ||
17 | #include <sound/soc.h> | ||
18 | #include <sound/tlv.h> | ||
19 | #include "max98371.h" | ||
20 | |||
21 | static const char *const monomix_text[] = { | ||
22 | "Left", "Right", "LeftRightDiv2", | ||
23 | }; | ||
24 | |||
25 | static const char *const hpf_cutoff_txt[] = { | ||
26 | "Disable", "DC Block", "50Hz", | ||
27 | "100Hz", "200Hz", "400Hz", "800Hz", | ||
28 | }; | ||
29 | |||
30 | static SOC_ENUM_SINGLE_DECL(max98371_monomix, MAX98371_MONOMIX_CFG, 0, | ||
31 | monomix_text); | ||
32 | |||
33 | static SOC_ENUM_SINGLE_DECL(max98371_hpf_cutoff, MAX98371_HPF, 0, | ||
34 | hpf_cutoff_txt); | ||
35 | |||
36 | static const DECLARE_TLV_DB_RANGE(max98371_dht_min_gain, | ||
37 | 0, 1, TLV_DB_SCALE_ITEM(537, 66, 0), | ||
38 | 2, 3, TLV_DB_SCALE_ITEM(677, 82, 0), | ||
39 | 4, 5, TLV_DB_SCALE_ITEM(852, 104, 0), | ||
40 | 6, 7, TLV_DB_SCALE_ITEM(1072, 131, 0), | ||
41 | 8, 9, TLV_DB_SCALE_ITEM(1350, 165, 0), | ||
42 | 10, 11, TLV_DB_SCALE_ITEM(1699, 101, 0), | ||
43 | ); | ||
44 | |||
45 | static const DECLARE_TLV_DB_RANGE(max98371_dht_max_gain, | ||
46 | 0, 1, TLV_DB_SCALE_ITEM(537, 66, 0), | ||
47 | 2, 3, TLV_DB_SCALE_ITEM(677, 82, 0), | ||
48 | 4, 5, TLV_DB_SCALE_ITEM(852, 104, 0), | ||
49 | 6, 7, TLV_DB_SCALE_ITEM(1072, 131, 0), | ||
50 | 8, 9, TLV_DB_SCALE_ITEM(1350, 165, 0), | ||
51 | 10, 11, TLV_DB_SCALE_ITEM(1699, 208, 0), | ||
52 | ); | ||
53 | |||
54 | static const DECLARE_TLV_DB_RANGE(max98371_dht_rot_gain, | ||
55 | 0, 1, TLV_DB_SCALE_ITEM(-50, -50, 0), | ||
56 | 2, 6, TLV_DB_SCALE_ITEM(-100, -100, 0), | ||
57 | 7, 8, TLV_DB_SCALE_ITEM(-800, -200, 0), | ||
58 | 9, 11, TLV_DB_SCALE_ITEM(-1200, -300, 0), | ||
59 | 12, 13, TLV_DB_SCALE_ITEM(-2000, -200, 0), | ||
60 | 14, 15, TLV_DB_SCALE_ITEM(-2500, -500, 0), | ||
61 | ); | ||
62 | |||
63 | static const struct reg_default max98371_reg[] = { | ||
64 | { 0x01, 0x00 }, | ||
65 | { 0x02, 0x00 }, | ||
66 | { 0x03, 0x00 }, | ||
67 | { 0x04, 0x00 }, | ||
68 | { 0x05, 0x00 }, | ||
69 | { 0x06, 0x00 }, | ||
70 | { 0x07, 0x00 }, | ||
71 | { 0x08, 0x00 }, | ||
72 | { 0x09, 0x00 }, | ||
73 | { 0x0A, 0x00 }, | ||
74 | { 0x10, 0x06 }, | ||
75 | { 0x11, 0x08 }, | ||
76 | { 0x14, 0x80 }, | ||
77 | { 0x15, 0x00 }, | ||
78 | { 0x16, 0x00 }, | ||
79 | { 0x18, 0x00 }, | ||
80 | { 0x19, 0x00 }, | ||
81 | { 0x1C, 0x00 }, | ||
82 | { 0x1D, 0x00 }, | ||
83 | { 0x1E, 0x00 }, | ||
84 | { 0x1F, 0x00 }, | ||
85 | { 0x20, 0x00 }, | ||
86 | { 0x21, 0x00 }, | ||
87 | { 0x22, 0x00 }, | ||
88 | { 0x23, 0x00 }, | ||
89 | { 0x24, 0x00 }, | ||
90 | { 0x25, 0x00 }, | ||
91 | { 0x26, 0x00 }, | ||
92 | { 0x27, 0x00 }, | ||
93 | { 0x28, 0x00 }, | ||
94 | { 0x29, 0x00 }, | ||
95 | { 0x2A, 0x00 }, | ||
96 | { 0x2B, 0x00 }, | ||
97 | { 0x2C, 0x00 }, | ||
98 | { 0x2D, 0x00 }, | ||
99 | { 0x2E, 0x0B }, | ||
100 | { 0x31, 0x00 }, | ||
101 | { 0x32, 0x18 }, | ||
102 | { 0x33, 0x00 }, | ||
103 | { 0x34, 0x00 }, | ||
104 | { 0x36, 0x00 }, | ||
105 | { 0x37, 0x00 }, | ||
106 | { 0x38, 0x00 }, | ||
107 | { 0x39, 0x00 }, | ||
108 | { 0x3A, 0x00 }, | ||
109 | { 0x3B, 0x00 }, | ||
110 | { 0x3B, 0x00 }, | ||
111 | { 0x3C, 0x00 }, | ||
112 | { 0x3D, 0x00 }, | ||
113 | { 0x3E, 0x00 }, | ||
114 | { 0x3F, 0x00 }, | ||
115 | { 0x40, 0x00 }, | ||
116 | { 0x41, 0x00 }, | ||
117 | { 0x42, 0x00 }, | ||
118 | { 0x43, 0x00 }, | ||
119 | { 0x4A, 0x00 }, | ||
120 | { 0x4B, 0x00 }, | ||
121 | { 0x4C, 0x00 }, | ||
122 | { 0x4D, 0x00 }, | ||
123 | { 0x4E, 0x00 }, | ||
124 | { 0x50, 0x00 }, | ||
125 | { 0x51, 0x00 }, | ||
126 | { 0x55, 0x00 }, | ||
127 | { 0x58, 0x00 }, | ||
128 | { 0x59, 0x00 }, | ||
129 | { 0x5C, 0x00 }, | ||
130 | { 0xFF, 0x43 }, | ||
131 | }; | ||
132 | |||
133 | static bool max98371_volatile_register(struct device *dev, unsigned int reg) | ||
134 | { | ||
135 | switch (reg) { | ||
136 | case MAX98371_IRQ_CLEAR1: | ||
137 | case MAX98371_IRQ_CLEAR2: | ||
138 | case MAX98371_IRQ_CLEAR3: | ||
139 | case MAX98371_VERSION: | ||
140 | return true; | ||
141 | default: | ||
142 | return false; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | static bool max98371_readable_register(struct device *dev, unsigned int reg) | ||
147 | { | ||
148 | switch (reg) { | ||
149 | case MAX98371_SOFT_RESET: | ||
150 | return false; | ||
151 | default: | ||
152 | return true; | ||
153 | } | ||
154 | }; | ||
155 | |||
156 | static const DECLARE_TLV_DB_RANGE(max98371_gain_tlv, | ||
157 | 0, 7, TLV_DB_SCALE_ITEM(0, 50, 0), | ||
158 | 8, 10, TLV_DB_SCALE_ITEM(400, 100, 0) | ||
159 | ); | ||
160 | |||
161 | static const DECLARE_TLV_DB_RANGE(max98371_noload_gain_tlv, | ||
162 | 0, 11, TLV_DB_SCALE_ITEM(950, 100, 0), | ||
163 | ); | ||
164 | |||
165 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -6300, 50, 1); | ||
166 | |||
167 | static const struct snd_kcontrol_new max98371_snd_controls[] = { | ||
168 | SOC_SINGLE_TLV("Speaker Volume", MAX98371_GAIN, | ||
169 | MAX98371_GAIN_SHIFT, (1<<MAX98371_GAIN_WIDTH)-1, 0, | ||
170 | max98371_gain_tlv), | ||
171 | SOC_SINGLE_TLV("Digital Volume", MAX98371_DIGITAL_GAIN, 0, | ||
172 | (1<<MAX98371_DIGITAL_GAIN_WIDTH)-1, 1, digital_tlv), | ||
173 | SOC_SINGLE_TLV("Speaker DHT Max Volume", MAX98371_GAIN, | ||
174 | 0, (1<<MAX98371_DHT_MAX_WIDTH)-1, 0, | ||
175 | max98371_dht_max_gain), | ||
176 | SOC_SINGLE_TLV("Speaker DHT Min Volume", MAX98371_DHT_GAIN, | ||
177 | 0, (1<<MAX98371_DHT_GAIN_WIDTH)-1, 0, | ||
178 | max98371_dht_min_gain), | ||
179 | SOC_SINGLE_TLV("Speaker DHT Rotation Volume", MAX98371_DHT_GAIN, | ||
180 | 0, (1<<MAX98371_DHT_ROT_WIDTH)-1, 0, | ||
181 | max98371_dht_rot_gain), | ||
182 | SOC_SINGLE("DHT Attack Step", MAX98371_DHT, MAX98371_DHT_STEP, 3, 0), | ||
183 | SOC_SINGLE("DHT Attack Rate", MAX98371_DHT, 0, 7, 0), | ||
184 | SOC_ENUM("Monomix Select", max98371_monomix), | ||
185 | SOC_ENUM("HPF Cutoff", max98371_hpf_cutoff), | ||
186 | }; | ||
187 | |||
188 | static int max98371_dai_set_fmt(struct snd_soc_dai *codec_dai, | ||
189 | unsigned int fmt) | ||
190 | { | ||
191 | struct snd_soc_codec *codec = codec_dai->codec; | ||
192 | struct max98371_priv *max98371 = snd_soc_codec_get_drvdata(codec); | ||
193 | unsigned int val = 0; | ||
194 | |||
195 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
196 | case SND_SOC_DAIFMT_CBS_CFS: | ||
197 | break; | ||
198 | default: | ||
199 | dev_err(codec->dev, "DAI clock mode unsupported"); | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | |||
203 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
204 | case SND_SOC_DAIFMT_I2S: | ||
205 | val |= 0; | ||
206 | break; | ||
207 | case SND_SOC_DAIFMT_RIGHT_J: | ||
208 | val |= MAX98371_DAI_RIGHT; | ||
209 | break; | ||
210 | case SND_SOC_DAIFMT_LEFT_J: | ||
211 | val |= MAX98371_DAI_LEFT; | ||
212 | break; | ||
213 | default: | ||
214 | dev_err(codec->dev, "DAI wrong mode unsupported"); | ||
215 | return -EINVAL; | ||
216 | } | ||
217 | regmap_update_bits(max98371->regmap, MAX98371_FMT, | ||
218 | MAX98371_FMT_MODE_MASK, val); | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | static int max98371_dai_hw_params(struct snd_pcm_substream *substream, | ||
223 | struct snd_pcm_hw_params *params, | ||
224 | struct snd_soc_dai *dai) | ||
225 | { | ||
226 | struct snd_soc_codec *codec = dai->codec; | ||
227 | struct max98371_priv *max98371 = snd_soc_codec_get_drvdata(codec); | ||
228 | int blr_clk_ratio, ch_size, channels = params_channels(params); | ||
229 | int rate = params_rate(params); | ||
230 | |||
231 | switch (params_format(params)) { | ||
232 | case SNDRV_PCM_FORMAT_S8: | ||
233 | regmap_update_bits(max98371->regmap, MAX98371_FMT, | ||
234 | MAX98371_FMT_MASK, MAX98371_DAI_CHANSZ_16); | ||
235 | ch_size = 8; | ||
236 | break; | ||
237 | case SNDRV_PCM_FORMAT_S16_LE: | ||
238 | regmap_update_bits(max98371->regmap, MAX98371_FMT, | ||
239 | MAX98371_FMT_MASK, MAX98371_DAI_CHANSZ_16); | ||
240 | ch_size = 16; | ||
241 | break; | ||
242 | case SNDRV_PCM_FORMAT_S24_LE: | ||
243 | regmap_update_bits(max98371->regmap, MAX98371_FMT, | ||
244 | MAX98371_FMT_MASK, MAX98371_DAI_CHANSZ_32); | ||
245 | ch_size = 24; | ||
246 | break; | ||
247 | case SNDRV_PCM_FORMAT_S32_LE: | ||
248 | regmap_update_bits(max98371->regmap, MAX98371_FMT, | ||
249 | MAX98371_FMT_MASK, MAX98371_DAI_CHANSZ_32); | ||
250 | ch_size = 32; | ||
251 | break; | ||
252 | default: | ||
253 | return -EINVAL; | ||
254 | } | ||
255 | |||
256 | /* BCLK/LRCLK ratio calculation */ | ||
257 | blr_clk_ratio = channels * ch_size; | ||
258 | switch (blr_clk_ratio) { | ||
259 | case 32: | ||
260 | regmap_update_bits(max98371->regmap, | ||
261 | MAX98371_DAI_CLK, | ||
262 | MAX98371_DAI_BSEL_MASK, MAX98371_DAI_BSEL_32); | ||
263 | break; | ||
264 | case 48: | ||
265 | regmap_update_bits(max98371->regmap, | ||
266 | MAX98371_DAI_CLK, | ||
267 | MAX98371_DAI_BSEL_MASK, MAX98371_DAI_BSEL_48); | ||
268 | break; | ||
269 | case 64: | ||
270 | regmap_update_bits(max98371->regmap, | ||
271 | MAX98371_DAI_CLK, | ||
272 | MAX98371_DAI_BSEL_MASK, MAX98371_DAI_BSEL_64); | ||
273 | break; | ||
274 | default: | ||
275 | return -EINVAL; | ||
276 | } | ||
277 | |||
278 | switch (rate) { | ||
279 | case 32000: | ||
280 | regmap_update_bits(max98371->regmap, | ||
281 | MAX98371_SPK_SR, | ||
282 | MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_32); | ||
283 | break; | ||
284 | case 44100: | ||
285 | regmap_update_bits(max98371->regmap, | ||
286 | MAX98371_SPK_SR, | ||
287 | MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_44); | ||
288 | break; | ||
289 | case 48000: | ||
290 | regmap_update_bits(max98371->regmap, | ||
291 | MAX98371_SPK_SR, | ||
292 | MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_48); | ||
293 | break; | ||
294 | case 88200: | ||
295 | regmap_update_bits(max98371->regmap, | ||
296 | MAX98371_SPK_SR, | ||
297 | MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_88); | ||
298 | break; | ||
299 | case 96000: | ||
300 | regmap_update_bits(max98371->regmap, | ||
301 | MAX98371_SPK_SR, | ||
302 | MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_96); | ||
303 | break; | ||
304 | default: | ||
305 | return -EINVAL; | ||
306 | } | ||
307 | |||
308 | /* enabling both the RX channels*/ | ||
309 | regmap_update_bits(max98371->regmap, MAX98371_MONOMIX_SRC, | ||
310 | MAX98371_MONOMIX_SRC_MASK, MONOMIX_RX_0_1); | ||
311 | regmap_update_bits(max98371->regmap, MAX98371_DAI_CHANNEL, | ||
312 | MAX98371_CHANNEL_MASK, MAX98371_CHANNEL_MASK); | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static const struct snd_soc_dapm_widget max98371_dapm_widgets[] = { | ||
317 | SND_SOC_DAPM_DAC("DAC", NULL, MAX98371_SPK_ENABLE, 0, 0), | ||
318 | SND_SOC_DAPM_SUPPLY("Global Enable", MAX98371_GLOBAL_ENABLE, | ||
319 | 0, 0, NULL, 0), | ||
320 | SND_SOC_DAPM_OUTPUT("SPK_OUT"), | ||
321 | }; | ||
322 | |||
323 | static const struct snd_soc_dapm_route max98371_audio_map[] = { | ||
324 | {"DAC", NULL, "HiFi Playback"}, | ||
325 | {"SPK_OUT", NULL, "DAC"}, | ||
326 | {"SPK_OUT", NULL, "Global Enable"}, | ||
327 | }; | ||
328 | |||
329 | #define MAX98371_RATES SNDRV_PCM_RATE_8000_48000 | ||
330 | #define MAX98371_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \ | ||
331 | SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE) | ||
332 | |||
333 | static const struct snd_soc_dai_ops max98371_dai_ops = { | ||
334 | .set_fmt = max98371_dai_set_fmt, | ||
335 | .hw_params = max98371_dai_hw_params, | ||
336 | }; | ||
337 | |||
338 | static struct snd_soc_dai_driver max98371_dai[] = { | ||
339 | { | ||
340 | .name = "max98371-aif1", | ||
341 | .playback = { | ||
342 | .stream_name = "HiFi Playback", | ||
343 | .channels_min = 1, | ||
344 | .channels_max = 2, | ||
345 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
346 | .formats = MAX98371_FORMATS, | ||
347 | }, | ||
348 | .ops = &max98371_dai_ops, | ||
349 | } | ||
350 | }; | ||
351 | |||
352 | static const struct snd_soc_codec_driver max98371_codec = { | ||
353 | .controls = max98371_snd_controls, | ||
354 | .num_controls = ARRAY_SIZE(max98371_snd_controls), | ||
355 | .dapm_routes = max98371_audio_map, | ||
356 | .num_dapm_routes = ARRAY_SIZE(max98371_audio_map), | ||
357 | .dapm_widgets = max98371_dapm_widgets, | ||
358 | .num_dapm_widgets = ARRAY_SIZE(max98371_dapm_widgets), | ||
359 | }; | ||
360 | |||
361 | static const struct regmap_config max98371_regmap = { | ||
362 | .reg_bits = 8, | ||
363 | .val_bits = 8, | ||
364 | .max_register = MAX98371_VERSION, | ||
365 | .reg_defaults = max98371_reg, | ||
366 | .num_reg_defaults = ARRAY_SIZE(max98371_reg), | ||
367 | .volatile_reg = max98371_volatile_register, | ||
368 | .readable_reg = max98371_readable_register, | ||
369 | .cache_type = REGCACHE_RBTREE, | ||
370 | }; | ||
371 | |||
372 | static int max98371_i2c_probe(struct i2c_client *i2c, | ||
373 | const struct i2c_device_id *id) | ||
374 | { | ||
375 | struct max98371_priv *max98371; | ||
376 | int ret, reg; | ||
377 | |||
378 | max98371 = devm_kzalloc(&i2c->dev, | ||
379 | sizeof(*max98371), GFP_KERNEL); | ||
380 | if (!max98371) | ||
381 | return -ENOMEM; | ||
382 | |||
383 | i2c_set_clientdata(i2c, max98371); | ||
384 | max98371->regmap = devm_regmap_init_i2c(i2c, &max98371_regmap); | ||
385 | if (IS_ERR(max98371->regmap)) { | ||
386 | ret = PTR_ERR(max98371->regmap); | ||
387 | dev_err(&i2c->dev, | ||
388 | "Failed to allocate regmap: %d\n", ret); | ||
389 | return ret; | ||
390 | } | ||
391 | |||
392 | ret = regmap_read(max98371->regmap, MAX98371_VERSION, ®); | ||
393 | if (ret < 0) { | ||
394 | dev_info(&i2c->dev, "device error %d\n", ret); | ||
395 | return ret; | ||
396 | } | ||
397 | dev_info(&i2c->dev, "device version %x\n", reg); | ||
398 | |||
399 | ret = snd_soc_register_codec(&i2c->dev, &max98371_codec, | ||
400 | max98371_dai, ARRAY_SIZE(max98371_dai)); | ||
401 | if (ret < 0) { | ||
402 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); | ||
403 | return ret; | ||
404 | } | ||
405 | return ret; | ||
406 | } | ||
407 | |||
408 | static int max98371_i2c_remove(struct i2c_client *client) | ||
409 | { | ||
410 | snd_soc_unregister_codec(&client->dev); | ||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | static const struct i2c_device_id max98371_i2c_id[] = { | ||
415 | { "max98371", 0 }, | ||
416 | }; | ||
417 | |||
418 | MODULE_DEVICE_TABLE(i2c, max98371_i2c_id); | ||
419 | |||
420 | static const struct of_device_id max98371_of_match[] = { | ||
421 | { .compatible = "maxim,max98371", }, | ||
422 | { } | ||
423 | }; | ||
424 | MODULE_DEVICE_TABLE(of, max98371_of_match); | ||
425 | |||
426 | static struct i2c_driver max98371_i2c_driver = { | ||
427 | .driver = { | ||
428 | .name = "max98371", | ||
429 | .owner = THIS_MODULE, | ||
430 | .pm = NULL, | ||
431 | .of_match_table = of_match_ptr(max98371_of_match), | ||
432 | }, | ||
433 | .probe = max98371_i2c_probe, | ||
434 | .remove = max98371_i2c_remove, | ||
435 | .id_table = max98371_i2c_id, | ||
436 | }; | ||
437 | |||
438 | module_i2c_driver(max98371_i2c_driver); | ||
439 | |||
440 | MODULE_AUTHOR("anish kumar <yesanishhere@gmail.com>"); | ||
441 | MODULE_DESCRIPTION("ALSA SoC MAX98371 driver"); | ||
442 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/max98371.h b/sound/soc/codecs/max98371.h new file mode 100644 index 000000000000..9f6330964d98 --- /dev/null +++ b/sound/soc/codecs/max98371.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * max98371.h -- MAX98371 ALSA SoC Audio driver | ||
3 | * | ||
4 | * Copyright 2011-2012 Maxim Integrated Products | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef _MAX98371_H | ||
12 | #define _MAX98371_H | ||
13 | |||
14 | #define MAX98371_IRQ_CLEAR1 0x01 | ||
15 | #define MAX98371_IRQ_CLEAR2 0x02 | ||
16 | #define MAX98371_IRQ_CLEAR3 0x03 | ||
17 | #define MAX98371_DAI_CLK 0x10 | ||
18 | #define MAX98371_DAI_BSEL_MASK 0xF | ||
19 | #define MAX98371_DAI_BSEL_32 2 | ||
20 | #define MAX98371_DAI_BSEL_48 3 | ||
21 | #define MAX98371_DAI_BSEL_64 4 | ||
22 | #define MAX98371_SPK_SR 0x11 | ||
23 | #define MAX98371_SPK_SR_MASK 0xF | ||
24 | #define MAX98371_SPK_SR_32 6 | ||
25 | #define MAX98371_SPK_SR_44 7 | ||
26 | #define MAX98371_SPK_SR_48 8 | ||
27 | #define MAX98371_SPK_SR_88 10 | ||
28 | #define MAX98371_SPK_SR_96 11 | ||
29 | #define MAX98371_DAI_CHANNEL 0x15 | ||
30 | #define MAX98371_CHANNEL_MASK 0x3 | ||
31 | #define MAX98371_MONOMIX_SRC 0x18 | ||
32 | #define MAX98371_MONOMIX_CFG 0x19 | ||
33 | #define MAX98371_HPF 0x1C | ||
34 | #define MAX98371_MONOMIX_SRC_MASK 0xFF | ||
35 | #define MONOMIX_RX_0_1 ((0x1)<<(4)) | ||
36 | #define M98371_DAI_CHANNEL_I2S 0x3 | ||
37 | #define MAX98371_DIGITAL_GAIN 0x2D | ||
38 | #define MAX98371_DIGITAL_GAIN_WIDTH 0x7 | ||
39 | #define MAX98371_GAIN 0x2E | ||
40 | #define MAX98371_GAIN_SHIFT 0x4 | ||
41 | #define MAX98371_GAIN_WIDTH 0x4 | ||
42 | #define MAX98371_DHT_MAX_WIDTH 4 | ||
43 | #define MAX98371_FMT 0x14 | ||
44 | #define MAX98371_CHANSZ_WIDTH 6 | ||
45 | #define MAX98371_FMT_MASK ((0x3)<<(MAX98371_CHANSZ_WIDTH)) | ||
46 | #define MAX98371_FMT_MODE_MASK ((0x7)<<(3)) | ||
47 | #define MAX98371_DAI_LEFT ((0x1)<<(3)) | ||
48 | #define MAX98371_DAI_RIGHT ((0x2)<<(3)) | ||
49 | #define MAX98371_DAI_CHANSZ_16 ((1)<<(MAX98371_CHANSZ_WIDTH)) | ||
50 | #define MAX98371_DAI_CHANSZ_24 ((2)<<(MAX98371_CHANSZ_WIDTH)) | ||
51 | #define MAX98371_DAI_CHANSZ_32 ((3)<<(MAX98371_CHANSZ_WIDTH)) | ||
52 | #define MAX98371_DHT 0x32 | ||
53 | #define MAX98371_DHT_STEP 0x3 | ||
54 | #define MAX98371_DHT_GAIN 0x31 | ||
55 | #define MAX98371_DHT_GAIN_WIDTH 0x4 | ||
56 | #define MAX98371_DHT_ROT_WIDTH 0x4 | ||
57 | #define MAX98371_SPK_ENABLE 0x4A | ||
58 | #define MAX98371_GLOBAL_ENABLE 0x50 | ||
59 | #define MAX98371_SOFT_RESET 0x51 | ||
60 | #define MAX98371_VERSION 0xFF | ||
61 | |||
62 | |||
63 | struct max98371_priv { | ||
64 | struct regmap *regmap; | ||
65 | struct snd_soc_codec *codec; | ||
66 | }; | ||
67 | #endif | ||