aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c115
1 files changed, 110 insertions, 5 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index e048e0910099..844ae8221a3a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -84,7 +84,7 @@ static int run_delayed_work(struct delayed_work *dwork)
84/* codec register dump */ 84/* codec register dump */
85static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) 85static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
86{ 86{
87 int i, step = 1, count = 0; 87 int ret, i, step = 1, count = 0;
88 88
89 if (!codec->reg_cache_size) 89 if (!codec->reg_cache_size)
90 return 0; 90 return 0;
@@ -101,12 +101,24 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
101 if (count >= PAGE_SIZE - 1) 101 if (count >= PAGE_SIZE - 1)
102 break; 102 break;
103 103
104 if (codec->display_register) 104 if (codec->display_register) {
105 count += codec->display_register(codec, buf + count, 105 count += codec->display_register(codec, buf + count,
106 PAGE_SIZE - count, i); 106 PAGE_SIZE - count, i);
107 else 107 } else {
108 count += snprintf(buf + count, PAGE_SIZE - count, 108 /* If the read fails it's almost certainly due to
109 "%4x", codec->read(codec, i)); 109 * the register being volatile and the device being
110 * powered off.
111 */
112 ret = codec->read(codec, i);
113 if (ret >= 0)
114 count += snprintf(buf + count,
115 PAGE_SIZE - count,
116 "%4x", ret);
117 else
118 count += snprintf(buf + count,
119 PAGE_SIZE - count,
120 "<no data: %d>", ret);
121 }
110 122
111 if (count >= PAGE_SIZE - 1) 123 if (count >= PAGE_SIZE - 1)
112 break; 124 break;
@@ -2353,6 +2365,99 @@ int snd_soc_limit_volume(struct snd_soc_codec *codec,
2353EXPORT_SYMBOL_GPL(snd_soc_limit_volume); 2365EXPORT_SYMBOL_GPL(snd_soc_limit_volume);
2354 2366
2355/** 2367/**
2368 * snd_soc_info_volsw_2r_sx - double with tlv and variable data size
2369 * mixer info callback
2370 * @kcontrol: mixer control
2371 * @uinfo: control element information
2372 *
2373 * Returns 0 for success.
2374 */
2375int snd_soc_info_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2376 struct snd_ctl_elem_info *uinfo)
2377{
2378 struct soc_mixer_control *mc =
2379 (struct soc_mixer_control *)kcontrol->private_value;
2380 int max = mc->max;
2381 int min = mc->min;
2382
2383 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2384 uinfo->count = 2;
2385 uinfo->value.integer.min = 0;
2386 uinfo->value.integer.max = max-min;
2387
2388 return 0;
2389}
2390EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r_sx);
2391
2392/**
2393 * snd_soc_get_volsw_2r_sx - double with tlv and variable data size
2394 * mixer get callback
2395 * @kcontrol: mixer control
2396 * @uinfo: control element information
2397 *
2398 * Returns 0 for success.
2399 */
2400int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2401 struct snd_ctl_elem_value *ucontrol)
2402{
2403 struct soc_mixer_control *mc =
2404 (struct soc_mixer_control *)kcontrol->private_value;
2405 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2406 unsigned int mask = (1<<mc->shift)-1;
2407 int min = mc->min;
2408 int val = snd_soc_read(codec, mc->reg) & mask;
2409 int valr = snd_soc_read(codec, mc->rreg) & mask;
2410
2411 ucontrol->value.integer.value[0] = ((val & 0xff)-min) & mask;
2412 ucontrol->value.integer.value[1] = ((valr & 0xff)-min) & mask;
2413 return 0;
2414}
2415EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r_sx);
2416
2417/**
2418 * snd_soc_put_volsw_2r_sx - double with tlv and variable data size
2419 * mixer put callback
2420 * @kcontrol: mixer control
2421 * @uinfo: control element information
2422 *
2423 * Returns 0 for success.
2424 */
2425int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2426 struct snd_ctl_elem_value *ucontrol)
2427{
2428 struct soc_mixer_control *mc =
2429 (struct soc_mixer_control *)kcontrol->private_value;
2430 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2431 unsigned int mask = (1<<mc->shift)-1;
2432 int min = mc->min;
2433 int ret;
2434 unsigned int val, valr, oval, ovalr;
2435
2436 val = ((ucontrol->value.integer.value[0]+min) & 0xff);
2437 val &= mask;
2438 valr = ((ucontrol->value.integer.value[1]+min) & 0xff);
2439 valr &= mask;
2440
2441 oval = snd_soc_read(codec, mc->reg) & mask;
2442 ovalr = snd_soc_read(codec, mc->rreg) & mask;
2443
2444 ret = 0;
2445 if (oval != val) {
2446 ret = snd_soc_write(codec, mc->reg, val);
2447 if (ret < 0)
2448 return ret;
2449 }
2450 if (ovalr != valr) {
2451 ret = snd_soc_write(codec, mc->rreg, valr);
2452 if (ret < 0)
2453 return ret;
2454 }
2455
2456 return 0;
2457}
2458EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
2459
2460/**
2356 * snd_soc_dai_set_sysclk - configure DAI system or master clock. 2461 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
2357 * @dai: DAI 2462 * @dai: DAI
2358 * @clk_id: DAI specific clock ID 2463 * @clk_id: DAI specific clock ID