Skip to content

Commit 1a94600

Browse files
committed
Merge remote-tracking branches 'asoc/topic/tas571x', 'asoc/topic/tlv320aic31xx', 'asoc/topic/tpa6130a2', 'asoc/topic/twl6040' and 'asoc/topic/wm8731' into asoc-next
6 parents 9a6a362 + f7d3d2d + 11f9192 + 39088c2 + d13e436 + cf5ef3a commit 1a94600

File tree

8 files changed

+438
-385
lines changed

8 files changed

+438
-385
lines changed

sound/soc/codecs/tas571x.c

+188
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <sound/pcm_params.h>
2929
#include <sound/soc.h>
3030
#include <sound/tlv.h>
31+
#include <asm/unaligned.h>
3132

3233
#include "tas571x.h"
3334

@@ -63,6 +64,10 @@ static int tas571x_register_size(struct tas571x_private *priv, unsigned int reg)
6364
case TAS571X_INPUT_MUX_REG:
6465
case TAS571X_CH4_SRC_SELECT_REG:
6566
case TAS571X_PWM_MUX_REG:
67+
case TAS5717_CH1_RIGHT_CH_MIX_REG:
68+
case TAS5717_CH1_LEFT_CH_MIX_REG:
69+
case TAS5717_CH2_LEFT_CH_MIX_REG:
70+
case TAS5717_CH2_RIGHT_CH_MIX_REG:
6671
return 4;
6772
default:
6873
return 1;
@@ -135,6 +140,129 @@ static int tas571x_reg_read(void *context, unsigned int reg,
135140
return 0;
136141
}
137142

143+
/*
144+
* register write for 8- and 20-byte registers
145+
*/
146+
static int tas571x_reg_write_multiword(struct i2c_client *client,
147+
unsigned int reg, const long values[], size_t len)
148+
{
149+
size_t i;
150+
uint8_t *buf, *p;
151+
int ret;
152+
size_t send_size = 1 + len * sizeof(uint32_t);
153+
154+
buf = kzalloc(send_size, GFP_KERNEL | GFP_DMA);
155+
if (!buf)
156+
return -ENOMEM;
157+
buf[0] = reg;
158+
159+
for (i = 0, p = buf + 1; i < len; i++, p += sizeof(uint32_t))
160+
put_unaligned_be32(values[i], p);
161+
162+
ret = i2c_master_send(client, buf, send_size);
163+
164+
kfree(buf);
165+
166+
if (ret == send_size)
167+
return 0;
168+
else if (ret < 0)
169+
return ret;
170+
else
171+
return -EIO;
172+
}
173+
174+
/*
175+
* register read for 8- and 20-byte registers
176+
*/
177+
static int tas571x_reg_read_multiword(struct i2c_client *client,
178+
unsigned int reg, long values[], size_t len)
179+
{
180+
unsigned int i;
181+
uint8_t send_buf;
182+
uint8_t *recv_buf, *p;
183+
struct i2c_msg msgs[2];
184+
unsigned int recv_size = len * sizeof(uint32_t);
185+
int ret;
186+
187+
recv_buf = kzalloc(recv_size, GFP_KERNEL | GFP_DMA);
188+
if (!recv_buf)
189+
return -ENOMEM;
190+
191+
send_buf = reg;
192+
193+
msgs[0].addr = client->addr;
194+
msgs[0].len = sizeof(send_buf);
195+
msgs[0].buf = &send_buf;
196+
msgs[0].flags = 0;
197+
198+
msgs[1].addr = client->addr;
199+
msgs[1].len = recv_size;
200+
msgs[1].buf = recv_buf;
201+
msgs[1].flags = I2C_M_RD;
202+
203+
ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
204+
if (ret < 0)
205+
goto err_ret;
206+
else if (ret != ARRAY_SIZE(msgs)) {
207+
ret = -EIO;
208+
goto err_ret;
209+
}
210+
211+
for (i = 0, p = recv_buf; i < len; i++, p += sizeof(uint32_t))
212+
values[i] = get_unaligned_be32(p);
213+
214+
err_ret:
215+
kfree(recv_buf);
216+
return ret;
217+
}
218+
219+
/*
220+
* Integer array controls for setting biquad, mixer, DRC coefficients.
221+
* According to the datasheet each coefficient is effectively 26bits,
222+
* i.e. stored as 32bits, where bits [31:26] are ignored.
223+
* TI's TAS57xx Graphical Development Environment tool however produces
224+
* coefficients with more than 26 bits. For this reason we allow values
225+
* in the full 32-bits reange.
226+
* The coefficients are ordered as given in the TAS571x data sheet:
227+
* b0, b1, b2, a1, a2
228+
*/
229+
230+
static int tas571x_coefficient_info(struct snd_kcontrol *kcontrol,
231+
struct snd_ctl_elem_info *uinfo)
232+
{
233+
int numcoef = kcontrol->private_value >> 16;
234+
235+
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
236+
uinfo->count = numcoef;
237+
uinfo->value.integer.min = 0;
238+
uinfo->value.integer.max = 0xffffffff;
239+
return 0;
240+
}
241+
242+
static int tas571x_coefficient_get(struct snd_kcontrol *kcontrol,
243+
struct snd_ctl_elem_value *ucontrol)
244+
{
245+
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
246+
struct i2c_client *i2c = to_i2c_client(codec->dev);
247+
int numcoef = kcontrol->private_value >> 16;
248+
int index = kcontrol->private_value & 0xffff;
249+
250+
return tas571x_reg_read_multiword(i2c, index,
251+
ucontrol->value.integer.value, numcoef);
252+
}
253+
254+
static int tas571x_coefficient_put(struct snd_kcontrol *kcontrol,
255+
struct snd_ctl_elem_value *ucontrol)
256+
{
257+
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
258+
struct i2c_client *i2c = to_i2c_client(codec->dev);
259+
int numcoef = kcontrol->private_value >> 16;
260+
int index = kcontrol->private_value & 0xffff;
261+
262+
return tas571x_reg_write_multiword(i2c, index,
263+
ucontrol->value.integer.value, numcoef);
264+
}
265+
138266
static int tas571x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format)
139267
{
140268
struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec);
@@ -241,6 +369,15 @@ static const struct snd_soc_dai_ops tas571x_dai_ops = {
241369
.digital_mute = tas571x_mute,
242370
};
243371

372+
373+
#define BIQUAD_COEFS(xname, reg) \
374+
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
375+
.info = tas571x_coefficient_info, \
376+
.get = tas571x_coefficient_get,\
377+
.put = tas571x_coefficient_put, \
378+
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
379+
.private_value = reg | (5 << 16) }
380+
244381
static const char *const tas5711_supply_names[] = {
245382
"AVDD",
246383
"DVDD",
@@ -264,6 +401,16 @@ static const struct snd_kcontrol_new tas5711_controls[] = {
264401
TAS571X_SOFT_MUTE_REG,
265402
TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
266403
1, 1),
404+
405+
SOC_DOUBLE_R_RANGE("CH1 Mixer Volume",
406+
TAS5717_CH1_LEFT_CH_MIX_REG,
407+
TAS5717_CH1_RIGHT_CH_MIX_REG,
408+
16, 0, 0x80, 0),
409+
410+
SOC_DOUBLE_R_RANGE("CH2 Mixer Volume",
411+
TAS5717_CH2_LEFT_CH_MIX_REG,
412+
TAS5717_CH2_RIGHT_CH_MIX_REG,
413+
16, 0, 0x80, 0),
267414
};
268415

269416
static const struct regmap_range tas571x_readonly_regs_range[] = {
@@ -340,6 +487,43 @@ static const struct snd_kcontrol_new tas5717_controls[] = {
340487
TAS571X_SOFT_MUTE_REG,
341488
TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
342489
1, 1),
490+
491+
/*
492+
* The biquads are named according to the register names.
493+
* Please note that TI's TAS57xx Graphical Development Environment
494+
* tool names them different.
495+
*/
496+
BIQUAD_COEFS("CH1 - Biquad 0", TAS5717_CH1_BQ0_REG),
497+
BIQUAD_COEFS("CH1 - Biquad 1", TAS5717_CH1_BQ1_REG),
498+
BIQUAD_COEFS("CH1 - Biquad 2", TAS5717_CH1_BQ2_REG),
499+
BIQUAD_COEFS("CH1 - Biquad 3", TAS5717_CH1_BQ3_REG),
500+
BIQUAD_COEFS("CH1 - Biquad 4", TAS5717_CH1_BQ4_REG),
501+
BIQUAD_COEFS("CH1 - Biquad 5", TAS5717_CH1_BQ5_REG),
502+
BIQUAD_COEFS("CH1 - Biquad 6", TAS5717_CH1_BQ6_REG),
503+
BIQUAD_COEFS("CH1 - Biquad 7", TAS5717_CH1_BQ7_REG),
504+
BIQUAD_COEFS("CH1 - Biquad 8", TAS5717_CH1_BQ8_REG),
505+
BIQUAD_COEFS("CH1 - Biquad 9", TAS5717_CH1_BQ9_REG),
506+
BIQUAD_COEFS("CH1 - Biquad 10", TAS5717_CH1_BQ10_REG),
507+
BIQUAD_COEFS("CH1 - Biquad 11", TAS5717_CH1_BQ11_REG),
508+
509+
BIQUAD_COEFS("CH2 - Biquad 0", TAS5717_CH2_BQ0_REG),
510+
BIQUAD_COEFS("CH2 - Biquad 1", TAS5717_CH2_BQ1_REG),
511+
BIQUAD_COEFS("CH2 - Biquad 2", TAS5717_CH2_BQ2_REG),
512+
BIQUAD_COEFS("CH2 - Biquad 3", TAS5717_CH2_BQ3_REG),
513+
BIQUAD_COEFS("CH2 - Biquad 4", TAS5717_CH2_BQ4_REG),
514+
BIQUAD_COEFS("CH2 - Biquad 5", TAS5717_CH2_BQ5_REG),
515+
BIQUAD_COEFS("CH2 - Biquad 6", TAS5717_CH2_BQ6_REG),
516+
BIQUAD_COEFS("CH2 - Biquad 7", TAS5717_CH2_BQ7_REG),
517+
BIQUAD_COEFS("CH2 - Biquad 8", TAS5717_CH2_BQ8_REG),
518+
BIQUAD_COEFS("CH2 - Biquad 9", TAS5717_CH2_BQ9_REG),
519+
BIQUAD_COEFS("CH2 - Biquad 10", TAS5717_CH2_BQ10_REG),
520+
BIQUAD_COEFS("CH2 - Biquad 11", TAS5717_CH2_BQ11_REG),
521+
522+
BIQUAD_COEFS("CH3 - Biquad 0", TAS5717_CH3_BQ0_REG),
523+
BIQUAD_COEFS("CH3 - Biquad 1", TAS5717_CH3_BQ1_REG),
524+
525+
BIQUAD_COEFS("CH4 - Biquad 0", TAS5717_CH4_BQ0_REG),
526+
BIQUAD_COEFS("CH4 - Biquad 1", TAS5717_CH4_BQ1_REG),
343527
};
344528

345529
static const struct reg_default tas5717_reg_defaults[] = {
@@ -350,6 +534,10 @@ static const struct reg_default tas5717_reg_defaults[] = {
350534
{ 0x08, 0x00c0 },
351535
{ 0x09, 0x00c0 },
352536
{ 0x1b, 0x82 },
537+
{ TAS5717_CH1_RIGHT_CH_MIX_REG, 0x0 },
538+
{ TAS5717_CH1_LEFT_CH_MIX_REG, 0x800000},
539+
{ TAS5717_CH2_LEFT_CH_MIX_REG, 0x0 },
540+
{ TAS5717_CH2_RIGHT_CH_MIX_REG, 0x800000},
353541
};
354542

355543
static const struct regmap_config tas5717_regmap_config = {

sound/soc/codecs/tas571x.h

+40
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,44 @@
5252
#define TAS571X_CH4_SRC_SELECT_REG 0x21
5353
#define TAS571X_PWM_MUX_REG 0x25
5454

55+
/* 20-byte biquad registers */
56+
#define TAS5717_CH1_BQ0_REG 0x26
57+
#define TAS5717_CH1_BQ1_REG 0x27
58+
#define TAS5717_CH1_BQ2_REG 0x28
59+
#define TAS5717_CH1_BQ3_REG 0x29
60+
#define TAS5717_CH1_BQ4_REG 0x2a
61+
#define TAS5717_CH1_BQ5_REG 0x2b
62+
#define TAS5717_CH1_BQ6_REG 0x2c
63+
#define TAS5717_CH1_BQ7_REG 0x2d
64+
#define TAS5717_CH1_BQ8_REG 0x2e
65+
#define TAS5717_CH1_BQ9_REG 0x2f
66+
67+
#define TAS5717_CH2_BQ0_REG 0x30
68+
#define TAS5717_CH2_BQ1_REG 0x31
69+
#define TAS5717_CH2_BQ2_REG 0x32
70+
#define TAS5717_CH2_BQ3_REG 0x33
71+
#define TAS5717_CH2_BQ4_REG 0x34
72+
#define TAS5717_CH2_BQ5_REG 0x35
73+
#define TAS5717_CH2_BQ6_REG 0x36
74+
#define TAS5717_CH2_BQ7_REG 0x37
75+
#define TAS5717_CH2_BQ8_REG 0x38
76+
#define TAS5717_CH2_BQ9_REG 0x39
77+
78+
#define TAS5717_CH1_BQ10_REG 0x58
79+
#define TAS5717_CH1_BQ11_REG 0x59
80+
81+
#define TAS5717_CH4_BQ0_REG 0x5a
82+
#define TAS5717_CH4_BQ1_REG 0x5b
83+
84+
#define TAS5717_CH2_BQ10_REG 0x5c
85+
#define TAS5717_CH2_BQ11_REG 0x5d
86+
87+
#define TAS5717_CH3_BQ0_REG 0x5e
88+
#define TAS5717_CH3_BQ1_REG 0x5f
89+
90+
#define TAS5717_CH1_RIGHT_CH_MIX_REG 0x72
91+
#define TAS5717_CH1_LEFT_CH_MIX_REG 0x73
92+
#define TAS5717_CH2_LEFT_CH_MIX_REG 0x76
93+
#define TAS5717_CH2_RIGHT_CH_MIX_REG 0x77
94+
5595
#endif /* _TAS571X_H */

0 commit comments

Comments
 (0)