aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/control.h7
-rw-r--r--include/sound/soc.h14
-rw-r--r--sound/core/control.c6
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/tlv320aic23.c10
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c23
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c21
-rw-r--r--sound/soc/soc-core.c21
8 files changed, 74 insertions, 32 deletions
diff --git a/include/sound/control.h b/include/sound/control.h
index 5358892b1b39..042613938a1d 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -31,10 +31,15 @@ typedef int (snd_kcontrol_info_t) (struct snd_kcontrol * kcontrol, struct snd_ct
31typedef int (snd_kcontrol_get_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol); 31typedef int (snd_kcontrol_get_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
32typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol); 32typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
33typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol, 33typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol,
34 int op_flag, /* 0=read,1=write,-1=command */ 34 int op_flag, /* SNDRV_CTL_TLV_OP_XXX */
35 unsigned int size, 35 unsigned int size,
36 unsigned int __user *tlv); 36 unsigned int __user *tlv);
37 37
38enum {
39 SNDRV_CTL_TLV_OP_READ = 0,
40 SNDRV_CTL_TLV_OP_WRITE = 1,
41 SNDRV_CTL_TLV_OP_CMD = -1,
42};
38 43
39struct snd_kcontrol_new { 44struct snd_kcontrol_new {
40 snd_ctl_elem_iface_t iface; /* interface identifier */ 45 snd_ctl_elem_iface_t iface; /* interface identifier */
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 27ed5ccb174a..be6ecae247b0 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -272,7 +272,14 @@
272 .get = xhandler_get, .put = xhandler_put, \ 272 .get = xhandler_get, .put = xhandler_put, \
273 .private_value = (unsigned long)&(struct soc_bytes_ext) \ 273 .private_value = (unsigned long)&(struct soc_bytes_ext) \
274 {.max = xcount} } 274 {.max = xcount} }
275 275#define SND_SOC_BYTES_TLV(xname, xcount, xhandler_get, xhandler_put) \
276{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
277 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE | \
278 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
279 .tlv.c = (snd_soc_bytes_tlv_callback), \
280 .info = snd_soc_info_bytes_ext, \
281 .private_value = (unsigned long)&(struct soc_bytes_ext) \
282 {.max = xcount, .get = xhandler_get, .put = xhandler_put, } }
276#define SOC_SINGLE_XR_SX(xname, xregbase, xregcount, xnbits, \ 283#define SOC_SINGLE_XR_SX(xname, xregbase, xregcount, xnbits, \
277 xmin, xmax, xinvert) \ 284 xmin, xmax, xinvert) \
278{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 285{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
@@ -560,6 +567,8 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
560 struct snd_ctl_elem_value *ucontrol); 567 struct snd_ctl_elem_value *ucontrol);
561int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol, 568int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol,
562 struct snd_ctl_elem_info *ucontrol); 569 struct snd_ctl_elem_info *ucontrol);
570int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag,
571 unsigned int size, unsigned int __user *tlv);
563int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol, 572int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol,
564 struct snd_ctl_elem_info *uinfo); 573 struct snd_ctl_elem_info *uinfo);
565int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, 574int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol,
@@ -1132,6 +1141,9 @@ struct soc_bytes {
1132 1141
1133struct soc_bytes_ext { 1142struct soc_bytes_ext {
1134 int max; 1143 int max;
1144 /* used for TLV byte control */
1145 int (*get)(unsigned int __user *bytes, unsigned int size);
1146 int (*put)(const unsigned int __user *bytes, unsigned int size);
1135}; 1147};
1136 1148
1137/* multi register control */ 1149/* multi register control */
diff --git a/sound/core/control.c b/sound/core/control.c
index f0b0e14497a5..b9611344ff9e 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1406,11 +1406,11 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
1406 case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS: 1406 case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
1407 return snd_ctl_subscribe_events(ctl, ip); 1407 return snd_ctl_subscribe_events(ctl, ip);
1408 case SNDRV_CTL_IOCTL_TLV_READ: 1408 case SNDRV_CTL_IOCTL_TLV_READ:
1409 return snd_ctl_tlv_ioctl(ctl, argp, 0); 1409 return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_READ);
1410 case SNDRV_CTL_IOCTL_TLV_WRITE: 1410 case SNDRV_CTL_IOCTL_TLV_WRITE:
1411 return snd_ctl_tlv_ioctl(ctl, argp, 1); 1411 return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_WRITE);
1412 case SNDRV_CTL_IOCTL_TLV_COMMAND: 1412 case SNDRV_CTL_IOCTL_TLV_COMMAND:
1413 return snd_ctl_tlv_ioctl(ctl, argp, -1); 1413 return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_CMD);
1414 case SNDRV_CTL_IOCTL_POWER: 1414 case SNDRV_CTL_IOCTL_POWER:
1415 return -ENOPROTOOPT; 1415 return -ENOPROTOOPT;
1416 case SNDRV_CTL_IOCTL_POWER_STATE: 1416 case SNDRV_CTL_IOCTL_POWER_STATE:
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1090135de0ba..8838838e25ed 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -564,7 +564,9 @@ config SND_SOC_TLV320AIC26
564 depends on SPI 564 depends on SPI
565 565
566config SND_SOC_TLV320AIC31XX 566config SND_SOC_TLV320AIC31XX
567 tristate 567 tristate "Texas Instruments TLV320AIC31xx CODECs"
568 depends on I2C
569 select REGMAP_I2C
568 570
569config SND_SOC_TLV320AIC32X4 571config SND_SOC_TLV320AIC32X4
570 tristate 572 tristate
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 686b8b85b956..d67167920c2f 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -364,16 +364,16 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
364 364
365 iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & ~(0x03 << 2); 365 iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
366 366
367 switch (params_format(params)) { 367 switch (params_width(params)) {
368 case SNDRV_PCM_FORMAT_S16_LE: 368 case 16:
369 break; 369 break;
370 case SNDRV_PCM_FORMAT_S20_3LE: 370 case 20:
371 iface_reg |= (0x01 << 2); 371 iface_reg |= (0x01 << 2);
372 break; 372 break;
373 case SNDRV_PCM_FORMAT_S24_LE: 373 case 24:
374 iface_reg |= (0x02 << 2); 374 iface_reg |= (0x02 << 2);
375 break; 375 break;
376 case SNDRV_PCM_FORMAT_S32_LE: 376 case 32:
377 iface_reg |= (0x03 << 2); 377 iface_reg |= (0x03 << 2);
378 break; 378 break;
379 } 379 }
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index 1cdae8ccc61b..095f4556ab1b 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -249,17 +249,16 @@ static const char * const mic_select_text[] = {
249 "Off", "FFR 10 Ohm", "FFR 20 Ohm", "FFR 40 Ohm" 249 "Off", "FFR 10 Ohm", "FFR 20 Ohm", "FFR 40 Ohm"
250}; 250};
251 251
252static const 252static SOC_ENUM_SINGLE_DECL(mic1lp_p_enum, AIC31XX_MICPGAPI, 6,
253SOC_ENUM_SINGLE_DECL(mic1lp_p_enum, AIC31XX_MICPGAPI, 6, mic_select_text); 253 mic_select_text);
254static const 254static SOC_ENUM_SINGLE_DECL(mic1rp_p_enum, AIC31XX_MICPGAPI, 4,
255SOC_ENUM_SINGLE_DECL(mic1rp_p_enum, AIC31XX_MICPGAPI, 4, mic_select_text); 255 mic_select_text);
256static const 256static SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2,
257SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2, mic_select_text); 257 mic_select_text);
258 258
259static const 259static SOC_ENUM_SINGLE_DECL(cm_m_enum, AIC31XX_MICPGAMI, 6, mic_select_text);
260SOC_ENUM_SINGLE_DECL(cm_m_enum, AIC31XX_MICPGAMI, 6, mic_select_text); 260static SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4,
261static const 261 mic_select_text);
262SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4, mic_select_text);
263 262
264static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6350, 50, 0); 263static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6350, 50, 0);
265static const DECLARE_TLV_DB_SCALE(adc_fgain_tlv, 0, 10, 0); 264static const DECLARE_TLV_DB_SCALE(adc_fgain_tlv, 0, 10, 0);
@@ -329,6 +328,7 @@ static int aic31xx_wait_bits(struct aic31xx_priv *aic31xx, unsigned int reg,
329 unsigned int bits; 328 unsigned int bits;
330 int counter = count; 329 int counter = count;
331 int ret = regmap_read(aic31xx->regmap, reg, &bits); 330 int ret = regmap_read(aic31xx->regmap, reg, &bits);
331
332 while ((bits & mask) != wbits && counter && !ret) { 332 while ((bits & mask) != wbits && counter && !ret) {
333 usleep_range(sleep, sleep * 2); 333 usleep_range(sleep, sleep * 2);
334 ret = regmap_read(aic31xx->regmap, reg, &bits); 334 ret = regmap_read(aic31xx->regmap, reg, &bits);
@@ -435,6 +435,7 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w,
435{ 435{
436 struct snd_soc_codec *codec = w->codec; 436 struct snd_soc_codec *codec = w->codec;
437 struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 437 struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
438
438 switch (event) { 439 switch (event) {
439 case SND_SOC_DAPM_POST_PMU: 440 case SND_SOC_DAPM_POST_PMU:
440 /* change mic bias voltage to user defined */ 441 /* change mic bias voltage to user defined */
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index 1d9b117345a3..89e41d2f7586 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -626,32 +626,33 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
626 snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN | 626 snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
627 AIC32X4_MICBIAS_2075V); 627 AIC32X4_MICBIAS_2075V);
628 } 628 }
629 if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) { 629 if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE)
630 snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE); 630 snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
631 }
632 631
633 tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ? 632 tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ?
634 AIC32X4_LDOCTLEN : 0; 633 AIC32X4_LDOCTLEN : 0;
635 snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg); 634 snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg);
636 635
637 tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE); 636 tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
638 if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) { 637 if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36)
639 tmp_reg |= AIC32X4_LDOIN_18_36; 638 tmp_reg |= AIC32X4_LDOIN_18_36;
640 } 639 if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED)
641 if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED) {
642 tmp_reg |= AIC32X4_LDOIN2HP; 640 tmp_reg |= AIC32X4_LDOIN2HP;
643 }
644 snd_soc_write(codec, AIC32X4_CMMODE, tmp_reg); 641 snd_soc_write(codec, AIC32X4_CMMODE, tmp_reg);
645 642
646 /* Mic PGA routing */ 643 /* Mic PGA routing */
647 if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K) 644 if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K)
648 snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K); 645 snd_soc_write(codec, AIC32X4_LMICPGANIN,
646 AIC32X4_LMICPGANIN_IN2R_10K);
649 else 647 else
650 snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_CM1L_10K); 648 snd_soc_write(codec, AIC32X4_LMICPGANIN,
649 AIC32X4_LMICPGANIN_CM1L_10K);
651 if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K) 650 if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K)
652 snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K); 651 snd_soc_write(codec, AIC32X4_RMICPGANIN,
652 AIC32X4_RMICPGANIN_IN1L_10K);
653 else 653 else
654 snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_CM1R_10K); 654 snd_soc_write(codec, AIC32X4_RMICPGANIN,
655 AIC32X4_RMICPGANIN_CM1R_10K);
655 656
656 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 657 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
657 658
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 2d6c8b86b7d3..d4bfd4a9076f 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3289,6 +3289,27 @@ int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol,
3289} 3289}
3290EXPORT_SYMBOL_GPL(snd_soc_bytes_info_ext); 3290EXPORT_SYMBOL_GPL(snd_soc_bytes_info_ext);
3291 3291
3292int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag,
3293 unsigned int size, unsigned int __user *tlv)
3294{
3295 struct soc_bytes_ext *params = (void *)kcontrol->private_value;
3296 unsigned int count = size < params->max ? size : params->max;
3297 int ret = -ENXIO;
3298
3299 switch (op_flag) {
3300 case SNDRV_CTL_TLV_OP_READ:
3301 if (params->get)
3302 ret = params->get(tlv, count);
3303 break;
3304 case SNDRV_CTL_TLV_OP_WRITE:
3305 if (params->put)
3306 ret = params->put(tlv, count);
3307 break;
3308 }
3309 return ret;
3310}
3311EXPORT_SYMBOL_GPL(snd_soc_bytes_tlv_callback);
3312
3292/** 3313/**
3293 * snd_soc_info_xr_sx - signed multi register info callback 3314 * snd_soc_info_xr_sx - signed multi register info callback
3294 * @kcontrol: mreg control 3315 * @kcontrol: mreg control