ASoC: tas571x: added missing register literals
[linux-2.6-block.git] / sound / soc / codecs / tas571x.c
CommitLineData
3fd6e7d9
KC
1/*
2 * TAS571x amplifier audio driver
3 *
4 * Copyright (C) 2015 Google, Inc.
5 * Copyright (c) 2013 Daniel Mack <zonque@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/clk.h>
14#include <linux/delay.h>
15#include <linux/device.h>
16#include <linux/gpio/consumer.h>
17#include <linux/i2c.h>
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/of_device.h>
22#include <linux/regmap.h>
23#include <linux/regulator/consumer.h>
24#include <linux/stddef.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/tlv.h>
28
29#include "tas571x.h"
30
31#define TAS571X_MAX_SUPPLIES 6
32
33struct tas571x_chip {
34 const char *const *supply_names;
35 int num_supply_names;
36 const struct snd_kcontrol_new *controls;
37 int num_controls;
38 const struct regmap_config *regmap_config;
39 int vol_reg_size;
40};
41
42struct tas571x_private {
43 const struct tas571x_chip *chip;
44 struct regmap *regmap;
45 struct regulator_bulk_data supplies[TAS571X_MAX_SUPPLIES];
46 struct clk *mclk;
47 unsigned int format;
48 struct gpio_desc *reset_gpio;
49 struct gpio_desc *pdn_gpio;
50 struct snd_soc_codec_driver codec_driver;
51};
52
53static int tas571x_register_size(struct tas571x_private *priv, unsigned int reg)
54{
55 switch (reg) {
56 case TAS571X_MVOL_REG:
57 case TAS571X_CH1_VOL_REG:
58 case TAS571X_CH2_VOL_REG:
59 return priv->chip->vol_reg_size;
a593ed09
PK
60 case TAS571X_INPUT_MUX_REG:
61 case TAS571X_CH4_SRC_SELECT_REG:
62 case TAS571X_PWM_MUX_REG:
63 return 4;
3fd6e7d9
KC
64 default:
65 return 1;
66 }
67}
68
69static int tas571x_reg_write(void *context, unsigned int reg,
70 unsigned int value)
71{
72 struct i2c_client *client = context;
73 struct tas571x_private *priv = i2c_get_clientdata(client);
74 unsigned int i, size;
75 uint8_t buf[5];
76 int ret;
77
78 size = tas571x_register_size(priv, reg);
79 buf[0] = reg;
80
81 for (i = size; i >= 1; --i) {
82 buf[i] = value;
83 value >>= 8;
84 }
85
86 ret = i2c_master_send(client, buf, size + 1);
87 if (ret == size + 1)
88 return 0;
89 else if (ret < 0)
90 return ret;
91 else
92 return -EIO;
93}
94
95static int tas571x_reg_read(void *context, unsigned int reg,
96 unsigned int *value)
97{
98 struct i2c_client *client = context;
99 struct tas571x_private *priv = i2c_get_clientdata(client);
100 uint8_t send_buf, recv_buf[4];
101 struct i2c_msg msgs[2];
102 unsigned int size;
103 unsigned int i;
104 int ret;
105
106 size = tas571x_register_size(priv, reg);
107 send_buf = reg;
108
109 msgs[0].addr = client->addr;
110 msgs[0].len = sizeof(send_buf);
111 msgs[0].buf = &send_buf;
112 msgs[0].flags = 0;
113
114 msgs[1].addr = client->addr;
115 msgs[1].len = size;
116 msgs[1].buf = recv_buf;
117 msgs[1].flags = I2C_M_RD;
118
119 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
120 if (ret < 0)
121 return ret;
122 else if (ret != ARRAY_SIZE(msgs))
123 return -EIO;
124
125 *value = 0;
126
127 for (i = 0; i < size; i++) {
128 *value <<= 8;
129 *value |= recv_buf[i];
130 }
131
132 return 0;
133}
134
135static int tas571x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format)
136{
137 struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec);
138
139 priv->format = format;
140
141 return 0;
142}
143
144static int tas571x_hw_params(struct snd_pcm_substream *substream,
145 struct snd_pcm_hw_params *params,
146 struct snd_soc_dai *dai)
147{
148 struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec);
149 u32 val;
150
151 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
152 case SND_SOC_DAIFMT_RIGHT_J:
153 val = 0x00;
154 break;
155 case SND_SOC_DAIFMT_I2S:
156 val = 0x03;
157 break;
158 case SND_SOC_DAIFMT_LEFT_J:
159 val = 0x06;
160 break;
161 default:
162 return -EINVAL;
163 }
164
165 if (params_width(params) >= 24)
166 val += 2;
167 else if (params_width(params) >= 20)
168 val += 1;
169
170 return regmap_update_bits(priv->regmap, TAS571X_SDI_REG,
171 TAS571X_SDI_FMT_MASK, val);
172}
173
04004850
PK
174static int tas571x_mute(struct snd_soc_dai *dai, int mute)
175{
176 struct snd_soc_codec *codec = dai->codec;
177 u8 sysctl2;
178 int ret;
179
180 sysctl2 = mute ? TAS571X_SYS_CTRL_2_SDN_MASK : 0;
181
182 ret = snd_soc_update_bits(codec,
183 TAS571X_SYS_CTRL_2_REG,
184 TAS571X_SYS_CTRL_2_SDN_MASK,
185 sysctl2);
186 usleep_range(1000, 2000);
187
188 return ret;
189}
190
3fd6e7d9
KC
191static int tas571x_set_bias_level(struct snd_soc_codec *codec,
192 enum snd_soc_bias_level level)
193{
194 struct tas571x_private *priv = snd_soc_codec_get_drvdata(codec);
195 int ret;
196
197 switch (level) {
198 case SND_SOC_BIAS_ON:
199 break;
200 case SND_SOC_BIAS_PREPARE:
201 break;
202 case SND_SOC_BIAS_STANDBY:
8f218fa9 203 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
3fd6e7d9
KC
204 if (!IS_ERR(priv->mclk)) {
205 ret = clk_prepare_enable(priv->mclk);
206 if (ret) {
207 dev_err(codec->dev,
208 "Failed to enable master clock: %d\n",
209 ret);
210 return ret;
211 }
212 }
213
214 gpiod_set_value(priv->pdn_gpio, 0);
215 usleep_range(5000, 6000);
216
217 regcache_cache_only(priv->regmap, false);
218 ret = regcache_sync(priv->regmap);
219 if (ret)
220 return ret;
221 }
222 break;
223 case SND_SOC_BIAS_OFF:
224 regcache_cache_only(priv->regmap, true);
225 gpiod_set_value(priv->pdn_gpio, 1);
226
227 if (!IS_ERR(priv->mclk))
228 clk_disable_unprepare(priv->mclk);
229 break;
230 }
231
3fd6e7d9
KC
232 return 0;
233}
234
235static const struct snd_soc_dai_ops tas571x_dai_ops = {
236 .set_fmt = tas571x_set_dai_fmt,
237 .hw_params = tas571x_hw_params,
04004850 238 .digital_mute = tas571x_mute,
3fd6e7d9
KC
239};
240
241static const char *const tas5711_supply_names[] = {
242 "AVDD",
243 "DVDD",
244 "PVDD_A",
245 "PVDD_B",
246 "PVDD_C",
247 "PVDD_D",
248};
249
250static const DECLARE_TLV_DB_SCALE(tas5711_volume_tlv, -10350, 50, 1);
251
252static const struct snd_kcontrol_new tas5711_controls[] = {
253 SOC_SINGLE_TLV("Master Volume",
254 TAS571X_MVOL_REG,
255 0, 0xff, 1, tas5711_volume_tlv),
256 SOC_DOUBLE_R_TLV("Speaker Volume",
257 TAS571X_CH1_VOL_REG,
258 TAS571X_CH2_VOL_REG,
259 0, 0xff, 1, tas5711_volume_tlv),
260 SOC_DOUBLE("Speaker Switch",
261 TAS571X_SOFT_MUTE_REG,
262 TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
263 1, 1),
264};
265
a593ed09
PK
266static const struct regmap_range tas571x_readonly_regs_range[] = {
267 regmap_reg_range(TAS571X_CLK_CTRL_REG, TAS571X_DEV_ID_REG),
268};
269
270static const struct regmap_range tas571x_volatile_regs_range[] = {
271 regmap_reg_range(TAS571X_CLK_CTRL_REG, TAS571X_ERR_STATUS_REG),
272 regmap_reg_range(TAS571X_OSC_TRIM_REG, TAS571X_OSC_TRIM_REG),
273};
274
275static const struct regmap_access_table tas571x_write_regs = {
276 .no_ranges = tas571x_readonly_regs_range,
277 .n_no_ranges = ARRAY_SIZE(tas571x_readonly_regs_range),
278};
279
280static const struct regmap_access_table tas571x_volatile_regs = {
281 .yes_ranges = tas571x_volatile_regs_range,
282 .n_yes_ranges = ARRAY_SIZE(tas571x_volatile_regs_range),
283
284};
285
3fd6e7d9
KC
286static const struct reg_default tas5711_reg_defaults[] = {
287 { 0x04, 0x05 },
288 { 0x05, 0x40 },
289 { 0x06, 0x00 },
290 { 0x07, 0xff },
291 { 0x08, 0x30 },
292 { 0x09, 0x30 },
293 { 0x1b, 0x82 },
294};
295
296static const struct regmap_config tas5711_regmap_config = {
297 .reg_bits = 8,
298 .val_bits = 32,
299 .max_register = 0xff,
300 .reg_read = tas571x_reg_read,
301 .reg_write = tas571x_reg_write,
302 .reg_defaults = tas5711_reg_defaults,
303 .num_reg_defaults = ARRAY_SIZE(tas5711_reg_defaults),
304 .cache_type = REGCACHE_RBTREE,
a593ed09
PK
305 .wr_table = &tas571x_write_regs,
306 .volatile_table = &tas571x_volatile_regs,
3fd6e7d9
KC
307};
308
309static const struct tas571x_chip tas5711_chip = {
310 .supply_names = tas5711_supply_names,
311 .num_supply_names = ARRAY_SIZE(tas5711_supply_names),
312 .controls = tas5711_controls,
313 .num_controls = ARRAY_SIZE(tas5711_controls),
314 .regmap_config = &tas5711_regmap_config,
315 .vol_reg_size = 1,
316};
317
318static const char *const tas5717_supply_names[] = {
319 "AVDD",
320 "DVDD",
321 "HPVDD",
322 "PVDD_AB",
323 "PVDD_CD",
324};
325
326static const DECLARE_TLV_DB_SCALE(tas5717_volume_tlv, -10375, 25, 0);
327
328static const struct snd_kcontrol_new tas5717_controls[] = {
329 /* MVOL LSB is ignored - see comments in tas571x_i2c_probe() */
330 SOC_SINGLE_TLV("Master Volume",
331 TAS571X_MVOL_REG, 1, 0x1ff, 1,
332 tas5717_volume_tlv),
333 SOC_DOUBLE_R_TLV("Speaker Volume",
334 TAS571X_CH1_VOL_REG, TAS571X_CH2_VOL_REG,
335 1, 0x1ff, 1, tas5717_volume_tlv),
336 SOC_DOUBLE("Speaker Switch",
337 TAS571X_SOFT_MUTE_REG,
338 TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
339 1, 1),
340};
341
342static const struct reg_default tas5717_reg_defaults[] = {
343 { 0x04, 0x05 },
344 { 0x05, 0x40 },
345 { 0x06, 0x00 },
346 { 0x07, 0x03ff },
347 { 0x08, 0x00c0 },
348 { 0x09, 0x00c0 },
349 { 0x1b, 0x82 },
350};
351
352static const struct regmap_config tas5717_regmap_config = {
353 .reg_bits = 8,
354 .val_bits = 32,
355 .max_register = 0xff,
356 .reg_read = tas571x_reg_read,
357 .reg_write = tas571x_reg_write,
358 .reg_defaults = tas5717_reg_defaults,
359 .num_reg_defaults = ARRAY_SIZE(tas5717_reg_defaults),
360 .cache_type = REGCACHE_RBTREE,
a593ed09
PK
361 .wr_table = &tas571x_write_regs,
362 .volatile_table = &tas571x_volatile_regs,
3fd6e7d9
KC
363};
364
365/* This entry is reused for tas5719 as the software interface is identical. */
366static const struct tas571x_chip tas5717_chip = {
367 .supply_names = tas5717_supply_names,
368 .num_supply_names = ARRAY_SIZE(tas5717_supply_names),
369 .controls = tas5717_controls,
370 .num_controls = ARRAY_SIZE(tas5717_controls),
371 .regmap_config = &tas5717_regmap_config,
372 .vol_reg_size = 2,
373};
374
375static const struct snd_soc_dapm_widget tas571x_dapm_widgets[] = {
376 SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
377 SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
378
379 SND_SOC_DAPM_OUTPUT("OUT_A"),
380 SND_SOC_DAPM_OUTPUT("OUT_B"),
381 SND_SOC_DAPM_OUTPUT("OUT_C"),
382 SND_SOC_DAPM_OUTPUT("OUT_D"),
383};
384
385static const struct snd_soc_dapm_route tas571x_dapm_routes[] = {
386 { "DACL", NULL, "Playback" },
387 { "DACR", NULL, "Playback" },
388
389 { "OUT_A", NULL, "DACL" },
390 { "OUT_B", NULL, "DACL" },
391 { "OUT_C", NULL, "DACR" },
392 { "OUT_D", NULL, "DACR" },
393};
394
395static const struct snd_soc_codec_driver tas571x_codec = {
396 .set_bias_level = tas571x_set_bias_level,
397 .idle_bias_off = true,
398
399 .dapm_widgets = tas571x_dapm_widgets,
400 .num_dapm_widgets = ARRAY_SIZE(tas571x_dapm_widgets),
401 .dapm_routes = tas571x_dapm_routes,
402 .num_dapm_routes = ARRAY_SIZE(tas571x_dapm_routes),
403};
404
405static struct snd_soc_dai_driver tas571x_dai = {
406 .name = "tas571x-hifi",
407 .playback = {
408 .stream_name = "Playback",
409 .channels_min = 2,
410 .channels_max = 2,
411 .rates = SNDRV_PCM_RATE_8000_48000,
412 .formats = SNDRV_PCM_FMTBIT_S32_LE |
413 SNDRV_PCM_FMTBIT_S24_LE |
414 SNDRV_PCM_FMTBIT_S16_LE,
415 },
416 .ops = &tas571x_dai_ops,
417};
418
419static const struct of_device_id tas571x_of_match[];
420
421static int tas571x_i2c_probe(struct i2c_client *client,
422 const struct i2c_device_id *id)
423{
424 struct tas571x_private *priv;
425 struct device *dev = &client->dev;
97fceb4d 426 const struct of_device_id *of_id;
3fd6e7d9
KC
427 int i, ret;
428
429 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
430 if (!priv)
431 return -ENOMEM;
432 i2c_set_clientdata(client, priv);
433
97fceb4d 434 of_id = of_match_device(tas571x_of_match, dev);
630e413d
PK
435 if (of_id)
436 priv->chip = of_id->data;
437 else
438 priv->chip = (void *) id->driver_data;
3fd6e7d9
KC
439
440 priv->mclk = devm_clk_get(dev, "mclk");
441 if (IS_ERR(priv->mclk) && PTR_ERR(priv->mclk) != -ENOENT) {
442 dev_err(dev, "Failed to request mclk: %ld\n",
443 PTR_ERR(priv->mclk));
444 return PTR_ERR(priv->mclk);
445 }
446
447 BUG_ON(priv->chip->num_supply_names > TAS571X_MAX_SUPPLIES);
448 for (i = 0; i < priv->chip->num_supply_names; i++)
449 priv->supplies[i].supply = priv->chip->supply_names[i];
450
451 ret = devm_regulator_bulk_get(dev, priv->chip->num_supply_names,
452 priv->supplies);
453 if (ret) {
454 dev_err(dev, "Failed to get supplies: %d\n", ret);
455 return ret;
456 }
457 ret = regulator_bulk_enable(priv->chip->num_supply_names,
458 priv->supplies);
459 if (ret) {
460 dev_err(dev, "Failed to enable supplies: %d\n", ret);
461 return ret;
462 }
463
464 priv->regmap = devm_regmap_init(dev, NULL, client,
465 priv->chip->regmap_config);
466 if (IS_ERR(priv->regmap))
467 return PTR_ERR(priv->regmap);
468
469 priv->pdn_gpio = devm_gpiod_get_optional(dev, "pdn", GPIOD_OUT_LOW);
470 if (IS_ERR(priv->pdn_gpio)) {
471 dev_err(dev, "error requesting pdn_gpio: %ld\n",
472 PTR_ERR(priv->pdn_gpio));
473 return PTR_ERR(priv->pdn_gpio);
474 }
475
476 priv->reset_gpio = devm_gpiod_get_optional(dev, "reset",
477 GPIOD_OUT_HIGH);
478 if (IS_ERR(priv->reset_gpio)) {
479 dev_err(dev, "error requesting reset_gpio: %ld\n",
480 PTR_ERR(priv->reset_gpio));
481 return PTR_ERR(priv->reset_gpio);
482 } else if (priv->reset_gpio) {
483 /* pulse the active low reset line for ~100us */
484 usleep_range(100, 200);
485 gpiod_set_value(priv->reset_gpio, 0);
486 usleep_range(12000, 20000);
487 }
488
489 ret = regmap_write(priv->regmap, TAS571X_OSC_TRIM_REG, 0);
490 if (ret)
491 return ret;
492
3fd6e7d9
KC
493
494 memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver));
495 priv->codec_driver.controls = priv->chip->controls;
496 priv->codec_driver.num_controls = priv->chip->num_controls;
497
498 if (priv->chip->vol_reg_size == 2) {
499 /*
500 * The master volume defaults to 0x3ff (mute), but we ignore
501 * (zero) the LSB because the hardware step size is 0.125 dB
502 * and TLV_DB_SCALE_ITEM has a resolution of 0.01 dB.
503 */
504 ret = regmap_update_bits(priv->regmap, TAS571X_MVOL_REG, 1, 0);
505 if (ret)
506 return ret;
507 }
508
509 regcache_cache_only(priv->regmap, true);
510 gpiod_set_value(priv->pdn_gpio, 1);
511
512 return snd_soc_register_codec(&client->dev, &priv->codec_driver,
513 &tas571x_dai, 1);
514}
515
516static int tas571x_i2c_remove(struct i2c_client *client)
517{
518 struct tas571x_private *priv = i2c_get_clientdata(client);
519
520 snd_soc_unregister_codec(&client->dev);
521 regulator_bulk_disable(priv->chip->num_supply_names, priv->supplies);
522
523 return 0;
524}
525
526static const struct of_device_id tas571x_of_match[] = {
527 { .compatible = "ti,tas5711", .data = &tas5711_chip, },
528 { .compatible = "ti,tas5717", .data = &tas5717_chip, },
529 { .compatible = "ti,tas5719", .data = &tas5717_chip, },
530 { }
531};
532MODULE_DEVICE_TABLE(of, tas571x_of_match);
533
534static const struct i2c_device_id tas571x_i2c_id[] = {
630e413d
PK
535 { "tas5711", (kernel_ulong_t) &tas5711_chip },
536 { "tas5717", (kernel_ulong_t) &tas5717_chip },
537 { "tas5719", (kernel_ulong_t) &tas5717_chip },
3fd6e7d9
KC
538 { }
539};
540MODULE_DEVICE_TABLE(i2c, tas571x_i2c_id);
541
542static struct i2c_driver tas571x_i2c_driver = {
543 .driver = {
544 .name = "tas571x",
545 .of_match_table = of_match_ptr(tas571x_of_match),
546 },
547 .probe = tas571x_i2c_probe,
548 .remove = tas571x_i2c_remove,
549 .id_table = tas571x_i2c_id,
550};
551module_i2c_driver(tas571x_i2c_driver);
552
553MODULE_DESCRIPTION("ASoC TAS571x driver");
554MODULE_AUTHOR("Kevin Cernekee <cernekee@chromium.org>");
555MODULE_LICENSE("GPL");