aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc.h21
-rw-r--r--sound/soc/soc-core.c95
2 files changed, 116 insertions, 0 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 697e7ffe39d7..65e9d03ed4f5 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -170,6 +170,21 @@
170 .get = xhandler_get, .put = xhandler_put, \ 170 .get = xhandler_get, .put = xhandler_put, \
171 .private_value = (unsigned long)&xenum } 171 .private_value = (unsigned long)&xenum }
172 172
173#define SOC_DOUBLE_R_SX_TLV(xname, xreg_left, xreg_right, xshift,\
174 xmin, xmax, tlv_array) \
175{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
176 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
177 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
178 .tlv.p = (tlv_array), \
179 .info = snd_soc_info_volsw_2r_sx, \
180 .get = snd_soc_get_volsw_2r_sx, \
181 .put = snd_soc_put_volsw_2r_sx, \
182 .private_value = (unsigned long)&(struct soc_mixer_control) \
183 {.reg = xreg_left, \
184 .rreg = xreg_right, .shift = xshift, \
185 .min = xmin, .max = xmax} }
186
187
173/* 188/*
174 * Simplified versions of above macros, declaring a struct and calculating 189 * Simplified versions of above macros, declaring a struct and calculating
175 * ARRAY_SIZE internally 190 * ARRAY_SIZE internally
@@ -329,6 +344,12 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
329 struct snd_ctl_elem_value *ucontrol); 344 struct snd_ctl_elem_value *ucontrol);
330int snd_soc_limit_volume(struct snd_soc_codec *codec, 345int snd_soc_limit_volume(struct snd_soc_codec *codec,
331 const char *name, int max); 346 const char *name, int max);
347int snd_soc_info_volsw_2r_sx(struct snd_kcontrol *kcontrol,
348 struct snd_ctl_elem_info *uinfo);
349int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol,
350 struct snd_ctl_elem_value *ucontrol);
351int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
352 struct snd_ctl_elem_value *ucontrol);
332 353
333/** 354/**
334 * struct snd_soc_jack_pin - Describes a pin to update based on jack detection 355 * struct snd_soc_jack_pin - Describes a pin to update based on jack detection
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index e1043f644730..6220bc1ee427 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2352,6 +2352,101 @@ int snd_soc_limit_volume(struct snd_soc_codec *codec,
2352EXPORT_SYMBOL_GPL(snd_soc_limit_volume); 2352EXPORT_SYMBOL_GPL(snd_soc_limit_volume);
2353 2353
2354/** 2354/**
2355 * snd_soc_info_volsw_2r_sx - double with tlv and variable data size
2356 * mixer info callback
2357 * @kcontrol: mixer control
2358 * @uinfo: control element information
2359 *
2360 * Returns 0 for success.
2361 */
2362int snd_soc_info_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2363 struct snd_ctl_elem_info *uinfo)
2364{
2365 struct soc_mixer_control *mc =
2366 (struct soc_mixer_control *)kcontrol->private_value;
2367 int max = mc->max;
2368 int min = mc->min;
2369
2370 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2371 uinfo->count = 2;
2372 uinfo->value.integer.min = 0;
2373 uinfo->value.integer.max = max-min;
2374
2375 return 0;
2376}
2377EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r_sx);
2378
2379/**
2380 * snd_soc_get_volsw_2r_sx - double with tlv and variable data size
2381 * mixer get callback
2382 * @kcontrol: mixer control
2383 * @uinfo: control element information
2384 *
2385 * Returns 0 for success.
2386 */
2387int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2388 struct snd_ctl_elem_value *ucontrol)
2389{
2390 struct soc_mixer_control *mc =
2391 (struct soc_mixer_control *)kcontrol->private_value;
2392 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2393 unsigned int mask = (1<<mc->shift)-1;
2394 int min = mc->min;
2395 int val = snd_soc_read(codec, mc->reg) & mask;
2396 int valr = snd_soc_read(codec, mc->rreg) & mask;
2397
2398 ucontrol->value.integer.value[0] = ((val & 0xff)-min);
2399 ucontrol->value.integer.value[1] = ((valr & 0xff)-min);
2400 return 0;
2401}
2402EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r_sx);
2403
2404/**
2405 * snd_soc_put_volsw_2r_sx - double with tlv and variable data size
2406 * mixer put callback
2407 * @kcontrol: mixer control
2408 * @uinfo: control element information
2409 *
2410 * Returns 0 for success.
2411 */
2412int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2413 struct snd_ctl_elem_value *ucontrol)
2414{
2415 struct soc_mixer_control *mc =
2416 (struct soc_mixer_control *)kcontrol->private_value;
2417 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2418 unsigned int mask = (1<<mc->shift)-1;
2419 int min = mc->min;
2420 int ret;
2421 unsigned int val, valr, oval, ovalr;
2422
2423 val = ((ucontrol->value.integer.value[0]+min) & 0xff);
2424 val &= mask;
2425 valr = ((ucontrol->value.integer.value[1]+min) & 0xff);
2426 valr &= mask;
2427
2428 oval = snd_soc_read(codec, mc->reg) & mask;
2429 ovalr = snd_soc_read(codec, mc->rreg) & mask;
2430
2431 ret = 0;
2432 if (oval != val) {
2433 ret = snd_soc_write(codec, mc->reg, val);
2434 if (ret < 0)
2435 return 0;
2436 ret = 1;
2437 }
2438 if (ovalr != valr) {
2439 ret = snd_soc_write(codec, mc->rreg, valr);
2440 if (ret < 0)
2441 return 0;
2442 ret = 1;
2443 }
2444
2445 return 0;
2446}
2447EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
2448
2449/**
2355 * snd_soc_dai_set_sysclk - configure DAI system or master clock. 2450 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
2356 * @dai: DAI 2451 * @dai: DAI
2357 * @clk_id: DAI specific clock ID 2452 * @clk_id: DAI specific clock ID