aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-04-12 08:57:19 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-04-12 08:57:19 -0400
commit5b9fd76972836272afba57404d2662627926165b (patch)
treef2030de5b09807083b1fc4d1cd6a45db9c27aa50
parenteeb7f91e3511d2b1338b3fae915e800d781627f8 (diff)
parent28dbd1611f5701c9b5b8c07924c1bd2ad6f64435 (diff)
Merge remote-tracking branch 'asoc/topic/tas5086' into asoc-next
-rw-r--r--Documentation/devicetree/bindings/sound/ti,tas5086.txt32
-rw-r--r--include/sound/tas5086.h7
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/tas5086.c591
5 files changed, 636 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/ti,tas5086.txt b/Documentation/devicetree/bindings/sound/ti,tas5086.txt
new file mode 100644
index 000000000000..8ea4f5b4818d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ti,tas5086.txt
@@ -0,0 +1,32 @@
1Texas Instruments TAS5086 6-channel PWM Processor
2
3Required properties:
4
5 - compatible: Should contain "ti,tas5086".
6 - reg: The i2c address. Should contain <0x1b>.
7
8Optional properties:
9
10 - reset-gpio: A GPIO spec to define which pin is connected to the
11 chip's !RESET pin. If specified, the driver will
12 assert a hardware reset at probe time.
13
14 - ti,charge-period: This property should contain the time in microseconds
15 that closely matches the external single-ended
16 split-capacitor charge period. The hardware chip
17 waits for this period of time before starting the
18 PWM signals. This helps reduce pops and clicks.
19
20 When not specified, the hardware default of 1300ms
21 is retained.
22
23Examples:
24
25 i2c_bus {
26 tas5086@1b {
27 compatible = "ti,tas5086";
28 reg = <0x1b>;
29 reset-gpio = <&gpio 23 0>;
30 ti,charge-period = <156000>;
31 };
32 };
diff --git a/include/sound/tas5086.h b/include/sound/tas5086.h
new file mode 100644
index 000000000000..aac481b7db8f
--- /dev/null
+++ b/include/sound/tas5086.h
@@ -0,0 +1,7 @@
1#ifndef _SND_SOC_CODEC_TAS5086_H_
2#define _SND_SOC_CODEC_TAS5086_H_
3
4#define TAS5086_CLK_IDX_MCLK 0
5#define TAS5086_CLK_IDX_SCLK 1
6
7#endif /* _SND_SOC_CODEC_TAS5086_H_ */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index cf7b9897fa6b..2f45f00e31b0 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -64,6 +64,7 @@ config SND_SOC_ALL_CODECS
64 select SND_SOC_STA32X if I2C 64 select SND_SOC_STA32X if I2C
65 select SND_SOC_STA529 if I2C 65 select SND_SOC_STA529 if I2C
66 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 66 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
67 select SND_SOC_TAS5086 if I2C
67 select SND_SOC_TLV320AIC23 if I2C 68 select SND_SOC_TLV320AIC23 if I2C
68 select SND_SOC_TLV320AIC26 if SPI_MASTER 69 select SND_SOC_TLV320AIC26 if SPI_MASTER
69 select SND_SOC_TLV320AIC32X4 if I2C 70 select SND_SOC_TLV320AIC32X4 if I2C
@@ -324,6 +325,9 @@ config SND_SOC_STA529
324config SND_SOC_STAC9766 325config SND_SOC_STAC9766
325 tristate 326 tristate
326 327
328config SND_SOC_TAS5086
329 tristate
330
327config SND_SOC_TLV320AIC23 331config SND_SOC_TLV320AIC23
328 tristate 332 tristate
329 333
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 3a7ec1c39741..b9e41c9a1f4c 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -56,6 +56,7 @@ snd-soc-ssm2602-objs := ssm2602.o
56snd-soc-sta32x-objs := sta32x.o 56snd-soc-sta32x-objs := sta32x.o
57snd-soc-sta529-objs := sta529.o 57snd-soc-sta529-objs := sta529.o
58snd-soc-stac9766-objs := stac9766.o 58snd-soc-stac9766-objs := stac9766.o
59snd-soc-tas5086-objs := tas5086.o
59snd-soc-tlv320aic23-objs := tlv320aic23.o 60snd-soc-tlv320aic23-objs := tlv320aic23.o
60snd-soc-tlv320aic26-objs := tlv320aic26.o 61snd-soc-tlv320aic26-objs := tlv320aic26.o
61snd-soc-tlv320aic3x-objs := tlv320aic3x.o 62snd-soc-tlv320aic3x-objs := tlv320aic3x.o
@@ -179,6 +180,7 @@ obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
179obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o 180obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o
180obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o 181obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
181obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o 182obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
183obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
182obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 184obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
183obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 185obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
184obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 186obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c
new file mode 100644
index 000000000000..d447c4aa1d5e
--- /dev/null
+++ b/sound/soc/codecs/tas5086.c
@@ -0,0 +1,591 @@
1/*
2 * TAS5086 ASoC codec driver
3 *
4 * Copyright (c) 2013 Daniel Mack <zonque@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * TODO:
17 * - implement DAPM and input muxing
18 * - implement modulation limit
19 * - implement non-default PWM start
20 *
21 * Note that this chip has a very unusual register layout, specifically
22 * because the registers are of unequal size, and multi-byte registers
23 * require bulk writes to take effect. Regmap does not support that kind
24 * of devices.
25 *
26 * Currently, the driver does not touch any of the registers >= 0x20, so
27 * it doesn't matter because the entire map can be accessed as 8-bit
28 * array. In case more features will be added in the future
29 * that require access to higher registers, the entire regmap H/W I/O
30 * routines have to be open-coded.
31 */
32
33#include <linux/module.h>
34#include <linux/slab.h>
35#include <linux/delay.h>
36#include <linux/gpio.h>
37#include <linux/i2c.h>
38#include <linux/regmap.h>
39#include <linux/spi/spi.h>
40#include <linux/of_device.h>
41#include <linux/of_gpio.h>
42#include <sound/pcm.h>
43#include <sound/pcm_params.h>
44#include <sound/soc.h>
45#include <sound/tlv.h>
46#include <sound/tas5086.h>
47
48#define TAS5086_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
49 SNDRV_PCM_FMTBIT_S20_3LE | \
50 SNDRV_PCM_FMTBIT_S24_3LE)
51
52#define TAS5086_PCM_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
53 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
54 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \
55 SNDRV_PCM_RATE_192000)
56
57/*
58 * TAS5086 registers
59 */
60#define TAS5086_CLOCK_CONTROL 0x00 /* Clock control register */
61#define TAS5086_CLOCK_RATE(val) (val << 5)
62#define TAS5086_CLOCK_RATE_MASK (0x7 << 5)
63#define TAS5086_CLOCK_RATIO(val) (val << 2)
64#define TAS5086_CLOCK_RATIO_MASK (0x7 << 2)
65#define TAS5086_CLOCK_SCLK_RATIO_48 (1 << 1)
66#define TAS5086_CLOCK_VALID (1 << 0)
67
68#define TAS5086_DEEMPH_MASK 0x03
69#define TAS5086_SOFT_MUTE_ALL 0x3f
70
71#define TAS5086_DEV_ID 0x01 /* Device ID register */
72#define TAS5086_ERROR_STATUS 0x02 /* Error status register */
73#define TAS5086_SYS_CONTROL_1 0x03 /* System control register 1 */
74#define TAS5086_SERIAL_DATA_IF 0x04 /* Serial data interface register */
75#define TAS5086_SYS_CONTROL_2 0x05 /* System control register 2 */
76#define TAS5086_SOFT_MUTE 0x06 /* Soft mute register */
77#define TAS5086_MASTER_VOL 0x07 /* Master volume */
78#define TAS5086_CHANNEL_VOL(X) (0x08 + (X)) /* Channel 1-6 volume */
79#define TAS5086_VOLUME_CONTROL 0x09 /* Volume control register */
80#define TAS5086_MOD_LIMIT 0x10 /* Modulation limit register */
81#define TAS5086_PWM_START 0x18 /* PWM start register */
82#define TAS5086_SURROUND 0x19 /* Surround register */
83#define TAS5086_SPLIT_CAP_CHARGE 0x1a /* Split cap charge period register */
84#define TAS5086_OSC_TRIM 0x1b /* Oscillator trim register */
85#define TAS5086_BKNDERR 0x1c
86
87/*
88 * Default TAS5086 power-up configuration
89 */
90static const struct reg_default tas5086_reg_defaults[] = {
91 { 0x00, 0x6c },
92 { 0x01, 0x03 },
93 { 0x02, 0x00 },
94 { 0x03, 0xa0 },
95 { 0x04, 0x05 },
96 { 0x05, 0x60 },
97 { 0x06, 0x00 },
98 { 0x07, 0xff },
99 { 0x08, 0x30 },
100 { 0x09, 0x30 },
101 { 0x0a, 0x30 },
102 { 0x0b, 0x30 },
103 { 0x0c, 0x30 },
104 { 0x0d, 0x30 },
105 { 0x0e, 0xb1 },
106 { 0x0f, 0x00 },
107 { 0x10, 0x02 },
108 { 0x11, 0x00 },
109 { 0x12, 0x00 },
110 { 0x13, 0x00 },
111 { 0x14, 0x00 },
112 { 0x15, 0x00 },
113 { 0x16, 0x00 },
114 { 0x17, 0x00 },
115 { 0x18, 0x3f },
116 { 0x19, 0x00 },
117 { 0x1a, 0x18 },
118 { 0x1b, 0x82 },
119 { 0x1c, 0x05 },
120};
121
122static bool tas5086_accessible_reg(struct device *dev, unsigned int reg)
123{
124 return !((reg == 0x0f) || (reg >= 0x11 && reg <= 0x17));
125}
126
127static bool tas5086_volatile_reg(struct device *dev, unsigned int reg)
128{
129 switch (reg) {
130 case TAS5086_DEV_ID:
131 case TAS5086_ERROR_STATUS:
132 return true;
133 }
134
135 return false;
136}
137
138static bool tas5086_writeable_reg(struct device *dev, unsigned int reg)
139{
140 return tas5086_accessible_reg(dev, reg) && (reg != TAS5086_DEV_ID);
141}
142
143struct tas5086_private {
144 struct regmap *regmap;
145 unsigned int mclk, sclk;
146 unsigned int format;
147 bool deemph;
148 /* Current sample rate for de-emphasis control */
149 int rate;
150 /* GPIO driving Reset pin, if any */
151 int gpio_nreset;
152};
153
154static int tas5086_deemph[] = { 0, 32000, 44100, 48000 };
155
156static int tas5086_set_deemph(struct snd_soc_codec *codec)
157{
158 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
159 int i, val = 0;
160
161 if (priv->deemph)
162 for (i = 0; i < ARRAY_SIZE(tas5086_deemph); i++)
163 if (tas5086_deemph[i] == priv->rate)
164 val = i;
165
166 return regmap_update_bits(priv->regmap, TAS5086_SYS_CONTROL_1,
167 TAS5086_DEEMPH_MASK, val);
168}
169
170static int tas5086_get_deemph(struct snd_kcontrol *kcontrol,
171 struct snd_ctl_elem_value *ucontrol)
172{
173 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
174 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
175
176 ucontrol->value.enumerated.item[0] = priv->deemph;
177
178 return 0;
179}
180
181static int tas5086_put_deemph(struct snd_kcontrol *kcontrol,
182 struct snd_ctl_elem_value *ucontrol)
183{
184 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
185 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
186
187 priv->deemph = ucontrol->value.enumerated.item[0];
188
189 return tas5086_set_deemph(codec);
190}
191
192
193static int tas5086_set_dai_sysclk(struct snd_soc_dai *codec_dai,
194 int clk_id, unsigned int freq, int dir)
195{
196 struct snd_soc_codec *codec = codec_dai->codec;
197 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
198
199 switch (clk_id) {
200 case TAS5086_CLK_IDX_MCLK:
201 priv->mclk = freq;
202 break;
203 case TAS5086_CLK_IDX_SCLK:
204 priv->sclk = freq;
205 break;
206 }
207
208 return 0;
209}
210
211static int tas5086_set_dai_fmt(struct snd_soc_dai *codec_dai,
212 unsigned int format)
213{
214 struct snd_soc_codec *codec = codec_dai->codec;
215 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
216
217 /* The TAS5086 can only be slave to all clocks */
218 if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
219 dev_err(codec->dev, "Invalid clocking mode\n");
220 return -EINVAL;
221 }
222
223 /* we need to refer to the data format from hw_params() */
224 priv->format = format;
225
226 return 0;
227}
228
229static const int tas5086_sample_rates[] = {
230 32000, 38000, 44100, 48000, 88200, 96000, 176400, 192000
231};
232
233static const int tas5086_ratios[] = {
234 64, 128, 192, 256, 384, 512
235};
236
237static int index_in_array(const int *array, int len, int needle)
238{
239 int i;
240
241 for (i = 0; i < len; i++)
242 if (array[i] == needle)
243 return i;
244
245 return -ENOENT;
246}
247
248static int tas5086_hw_params(struct snd_pcm_substream *substream,
249 struct snd_pcm_hw_params *params,
250 struct snd_soc_dai *dai)
251{
252 struct snd_soc_codec *codec = dai->codec;
253 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
254 int val;
255 int ret;
256
257 priv->rate = params_rate(params);
258
259 /* Look up the sample rate and refer to the offset in the list */
260 val = index_in_array(tas5086_sample_rates,
261 ARRAY_SIZE(tas5086_sample_rates), priv->rate);
262
263 if (val < 0) {
264 dev_err(codec->dev, "Invalid sample rate\n");
265 return -EINVAL;
266 }
267
268 ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL,
269 TAS5086_CLOCK_RATE_MASK,
270 TAS5086_CLOCK_RATE(val));
271 if (ret < 0)
272 return ret;
273
274 /* MCLK / Fs ratio */
275 val = index_in_array(tas5086_ratios, ARRAY_SIZE(tas5086_ratios),
276 priv->mclk / priv->rate);
277 if (val < 0) {
278 dev_err(codec->dev, "Inavlid MCLK / Fs ratio\n");
279 return -EINVAL;
280 }
281
282 ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL,
283 TAS5086_CLOCK_RATIO_MASK,
284 TAS5086_CLOCK_RATIO(val));
285 if (ret < 0)
286 return ret;
287
288
289 ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL,
290 TAS5086_CLOCK_SCLK_RATIO_48,
291 (priv->sclk == 48 * priv->rate) ?
292 TAS5086_CLOCK_SCLK_RATIO_48 : 0);
293 if (ret < 0)
294 return ret;
295
296 /*
297 * The chip has a very unituitive register mapping and muxes information
298 * about data format and sample depth into the same register, but not on
299 * a logical bit-boundary. Hence, we have to refer to the format passed
300 * in the set_dai_fmt() callback and set up everything from here.
301 *
302 * First, determine the 'base' value, using the format ...
303 */
304 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
305 case SND_SOC_DAIFMT_RIGHT_J:
306 val = 0x00;
307 break;
308 case SND_SOC_DAIFMT_I2S:
309 val = 0x03;
310 break;
311 case SND_SOC_DAIFMT_LEFT_J:
312 val = 0x06;
313 break;
314 default:
315 dev_err(codec->dev, "Invalid DAI format\n");
316 return -EINVAL;
317 }
318
319 /* ... then add the offset for the sample bit depth. */
320 switch (params_format(params)) {
321 case SNDRV_PCM_FORMAT_S16_LE:
322 val += 0;
323 break;
324 case SNDRV_PCM_FORMAT_S20_3LE:
325 val += 1;
326 break;
327 case SNDRV_PCM_FORMAT_S24_3LE:
328 val += 2;
329 break;
330 default:
331 dev_err(codec->dev, "Invalid bit width\n");
332 return -EINVAL;
333 };
334
335 ret = regmap_write(priv->regmap, TAS5086_SERIAL_DATA_IF, val);
336 if (ret < 0)
337 return ret;
338
339 /* clock is considered valid now */
340 ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL,
341 TAS5086_CLOCK_VALID, TAS5086_CLOCK_VALID);
342 if (ret < 0)
343 return ret;
344
345 return tas5086_set_deemph(codec);
346}
347
348static int tas5086_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
349{
350 struct snd_soc_codec *codec = dai->codec;
351 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
352 unsigned int val = 0;
353
354 if (mute)
355 val = TAS5086_SOFT_MUTE_ALL;
356
357 return regmap_write(priv->regmap, TAS5086_SOFT_MUTE, val);
358}
359
360/* TAS5086 controls */
361static const DECLARE_TLV_DB_SCALE(tas5086_dac_tlv, -10350, 50, 1);
362
363static const struct snd_kcontrol_new tas5086_controls[] = {
364 SOC_SINGLE_TLV("Master Playback Volume", TAS5086_MASTER_VOL,
365 0, 0xff, 1, tas5086_dac_tlv),
366 SOC_DOUBLE_R_TLV("Channel 1/2 Playback Volume",
367 TAS5086_CHANNEL_VOL(0), TAS5086_CHANNEL_VOL(1),
368 0, 0xff, 1, tas5086_dac_tlv),
369 SOC_DOUBLE_R_TLV("Channel 3/4 Playback Volume",
370 TAS5086_CHANNEL_VOL(2), TAS5086_CHANNEL_VOL(3),
371 0, 0xff, 1, tas5086_dac_tlv),
372 SOC_DOUBLE_R_TLV("Channel 5/6 Playback Volume",
373 TAS5086_CHANNEL_VOL(4), TAS5086_CHANNEL_VOL(5),
374 0, 0xff, 1, tas5086_dac_tlv),
375 SOC_SINGLE_BOOL_EXT("De-emphasis Switch", 0,
376 tas5086_get_deemph, tas5086_put_deemph),
377};
378
379static const struct snd_soc_dai_ops tas5086_dai_ops = {
380 .hw_params = tas5086_hw_params,
381 .set_sysclk = tas5086_set_dai_sysclk,
382 .set_fmt = tas5086_set_dai_fmt,
383 .mute_stream = tas5086_mute_stream,
384};
385
386static struct snd_soc_dai_driver tas5086_dai = {
387 .name = "tas5086-hifi",
388 .playback = {
389 .stream_name = "Playback",
390 .channels_min = 2,
391 .channels_max = 6,
392 .rates = TAS5086_PCM_RATES,
393 .formats = TAS5086_PCM_FORMATS,
394 },
395 .ops = &tas5086_dai_ops,
396};
397
398#ifdef CONFIG_PM
399static int tas5086_soc_resume(struct snd_soc_codec *codec)
400{
401 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
402
403 /* Restore codec state */
404 return regcache_sync(priv->regmap);
405}
406#else
407#define tas5086_soc_resume NULL
408#endif /* CONFIG_PM */
409
410#ifdef CONFIG_OF
411static const struct of_device_id tas5086_dt_ids[] = {
412 { .compatible = "ti,tas5086", },
413 { }
414};
415MODULE_DEVICE_TABLE(of, tas5086_dt_ids);
416#endif
417
418/* charge period values in microseconds */
419static const int tas5086_charge_period[] = {
420 13000, 16900, 23400, 31200, 41600, 54600, 72800, 96200,
421 130000, 156000, 234000, 312000, 416000, 546000, 728000, 962000,
422 1300000, 169000, 2340000, 3120000, 4160000, 5460000, 7280000, 9620000,
423};
424
425static int tas5086_probe(struct snd_soc_codec *codec)
426{
427 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
428 int charge_period = 1300000; /* hardware default is 1300 ms */
429 int i, ret;
430
431 if (of_match_device(of_match_ptr(tas5086_dt_ids), codec->dev)) {
432 struct device_node *of_node = codec->dev->of_node;
433 of_property_read_u32(of_node, "ti,charge-period", &charge_period);
434 }
435
436 /* lookup and set split-capacitor charge period */
437 if (charge_period == 0) {
438 regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, 0);
439 } else {
440 i = index_in_array(tas5086_charge_period,
441 ARRAY_SIZE(tas5086_charge_period),
442 charge_period);
443 if (i >= 0)
444 regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE,
445 i + 0x08);
446 else
447 dev_warn(codec->dev,
448 "Invalid split-cap charge period of %d ns.\n",
449 charge_period);
450 }
451
452 /* enable factory trim */
453 ret = regmap_write(priv->regmap, TAS5086_OSC_TRIM, 0x00);
454 if (ret < 0)
455 return ret;
456
457 /* start all channels */
458 ret = regmap_write(priv->regmap, TAS5086_SYS_CONTROL_2, 0x20);
459 if (ret < 0)
460 return ret;
461
462 /* set master volume to 0 dB */
463 ret = regmap_write(priv->regmap, TAS5086_MASTER_VOL, 0x30);
464 if (ret < 0)
465 return ret;
466
467 /* mute all channels for now */
468 ret = regmap_write(priv->regmap, TAS5086_SOFT_MUTE,
469 TAS5086_SOFT_MUTE_ALL);
470 if (ret < 0)
471 return ret;
472
473 return 0;
474}
475
476static int tas5086_remove(struct snd_soc_codec *codec)
477{
478 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
479
480 if (gpio_is_valid(priv->gpio_nreset))
481 /* Set codec to the reset state */
482 gpio_set_value(priv->gpio_nreset, 0);
483
484 return 0;
485};
486
487static struct snd_soc_codec_driver soc_codec_dev_tas5086 = {
488 .probe = tas5086_probe,
489 .remove = tas5086_remove,
490 .resume = tas5086_soc_resume,
491 .controls = tas5086_controls,
492 .num_controls = ARRAY_SIZE(tas5086_controls),
493};
494
495static const struct i2c_device_id tas5086_i2c_id[] = {
496 { "tas5086", 0 },
497 { }
498};
499MODULE_DEVICE_TABLE(i2c, tas5086_i2c_id);
500
501static const struct regmap_config tas5086_regmap = {
502 .reg_bits = 8,
503 .val_bits = 8,
504 .max_register = ARRAY_SIZE(tas5086_reg_defaults),
505 .reg_defaults = tas5086_reg_defaults,
506 .num_reg_defaults = ARRAY_SIZE(tas5086_reg_defaults),
507 .cache_type = REGCACHE_RBTREE,
508 .volatile_reg = tas5086_volatile_reg,
509 .writeable_reg = tas5086_writeable_reg,
510 .readable_reg = tas5086_accessible_reg,
511};
512
513static int tas5086_i2c_probe(struct i2c_client *i2c,
514 const struct i2c_device_id *id)
515{
516 struct tas5086_private *priv;
517 struct device *dev = &i2c->dev;
518 int gpio_nreset = -EINVAL;
519 int i, ret;
520
521 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
522 if (!priv)
523 return -ENOMEM;
524
525 priv->regmap = devm_regmap_init_i2c(i2c, &tas5086_regmap);
526 if (IS_ERR(priv->regmap)) {
527 ret = PTR_ERR(priv->regmap);
528 dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret);
529 return ret;
530 }
531
532 i2c_set_clientdata(i2c, priv);
533
534 if (of_match_device(of_match_ptr(tas5086_dt_ids), dev)) {
535 struct device_node *of_node = dev->of_node;
536 gpio_nreset = of_get_named_gpio(of_node, "reset-gpio", 0);
537 }
538
539 if (gpio_is_valid(gpio_nreset))
540 if (devm_gpio_request(dev, gpio_nreset, "TAS5086 Reset"))
541 gpio_nreset = -EINVAL;
542
543 if (gpio_is_valid(gpio_nreset)) {
544 /* Reset codec - minimum assertion time is 400ns */
545 gpio_direction_output(gpio_nreset, 0);
546 udelay(1);
547 gpio_set_value(gpio_nreset, 1);
548
549 /* Codec needs ~15ms to wake up */
550 msleep(15);
551 }
552
553 priv->gpio_nreset = gpio_nreset;
554
555 /* The TAS5086 always returns 0x03 in its TAS5086_DEV_ID register */
556 ret = regmap_read(priv->regmap, TAS5086_DEV_ID, &i);
557 if (ret < 0)
558 return ret;
559
560 if (i != 0x3) {
561 dev_err(dev,
562 "Failed to identify TAS5086 codec (got %02x)\n", i);
563 return -ENODEV;
564 }
565
566 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_tas5086,
567 &tas5086_dai, 1);
568}
569
570static int tas5086_i2c_remove(struct i2c_client *i2c)
571{
572 snd_soc_unregister_codec(&i2c->dev);
573 return 0;
574}
575
576static struct i2c_driver tas5086_i2c_driver = {
577 .driver = {
578 .name = "tas5086",
579 .owner = THIS_MODULE,
580 .of_match_table = of_match_ptr(tas5086_dt_ids),
581 },
582 .id_table = tas5086_i2c_id,
583 .probe = tas5086_i2c_probe,
584 .remove = tas5086_i2c_remove,
585};
586
587module_i2c_driver(tas5086_i2c_driver);
588
589MODULE_AUTHOR("Daniel Mack <zonque@gmail.com>");
590MODULE_DESCRIPTION("Texas Instruments TAS5086 ALSA SoC Codec Driver");
591MODULE_LICENSE("GPL");