diff options
Diffstat (limited to 'sound')
116 files changed, 4807 insertions, 2385 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index a2104671f51d..5dcf88bed9b7 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -1242,6 +1242,7 @@ int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_par | |||
1242 | return -EINVAL; | 1242 | return -EINVAL; |
1243 | return 0; | 1243 | return 0; |
1244 | } | 1244 | } |
1245 | EXPORT_SYMBOL(snd_pcm_hw_constraint_mask64); | ||
1245 | 1246 | ||
1246 | /** | 1247 | /** |
1247 | * snd_pcm_hw_constraint_integer - apply an integer constraint to an interval | 1248 | * snd_pcm_hw_constraint_integer - apply an integer constraint to an interval |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index ec4536c8d8d4..dafcf82139e2 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -932,7 +932,7 @@ int snd_hda_bus_new(struct snd_card *card, | |||
932 | } | 932 | } |
933 | EXPORT_SYMBOL_GPL(snd_hda_bus_new); | 933 | EXPORT_SYMBOL_GPL(snd_hda_bus_new); |
934 | 934 | ||
935 | #ifdef CONFIG_SND_HDA_GENERIC | 935 | #if IS_ENABLED(CONFIG_SND_HDA_GENERIC) |
936 | #define is_generic_config(codec) \ | 936 | #define is_generic_config(codec) \ |
937 | (codec->modelname && !strcmp(codec->modelname, "generic")) | 937 | (codec->modelname && !strcmp(codec->modelname, "generic")) |
938 | #else | 938 | #else |
@@ -1339,23 +1339,15 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid) | |||
1339 | /* | 1339 | /* |
1340 | * Dynamic symbol binding for the codec parsers | 1340 | * Dynamic symbol binding for the codec parsers |
1341 | */ | 1341 | */ |
1342 | #ifdef MODULE | ||
1343 | #define load_parser_sym(sym) ((int (*)(struct hda_codec *))symbol_request(sym)) | ||
1344 | #define unload_parser_addr(addr) symbol_put_addr(addr) | ||
1345 | #else | ||
1346 | #define load_parser_sym(sym) (sym) | ||
1347 | #define unload_parser_addr(addr) do {} while (0) | ||
1348 | #endif | ||
1349 | 1342 | ||
1350 | #define load_parser(codec, sym) \ | 1343 | #define load_parser(codec, sym) \ |
1351 | ((codec)->parser = load_parser_sym(sym)) | 1344 | ((codec)->parser = (int (*)(struct hda_codec *))symbol_request(sym)) |
1352 | 1345 | ||
1353 | static void unload_parser(struct hda_codec *codec) | 1346 | static void unload_parser(struct hda_codec *codec) |
1354 | { | 1347 | { |
1355 | if (codec->parser) { | 1348 | if (codec->parser) |
1356 | unload_parser_addr(codec->parser); | 1349 | symbol_put_addr(codec->parser); |
1357 | codec->parser = NULL; | 1350 | codec->parser = NULL; |
1358 | } | ||
1359 | } | 1351 | } |
1360 | 1352 | ||
1361 | /* | 1353 | /* |
@@ -1570,7 +1562,7 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec) | |||
1570 | EXPORT_SYMBOL_GPL(snd_hda_codec_update_widgets); | 1562 | EXPORT_SYMBOL_GPL(snd_hda_codec_update_widgets); |
1571 | 1563 | ||
1572 | 1564 | ||
1573 | #ifdef CONFIG_SND_HDA_CODEC_HDMI | 1565 | #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) |
1574 | /* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */ | 1566 | /* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */ |
1575 | static bool is_likely_hdmi_codec(struct hda_codec *codec) | 1567 | static bool is_likely_hdmi_codec(struct hda_codec *codec) |
1576 | { | 1568 | { |
@@ -1620,12 +1612,20 @@ int snd_hda_codec_configure(struct hda_codec *codec) | |||
1620 | patch = codec->preset->patch; | 1612 | patch = codec->preset->patch; |
1621 | if (!patch) { | 1613 | if (!patch) { |
1622 | unload_parser(codec); /* to be sure */ | 1614 | unload_parser(codec); /* to be sure */ |
1623 | if (is_likely_hdmi_codec(codec)) | 1615 | if (is_likely_hdmi_codec(codec)) { |
1616 | #if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI) | ||
1624 | patch = load_parser(codec, snd_hda_parse_hdmi_codec); | 1617 | patch = load_parser(codec, snd_hda_parse_hdmi_codec); |
1625 | #ifdef CONFIG_SND_HDA_GENERIC | 1618 | #elif IS_BUILTIN(CONFIG_SND_HDA_CODEC_HDMI) |
1626 | if (!patch) | 1619 | patch = snd_hda_parse_hdmi_codec; |
1620 | #endif | ||
1621 | } | ||
1622 | if (!patch) { | ||
1623 | #if IS_MODULE(CONFIG_SND_HDA_GENERIC) | ||
1627 | patch = load_parser(codec, snd_hda_parse_generic_codec); | 1624 | patch = load_parser(codec, snd_hda_parse_generic_codec); |
1625 | #elif IS_BUILTIN(CONFIG_SND_HDA_GENERIC) | ||
1626 | patch = snd_hda_parse_generic_codec; | ||
1628 | #endif | 1627 | #endif |
1628 | } | ||
1629 | if (!patch) { | 1629 | if (!patch) { |
1630 | printk(KERN_ERR "hda-codec: No codec parser is available\n"); | 1630 | printk(KERN_ERR "hda-codec: No codec parser is available\n"); |
1631 | return -ENODEV; | 1631 | return -ENODEV; |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 8321a97d5c05..d9a09bdd09db 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -3269,7 +3269,7 @@ static int cap_put_caller(struct snd_kcontrol *kcontrol, | |||
3269 | mutex_unlock(&codec->control_mutex); | 3269 | mutex_unlock(&codec->control_mutex); |
3270 | snd_hda_codec_flush_cache(codec); /* flush the updates */ | 3270 | snd_hda_codec_flush_cache(codec); /* flush the updates */ |
3271 | if (err >= 0 && spec->cap_sync_hook) | 3271 | if (err >= 0 && spec->cap_sync_hook) |
3272 | spec->cap_sync_hook(codec, ucontrol); | 3272 | spec->cap_sync_hook(codec, kcontrol, ucontrol); |
3273 | return err; | 3273 | return err; |
3274 | } | 3274 | } |
3275 | 3275 | ||
@@ -3390,7 +3390,7 @@ static int cap_single_sw_put(struct snd_kcontrol *kcontrol, | |||
3390 | return ret; | 3390 | return ret; |
3391 | 3391 | ||
3392 | if (spec->cap_sync_hook) | 3392 | if (spec->cap_sync_hook) |
3393 | spec->cap_sync_hook(codec, ucontrol); | 3393 | spec->cap_sync_hook(codec, kcontrol, ucontrol); |
3394 | 3394 | ||
3395 | return ret; | 3395 | return ret; |
3396 | } | 3396 | } |
@@ -3795,7 +3795,7 @@ static int mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
3795 | return 0; | 3795 | return 0; |
3796 | snd_hda_activate_path(codec, path, true, false); | 3796 | snd_hda_activate_path(codec, path, true, false); |
3797 | if (spec->cap_sync_hook) | 3797 | if (spec->cap_sync_hook) |
3798 | spec->cap_sync_hook(codec, NULL); | 3798 | spec->cap_sync_hook(codec, NULL, NULL); |
3799 | path_power_down_sync(codec, old_path); | 3799 | path_power_down_sync(codec, old_path); |
3800 | return 1; | 3800 | return 1; |
3801 | } | 3801 | } |
@@ -5270,7 +5270,7 @@ static void init_input_src(struct hda_codec *codec) | |||
5270 | } | 5270 | } |
5271 | 5271 | ||
5272 | if (spec->cap_sync_hook) | 5272 | if (spec->cap_sync_hook) |
5273 | spec->cap_sync_hook(codec, NULL); | 5273 | spec->cap_sync_hook(codec, NULL, NULL); |
5274 | } | 5274 | } |
5275 | 5275 | ||
5276 | /* set right pin controls for digital I/O */ | 5276 | /* set right pin controls for digital I/O */ |
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 07f767231c9f..c908afbe4d94 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h | |||
@@ -274,6 +274,7 @@ struct hda_gen_spec { | |||
274 | void (*init_hook)(struct hda_codec *codec); | 274 | void (*init_hook)(struct hda_codec *codec); |
275 | void (*automute_hook)(struct hda_codec *codec); | 275 | void (*automute_hook)(struct hda_codec *codec); |
276 | void (*cap_sync_hook)(struct hda_codec *codec, | 276 | void (*cap_sync_hook)(struct hda_codec *codec, |
277 | struct snd_kcontrol *kcontrol, | ||
277 | struct snd_ctl_elem_value *ucontrol); | 278 | struct snd_ctl_elem_value *ucontrol); |
278 | 279 | ||
279 | /* PCM hooks */ | 280 | /* PCM hooks */ |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index fa2879a21a50..e354ab1ec20f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -198,7 +198,7 @@ MODULE_DESCRIPTION("Intel HDA driver"); | |||
198 | #endif | 198 | #endif |
199 | 199 | ||
200 | #if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO) | 200 | #if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO) |
201 | #ifdef CONFIG_SND_HDA_CODEC_HDMI | 201 | #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) |
202 | #define SUPPORT_VGA_SWITCHEROO | 202 | #define SUPPORT_VGA_SWITCHEROO |
203 | #endif | 203 | #endif |
204 | #endif | 204 | #endif |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 7a426ed491f2..8ed0bcc01386 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -244,6 +244,19 @@ static void ad_fixup_inv_jack_detect(struct hda_codec *codec, | |||
244 | } | 244 | } |
245 | } | 245 | } |
246 | 246 | ||
247 | /* Toshiba Satellite L40 implements EAPD in a standard way unlike others */ | ||
248 | static void ad1986a_fixup_eapd(struct hda_codec *codec, | ||
249 | const struct hda_fixup *fix, int action) | ||
250 | { | ||
251 | struct ad198x_spec *spec = codec->spec; | ||
252 | |||
253 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
254 | codec->inv_eapd = 0; | ||
255 | spec->gen.keep_eapd_on = 1; | ||
256 | spec->eapd_nid = 0x1b; | ||
257 | } | ||
258 | } | ||
259 | |||
247 | enum { | 260 | enum { |
248 | AD1986A_FIXUP_INV_JACK_DETECT, | 261 | AD1986A_FIXUP_INV_JACK_DETECT, |
249 | AD1986A_FIXUP_ULTRA, | 262 | AD1986A_FIXUP_ULTRA, |
@@ -251,6 +264,7 @@ enum { | |||
251 | AD1986A_FIXUP_3STACK, | 264 | AD1986A_FIXUP_3STACK, |
252 | AD1986A_FIXUP_LAPTOP, | 265 | AD1986A_FIXUP_LAPTOP, |
253 | AD1986A_FIXUP_LAPTOP_IMIC, | 266 | AD1986A_FIXUP_LAPTOP_IMIC, |
267 | AD1986A_FIXUP_EAPD, | ||
254 | }; | 268 | }; |
255 | 269 | ||
256 | static const struct hda_fixup ad1986a_fixups[] = { | 270 | static const struct hda_fixup ad1986a_fixups[] = { |
@@ -311,6 +325,10 @@ static const struct hda_fixup ad1986a_fixups[] = { | |||
311 | .chained_before = 1, | 325 | .chained_before = 1, |
312 | .chain_id = AD1986A_FIXUP_LAPTOP, | 326 | .chain_id = AD1986A_FIXUP_LAPTOP, |
313 | }, | 327 | }, |
328 | [AD1986A_FIXUP_EAPD] = { | ||
329 | .type = HDA_FIXUP_FUNC, | ||
330 | .v.func = ad1986a_fixup_eapd, | ||
331 | }, | ||
314 | }; | 332 | }; |
315 | 333 | ||
316 | static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { | 334 | static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { |
@@ -318,6 +336,7 @@ static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { | |||
318 | SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK), | 336 | SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK), |
319 | SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK), | 337 | SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK), |
320 | SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK), | 338 | SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK), |
339 | SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40", AD1986A_FIXUP_EAPD), | ||
321 | SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP), | 340 | SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP), |
322 | SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG), | 341 | SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG), |
323 | SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA), | 342 | SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA), |
@@ -472,6 +491,8 @@ static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec) | |||
472 | static int patch_ad1983(struct hda_codec *codec) | 491 | static int patch_ad1983(struct hda_codec *codec) |
473 | { | 492 | { |
474 | struct ad198x_spec *spec; | 493 | struct ad198x_spec *spec; |
494 | static hda_nid_t conn_0c[] = { 0x08 }; | ||
495 | static hda_nid_t conn_0d[] = { 0x09 }; | ||
475 | int err; | 496 | int err; |
476 | 497 | ||
477 | err = alloc_ad_spec(codec); | 498 | err = alloc_ad_spec(codec); |
@@ -479,8 +500,14 @@ static int patch_ad1983(struct hda_codec *codec) | |||
479 | return err; | 500 | return err; |
480 | spec = codec->spec; | 501 | spec = codec->spec; |
481 | 502 | ||
503 | spec->gen.mixer_nid = 0x0e; | ||
482 | spec->gen.beep_nid = 0x10; | 504 | spec->gen.beep_nid = 0x10; |
483 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 505 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
506 | |||
507 | /* limit the loopback routes not to confuse the parser */ | ||
508 | snd_hda_override_conn_list(codec, 0x0c, ARRAY_SIZE(conn_0c), conn_0c); | ||
509 | snd_hda_override_conn_list(codec, 0x0d, ARRAY_SIZE(conn_0d), conn_0d); | ||
510 | |||
484 | err = ad198x_parse_auto_config(codec, false); | 511 | err = ad198x_parse_auto_config(codec, false); |
485 | if (err < 0) | 512 | if (err < 0) |
486 | goto error; | 513 | goto error; |
@@ -999,6 +1026,9 @@ static void ad1884_fixup_thinkpad(struct hda_codec *codec, | |||
999 | spec->gen.keep_eapd_on = 1; | 1026 | spec->gen.keep_eapd_on = 1; |
1000 | spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; | 1027 | spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; |
1001 | spec->eapd_nid = 0x12; | 1028 | spec->eapd_nid = 0x12; |
1029 | /* Analog PC Beeper - allow firmware/ACPI beeps */ | ||
1030 | spec->beep_amp = HDA_COMPOSE_AMP_VAL(0x20, 3, 3, HDA_INPUT); | ||
1031 | spec->gen.beep_nid = 0; /* no digital beep */ | ||
1002 | } | 1032 | } |
1003 | } | 1033 | } |
1004 | 1034 | ||
@@ -1065,6 +1095,7 @@ static int patch_ad1884(struct hda_codec *codec) | |||
1065 | spec = codec->spec; | 1095 | spec = codec->spec; |
1066 | 1096 | ||
1067 | spec->gen.mixer_nid = 0x20; | 1097 | spec->gen.mixer_nid = 0x20; |
1098 | spec->gen.mixer_merge_nid = 0x21; | ||
1068 | spec->gen.beep_nid = 0x10; | 1099 | spec->gen.beep_nid = 0x10; |
1069 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 1100 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
1070 | 1101 | ||
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 54d14793725a..46ecdbb9053f 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -2662,60 +2662,6 @@ static bool dspload_wait_loaded(struct hda_codec *codec) | |||
2662 | } | 2662 | } |
2663 | 2663 | ||
2664 | /* | 2664 | /* |
2665 | * PCM stuffs | ||
2666 | */ | ||
2667 | static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid, | ||
2668 | u32 stream_tag, | ||
2669 | int channel_id, int format) | ||
2670 | { | ||
2671 | unsigned int oldval, newval; | ||
2672 | |||
2673 | if (!nid) | ||
2674 | return; | ||
2675 | |||
2676 | snd_printdd( | ||
2677 | "ca0132_setup_stream: NID=0x%x, stream=0x%x, " | ||
2678 | "channel=%d, format=0x%x\n", | ||
2679 | nid, stream_tag, channel_id, format); | ||
2680 | |||
2681 | /* update the format-id if changed */ | ||
2682 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
2683 | AC_VERB_GET_STREAM_FORMAT, | ||
2684 | 0); | ||
2685 | if (oldval != format) { | ||
2686 | msleep(20); | ||
2687 | snd_hda_codec_write(codec, nid, 0, | ||
2688 | AC_VERB_SET_STREAM_FORMAT, | ||
2689 | format); | ||
2690 | } | ||
2691 | |||
2692 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | ||
2693 | newval = (stream_tag << 4) | channel_id; | ||
2694 | if (oldval != newval) { | ||
2695 | snd_hda_codec_write(codec, nid, 0, | ||
2696 | AC_VERB_SET_CHANNEL_STREAMID, | ||
2697 | newval); | ||
2698 | } | ||
2699 | } | ||
2700 | |||
2701 | static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) | ||
2702 | { | ||
2703 | unsigned int val; | ||
2704 | |||
2705 | if (!nid) | ||
2706 | return; | ||
2707 | |||
2708 | snd_printdd(KERN_INFO "ca0132_cleanup_stream: NID=0x%x\n", nid); | ||
2709 | |||
2710 | val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | ||
2711 | if (!val) | ||
2712 | return; | ||
2713 | |||
2714 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); | ||
2715 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0); | ||
2716 | } | ||
2717 | |||
2718 | /* | ||
2719 | * PCM callbacks | 2665 | * PCM callbacks |
2720 | */ | 2666 | */ |
2721 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 2667 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
@@ -2726,7 +2672,7 @@ static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
2726 | { | 2672 | { |
2727 | struct ca0132_spec *spec = codec->spec; | 2673 | struct ca0132_spec *spec = codec->spec; |
2728 | 2674 | ||
2729 | ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); | 2675 | snd_hda_codec_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); |
2730 | 2676 | ||
2731 | return 0; | 2677 | return 0; |
2732 | } | 2678 | } |
@@ -2745,7 +2691,7 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
2745 | if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) | 2691 | if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) |
2746 | msleep(50); | 2692 | msleep(50); |
2747 | 2693 | ||
2748 | ca0132_cleanup_stream(codec, spec->dacs[0]); | 2694 | snd_hda_codec_cleanup_stream(codec, spec->dacs[0]); |
2749 | 2695 | ||
2750 | return 0; | 2696 | return 0; |
2751 | } | 2697 | } |
@@ -2822,10 +2768,8 @@ static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
2822 | unsigned int format, | 2768 | unsigned int format, |
2823 | struct snd_pcm_substream *substream) | 2769 | struct snd_pcm_substream *substream) |
2824 | { | 2770 | { |
2825 | struct ca0132_spec *spec = codec->spec; | 2771 | snd_hda_codec_setup_stream(codec, hinfo->nid, |
2826 | 2772 | stream_tag, 0, format); | |
2827 | ca0132_setup_stream(codec, spec->adcs[substream->number], | ||
2828 | stream_tag, 0, format); | ||
2829 | 2773 | ||
2830 | return 0; | 2774 | return 0; |
2831 | } | 2775 | } |
@@ -2839,7 +2783,7 @@ static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
2839 | if (spec->dsp_state == DSP_DOWNLOADING) | 2783 | if (spec->dsp_state == DSP_DOWNLOADING) |
2840 | return 0; | 2784 | return 0; |
2841 | 2785 | ||
2842 | ca0132_cleanup_stream(codec, hinfo->nid); | 2786 | snd_hda_codec_cleanup_stream(codec, hinfo->nid); |
2843 | return 0; | 2787 | return 0; |
2844 | } | 2788 | } |
2845 | 2789 | ||
@@ -4742,6 +4686,8 @@ static int patch_ca0132(struct hda_codec *codec) | |||
4742 | return err; | 4686 | return err; |
4743 | 4687 | ||
4744 | codec->patch_ops = ca0132_patch_ops; | 4688 | codec->patch_ops = ca0132_patch_ops; |
4689 | codec->pcm_format_first = 1; | ||
4690 | codec->no_sticky_stream = 1; | ||
4745 | 4691 | ||
4746 | return 0; | 4692 | return 0; |
4747 | } | 4693 | } |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 4e0ec146553d..bcf91bea3317 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -3291,7 +3291,8 @@ static void cxt_update_headset_mode(struct hda_codec *codec) | |||
3291 | } | 3291 | } |
3292 | 3292 | ||
3293 | static void cxt_update_headset_mode_hook(struct hda_codec *codec, | 3293 | static void cxt_update_headset_mode_hook(struct hda_codec *codec, |
3294 | struct snd_ctl_elem_value *ucontrol) | 3294 | struct snd_kcontrol *kcontrol, |
3295 | struct snd_ctl_elem_value *ucontrol) | ||
3295 | { | 3296 | { |
3296 | cxt_update_headset_mode(codec); | 3297 | cxt_update_headset_mode(codec); |
3297 | } | 3298 | } |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 56a8f1876603..850296a1e0ff 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -708,7 +708,8 @@ static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) | |||
708 | } | 708 | } |
709 | 709 | ||
710 | static void alc_inv_dmic_hook(struct hda_codec *codec, | 710 | static void alc_inv_dmic_hook(struct hda_codec *codec, |
711 | struct snd_ctl_elem_value *ucontrol) | 711 | struct snd_kcontrol *kcontrol, |
712 | struct snd_ctl_elem_value *ucontrol) | ||
712 | { | 713 | { |
713 | alc_inv_dmic_sync(codec, false); | 714 | alc_inv_dmic_sync(codec, false); |
714 | } | 715 | } |
@@ -1821,6 +1822,7 @@ enum { | |||
1821 | ALC889_FIXUP_IMAC91_VREF, | 1822 | ALC889_FIXUP_IMAC91_VREF, |
1822 | ALC889_FIXUP_MBA11_VREF, | 1823 | ALC889_FIXUP_MBA11_VREF, |
1823 | ALC889_FIXUP_MBA21_VREF, | 1824 | ALC889_FIXUP_MBA21_VREF, |
1825 | ALC889_FIXUP_MP11_VREF, | ||
1824 | ALC882_FIXUP_INV_DMIC, | 1826 | ALC882_FIXUP_INV_DMIC, |
1825 | ALC882_FIXUP_NO_PRIMARY_HP, | 1827 | ALC882_FIXUP_NO_PRIMARY_HP, |
1826 | ALC887_FIXUP_ASUS_BASS, | 1828 | ALC887_FIXUP_ASUS_BASS, |
@@ -2190,6 +2192,12 @@ static const struct hda_fixup alc882_fixups[] = { | |||
2190 | .chained = true, | 2192 | .chained = true, |
2191 | .chain_id = ALC889_FIXUP_MBP_VREF, | 2193 | .chain_id = ALC889_FIXUP_MBP_VREF, |
2192 | }, | 2194 | }, |
2195 | [ALC889_FIXUP_MP11_VREF] = { | ||
2196 | .type = HDA_FIXUP_FUNC, | ||
2197 | .v.func = alc889_fixup_mba11_vref, | ||
2198 | .chained = true, | ||
2199 | .chain_id = ALC885_FIXUP_MACPRO_GPIO, | ||
2200 | }, | ||
2193 | [ALC882_FIXUP_INV_DMIC] = { | 2201 | [ALC882_FIXUP_INV_DMIC] = { |
2194 | .type = HDA_FIXUP_FUNC, | 2202 | .type = HDA_FIXUP_FUNC, |
2195 | .v.func = alc_fixup_inv_dmic_0x12, | 2203 | .v.func = alc_fixup_inv_dmic_0x12, |
@@ -2253,7 +2261,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { | |||
2253 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), | 2261 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), |
2254 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), | 2262 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), |
2255 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), | 2263 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), |
2256 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), | 2264 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF), |
2257 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), | 2265 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), |
2258 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), | 2266 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), |
2259 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), | 2267 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), |
@@ -3211,7 +3219,8 @@ static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) | |||
3211 | 3219 | ||
3212 | /* turn on/off mic-mute LED per capture hook */ | 3220 | /* turn on/off mic-mute LED per capture hook */ |
3213 | static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, | 3221 | static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, |
3214 | struct snd_ctl_elem_value *ucontrol) | 3222 | struct snd_kcontrol *kcontrol, |
3223 | struct snd_ctl_elem_value *ucontrol) | ||
3215 | { | 3224 | { |
3216 | struct alc_spec *spec = codec->spec; | 3225 | struct alc_spec *spec = codec->spec; |
3217 | unsigned int oldval = spec->gpio_led; | 3226 | unsigned int oldval = spec->gpio_led; |
@@ -3521,7 +3530,8 @@ static void alc_update_headset_mode(struct hda_codec *codec) | |||
3521 | } | 3530 | } |
3522 | 3531 | ||
3523 | static void alc_update_headset_mode_hook(struct hda_codec *codec, | 3532 | static void alc_update_headset_mode_hook(struct hda_codec *codec, |
3524 | struct snd_ctl_elem_value *ucontrol) | 3533 | struct snd_kcontrol *kcontrol, |
3534 | struct snd_ctl_elem_value *ucontrol) | ||
3525 | { | 3535 | { |
3526 | alc_update_headset_mode(codec); | 3536 | alc_update_headset_mode(codec); |
3527 | } | 3537 | } |
@@ -4243,6 +4253,7 @@ static const struct hda_fixup alc269_fixups[] = { | |||
4243 | }; | 4253 | }; |
4244 | 4254 | ||
4245 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 4255 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
4256 | SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC), | ||
4246 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), | 4257 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), |
4247 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), | 4258 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), |
4248 | SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), | 4259 | SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), |
@@ -4298,7 +4309,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4298 | SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4309 | SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4299 | SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4310 | SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4300 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4311 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4312 | SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4301 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4313 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4314 | SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4302 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4315 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4303 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4316 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4304 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4317 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
@@ -4307,6 +4320,54 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4307 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4320 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4308 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4321 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4309 | SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), | 4322 | SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), |
4323 | /* ALC282 */ | ||
4324 | SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4325 | SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4326 | SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4327 | SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4328 | SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4329 | SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4330 | SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4331 | SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4332 | SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4333 | SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4334 | SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4335 | SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4336 | SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4337 | SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4338 | SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4339 | SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4340 | SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4341 | SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4342 | SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4343 | SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4344 | SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4345 | SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4346 | /* ALC290 */ | ||
4347 | SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4348 | SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4349 | SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4350 | SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4351 | SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4352 | SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4353 | SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4354 | SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4355 | SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4356 | SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4357 | SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4358 | SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4359 | SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4360 | SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4361 | SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4362 | SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4363 | SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4364 | SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4365 | SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4366 | SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4367 | SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4368 | SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4369 | SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4370 | SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4310 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), | 4371 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), |
4311 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), | 4372 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), |
4312 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4373 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
@@ -4322,6 +4383,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4322 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), | 4383 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
4323 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), | 4384 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
4324 | SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), | 4385 | SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), |
4386 | SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), | ||
4325 | SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), | 4387 | SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), |
4326 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), | 4388 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), |
4327 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 4389 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
@@ -5096,12 +5158,13 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { | |||
5096 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 5158 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
5097 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5159 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5098 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5160 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5161 | SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | ||
5099 | SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5162 | SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5100 | SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5163 | SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5101 | SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5164 | SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5102 | SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5165 | SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5103 | SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5166 | SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5104 | SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5167 | SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5105 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), | 5168 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
5106 | SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A_CHMAP), | 5169 | SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A_CHMAP), |
5107 | SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_CHMAP), | 5170 | SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_CHMAP), |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6998cf29b9bc..3bc29c9b2529 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -83,6 +83,7 @@ enum { | |||
83 | STAC_DELL_M6_BOTH, | 83 | STAC_DELL_M6_BOTH, |
84 | STAC_DELL_EQ, | 84 | STAC_DELL_EQ, |
85 | STAC_ALIENWARE_M17X, | 85 | STAC_ALIENWARE_M17X, |
86 | STAC_92HD89XX_HP_FRONT_JACK, | ||
86 | STAC_92HD73XX_MODELS | 87 | STAC_92HD73XX_MODELS |
87 | }; | 88 | }; |
88 | 89 | ||
@@ -97,6 +98,7 @@ enum { | |||
97 | STAC_92HD83XXX_HP_LED, | 98 | STAC_92HD83XXX_HP_LED, |
98 | STAC_92HD83XXX_HP_INV_LED, | 99 | STAC_92HD83XXX_HP_INV_LED, |
99 | STAC_92HD83XXX_HP_MIC_LED, | 100 | STAC_92HD83XXX_HP_MIC_LED, |
101 | STAC_HP_LED_GPIO10, | ||
100 | STAC_92HD83XXX_HEADSET_JACK, | 102 | STAC_92HD83XXX_HEADSET_JACK, |
101 | STAC_92HD83XXX_HP, | 103 | STAC_92HD83XXX_HP, |
102 | STAC_HP_ENVY_BASS, | 104 | STAC_HP_ENVY_BASS, |
@@ -194,7 +196,7 @@ struct sigmatel_spec { | |||
194 | int default_polarity; | 196 | int default_polarity; |
195 | 197 | ||
196 | unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */ | 198 | unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */ |
197 | bool mic_mute_led_on; /* current mic mute state */ | 199 | unsigned int mic_enabled; /* current mic mute state (bitmask) */ |
198 | 200 | ||
199 | /* stream */ | 201 | /* stream */ |
200 | unsigned int stream_delay; | 202 | unsigned int stream_delay; |
@@ -324,19 +326,26 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, | |||
324 | 326 | ||
325 | /* hook for controlling mic-mute LED GPIO */ | 327 | /* hook for controlling mic-mute LED GPIO */ |
326 | static void stac_capture_led_hook(struct hda_codec *codec, | 328 | static void stac_capture_led_hook(struct hda_codec *codec, |
327 | struct snd_ctl_elem_value *ucontrol) | 329 | struct snd_kcontrol *kcontrol, |
330 | struct snd_ctl_elem_value *ucontrol) | ||
328 | { | 331 | { |
329 | struct sigmatel_spec *spec = codec->spec; | 332 | struct sigmatel_spec *spec = codec->spec; |
330 | bool mute; | 333 | unsigned int mask; |
334 | bool cur_mute, prev_mute; | ||
331 | 335 | ||
332 | if (!ucontrol) | 336 | if (!kcontrol || !ucontrol) |
333 | return; | 337 | return; |
334 | 338 | ||
335 | mute = !(ucontrol->value.integer.value[0] || | 339 | mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
336 | ucontrol->value.integer.value[1]); | 340 | prev_mute = !spec->mic_enabled; |
337 | if (spec->mic_mute_led_on != mute) { | 341 | if (ucontrol->value.integer.value[0] || |
338 | spec->mic_mute_led_on = mute; | 342 | ucontrol->value.integer.value[1]) |
339 | if (mute) | 343 | spec->mic_enabled |= mask; |
344 | else | ||
345 | spec->mic_enabled &= ~mask; | ||
346 | cur_mute = !spec->mic_enabled; | ||
347 | if (cur_mute != prev_mute) { | ||
348 | if (cur_mute) | ||
340 | spec->gpio_data |= spec->mic_mute_led_gpio; | 349 | spec->gpio_data |= spec->mic_mute_led_gpio; |
341 | else | 350 | else |
342 | spec->gpio_data &= ~spec->mic_mute_led_gpio; | 351 | spec->gpio_data &= ~spec->mic_mute_led_gpio; |
@@ -1788,6 +1797,12 @@ static const struct hda_pintbl intel_dg45id_pin_configs[] = { | |||
1788 | {} | 1797 | {} |
1789 | }; | 1798 | }; |
1790 | 1799 | ||
1800 | static const struct hda_pintbl stac92hd89xx_hp_front_jack_pin_configs[] = { | ||
1801 | { 0x0a, 0x02214030 }, | ||
1802 | { 0x0b, 0x02A19010 }, | ||
1803 | {} | ||
1804 | }; | ||
1805 | |||
1791 | static void stac92hd73xx_fixup_ref(struct hda_codec *codec, | 1806 | static void stac92hd73xx_fixup_ref(struct hda_codec *codec, |
1792 | const struct hda_fixup *fix, int action) | 1807 | const struct hda_fixup *fix, int action) |
1793 | { | 1808 | { |
@@ -1906,6 +1921,10 @@ static const struct hda_fixup stac92hd73xx_fixups[] = { | |||
1906 | [STAC_92HD73XX_NO_JD] = { | 1921 | [STAC_92HD73XX_NO_JD] = { |
1907 | .type = HDA_FIXUP_FUNC, | 1922 | .type = HDA_FIXUP_FUNC, |
1908 | .v.func = stac92hd73xx_fixup_no_jd, | 1923 | .v.func = stac92hd73xx_fixup_no_jd, |
1924 | }, | ||
1925 | [STAC_92HD89XX_HP_FRONT_JACK] = { | ||
1926 | .type = HDA_FIXUP_PINS, | ||
1927 | .v.pins = stac92hd89xx_hp_front_jack_pin_configs, | ||
1909 | } | 1928 | } |
1910 | }; | 1929 | }; |
1911 | 1930 | ||
@@ -1966,6 +1985,8 @@ static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = { | |||
1966 | "Alienware M17x", STAC_ALIENWARE_M17X), | 1985 | "Alienware M17x", STAC_ALIENWARE_M17X), |
1967 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, | 1986 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, |
1968 | "Alienware M17x R3", STAC_DELL_EQ), | 1987 | "Alienware M17x R3", STAC_DELL_EQ), |
1988 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17, | ||
1989 | "unknown HP", STAC_92HD89XX_HP_FRONT_JACK), | ||
1969 | {} /* terminator */ | 1990 | {} /* terminator */ |
1970 | }; | 1991 | }; |
1971 | 1992 | ||
@@ -2110,6 +2131,17 @@ static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec, | |||
2110 | } | 2131 | } |
2111 | } | 2132 | } |
2112 | 2133 | ||
2134 | static void stac92hd83xxx_fixup_hp_led_gpio10(struct hda_codec *codec, | ||
2135 | const struct hda_fixup *fix, int action) | ||
2136 | { | ||
2137 | struct sigmatel_spec *spec = codec->spec; | ||
2138 | |||
2139 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
2140 | spec->gpio_led = 0x10; /* GPIO4 */ | ||
2141 | spec->default_polarity = 0; | ||
2142 | } | ||
2143 | } | ||
2144 | |||
2113 | static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec, | 2145 | static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec, |
2114 | const struct hda_fixup *fix, int action) | 2146 | const struct hda_fixup *fix, int action) |
2115 | { | 2147 | { |
@@ -2604,6 +2636,12 @@ static const struct hda_fixup stac92hd83xxx_fixups[] = { | |||
2604 | .chained = true, | 2636 | .chained = true, |
2605 | .chain_id = STAC_92HD83XXX_HP, | 2637 | .chain_id = STAC_92HD83XXX_HP, |
2606 | }, | 2638 | }, |
2639 | [STAC_HP_LED_GPIO10] = { | ||
2640 | .type = HDA_FIXUP_FUNC, | ||
2641 | .v.func = stac92hd83xxx_fixup_hp_led_gpio10, | ||
2642 | .chained = true, | ||
2643 | .chain_id = STAC_92HD83XXX_HP, | ||
2644 | }, | ||
2607 | [STAC_92HD83XXX_HEADSET_JACK] = { | 2645 | [STAC_92HD83XXX_HEADSET_JACK] = { |
2608 | .type = HDA_FIXUP_FUNC, | 2646 | .type = HDA_FIXUP_FUNC, |
2609 | .v.func = stac92hd83xxx_fixup_headset_jack, | 2647 | .v.func = stac92hd83xxx_fixup_headset_jack, |
@@ -2682,6 +2720,8 @@ static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = { | |||
2682 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | 2720 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), |
2683 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888, | 2721 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888, |
2684 | "HP Envy Spectre", STAC_HP_ENVY_BASS), | 2722 | "HP Envy Spectre", STAC_HP_ENVY_BASS), |
2723 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1899, | ||
2724 | "HP Folio 13", STAC_HP_LED_GPIO10), | ||
2685 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df, | 2725 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df, |
2686 | "HP Folio", STAC_HP_BNB13_EQ), | 2726 | "HP Folio", STAC_HP_BNB13_EQ), |
2687 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18F8, | 2727 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18F8, |
@@ -4462,7 +4502,7 @@ static void stac_setup_gpio(struct hda_codec *codec) | |||
4462 | if (spec->mic_mute_led_gpio) { | 4502 | if (spec->mic_mute_led_gpio) { |
4463 | spec->gpio_mask |= spec->mic_mute_led_gpio; | 4503 | spec->gpio_mask |= spec->mic_mute_led_gpio; |
4464 | spec->gpio_dir |= spec->mic_mute_led_gpio; | 4504 | spec->gpio_dir |= spec->mic_mute_led_gpio; |
4465 | spec->mic_mute_led_on = true; | 4505 | spec->mic_enabled = 0; |
4466 | spec->gpio_data |= spec->mic_mute_led_gpio; | 4506 | spec->gpio_data |= spec->mic_mute_led_gpio; |
4467 | 4507 | ||
4468 | spec->gen.cap_sync_hook = stac_capture_led_hook; | 4508 | spec->gen.cap_sync_hook = stac_capture_led_hook; |
diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c index 5799fbc24c28..8fe3b8c18ed4 100644 --- a/sound/pci/hda/thinkpad_helper.c +++ b/sound/pci/hda/thinkpad_helper.c | |||
@@ -39,6 +39,7 @@ static void update_tpacpi_mute_led(void *private_data, int enabled) | |||
39 | } | 39 | } |
40 | 40 | ||
41 | static void update_tpacpi_micmute_led(struct hda_codec *codec, | 41 | static void update_tpacpi_micmute_led(struct hda_codec *codec, |
42 | struct snd_kcontrol *kcontrol, | ||
42 | struct snd_ctl_elem_value *ucontrol) | 43 | struct snd_ctl_elem_value *ucontrol) |
43 | { | 44 | { |
44 | if (!ucontrol || !led_set_func) | 45 | if (!ucontrol || !led_set_func) |
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig index 54f74f8cbb75..b2107918f0ad 100644 --- a/sound/soc/blackfin/Kconfig +++ b/sound/soc/blackfin/Kconfig | |||
@@ -11,7 +11,7 @@ config SND_BF5XX_I2S | |||
11 | 11 | ||
12 | config SND_BF5XX_SOC_SSM2602 | 12 | config SND_BF5XX_SOC_SSM2602 |
13 | tristate "SoC SSM2602 Audio Codec Add-On Card support" | 13 | tristate "SoC SSM2602 Audio Codec Add-On Card support" |
14 | depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) | 14 | depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI |
15 | select SND_BF5XX_SOC_I2S if !BF60x | 15 | select SND_BF5XX_SOC_I2S if !BF60x |
16 | select SND_BF6XX_SOC_I2S if BF60x | 16 | select SND_BF6XX_SOC_I2S if BF60x |
17 | select SND_SOC_SSM2602 | 17 | select SND_SOC_SSM2602 |
@@ -21,10 +21,9 @@ config SND_BF5XX_SOC_SSM2602 | |||
21 | 21 | ||
22 | config SND_SOC_BFIN_EVAL_ADAU1701 | 22 | config SND_SOC_BFIN_EVAL_ADAU1701 |
23 | tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards" | 23 | tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards" |
24 | depends on SND_BF5XX_I2S | 24 | depends on SND_BF5XX_I2S && I2C |
25 | select SND_BF5XX_SOC_I2S | 25 | select SND_BF5XX_SOC_I2S |
26 | select SND_SOC_ADAU1701 | 26 | select SND_SOC_ADAU1701 |
27 | select I2C | ||
28 | help | 27 | help |
29 | Say Y if you want to add support for the Analog Devices EVAL-ADAU1701MINIZ | 28 | Say Y if you want to add support for the Analog Devices EVAL-ADAU1701MINIZ |
30 | board connected to one of the Blackfin evaluation boards like the | 29 | board connected to one of the Blackfin evaluation boards like the |
@@ -45,9 +44,10 @@ config SND_SOC_BFIN_EVAL_ADAU1373 | |||
45 | 44 | ||
46 | config SND_SOC_BFIN_EVAL_ADAV80X | 45 | config SND_SOC_BFIN_EVAL_ADAV80X |
47 | tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards" | 46 | tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards" |
48 | depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) | 47 | depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI |
49 | select SND_BF5XX_SOC_I2S | 48 | select SND_BF5XX_SOC_I2S |
50 | select SND_SOC_ADAV80X | 49 | select SND_SOC_ADAV801 if SPI_MASTER |
50 | select SND_SOC_ADAV803 if I2C | ||
51 | help | 51 | help |
52 | Say Y if you want to add support for the Analog Devices EVAL-ADAV801 or | 52 | Say Y if you want to add support for the Analog Devices EVAL-ADAV801 or |
53 | EVAL-ADAV803 board connected to one of the Blackfin evaluation boards | 53 | EVAL-ADAV803 board connected to one of the Blackfin evaluation boards |
@@ -58,7 +58,7 @@ config SND_SOC_BFIN_EVAL_ADAV80X | |||
58 | 58 | ||
59 | config SND_BF5XX_SOC_AD1836 | 59 | config SND_BF5XX_SOC_AD1836 |
60 | tristate "SoC AD1836 Audio support for BF5xx" | 60 | tristate "SoC AD1836 Audio support for BF5xx" |
61 | depends on SND_BF5XX_I2S | 61 | depends on SND_BF5XX_I2S && SPI_MASTER |
62 | select SND_BF5XX_SOC_I2S | 62 | select SND_BF5XX_SOC_I2S |
63 | select SND_SOC_AD1836 | 63 | select SND_SOC_AD1836 |
64 | help | 64 | help |
@@ -66,9 +66,10 @@ config SND_BF5XX_SOC_AD1836 | |||
66 | 66 | ||
67 | config SND_BF5XX_SOC_AD193X | 67 | config SND_BF5XX_SOC_AD193X |
68 | tristate "SoC AD193X Audio support for Blackfin" | 68 | tristate "SoC AD193X Audio support for Blackfin" |
69 | depends on SND_BF5XX_I2S | 69 | depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI |
70 | select SND_BF5XX_SOC_I2S | 70 | select SND_BF5XX_SOC_I2S |
71 | select SND_SOC_AD193X | 71 | select SND_SOC_AD193X_I2C if I2C |
72 | select SND_SOC_AD193X_SPI if SPI_MASTER | ||
72 | help | 73 | help |
73 | Say Y if you want to add support for AD193X codec on Blackfin. | 74 | Say Y if you want to add support for AD193X codec on Blackfin. |
74 | This driver supports AD1936, AD1937, AD1938 and AD1939. | 75 | This driver supports AD1936, AD1937, AD1938 and AD1939. |
diff --git a/sound/soc/cirrus/Kconfig b/sound/soc/cirrus/Kconfig index 06f938deda15..c872dacbab98 100644 --- a/sound/soc/cirrus/Kconfig +++ b/sound/soc/cirrus/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SND_EP93XX_SOC | 1 | config SND_EP93XX_SOC |
2 | tristate "SoC Audio support for the Cirrus Logic EP93xx series" | 2 | tristate "SoC Audio support for the Cirrus Logic EP93xx series" |
3 | depends on (ARCH_EP93XX || COMPILE_TEST) && SND_SOC | 3 | depends on ARCH_EP93XX || COMPILE_TEST |
4 | select SND_SOC_GENERIC_DMAENGINE_PCM | 4 | select SND_SOC_GENERIC_DMAENGINE_PCM |
5 | help | 5 | help |
6 | Say Y or M if you want to add support for codecs attached to | 6 | Say Y or M if you want to add support for codecs attached to |
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 75d0ad5d2dcb..8703244ee9fb 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c | |||
@@ -448,38 +448,38 @@ static const char *pm860x_opamp_texts[] = {"-50%", "-25%", "0%", "75%"}; | |||
448 | 448 | ||
449 | static const char *pm860x_pa_texts[] = {"-33%", "0%", "33%", "66%"}; | 449 | static const char *pm860x_pa_texts[] = {"-33%", "0%", "33%", "66%"}; |
450 | 450 | ||
451 | static const struct soc_enum pm860x_hs1_opamp_enum = | 451 | static SOC_ENUM_SINGLE_DECL(pm860x_hs1_opamp_enum, |
452 | SOC_ENUM_SINGLE(PM860X_HS1_CTRL, 5, 4, pm860x_opamp_texts); | 452 | PM860X_HS1_CTRL, 5, pm860x_opamp_texts); |
453 | 453 | ||
454 | static const struct soc_enum pm860x_hs2_opamp_enum = | 454 | static SOC_ENUM_SINGLE_DECL(pm860x_hs2_opamp_enum, |
455 | SOC_ENUM_SINGLE(PM860X_HS2_CTRL, 5, 4, pm860x_opamp_texts); | 455 | PM860X_HS2_CTRL, 5, pm860x_opamp_texts); |
456 | 456 | ||
457 | static const struct soc_enum pm860x_hs1_pa_enum = | 457 | static SOC_ENUM_SINGLE_DECL(pm860x_hs1_pa_enum, |
458 | SOC_ENUM_SINGLE(PM860X_HS1_CTRL, 3, 4, pm860x_pa_texts); | 458 | PM860X_HS1_CTRL, 3, pm860x_pa_texts); |
459 | 459 | ||
460 | static const struct soc_enum pm860x_hs2_pa_enum = | 460 | static SOC_ENUM_SINGLE_DECL(pm860x_hs2_pa_enum, |
461 | SOC_ENUM_SINGLE(PM860X_HS2_CTRL, 3, 4, pm860x_pa_texts); | 461 | PM860X_HS2_CTRL, 3, pm860x_pa_texts); |
462 | 462 | ||
463 | static const struct soc_enum pm860x_lo1_opamp_enum = | 463 | static SOC_ENUM_SINGLE_DECL(pm860x_lo1_opamp_enum, |
464 | SOC_ENUM_SINGLE(PM860X_LO1_CTRL, 5, 4, pm860x_opamp_texts); | 464 | PM860X_LO1_CTRL, 5, pm860x_opamp_texts); |
465 | 465 | ||
466 | static const struct soc_enum pm860x_lo2_opamp_enum = | 466 | static SOC_ENUM_SINGLE_DECL(pm860x_lo2_opamp_enum, |
467 | SOC_ENUM_SINGLE(PM860X_LO2_CTRL, 5, 4, pm860x_opamp_texts); | 467 | PM860X_LO2_CTRL, 5, pm860x_opamp_texts); |
468 | 468 | ||
469 | static const struct soc_enum pm860x_lo1_pa_enum = | 469 | static SOC_ENUM_SINGLE_DECL(pm860x_lo1_pa_enum, |
470 | SOC_ENUM_SINGLE(PM860X_LO1_CTRL, 3, 4, pm860x_pa_texts); | 470 | PM860X_LO1_CTRL, 3, pm860x_pa_texts); |
471 | 471 | ||
472 | static const struct soc_enum pm860x_lo2_pa_enum = | 472 | static SOC_ENUM_SINGLE_DECL(pm860x_lo2_pa_enum, |
473 | SOC_ENUM_SINGLE(PM860X_LO2_CTRL, 3, 4, pm860x_pa_texts); | 473 | PM860X_LO2_CTRL, 3, pm860x_pa_texts); |
474 | 474 | ||
475 | static const struct soc_enum pm860x_spk_pa_enum = | 475 | static SOC_ENUM_SINGLE_DECL(pm860x_spk_pa_enum, |
476 | SOC_ENUM_SINGLE(PM860X_EAR_CTRL_1, 5, 4, pm860x_pa_texts); | 476 | PM860X_EAR_CTRL_1, 5, pm860x_pa_texts); |
477 | 477 | ||
478 | static const struct soc_enum pm860x_ear_pa_enum = | 478 | static SOC_ENUM_SINGLE_DECL(pm860x_ear_pa_enum, |
479 | SOC_ENUM_SINGLE(PM860X_EAR_CTRL_2, 0, 4, pm860x_pa_texts); | 479 | PM860X_EAR_CTRL_2, 0, pm860x_pa_texts); |
480 | 480 | ||
481 | static const struct soc_enum pm860x_spk_ear_opamp_enum = | 481 | static SOC_ENUM_SINGLE_DECL(pm860x_spk_ear_opamp_enum, |
482 | SOC_ENUM_SINGLE(PM860X_EAR_CTRL_1, 3, 4, pm860x_opamp_texts); | 482 | PM860X_EAR_CTRL_1, 3, pm860x_opamp_texts); |
483 | 483 | ||
484 | static const struct snd_kcontrol_new pm860x_snd_controls[] = { | 484 | static const struct snd_kcontrol_new pm860x_snd_controls[] = { |
485 | SOC_DOUBLE_R_TLV("ADC Capture Volume", PM860X_ADC_ANA_2, | 485 | SOC_DOUBLE_R_TLV("ADC Capture Volume", PM860X_ADC_ANA_2, |
@@ -561,8 +561,8 @@ static const char *aif1_text[] = { | |||
561 | "PCM L", "PCM R", | 561 | "PCM L", "PCM R", |
562 | }; | 562 | }; |
563 | 563 | ||
564 | static const struct soc_enum aif1_enum = | 564 | static SOC_ENUM_SINGLE_DECL(aif1_enum, |
565 | SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 6, 2, aif1_text); | 565 | PM860X_PCM_IFACE_3, 6, aif1_text); |
566 | 566 | ||
567 | static const struct snd_kcontrol_new aif1_mux = | 567 | static const struct snd_kcontrol_new aif1_mux = |
568 | SOC_DAPM_ENUM("PCM Mux", aif1_enum); | 568 | SOC_DAPM_ENUM("PCM Mux", aif1_enum); |
@@ -572,8 +572,8 @@ static const char *i2s_din_text[] = { | |||
572 | "DIN", "DIN1", | 572 | "DIN", "DIN1", |
573 | }; | 573 | }; |
574 | 574 | ||
575 | static const struct soc_enum i2s_din_enum = | 575 | static SOC_ENUM_SINGLE_DECL(i2s_din_enum, |
576 | SOC_ENUM_SINGLE(PM860X_I2S_IFACE_3, 1, 2, i2s_din_text); | 576 | PM860X_I2S_IFACE_3, 1, i2s_din_text); |
577 | 577 | ||
578 | static const struct snd_kcontrol_new i2s_din_mux = | 578 | static const struct snd_kcontrol_new i2s_din_mux = |
579 | SOC_DAPM_ENUM("I2S DIN Mux", i2s_din_enum); | 579 | SOC_DAPM_ENUM("I2S DIN Mux", i2s_din_enum); |
@@ -583,8 +583,8 @@ static const char *i2s_mic_text[] = { | |||
583 | "Ex PA", "ADC", | 583 | "Ex PA", "ADC", |
584 | }; | 584 | }; |
585 | 585 | ||
586 | static const struct soc_enum i2s_mic_enum = | 586 | static SOC_ENUM_SINGLE_DECL(i2s_mic_enum, |
587 | SOC_ENUM_SINGLE(PM860X_I2S_IFACE_3, 4, 2, i2s_mic_text); | 587 | PM860X_I2S_IFACE_3, 4, i2s_mic_text); |
588 | 588 | ||
589 | static const struct snd_kcontrol_new i2s_mic_mux = | 589 | static const struct snd_kcontrol_new i2s_mic_mux = |
590 | SOC_DAPM_ENUM("I2S Mic Mux", i2s_mic_enum); | 590 | SOC_DAPM_ENUM("I2S Mic Mux", i2s_mic_enum); |
@@ -594,8 +594,8 @@ static const char *adcl_text[] = { | |||
594 | "ADCR", "ADCL", | 594 | "ADCR", "ADCL", |
595 | }; | 595 | }; |
596 | 596 | ||
597 | static const struct soc_enum adcl_enum = | 597 | static SOC_ENUM_SINGLE_DECL(adcl_enum, |
598 | SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 4, 2, adcl_text); | 598 | PM860X_PCM_IFACE_3, 4, adcl_text); |
599 | 599 | ||
600 | static const struct snd_kcontrol_new adcl_mux = | 600 | static const struct snd_kcontrol_new adcl_mux = |
601 | SOC_DAPM_ENUM("ADC Left Mux", adcl_enum); | 601 | SOC_DAPM_ENUM("ADC Left Mux", adcl_enum); |
@@ -605,8 +605,8 @@ static const char *adcr_text[] = { | |||
605 | "ADCL", "ADCR", | 605 | "ADCL", "ADCR", |
606 | }; | 606 | }; |
607 | 607 | ||
608 | static const struct soc_enum adcr_enum = | 608 | static SOC_ENUM_SINGLE_DECL(adcr_enum, |
609 | SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 2, 2, adcr_text); | 609 | PM860X_PCM_IFACE_3, 2, adcr_text); |
610 | 610 | ||
611 | static const struct snd_kcontrol_new adcr_mux = | 611 | static const struct snd_kcontrol_new adcr_mux = |
612 | SOC_DAPM_ENUM("ADC Right Mux", adcr_enum); | 612 | SOC_DAPM_ENUM("ADC Right Mux", adcr_enum); |
@@ -616,8 +616,8 @@ static const char *adcr_ec_text[] = { | |||
616 | "ADCR", "EC", | 616 | "ADCR", "EC", |
617 | }; | 617 | }; |
618 | 618 | ||
619 | static const struct soc_enum adcr_ec_enum = | 619 | static SOC_ENUM_SINGLE_DECL(adcr_ec_enum, |
620 | SOC_ENUM_SINGLE(PM860X_ADC_EN_2, 3, 2, adcr_ec_text); | 620 | PM860X_ADC_EN_2, 3, adcr_ec_text); |
621 | 621 | ||
622 | static const struct snd_kcontrol_new adcr_ec_mux = | 622 | static const struct snd_kcontrol_new adcr_ec_mux = |
623 | SOC_DAPM_ENUM("ADCR EC Mux", adcr_ec_enum); | 623 | SOC_DAPM_ENUM("ADCR EC Mux", adcr_ec_enum); |
@@ -627,8 +627,8 @@ static const char *ec_text[] = { | |||
627 | "Left", "Right", "Left + Right", | 627 | "Left", "Right", "Left + Right", |
628 | }; | 628 | }; |
629 | 629 | ||
630 | static const struct soc_enum ec_enum = | 630 | static SOC_ENUM_SINGLE_DECL(ec_enum, |
631 | SOC_ENUM_SINGLE(PM860X_EC_PATH, 1, 3, ec_text); | 631 | PM860X_EC_PATH, 1, ec_text); |
632 | 632 | ||
633 | static const struct snd_kcontrol_new ec_mux = | 633 | static const struct snd_kcontrol_new ec_mux = |
634 | SOC_DAPM_ENUM("EC Mux", ec_enum); | 634 | SOC_DAPM_ENUM("EC Mux", ec_enum); |
@@ -638,36 +638,36 @@ static const char *dac_text[] = { | |||
638 | }; | 638 | }; |
639 | 639 | ||
640 | /* DAC Headset 1 Mux / Mux10 */ | 640 | /* DAC Headset 1 Mux / Mux10 */ |
641 | static const struct soc_enum dac_hs1_enum = | 641 | static SOC_ENUM_SINGLE_DECL(dac_hs1_enum, |
642 | SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 0, 4, dac_text); | 642 | PM860X_ANA_INPUT_SEL_1, 0, dac_text); |
643 | 643 | ||
644 | static const struct snd_kcontrol_new dac_hs1_mux = | 644 | static const struct snd_kcontrol_new dac_hs1_mux = |
645 | SOC_DAPM_ENUM("DAC HS1 Mux", dac_hs1_enum); | 645 | SOC_DAPM_ENUM("DAC HS1 Mux", dac_hs1_enum); |
646 | 646 | ||
647 | /* DAC Headset 2 Mux / Mux11 */ | 647 | /* DAC Headset 2 Mux / Mux11 */ |
648 | static const struct soc_enum dac_hs2_enum = | 648 | static SOC_ENUM_SINGLE_DECL(dac_hs2_enum, |
649 | SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 2, 4, dac_text); | 649 | PM860X_ANA_INPUT_SEL_1, 2, dac_text); |
650 | 650 | ||
651 | static const struct snd_kcontrol_new dac_hs2_mux = | 651 | static const struct snd_kcontrol_new dac_hs2_mux = |
652 | SOC_DAPM_ENUM("DAC HS2 Mux", dac_hs2_enum); | 652 | SOC_DAPM_ENUM("DAC HS2 Mux", dac_hs2_enum); |
653 | 653 | ||
654 | /* DAC Lineout 1 Mux / Mux12 */ | 654 | /* DAC Lineout 1 Mux / Mux12 */ |
655 | static const struct soc_enum dac_lo1_enum = | 655 | static SOC_ENUM_SINGLE_DECL(dac_lo1_enum, |
656 | SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 4, 4, dac_text); | 656 | PM860X_ANA_INPUT_SEL_1, 4, dac_text); |
657 | 657 | ||
658 | static const struct snd_kcontrol_new dac_lo1_mux = | 658 | static const struct snd_kcontrol_new dac_lo1_mux = |
659 | SOC_DAPM_ENUM("DAC LO1 Mux", dac_lo1_enum); | 659 | SOC_DAPM_ENUM("DAC LO1 Mux", dac_lo1_enum); |
660 | 660 | ||
661 | /* DAC Lineout 2 Mux / Mux13 */ | 661 | /* DAC Lineout 2 Mux / Mux13 */ |
662 | static const struct soc_enum dac_lo2_enum = | 662 | static SOC_ENUM_SINGLE_DECL(dac_lo2_enum, |
663 | SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 6, 4, dac_text); | 663 | PM860X_ANA_INPUT_SEL_1, 6, dac_text); |
664 | 664 | ||
665 | static const struct snd_kcontrol_new dac_lo2_mux = | 665 | static const struct snd_kcontrol_new dac_lo2_mux = |
666 | SOC_DAPM_ENUM("DAC LO2 Mux", dac_lo2_enum); | 666 | SOC_DAPM_ENUM("DAC LO2 Mux", dac_lo2_enum); |
667 | 667 | ||
668 | /* DAC Spearker Earphone Mux / Mux14 */ | 668 | /* DAC Spearker Earphone Mux / Mux14 */ |
669 | static const struct soc_enum dac_spk_ear_enum = | 669 | static SOC_ENUM_SINGLE_DECL(dac_spk_ear_enum, |
670 | SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_2, 0, 4, dac_text); | 670 | PM860X_ANA_INPUT_SEL_2, 0, dac_text); |
671 | 671 | ||
672 | static const struct snd_kcontrol_new dac_spk_ear_mux = | 672 | static const struct snd_kcontrol_new dac_spk_ear_mux = |
673 | SOC_DAPM_ENUM("DAC SP Mux", dac_spk_ear_enum); | 673 | SOC_DAPM_ENUM("DAC SP Mux", dac_spk_ear_enum); |
@@ -677,29 +677,29 @@ static const char *in_text[] = { | |||
677 | "Digital", "Analog", | 677 | "Digital", "Analog", |
678 | }; | 678 | }; |
679 | 679 | ||
680 | static const struct soc_enum hs1_enum = | 680 | static SOC_ENUM_SINGLE_DECL(hs1_enum, |
681 | SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 0, 2, in_text); | 681 | PM860X_ANA_TO_ANA, 0, in_text); |
682 | 682 | ||
683 | static const struct snd_kcontrol_new hs1_mux = | 683 | static const struct snd_kcontrol_new hs1_mux = |
684 | SOC_DAPM_ENUM("Headset1 Mux", hs1_enum); | 684 | SOC_DAPM_ENUM("Headset1 Mux", hs1_enum); |
685 | 685 | ||
686 | /* Headset 2 Mux / Mux16 */ | 686 | /* Headset 2 Mux / Mux16 */ |
687 | static const struct soc_enum hs2_enum = | 687 | static SOC_ENUM_SINGLE_DECL(hs2_enum, |
688 | SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 1, 2, in_text); | 688 | PM860X_ANA_TO_ANA, 1, in_text); |
689 | 689 | ||
690 | static const struct snd_kcontrol_new hs2_mux = | 690 | static const struct snd_kcontrol_new hs2_mux = |
691 | SOC_DAPM_ENUM("Headset2 Mux", hs2_enum); | 691 | SOC_DAPM_ENUM("Headset2 Mux", hs2_enum); |
692 | 692 | ||
693 | /* Lineout 1 Mux / Mux17 */ | 693 | /* Lineout 1 Mux / Mux17 */ |
694 | static const struct soc_enum lo1_enum = | 694 | static SOC_ENUM_SINGLE_DECL(lo1_enum, |
695 | SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 2, 2, in_text); | 695 | PM860X_ANA_TO_ANA, 2, in_text); |
696 | 696 | ||
697 | static const struct snd_kcontrol_new lo1_mux = | 697 | static const struct snd_kcontrol_new lo1_mux = |
698 | SOC_DAPM_ENUM("Lineout1 Mux", lo1_enum); | 698 | SOC_DAPM_ENUM("Lineout1 Mux", lo1_enum); |
699 | 699 | ||
700 | /* Lineout 2 Mux / Mux18 */ | 700 | /* Lineout 2 Mux / Mux18 */ |
701 | static const struct soc_enum lo2_enum = | 701 | static SOC_ENUM_SINGLE_DECL(lo2_enum, |
702 | SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 3, 2, in_text); | 702 | PM860X_ANA_TO_ANA, 3, in_text); |
703 | 703 | ||
704 | static const struct snd_kcontrol_new lo2_mux = | 704 | static const struct snd_kcontrol_new lo2_mux = |
705 | SOC_DAPM_ENUM("Lineout2 Mux", lo2_enum); | 705 | SOC_DAPM_ENUM("Lineout2 Mux", lo2_enum); |
@@ -709,8 +709,8 @@ static const char *spk_text[] = { | |||
709 | "Earpiece", "Speaker", | 709 | "Earpiece", "Speaker", |
710 | }; | 710 | }; |
711 | 711 | ||
712 | static const struct soc_enum spk_enum = | 712 | static SOC_ENUM_SINGLE_DECL(spk_enum, |
713 | SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 6, 2, spk_text); | 713 | PM860X_ANA_TO_ANA, 6, spk_text); |
714 | 714 | ||
715 | static const struct snd_kcontrol_new spk_demux = | 715 | static const struct snd_kcontrol_new spk_demux = |
716 | SOC_DAPM_ENUM("Speaker Earpiece Demux", spk_enum); | 716 | SOC_DAPM_ENUM("Speaker Earpiece Demux", spk_enum); |
@@ -720,8 +720,8 @@ static const char *mic_text[] = { | |||
720 | "Mic 1", "Mic 2", | 720 | "Mic 1", "Mic 2", |
721 | }; | 721 | }; |
722 | 722 | ||
723 | static const struct soc_enum mic_enum = | 723 | static SOC_ENUM_SINGLE_DECL(mic_enum, |
724 | SOC_ENUM_SINGLE(PM860X_ADC_ANA_4, 4, 2, mic_text); | 724 | PM860X_ADC_ANA_4, 4, mic_text); |
725 | 725 | ||
726 | static const struct snd_kcontrol_new mic_mux = | 726 | static const struct snd_kcontrol_new mic_mux = |
727 | SOC_DAPM_ENUM("MIC Mux", mic_enum); | 727 | SOC_DAPM_ENUM("MIC Mux", mic_enum); |
@@ -1328,6 +1328,9 @@ static int pm860x_probe(struct snd_soc_codec *codec) | |||
1328 | pm860x->codec = codec; | 1328 | pm860x->codec = codec; |
1329 | 1329 | ||
1330 | codec->control_data = pm860x->regmap; | 1330 | codec->control_data = pm860x->regmap; |
1331 | ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); | ||
1332 | if (ret) | ||
1333 | return ret; | ||
1331 | 1334 | ||
1332 | for (i = 0; i < 4; i++) { | 1335 | for (i = 0; i < 4; i++) { |
1333 | ret = request_threaded_irq(pm860x->irq[i], NULL, | 1336 | ret = request_threaded_irq(pm860x->irq[i], NULL, |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 983d087aa92a..9a6b98de4e29 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -8,6 +8,8 @@ config SND_SOC_I2C_AND_SPI | |||
8 | default y if I2C=y | 8 | default y if I2C=y |
9 | default y if SPI_MASTER=y | 9 | default y if SPI_MASTER=y |
10 | 10 | ||
11 | menu "CODEC drivers" | ||
12 | |||
11 | config SND_SOC_ALL_CODECS | 13 | config SND_SOC_ALL_CODECS |
12 | tristate "Build all ASoC CODEC drivers" | 14 | tristate "Build all ASoC CODEC drivers" |
13 | depends on COMPILE_TEST | 15 | depends on COMPILE_TEST |
@@ -16,15 +18,20 @@ config SND_SOC_ALL_CODECS | |||
16 | select SND_SOC_AB8500_CODEC if ABX500_CORE | 18 | select SND_SOC_AB8500_CODEC if ABX500_CORE |
17 | select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS | 19 | select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS |
18 | select SND_SOC_AD1836 if SPI_MASTER | 20 | select SND_SOC_AD1836 if SPI_MASTER |
19 | select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI | 21 | select SND_SOC_AD193X_SPI if SPI_MASTER |
22 | select SND_SOC_AD193X_I2C if I2C | ||
20 | select SND_SOC_AD1980 if SND_SOC_AC97_BUS | 23 | select SND_SOC_AD1980 if SND_SOC_AC97_BUS |
21 | select SND_SOC_AD73311 | 24 | select SND_SOC_AD73311 |
22 | select SND_SOC_ADAU1373 if I2C | 25 | select SND_SOC_ADAU1373 if I2C |
23 | select SND_SOC_ADAV80X if SND_SOC_I2C_AND_SPI | 26 | select SND_SOC_ADAV801 if SPI_MASTER |
27 | select SND_SOC_ADAV803 if I2C | ||
28 | select SND_SOC_ADAU1977_SPI if SPI_MASTER | ||
29 | select SND_SOC_ADAU1977_I2C if I2C | ||
24 | select SND_SOC_ADAU1701 if I2C | 30 | select SND_SOC_ADAU1701 if I2C |
25 | select SND_SOC_ADS117X | 31 | select SND_SOC_ADS117X |
26 | select SND_SOC_AK4104 if SPI_MASTER | 32 | select SND_SOC_AK4104 if SPI_MASTER |
27 | select SND_SOC_AK4535 if I2C | 33 | select SND_SOC_AK4535 if I2C |
34 | select SND_SOC_AK4554 | ||
28 | select SND_SOC_AK4641 if I2C | 35 | select SND_SOC_AK4641 if I2C |
29 | select SND_SOC_AK4642 if I2C | 36 | select SND_SOC_AK4642 if I2C |
30 | select SND_SOC_AK4671 if I2C | 37 | select SND_SOC_AK4671 if I2C |
@@ -59,6 +66,8 @@ config SND_SOC_ALL_CODECS | |||
59 | select SND_SOC_PCM1681 if I2C | 66 | select SND_SOC_PCM1681 if I2C |
60 | select SND_SOC_PCM1792A if SPI_MASTER | 67 | select SND_SOC_PCM1792A if SPI_MASTER |
61 | select SND_SOC_PCM3008 | 68 | select SND_SOC_PCM3008 |
69 | select SND_SOC_PCM512x_I2C if I2C | ||
70 | select SND_SOC_PCM512x_SPI if SPI_MASTER | ||
62 | select SND_SOC_RT5631 if I2C | 71 | select SND_SOC_RT5631 if I2C |
63 | select SND_SOC_RT5640 if I2C | 72 | select SND_SOC_RT5640 if I2C |
64 | select SND_SOC_SGTL5000 if I2C | 73 | select SND_SOC_SGTL5000 if I2C |
@@ -182,6 +191,14 @@ config SND_SOC_AD1836 | |||
182 | config SND_SOC_AD193X | 191 | config SND_SOC_AD193X |
183 | tristate | 192 | tristate |
184 | 193 | ||
194 | config SND_SOC_AD193X_SPI | ||
195 | tristate | ||
196 | select SND_SOC_AD193X | ||
197 | |||
198 | config SND_SOC_AD193X_I2C | ||
199 | tristate | ||
200 | select SND_SOC_AD193X | ||
201 | |||
185 | config SND_SOC_AD1980 | 202 | config SND_SOC_AD1980 |
186 | tristate | 203 | tristate |
187 | 204 | ||
@@ -189,41 +206,66 @@ config SND_SOC_AD73311 | |||
189 | tristate | 206 | tristate |
190 | 207 | ||
191 | config SND_SOC_ADAU1701 | 208 | config SND_SOC_ADAU1701 |
209 | tristate "Analog Devices ADAU1701 CODEC" | ||
210 | depends on I2C | ||
192 | select SND_SOC_SIGMADSP | 211 | select SND_SOC_SIGMADSP |
193 | tristate | ||
194 | 212 | ||
195 | config SND_SOC_ADAU1373 | 213 | config SND_SOC_ADAU1373 |
196 | tristate | 214 | tristate |
197 | 215 | ||
216 | config SND_SOC_ADAU1977 | ||
217 | tristate | ||
218 | |||
219 | config SND_SOC_ADAU1977_SPI | ||
220 | tristate | ||
221 | select SND_SOC_ADAU1977 | ||
222 | select REGMAP_SPI | ||
223 | |||
224 | config SND_SOC_ADAU1977_I2C | ||
225 | tristate | ||
226 | select SND_SOC_ADAU1977 | ||
227 | select REGMAP_I2C | ||
228 | |||
198 | config SND_SOC_ADAV80X | 229 | config SND_SOC_ADAV80X |
199 | tristate | 230 | tristate |
200 | 231 | ||
232 | config SND_SOC_ADAV801 | ||
233 | tristate | ||
234 | select SND_SOC_ADAV80X | ||
235 | |||
236 | config SND_SOC_ADAV803 | ||
237 | tristate | ||
238 | select SND_SOC_ADAV80X | ||
239 | |||
201 | config SND_SOC_ADS117X | 240 | config SND_SOC_ADS117X |
202 | tristate | 241 | tristate |
203 | 242 | ||
204 | config SND_SOC_AK4104 | 243 | config SND_SOC_AK4104 |
205 | tristate | 244 | tristate "AKM AK4104 CODEC" |
245 | depends on SPI_MASTER | ||
206 | 246 | ||
207 | config SND_SOC_AK4535 | 247 | config SND_SOC_AK4535 |
208 | tristate | 248 | tristate |
209 | 249 | ||
210 | config SND_SOC_AK4554 | 250 | config SND_SOC_AK4554 |
211 | tristate | 251 | tristate "AKM AK4554 CODEC" |
212 | 252 | ||
213 | config SND_SOC_AK4641 | 253 | config SND_SOC_AK4641 |
214 | tristate | 254 | tristate |
215 | 255 | ||
216 | config SND_SOC_AK4642 | 256 | config SND_SOC_AK4642 |
217 | tristate | 257 | tristate "AKM AK4642 CODEC" |
258 | depends on I2C | ||
218 | 259 | ||
219 | config SND_SOC_AK4671 | 260 | config SND_SOC_AK4671 |
220 | tristate | 261 | tristate |
221 | 262 | ||
222 | config SND_SOC_AK5386 | 263 | config SND_SOC_AK5386 |
223 | tristate | 264 | tristate "AKM AK5638 CODEC" |
224 | 265 | ||
225 | config SND_SOC_ALC5623 | 266 | config SND_SOC_ALC5623 |
226 | tristate | 267 | tristate |
268 | |||
227 | config SND_SOC_ALC5632 | 269 | config SND_SOC_ALC5632 |
228 | tristate | 270 | tristate |
229 | 271 | ||
@@ -234,14 +276,17 @@ config SND_SOC_CS42L51 | |||
234 | tristate | 276 | tristate |
235 | 277 | ||
236 | config SND_SOC_CS42L52 | 278 | config SND_SOC_CS42L52 |
237 | tristate | 279 | tristate "Cirrus Logic CS42L52 CODEC" |
280 | depends on I2C | ||
238 | 281 | ||
239 | config SND_SOC_CS42L73 | 282 | config SND_SOC_CS42L73 |
240 | tristate | 283 | tristate "Cirrus Logic CS42L73 CODEC" |
284 | depends on I2C | ||
241 | 285 | ||
242 | # Cirrus Logic CS4270 Codec | 286 | # Cirrus Logic CS4270 Codec |
243 | config SND_SOC_CS4270 | 287 | config SND_SOC_CS4270 |
244 | tristate | 288 | tristate "Cirrus Logic CS4270 CODEC" |
289 | depends on I2C | ||
245 | 290 | ||
246 | # Cirrus Logic CS4270 Codec VD = 3.3V Errata | 291 | # Cirrus Logic CS4270 Codec VD = 3.3V Errata |
247 | # Select if you are affected by the errata where the part will not function | 292 | # Select if you are affected by the errata where the part will not function |
@@ -252,7 +297,8 @@ config SND_SOC_CS4270_VD33_ERRATA | |||
252 | depends on SND_SOC_CS4270 | 297 | depends on SND_SOC_CS4270 |
253 | 298 | ||
254 | config SND_SOC_CS4271 | 299 | config SND_SOC_CS4271 |
255 | tristate | 300 | tristate "Cirrus Logic CS4271 CODEC" |
301 | depends on SND_SOC_I2C_AND_SPI | ||
256 | 302 | ||
257 | config SND_SOC_CX20442 | 303 | config SND_SOC_CX20442 |
258 | tristate | 304 | tristate |
@@ -283,6 +329,9 @@ config SND_SOC_BT_SCO | |||
283 | config SND_SOC_DMIC | 329 | config SND_SOC_DMIC |
284 | tristate | 330 | tristate |
285 | 331 | ||
332 | config SND_SOC_HDMI_CODEC | ||
333 | tristate "HDMI stub CODEC" | ||
334 | |||
286 | config SND_SOC_ISABELLE | 335 | config SND_SOC_ISABELLE |
287 | tristate | 336 | tristate |
288 | 337 | ||
@@ -301,18 +350,32 @@ config SND_SOC_MAX98095 | |||
301 | config SND_SOC_MAX9850 | 350 | config SND_SOC_MAX9850 |
302 | tristate | 351 | tristate |
303 | 352 | ||
304 | config SND_SOC_HDMI_CODEC | ||
305 | tristate | ||
306 | |||
307 | config SND_SOC_PCM1681 | 353 | config SND_SOC_PCM1681 |
308 | tristate | 354 | tristate "Texas Instruments PCM1681 CODEC" |
355 | depends on I2C | ||
309 | 356 | ||
310 | config SND_SOC_PCM1792A | 357 | config SND_SOC_PCM1792A |
311 | tristate | 358 | tristate "Texas Instruments PCM1792A CODEC" |
359 | depends on SPI_MASTER | ||
312 | 360 | ||
313 | config SND_SOC_PCM3008 | 361 | config SND_SOC_PCM3008 |
314 | tristate | 362 | tristate |
315 | 363 | ||
364 | config SND_SOC_PCM512x | ||
365 | tristate | ||
366 | |||
367 | config SND_SOC_PCM512x_I2C | ||
368 | tristate "Texas Instruments PCM512x CODECs - I2C" | ||
369 | depends on I2C | ||
370 | select SND_SOC_PCM512x | ||
371 | select REGMAP_I2C | ||
372 | |||
373 | config SND_SOC_PCM512x_SPI | ||
374 | tristate "Texas Instruments PCM512x CODECs - SPI" | ||
375 | depends on SPI_MASTER | ||
376 | select SND_SOC_PCM512x | ||
377 | select REGMAP_SPI | ||
378 | |||
316 | config SND_SOC_RT5631 | 379 | config SND_SOC_RT5631 |
317 | tristate | 380 | tristate |
318 | 381 | ||
@@ -321,7 +384,8 @@ config SND_SOC_RT5640 | |||
321 | 384 | ||
322 | #Freescale sgtl5000 codec | 385 | #Freescale sgtl5000 codec |
323 | config SND_SOC_SGTL5000 | 386 | config SND_SOC_SGTL5000 |
324 | tristate | 387 | tristate "Freescale SGTL5000 CODEC" |
388 | depends on I2C | ||
325 | 389 | ||
326 | config SND_SOC_SI476X | 390 | config SND_SOC_SI476X |
327 | tristate | 391 | tristate |
@@ -334,7 +398,7 @@ config SND_SOC_SN95031 | |||
334 | tristate | 398 | tristate |
335 | 399 | ||
336 | config SND_SOC_SPDIF | 400 | config SND_SOC_SPDIF |
337 | tristate | 401 | tristate "S/PDIF CODEC" |
338 | 402 | ||
339 | config SND_SOC_SSM2518 | 403 | config SND_SOC_SSM2518 |
340 | tristate | 404 | tristate |
@@ -352,7 +416,8 @@ config SND_SOC_STAC9766 | |||
352 | tristate | 416 | tristate |
353 | 417 | ||
354 | config SND_SOC_TAS5086 | 418 | config SND_SOC_TAS5086 |
355 | tristate | 419 | tristate "Texas Instruments TAS5086 speaker amplifier" |
420 | depends on I2C | ||
356 | 421 | ||
357 | config SND_SOC_TLV320AIC23 | 422 | config SND_SOC_TLV320AIC23 |
358 | tristate | 423 | tristate |
@@ -365,7 +430,8 @@ config SND_SOC_TLV320AIC32X4 | |||
365 | tristate | 430 | tristate |
366 | 431 | ||
367 | config SND_SOC_TLV320AIC3X | 432 | config SND_SOC_TLV320AIC3X |
368 | tristate | 433 | tristate "Texas Instruments TLV320AIC3x CODECs" |
434 | depends on I2C | ||
369 | 435 | ||
370 | config SND_SOC_TLV320DAC33 | 436 | config SND_SOC_TLV320DAC33 |
371 | tristate | 437 | tristate |
@@ -414,55 +480,69 @@ config SND_SOC_WM8400 | |||
414 | tristate | 480 | tristate |
415 | 481 | ||
416 | config SND_SOC_WM8510 | 482 | config SND_SOC_WM8510 |
417 | tristate | 483 | tristate "Wolfson Microelectronics WM8510 CODEC" |
484 | depends on SND_SOC_I2C_AND_SPI | ||
418 | 485 | ||
419 | config SND_SOC_WM8523 | 486 | config SND_SOC_WM8523 |
420 | tristate | 487 | tristate "Wolfson Microelectronics WM8523 DAC" |
488 | depends on I2C | ||
421 | 489 | ||
422 | config SND_SOC_WM8580 | 490 | config SND_SOC_WM8580 |
423 | tristate | 491 | tristate "Wolfson Microelectronics WM8523 CODEC" |
492 | depends on I2C | ||
424 | 493 | ||
425 | config SND_SOC_WM8711 | 494 | config SND_SOC_WM8711 |
426 | tristate | 495 | tristate "Wolfson Microelectronics WM8711 CODEC" |
496 | depends on SND_SOC_I2C_AND_SPI | ||
427 | 497 | ||
428 | config SND_SOC_WM8727 | 498 | config SND_SOC_WM8727 |
429 | tristate | 499 | tristate |
430 | 500 | ||
431 | config SND_SOC_WM8728 | 501 | config SND_SOC_WM8728 |
432 | tristate | 502 | tristate "Wolfson Microelectronics WM8728 DAC" |
503 | depends on SND_SOC_I2C_AND_SPI | ||
433 | 504 | ||
434 | config SND_SOC_WM8731 | 505 | config SND_SOC_WM8731 |
435 | tristate | 506 | tristate "Wolfson Microelectronics WM8731 CODEC" |
507 | depends on SND_SOC_I2C_AND_SPI | ||
436 | 508 | ||
437 | config SND_SOC_WM8737 | 509 | config SND_SOC_WM8737 |
438 | tristate | 510 | tristate "Wolfson Microelectronics WM8737 ADC" |
511 | depends on SND_SOC_I2C_AND_SPI | ||
439 | 512 | ||
440 | config SND_SOC_WM8741 | 513 | config SND_SOC_WM8741 |
441 | tristate | 514 | tristate "Wolfson Microelectronics WM8737 DAC" |
515 | depends on SND_SOC_I2C_AND_SPI | ||
442 | 516 | ||
443 | config SND_SOC_WM8750 | 517 | config SND_SOC_WM8750 |
444 | tristate | 518 | tristate "Wolfson Microelectronics WM8750 CODEC" |
519 | depends on SND_SOC_I2C_AND_SPI | ||
445 | 520 | ||
446 | config SND_SOC_WM8753 | 521 | config SND_SOC_WM8753 |
447 | tristate | 522 | tristate "Wolfson Microelectronics WM8753 CODEC" |
523 | depends on SND_SOC_I2C_AND_SPI | ||
448 | 524 | ||
449 | config SND_SOC_WM8770 | 525 | config SND_SOC_WM8770 |
450 | tristate | 526 | tristate "Wolfson Microelectronics WM8770 CODEC" |
527 | depends on SPI_MASTER | ||
451 | 528 | ||
452 | config SND_SOC_WM8776 | 529 | config SND_SOC_WM8776 |
453 | tristate | 530 | tristate "Wolfson Microelectronics WM8776 CODEC" |
531 | depends on SND_SOC_I2C_AND_SPI | ||
454 | 532 | ||
455 | config SND_SOC_WM8782 | 533 | config SND_SOC_WM8782 |
456 | tristate | 534 | tristate |
457 | 535 | ||
458 | config SND_SOC_WM8804 | 536 | config SND_SOC_WM8804 |
459 | tristate | 537 | tristate "Wolfson Microelectronics WM8804 S/PDIF transceiver" |
538 | depends on SND_SOC_I2C_AND_SPI | ||
460 | 539 | ||
461 | config SND_SOC_WM8900 | 540 | config SND_SOC_WM8900 |
462 | tristate | 541 | tristate |
463 | 542 | ||
464 | config SND_SOC_WM8903 | 543 | config SND_SOC_WM8903 |
465 | tristate | 544 | tristate "Wolfson Microelectronics WM8903 CODEC" |
545 | depends on I2C | ||
466 | 546 | ||
467 | config SND_SOC_WM8904 | 547 | config SND_SOC_WM8904 |
468 | tristate | 548 | tristate |
@@ -480,7 +560,8 @@ config SND_SOC_WM8961 | |||
480 | tristate | 560 | tristate |
481 | 561 | ||
482 | config SND_SOC_WM8962 | 562 | config SND_SOC_WM8962 |
483 | tristate | 563 | tristate "Wolfson Microelectronics WM8962 CODEC" |
564 | depends on I2C | ||
484 | 565 | ||
485 | config SND_SOC_WM8971 | 566 | config SND_SOC_WM8971 |
486 | tristate | 567 | tristate |
@@ -553,4 +634,7 @@ config SND_SOC_ML26124 | |||
553 | tristate | 634 | tristate |
554 | 635 | ||
555 | config SND_SOC_TPA6130A2 | 636 | config SND_SOC_TPA6130A2 |
556 | tristate | 637 | tristate "Texas Instruments TPA6130A2 headphone amplifier" |
638 | depends on I2C | ||
639 | |||
640 | endmenu | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index bc126764a44d..2a773b855572 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -3,11 +3,18 @@ snd-soc-ab8500-codec-objs := ab8500-codec.o | |||
3 | snd-soc-ac97-objs := ac97.o | 3 | snd-soc-ac97-objs := ac97.o |
4 | snd-soc-ad1836-objs := ad1836.o | 4 | snd-soc-ad1836-objs := ad1836.o |
5 | snd-soc-ad193x-objs := ad193x.o | 5 | snd-soc-ad193x-objs := ad193x.o |
6 | snd-soc-ad193x-spi-objs := ad193x-spi.o | ||
7 | snd-soc-ad193x-i2c-objs := ad193x-i2c.o | ||
6 | snd-soc-ad1980-objs := ad1980.o | 8 | snd-soc-ad1980-objs := ad1980.o |
7 | snd-soc-ad73311-objs := ad73311.o | 9 | snd-soc-ad73311-objs := ad73311.o |
8 | snd-soc-adau1701-objs := adau1701.o | 10 | snd-soc-adau1701-objs := adau1701.o |
9 | snd-soc-adau1373-objs := adau1373.o | 11 | snd-soc-adau1373-objs := adau1373.o |
12 | snd-soc-adau1977-objs := adau1977.o | ||
13 | snd-soc-adau1977-spi-objs := adau1977-spi.o | ||
14 | snd-soc-adau1977-i2c-objs := adau1977-i2c.o | ||
10 | snd-soc-adav80x-objs := adav80x.o | 15 | snd-soc-adav80x-objs := adav80x.o |
16 | snd-soc-adav801-objs := adav801.o | ||
17 | snd-soc-adav803-objs := adav803.o | ||
11 | snd-soc-ads117x-objs := ads117x.o | 18 | snd-soc-ads117x-objs := ads117x.o |
12 | snd-soc-ak4104-objs := ak4104.o | 19 | snd-soc-ak4104-objs := ak4104.o |
13 | snd-soc-ak4535-objs := ak4535.o | 20 | snd-soc-ak4535-objs := ak4535.o |
@@ -46,6 +53,9 @@ snd-soc-hdmi-codec-objs := hdmi.o | |||
46 | snd-soc-pcm1681-objs := pcm1681.o | 53 | snd-soc-pcm1681-objs := pcm1681.o |
47 | snd-soc-pcm1792a-codec-objs := pcm1792a.o | 54 | snd-soc-pcm1792a-codec-objs := pcm1792a.o |
48 | snd-soc-pcm3008-objs := pcm3008.o | 55 | snd-soc-pcm3008-objs := pcm3008.o |
56 | snd-soc-pcm512x-objs := pcm512x.o | ||
57 | snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o | ||
58 | snd-soc-pcm512x-spi-objs := pcm512x-spi.o | ||
49 | snd-soc-rt5631-objs := rt5631.o | 59 | snd-soc-rt5631-objs := rt5631.o |
50 | snd-soc-rt5640-objs := rt5640.o | 60 | snd-soc-rt5640-objs := rt5640.o |
51 | snd-soc-sgtl5000-objs := sgtl5000.o | 61 | snd-soc-sgtl5000-objs := sgtl5000.o |
@@ -134,11 +144,18 @@ obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o | |||
134 | obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o | 144 | obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o |
135 | obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o | 145 | obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o |
136 | obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o | 146 | obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o |
147 | obj-$(CONFIG_SND_SOC_AD193X_SPI) += snd-soc-ad193x-spi.o | ||
148 | obj-$(CONFIG_SND_SOC_AD193X_I2C) += snd-soc-ad193x-i2c.o | ||
137 | obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o | 149 | obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o |
138 | obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o | 150 | obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o |
139 | obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o | 151 | obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o |
152 | obj-$(CONFIG_SND_SOC_ADAU1977) += snd-soc-adau1977.o | ||
153 | obj-$(CONFIG_SND_SOC_ADAU1977_SPI) += snd-soc-adau1977-spi.o | ||
154 | obj-$(CONFIG_SND_SOC_ADAU1977_I2C) += snd-soc-adau1977-i2c.o | ||
140 | obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o | 155 | obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o |
141 | obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o | 156 | obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o |
157 | obj-$(CONFIG_SND_SOC_ADAV801) += snd-soc-adav801.o | ||
158 | obj-$(CONFIG_SND_SOC_ADAV803) += snd-soc-adav803.o | ||
142 | obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o | 159 | obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o |
143 | obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o | 160 | obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o |
144 | obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o | 161 | obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o |
@@ -179,6 +196,9 @@ obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o | |||
179 | obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o | 196 | obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o |
180 | obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o | 197 | obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o |
181 | obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o | 198 | obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o |
199 | obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o | ||
200 | obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o | ||
201 | obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o | ||
182 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o | 202 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o |
183 | obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o | 203 | obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o |
184 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o | 204 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o |
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 77f459868579..685998dd086e 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c | |||
@@ -40,8 +40,8 @@ struct ad1836_priv { | |||
40 | */ | 40 | */ |
41 | static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"}; | 41 | static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"}; |
42 | 42 | ||
43 | static const struct soc_enum ad1836_deemp_enum = | 43 | static SOC_ENUM_SINGLE_DECL(ad1836_deemp_enum, |
44 | SOC_ENUM_SINGLE(AD1836_DAC_CTRL1, 8, 4, ad1836_deemp); | 44 | AD1836_DAC_CTRL1, 8, ad1836_deemp); |
45 | 45 | ||
46 | #define AD1836_DAC_VOLUME(x) \ | 46 | #define AD1836_DAC_VOLUME(x) \ |
47 | SOC_DOUBLE_R("DAC" #x " Playback Volume", AD1836_DAC_L_VOL(x), \ | 47 | SOC_DOUBLE_R("DAC" #x " Playback Volume", AD1836_DAC_L_VOL(x), \ |
diff --git a/sound/soc/codecs/ad193x-i2c.c b/sound/soc/codecs/ad193x-i2c.c new file mode 100644 index 000000000000..df3a1a415825 --- /dev/null +++ b/sound/soc/codecs/ad193x-i2c.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * AD1936/AD1937 audio driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/regmap.h> | ||
12 | |||
13 | #include <sound/soc.h> | ||
14 | |||
15 | #include "ad193x.h" | ||
16 | |||
17 | static const struct i2c_device_id ad193x_id[] = { | ||
18 | { "ad1936", 0 }, | ||
19 | { "ad1937", 0 }, | ||
20 | { } | ||
21 | }; | ||
22 | MODULE_DEVICE_TABLE(i2c, ad193x_id); | ||
23 | |||
24 | static int ad193x_i2c_probe(struct i2c_client *client, | ||
25 | const struct i2c_device_id *id) | ||
26 | { | ||
27 | struct regmap_config config; | ||
28 | |||
29 | config = ad193x_regmap_config; | ||
30 | config.val_bits = 8; | ||
31 | config.reg_bits = 8; | ||
32 | |||
33 | return ad193x_probe(&client->dev, devm_regmap_init_i2c(client, &config)); | ||
34 | } | ||
35 | |||
36 | static int ad193x_i2c_remove(struct i2c_client *client) | ||
37 | { | ||
38 | snd_soc_unregister_codec(&client->dev); | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static struct i2c_driver ad193x_i2c_driver = { | ||
43 | .driver = { | ||
44 | .name = "ad193x", | ||
45 | }, | ||
46 | .probe = ad193x_i2c_probe, | ||
47 | .remove = ad193x_i2c_remove, | ||
48 | .id_table = ad193x_id, | ||
49 | }; | ||
50 | module_i2c_driver(ad193x_i2c_driver); | ||
51 | |||
52 | MODULE_DESCRIPTION("ASoC AD1936/AD1937 audio CODEC driver"); | ||
53 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | ||
54 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/ad193x-spi.c b/sound/soc/codecs/ad193x-spi.c new file mode 100644 index 000000000000..390cef9b9dc2 --- /dev/null +++ b/sound/soc/codecs/ad193x-spi.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * AD1938/AD1939 audio driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/spi/spi.h> | ||
11 | #include <linux/regmap.h> | ||
12 | |||
13 | #include <sound/soc.h> | ||
14 | |||
15 | #include "ad193x.h" | ||
16 | |||
17 | static int ad193x_spi_probe(struct spi_device *spi) | ||
18 | { | ||
19 | struct regmap_config config; | ||
20 | |||
21 | config = ad193x_regmap_config; | ||
22 | config.val_bits = 8; | ||
23 | config.reg_bits = 16; | ||
24 | config.read_flag_mask = 0x09; | ||
25 | config.write_flag_mask = 0x08; | ||
26 | |||
27 | return ad193x_probe(&spi->dev, devm_regmap_init_spi(spi, &config)); | ||
28 | } | ||
29 | |||
30 | static int ad193x_spi_remove(struct spi_device *spi) | ||
31 | { | ||
32 | snd_soc_unregister_codec(&spi->dev); | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static struct spi_driver ad193x_spi_driver = { | ||
37 | .driver = { | ||
38 | .name = "ad193x", | ||
39 | .owner = THIS_MODULE, | ||
40 | }, | ||
41 | .probe = ad193x_spi_probe, | ||
42 | .remove = ad193x_spi_remove, | ||
43 | }; | ||
44 | module_spi_driver(ad193x_spi_driver); | ||
45 | |||
46 | MODULE_DESCRIPTION("ASoC AD1938/AD1939 audio CODEC driver"); | ||
47 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | ||
48 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 5a42dca535b7..9381a767e75f 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c | |||
@@ -6,12 +6,10 @@ | |||
6 | * Licensed under the GPL-2 or later. | 6 | * Licensed under the GPL-2 or later. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/module.h> | 9 | #include <linux/module.h> |
11 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
12 | #include <linux/device.h> | 11 | #include <linux/device.h> |
13 | #include <linux/i2c.h> | 12 | #include <linux/regmap.h> |
14 | #include <linux/spi/spi.h> | ||
15 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
16 | #include <sound/core.h> | 14 | #include <sound/core.h> |
17 | #include <sound/pcm.h> | 15 | #include <sound/pcm.h> |
@@ -19,6 +17,7 @@ | |||
19 | #include <sound/initval.h> | 17 | #include <sound/initval.h> |
20 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
21 | #include <sound/tlv.h> | 19 | #include <sound/tlv.h> |
20 | |||
22 | #include "ad193x.h" | 21 | #include "ad193x.h" |
23 | 22 | ||
24 | /* codec private data */ | 23 | /* codec private data */ |
@@ -32,8 +31,8 @@ struct ad193x_priv { | |||
32 | */ | 31 | */ |
33 | static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"}; | 32 | static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"}; |
34 | 33 | ||
35 | static const struct soc_enum ad193x_deemp_enum = | 34 | static SOC_ENUM_SINGLE_DECL(ad193x_deemp_enum, AD193X_DAC_CTRL2, 1, |
36 | SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp); | 35 | ad193x_deemp); |
37 | 36 | ||
38 | static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0); | 37 | static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0); |
39 | 38 | ||
@@ -320,7 +319,7 @@ static struct snd_soc_dai_driver ad193x_dai = { | |||
320 | .ops = &ad193x_dai_ops, | 319 | .ops = &ad193x_dai_ops, |
321 | }; | 320 | }; |
322 | 321 | ||
323 | static int ad193x_probe(struct snd_soc_codec *codec) | 322 | static int ad193x_codec_probe(struct snd_soc_codec *codec) |
324 | { | 323 | { |
325 | struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); | 324 | struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); |
326 | int ret; | 325 | int ret; |
@@ -352,7 +351,7 @@ static int ad193x_probe(struct snd_soc_codec *codec) | |||
352 | } | 351 | } |
353 | 352 | ||
354 | static struct snd_soc_codec_driver soc_codec_dev_ad193x = { | 353 | static struct snd_soc_codec_driver soc_codec_dev_ad193x = { |
355 | .probe = ad193x_probe, | 354 | .probe = ad193x_codec_probe, |
356 | .controls = ad193x_snd_controls, | 355 | .controls = ad193x_snd_controls, |
357 | .num_controls = ARRAY_SIZE(ad193x_snd_controls), | 356 | .num_controls = ARRAY_SIZE(ad193x_snd_controls), |
358 | .dapm_widgets = ad193x_dapm_widgets, | 357 | .dapm_widgets = ad193x_dapm_widgets, |
@@ -366,140 +365,31 @@ static bool adau193x_reg_volatile(struct device *dev, unsigned int reg) | |||
366 | return false; | 365 | return false; |
367 | } | 366 | } |
368 | 367 | ||
369 | #if defined(CONFIG_SPI_MASTER) | 368 | const struct regmap_config ad193x_regmap_config = { |
370 | |||
371 | static const struct regmap_config ad193x_spi_regmap_config = { | ||
372 | .val_bits = 8, | ||
373 | .reg_bits = 16, | ||
374 | .read_flag_mask = 0x09, | ||
375 | .write_flag_mask = 0x08, | ||
376 | |||
377 | .max_register = AD193X_NUM_REGS - 1, | 369 | .max_register = AD193X_NUM_REGS - 1, |
378 | .volatile_reg = adau193x_reg_volatile, | 370 | .volatile_reg = adau193x_reg_volatile, |
379 | }; | 371 | }; |
372 | EXPORT_SYMBOL_GPL(ad193x_regmap_config); | ||
380 | 373 | ||
381 | static int ad193x_spi_probe(struct spi_device *spi) | 374 | int ad193x_probe(struct device *dev, struct regmap *regmap) |
382 | { | 375 | { |
383 | struct ad193x_priv *ad193x; | 376 | struct ad193x_priv *ad193x; |
384 | 377 | ||
385 | ad193x = devm_kzalloc(&spi->dev, sizeof(struct ad193x_priv), | 378 | if (IS_ERR(regmap)) |
386 | GFP_KERNEL); | 379 | return PTR_ERR(regmap); |
387 | if (ad193x == NULL) | ||
388 | return -ENOMEM; | ||
389 | |||
390 | ad193x->regmap = devm_regmap_init_spi(spi, &ad193x_spi_regmap_config); | ||
391 | if (IS_ERR(ad193x->regmap)) | ||
392 | return PTR_ERR(ad193x->regmap); | ||
393 | |||
394 | spi_set_drvdata(spi, ad193x); | ||
395 | |||
396 | return snd_soc_register_codec(&spi->dev, &soc_codec_dev_ad193x, | ||
397 | &ad193x_dai, 1); | ||
398 | } | ||
399 | |||
400 | static int ad193x_spi_remove(struct spi_device *spi) | ||
401 | { | ||
402 | snd_soc_unregister_codec(&spi->dev); | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static struct spi_driver ad193x_spi_driver = { | ||
407 | .driver = { | ||
408 | .name = "ad193x", | ||
409 | .owner = THIS_MODULE, | ||
410 | }, | ||
411 | .probe = ad193x_spi_probe, | ||
412 | .remove = ad193x_spi_remove, | ||
413 | }; | ||
414 | #endif | ||
415 | |||
416 | #if IS_ENABLED(CONFIG_I2C) | ||
417 | |||
418 | static const struct regmap_config ad193x_i2c_regmap_config = { | ||
419 | .val_bits = 8, | ||
420 | .reg_bits = 8, | ||
421 | |||
422 | .max_register = AD193X_NUM_REGS - 1, | ||
423 | .volatile_reg = adau193x_reg_volatile, | ||
424 | }; | ||
425 | |||
426 | static const struct i2c_device_id ad193x_id[] = { | ||
427 | { "ad1936", 0 }, | ||
428 | { "ad1937", 0 }, | ||
429 | { } | ||
430 | }; | ||
431 | MODULE_DEVICE_TABLE(i2c, ad193x_id); | ||
432 | 380 | ||
433 | static int ad193x_i2c_probe(struct i2c_client *client, | 381 | ad193x = devm_kzalloc(dev, sizeof(*ad193x), GFP_KERNEL); |
434 | const struct i2c_device_id *id) | ||
435 | { | ||
436 | struct ad193x_priv *ad193x; | ||
437 | |||
438 | ad193x = devm_kzalloc(&client->dev, sizeof(struct ad193x_priv), | ||
439 | GFP_KERNEL); | ||
440 | if (ad193x == NULL) | 382 | if (ad193x == NULL) |
441 | return -ENOMEM; | 383 | return -ENOMEM; |
442 | 384 | ||
443 | ad193x->regmap = devm_regmap_init_i2c(client, &ad193x_i2c_regmap_config); | 385 | ad193x->regmap = regmap; |
444 | if (IS_ERR(ad193x->regmap)) | ||
445 | return PTR_ERR(ad193x->regmap); | ||
446 | |||
447 | i2c_set_clientdata(client, ad193x); | ||
448 | |||
449 | return snd_soc_register_codec(&client->dev, &soc_codec_dev_ad193x, | ||
450 | &ad193x_dai, 1); | ||
451 | } | ||
452 | |||
453 | static int ad193x_i2c_remove(struct i2c_client *client) | ||
454 | { | ||
455 | snd_soc_unregister_codec(&client->dev); | ||
456 | return 0; | ||
457 | } | ||
458 | 386 | ||
459 | static struct i2c_driver ad193x_i2c_driver = { | 387 | dev_set_drvdata(dev, ad193x); |
460 | .driver = { | ||
461 | .name = "ad193x", | ||
462 | }, | ||
463 | .probe = ad193x_i2c_probe, | ||
464 | .remove = ad193x_i2c_remove, | ||
465 | .id_table = ad193x_id, | ||
466 | }; | ||
467 | #endif | ||
468 | |||
469 | static int __init ad193x_modinit(void) | ||
470 | { | ||
471 | int ret; | ||
472 | |||
473 | #if IS_ENABLED(CONFIG_I2C) | ||
474 | ret = i2c_add_driver(&ad193x_i2c_driver); | ||
475 | if (ret != 0) { | ||
476 | printk(KERN_ERR "Failed to register AD193X I2C driver: %d\n", | ||
477 | ret); | ||
478 | } | ||
479 | #endif | ||
480 | |||
481 | #if defined(CONFIG_SPI_MASTER) | ||
482 | ret = spi_register_driver(&ad193x_spi_driver); | ||
483 | if (ret != 0) { | ||
484 | printk(KERN_ERR "Failed to register AD193X SPI driver: %d\n", | ||
485 | ret); | ||
486 | } | ||
487 | #endif | ||
488 | return ret; | ||
489 | } | ||
490 | module_init(ad193x_modinit); | ||
491 | |||
492 | static void __exit ad193x_modexit(void) | ||
493 | { | ||
494 | #if defined(CONFIG_SPI_MASTER) | ||
495 | spi_unregister_driver(&ad193x_spi_driver); | ||
496 | #endif | ||
497 | 388 | ||
498 | #if IS_ENABLED(CONFIG_I2C) | 389 | return snd_soc_register_codec(dev, &soc_codec_dev_ad193x, |
499 | i2c_del_driver(&ad193x_i2c_driver); | 390 | &ad193x_dai, 1); |
500 | #endif | ||
501 | } | 391 | } |
502 | module_exit(ad193x_modexit); | 392 | EXPORT_SYMBOL_GPL(ad193x_probe); |
503 | 393 | ||
504 | MODULE_DESCRIPTION("ASoC ad193x driver"); | 394 | MODULE_DESCRIPTION("ASoC ad193x driver"); |
505 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | 395 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); |
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h index 473388049992..ab9a998f15be 100644 --- a/sound/soc/codecs/ad193x.h +++ b/sound/soc/codecs/ad193x.h | |||
@@ -9,6 +9,13 @@ | |||
9 | #ifndef __AD193X_H__ | 9 | #ifndef __AD193X_H__ |
10 | #define __AD193X_H__ | 10 | #define __AD193X_H__ |
11 | 11 | ||
12 | #include <linux/regmap.h> | ||
13 | |||
14 | struct device; | ||
15 | |||
16 | extern const struct regmap_config ad193x_regmap_config; | ||
17 | int ad193x_probe(struct device *dev, struct regmap *regmap); | ||
18 | |||
12 | #define AD193X_PLL_CLK_CTRL0 0x00 | 19 | #define AD193X_PLL_CLK_CTRL0 0x00 |
13 | #define AD193X_PLL_POWERDOWN 0x01 | 20 | #define AD193X_PLL_POWERDOWN 0x01 |
14 | #define AD193X_PLL_INPUT_MASK 0x6 | 21 | #define AD193X_PLL_INPUT_MASK 0x6 |
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 7257a8885f42..34d965a4a040 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
@@ -57,8 +57,8 @@ static const u16 ad1980_reg[] = { | |||
57 | static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line", | 57 | static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line", |
58 | "Stereo Mix", "Mono Mix", "Phone"}; | 58 | "Stereo Mix", "Mono Mix", "Phone"}; |
59 | 59 | ||
60 | static const struct soc_enum ad1980_cap_src = | 60 | static SOC_ENUM_DOUBLE_DECL(ad1980_cap_src, |
61 | SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 7, ad1980_rec_sel); | 61 | AC97_REC_SEL, 8, 0, ad1980_rec_sel); |
62 | 62 | ||
63 | static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = { | 63 | static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = { |
64 | SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1), | 64 | SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1), |
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index eb836ed5271f..5223800775ad 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c | |||
@@ -345,15 +345,15 @@ static const char *adau1373_fdsp_sel_text[] = { | |||
345 | "Channel 5", | 345 | "Channel 5", |
346 | }; | 346 | }; |
347 | 347 | ||
348 | static const SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum, | 348 | static SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum, |
349 | ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text); | 349 | ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text); |
350 | static const SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum, | 350 | static SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum, |
351 | ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text); | 351 | ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text); |
352 | static const SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum, | 352 | static SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum, |
353 | ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text); | 353 | ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text); |
354 | static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum, | 354 | static SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum, |
355 | ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text); | 355 | ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text); |
356 | static const SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum, | 356 | static SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum, |
357 | ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text); | 357 | ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text); |
358 | 358 | ||
359 | static const char *adau1373_hpf_cutoff_text[] = { | 359 | static const char *adau1373_hpf_cutoff_text[] = { |
@@ -362,7 +362,7 @@ static const char *adau1373_hpf_cutoff_text[] = { | |||
362 | "800Hz", | 362 | "800Hz", |
363 | }; | 363 | }; |
364 | 364 | ||
365 | static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum, | 365 | static SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum, |
366 | ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text); | 366 | ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text); |
367 | 367 | ||
368 | static const char *adau1373_bass_lpf_cutoff_text[] = { | 368 | static const char *adau1373_bass_lpf_cutoff_text[] = { |
@@ -388,14 +388,14 @@ static const unsigned int adau1373_bass_tlv[] = { | |||
388 | 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0), | 388 | 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0), |
389 | }; | 389 | }; |
390 | 390 | ||
391 | static const SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum, | 391 | static SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum, |
392 | ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text); | 392 | ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text); |
393 | 393 | ||
394 | static const SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum, | 394 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum, |
395 | ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text, | 395 | ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text, |
396 | adau1373_bass_clip_level_values); | 396 | adau1373_bass_clip_level_values); |
397 | 397 | ||
398 | static const SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum, | 398 | static SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum, |
399 | ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text); | 399 | ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text); |
400 | 400 | ||
401 | static const char *adau1373_3d_level_text[] = { | 401 | static const char *adau1373_3d_level_text[] = { |
@@ -409,9 +409,9 @@ static const char *adau1373_3d_cutoff_text[] = { | |||
409 | "0.16875 fs", "0.27083 fs" | 409 | "0.16875 fs", "0.27083 fs" |
410 | }; | 410 | }; |
411 | 411 | ||
412 | static const SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum, | 412 | static SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum, |
413 | ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text); | 413 | ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text); |
414 | static const SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum, | 414 | static SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum, |
415 | ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text); | 415 | ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text); |
416 | 416 | ||
417 | static const unsigned int adau1373_3d_tlv[] = { | 417 | static const unsigned int adau1373_3d_tlv[] = { |
@@ -427,11 +427,11 @@ static const char *adau1373_lr_mux_text[] = { | |||
427 | "Stereo", | 427 | "Stereo", |
428 | }; | 428 | }; |
429 | 429 | ||
430 | static const SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum, | 430 | static SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum, |
431 | ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text); | 431 | ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text); |
432 | static const SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum, | 432 | static SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum, |
433 | ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text); | 433 | ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text); |
434 | static const SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum, | 434 | static SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum, |
435 | ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text); | 435 | ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text); |
436 | 436 | ||
437 | static const struct snd_kcontrol_new adau1373_controls[] = { | 437 | static const struct snd_kcontrol_new adau1373_controls[] = { |
@@ -576,8 +576,8 @@ static const char *adau1373_decimator_text[] = { | |||
576 | "DMIC1", | 576 | "DMIC1", |
577 | }; | 577 | }; |
578 | 578 | ||
579 | static const struct soc_enum adau1373_decimator_enum = | 579 | static SOC_ENUM_SINGLE_VIRT_DECL(adau1373_decimator_enum, |
580 | SOC_ENUM_SINGLE(0, 0, 2, adau1373_decimator_text); | 580 | adau1373_decimator_text); |
581 | 581 | ||
582 | static const struct snd_kcontrol_new adau1373_decimator_mux = | 582 | static const struct snd_kcontrol_new adau1373_decimator_mux = |
583 | SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum); | 583 | SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum); |
diff --git a/sound/soc/codecs/adau1977-i2c.c b/sound/soc/codecs/adau1977-i2c.c new file mode 100644 index 000000000000..9700e8c838c9 --- /dev/null +++ b/sound/soc/codecs/adau1977-i2c.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * ADAU1977/ADAU1978/ADAU1979 driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
6 | * | ||
7 | * Licensed under the GPL-2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/mod_devicetable.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/regmap.h> | ||
14 | #include <sound/soc.h> | ||
15 | |||
16 | #include "adau1977.h" | ||
17 | |||
18 | static int adau1977_i2c_probe(struct i2c_client *client, | ||
19 | const struct i2c_device_id *id) | ||
20 | { | ||
21 | struct regmap_config config; | ||
22 | |||
23 | config = adau1977_regmap_config; | ||
24 | config.val_bits = 8; | ||
25 | config.reg_bits = 8; | ||
26 | |||
27 | return adau1977_probe(&client->dev, | ||
28 | devm_regmap_init_i2c(client, &config), | ||
29 | id->driver_data, NULL); | ||
30 | } | ||
31 | |||
32 | static int adau1977_i2c_remove(struct i2c_client *client) | ||
33 | { | ||
34 | snd_soc_unregister_codec(&client->dev); | ||
35 | return 0; | ||
36 | } | ||
37 | |||
38 | static const struct i2c_device_id adau1977_i2c_ids[] = { | ||
39 | { "adau1977", ADAU1977 }, | ||
40 | { "adau1978", ADAU1978 }, | ||
41 | { "adau1979", ADAU1978 }, | ||
42 | { } | ||
43 | }; | ||
44 | MODULE_DEVICE_TABLE(i2c, adau1977_i2c_ids); | ||
45 | |||
46 | static struct i2c_driver adau1977_i2c_driver = { | ||
47 | .driver = { | ||
48 | .name = "adau1977", | ||
49 | .owner = THIS_MODULE, | ||
50 | }, | ||
51 | .probe = adau1977_i2c_probe, | ||
52 | .remove = adau1977_i2c_remove, | ||
53 | .id_table = adau1977_i2c_ids, | ||
54 | }; | ||
55 | module_i2c_driver(adau1977_i2c_driver); | ||
56 | |||
57 | MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver"); | ||
58 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
59 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/adau1977-spi.c b/sound/soc/codecs/adau1977-spi.c new file mode 100644 index 000000000000..b05cf5da3a94 --- /dev/null +++ b/sound/soc/codecs/adau1977-spi.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * ADAU1977/ADAU1978/ADAU1979 driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
6 | * | ||
7 | * Licensed under the GPL-2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/mod_devicetable.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/regmap.h> | ||
13 | #include <linux/spi/spi.h> | ||
14 | #include <sound/soc.h> | ||
15 | |||
16 | #include "adau1977.h" | ||
17 | |||
18 | static void adau1977_spi_switch_mode(struct device *dev) | ||
19 | { | ||
20 | struct spi_device *spi = to_spi_device(dev); | ||
21 | |||
22 | /* | ||
23 | * To get the device into SPI mode CLATCH has to be pulled low three | ||
24 | * times. Do this by issuing three dummy reads. | ||
25 | */ | ||
26 | spi_w8r8(spi, 0x00); | ||
27 | spi_w8r8(spi, 0x00); | ||
28 | spi_w8r8(spi, 0x00); | ||
29 | } | ||
30 | |||
31 | static int adau1977_spi_probe(struct spi_device *spi) | ||
32 | { | ||
33 | const struct spi_device_id *id = spi_get_device_id(spi); | ||
34 | struct regmap_config config; | ||
35 | |||
36 | if (!id) | ||
37 | return -EINVAL; | ||
38 | |||
39 | config = adau1977_regmap_config; | ||
40 | config.val_bits = 8; | ||
41 | config.reg_bits = 16; | ||
42 | config.read_flag_mask = 0x1; | ||
43 | |||
44 | return adau1977_probe(&spi->dev, | ||
45 | devm_regmap_init_spi(spi, &config), | ||
46 | id->driver_data, adau1977_spi_switch_mode); | ||
47 | } | ||
48 | |||
49 | static int adau1977_spi_remove(struct spi_device *spi) | ||
50 | { | ||
51 | snd_soc_unregister_codec(&spi->dev); | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static const struct spi_device_id adau1977_spi_ids[] = { | ||
56 | { "adau1977", ADAU1977 }, | ||
57 | { "adau1978", ADAU1978 }, | ||
58 | { "adau1979", ADAU1978 }, | ||
59 | { } | ||
60 | }; | ||
61 | MODULE_DEVICE_TABLE(spi, adau1977_spi_ids); | ||
62 | |||
63 | static struct spi_driver adau1977_spi_driver = { | ||
64 | .driver = { | ||
65 | .name = "adau1977", | ||
66 | .owner = THIS_MODULE, | ||
67 | }, | ||
68 | .probe = adau1977_spi_probe, | ||
69 | .remove = adau1977_spi_remove, | ||
70 | .id_table = adau1977_spi_ids, | ||
71 | }; | ||
72 | module_spi_driver(adau1977_spi_driver); | ||
73 | |||
74 | MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver"); | ||
75 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
76 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c new file mode 100644 index 000000000000..fd55da7cb9d4 --- /dev/null +++ b/sound/soc/codecs/adau1977.c | |||
@@ -0,0 +1,1018 @@ | |||
1 | /* | ||
2 | * ADAU1977/ADAU1978/ADAU1979 driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
6 | * | ||
7 | * Licensed under the GPL-2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/delay.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/gpio/consumer.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_data/adau1977.h> | ||
17 | #include <linux/regmap.h> | ||
18 | #include <linux/regulator/consumer.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #include <sound/core.h> | ||
22 | #include <sound/initval.h> | ||
23 | #include <sound/pcm.h> | ||
24 | #include <sound/pcm_params.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include <sound/tlv.h> | ||
27 | |||
28 | #include "adau1977.h" | ||
29 | |||
30 | #define ADAU1977_REG_POWER 0x00 | ||
31 | #define ADAU1977_REG_PLL 0x01 | ||
32 | #define ADAU1977_REG_BOOST 0x02 | ||
33 | #define ADAU1977_REG_MICBIAS 0x03 | ||
34 | #define ADAU1977_REG_BLOCK_POWER_SAI 0x04 | ||
35 | #define ADAU1977_REG_SAI_CTRL0 0x05 | ||
36 | #define ADAU1977_REG_SAI_CTRL1 0x06 | ||
37 | #define ADAU1977_REG_CMAP12 0x07 | ||
38 | #define ADAU1977_REG_CMAP34 0x08 | ||
39 | #define ADAU1977_REG_SAI_OVERTEMP 0x09 | ||
40 | #define ADAU1977_REG_POST_ADC_GAIN(x) (0x0a + (x)) | ||
41 | #define ADAU1977_REG_MISC_CONTROL 0x0e | ||
42 | #define ADAU1977_REG_DIAG_CONTROL 0x10 | ||
43 | #define ADAU1977_REG_STATUS(x) (0x11 + (x)) | ||
44 | #define ADAU1977_REG_DIAG_IRQ1 0x15 | ||
45 | #define ADAU1977_REG_DIAG_IRQ2 0x16 | ||
46 | #define ADAU1977_REG_ADJUST1 0x17 | ||
47 | #define ADAU1977_REG_ADJUST2 0x18 | ||
48 | #define ADAU1977_REG_ADC_CLIP 0x19 | ||
49 | #define ADAU1977_REG_DC_HPF_CAL 0x1a | ||
50 | |||
51 | #define ADAU1977_POWER_RESET BIT(7) | ||
52 | #define ADAU1977_POWER_PWUP BIT(0) | ||
53 | |||
54 | #define ADAU1977_PLL_CLK_S BIT(4) | ||
55 | #define ADAU1977_PLL_MCS_MASK 0x7 | ||
56 | |||
57 | #define ADAU1977_MICBIAS_MB_VOLTS_MASK 0xf0 | ||
58 | #define ADAU1977_MICBIAS_MB_VOLTS_OFFSET 4 | ||
59 | |||
60 | #define ADAU1977_BLOCK_POWER_SAI_LR_POL BIT(7) | ||
61 | #define ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE BIT(6) | ||
62 | #define ADAU1977_BLOCK_POWER_SAI_LDO_EN BIT(5) | ||
63 | |||
64 | #define ADAU1977_SAI_CTRL0_FMT_MASK (0x3 << 6) | ||
65 | #define ADAU1977_SAI_CTRL0_FMT_I2S (0x0 << 6) | ||
66 | #define ADAU1977_SAI_CTRL0_FMT_LJ (0x1 << 6) | ||
67 | #define ADAU1977_SAI_CTRL0_FMT_RJ_24BIT (0x2 << 6) | ||
68 | #define ADAU1977_SAI_CTRL0_FMT_RJ_16BIT (0x3 << 6) | ||
69 | |||
70 | #define ADAU1977_SAI_CTRL0_SAI_MASK (0x7 << 3) | ||
71 | #define ADAU1977_SAI_CTRL0_SAI_I2S (0x0 << 3) | ||
72 | #define ADAU1977_SAI_CTRL0_SAI_TDM_2 (0x1 << 3) | ||
73 | #define ADAU1977_SAI_CTRL0_SAI_TDM_4 (0x2 << 3) | ||
74 | #define ADAU1977_SAI_CTRL0_SAI_TDM_8 (0x3 << 3) | ||
75 | #define ADAU1977_SAI_CTRL0_SAI_TDM_16 (0x4 << 3) | ||
76 | |||
77 | #define ADAU1977_SAI_CTRL0_FS_MASK (0x7) | ||
78 | #define ADAU1977_SAI_CTRL0_FS_8000_12000 (0x0) | ||
79 | #define ADAU1977_SAI_CTRL0_FS_16000_24000 (0x1) | ||
80 | #define ADAU1977_SAI_CTRL0_FS_32000_48000 (0x2) | ||
81 | #define ADAU1977_SAI_CTRL0_FS_64000_96000 (0x3) | ||
82 | #define ADAU1977_SAI_CTRL0_FS_128000_192000 (0x4) | ||
83 | |||
84 | #define ADAU1977_SAI_CTRL1_SLOT_WIDTH_MASK (0x3 << 5) | ||
85 | #define ADAU1977_SAI_CTRL1_SLOT_WIDTH_32 (0x0 << 5) | ||
86 | #define ADAU1977_SAI_CTRL1_SLOT_WIDTH_24 (0x1 << 5) | ||
87 | #define ADAU1977_SAI_CTRL1_SLOT_WIDTH_16 (0x2 << 5) | ||
88 | #define ADAU1977_SAI_CTRL1_DATA_WIDTH_MASK (0x1 << 4) | ||
89 | #define ADAU1977_SAI_CTRL1_DATA_WIDTH_16BIT (0x1 << 4) | ||
90 | #define ADAU1977_SAI_CTRL1_DATA_WIDTH_24BIT (0x0 << 4) | ||
91 | #define ADAU1977_SAI_CTRL1_LRCLK_PULSE BIT(3) | ||
92 | #define ADAU1977_SAI_CTRL1_MSB BIT(2) | ||
93 | #define ADAU1977_SAI_CTRL1_BCLKRATE_16 (0x1 << 1) | ||
94 | #define ADAU1977_SAI_CTRL1_BCLKRATE_32 (0x0 << 1) | ||
95 | #define ADAU1977_SAI_CTRL1_BCLKRATE_MASK (0x1 << 1) | ||
96 | #define ADAU1977_SAI_CTRL1_MASTER BIT(0) | ||
97 | |||
98 | #define ADAU1977_SAI_OVERTEMP_DRV_C(x) BIT(4 + (x)) | ||
99 | #define ADAU1977_SAI_OVERTEMP_DRV_HIZ BIT(3) | ||
100 | |||
101 | #define ADAU1977_MISC_CONTROL_SUM_MODE_MASK (0x3 << 6) | ||
102 | #define ADAU1977_MISC_CONTROL_SUM_MODE_1CH (0x2 << 6) | ||
103 | #define ADAU1977_MISC_CONTROL_SUM_MODE_2CH (0x1 << 6) | ||
104 | #define ADAU1977_MISC_CONTROL_SUM_MODE_4CH (0x0 << 6) | ||
105 | #define ADAU1977_MISC_CONTROL_MMUTE BIT(4) | ||
106 | #define ADAU1977_MISC_CONTROL_DC_CAL BIT(0) | ||
107 | |||
108 | #define ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET 4 | ||
109 | #define ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET 0 | ||
110 | |||
111 | struct adau1977 { | ||
112 | struct regmap *regmap; | ||
113 | bool right_j; | ||
114 | unsigned int sysclk; | ||
115 | enum adau1977_sysclk_src sysclk_src; | ||
116 | struct gpio_desc *reset_gpio; | ||
117 | enum adau1977_type type; | ||
118 | |||
119 | struct regulator *avdd_reg; | ||
120 | struct regulator *dvdd_reg; | ||
121 | |||
122 | struct snd_pcm_hw_constraint_list constraints; | ||
123 | |||
124 | struct device *dev; | ||
125 | void (*switch_mode)(struct device *dev); | ||
126 | |||
127 | unsigned int max_master_fs; | ||
128 | unsigned int slot_width; | ||
129 | bool enabled; | ||
130 | bool master; | ||
131 | }; | ||
132 | |||
133 | static const struct reg_default adau1977_reg_defaults[] = { | ||
134 | { 0x00, 0x00 }, | ||
135 | { 0x01, 0x41 }, | ||
136 | { 0x02, 0x4a }, | ||
137 | { 0x03, 0x7d }, | ||
138 | { 0x04, 0x3d }, | ||
139 | { 0x05, 0x02 }, | ||
140 | { 0x06, 0x00 }, | ||
141 | { 0x07, 0x10 }, | ||
142 | { 0x08, 0x32 }, | ||
143 | { 0x09, 0xf0 }, | ||
144 | { 0x0a, 0xa0 }, | ||
145 | { 0x0b, 0xa0 }, | ||
146 | { 0x0c, 0xa0 }, | ||
147 | { 0x0d, 0xa0 }, | ||
148 | { 0x0e, 0x02 }, | ||
149 | { 0x10, 0x0f }, | ||
150 | { 0x15, 0x20 }, | ||
151 | { 0x16, 0x00 }, | ||
152 | { 0x17, 0x00 }, | ||
153 | { 0x18, 0x00 }, | ||
154 | { 0x1a, 0x00 }, | ||
155 | }; | ||
156 | |||
157 | static const DECLARE_TLV_DB_MINMAX_MUTE(adau1977_adc_gain, -3562, 6000); | ||
158 | |||
159 | static const struct snd_soc_dapm_widget adau1977_micbias_dapm_widgets[] = { | ||
160 | SND_SOC_DAPM_SUPPLY("MICBIAS", ADAU1977_REG_MICBIAS, | ||
161 | 3, 0, NULL, 0) | ||
162 | }; | ||
163 | |||
164 | static const struct snd_soc_dapm_widget adau1977_dapm_widgets[] = { | ||
165 | SND_SOC_DAPM_SUPPLY("Vref", ADAU1977_REG_BLOCK_POWER_SAI, | ||
166 | 4, 0, NULL, 0), | ||
167 | |||
168 | SND_SOC_DAPM_ADC("ADC1", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 0, 0), | ||
169 | SND_SOC_DAPM_ADC("ADC2", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 1, 0), | ||
170 | SND_SOC_DAPM_ADC("ADC3", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 2, 0), | ||
171 | SND_SOC_DAPM_ADC("ADC4", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 3, 0), | ||
172 | |||
173 | SND_SOC_DAPM_INPUT("AIN1"), | ||
174 | SND_SOC_DAPM_INPUT("AIN2"), | ||
175 | SND_SOC_DAPM_INPUT("AIN3"), | ||
176 | SND_SOC_DAPM_INPUT("AIN4"), | ||
177 | |||
178 | SND_SOC_DAPM_OUTPUT("VREF"), | ||
179 | }; | ||
180 | |||
181 | static const struct snd_soc_dapm_route adau1977_dapm_routes[] = { | ||
182 | { "ADC1", NULL, "AIN1" }, | ||
183 | { "ADC2", NULL, "AIN2" }, | ||
184 | { "ADC3", NULL, "AIN3" }, | ||
185 | { "ADC4", NULL, "AIN4" }, | ||
186 | |||
187 | { "ADC1", NULL, "Vref" }, | ||
188 | { "ADC2", NULL, "Vref" }, | ||
189 | { "ADC3", NULL, "Vref" }, | ||
190 | { "ADC4", NULL, "Vref" }, | ||
191 | |||
192 | { "VREF", NULL, "Vref" }, | ||
193 | }; | ||
194 | |||
195 | #define ADAU1977_VOLUME(x) \ | ||
196 | SOC_SINGLE_TLV("ADC" #x " Capture Volume", \ | ||
197 | ADAU1977_REG_POST_ADC_GAIN((x) - 1), \ | ||
198 | 0, 255, 1, adau1977_adc_gain) | ||
199 | |||
200 | #define ADAU1977_HPF_SWITCH(x) \ | ||
201 | SOC_SINGLE("ADC" #x " Highpass-Filter Capture Switch", \ | ||
202 | ADAU1977_REG_DC_HPF_CAL, (x) - 1, 1, 0) | ||
203 | |||
204 | #define ADAU1977_DC_SUB_SWITCH(x) \ | ||
205 | SOC_SINGLE("ADC" #x " DC Substraction Capture Switch", \ | ||
206 | ADAU1977_REG_DC_HPF_CAL, (x) + 3, 1, 0) | ||
207 | |||
208 | static const struct snd_kcontrol_new adau1977_snd_controls[] = { | ||
209 | ADAU1977_VOLUME(1), | ||
210 | ADAU1977_VOLUME(2), | ||
211 | ADAU1977_VOLUME(3), | ||
212 | ADAU1977_VOLUME(4), | ||
213 | |||
214 | ADAU1977_HPF_SWITCH(1), | ||
215 | ADAU1977_HPF_SWITCH(2), | ||
216 | ADAU1977_HPF_SWITCH(3), | ||
217 | ADAU1977_HPF_SWITCH(4), | ||
218 | |||
219 | ADAU1977_DC_SUB_SWITCH(1), | ||
220 | ADAU1977_DC_SUB_SWITCH(2), | ||
221 | ADAU1977_DC_SUB_SWITCH(3), | ||
222 | ADAU1977_DC_SUB_SWITCH(4), | ||
223 | }; | ||
224 | |||
225 | static int adau1977_reset(struct adau1977 *adau1977) | ||
226 | { | ||
227 | int ret; | ||
228 | |||
229 | /* | ||
230 | * The reset bit is obviously volatile, but we need to be able to cache | ||
231 | * the other bits in the register, so we can't just mark the whole | ||
232 | * register as volatile. Since this is the only place where we'll ever | ||
233 | * touch the reset bit just bypass the cache for this operation. | ||
234 | */ | ||
235 | regcache_cache_bypass(adau1977->regmap, true); | ||
236 | ret = regmap_write(adau1977->regmap, ADAU1977_REG_POWER, | ||
237 | ADAU1977_POWER_RESET); | ||
238 | regcache_cache_bypass(adau1977->regmap, false); | ||
239 | if (ret) | ||
240 | return ret; | ||
241 | |||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Returns the appropriate setting for ths FS field in the CTRL0 register | ||
247 | * depending on the rate. | ||
248 | */ | ||
249 | static int adau1977_lookup_fs(unsigned int rate) | ||
250 | { | ||
251 | if (rate >= 8000 && rate <= 12000) | ||
252 | return ADAU1977_SAI_CTRL0_FS_8000_12000; | ||
253 | else if (rate >= 16000 && rate <= 24000) | ||
254 | return ADAU1977_SAI_CTRL0_FS_16000_24000; | ||
255 | else if (rate >= 32000 && rate <= 48000) | ||
256 | return ADAU1977_SAI_CTRL0_FS_32000_48000; | ||
257 | else if (rate >= 64000 && rate <= 96000) | ||
258 | return ADAU1977_SAI_CTRL0_FS_64000_96000; | ||
259 | else if (rate >= 128000 && rate <= 192000) | ||
260 | return ADAU1977_SAI_CTRL0_FS_128000_192000; | ||
261 | else | ||
262 | return -EINVAL; | ||
263 | } | ||
264 | |||
265 | static int adau1977_lookup_mcs(struct adau1977 *adau1977, unsigned int rate, | ||
266 | unsigned int fs) | ||
267 | { | ||
268 | unsigned int mcs; | ||
269 | |||
270 | /* | ||
271 | * rate = sysclk / (512 * mcs_lut[mcs]) * 2**fs | ||
272 | * => mcs_lut[mcs] = sysclk / (512 * rate) * 2**fs | ||
273 | * => mcs_lut[mcs] = sysclk / ((512 / 2**fs) * rate) | ||
274 | */ | ||
275 | |||
276 | rate *= 512 >> fs; | ||
277 | |||
278 | if (adau1977->sysclk % rate != 0) | ||
279 | return -EINVAL; | ||
280 | |||
281 | mcs = adau1977->sysclk / rate; | ||
282 | |||
283 | /* The factors configured by MCS are 1, 2, 3, 4, 6 */ | ||
284 | if (mcs < 1 || mcs > 6 || mcs == 5) | ||
285 | return -EINVAL; | ||
286 | |||
287 | mcs = mcs - 1; | ||
288 | if (mcs == 5) | ||
289 | mcs = 4; | ||
290 | |||
291 | return mcs; | ||
292 | } | ||
293 | |||
294 | static int adau1977_hw_params(struct snd_pcm_substream *substream, | ||
295 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
296 | { | ||
297 | struct snd_soc_codec *codec = dai->codec; | ||
298 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec); | ||
299 | unsigned int rate = params_rate(params); | ||
300 | unsigned int slot_width; | ||
301 | unsigned int ctrl0, ctrl0_mask; | ||
302 | unsigned int ctrl1; | ||
303 | int mcs, fs; | ||
304 | int ret; | ||
305 | |||
306 | fs = adau1977_lookup_fs(rate); | ||
307 | if (fs < 0) | ||
308 | return fs; | ||
309 | |||
310 | if (adau1977->sysclk_src == ADAU1977_SYSCLK_SRC_MCLK) { | ||
311 | mcs = adau1977_lookup_mcs(adau1977, rate, fs); | ||
312 | if (mcs < 0) | ||
313 | return mcs; | ||
314 | } else { | ||
315 | mcs = 0; | ||
316 | } | ||
317 | |||
318 | ctrl0_mask = ADAU1977_SAI_CTRL0_FS_MASK; | ||
319 | ctrl0 = fs; | ||
320 | |||
321 | if (adau1977->right_j) { | ||
322 | switch (params_width(params)) { | ||
323 | case 16: | ||
324 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_16BIT; | ||
325 | break; | ||
326 | case 24: | ||
327 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT; | ||
328 | break; | ||
329 | default: | ||
330 | return -EINVAL; | ||
331 | } | ||
332 | ctrl0_mask |= ADAU1977_SAI_CTRL0_FMT_MASK; | ||
333 | } | ||
334 | |||
335 | if (adau1977->master) { | ||
336 | switch (params_width(params)) { | ||
337 | case 16: | ||
338 | ctrl1 = ADAU1977_SAI_CTRL1_DATA_WIDTH_16BIT; | ||
339 | slot_width = 16; | ||
340 | break; | ||
341 | case 24: | ||
342 | case 32: | ||
343 | ctrl1 = ADAU1977_SAI_CTRL1_DATA_WIDTH_24BIT; | ||
344 | slot_width = 32; | ||
345 | break; | ||
346 | default: | ||
347 | return -EINVAL; | ||
348 | } | ||
349 | |||
350 | /* In TDM mode there is a fixed slot width */ | ||
351 | if (adau1977->slot_width) | ||
352 | slot_width = adau1977->slot_width; | ||
353 | |||
354 | if (slot_width == 16) | ||
355 | ctrl1 |= ADAU1977_SAI_CTRL1_BCLKRATE_16; | ||
356 | else | ||
357 | ctrl1 |= ADAU1977_SAI_CTRL1_BCLKRATE_32; | ||
358 | |||
359 | ret = regmap_update_bits(adau1977->regmap, | ||
360 | ADAU1977_REG_SAI_CTRL1, | ||
361 | ADAU1977_SAI_CTRL1_DATA_WIDTH_MASK | | ||
362 | ADAU1977_SAI_CTRL1_BCLKRATE_MASK, | ||
363 | ctrl1); | ||
364 | if (ret < 0) | ||
365 | return ret; | ||
366 | } | ||
367 | |||
368 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0, | ||
369 | ctrl0_mask, ctrl0); | ||
370 | if (ret < 0) | ||
371 | return ret; | ||
372 | |||
373 | return regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL, | ||
374 | ADAU1977_PLL_MCS_MASK, mcs); | ||
375 | } | ||
376 | |||
377 | static int adau1977_power_disable(struct adau1977 *adau1977) | ||
378 | { | ||
379 | int ret = 0; | ||
380 | |||
381 | if (!adau1977->enabled) | ||
382 | return 0; | ||
383 | |||
384 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER, | ||
385 | ADAU1977_POWER_PWUP, 0); | ||
386 | if (ret) | ||
387 | return ret; | ||
388 | |||
389 | regcache_mark_dirty(adau1977->regmap); | ||
390 | |||
391 | if (adau1977->reset_gpio) | ||
392 | gpiod_set_value_cansleep(adau1977->reset_gpio, 0); | ||
393 | |||
394 | regcache_cache_only(adau1977->regmap, true); | ||
395 | |||
396 | regulator_disable(adau1977->avdd_reg); | ||
397 | if (adau1977->dvdd_reg) | ||
398 | regulator_disable(adau1977->dvdd_reg); | ||
399 | |||
400 | adau1977->enabled = false; | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static int adau1977_power_enable(struct adau1977 *adau1977) | ||
406 | { | ||
407 | unsigned int val; | ||
408 | int ret = 0; | ||
409 | |||
410 | if (adau1977->enabled) | ||
411 | return 0; | ||
412 | |||
413 | ret = regulator_enable(adau1977->avdd_reg); | ||
414 | if (ret) | ||
415 | return ret; | ||
416 | |||
417 | if (adau1977->dvdd_reg) { | ||
418 | ret = regulator_enable(adau1977->dvdd_reg); | ||
419 | if (ret) | ||
420 | goto err_disable_avdd; | ||
421 | } | ||
422 | |||
423 | if (adau1977->reset_gpio) | ||
424 | gpiod_set_value_cansleep(adau1977->reset_gpio, 1); | ||
425 | |||
426 | regcache_cache_only(adau1977->regmap, false); | ||
427 | |||
428 | if (adau1977->switch_mode) | ||
429 | adau1977->switch_mode(adau1977->dev); | ||
430 | |||
431 | ret = adau1977_reset(adau1977); | ||
432 | if (ret) | ||
433 | goto err_disable_dvdd; | ||
434 | |||
435 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER, | ||
436 | ADAU1977_POWER_PWUP, ADAU1977_POWER_PWUP); | ||
437 | if (ret) | ||
438 | goto err_disable_dvdd; | ||
439 | |||
440 | ret = regcache_sync(adau1977->regmap); | ||
441 | if (ret) | ||
442 | goto err_disable_dvdd; | ||
443 | |||
444 | /* | ||
445 | * The PLL register is not affected by the software reset. It is | ||
446 | * possible that the value of the register was changed to the | ||
447 | * default value while we were in cache only mode. In this case | ||
448 | * regcache_sync will skip over it and we have to manually sync | ||
449 | * it. | ||
450 | */ | ||
451 | ret = regmap_read(adau1977->regmap, ADAU1977_REG_PLL, &val); | ||
452 | if (ret) | ||
453 | goto err_disable_dvdd; | ||
454 | |||
455 | if (val == 0x41) { | ||
456 | regcache_cache_bypass(adau1977->regmap, true); | ||
457 | ret = regmap_write(adau1977->regmap, ADAU1977_REG_PLL, | ||
458 | 0x41); | ||
459 | if (ret) | ||
460 | goto err_disable_dvdd; | ||
461 | regcache_cache_bypass(adau1977->regmap, false); | ||
462 | } | ||
463 | |||
464 | adau1977->enabled = true; | ||
465 | |||
466 | return ret; | ||
467 | |||
468 | err_disable_dvdd: | ||
469 | if (adau1977->dvdd_reg) | ||
470 | regulator_disable(adau1977->dvdd_reg); | ||
471 | err_disable_avdd: | ||
472 | regulator_disable(adau1977->avdd_reg); | ||
473 | return ret; | ||
474 | } | ||
475 | |||
476 | static int adau1977_set_bias_level(struct snd_soc_codec *codec, | ||
477 | enum snd_soc_bias_level level) | ||
478 | { | ||
479 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec); | ||
480 | int ret = 0; | ||
481 | |||
482 | switch (level) { | ||
483 | case SND_SOC_BIAS_ON: | ||
484 | break; | ||
485 | case SND_SOC_BIAS_PREPARE: | ||
486 | break; | ||
487 | case SND_SOC_BIAS_STANDBY: | ||
488 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) | ||
489 | ret = adau1977_power_enable(adau1977); | ||
490 | break; | ||
491 | case SND_SOC_BIAS_OFF: | ||
492 | ret = adau1977_power_disable(adau1977); | ||
493 | break; | ||
494 | } | ||
495 | |||
496 | if (ret) | ||
497 | return ret; | ||
498 | |||
499 | codec->dapm.bias_level = level; | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | ||
505 | unsigned int rx_mask, int slots, int width) | ||
506 | { | ||
507 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec); | ||
508 | unsigned int ctrl0, ctrl1, drv; | ||
509 | unsigned int slot[4]; | ||
510 | unsigned int i; | ||
511 | int ret; | ||
512 | |||
513 | if (slots == 0) { | ||
514 | /* 0 = No fixed slot width */ | ||
515 | adau1977->slot_width = 0; | ||
516 | adau1977->max_master_fs = 192000; | ||
517 | return regmap_update_bits(adau1977->regmap, | ||
518 | ADAU1977_REG_SAI_CTRL0, ADAU1977_SAI_CTRL0_SAI_MASK, | ||
519 | ADAU1977_SAI_CTRL0_SAI_I2S); | ||
520 | } | ||
521 | |||
522 | if (rx_mask == 0 || tx_mask != 0) | ||
523 | return -EINVAL; | ||
524 | |||
525 | drv = 0; | ||
526 | for (i = 0; i < 4; i++) { | ||
527 | slot[i] = __ffs(rx_mask); | ||
528 | drv |= ADAU1977_SAI_OVERTEMP_DRV_C(i); | ||
529 | rx_mask &= ~(1 << slot[i]); | ||
530 | if (slot[i] >= slots) | ||
531 | return -EINVAL; | ||
532 | if (rx_mask == 0) | ||
533 | break; | ||
534 | } | ||
535 | |||
536 | if (rx_mask != 0) | ||
537 | return -EINVAL; | ||
538 | |||
539 | switch (width) { | ||
540 | case 16: | ||
541 | ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_16; | ||
542 | break; | ||
543 | case 24: | ||
544 | /* We can only generate 16 bit or 32 bit wide slots */ | ||
545 | if (adau1977->master) | ||
546 | return -EINVAL; | ||
547 | ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_24; | ||
548 | break; | ||
549 | case 32: | ||
550 | ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_32; | ||
551 | break; | ||
552 | default: | ||
553 | return -EINVAL; | ||
554 | } | ||
555 | |||
556 | switch (slots) { | ||
557 | case 2: | ||
558 | ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_2; | ||
559 | break; | ||
560 | case 4: | ||
561 | ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_4; | ||
562 | break; | ||
563 | case 8: | ||
564 | ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_8; | ||
565 | break; | ||
566 | case 16: | ||
567 | ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_16; | ||
568 | break; | ||
569 | default: | ||
570 | return -EINVAL; | ||
571 | } | ||
572 | |||
573 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP, | ||
574 | ADAU1977_SAI_OVERTEMP_DRV_C(0) | | ||
575 | ADAU1977_SAI_OVERTEMP_DRV_C(1) | | ||
576 | ADAU1977_SAI_OVERTEMP_DRV_C(2) | | ||
577 | ADAU1977_SAI_OVERTEMP_DRV_C(3), drv); | ||
578 | if (ret) | ||
579 | return ret; | ||
580 | |||
581 | ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP12, | ||
582 | (slot[1] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) | | ||
583 | (slot[0] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET)); | ||
584 | if (ret) | ||
585 | return ret; | ||
586 | |||
587 | ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP34, | ||
588 | (slot[3] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) | | ||
589 | (slot[2] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET)); | ||
590 | if (ret) | ||
591 | return ret; | ||
592 | |||
593 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0, | ||
594 | ADAU1977_SAI_CTRL0_SAI_MASK, ctrl0); | ||
595 | if (ret) | ||
596 | return ret; | ||
597 | |||
598 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1, | ||
599 | ADAU1977_SAI_CTRL1_SLOT_WIDTH_MASK, ctrl1); | ||
600 | if (ret) | ||
601 | return ret; | ||
602 | |||
603 | adau1977->slot_width = width; | ||
604 | |||
605 | /* In master mode the maximum bitclock is 24.576 MHz */ | ||
606 | adau1977->max_master_fs = min(192000, 24576000 / width / slots); | ||
607 | |||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | static int adau1977_mute(struct snd_soc_dai *dai, int mute, int stream) | ||
612 | { | ||
613 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec); | ||
614 | unsigned int val; | ||
615 | |||
616 | if (mute) | ||
617 | val = ADAU1977_MISC_CONTROL_MMUTE; | ||
618 | else | ||
619 | val = 0; | ||
620 | |||
621 | return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MISC_CONTROL, | ||
622 | ADAU1977_MISC_CONTROL_MMUTE, val); | ||
623 | } | ||
624 | |||
625 | static int adau1977_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
626 | { | ||
627 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec); | ||
628 | unsigned int ctrl0 = 0, ctrl1 = 0, block_power = 0; | ||
629 | bool invert_lrclk; | ||
630 | int ret; | ||
631 | |||
632 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
633 | case SND_SOC_DAIFMT_CBS_CFS: | ||
634 | adau1977->master = false; | ||
635 | break; | ||
636 | case SND_SOC_DAIFMT_CBM_CFM: | ||
637 | ctrl1 |= ADAU1977_SAI_CTRL1_MASTER; | ||
638 | adau1977->master = true; | ||
639 | break; | ||
640 | default: | ||
641 | return -EINVAL; | ||
642 | } | ||
643 | |||
644 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
645 | case SND_SOC_DAIFMT_NB_NF: | ||
646 | invert_lrclk = false; | ||
647 | break; | ||
648 | case SND_SOC_DAIFMT_IB_NF: | ||
649 | block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE; | ||
650 | invert_lrclk = false; | ||
651 | break; | ||
652 | case SND_SOC_DAIFMT_NB_IF: | ||
653 | invert_lrclk = true; | ||
654 | break; | ||
655 | case SND_SOC_DAIFMT_IB_IF: | ||
656 | block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE; | ||
657 | invert_lrclk = true; | ||
658 | break; | ||
659 | default: | ||
660 | return -EINVAL; | ||
661 | } | ||
662 | |||
663 | adau1977->right_j = false; | ||
664 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
665 | case SND_SOC_DAIFMT_I2S: | ||
666 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S; | ||
667 | break; | ||
668 | case SND_SOC_DAIFMT_LEFT_J: | ||
669 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ; | ||
670 | invert_lrclk = !invert_lrclk; | ||
671 | break; | ||
672 | case SND_SOC_DAIFMT_RIGHT_J: | ||
673 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT; | ||
674 | adau1977->right_j = true; | ||
675 | invert_lrclk = !invert_lrclk; | ||
676 | break; | ||
677 | case SND_SOC_DAIFMT_DSP_A: | ||
678 | ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE; | ||
679 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S; | ||
680 | invert_lrclk = false; | ||
681 | break; | ||
682 | case SND_SOC_DAIFMT_DSP_B: | ||
683 | ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE; | ||
684 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ; | ||
685 | invert_lrclk = false; | ||
686 | break; | ||
687 | default: | ||
688 | return -EINVAL; | ||
689 | } | ||
690 | |||
691 | if (invert_lrclk) | ||
692 | block_power |= ADAU1977_BLOCK_POWER_SAI_LR_POL; | ||
693 | |||
694 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI, | ||
695 | ADAU1977_BLOCK_POWER_SAI_LR_POL | | ||
696 | ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE, block_power); | ||
697 | if (ret) | ||
698 | return ret; | ||
699 | |||
700 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0, | ||
701 | ADAU1977_SAI_CTRL0_FMT_MASK, | ||
702 | ctrl0); | ||
703 | if (ret) | ||
704 | return ret; | ||
705 | |||
706 | return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1, | ||
707 | ADAU1977_SAI_CTRL1_MASTER | ADAU1977_SAI_CTRL1_LRCLK_PULSE, | ||
708 | ctrl1); | ||
709 | } | ||
710 | |||
711 | static int adau1977_startup(struct snd_pcm_substream *substream, | ||
712 | struct snd_soc_dai *dai) | ||
713 | { | ||
714 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec); | ||
715 | u64 formats = 0; | ||
716 | |||
717 | if (adau1977->slot_width == 16) | ||
718 | formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE; | ||
719 | else if (adau1977->right_j || adau1977->slot_width == 24) | ||
720 | formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | | ||
721 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE; | ||
722 | |||
723 | snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
724 | SNDRV_PCM_HW_PARAM_RATE, &adau1977->constraints); | ||
725 | |||
726 | if (adau1977->master) | ||
727 | snd_pcm_hw_constraint_minmax(substream->runtime, | ||
728 | SNDRV_PCM_HW_PARAM_RATE, 8000, adau1977->max_master_fs); | ||
729 | |||
730 | if (formats != 0) | ||
731 | snd_pcm_hw_constraint_mask64(substream->runtime, | ||
732 | SNDRV_PCM_HW_PARAM_FORMAT, formats); | ||
733 | |||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | static int adau1977_set_tristate(struct snd_soc_dai *dai, int tristate) | ||
738 | { | ||
739 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec); | ||
740 | unsigned int val; | ||
741 | |||
742 | if (tristate) | ||
743 | val = ADAU1977_SAI_OVERTEMP_DRV_HIZ; | ||
744 | else | ||
745 | val = 0; | ||
746 | |||
747 | return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP, | ||
748 | ADAU1977_SAI_OVERTEMP_DRV_HIZ, val); | ||
749 | } | ||
750 | |||
751 | static const struct snd_soc_dai_ops adau1977_dai_ops = { | ||
752 | .startup = adau1977_startup, | ||
753 | .hw_params = adau1977_hw_params, | ||
754 | .mute_stream = adau1977_mute, | ||
755 | .set_fmt = adau1977_set_dai_fmt, | ||
756 | .set_tdm_slot = adau1977_set_tdm_slot, | ||
757 | .set_tristate = adau1977_set_tristate, | ||
758 | }; | ||
759 | |||
760 | static struct snd_soc_dai_driver adau1977_dai = { | ||
761 | .name = "adau1977-hifi", | ||
762 | .capture = { | ||
763 | .stream_name = "Capture", | ||
764 | .channels_min = 1, | ||
765 | .channels_max = 4, | ||
766 | .rates = SNDRV_PCM_RATE_KNOT, | ||
767 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | | ||
768 | SNDRV_PCM_FMTBIT_S32_LE, | ||
769 | .sig_bits = 24, | ||
770 | }, | ||
771 | .ops = &adau1977_dai_ops, | ||
772 | }; | ||
773 | |||
774 | static const unsigned int adau1977_rates[] = { | ||
775 | 8000, 16000, 32000, 64000, 128000, | ||
776 | 11025, 22050, 44100, 88200, 172400, | ||
777 | 12000, 24000, 48000, 96000, 192000, | ||
778 | }; | ||
779 | |||
780 | #define ADAU1977_RATE_CONSTRAINT_MASK_32000 0x001f | ||
781 | #define ADAU1977_RATE_CONSTRAINT_MASK_44100 0x03e0 | ||
782 | #define ADAU1977_RATE_CONSTRAINT_MASK_48000 0x7c00 | ||
783 | /* All rates >= 32000 */ | ||
784 | #define ADAU1977_RATE_CONSTRAINT_MASK_LRCLK 0x739c | ||
785 | |||
786 | static bool adau1977_check_sysclk(unsigned int mclk, unsigned int base_freq) | ||
787 | { | ||
788 | unsigned int mcs; | ||
789 | |||
790 | if (mclk % (base_freq * 128) != 0) | ||
791 | return false; | ||
792 | |||
793 | mcs = mclk / (128 * base_freq); | ||
794 | if (mcs < 1 || mcs > 6 || mcs == 5) | ||
795 | return false; | ||
796 | |||
797 | return true; | ||
798 | } | ||
799 | |||
800 | static int adau1977_set_sysclk(struct snd_soc_codec *codec, | ||
801 | int clk_id, int source, unsigned int freq, int dir) | ||
802 | { | ||
803 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec); | ||
804 | unsigned int mask = 0; | ||
805 | unsigned int clk_src; | ||
806 | unsigned int ret; | ||
807 | |||
808 | if (dir != SND_SOC_CLOCK_IN) | ||
809 | return -EINVAL; | ||
810 | |||
811 | if (clk_id != ADAU1977_SYSCLK) | ||
812 | return -EINVAL; | ||
813 | |||
814 | switch (source) { | ||
815 | case ADAU1977_SYSCLK_SRC_MCLK: | ||
816 | clk_src = 0; | ||
817 | break; | ||
818 | case ADAU1977_SYSCLK_SRC_LRCLK: | ||
819 | clk_src = ADAU1977_PLL_CLK_S; | ||
820 | break; | ||
821 | default: | ||
822 | return -EINVAL; | ||
823 | } | ||
824 | |||
825 | if (freq != 0 && source == ADAU1977_SYSCLK_SRC_MCLK) { | ||
826 | if (freq < 4000000 || freq > 36864000) | ||
827 | return -EINVAL; | ||
828 | |||
829 | if (adau1977_check_sysclk(freq, 32000)) | ||
830 | mask |= ADAU1977_RATE_CONSTRAINT_MASK_32000; | ||
831 | if (adau1977_check_sysclk(freq, 44100)) | ||
832 | mask |= ADAU1977_RATE_CONSTRAINT_MASK_44100; | ||
833 | if (adau1977_check_sysclk(freq, 48000)) | ||
834 | mask |= ADAU1977_RATE_CONSTRAINT_MASK_48000; | ||
835 | |||
836 | if (mask == 0) | ||
837 | return -EINVAL; | ||
838 | } else if (source == ADAU1977_SYSCLK_SRC_LRCLK) { | ||
839 | mask = ADAU1977_RATE_CONSTRAINT_MASK_LRCLK; | ||
840 | } | ||
841 | |||
842 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL, | ||
843 | ADAU1977_PLL_CLK_S, clk_src); | ||
844 | if (ret) | ||
845 | return ret; | ||
846 | |||
847 | adau1977->constraints.mask = mask; | ||
848 | adau1977->sysclk_src = source; | ||
849 | adau1977->sysclk = freq; | ||
850 | |||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static int adau1977_codec_probe(struct snd_soc_codec *codec) | ||
855 | { | ||
856 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec); | ||
857 | int ret; | ||
858 | |||
859 | switch (adau1977->type) { | ||
860 | case ADAU1977: | ||
861 | ret = snd_soc_dapm_new_controls(&codec->dapm, | ||
862 | adau1977_micbias_dapm_widgets, | ||
863 | ARRAY_SIZE(adau1977_micbias_dapm_widgets)); | ||
864 | if (ret < 0) | ||
865 | return ret; | ||
866 | break; | ||
867 | default: | ||
868 | break; | ||
869 | } | ||
870 | |||
871 | return 0; | ||
872 | } | ||
873 | |||
874 | static struct snd_soc_codec_driver adau1977_codec_driver = { | ||
875 | .probe = adau1977_codec_probe, | ||
876 | .set_bias_level = adau1977_set_bias_level, | ||
877 | .set_sysclk = adau1977_set_sysclk, | ||
878 | .idle_bias_off = true, | ||
879 | |||
880 | .controls = adau1977_snd_controls, | ||
881 | .num_controls = ARRAY_SIZE(adau1977_snd_controls), | ||
882 | .dapm_widgets = adau1977_dapm_widgets, | ||
883 | .num_dapm_widgets = ARRAY_SIZE(adau1977_dapm_widgets), | ||
884 | .dapm_routes = adau1977_dapm_routes, | ||
885 | .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes), | ||
886 | }; | ||
887 | |||
888 | static int adau1977_setup_micbias(struct adau1977 *adau1977) | ||
889 | { | ||
890 | struct adau1977_platform_data *pdata = adau1977->dev->platform_data; | ||
891 | unsigned int micbias; | ||
892 | |||
893 | if (pdata) { | ||
894 | micbias = pdata->micbias; | ||
895 | if (micbias > ADAU1977_MICBIAS_9V0) | ||
896 | return -EINVAL; | ||
897 | |||
898 | } else { | ||
899 | micbias = ADAU1977_MICBIAS_8V5; | ||
900 | } | ||
901 | |||
902 | return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MICBIAS, | ||
903 | ADAU1977_MICBIAS_MB_VOLTS_MASK, | ||
904 | micbias << ADAU1977_MICBIAS_MB_VOLTS_OFFSET); | ||
905 | } | ||
906 | |||
907 | int adau1977_probe(struct device *dev, struct regmap *regmap, | ||
908 | enum adau1977_type type, void (*switch_mode)(struct device *dev)) | ||
909 | { | ||
910 | unsigned int power_off_mask; | ||
911 | struct adau1977 *adau1977; | ||
912 | int ret; | ||
913 | |||
914 | if (IS_ERR(regmap)) | ||
915 | return PTR_ERR(regmap); | ||
916 | |||
917 | adau1977 = devm_kzalloc(dev, sizeof(*adau1977), GFP_KERNEL); | ||
918 | if (adau1977 == NULL) | ||
919 | return -ENOMEM; | ||
920 | |||
921 | adau1977->dev = dev; | ||
922 | adau1977->type = type; | ||
923 | adau1977->regmap = regmap; | ||
924 | adau1977->switch_mode = switch_mode; | ||
925 | adau1977->max_master_fs = 192000; | ||
926 | |||
927 | adau1977->constraints.list = adau1977_rates; | ||
928 | adau1977->constraints.count = ARRAY_SIZE(adau1977_rates); | ||
929 | |||
930 | adau1977->avdd_reg = devm_regulator_get(dev, "AVDD"); | ||
931 | if (IS_ERR(adau1977->avdd_reg)) | ||
932 | return PTR_ERR(adau1977->avdd_reg); | ||
933 | |||
934 | adau1977->dvdd_reg = devm_regulator_get_optional(dev, "DVDD"); | ||
935 | if (IS_ERR(adau1977->dvdd_reg)) { | ||
936 | if (PTR_ERR(adau1977->dvdd_reg) != -ENODEV) | ||
937 | return PTR_ERR(adau1977->dvdd_reg); | ||
938 | adau1977->dvdd_reg = NULL; | ||
939 | } | ||
940 | |||
941 | adau1977->reset_gpio = devm_gpiod_get(dev, "reset"); | ||
942 | if (IS_ERR(adau1977->reset_gpio)) { | ||
943 | ret = PTR_ERR(adau1977->reset_gpio); | ||
944 | if (ret != -ENOENT && ret != -ENOSYS) | ||
945 | return PTR_ERR(adau1977->reset_gpio); | ||
946 | adau1977->reset_gpio = NULL; | ||
947 | } | ||
948 | |||
949 | dev_set_drvdata(dev, adau1977); | ||
950 | |||
951 | if (adau1977->reset_gpio) { | ||
952 | ret = gpiod_direction_output(adau1977->reset_gpio, 0); | ||
953 | if (ret) | ||
954 | return ret; | ||
955 | ndelay(100); | ||
956 | } | ||
957 | |||
958 | ret = adau1977_power_enable(adau1977); | ||
959 | if (ret) | ||
960 | return ret; | ||
961 | |||
962 | if (type == ADAU1977) { | ||
963 | ret = adau1977_setup_micbias(adau1977); | ||
964 | if (ret) | ||
965 | goto err_poweroff; | ||
966 | } | ||
967 | |||
968 | if (adau1977->dvdd_reg) | ||
969 | power_off_mask = ~0; | ||
970 | else | ||
971 | power_off_mask = ~ADAU1977_BLOCK_POWER_SAI_LDO_EN; | ||
972 | |||
973 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI, | ||
974 | power_off_mask, 0x00); | ||
975 | if (ret) | ||
976 | goto err_poweroff; | ||
977 | |||
978 | ret = adau1977_power_disable(adau1977); | ||
979 | if (ret) | ||
980 | return ret; | ||
981 | |||
982 | return snd_soc_register_codec(dev, &adau1977_codec_driver, | ||
983 | &adau1977_dai, 1); | ||
984 | |||
985 | err_poweroff: | ||
986 | adau1977_power_disable(adau1977); | ||
987 | return ret; | ||
988 | |||
989 | } | ||
990 | EXPORT_SYMBOL_GPL(adau1977_probe); | ||
991 | |||
992 | static bool adau1977_register_volatile(struct device *dev, unsigned int reg) | ||
993 | { | ||
994 | switch (reg) { | ||
995 | case ADAU1977_REG_STATUS(0): | ||
996 | case ADAU1977_REG_STATUS(1): | ||
997 | case ADAU1977_REG_STATUS(2): | ||
998 | case ADAU1977_REG_STATUS(3): | ||
999 | case ADAU1977_REG_ADC_CLIP: | ||
1000 | return true; | ||
1001 | } | ||
1002 | |||
1003 | return false; | ||
1004 | } | ||
1005 | |||
1006 | const struct regmap_config adau1977_regmap_config = { | ||
1007 | .max_register = ADAU1977_REG_DC_HPF_CAL, | ||
1008 | .volatile_reg = adau1977_register_volatile, | ||
1009 | |||
1010 | .cache_type = REGCACHE_RBTREE, | ||
1011 | .reg_defaults = adau1977_reg_defaults, | ||
1012 | .num_reg_defaults = ARRAY_SIZE(adau1977_reg_defaults), | ||
1013 | }; | ||
1014 | EXPORT_SYMBOL_GPL(adau1977_regmap_config); | ||
1015 | |||
1016 | MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver"); | ||
1017 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
1018 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/adau1977.h b/sound/soc/codecs/adau1977.h new file mode 100644 index 000000000000..95e714345a86 --- /dev/null +++ b/sound/soc/codecs/adau1977.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * ADAU1977/ADAU1978/ADAU1979 driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
6 | * | ||
7 | * Licensed under the GPL-2. | ||
8 | */ | ||
9 | |||
10 | #ifndef __SOUND_SOC_CODECS_ADAU1977_H__ | ||
11 | #define __SOUND_SOC_CODECS_ADAU1977_H__ | ||
12 | |||
13 | #include <linux/regmap.h> | ||
14 | |||
15 | struct device; | ||
16 | |||
17 | enum adau1977_type { | ||
18 | ADAU1977, | ||
19 | ADAU1978, | ||
20 | ADAU1979, | ||
21 | }; | ||
22 | |||
23 | int adau1977_probe(struct device *dev, struct regmap *regmap, | ||
24 | enum adau1977_type type, void (*switch_mode)(struct device *dev)); | ||
25 | |||
26 | extern const struct regmap_config adau1977_regmap_config; | ||
27 | |||
28 | enum adau1977_clk_id { | ||
29 | ADAU1977_SYSCLK, | ||
30 | }; | ||
31 | |||
32 | enum adau1977_sysclk_src { | ||
33 | ADAU1977_SYSCLK_SRC_MCLK, | ||
34 | ADAU1977_SYSCLK_SRC_LRCLK, | ||
35 | }; | ||
36 | |||
37 | #endif | ||
diff --git a/sound/soc/codecs/adav801.c b/sound/soc/codecs/adav801.c new file mode 100644 index 000000000000..790fce33ab10 --- /dev/null +++ b/sound/soc/codecs/adav801.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * ADAV801 audio driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/spi/spi.h> | ||
11 | #include <linux/regmap.h> | ||
12 | |||
13 | #include <sound/soc.h> | ||
14 | |||
15 | #include "adav80x.h" | ||
16 | |||
17 | static const struct spi_device_id adav80x_spi_id[] = { | ||
18 | { "adav801", 0 }, | ||
19 | { } | ||
20 | }; | ||
21 | MODULE_DEVICE_TABLE(spi, adav80x_spi_id); | ||
22 | |||
23 | static int adav80x_spi_probe(struct spi_device *spi) | ||
24 | { | ||
25 | struct regmap_config config; | ||
26 | |||
27 | config = adav80x_regmap_config; | ||
28 | config.read_flag_mask = 0x01; | ||
29 | |||
30 | return adav80x_bus_probe(&spi->dev, devm_regmap_init_spi(spi, &config)); | ||
31 | } | ||
32 | |||
33 | static int adav80x_spi_remove(struct spi_device *spi) | ||
34 | { | ||
35 | snd_soc_unregister_codec(&spi->dev); | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static struct spi_driver adav80x_spi_driver = { | ||
40 | .driver = { | ||
41 | .name = "adav801", | ||
42 | .owner = THIS_MODULE, | ||
43 | }, | ||
44 | .probe = adav80x_spi_probe, | ||
45 | .remove = adav80x_spi_remove, | ||
46 | .id_table = adav80x_spi_id, | ||
47 | }; | ||
48 | module_spi_driver(adav80x_spi_driver); | ||
49 | |||
50 | MODULE_DESCRIPTION("ASoC ADAV801 driver"); | ||
51 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
52 | MODULE_AUTHOR("Yi Li <yi.li@analog.com>>"); | ||
53 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/adav803.c b/sound/soc/codecs/adav803.c new file mode 100644 index 000000000000..66d9fce34e62 --- /dev/null +++ b/sound/soc/codecs/adav803.c | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * ADAV803 audio driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/regmap.h> | ||
12 | |||
13 | #include <sound/soc.h> | ||
14 | |||
15 | #include "adav80x.h" | ||
16 | |||
17 | static const struct i2c_device_id adav803_id[] = { | ||
18 | { "adav803", 0 }, | ||
19 | { } | ||
20 | }; | ||
21 | MODULE_DEVICE_TABLE(i2c, adav803_id); | ||
22 | |||
23 | static int adav803_probe(struct i2c_client *client, | ||
24 | const struct i2c_device_id *id) | ||
25 | { | ||
26 | return adav80x_bus_probe(&client->dev, | ||
27 | devm_regmap_init_i2c(client, &adav80x_regmap_config)); | ||
28 | } | ||
29 | |||
30 | static int adav803_remove(struct i2c_client *client) | ||
31 | { | ||
32 | snd_soc_unregister_codec(&client->dev); | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static struct i2c_driver adav803_driver = { | ||
37 | .driver = { | ||
38 | .name = "adav803", | ||
39 | .owner = THIS_MODULE, | ||
40 | }, | ||
41 | .probe = adav803_probe, | ||
42 | .remove = adav803_remove, | ||
43 | .id_table = adav803_id, | ||
44 | }; | ||
45 | module_i2c_driver(adav803_driver); | ||
46 | |||
47 | MODULE_DESCRIPTION("ASoC ADAV803 driver"); | ||
48 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
49 | MODULE_AUTHOR("Yi Li <yi.li@analog.com>>"); | ||
50 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index f78b27a7c461..7470831ba756 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c | |||
@@ -8,17 +8,15 @@ | |||
8 | * Licensed under the GPL-2 or later. | 8 | * Licensed under the GPL-2 or later. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | 11 | #include <linux/module.h> |
13 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
14 | #include <linux/i2c.h> | 13 | #include <linux/regmap.h> |
15 | #include <linux/spi/spi.h> | ||
16 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
17 | #include <sound/core.h> | 15 | |
18 | #include <sound/pcm.h> | 16 | #include <sound/pcm.h> |
19 | #include <sound/pcm_params.h> | 17 | #include <sound/pcm_params.h> |
20 | #include <sound/tlv.h> | ||
21 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
19 | #include <sound/tlv.h> | ||
22 | 20 | ||
23 | #include "adav80x.h" | 21 | #include "adav80x.h" |
24 | 22 | ||
@@ -541,6 +539,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec, | |||
541 | unsigned int freq, int dir) | 539 | unsigned int freq, int dir) |
542 | { | 540 | { |
543 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); | 541 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
542 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
544 | 543 | ||
545 | if (dir == SND_SOC_CLOCK_IN) { | 544 | if (dir == SND_SOC_CLOCK_IN) { |
546 | switch (clk_id) { | 545 | switch (clk_id) { |
@@ -573,7 +572,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec, | |||
573 | regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2, | 572 | regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2, |
574 | iclk_ctrl2); | 573 | iclk_ctrl2); |
575 | 574 | ||
576 | snd_soc_dapm_sync(&codec->dapm); | 575 | snd_soc_dapm_sync(dapm); |
577 | } | 576 | } |
578 | } else { | 577 | } else { |
579 | unsigned int mask; | 578 | unsigned int mask; |
@@ -600,17 +599,21 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec, | |||
600 | adav80x->sysclk_pd[clk_id] = false; | 599 | adav80x->sysclk_pd[clk_id] = false; |
601 | } | 600 | } |
602 | 601 | ||
602 | snd_soc_dapm_mutex_lock(dapm); | ||
603 | |||
603 | if (adav80x->sysclk_pd[0]) | 604 | if (adav80x->sysclk_pd[0]) |
604 | snd_soc_dapm_disable_pin(&codec->dapm, "PLL1"); | 605 | snd_soc_dapm_disable_pin_unlocked(dapm, "PLL1"); |
605 | else | 606 | else |
606 | snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); | 607 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL1"); |
607 | 608 | ||
608 | if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2]) | 609 | if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2]) |
609 | snd_soc_dapm_disable_pin(&codec->dapm, "PLL2"); | 610 | snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2"); |
610 | else | 611 | else |
611 | snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2"); | 612 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2"); |
612 | 613 | ||
613 | snd_soc_dapm_sync(&codec->dapm); | 614 | snd_soc_dapm_sync_unlocked(dapm); |
615 | |||
616 | snd_soc_dapm_mutex_unlock(dapm); | ||
614 | } | 617 | } |
615 | 618 | ||
616 | return 0; | 619 | return 0; |
@@ -722,7 +725,7 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream, | |||
722 | struct snd_soc_codec *codec = dai->codec; | 725 | struct snd_soc_codec *codec = dai->codec; |
723 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); | 726 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
724 | 727 | ||
725 | if (!codec->active || !adav80x->rate) | 728 | if (!snd_soc_codec_is_active(codec) || !adav80x->rate) |
726 | return 0; | 729 | return 0; |
727 | 730 | ||
728 | return snd_pcm_hw_constraint_minmax(substream->runtime, | 731 | return snd_pcm_hw_constraint_minmax(substream->runtime, |
@@ -735,7 +738,7 @@ static void adav80x_dai_shutdown(struct snd_pcm_substream *substream, | |||
735 | struct snd_soc_codec *codec = dai->codec; | 738 | struct snd_soc_codec *codec = dai->codec; |
736 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); | 739 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
737 | 740 | ||
738 | if (!codec->active) | 741 | if (!snd_soc_codec_is_active(codec)) |
739 | adav80x->rate = 0; | 742 | adav80x->rate = 0; |
740 | } | 743 | } |
741 | 744 | ||
@@ -864,39 +867,26 @@ static struct snd_soc_codec_driver adav80x_codec_driver = { | |||
864 | .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), | 867 | .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), |
865 | }; | 868 | }; |
866 | 869 | ||
867 | static int adav80x_bus_probe(struct device *dev, struct regmap *regmap) | 870 | int adav80x_bus_probe(struct device *dev, struct regmap *regmap) |
868 | { | 871 | { |
869 | struct adav80x *adav80x; | 872 | struct adav80x *adav80x; |
870 | int ret; | ||
871 | 873 | ||
872 | if (IS_ERR(regmap)) | 874 | if (IS_ERR(regmap)) |
873 | return PTR_ERR(regmap); | 875 | return PTR_ERR(regmap); |
874 | 876 | ||
875 | adav80x = kzalloc(sizeof(*adav80x), GFP_KERNEL); | 877 | adav80x = devm_kzalloc(dev, sizeof(*adav80x), GFP_KERNEL); |
876 | if (!adav80x) | 878 | if (!adav80x) |
877 | return -ENOMEM; | 879 | return -ENOMEM; |
878 | 880 | ||
879 | |||
880 | dev_set_drvdata(dev, adav80x); | 881 | dev_set_drvdata(dev, adav80x); |
881 | adav80x->regmap = regmap; | 882 | adav80x->regmap = regmap; |
882 | 883 | ||
883 | ret = snd_soc_register_codec(dev, &adav80x_codec_driver, | 884 | return snd_soc_register_codec(dev, &adav80x_codec_driver, |
884 | adav80x_dais, ARRAY_SIZE(adav80x_dais)); | 885 | adav80x_dais, ARRAY_SIZE(adav80x_dais)); |
885 | if (ret) | ||
886 | kfree(adav80x); | ||
887 | |||
888 | return ret; | ||
889 | } | 886 | } |
887 | EXPORT_SYMBOL_GPL(adav80x_bus_probe); | ||
890 | 888 | ||
891 | static int adav80x_bus_remove(struct device *dev) | 889 | const struct regmap_config adav80x_regmap_config = { |
892 | { | ||
893 | snd_soc_unregister_codec(dev); | ||
894 | kfree(dev_get_drvdata(dev)); | ||
895 | return 0; | ||
896 | } | ||
897 | |||
898 | #if defined(CONFIG_SPI_MASTER) | ||
899 | static const struct regmap_config adav80x_spi_regmap_config = { | ||
900 | .val_bits = 8, | 890 | .val_bits = 8, |
901 | .pad_bits = 1, | 891 | .pad_bits = 1, |
902 | .reg_bits = 7, | 892 | .reg_bits = 7, |
@@ -908,105 +898,7 @@ static const struct regmap_config adav80x_spi_regmap_config = { | |||
908 | .reg_defaults = adav80x_reg_defaults, | 898 | .reg_defaults = adav80x_reg_defaults, |
909 | .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults), | 899 | .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults), |
910 | }; | 900 | }; |
911 | 901 | EXPORT_SYMBOL_GPL(adav80x_regmap_config); | |
912 | static const struct spi_device_id adav80x_spi_id[] = { | ||
913 | { "adav801", 0 }, | ||
914 | { } | ||
915 | }; | ||
916 | MODULE_DEVICE_TABLE(spi, adav80x_spi_id); | ||
917 | |||
918 | static int adav80x_spi_probe(struct spi_device *spi) | ||
919 | { | ||
920 | return adav80x_bus_probe(&spi->dev, | ||
921 | devm_regmap_init_spi(spi, &adav80x_spi_regmap_config)); | ||
922 | } | ||
923 | |||
924 | static int adav80x_spi_remove(struct spi_device *spi) | ||
925 | { | ||
926 | return adav80x_bus_remove(&spi->dev); | ||
927 | } | ||
928 | |||
929 | static struct spi_driver adav80x_spi_driver = { | ||
930 | .driver = { | ||
931 | .name = "adav801", | ||
932 | .owner = THIS_MODULE, | ||
933 | }, | ||
934 | .probe = adav80x_spi_probe, | ||
935 | .remove = adav80x_spi_remove, | ||
936 | .id_table = adav80x_spi_id, | ||
937 | }; | ||
938 | #endif | ||
939 | |||
940 | #if IS_ENABLED(CONFIG_I2C) | ||
941 | static const struct regmap_config adav80x_i2c_regmap_config = { | ||
942 | .val_bits = 8, | ||
943 | .pad_bits = 1, | ||
944 | .reg_bits = 7, | ||
945 | |||
946 | .max_register = ADAV80X_PLL_OUTE, | ||
947 | |||
948 | .cache_type = REGCACHE_RBTREE, | ||
949 | .reg_defaults = adav80x_reg_defaults, | ||
950 | .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults), | ||
951 | }; | ||
952 | |||
953 | static const struct i2c_device_id adav80x_i2c_id[] = { | ||
954 | { "adav803", 0 }, | ||
955 | { } | ||
956 | }; | ||
957 | MODULE_DEVICE_TABLE(i2c, adav80x_i2c_id); | ||
958 | |||
959 | static int adav80x_i2c_probe(struct i2c_client *client, | ||
960 | const struct i2c_device_id *id) | ||
961 | { | ||
962 | return adav80x_bus_probe(&client->dev, | ||
963 | devm_regmap_init_i2c(client, &adav80x_i2c_regmap_config)); | ||
964 | } | ||
965 | |||
966 | static int adav80x_i2c_remove(struct i2c_client *client) | ||
967 | { | ||
968 | return adav80x_bus_remove(&client->dev); | ||
969 | } | ||
970 | |||
971 | static struct i2c_driver adav80x_i2c_driver = { | ||
972 | .driver = { | ||
973 | .name = "adav803", | ||
974 | .owner = THIS_MODULE, | ||
975 | }, | ||
976 | .probe = adav80x_i2c_probe, | ||
977 | .remove = adav80x_i2c_remove, | ||
978 | .id_table = adav80x_i2c_id, | ||
979 | }; | ||
980 | #endif | ||
981 | |||
982 | static int __init adav80x_init(void) | ||
983 | { | ||
984 | int ret = 0; | ||
985 | |||
986 | #if IS_ENABLED(CONFIG_I2C) | ||
987 | ret = i2c_add_driver(&adav80x_i2c_driver); | ||
988 | if (ret) | ||
989 | return ret; | ||
990 | #endif | ||
991 | |||
992 | #if defined(CONFIG_SPI_MASTER) | ||
993 | ret = spi_register_driver(&adav80x_spi_driver); | ||
994 | #endif | ||
995 | |||
996 | return ret; | ||
997 | } | ||
998 | module_init(adav80x_init); | ||
999 | |||
1000 | static void __exit adav80x_exit(void) | ||
1001 | { | ||
1002 | #if IS_ENABLED(CONFIG_I2C) | ||
1003 | i2c_del_driver(&adav80x_i2c_driver); | ||
1004 | #endif | ||
1005 | #if defined(CONFIG_SPI_MASTER) | ||
1006 | spi_unregister_driver(&adav80x_spi_driver); | ||
1007 | #endif | ||
1008 | } | ||
1009 | module_exit(adav80x_exit); | ||
1010 | 902 | ||
1011 | MODULE_DESCRIPTION("ASoC ADAV80x driver"); | 903 | MODULE_DESCRIPTION("ASoC ADAV80x driver"); |
1012 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | 904 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); |
diff --git a/sound/soc/codecs/adav80x.h b/sound/soc/codecs/adav80x.h index adb0fc76d4e3..8a1d7c09dca5 100644 --- a/sound/soc/codecs/adav80x.h +++ b/sound/soc/codecs/adav80x.h | |||
@@ -9,6 +9,13 @@ | |||
9 | #ifndef _ADAV80X_H | 9 | #ifndef _ADAV80X_H |
10 | #define _ADAV80X_H | 10 | #define _ADAV80X_H |
11 | 11 | ||
12 | #include <linux/regmap.h> | ||
13 | |||
14 | struct device; | ||
15 | |||
16 | extern const struct regmap_config adav80x_regmap_config; | ||
17 | int adav80x_bus_probe(struct device *dev, struct regmap *regmap); | ||
18 | |||
12 | enum adav80x_pll_src { | 19 | enum adav80x_pll_src { |
13 | ADAV80X_PLL_SRC_XIN, | 20 | ADAV80X_PLL_SRC_XIN, |
14 | ADAV80X_PLL_SRC_XTAL, | 21 | ADAV80X_PLL_SRC_XTAL, |
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index b4819dcd4f4d..10adf25d4c14 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c | |||
@@ -174,8 +174,6 @@ static int ak4104_probe(struct snd_soc_codec *codec) | |||
174 | struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); | 174 | struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); |
175 | int ret; | 175 | int ret; |
176 | 176 | ||
177 | codec->control_data = ak4104->regmap; | ||
178 | |||
179 | /* set power-up and non-reset bits */ | 177 | /* set power-up and non-reset bits */ |
180 | ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, | 178 | ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, |
181 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, | 179 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, |
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 94cbe508dd37..684b56f2856a 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c | |||
@@ -113,14 +113,14 @@ static const DECLARE_TLV_DB_SCALE(alc_tlv, -800, 50, 0); | |||
113 | static const DECLARE_TLV_DB_SCALE(aux_in_tlv, -2100, 300, 0); | 113 | static const DECLARE_TLV_DB_SCALE(aux_in_tlv, -2100, 300, 0); |
114 | 114 | ||
115 | 115 | ||
116 | static const struct soc_enum ak4641_mono_out_enum = | 116 | static SOC_ENUM_SINGLE_DECL(ak4641_mono_out_enum, |
117 | SOC_ENUM_SINGLE(AK4641_SIG1, 6, 2, ak4641_mono_out); | 117 | AK4641_SIG1, 6, ak4641_mono_out); |
118 | static const struct soc_enum ak4641_hp_out_enum = | 118 | static SOC_ENUM_SINGLE_DECL(ak4641_hp_out_enum, |
119 | SOC_ENUM_SINGLE(AK4641_MODE2, 2, 2, ak4641_hp_out); | 119 | AK4641_MODE2, 2, ak4641_hp_out); |
120 | static const struct soc_enum ak4641_mic_select_enum = | 120 | static SOC_ENUM_SINGLE_DECL(ak4641_mic_select_enum, |
121 | SOC_ENUM_SINGLE(AK4641_MIC, 1, 2, ak4641_mic_select); | 121 | AK4641_MIC, 1, ak4641_mic_select); |
122 | static const struct soc_enum ak4641_mic_or_dac_enum = | 122 | static SOC_ENUM_SINGLE_DECL(ak4641_mic_or_dac_enum, |
123 | SOC_ENUM_SINGLE(AK4641_BTIF, 4, 2, ak4641_mic_or_dac); | 123 | AK4641_BTIF, 4, ak4641_mic_or_dac); |
124 | 124 | ||
125 | static const struct snd_kcontrol_new ak4641_snd_controls[] = { | 125 | static const struct snd_kcontrol_new ak4641_snd_controls[] = { |
126 | SOC_ENUM("Mono 1 Output", ak4641_mono_out_enum), | 126 | SOC_ENUM("Mono 1 Output", ak4641_mono_out_enum), |
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 25bdf6ad4a54..deb2b44669de 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/i2c.h> | 16 | #include <linux/i2c.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/regmap.h> | ||
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
19 | #include <sound/soc.h> | 20 | #include <sound/soc.h> |
20 | #include <sound/initval.h> | 21 | #include <sound/initval.h> |
@@ -23,104 +24,99 @@ | |||
23 | #include "ak4671.h" | 24 | #include "ak4671.h" |
24 | 25 | ||
25 | 26 | ||
26 | /* codec private data */ | ||
27 | struct ak4671_priv { | ||
28 | enum snd_soc_control_type control_type; | ||
29 | }; | ||
30 | |||
31 | /* ak4671 register cache & default register settings */ | 27 | /* ak4671 register cache & default register settings */ |
32 | static const u8 ak4671_reg[AK4671_CACHEREGNUM] = { | 28 | static const struct reg_default ak4671_reg_defaults[] = { |
33 | 0x00, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */ | 29 | { 0x00, 0x00 }, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */ |
34 | 0xf6, /* AK4671_PLL_MODE_SELECT0 (0x01) */ | 30 | { 0x01, 0xf6 }, /* AK4671_PLL_MODE_SELECT0 (0x01) */ |
35 | 0x00, /* AK4671_PLL_MODE_SELECT1 (0x02) */ | 31 | { 0x02, 0x00 }, /* AK4671_PLL_MODE_SELECT1 (0x02) */ |
36 | 0x02, /* AK4671_FORMAT_SELECT (0x03) */ | 32 | { 0x03, 0x02 }, /* AK4671_FORMAT_SELECT (0x03) */ |
37 | 0x00, /* AK4671_MIC_SIGNAL_SELECT (0x04) */ | 33 | { 0x04, 0x00 }, /* AK4671_MIC_SIGNAL_SELECT (0x04) */ |
38 | 0x55, /* AK4671_MIC_AMP_GAIN (0x05) */ | 34 | { 0x05, 0x55 }, /* AK4671_MIC_AMP_GAIN (0x05) */ |
39 | 0x00, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */ | 35 | { 0x06, 0x00 }, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */ |
40 | 0x00, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */ | 36 | { 0x07, 0x00 }, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */ |
41 | 0xb5, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */ | 37 | { 0x08, 0xb5 }, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */ |
42 | 0x00, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */ | 38 | { 0x09, 0x00 }, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */ |
43 | 0x00, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */ | 39 | { 0x0a, 0x00 }, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */ |
44 | 0x00, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */ | 40 | { 0x0b, 0x00 }, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */ |
45 | 0x00, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */ | 41 | { 0x0c, 0x00 }, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */ |
46 | 0x00, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */ | 42 | { 0x0d, 0x00 }, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */ |
47 | 0x00, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */ | 43 | { 0x0e, 0x00 }, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */ |
48 | 0x00, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */ | 44 | { 0x0f, 0x00 }, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */ |
49 | 0x00, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */ | 45 | { 0x10, 0x00 }, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */ |
50 | 0x80, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */ | 46 | { 0x11, 0x80 }, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */ |
51 | 0x91, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */ | 47 | { 0x12, 0x91 }, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */ |
52 | 0x91, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */ | 48 | { 0x13, 0x91 }, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */ |
53 | 0xe1, /* AK4671_ALC_REFERENCE_SELECT (0x14) */ | 49 | { 0x14, 0xe1 }, /* AK4671_ALC_REFERENCE_SELECT (0x14) */ |
54 | 0x00, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */ | 50 | { 0x15, 0x00 }, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */ |
55 | 0x00, /* AK4671_ALC_TIMER_SELECT (0x16) */ | 51 | { 0x16, 0x00 }, /* AK4671_ALC_TIMER_SELECT (0x16) */ |
56 | 0x00, /* AK4671_ALC_MODE_CONTROL (0x17) */ | 52 | { 0x17, 0x00 }, /* AK4671_ALC_MODE_CONTROL (0x17) */ |
57 | 0x02, /* AK4671_MODE_CONTROL1 (0x18) */ | 53 | { 0x18, 0x02 }, /* AK4671_MODE_CONTROL1 (0x18) */ |
58 | 0x01, /* AK4671_MODE_CONTROL2 (0x19) */ | 54 | { 0x19, 0x01 }, /* AK4671_MODE_CONTROL2 (0x19) */ |
59 | 0x18, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */ | 55 | { 0x1a, 0x18 }, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */ |
60 | 0x18, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */ | 56 | { 0x1b, 0x18 }, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */ |
61 | 0x00, /* AK4671_SIDETONE_A_CONTROL (0x1c) */ | 57 | { 0x1c, 0x00 }, /* AK4671_SIDETONE_A_CONTROL (0x1c) */ |
62 | 0x02, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */ | 58 | { 0x1d, 0x02 }, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */ |
63 | 0x00, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */ | 59 | { 0x1e, 0x00 }, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */ |
64 | 0x00, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */ | 60 | { 0x1f, 0x00 }, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */ |
65 | 0x00, /* AK4671_FIL3_COEFFICIENT2 (0x20) */ | 61 | { 0x20, 0x00 }, /* AK4671_FIL3_COEFFICIENT2 (0x20) */ |
66 | 0x00, /* AK4671_FIL3_COEFFICIENT3 (0x21) */ | 62 | { 0x21, 0x00 }, /* AK4671_FIL3_COEFFICIENT3 (0x21) */ |
67 | 0x00, /* AK4671_EQ_COEFFICIENT0 (0x22) */ | 63 | { 0x22, 0x00 }, /* AK4671_EQ_COEFFICIENT0 (0x22) */ |
68 | 0x00, /* AK4671_EQ_COEFFICIENT1 (0x23) */ | 64 | { 0x23, 0x00 }, /* AK4671_EQ_COEFFICIENT1 (0x23) */ |
69 | 0x00, /* AK4671_EQ_COEFFICIENT2 (0x24) */ | 65 | { 0x24, 0x00 }, /* AK4671_EQ_COEFFICIENT2 (0x24) */ |
70 | 0x00, /* AK4671_EQ_COEFFICIENT3 (0x25) */ | 66 | { 0x25, 0x00 }, /* AK4671_EQ_COEFFICIENT3 (0x25) */ |
71 | 0x00, /* AK4671_EQ_COEFFICIENT4 (0x26) */ | 67 | { 0x26, 0x00 }, /* AK4671_EQ_COEFFICIENT4 (0x26) */ |
72 | 0x00, /* AK4671_EQ_COEFFICIENT5 (0x27) */ | 68 | { 0x27, 0x00 }, /* AK4671_EQ_COEFFICIENT5 (0x27) */ |
73 | 0xa9, /* AK4671_FIL1_COEFFICIENT0 (0x28) */ | 69 | { 0x28, 0xa9 }, /* AK4671_FIL1_COEFFICIENT0 (0x28) */ |
74 | 0x1f, /* AK4671_FIL1_COEFFICIENT1 (0x29) */ | 70 | { 0x29, 0x1f }, /* AK4671_FIL1_COEFFICIENT1 (0x29) */ |
75 | 0xad, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */ | 71 | { 0x2a, 0xad }, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */ |
76 | 0x20, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */ | 72 | { 0x2b, 0x20 }, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */ |
77 | 0x00, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */ | 73 | { 0x2c, 0x00 }, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */ |
78 | 0x00, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */ | 74 | { 0x2d, 0x00 }, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */ |
79 | 0x00, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */ | 75 | { 0x2e, 0x00 }, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */ |
80 | 0x00, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */ | 76 | { 0x2f, 0x00 }, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */ |
81 | 0x00, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */ | 77 | { 0x30, 0x00 }, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */ |
82 | 0x00, /* this register not used */ | 78 | |
83 | 0x00, /* AK4671_E1_COEFFICIENT0 (0x32) */ | 79 | { 0x32, 0x00 }, /* AK4671_E1_COEFFICIENT0 (0x32) */ |
84 | 0x00, /* AK4671_E1_COEFFICIENT1 (0x33) */ | 80 | { 0x33, 0x00 }, /* AK4671_E1_COEFFICIENT1 (0x33) */ |
85 | 0x00, /* AK4671_E1_COEFFICIENT2 (0x34) */ | 81 | { 0x34, 0x00 }, /* AK4671_E1_COEFFICIENT2 (0x34) */ |
86 | 0x00, /* AK4671_E1_COEFFICIENT3 (0x35) */ | 82 | { 0x35, 0x00 }, /* AK4671_E1_COEFFICIENT3 (0x35) */ |
87 | 0x00, /* AK4671_E1_COEFFICIENT4 (0x36) */ | 83 | { 0x36, 0x00 }, /* AK4671_E1_COEFFICIENT4 (0x36) */ |
88 | 0x00, /* AK4671_E1_COEFFICIENT5 (0x37) */ | 84 | { 0x37, 0x00 }, /* AK4671_E1_COEFFICIENT5 (0x37) */ |
89 | 0x00, /* AK4671_E2_COEFFICIENT0 (0x38) */ | 85 | { 0x38, 0x00 }, /* AK4671_E2_COEFFICIENT0 (0x38) */ |
90 | 0x00, /* AK4671_E2_COEFFICIENT1 (0x39) */ | 86 | { 0x39, 0x00 }, /* AK4671_E2_COEFFICIENT1 (0x39) */ |
91 | 0x00, /* AK4671_E2_COEFFICIENT2 (0x3a) */ | 87 | { 0x3a, 0x00 }, /* AK4671_E2_COEFFICIENT2 (0x3a) */ |
92 | 0x00, /* AK4671_E2_COEFFICIENT3 (0x3b) */ | 88 | { 0x3b, 0x00 }, /* AK4671_E2_COEFFICIENT3 (0x3b) */ |
93 | 0x00, /* AK4671_E2_COEFFICIENT4 (0x3c) */ | 89 | { 0x3c, 0x00 }, /* AK4671_E2_COEFFICIENT4 (0x3c) */ |
94 | 0x00, /* AK4671_E2_COEFFICIENT5 (0x3d) */ | 90 | { 0x3d, 0x00 }, /* AK4671_E2_COEFFICIENT5 (0x3d) */ |
95 | 0x00, /* AK4671_E3_COEFFICIENT0 (0x3e) */ | 91 | { 0x3e, 0x00 }, /* AK4671_E3_COEFFICIENT0 (0x3e) */ |
96 | 0x00, /* AK4671_E3_COEFFICIENT1 (0x3f) */ | 92 | { 0x3f, 0x00 }, /* AK4671_E3_COEFFICIENT1 (0x3f) */ |
97 | 0x00, /* AK4671_E3_COEFFICIENT2 (0x40) */ | 93 | { 0x40, 0x00 }, /* AK4671_E3_COEFFICIENT2 (0x40) */ |
98 | 0x00, /* AK4671_E3_COEFFICIENT3 (0x41) */ | 94 | { 0x41, 0x00 }, /* AK4671_E3_COEFFICIENT3 (0x41) */ |
99 | 0x00, /* AK4671_E3_COEFFICIENT4 (0x42) */ | 95 | { 0x42, 0x00 }, /* AK4671_E3_COEFFICIENT4 (0x42) */ |
100 | 0x00, /* AK4671_E3_COEFFICIENT5 (0x43) */ | 96 | { 0x43, 0x00 }, /* AK4671_E3_COEFFICIENT5 (0x43) */ |
101 | 0x00, /* AK4671_E4_COEFFICIENT0 (0x44) */ | 97 | { 0x44, 0x00 }, /* AK4671_E4_COEFFICIENT0 (0x44) */ |
102 | 0x00, /* AK4671_E4_COEFFICIENT1 (0x45) */ | 98 | { 0x45, 0x00 }, /* AK4671_E4_COEFFICIENT1 (0x45) */ |
103 | 0x00, /* AK4671_E4_COEFFICIENT2 (0x46) */ | 99 | { 0x46, 0x00 }, /* AK4671_E4_COEFFICIENT2 (0x46) */ |
104 | 0x00, /* AK4671_E4_COEFFICIENT3 (0x47) */ | 100 | { 0x47, 0x00 }, /* AK4671_E4_COEFFICIENT3 (0x47) */ |
105 | 0x00, /* AK4671_E4_COEFFICIENT4 (0x48) */ | 101 | { 0x48, 0x00 }, /* AK4671_E4_COEFFICIENT4 (0x48) */ |
106 | 0x00, /* AK4671_E4_COEFFICIENT5 (0x49) */ | 102 | { 0x49, 0x00 }, /* AK4671_E4_COEFFICIENT5 (0x49) */ |
107 | 0x00, /* AK4671_E5_COEFFICIENT0 (0x4a) */ | 103 | { 0x4a, 0x00 }, /* AK4671_E5_COEFFICIENT0 (0x4a) */ |
108 | 0x00, /* AK4671_E5_COEFFICIENT1 (0x4b) */ | 104 | { 0x4b, 0x00 }, /* AK4671_E5_COEFFICIENT1 (0x4b) */ |
109 | 0x00, /* AK4671_E5_COEFFICIENT2 (0x4c) */ | 105 | { 0x4c, 0x00 }, /* AK4671_E5_COEFFICIENT2 (0x4c) */ |
110 | 0x00, /* AK4671_E5_COEFFICIENT3 (0x4d) */ | 106 | { 0x4d, 0x00 }, /* AK4671_E5_COEFFICIENT3 (0x4d) */ |
111 | 0x00, /* AK4671_E5_COEFFICIENT4 (0x4e) */ | 107 | { 0x4e, 0x00 }, /* AK4671_E5_COEFFICIENT4 (0x4e) */ |
112 | 0x00, /* AK4671_E5_COEFFICIENT5 (0x4f) */ | 108 | { 0x4f, 0x00 }, /* AK4671_E5_COEFFICIENT5 (0x4f) */ |
113 | 0x88, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */ | 109 | { 0x50, 0x88 }, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */ |
114 | 0x88, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */ | 110 | { 0x51, 0x88 }, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */ |
115 | 0x08, /* AK4671_EQ_CONTRO_10KHZ (0x52) */ | 111 | { 0x52, 0x08 }, /* AK4671_EQ_CONTRO_10KHZ (0x52) */ |
116 | 0x00, /* AK4671_PCM_IF_CONTROL0 (0x53) */ | 112 | { 0x53, 0x00 }, /* AK4671_PCM_IF_CONTROL0 (0x53) */ |
117 | 0x00, /* AK4671_PCM_IF_CONTROL1 (0x54) */ | 113 | { 0x54, 0x00 }, /* AK4671_PCM_IF_CONTROL1 (0x54) */ |
118 | 0x00, /* AK4671_PCM_IF_CONTROL2 (0x55) */ | 114 | { 0x55, 0x00 }, /* AK4671_PCM_IF_CONTROL2 (0x55) */ |
119 | 0x18, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */ | 115 | { 0x56, 0x18 }, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */ |
120 | 0x18, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */ | 116 | { 0x57, 0x18 }, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */ |
121 | 0x00, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */ | 117 | { 0x58, 0x00 }, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */ |
122 | 0x00, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */ | 118 | { 0x59, 0x00 }, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */ |
123 | 0x00, /* AK4671_SAR_ADC_CONTROL (0x5a) */ | 119 | { 0x5a, 0x00 }, /* AK4671_SAR_ADC_CONTROL (0x5a) */ |
124 | }; | 120 | }; |
125 | 121 | ||
126 | /* | 122 | /* |
@@ -241,19 +237,17 @@ static const struct snd_kcontrol_new ak4671_rout3_mixer_controls[] = { | |||
241 | /* Input MUXs */ | 237 | /* Input MUXs */ |
242 | static const char *ak4671_lin_mux_texts[] = | 238 | static const char *ak4671_lin_mux_texts[] = |
243 | {"LIN1", "LIN2", "LIN3", "LIN4"}; | 239 | {"LIN1", "LIN2", "LIN3", "LIN4"}; |
244 | static const struct soc_enum ak4671_lin_mux_enum = | 240 | static SOC_ENUM_SINGLE_DECL(ak4671_lin_mux_enum, |
245 | SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 0, | 241 | AK4671_MIC_SIGNAL_SELECT, 0, |
246 | ARRAY_SIZE(ak4671_lin_mux_texts), | 242 | ak4671_lin_mux_texts); |
247 | ak4671_lin_mux_texts); | ||
248 | static const struct snd_kcontrol_new ak4671_lin_mux_control = | 243 | static const struct snd_kcontrol_new ak4671_lin_mux_control = |
249 | SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum); | 244 | SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum); |
250 | 245 | ||
251 | static const char *ak4671_rin_mux_texts[] = | 246 | static const char *ak4671_rin_mux_texts[] = |
252 | {"RIN1", "RIN2", "RIN3", "RIN4"}; | 247 | {"RIN1", "RIN2", "RIN3", "RIN4"}; |
253 | static const struct soc_enum ak4671_rin_mux_enum = | 248 | static SOC_ENUM_SINGLE_DECL(ak4671_rin_mux_enum, |
254 | SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 2, | 249 | AK4671_MIC_SIGNAL_SELECT, 2, |
255 | ARRAY_SIZE(ak4671_rin_mux_texts), | 250 | ak4671_rin_mux_texts); |
256 | ak4671_rin_mux_texts); | ||
257 | static const struct snd_kcontrol_new ak4671_rin_mux_control = | 251 | static const struct snd_kcontrol_new ak4671_rin_mux_control = |
258 | SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum); | 252 | SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum); |
259 | 253 | ||
@@ -619,18 +613,14 @@ static struct snd_soc_dai_driver ak4671_dai = { | |||
619 | 613 | ||
620 | static int ak4671_probe(struct snd_soc_codec *codec) | 614 | static int ak4671_probe(struct snd_soc_codec *codec) |
621 | { | 615 | { |
622 | struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec); | ||
623 | int ret; | 616 | int ret; |
624 | 617 | ||
625 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type); | 618 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); |
626 | if (ret < 0) { | 619 | if (ret < 0) { |
627 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 620 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
628 | return ret; | 621 | return ret; |
629 | } | 622 | } |
630 | 623 | ||
631 | snd_soc_add_codec_controls(codec, ak4671_snd_controls, | ||
632 | ARRAY_SIZE(ak4671_snd_controls)); | ||
633 | |||
634 | ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 624 | ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
635 | 625 | ||
636 | return ret; | 626 | return ret; |
@@ -646,28 +636,36 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { | |||
646 | .probe = ak4671_probe, | 636 | .probe = ak4671_probe, |
647 | .remove = ak4671_remove, | 637 | .remove = ak4671_remove, |
648 | .set_bias_level = ak4671_set_bias_level, | 638 | .set_bias_level = ak4671_set_bias_level, |
649 | .reg_cache_size = AK4671_CACHEREGNUM, | 639 | .controls = ak4671_snd_controls, |
650 | .reg_word_size = sizeof(u8), | 640 | .num_controls = ARRAY_SIZE(ak4671_snd_controls), |
651 | .reg_cache_default = ak4671_reg, | ||
652 | .dapm_widgets = ak4671_dapm_widgets, | 641 | .dapm_widgets = ak4671_dapm_widgets, |
653 | .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets), | 642 | .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets), |
654 | .dapm_routes = ak4671_intercon, | 643 | .dapm_routes = ak4671_intercon, |
655 | .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), | 644 | .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), |
656 | }; | 645 | }; |
657 | 646 | ||
647 | static const struct regmap_config ak4671_regmap = { | ||
648 | .reg_bits = 8, | ||
649 | .val_bits = 8, | ||
650 | |||
651 | .max_register = AK4671_SAR_ADC_CONTROL, | ||
652 | .reg_defaults = ak4671_reg_defaults, | ||
653 | .num_reg_defaults = ARRAY_SIZE(ak4671_reg_defaults), | ||
654 | .cache_type = REGCACHE_RBTREE, | ||
655 | }; | ||
656 | |||
658 | static int ak4671_i2c_probe(struct i2c_client *client, | 657 | static int ak4671_i2c_probe(struct i2c_client *client, |
659 | const struct i2c_device_id *id) | 658 | const struct i2c_device_id *id) |
660 | { | 659 | { |
661 | struct ak4671_priv *ak4671; | 660 | struct regmap *regmap; |
662 | int ret; | 661 | int ret; |
663 | 662 | ||
664 | ak4671 = devm_kzalloc(&client->dev, sizeof(struct ak4671_priv), | 663 | regmap = devm_regmap_init_i2c(client, &ak4671_regmap); |
665 | GFP_KERNEL); | 664 | if (IS_ERR(regmap)) { |
666 | if (ak4671 == NULL) | 665 | ret = PTR_ERR(regmap); |
667 | return -ENOMEM; | 666 | dev_err(&client->dev, "Failed to create regmap: %d\n", ret); |
668 | 667 | return ret; | |
669 | i2c_set_clientdata(client, ak4671); | 668 | } |
670 | ak4671->control_type = SND_SOC_I2C; | ||
671 | 669 | ||
672 | ret = snd_soc_register_codec(&client->dev, | 670 | ret = snd_soc_register_codec(&client->dev, |
673 | &soc_codec_dev_ak4671, &ak4671_dai, 1); | 671 | &soc_codec_dev_ak4671, &ak4671_dai, 1); |
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h index 61cb7ab7552c..394a34d3f50a 100644 --- a/sound/soc/codecs/ak4671.h +++ b/sound/soc/codecs/ak4671.h | |||
@@ -105,8 +105,6 @@ | |||
105 | #define AK4671_DIGITAL_MIXING_CONTROL2 0x59 | 105 | #define AK4671_DIGITAL_MIXING_CONTROL2 0x59 |
106 | #define AK4671_SAR_ADC_CONTROL 0x5a | 106 | #define AK4671_SAR_ADC_CONTROL 0x5a |
107 | 107 | ||
108 | #define AK4671_CACHEREGNUM (AK4671_SAR_ADC_CONTROL + 1) | ||
109 | |||
110 | /* Bitfield Definitions */ | 108 | /* Bitfield Definitions */ |
111 | 109 | ||
112 | /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */ | 110 | /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */ |
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index d3036283482a..ed506253a914 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/pm.h> | 22 | #include <linux/pm.h> |
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include <linux/regmap.h> | ||
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
25 | #include <sound/core.h> | 26 | #include <sound/core.h> |
26 | #include <sound/pcm.h> | 27 | #include <sound/pcm.h> |
@@ -38,26 +39,13 @@ MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)"); | |||
38 | 39 | ||
39 | /* codec private data */ | 40 | /* codec private data */ |
40 | struct alc5623_priv { | 41 | struct alc5623_priv { |
41 | enum snd_soc_control_type control_type; | 42 | struct regmap *regmap; |
42 | u8 id; | 43 | u8 id; |
43 | unsigned int sysclk; | 44 | unsigned int sysclk; |
44 | u16 reg_cache[ALC5623_VENDOR_ID2+2]; | ||
45 | unsigned int add_ctrl; | 45 | unsigned int add_ctrl; |
46 | unsigned int jack_det_ctrl; | 46 | unsigned int jack_det_ctrl; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static void alc5623_fill_cache(struct snd_soc_codec *codec) | ||
50 | { | ||
51 | int i, step = codec->driver->reg_cache_step; | ||
52 | u16 *cache = codec->reg_cache; | ||
53 | |||
54 | /* not really efficient ... */ | ||
55 | codec->cache_bypass = 1; | ||
56 | for (i = 0 ; i < codec->driver->reg_cache_size ; i += step) | ||
57 | cache[i] = snd_soc_read(codec, i); | ||
58 | codec->cache_bypass = 0; | ||
59 | } | ||
60 | |||
61 | static inline int alc5623_reset(struct snd_soc_codec *codec) | 49 | static inline int alc5623_reset(struct snd_soc_codec *codec) |
62 | { | 50 | { |
63 | return snd_soc_write(codec, ALC5623_RESET, 0); | 51 | return snd_soc_write(codec, ALC5623_RESET, 0); |
@@ -228,32 +216,37 @@ static const char *alc5623_aux_out_input_sel[] = { | |||
228 | "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; | 216 | "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; |
229 | 217 | ||
230 | /* auxout output mux */ | 218 | /* auxout output mux */ |
231 | static const struct soc_enum alc5623_aux_out_input_enum = | 219 | static SOC_ENUM_SINGLE_DECL(alc5623_aux_out_input_enum, |
232 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 6, 4, alc5623_aux_out_input_sel); | 220 | ALC5623_OUTPUT_MIXER_CTRL, 6, |
221 | alc5623_aux_out_input_sel); | ||
233 | static const struct snd_kcontrol_new alc5623_auxout_mux_controls = | 222 | static const struct snd_kcontrol_new alc5623_auxout_mux_controls = |
234 | SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum); | 223 | SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum); |
235 | 224 | ||
236 | /* speaker output mux */ | 225 | /* speaker output mux */ |
237 | static const struct soc_enum alc5623_spkout_input_enum = | 226 | static SOC_ENUM_SINGLE_DECL(alc5623_spkout_input_enum, |
238 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel); | 227 | ALC5623_OUTPUT_MIXER_CTRL, 10, |
228 | alc5623_spkout_input_sel); | ||
239 | static const struct snd_kcontrol_new alc5623_spkout_mux_controls = | 229 | static const struct snd_kcontrol_new alc5623_spkout_mux_controls = |
240 | SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum); | 230 | SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum); |
241 | 231 | ||
242 | /* headphone left output mux */ | 232 | /* headphone left output mux */ |
243 | static const struct soc_enum alc5623_hpl_out_input_enum = | 233 | static SOC_ENUM_SINGLE_DECL(alc5623_hpl_out_input_enum, |
244 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 9, 2, alc5623_hpl_out_input_sel); | 234 | ALC5623_OUTPUT_MIXER_CTRL, 9, |
235 | alc5623_hpl_out_input_sel); | ||
245 | static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls = | 236 | static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls = |
246 | SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum); | 237 | SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum); |
247 | 238 | ||
248 | /* headphone right output mux */ | 239 | /* headphone right output mux */ |
249 | static const struct soc_enum alc5623_hpr_out_input_enum = | 240 | static SOC_ENUM_SINGLE_DECL(alc5623_hpr_out_input_enum, |
250 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 8, 2, alc5623_hpr_out_input_sel); | 241 | ALC5623_OUTPUT_MIXER_CTRL, 8, |
242 | alc5623_hpr_out_input_sel); | ||
251 | static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls = | 243 | static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls = |
252 | SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum); | 244 | SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum); |
253 | 245 | ||
254 | /* speaker output N select */ | 246 | /* speaker output N select */ |
255 | static const struct soc_enum alc5623_spk_n_sour_enum = | 247 | static SOC_ENUM_SINGLE_DECL(alc5623_spk_n_sour_enum, |
256 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 14, 4, alc5623_spk_n_sour_sel); | 248 | ALC5623_OUTPUT_MIXER_CTRL, 14, |
249 | alc5623_spk_n_sour_sel); | ||
257 | static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls = | 250 | static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls = |
258 | SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum); | 251 | SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum); |
259 | 252 | ||
@@ -338,8 +331,9 @@ SND_SOC_DAPM_VMID("Vmid"), | |||
338 | }; | 331 | }; |
339 | 332 | ||
340 | static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"}; | 333 | static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"}; |
341 | static const struct soc_enum alc5623_amp_enum = | 334 | static SOC_ENUM_SINGLE_DECL(alc5623_amp_enum, |
342 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 13, 2, alc5623_amp_names); | 335 | ALC5623_OUTPUT_MIXER_CTRL, 13, |
336 | alc5623_amp_names); | ||
343 | static const struct snd_kcontrol_new alc5623_amp_mux_controls = | 337 | static const struct snd_kcontrol_new alc5623_amp_mux_controls = |
344 | SOC_DAPM_ENUM("Route", alc5623_amp_enum); | 338 | SOC_DAPM_ENUM("Route", alc5623_amp_enum); |
345 | 339 | ||
@@ -869,18 +863,28 @@ static struct snd_soc_dai_driver alc5623_dai = { | |||
869 | 863 | ||
870 | static int alc5623_suspend(struct snd_soc_codec *codec) | 864 | static int alc5623_suspend(struct snd_soc_codec *codec) |
871 | { | 865 | { |
866 | struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); | ||
867 | |||
872 | alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); | 868 | alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); |
869 | regcache_cache_only(alc5623->regmap, true); | ||
870 | |||
873 | return 0; | 871 | return 0; |
874 | } | 872 | } |
875 | 873 | ||
876 | static int alc5623_resume(struct snd_soc_codec *codec) | 874 | static int alc5623_resume(struct snd_soc_codec *codec) |
877 | { | 875 | { |
878 | int i, step = codec->driver->reg_cache_step; | 876 | struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); |
879 | u16 *cache = codec->reg_cache; | 877 | int ret; |
880 | 878 | ||
881 | /* Sync reg_cache with the hardware */ | 879 | /* Sync reg_cache with the hardware */ |
882 | for (i = 2 ; i < codec->driver->reg_cache_size ; i += step) | 880 | regcache_cache_only(alc5623->regmap, false); |
883 | snd_soc_write(codec, i, cache[i]); | 881 | ret = regcache_sync(alc5623->regmap); |
882 | if (ret != 0) { | ||
883 | dev_err(codec->dev, "Failed to sync register cache: %d\n", | ||
884 | ret); | ||
885 | regcache_cache_only(alc5623->regmap, true); | ||
886 | return ret; | ||
887 | } | ||
884 | 888 | ||
885 | alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 889 | alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
886 | 890 | ||
@@ -900,14 +904,14 @@ static int alc5623_probe(struct snd_soc_codec *codec) | |||
900 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 904 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
901 | int ret; | 905 | int ret; |
902 | 906 | ||
903 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type); | 907 | codec->control_data = alc5623->regmap; |
908 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
904 | if (ret < 0) { | 909 | if (ret < 0) { |
905 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 910 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
906 | return ret; | 911 | return ret; |
907 | } | 912 | } |
908 | 913 | ||
909 | alc5623_reset(codec); | 914 | alc5623_reset(codec); |
910 | alc5623_fill_cache(codec); | ||
911 | 915 | ||
912 | /* power on device */ | 916 | /* power on device */ |
913 | alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 917 | alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
@@ -980,9 +984,15 @@ static struct snd_soc_codec_driver soc_codec_device_alc5623 = { | |||
980 | .suspend = alc5623_suspend, | 984 | .suspend = alc5623_suspend, |
981 | .resume = alc5623_resume, | 985 | .resume = alc5623_resume, |
982 | .set_bias_level = alc5623_set_bias_level, | 986 | .set_bias_level = alc5623_set_bias_level, |
983 | .reg_cache_size = ALC5623_VENDOR_ID2+2, | 987 | }; |
984 | .reg_word_size = sizeof(u16), | 988 | |
985 | .reg_cache_step = 2, | 989 | static const struct regmap_config alc5623_regmap = { |
990 | .reg_bits = 8, | ||
991 | .val_bits = 16, | ||
992 | .reg_stride = 2, | ||
993 | |||
994 | .max_register = ALC5623_VENDOR_ID2, | ||
995 | .cache_type = REGCACHE_RBTREE, | ||
986 | }; | 996 | }; |
987 | 997 | ||
988 | /* | 998 | /* |
@@ -996,19 +1006,32 @@ static int alc5623_i2c_probe(struct i2c_client *client, | |||
996 | { | 1006 | { |
997 | struct alc5623_platform_data *pdata; | 1007 | struct alc5623_platform_data *pdata; |
998 | struct alc5623_priv *alc5623; | 1008 | struct alc5623_priv *alc5623; |
999 | int ret, vid1, vid2; | 1009 | unsigned int vid1, vid2; |
1010 | int ret; | ||
1000 | 1011 | ||
1001 | vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1); | 1012 | alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv), |
1002 | if (vid1 < 0) { | 1013 | GFP_KERNEL); |
1003 | dev_err(&client->dev, "failed to read I2C\n"); | 1014 | if (alc5623 == NULL) |
1004 | return -EIO; | 1015 | return -ENOMEM; |
1016 | |||
1017 | alc5623->regmap = devm_regmap_init_i2c(client, &alc5623_regmap); | ||
1018 | if (IS_ERR(alc5623->regmap)) { | ||
1019 | ret = PTR_ERR(alc5623->regmap); | ||
1020 | dev_err(&client->dev, "Failed to initialise I/O: %d\n", ret); | ||
1021 | return ret; | ||
1022 | } | ||
1023 | |||
1024 | ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID1, &vid1); | ||
1025 | if (ret < 0) { | ||
1026 | dev_err(&client->dev, "failed to read vendor ID1: %d\n", ret); | ||
1027 | return ret; | ||
1005 | } | 1028 | } |
1006 | vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8); | 1029 | vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8); |
1007 | 1030 | ||
1008 | vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2); | 1031 | ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID2, &vid2); |
1009 | if (vid2 < 0) { | 1032 | if (ret < 0) { |
1010 | dev_err(&client->dev, "failed to read I2C\n"); | 1033 | dev_err(&client->dev, "failed to read vendor ID2: %d\n", ret); |
1011 | return -EIO; | 1034 | return ret; |
1012 | } | 1035 | } |
1013 | 1036 | ||
1014 | if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { | 1037 | if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { |
@@ -1021,11 +1044,6 @@ static int alc5623_i2c_probe(struct i2c_client *client, | |||
1021 | 1044 | ||
1022 | dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2); | 1045 | dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2); |
1023 | 1046 | ||
1024 | alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv), | ||
1025 | GFP_KERNEL); | ||
1026 | if (alc5623 == NULL) | ||
1027 | return -ENOMEM; | ||
1028 | |||
1029 | pdata = client->dev.platform_data; | 1047 | pdata = client->dev.platform_data; |
1030 | if (pdata) { | 1048 | if (pdata) { |
1031 | alc5623->add_ctrl = pdata->add_ctrl; | 1049 | alc5623->add_ctrl = pdata->add_ctrl; |
@@ -1048,7 +1066,6 @@ static int alc5623_i2c_probe(struct i2c_client *client, | |||
1048 | } | 1066 | } |
1049 | 1067 | ||
1050 | i2c_set_clientdata(client, alc5623); | 1068 | i2c_set_clientdata(client, alc5623); |
1051 | alc5623->control_type = SND_SOC_I2C; | ||
1052 | 1069 | ||
1053 | ret = snd_soc_register_codec(&client->dev, | 1070 | ret = snd_soc_register_codec(&client->dev, |
1054 | &soc_codec_device_alc5623, &alc5623_dai, 1); | 1071 | &soc_codec_device_alc5623, &alc5623_dai, 1); |
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index fb001c56cf8d..d885056ad8f2 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c | |||
@@ -293,51 +293,59 @@ static const char * const alc5632_i2s_out_sel[] = { | |||
293 | "ADC LR", "Voice Stereo Digital"}; | 293 | "ADC LR", "Voice Stereo Digital"}; |
294 | 294 | ||
295 | /* auxout output mux */ | 295 | /* auxout output mux */ |
296 | static const struct soc_enum alc5632_aux_out_input_enum = | 296 | static SOC_ENUM_SINGLE_DECL(alc5632_aux_out_input_enum, |
297 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 6, 4, alc5632_aux_out_input_sel); | 297 | ALC5632_OUTPUT_MIXER_CTRL, 6, |
298 | alc5632_aux_out_input_sel); | ||
298 | static const struct snd_kcontrol_new alc5632_auxout_mux_controls = | 299 | static const struct snd_kcontrol_new alc5632_auxout_mux_controls = |
299 | SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum); | 300 | SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum); |
300 | 301 | ||
301 | /* speaker output mux */ | 302 | /* speaker output mux */ |
302 | static const struct soc_enum alc5632_spkout_input_enum = | 303 | static SOC_ENUM_SINGLE_DECL(alc5632_spkout_input_enum, |
303 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 10, 4, alc5632_spkout_input_sel); | 304 | ALC5632_OUTPUT_MIXER_CTRL, 10, |
305 | alc5632_spkout_input_sel); | ||
304 | static const struct snd_kcontrol_new alc5632_spkout_mux_controls = | 306 | static const struct snd_kcontrol_new alc5632_spkout_mux_controls = |
305 | SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum); | 307 | SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum); |
306 | 308 | ||
307 | /* headphone left output mux */ | 309 | /* headphone left output mux */ |
308 | static const struct soc_enum alc5632_hpl_out_input_enum = | 310 | static SOC_ENUM_SINGLE_DECL(alc5632_hpl_out_input_enum, |
309 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 9, 2, alc5632_hpl_out_input_sel); | 311 | ALC5632_OUTPUT_MIXER_CTRL, 9, |
312 | alc5632_hpl_out_input_sel); | ||
310 | static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls = | 313 | static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls = |
311 | SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum); | 314 | SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum); |
312 | 315 | ||
313 | /* headphone right output mux */ | 316 | /* headphone right output mux */ |
314 | static const struct soc_enum alc5632_hpr_out_input_enum = | 317 | static SOC_ENUM_SINGLE_DECL(alc5632_hpr_out_input_enum, |
315 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 8, 2, alc5632_hpr_out_input_sel); | 318 | ALC5632_OUTPUT_MIXER_CTRL, 8, |
319 | alc5632_hpr_out_input_sel); | ||
316 | static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls = | 320 | static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls = |
317 | SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum); | 321 | SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum); |
318 | 322 | ||
319 | /* speaker output N select */ | 323 | /* speaker output N select */ |
320 | static const struct soc_enum alc5632_spk_n_sour_enum = | 324 | static SOC_ENUM_SINGLE_DECL(alc5632_spk_n_sour_enum, |
321 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 14, 4, alc5632_spk_n_sour_sel); | 325 | ALC5632_OUTPUT_MIXER_CTRL, 14, |
326 | alc5632_spk_n_sour_sel); | ||
322 | static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls = | 327 | static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls = |
323 | SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum); | 328 | SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum); |
324 | 329 | ||
325 | /* speaker amplifier */ | 330 | /* speaker amplifier */ |
326 | static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"}; | 331 | static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"}; |
327 | static const struct soc_enum alc5632_amp_enum = | 332 | static SOC_ENUM_SINGLE_DECL(alc5632_amp_enum, |
328 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 13, 2, alc5632_amp_names); | 333 | ALC5632_OUTPUT_MIXER_CTRL, 13, |
334 | alc5632_amp_names); | ||
329 | static const struct snd_kcontrol_new alc5632_amp_mux_controls = | 335 | static const struct snd_kcontrol_new alc5632_amp_mux_controls = |
330 | SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); | 336 | SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); |
331 | 337 | ||
332 | /* ADC output select */ | 338 | /* ADC output select */ |
333 | static const struct soc_enum alc5632_adcr_func_enum = | 339 | static SOC_ENUM_SINGLE_DECL(alc5632_adcr_func_enum, |
334 | SOC_ENUM_SINGLE(ALC5632_DAC_FUNC_SELECT, 5, 2, alc5632_adcr_func_sel); | 340 | ALC5632_DAC_FUNC_SELECT, 5, |
341 | alc5632_adcr_func_sel); | ||
335 | static const struct snd_kcontrol_new alc5632_adcr_func_controls = | 342 | static const struct snd_kcontrol_new alc5632_adcr_func_controls = |
336 | SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum); | 343 | SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum); |
337 | 344 | ||
338 | /* I2S out select */ | 345 | /* I2S out select */ |
339 | static const struct soc_enum alc5632_i2s_out_enum = | 346 | static SOC_ENUM_SINGLE_DECL(alc5632_i2s_out_enum, |
340 | SOC_ENUM_SINGLE(ALC5632_I2S_OUT_CTL, 5, 2, alc5632_i2s_out_sel); | 347 | ALC5632_I2S_OUT_CTL, 5, |
348 | alc5632_i2s_out_sel); | ||
341 | static const struct snd_kcontrol_new alc5632_i2s_out_controls = | 349 | static const struct snd_kcontrol_new alc5632_i2s_out_controls = |
342 | SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum); | 350 | SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum); |
343 | 351 | ||
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index e4295fee8f13..29e198f57d4c 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -53,6 +53,14 @@ | |||
53 | #define ARIZONA_AIF_RX_ENABLES 0x1A | 53 | #define ARIZONA_AIF_RX_ENABLES 0x1A |
54 | #define ARIZONA_AIF_FORCE_WRITE 0x1B | 54 | #define ARIZONA_AIF_FORCE_WRITE 0x1B |
55 | 55 | ||
56 | #define ARIZONA_FLL_VCO_CORNER 141900000 | ||
57 | #define ARIZONA_FLL_MAX_FREF 13500000 | ||
58 | #define ARIZONA_FLL_MIN_FVCO 90000000 | ||
59 | #define ARIZONA_FLL_MAX_FRATIO 16 | ||
60 | #define ARIZONA_FLL_MAX_REFDIV 8 | ||
61 | #define ARIZONA_FLL_MIN_OUTDIV 2 | ||
62 | #define ARIZONA_FLL_MAX_OUTDIV 7 | ||
63 | |||
56 | #define arizona_fll_err(_fll, fmt, ...) \ | 64 | #define arizona_fll_err(_fll, fmt, ...) \ |
57 | dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) | 65 | dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) |
58 | #define arizona_fll_warn(_fll, fmt, ...) \ | 66 | #define arizona_fll_warn(_fll, fmt, ...) \ |
@@ -542,67 +550,76 @@ static const char *arizona_vol_ramp_text[] = { | |||
542 | "15ms/6dB", "30ms/6dB", | 550 | "15ms/6dB", "30ms/6dB", |
543 | }; | 551 | }; |
544 | 552 | ||
545 | const struct soc_enum arizona_in_vd_ramp = | 553 | SOC_ENUM_SINGLE_DECL(arizona_in_vd_ramp, |
546 | SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, | 554 | ARIZONA_INPUT_VOLUME_RAMP, |
547 | ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); | 555 | ARIZONA_IN_VD_RAMP_SHIFT, |
556 | arizona_vol_ramp_text); | ||
548 | EXPORT_SYMBOL_GPL(arizona_in_vd_ramp); | 557 | EXPORT_SYMBOL_GPL(arizona_in_vd_ramp); |
549 | 558 | ||
550 | const struct soc_enum arizona_in_vi_ramp = | 559 | SOC_ENUM_SINGLE_DECL(arizona_in_vi_ramp, |
551 | SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, | 560 | ARIZONA_INPUT_VOLUME_RAMP, |
552 | ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); | 561 | ARIZONA_IN_VI_RAMP_SHIFT, |
562 | arizona_vol_ramp_text); | ||
553 | EXPORT_SYMBOL_GPL(arizona_in_vi_ramp); | 563 | EXPORT_SYMBOL_GPL(arizona_in_vi_ramp); |
554 | 564 | ||
555 | const struct soc_enum arizona_out_vd_ramp = | 565 | SOC_ENUM_SINGLE_DECL(arizona_out_vd_ramp, |
556 | SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, | 566 | ARIZONA_OUTPUT_VOLUME_RAMP, |
557 | ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); | 567 | ARIZONA_OUT_VD_RAMP_SHIFT, |
568 | arizona_vol_ramp_text); | ||
558 | EXPORT_SYMBOL_GPL(arizona_out_vd_ramp); | 569 | EXPORT_SYMBOL_GPL(arizona_out_vd_ramp); |
559 | 570 | ||
560 | const struct soc_enum arizona_out_vi_ramp = | 571 | SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp, |
561 | SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, | 572 | ARIZONA_OUTPUT_VOLUME_RAMP, |
562 | ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); | 573 | ARIZONA_OUT_VI_RAMP_SHIFT, |
574 | arizona_vol_ramp_text); | ||
563 | EXPORT_SYMBOL_GPL(arizona_out_vi_ramp); | 575 | EXPORT_SYMBOL_GPL(arizona_out_vi_ramp); |
564 | 576 | ||
565 | static const char *arizona_lhpf_mode_text[] = { | 577 | static const char *arizona_lhpf_mode_text[] = { |
566 | "Low-pass", "High-pass" | 578 | "Low-pass", "High-pass" |
567 | }; | 579 | }; |
568 | 580 | ||
569 | const struct soc_enum arizona_lhpf1_mode = | 581 | SOC_ENUM_SINGLE_DECL(arizona_lhpf1_mode, |
570 | SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2, | 582 | ARIZONA_HPLPF1_1, |
571 | arizona_lhpf_mode_text); | 583 | ARIZONA_LHPF1_MODE_SHIFT, |
584 | arizona_lhpf_mode_text); | ||
572 | EXPORT_SYMBOL_GPL(arizona_lhpf1_mode); | 585 | EXPORT_SYMBOL_GPL(arizona_lhpf1_mode); |
573 | 586 | ||
574 | const struct soc_enum arizona_lhpf2_mode = | 587 | SOC_ENUM_SINGLE_DECL(arizona_lhpf2_mode, |
575 | SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2, | 588 | ARIZONA_HPLPF2_1, |
576 | arizona_lhpf_mode_text); | 589 | ARIZONA_LHPF2_MODE_SHIFT, |
590 | arizona_lhpf_mode_text); | ||
577 | EXPORT_SYMBOL_GPL(arizona_lhpf2_mode); | 591 | EXPORT_SYMBOL_GPL(arizona_lhpf2_mode); |
578 | 592 | ||
579 | const struct soc_enum arizona_lhpf3_mode = | 593 | SOC_ENUM_SINGLE_DECL(arizona_lhpf3_mode, |
580 | SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2, | 594 | ARIZONA_HPLPF3_1, |
581 | arizona_lhpf_mode_text); | 595 | ARIZONA_LHPF3_MODE_SHIFT, |
596 | arizona_lhpf_mode_text); | ||
582 | EXPORT_SYMBOL_GPL(arizona_lhpf3_mode); | 597 | EXPORT_SYMBOL_GPL(arizona_lhpf3_mode); |
583 | 598 | ||
584 | const struct soc_enum arizona_lhpf4_mode = | 599 | SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode, |
585 | SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2, | 600 | ARIZONA_HPLPF4_1, |
586 | arizona_lhpf_mode_text); | 601 | ARIZONA_LHPF4_MODE_SHIFT, |
602 | arizona_lhpf_mode_text); | ||
587 | EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); | 603 | EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); |
588 | 604 | ||
589 | static const char *arizona_ng_hold_text[] = { | 605 | static const char *arizona_ng_hold_text[] = { |
590 | "30ms", "120ms", "250ms", "500ms", | 606 | "30ms", "120ms", "250ms", "500ms", |
591 | }; | 607 | }; |
592 | 608 | ||
593 | const struct soc_enum arizona_ng_hold = | 609 | SOC_ENUM_SINGLE_DECL(arizona_ng_hold, |
594 | SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT, | 610 | ARIZONA_NOISE_GATE_CONTROL, |
595 | 4, arizona_ng_hold_text); | 611 | ARIZONA_NGATE_HOLD_SHIFT, |
612 | arizona_ng_hold_text); | ||
596 | EXPORT_SYMBOL_GPL(arizona_ng_hold); | 613 | EXPORT_SYMBOL_GPL(arizona_ng_hold); |
597 | 614 | ||
598 | static const char * const arizona_in_hpf_cut_text[] = { | 615 | static const char * const arizona_in_hpf_cut_text[] = { |
599 | "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz" | 616 | "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz" |
600 | }; | 617 | }; |
601 | 618 | ||
602 | const struct soc_enum arizona_in_hpf_cut_enum = | 619 | SOC_ENUM_SINGLE_DECL(arizona_in_hpf_cut_enum, |
603 | SOC_ENUM_SINGLE(ARIZONA_HPF_CONTROL, ARIZONA_IN_HPF_CUT_SHIFT, | 620 | ARIZONA_HPF_CONTROL, |
604 | ARRAY_SIZE(arizona_in_hpf_cut_text), | 621 | ARIZONA_IN_HPF_CUT_SHIFT, |
605 | arizona_in_hpf_cut_text); | 622 | arizona_in_hpf_cut_text); |
606 | EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum); | 623 | EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum); |
607 | 624 | ||
608 | static const char * const arizona_in_dmic_osr_text[] = { | 625 | static const char * const arizona_in_dmic_osr_text[] = { |
@@ -1377,74 +1394,147 @@ struct arizona_fll_cfg { | |||
1377 | int gain; | 1394 | int gain; |
1378 | }; | 1395 | }; |
1379 | 1396 | ||
1380 | static int arizona_calc_fll(struct arizona_fll *fll, | 1397 | static int arizona_validate_fll(struct arizona_fll *fll, |
1381 | struct arizona_fll_cfg *cfg, | 1398 | unsigned int Fref, |
1382 | unsigned int Fref, | 1399 | unsigned int Fout) |
1383 | unsigned int Fout) | ||
1384 | { | 1400 | { |
1385 | unsigned int target, div, gcd_fll; | 1401 | unsigned int Fvco_min; |
1386 | int i, ratio; | 1402 | |
1403 | if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) { | ||
1404 | arizona_fll_err(fll, | ||
1405 | "Can't scale %dMHz in to <=13.5MHz\n", | ||
1406 | Fref); | ||
1407 | return -EINVAL; | ||
1408 | } | ||
1387 | 1409 | ||
1388 | arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout); | 1410 | Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult; |
1411 | if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) { | ||
1412 | arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n", | ||
1413 | Fout); | ||
1414 | return -EINVAL; | ||
1415 | } | ||
1416 | |||
1417 | return 0; | ||
1418 | } | ||
1419 | |||
1420 | static int arizona_find_fratio(unsigned int Fref, int *fratio) | ||
1421 | { | ||
1422 | int i; | ||
1423 | |||
1424 | /* Find an appropriate FLL_FRATIO */ | ||
1425 | for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { | ||
1426 | if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { | ||
1427 | if (fratio) | ||
1428 | *fratio = fll_fratios[i].fratio; | ||
1429 | return fll_fratios[i].ratio; | ||
1430 | } | ||
1431 | } | ||
1432 | |||
1433 | return -EINVAL; | ||
1434 | } | ||
1435 | |||
1436 | static int arizona_calc_fratio(struct arizona_fll *fll, | ||
1437 | struct arizona_fll_cfg *cfg, | ||
1438 | unsigned int target, | ||
1439 | unsigned int Fref, bool sync) | ||
1440 | { | ||
1441 | int init_ratio, ratio; | ||
1442 | int refdiv, div; | ||
1389 | 1443 | ||
1390 | /* Fref must be <=13.5MHz */ | 1444 | /* Fref must be <=13.5MHz, find initial refdiv */ |
1391 | div = 1; | 1445 | div = 1; |
1392 | cfg->refdiv = 0; | 1446 | cfg->refdiv = 0; |
1393 | while ((Fref / div) > 13500000) { | 1447 | while (Fref > ARIZONA_FLL_MAX_FREF) { |
1394 | div *= 2; | 1448 | div *= 2; |
1449 | Fref /= 2; | ||
1395 | cfg->refdiv++; | 1450 | cfg->refdiv++; |
1396 | 1451 | ||
1397 | if (div > 8) { | 1452 | if (div > ARIZONA_FLL_MAX_REFDIV) |
1398 | arizona_fll_err(fll, | ||
1399 | "Can't scale %dMHz in to <=13.5MHz\n", | ||
1400 | Fref); | ||
1401 | return -EINVAL; | 1453 | return -EINVAL; |
1454 | } | ||
1455 | |||
1456 | /* Find an appropriate FLL_FRATIO */ | ||
1457 | init_ratio = arizona_find_fratio(Fref, &cfg->fratio); | ||
1458 | if (init_ratio < 0) { | ||
1459 | arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n", | ||
1460 | Fref); | ||
1461 | return init_ratio; | ||
1462 | } | ||
1463 | |||
1464 | switch (fll->arizona->type) { | ||
1465 | case WM5110: | ||
1466 | if (fll->arizona->rev < 3 || sync) | ||
1467 | return init_ratio; | ||
1468 | break; | ||
1469 | default: | ||
1470 | return init_ratio; | ||
1471 | } | ||
1472 | |||
1473 | cfg->fratio = init_ratio - 1; | ||
1474 | |||
1475 | /* Adjust FRATIO/refdiv to avoid integer mode if possible */ | ||
1476 | refdiv = cfg->refdiv; | ||
1477 | |||
1478 | while (div <= ARIZONA_FLL_MAX_REFDIV) { | ||
1479 | for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO; | ||
1480 | ratio++) { | ||
1481 | if (target % (ratio * Fref)) { | ||
1482 | cfg->refdiv = refdiv; | ||
1483 | cfg->fratio = ratio - 1; | ||
1484 | return ratio; | ||
1485 | } | ||
1402 | } | 1486 | } |
1487 | |||
1488 | for (ratio = init_ratio - 1; ratio >= 0; ratio--) { | ||
1489 | if (ARIZONA_FLL_VCO_CORNER / (fll->vco_mult * ratio) < | ||
1490 | Fref) | ||
1491 | break; | ||
1492 | |||
1493 | if (target % (ratio * Fref)) { | ||
1494 | cfg->refdiv = refdiv; | ||
1495 | cfg->fratio = ratio - 1; | ||
1496 | return ratio; | ||
1497 | } | ||
1498 | } | ||
1499 | |||
1500 | div *= 2; | ||
1501 | Fref /= 2; | ||
1502 | refdiv++; | ||
1503 | init_ratio = arizona_find_fratio(Fref, NULL); | ||
1403 | } | 1504 | } |
1404 | 1505 | ||
1405 | /* Apply the division for our remaining calculations */ | 1506 | arizona_fll_warn(fll, "Falling back to integer mode operation\n"); |
1406 | Fref /= div; | 1507 | return cfg->fratio + 1; |
1508 | } | ||
1509 | |||
1510 | static int arizona_calc_fll(struct arizona_fll *fll, | ||
1511 | struct arizona_fll_cfg *cfg, | ||
1512 | unsigned int Fref, bool sync) | ||
1513 | { | ||
1514 | unsigned int target, div, gcd_fll; | ||
1515 | int i, ratio; | ||
1516 | |||
1517 | arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout); | ||
1407 | 1518 | ||
1408 | /* Fvco should be over the targt; don't check the upper bound */ | 1519 | /* Fvco should be over the targt; don't check the upper bound */ |
1409 | div = 1; | 1520 | div = ARIZONA_FLL_MIN_OUTDIV; |
1410 | while (Fout * div < 90000000 * fll->vco_mult) { | 1521 | while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) { |
1411 | div++; | 1522 | div++; |
1412 | if (div > 7) { | 1523 | if (div > ARIZONA_FLL_MAX_OUTDIV) |
1413 | arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n", | ||
1414 | Fout); | ||
1415 | return -EINVAL; | 1524 | return -EINVAL; |
1416 | } | ||
1417 | } | 1525 | } |
1418 | target = Fout * div / fll->vco_mult; | 1526 | target = fll->fout * div / fll->vco_mult; |
1419 | cfg->outdiv = div; | 1527 | cfg->outdiv = div; |
1420 | 1528 | ||
1421 | arizona_fll_dbg(fll, "Fvco=%dHz\n", target); | 1529 | arizona_fll_dbg(fll, "Fvco=%dHz\n", target); |
1422 | 1530 | ||
1423 | /* Find an appropraite FLL_FRATIO and factor it out of the target */ | 1531 | /* Find an appropriate FLL_FRATIO and refdiv */ |
1424 | for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { | 1532 | ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync); |
1425 | if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { | 1533 | if (ratio < 0) |
1426 | cfg->fratio = fll_fratios[i].fratio; | 1534 | return ratio; |
1427 | ratio = fll_fratios[i].ratio; | ||
1428 | break; | ||
1429 | } | ||
1430 | } | ||
1431 | if (i == ARRAY_SIZE(fll_fratios)) { | ||
1432 | arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n", | ||
1433 | Fref); | ||
1434 | return -EINVAL; | ||
1435 | } | ||
1436 | 1535 | ||
1437 | for (i = 0; i < ARRAY_SIZE(fll_gains); i++) { | 1536 | /* Apply the division for our remaining calculations */ |
1438 | if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) { | 1537 | Fref = Fref / (1 << cfg->refdiv); |
1439 | cfg->gain = fll_gains[i].gain; | ||
1440 | break; | ||
1441 | } | ||
1442 | } | ||
1443 | if (i == ARRAY_SIZE(fll_gains)) { | ||
1444 | arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n", | ||
1445 | Fref); | ||
1446 | return -EINVAL; | ||
1447 | } | ||
1448 | 1538 | ||
1449 | cfg->n = target / (ratio * Fref); | 1539 | cfg->n = target / (ratio * Fref); |
1450 | 1540 | ||
@@ -1469,6 +1559,18 @@ static int arizona_calc_fll(struct arizona_fll *fll, | |||
1469 | cfg->lambda >>= 1; | 1559 | cfg->lambda >>= 1; |
1470 | } | 1560 | } |
1471 | 1561 | ||
1562 | for (i = 0; i < ARRAY_SIZE(fll_gains); i++) { | ||
1563 | if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) { | ||
1564 | cfg->gain = fll_gains[i].gain; | ||
1565 | break; | ||
1566 | } | ||
1567 | } | ||
1568 | if (i == ARRAY_SIZE(fll_gains)) { | ||
1569 | arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n", | ||
1570 | Fref); | ||
1571 | return -EINVAL; | ||
1572 | } | ||
1573 | |||
1472 | arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n", | 1574 | arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n", |
1473 | cfg->n, cfg->theta, cfg->lambda); | 1575 | cfg->n, cfg->theta, cfg->lambda); |
1474 | arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", | 1576 | arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", |
@@ -1496,14 +1598,18 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base, | |||
1496 | cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | | 1598 | cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | |
1497 | source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); | 1599 | source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); |
1498 | 1600 | ||
1499 | if (sync) | 1601 | if (sync) { |
1500 | regmap_update_bits_async(arizona->regmap, base + 0x7, | 1602 | regmap_update_bits(arizona->regmap, base + 0x7, |
1501 | ARIZONA_FLL1_GAIN_MASK, | 1603 | ARIZONA_FLL1_GAIN_MASK, |
1502 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); | 1604 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); |
1503 | else | 1605 | } else { |
1504 | regmap_update_bits_async(arizona->regmap, base + 0x9, | 1606 | regmap_update_bits(arizona->regmap, base + 0x5, |
1505 | ARIZONA_FLL1_GAIN_MASK, | 1607 | ARIZONA_FLL1_OUTDIV_MASK, |
1506 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); | 1608 | cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); |
1609 | regmap_update_bits(arizona->regmap, base + 0x9, | ||
1610 | ARIZONA_FLL1_GAIN_MASK, | ||
1611 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); | ||
1612 | } | ||
1507 | 1613 | ||
1508 | regmap_update_bits_async(arizona->regmap, base + 2, | 1614 | regmap_update_bits_async(arizona->regmap, base + 2, |
1509 | ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, | 1615 | ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, |
@@ -1526,13 +1632,12 @@ static bool arizona_is_enabled_fll(struct arizona_fll *fll) | |||
1526 | return reg & ARIZONA_FLL1_ENA; | 1632 | return reg & ARIZONA_FLL1_ENA; |
1527 | } | 1633 | } |
1528 | 1634 | ||
1529 | static void arizona_enable_fll(struct arizona_fll *fll, | 1635 | static void arizona_enable_fll(struct arizona_fll *fll) |
1530 | struct arizona_fll_cfg *ref, | ||
1531 | struct arizona_fll_cfg *sync) | ||
1532 | { | 1636 | { |
1533 | struct arizona *arizona = fll->arizona; | 1637 | struct arizona *arizona = fll->arizona; |
1534 | int ret; | 1638 | int ret; |
1535 | bool use_sync = false; | 1639 | bool use_sync = false; |
1640 | struct arizona_fll_cfg cfg; | ||
1536 | 1641 | ||
1537 | /* | 1642 | /* |
1538 | * If we have both REFCLK and SYNCCLK then enable both, | 1643 | * If we have both REFCLK and SYNCCLK then enable both, |
@@ -1540,23 +1645,21 @@ static void arizona_enable_fll(struct arizona_fll *fll, | |||
1540 | */ | 1645 | */ |
1541 | if (fll->ref_src >= 0 && fll->ref_freq && | 1646 | if (fll->ref_src >= 0 && fll->ref_freq && |
1542 | fll->ref_src != fll->sync_src) { | 1647 | fll->ref_src != fll->sync_src) { |
1543 | regmap_update_bits_async(arizona->regmap, fll->base + 5, | 1648 | arizona_calc_fll(fll, &cfg, fll->ref_freq, false); |
1544 | ARIZONA_FLL1_OUTDIV_MASK, | ||
1545 | ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); | ||
1546 | 1649 | ||
1547 | arizona_apply_fll(arizona, fll->base, ref, fll->ref_src, | 1650 | arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src, |
1548 | false); | 1651 | false); |
1549 | if (fll->sync_src >= 0) { | 1652 | if (fll->sync_src >= 0) { |
1550 | arizona_apply_fll(arizona, fll->base + 0x10, sync, | 1653 | arizona_calc_fll(fll, &cfg, fll->sync_freq, true); |
1654 | |||
1655 | arizona_apply_fll(arizona, fll->base + 0x10, &cfg, | ||
1551 | fll->sync_src, true); | 1656 | fll->sync_src, true); |
1552 | use_sync = true; | 1657 | use_sync = true; |
1553 | } | 1658 | } |
1554 | } else if (fll->sync_src >= 0) { | 1659 | } else if (fll->sync_src >= 0) { |
1555 | regmap_update_bits_async(arizona->regmap, fll->base + 5, | 1660 | arizona_calc_fll(fll, &cfg, fll->sync_freq, false); |
1556 | ARIZONA_FLL1_OUTDIV_MASK, | ||
1557 | sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); | ||
1558 | 1661 | ||
1559 | arizona_apply_fll(arizona, fll->base, sync, | 1662 | arizona_apply_fll(arizona, fll->base, &cfg, |
1560 | fll->sync_src, false); | 1663 | fll->sync_src, false); |
1561 | 1664 | ||
1562 | regmap_update_bits_async(arizona->regmap, fll->base + 0x11, | 1665 | regmap_update_bits_async(arizona->regmap, fll->base + 0x11, |
@@ -1618,32 +1721,22 @@ static void arizona_disable_fll(struct arizona_fll *fll) | |||
1618 | int arizona_set_fll_refclk(struct arizona_fll *fll, int source, | 1721 | int arizona_set_fll_refclk(struct arizona_fll *fll, int source, |
1619 | unsigned int Fref, unsigned int Fout) | 1722 | unsigned int Fref, unsigned int Fout) |
1620 | { | 1723 | { |
1621 | struct arizona_fll_cfg ref, sync; | ||
1622 | int ret; | 1724 | int ret; |
1623 | 1725 | ||
1624 | if (fll->ref_src == source && fll->ref_freq == Fref) | 1726 | if (fll->ref_src == source && fll->ref_freq == Fref) |
1625 | return 0; | 1727 | return 0; |
1626 | 1728 | ||
1627 | if (fll->fout) { | 1729 | if (fll->fout && Fref > 0) { |
1628 | if (Fref > 0) { | 1730 | ret = arizona_validate_fll(fll, Fref, fll->fout); |
1629 | ret = arizona_calc_fll(fll, &ref, Fref, fll->fout); | 1731 | if (ret != 0) |
1630 | if (ret != 0) | 1732 | return ret; |
1631 | return ret; | ||
1632 | } | ||
1633 | |||
1634 | if (fll->sync_src >= 0) { | ||
1635 | ret = arizona_calc_fll(fll, &sync, fll->sync_freq, | ||
1636 | fll->fout); | ||
1637 | if (ret != 0) | ||
1638 | return ret; | ||
1639 | } | ||
1640 | } | 1733 | } |
1641 | 1734 | ||
1642 | fll->ref_src = source; | 1735 | fll->ref_src = source; |
1643 | fll->ref_freq = Fref; | 1736 | fll->ref_freq = Fref; |
1644 | 1737 | ||
1645 | if (fll->fout && Fref > 0) { | 1738 | if (fll->fout && Fref > 0) { |
1646 | arizona_enable_fll(fll, &ref, &sync); | 1739 | arizona_enable_fll(fll); |
1647 | } | 1740 | } |
1648 | 1741 | ||
1649 | return 0; | 1742 | return 0; |
@@ -1653,7 +1746,6 @@ EXPORT_SYMBOL_GPL(arizona_set_fll_refclk); | |||
1653 | int arizona_set_fll(struct arizona_fll *fll, int source, | 1746 | int arizona_set_fll(struct arizona_fll *fll, int source, |
1654 | unsigned int Fref, unsigned int Fout) | 1747 | unsigned int Fref, unsigned int Fout) |
1655 | { | 1748 | { |
1656 | struct arizona_fll_cfg ref, sync; | ||
1657 | int ret; | 1749 | int ret; |
1658 | 1750 | ||
1659 | if (fll->sync_src == source && | 1751 | if (fll->sync_src == source && |
@@ -1662,13 +1754,12 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
1662 | 1754 | ||
1663 | if (Fout) { | 1755 | if (Fout) { |
1664 | if (fll->ref_src >= 0) { | 1756 | if (fll->ref_src >= 0) { |
1665 | ret = arizona_calc_fll(fll, &ref, fll->ref_freq, | 1757 | ret = arizona_validate_fll(fll, fll->ref_freq, Fout); |
1666 | Fout); | ||
1667 | if (ret != 0) | 1758 | if (ret != 0) |
1668 | return ret; | 1759 | return ret; |
1669 | } | 1760 | } |
1670 | 1761 | ||
1671 | ret = arizona_calc_fll(fll, &sync, Fref, Fout); | 1762 | ret = arizona_validate_fll(fll, Fref, Fout); |
1672 | if (ret != 0) | 1763 | if (ret != 0) |
1673 | return ret; | 1764 | return ret; |
1674 | } | 1765 | } |
@@ -1678,7 +1769,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
1678 | fll->fout = Fout; | 1769 | fll->fout = Fout; |
1679 | 1770 | ||
1680 | if (Fout) { | 1771 | if (Fout) { |
1681 | arizona_enable_fll(fll, &ref, &sync); | 1772 | arizona_enable_fll(fll); |
1682 | } else { | 1773 | } else { |
1683 | arizona_disable_fll(fll); | 1774 | arizona_disable_fll(fll); |
1684 | } | 1775 | } |
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index ce05fd93dc74..aef4965750c7 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
@@ -159,7 +159,6 @@ static bool cs4271_volatile_reg(struct device *dev, unsigned int reg) | |||
159 | } | 159 | } |
160 | 160 | ||
161 | struct cs4271_private { | 161 | struct cs4271_private { |
162 | /* SND_SOC_I2C or SND_SOC_SPI */ | ||
163 | unsigned int mclk; | 162 | unsigned int mclk; |
164 | bool master; | 163 | bool master; |
165 | bool deemph; | 164 | bool deemph; |
@@ -540,14 +539,10 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
540 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); | 539 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); |
541 | struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; | 540 | struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; |
542 | int ret; | 541 | int ret; |
543 | int gpio_nreset = -EINVAL; | ||
544 | bool amutec_eq_bmutec = false; | 542 | bool amutec_eq_bmutec = false; |
545 | 543 | ||
546 | #ifdef CONFIG_OF | 544 | #ifdef CONFIG_OF |
547 | if (of_match_device(cs4271_dt_ids, codec->dev)) { | 545 | if (of_match_device(cs4271_dt_ids, codec->dev)) { |
548 | gpio_nreset = of_get_named_gpio(codec->dev->of_node, | ||
549 | "reset-gpio", 0); | ||
550 | |||
551 | if (of_get_property(codec->dev->of_node, | 546 | if (of_get_property(codec->dev->of_node, |
552 | "cirrus,amutec-eq-bmutec", NULL)) | 547 | "cirrus,amutec-eq-bmutec", NULL)) |
553 | amutec_eq_bmutec = true; | 548 | amutec_eq_bmutec = true; |
@@ -559,27 +554,19 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
559 | #endif | 554 | #endif |
560 | 555 | ||
561 | if (cs4271plat) { | 556 | if (cs4271plat) { |
562 | if (gpio_is_valid(cs4271plat->gpio_nreset)) | ||
563 | gpio_nreset = cs4271plat->gpio_nreset; | ||
564 | |||
565 | amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec; | 557 | amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec; |
566 | cs4271->enable_soft_reset = cs4271plat->enable_soft_reset; | 558 | cs4271->enable_soft_reset = cs4271plat->enable_soft_reset; |
567 | } | 559 | } |
568 | 560 | ||
569 | if (gpio_nreset >= 0) | 561 | if (gpio_is_valid(cs4271->gpio_nreset)) { |
570 | if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset")) | ||
571 | gpio_nreset = -EINVAL; | ||
572 | if (gpio_nreset >= 0) { | ||
573 | /* Reset codec */ | 562 | /* Reset codec */ |
574 | gpio_direction_output(gpio_nreset, 0); | 563 | gpio_direction_output(cs4271->gpio_nreset, 0); |
575 | udelay(1); | 564 | udelay(1); |
576 | gpio_set_value(gpio_nreset, 1); | 565 | gpio_set_value(cs4271->gpio_nreset, 1); |
577 | /* Give the codec time to wake up */ | 566 | /* Give the codec time to wake up */ |
578 | udelay(1); | 567 | udelay(1); |
579 | } | 568 | } |
580 | 569 | ||
581 | cs4271->gpio_nreset = gpio_nreset; | ||
582 | |||
583 | ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, | 570 | ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, |
584 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN, | 571 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN, |
585 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN); | 572 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN); |
@@ -625,6 +612,36 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = { | |||
625 | .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes), | 612 | .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes), |
626 | }; | 613 | }; |
627 | 614 | ||
615 | static int cs4271_common_probe(struct device *dev, | ||
616 | struct cs4271_private **c) | ||
617 | { | ||
618 | struct cs4271_platform_data *cs4271plat = dev->platform_data; | ||
619 | struct cs4271_private *cs4271; | ||
620 | |||
621 | cs4271 = devm_kzalloc(dev, sizeof(*cs4271), GFP_KERNEL); | ||
622 | if (!cs4271) | ||
623 | return -ENOMEM; | ||
624 | |||
625 | if (of_match_device(cs4271_dt_ids, dev)) | ||
626 | cs4271->gpio_nreset = | ||
627 | of_get_named_gpio(dev->of_node, "reset-gpio", 0); | ||
628 | |||
629 | if (cs4271plat) | ||
630 | cs4271->gpio_nreset = cs4271plat->gpio_nreset; | ||
631 | |||
632 | if (gpio_is_valid(cs4271->gpio_nreset)) { | ||
633 | int ret; | ||
634 | |||
635 | ret = devm_gpio_request(dev, cs4271->gpio_nreset, | ||
636 | "CS4271 Reset"); | ||
637 | if (ret < 0) | ||
638 | return ret; | ||
639 | } | ||
640 | |||
641 | *c = cs4271; | ||
642 | return 0; | ||
643 | } | ||
644 | |||
628 | #if defined(CONFIG_SPI_MASTER) | 645 | #if defined(CONFIG_SPI_MASTER) |
629 | 646 | ||
630 | static const struct regmap_config cs4271_spi_regmap = { | 647 | static const struct regmap_config cs4271_spi_regmap = { |
@@ -644,10 +661,11 @@ static const struct regmap_config cs4271_spi_regmap = { | |||
644 | static int cs4271_spi_probe(struct spi_device *spi) | 661 | static int cs4271_spi_probe(struct spi_device *spi) |
645 | { | 662 | { |
646 | struct cs4271_private *cs4271; | 663 | struct cs4271_private *cs4271; |
664 | int ret; | ||
647 | 665 | ||
648 | cs4271 = devm_kzalloc(&spi->dev, sizeof(*cs4271), GFP_KERNEL); | 666 | ret = cs4271_common_probe(&spi->dev, &cs4271); |
649 | if (!cs4271) | 667 | if (ret < 0) |
650 | return -ENOMEM; | 668 | return ret; |
651 | 669 | ||
652 | spi_set_drvdata(spi, cs4271); | 670 | spi_set_drvdata(spi, cs4271); |
653 | cs4271->regmap = devm_regmap_init_spi(spi, &cs4271_spi_regmap); | 671 | cs4271->regmap = devm_regmap_init_spi(spi, &cs4271_spi_regmap); |
@@ -698,10 +716,11 @@ static int cs4271_i2c_probe(struct i2c_client *client, | |||
698 | const struct i2c_device_id *id) | 716 | const struct i2c_device_id *id) |
699 | { | 717 | { |
700 | struct cs4271_private *cs4271; | 718 | struct cs4271_private *cs4271; |
719 | int ret; | ||
701 | 720 | ||
702 | cs4271 = devm_kzalloc(&client->dev, sizeof(*cs4271), GFP_KERNEL); | 721 | ret = cs4271_common_probe(&client->dev, &cs4271); |
703 | if (!cs4271) | 722 | if (ret < 0) |
704 | return -ENOMEM; | 723 | return ret; |
705 | 724 | ||
706 | i2c_set_clientdata(client, cs4271); | 725 | i2c_set_clientdata(client, cs4271); |
707 | cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap); | 726 | cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap); |
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 6e9ea8379a91..3eab46020a30 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <sound/pcm_params.h> | 30 | #include <sound/pcm_params.h> |
31 | #include <sound/pcm.h> | 31 | #include <sound/pcm.h> |
32 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
33 | #include <linux/regmap.h> | ||
33 | 34 | ||
34 | #include "cs42l51.h" | 35 | #include "cs42l51.h" |
35 | 36 | ||
@@ -40,7 +41,6 @@ enum master_slave_mode { | |||
40 | }; | 41 | }; |
41 | 42 | ||
42 | struct cs42l51_private { | 43 | struct cs42l51_private { |
43 | enum snd_soc_control_type control_type; | ||
44 | unsigned int mclk; | 44 | unsigned int mclk; |
45 | unsigned int audio_mode; /* The mode (I2S or left-justified) */ | 45 | unsigned int audio_mode; /* The mode (I2S or left-justified) */ |
46 | enum master_slave_mode func; | 46 | enum master_slave_mode func; |
@@ -52,24 +52,6 @@ struct cs42l51_private { | |||
52 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ | 52 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ |
53 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) | 53 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) |
54 | 54 | ||
55 | static int cs42l51_fill_cache(struct snd_soc_codec *codec) | ||
56 | { | ||
57 | u8 *cache = codec->reg_cache + 1; | ||
58 | struct i2c_client *i2c_client = to_i2c_client(codec->dev); | ||
59 | s32 length; | ||
60 | |||
61 | length = i2c_smbus_read_i2c_block_data(i2c_client, | ||
62 | CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache); | ||
63 | if (length != CS42L51_NUMREGS) { | ||
64 | dev_err(&i2c_client->dev, | ||
65 | "I2C read failure, addr=0x%x (ret=%d vs %d)\n", | ||
66 | i2c_client->addr, length, CS42L51_NUMREGS); | ||
67 | return -EIO; | ||
68 | } | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, | 55 | static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, |
74 | struct snd_ctl_elem_value *ucontrol) | 56 | struct snd_ctl_elem_value *ucontrol) |
75 | { | 57 | { |
@@ -505,16 +487,9 @@ static struct snd_soc_dai_driver cs42l51_dai = { | |||
505 | 487 | ||
506 | static int cs42l51_probe(struct snd_soc_codec *codec) | 488 | static int cs42l51_probe(struct snd_soc_codec *codec) |
507 | { | 489 | { |
508 | struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); | ||
509 | int ret, reg; | 490 | int ret, reg; |
510 | 491 | ||
511 | ret = cs42l51_fill_cache(codec); | 492 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); |
512 | if (ret < 0) { | ||
513 | dev_err(codec->dev, "failed to fill register cache\n"); | ||
514 | return ret; | ||
515 | } | ||
516 | |||
517 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type); | ||
518 | if (ret < 0) { | 493 | if (ret < 0) { |
519 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 494 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
520 | return ret; | 495 | return ret; |
@@ -538,8 +513,6 @@ static int cs42l51_probe(struct snd_soc_codec *codec) | |||
538 | 513 | ||
539 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | 514 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { |
540 | .probe = cs42l51_probe, | 515 | .probe = cs42l51_probe, |
541 | .reg_cache_size = CS42L51_NUMREGS + 1, | ||
542 | .reg_word_size = sizeof(u8), | ||
543 | 516 | ||
544 | .controls = cs42l51_snd_controls, | 517 | .controls = cs42l51_snd_controls, |
545 | .num_controls = ARRAY_SIZE(cs42l51_snd_controls), | 518 | .num_controls = ARRAY_SIZE(cs42l51_snd_controls), |
@@ -549,38 +522,53 @@ static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | |||
549 | .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), | 522 | .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), |
550 | }; | 523 | }; |
551 | 524 | ||
525 | static const struct regmap_config cs42l51_regmap = { | ||
526 | .reg_bits = 8, | ||
527 | .val_bits = 8, | ||
528 | |||
529 | .max_register = CS42L51_CHARGE_FREQ, | ||
530 | .cache_type = REGCACHE_RBTREE, | ||
531 | }; | ||
532 | |||
552 | static int cs42l51_i2c_probe(struct i2c_client *i2c_client, | 533 | static int cs42l51_i2c_probe(struct i2c_client *i2c_client, |
553 | const struct i2c_device_id *id) | 534 | const struct i2c_device_id *id) |
554 | { | 535 | { |
555 | struct cs42l51_private *cs42l51; | 536 | struct cs42l51_private *cs42l51; |
537 | struct regmap *regmap; | ||
538 | unsigned int val; | ||
556 | int ret; | 539 | int ret; |
557 | 540 | ||
541 | regmap = devm_regmap_init_i2c(i2c_client, &cs42l51_regmap); | ||
542 | if (IS_ERR(regmap)) { | ||
543 | ret = PTR_ERR(regmap); | ||
544 | dev_err(&i2c_client->dev, "Failed to create regmap: %d\n", | ||
545 | ret); | ||
546 | return ret; | ||
547 | } | ||
548 | |||
558 | /* Verify that we have a CS42L51 */ | 549 | /* Verify that we have a CS42L51 */ |
559 | ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID); | 550 | ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val); |
560 | if (ret < 0) { | 551 | if (ret < 0) { |
561 | dev_err(&i2c_client->dev, "failed to read I2C\n"); | 552 | dev_err(&i2c_client->dev, "failed to read I2C\n"); |
562 | goto error; | 553 | goto error; |
563 | } | 554 | } |
564 | 555 | ||
565 | if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && | 556 | if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && |
566 | (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { | 557 | (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { |
567 | dev_err(&i2c_client->dev, "Invalid chip id\n"); | 558 | dev_err(&i2c_client->dev, "Invalid chip id: %x\n", val); |
568 | ret = -ENODEV; | 559 | ret = -ENODEV; |
569 | goto error; | 560 | goto error; |
570 | } | 561 | } |
571 | 562 | ||
572 | dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n", | 563 | dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n", |
573 | ret & 7); | 564 | val & 7); |
574 | 565 | ||
575 | cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private), | 566 | cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private), |
576 | GFP_KERNEL); | 567 | GFP_KERNEL); |
577 | if (!cs42l51) { | 568 | if (!cs42l51) |
578 | dev_err(&i2c_client->dev, "could not allocate codec\n"); | ||
579 | return -ENOMEM; | 569 | return -ENOMEM; |
580 | } | ||
581 | 570 | ||
582 | i2c_set_clientdata(i2c_client, cs42l51); | 571 | i2c_set_clientdata(i2c_client, cs42l51); |
583 | cs42l51->control_type = SND_SOC_I2C; | ||
584 | 572 | ||
585 | ret = snd_soc_register_codec(&i2c_client->dev, | 573 | ret = snd_soc_register_codec(&i2c_client->dev, |
586 | &soc_codec_device_cs42l51, &cs42l51_dai, 1); | 574 | &soc_codec_device_cs42l51, &cs42l51_dai, 1); |
@@ -600,10 +588,17 @@ static const struct i2c_device_id cs42l51_id[] = { | |||
600 | }; | 588 | }; |
601 | MODULE_DEVICE_TABLE(i2c, cs42l51_id); | 589 | MODULE_DEVICE_TABLE(i2c, cs42l51_id); |
602 | 590 | ||
591 | static const struct of_device_id cs42l51_of_match[] = { | ||
592 | { .compatible = "cirrus,cs42l51", }, | ||
593 | { } | ||
594 | }; | ||
595 | MODULE_DEVICE_TABLE(of, cs42l51_of_match); | ||
596 | |||
603 | static struct i2c_driver cs42l51_i2c_driver = { | 597 | static struct i2c_driver cs42l51_i2c_driver = { |
604 | .driver = { | 598 | .driver = { |
605 | .name = "cs42l51-codec", | 599 | .name = "cs42l51-codec", |
606 | .owner = THIS_MODULE, | 600 | .owner = THIS_MODULE, |
601 | .of_match_table = cs42l51_of_match, | ||
607 | }, | 602 | }, |
608 | .id_table = cs42l51_id, | 603 | .id_table = cs42l51_id, |
609 | .probe = cs42l51_i2c_probe, | 604 | .probe = cs42l51_i2c_probe, |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 0bac6d5a4ac8..be455ea5f2fe 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -210,13 +210,11 @@ static const char * const cs42l52_adca_text[] = { | |||
210 | static const char * const cs42l52_adcb_text[] = { | 210 | static const char * const cs42l52_adcb_text[] = { |
211 | "Input1B", "Input2B", "Input3B", "Input4B", "PGA Input Right"}; | 211 | "Input1B", "Input2B", "Input3B", "Input4B", "PGA Input Right"}; |
212 | 212 | ||
213 | static const struct soc_enum adca_enum = | 213 | static SOC_ENUM_SINGLE_DECL(adca_enum, |
214 | SOC_ENUM_SINGLE(CS42L52_ADC_PGA_A, 5, | 214 | CS42L52_ADC_PGA_A, 5, cs42l52_adca_text); |
215 | ARRAY_SIZE(cs42l52_adca_text), cs42l52_adca_text); | ||
216 | 215 | ||
217 | static const struct soc_enum adcb_enum = | 216 | static SOC_ENUM_SINGLE_DECL(adcb_enum, |
218 | SOC_ENUM_SINGLE(CS42L52_ADC_PGA_B, 5, | 217 | CS42L52_ADC_PGA_B, 5, cs42l52_adcb_text); |
219 | ARRAY_SIZE(cs42l52_adcb_text), cs42l52_adcb_text); | ||
220 | 218 | ||
221 | static const struct snd_kcontrol_new adca_mux = | 219 | static const struct snd_kcontrol_new adca_mux = |
222 | SOC_DAPM_ENUM("Left ADC Input Capture Mux", adca_enum); | 220 | SOC_DAPM_ENUM("Left ADC Input Capture Mux", adca_enum); |
@@ -229,26 +227,22 @@ static const char * const mic_bias_level_text[] = { | |||
229 | "0.8 +VA", "0.83 +VA", "0.91 +VA" | 227 | "0.8 +VA", "0.83 +VA", "0.91 +VA" |
230 | }; | 228 | }; |
231 | 229 | ||
232 | static const struct soc_enum mic_bias_level_enum = | 230 | static SOC_ENUM_SINGLE_DECL(mic_bias_level_enum, |
233 | SOC_ENUM_SINGLE(CS42L52_IFACE_CTL2, 0, | 231 | CS42L52_IFACE_CTL2, 0, mic_bias_level_text); |
234 | ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text); | ||
235 | 232 | ||
236 | static const char * const cs42l52_mic_text[] = { "MIC1", "MIC2" }; | 233 | static const char * const cs42l52_mic_text[] = { "MIC1", "MIC2" }; |
237 | 234 | ||
238 | static const struct soc_enum mica_enum = | 235 | static SOC_ENUM_SINGLE_DECL(mica_enum, |
239 | SOC_ENUM_SINGLE(CS42L52_MICA_CTL, 5, | 236 | CS42L52_MICA_CTL, 5, cs42l52_mic_text); |
240 | ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text); | ||
241 | 237 | ||
242 | static const struct soc_enum micb_enum = | 238 | static SOC_ENUM_SINGLE_DECL(micb_enum, |
243 | SOC_ENUM_SINGLE(CS42L52_MICB_CTL, 5, | 239 | CS42L52_MICB_CTL, 5, cs42l52_mic_text); |
244 | ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text); | ||
245 | 240 | ||
246 | static const char * const digital_output_mux_text[] = {"ADC", "DSP"}; | 241 | static const char * const digital_output_mux_text[] = {"ADC", "DSP"}; |
247 | 242 | ||
248 | static const struct soc_enum digital_output_mux_enum = | 243 | static SOC_ENUM_SINGLE_DECL(digital_output_mux_enum, |
249 | SOC_ENUM_SINGLE(CS42L52_ADC_MISC_CTL, 6, | 244 | CS42L52_ADC_MISC_CTL, 6, |
250 | ARRAY_SIZE(digital_output_mux_text), | 245 | digital_output_mux_text); |
251 | digital_output_mux_text); | ||
252 | 246 | ||
253 | static const struct snd_kcontrol_new digital_output_mux = | 247 | static const struct snd_kcontrol_new digital_output_mux = |
254 | SOC_DAPM_ENUM("Digital Output Mux", digital_output_mux_enum); | 248 | SOC_DAPM_ENUM("Digital Output Mux", digital_output_mux_enum); |
@@ -258,18 +252,18 @@ static const char * const hp_gain_num_text[] = { | |||
258 | "0.7099", "0.8399", "1.000", "1.1430" | 252 | "0.7099", "0.8399", "1.000", "1.1430" |
259 | }; | 253 | }; |
260 | 254 | ||
261 | static const struct soc_enum hp_gain_enum = | 255 | static SOC_ENUM_SINGLE_DECL(hp_gain_enum, |
262 | SOC_ENUM_SINGLE(CS42L52_PB_CTL1, 5, | 256 | CS42L52_PB_CTL1, 5, |
263 | ARRAY_SIZE(hp_gain_num_text), hp_gain_num_text); | 257 | hp_gain_num_text); |
264 | 258 | ||
265 | static const char * const beep_pitch_text[] = { | 259 | static const char * const beep_pitch_text[] = { |
266 | "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5", | 260 | "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5", |
267 | "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7" | 261 | "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7" |
268 | }; | 262 | }; |
269 | 263 | ||
270 | static const struct soc_enum beep_pitch_enum = | 264 | static SOC_ENUM_SINGLE_DECL(beep_pitch_enum, |
271 | SOC_ENUM_SINGLE(CS42L52_BEEP_FREQ, 4, | 265 | CS42L52_BEEP_FREQ, 4, |
272 | ARRAY_SIZE(beep_pitch_text), beep_pitch_text); | 266 | beep_pitch_text); |
273 | 267 | ||
274 | static const char * const beep_ontime_text[] = { | 268 | static const char * const beep_ontime_text[] = { |
275 | "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s", | 269 | "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s", |
@@ -277,66 +271,66 @@ static const char * const beep_ontime_text[] = { | |||
277 | "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s" | 271 | "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s" |
278 | }; | 272 | }; |
279 | 273 | ||
280 | static const struct soc_enum beep_ontime_enum = | 274 | static SOC_ENUM_SINGLE_DECL(beep_ontime_enum, |
281 | SOC_ENUM_SINGLE(CS42L52_BEEP_FREQ, 0, | 275 | CS42L52_BEEP_FREQ, 0, |
282 | ARRAY_SIZE(beep_ontime_text), beep_ontime_text); | 276 | beep_ontime_text); |
283 | 277 | ||
284 | static const char * const beep_offtime_text[] = { | 278 | static const char * const beep_offtime_text[] = { |
285 | "1.23 s", "2.58 s", "3.90 s", "5.20 s", | 279 | "1.23 s", "2.58 s", "3.90 s", "5.20 s", |
286 | "6.60 s", "8.05 s", "9.35 s", "10.80 s" | 280 | "6.60 s", "8.05 s", "9.35 s", "10.80 s" |
287 | }; | 281 | }; |
288 | 282 | ||
289 | static const struct soc_enum beep_offtime_enum = | 283 | static SOC_ENUM_SINGLE_DECL(beep_offtime_enum, |
290 | SOC_ENUM_SINGLE(CS42L52_BEEP_VOL, 5, | 284 | CS42L52_BEEP_VOL, 5, |
291 | ARRAY_SIZE(beep_offtime_text), beep_offtime_text); | 285 | beep_offtime_text); |
292 | 286 | ||
293 | static const char * const beep_config_text[] = { | 287 | static const char * const beep_config_text[] = { |
294 | "Off", "Single", "Multiple", "Continuous" | 288 | "Off", "Single", "Multiple", "Continuous" |
295 | }; | 289 | }; |
296 | 290 | ||
297 | static const struct soc_enum beep_config_enum = | 291 | static SOC_ENUM_SINGLE_DECL(beep_config_enum, |
298 | SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 6, | 292 | CS42L52_BEEP_TONE_CTL, 6, |
299 | ARRAY_SIZE(beep_config_text), beep_config_text); | 293 | beep_config_text); |
300 | 294 | ||
301 | static const char * const beep_bass_text[] = { | 295 | static const char * const beep_bass_text[] = { |
302 | "50 Hz", "100 Hz", "200 Hz", "250 Hz" | 296 | "50 Hz", "100 Hz", "200 Hz", "250 Hz" |
303 | }; | 297 | }; |
304 | 298 | ||
305 | static const struct soc_enum beep_bass_enum = | 299 | static SOC_ENUM_SINGLE_DECL(beep_bass_enum, |
306 | SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 1, | 300 | CS42L52_BEEP_TONE_CTL, 1, |
307 | ARRAY_SIZE(beep_bass_text), beep_bass_text); | 301 | beep_bass_text); |
308 | 302 | ||
309 | static const char * const beep_treble_text[] = { | 303 | static const char * const beep_treble_text[] = { |
310 | "5 kHz", "7 kHz", "10 kHz", " 15 kHz" | 304 | "5 kHz", "7 kHz", "10 kHz", " 15 kHz" |
311 | }; | 305 | }; |
312 | 306 | ||
313 | static const struct soc_enum beep_treble_enum = | 307 | static SOC_ENUM_SINGLE_DECL(beep_treble_enum, |
314 | SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 3, | 308 | CS42L52_BEEP_TONE_CTL, 3, |
315 | ARRAY_SIZE(beep_treble_text), beep_treble_text); | 309 | beep_treble_text); |
316 | 310 | ||
317 | static const char * const ng_threshold_text[] = { | 311 | static const char * const ng_threshold_text[] = { |
318 | "-34dB", "-37dB", "-40dB", "-43dB", | 312 | "-34dB", "-37dB", "-40dB", "-43dB", |
319 | "-46dB", "-52dB", "-58dB", "-64dB" | 313 | "-46dB", "-52dB", "-58dB", "-64dB" |
320 | }; | 314 | }; |
321 | 315 | ||
322 | static const struct soc_enum ng_threshold_enum = | 316 | static SOC_ENUM_SINGLE_DECL(ng_threshold_enum, |
323 | SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 2, | 317 | CS42L52_NOISE_GATE_CTL, 2, |
324 | ARRAY_SIZE(ng_threshold_text), ng_threshold_text); | 318 | ng_threshold_text); |
325 | 319 | ||
326 | static const char * const cs42l52_ng_delay_text[] = { | 320 | static const char * const cs42l52_ng_delay_text[] = { |
327 | "50ms", "100ms", "150ms", "200ms"}; | 321 | "50ms", "100ms", "150ms", "200ms"}; |
328 | 322 | ||
329 | static const struct soc_enum ng_delay_enum = | 323 | static SOC_ENUM_SINGLE_DECL(ng_delay_enum, |
330 | SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 0, | 324 | CS42L52_NOISE_GATE_CTL, 0, |
331 | ARRAY_SIZE(cs42l52_ng_delay_text), cs42l52_ng_delay_text); | 325 | cs42l52_ng_delay_text); |
332 | 326 | ||
333 | static const char * const cs42l52_ng_type_text[] = { | 327 | static const char * const cs42l52_ng_type_text[] = { |
334 | "Apply Specific", "Apply All" | 328 | "Apply Specific", "Apply All" |
335 | }; | 329 | }; |
336 | 330 | ||
337 | static const struct soc_enum ng_type_enum = | 331 | static SOC_ENUM_SINGLE_DECL(ng_type_enum, |
338 | SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 6, | 332 | CS42L52_NOISE_GATE_CTL, 6, |
339 | ARRAY_SIZE(cs42l52_ng_type_text), cs42l52_ng_type_text); | 333 | cs42l52_ng_type_text); |
340 | 334 | ||
341 | static const char * const left_swap_text[] = { | 335 | static const char * const left_swap_text[] = { |
342 | "Left", "LR 2", "Right"}; | 336 | "Left", "LR 2", "Right"}; |
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 549d5d6a3fef..06f429184821 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -278,13 +278,13 @@ static const DECLARE_TLV_DB_SCALE(attn_tlv, -6300, 100, 1); | |||
278 | static const char * const cs42l73_pgaa_text[] = { "Line A", "Mic 1" }; | 278 | static const char * const cs42l73_pgaa_text[] = { "Line A", "Mic 1" }; |
279 | static const char * const cs42l73_pgab_text[] = { "Line B", "Mic 2" }; | 279 | static const char * const cs42l73_pgab_text[] = { "Line B", "Mic 2" }; |
280 | 280 | ||
281 | static const struct soc_enum pgaa_enum = | 281 | static SOC_ENUM_SINGLE_DECL(pgaa_enum, |
282 | SOC_ENUM_SINGLE(CS42L73_ADCIPC, 3, | 282 | CS42L73_ADCIPC, 3, |
283 | ARRAY_SIZE(cs42l73_pgaa_text), cs42l73_pgaa_text); | 283 | cs42l73_pgaa_text); |
284 | 284 | ||
285 | static const struct soc_enum pgab_enum = | 285 | static SOC_ENUM_SINGLE_DECL(pgab_enum, |
286 | SOC_ENUM_SINGLE(CS42L73_ADCIPC, 7, | 286 | CS42L73_ADCIPC, 7, |
287 | ARRAY_SIZE(cs42l73_pgab_text), cs42l73_pgab_text); | 287 | cs42l73_pgab_text); |
288 | 288 | ||
289 | static const struct snd_kcontrol_new pgaa_mux = | 289 | static const struct snd_kcontrol_new pgaa_mux = |
290 | SOC_DAPM_ENUM("Left Analog Input Capture Mux", pgaa_enum); | 290 | SOC_DAPM_ENUM("Left Analog Input Capture Mux", pgaa_enum); |
@@ -309,9 +309,9 @@ static const struct snd_kcontrol_new input_right_mixer[] = { | |||
309 | static const char * const cs42l73_ng_delay_text[] = { | 309 | static const char * const cs42l73_ng_delay_text[] = { |
310 | "50ms", "100ms", "150ms", "200ms" }; | 310 | "50ms", "100ms", "150ms", "200ms" }; |
311 | 311 | ||
312 | static const struct soc_enum ng_delay_enum = | 312 | static SOC_ENUM_SINGLE_DECL(ng_delay_enum, |
313 | SOC_ENUM_SINGLE(CS42L73_NGCAB, 0, | 313 | CS42L73_NGCAB, 0, |
314 | ARRAY_SIZE(cs42l73_ng_delay_text), cs42l73_ng_delay_text); | 314 | cs42l73_ng_delay_text); |
315 | 315 | ||
316 | static const char * const cs42l73_mono_mix_texts[] = { | 316 | static const char * const cs42l73_mono_mix_texts[] = { |
317 | "Left", "Right", "Mono Mix"}; | 317 | "Left", "Right", "Mono Mix"}; |
@@ -357,19 +357,19 @@ static const struct snd_kcontrol_new esl_xsp_mixer = | |||
357 | static const char * const cs42l73_ip_swap_text[] = { | 357 | static const char * const cs42l73_ip_swap_text[] = { |
358 | "Stereo", "Mono A", "Mono B", "Swap A-B"}; | 358 | "Stereo", "Mono A", "Mono B", "Swap A-B"}; |
359 | 359 | ||
360 | static const struct soc_enum ip_swap_enum = | 360 | static SOC_ENUM_SINGLE_DECL(ip_swap_enum, |
361 | SOC_ENUM_SINGLE(CS42L73_MIOPC, 6, | 361 | CS42L73_MIOPC, 6, |
362 | ARRAY_SIZE(cs42l73_ip_swap_text), cs42l73_ip_swap_text); | 362 | cs42l73_ip_swap_text); |
363 | 363 | ||
364 | static const char * const cs42l73_spo_mixer_text[] = {"Mono", "Stereo"}; | 364 | static const char * const cs42l73_spo_mixer_text[] = {"Mono", "Stereo"}; |
365 | 365 | ||
366 | static const struct soc_enum vsp_output_mux_enum = | 366 | static SOC_ENUM_SINGLE_DECL(vsp_output_mux_enum, |
367 | SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 5, | 367 | CS42L73_MIXERCTL, 5, |
368 | ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text); | 368 | cs42l73_spo_mixer_text); |
369 | 369 | ||
370 | static const struct soc_enum xsp_output_mux_enum = | 370 | static SOC_ENUM_SINGLE_DECL(xsp_output_mux_enum, |
371 | SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 4, | 371 | CS42L73_MIXERCTL, 4, |
372 | ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text); | 372 | cs42l73_spo_mixer_text); |
373 | 373 | ||
374 | static const struct snd_kcontrol_new vsp_output_mux = | 374 | static const struct snd_kcontrol_new vsp_output_mux = |
375 | SOC_DAPM_ENUM("Route", vsp_output_mux_enum); | 375 | SOC_DAPM_ENUM("Route", vsp_output_mux_enum); |
@@ -1108,7 +1108,7 @@ static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |||
1108 | return 0; | 1108 | return 0; |
1109 | } | 1109 | } |
1110 | 1110 | ||
1111 | static u32 cs42l73_asrc_rates[] = { | 1111 | static const unsigned int cs42l73_asrc_rates[] = { |
1112 | 8000, 11025, 12000, 16000, 22050, | 1112 | 8000, 11025, 12000, 16000, 22050, |
1113 | 24000, 32000, 44100, 48000 | 1113 | 24000, 32000, 44100, 48000 |
1114 | }; | 1114 | }; |
@@ -1241,7 +1241,7 @@ static int cs42l73_set_tristate(struct snd_soc_dai *dai, int tristate) | |||
1241 | 0x7F, tristate << 7); | 1241 | 0x7F, tristate << 7); |
1242 | } | 1242 | } |
1243 | 1243 | ||
1244 | static struct snd_pcm_hw_constraint_list constraints_12_24 = { | 1244 | static const struct snd_pcm_hw_constraint_list constraints_12_24 = { |
1245 | .count = ARRAY_SIZE(cs42l73_asrc_rates), | 1245 | .count = ARRAY_SIZE(cs42l73_asrc_rates), |
1246 | .list = cs42l73_asrc_rates, | 1246 | .list = cs42l73_asrc_rates, |
1247 | }; | 1247 | }; |
@@ -1255,9 +1255,6 @@ static int cs42l73_pcm_startup(struct snd_pcm_substream *substream, | |||
1255 | return 0; | 1255 | return 0; |
1256 | } | 1256 | } |
1257 | 1257 | ||
1258 | /* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */ | ||
1259 | #define CS42L73_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT) | ||
1260 | |||
1261 | 1258 | ||
1262 | #define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | 1259 | #define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
1263 | SNDRV_PCM_FMTBIT_S24_LE) | 1260 | SNDRV_PCM_FMTBIT_S24_LE) |
@@ -1278,14 +1275,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { | |||
1278 | .stream_name = "XSP Playback", | 1275 | .stream_name = "XSP Playback", |
1279 | .channels_min = 1, | 1276 | .channels_min = 1, |
1280 | .channels_max = 2, | 1277 | .channels_max = 2, |
1281 | .rates = CS42L73_RATES, | 1278 | .rates = SNDRV_PCM_RATE_KNOT, |
1282 | .formats = CS42L73_FORMATS, | 1279 | .formats = CS42L73_FORMATS, |
1283 | }, | 1280 | }, |
1284 | .capture = { | 1281 | .capture = { |
1285 | .stream_name = "XSP Capture", | 1282 | .stream_name = "XSP Capture", |
1286 | .channels_min = 1, | 1283 | .channels_min = 1, |
1287 | .channels_max = 2, | 1284 | .channels_max = 2, |
1288 | .rates = CS42L73_RATES, | 1285 | .rates = SNDRV_PCM_RATE_KNOT, |
1289 | .formats = CS42L73_FORMATS, | 1286 | .formats = CS42L73_FORMATS, |
1290 | }, | 1287 | }, |
1291 | .ops = &cs42l73_ops, | 1288 | .ops = &cs42l73_ops, |
@@ -1298,14 +1295,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { | |||
1298 | .stream_name = "ASP Playback", | 1295 | .stream_name = "ASP Playback", |
1299 | .channels_min = 2, | 1296 | .channels_min = 2, |
1300 | .channels_max = 2, | 1297 | .channels_max = 2, |
1301 | .rates = CS42L73_RATES, | 1298 | .rates = SNDRV_PCM_RATE_KNOT, |
1302 | .formats = CS42L73_FORMATS, | 1299 | .formats = CS42L73_FORMATS, |
1303 | }, | 1300 | }, |
1304 | .capture = { | 1301 | .capture = { |
1305 | .stream_name = "ASP Capture", | 1302 | .stream_name = "ASP Capture", |
1306 | .channels_min = 2, | 1303 | .channels_min = 2, |
1307 | .channels_max = 2, | 1304 | .channels_max = 2, |
1308 | .rates = CS42L73_RATES, | 1305 | .rates = SNDRV_PCM_RATE_KNOT, |
1309 | .formats = CS42L73_FORMATS, | 1306 | .formats = CS42L73_FORMATS, |
1310 | }, | 1307 | }, |
1311 | .ops = &cs42l73_ops, | 1308 | .ops = &cs42l73_ops, |
@@ -1318,14 +1315,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { | |||
1318 | .stream_name = "VSP Playback", | 1315 | .stream_name = "VSP Playback", |
1319 | .channels_min = 1, | 1316 | .channels_min = 1, |
1320 | .channels_max = 2, | 1317 | .channels_max = 2, |
1321 | .rates = CS42L73_RATES, | 1318 | .rates = SNDRV_PCM_RATE_KNOT, |
1322 | .formats = CS42L73_FORMATS, | 1319 | .formats = CS42L73_FORMATS, |
1323 | }, | 1320 | }, |
1324 | .capture = { | 1321 | .capture = { |
1325 | .stream_name = "VSP Capture", | 1322 | .stream_name = "VSP Capture", |
1326 | .channels_min = 1, | 1323 | .channels_min = 1, |
1327 | .channels_max = 2, | 1324 | .channels_max = 2, |
1328 | .rates = CS42L73_RATES, | 1325 | .rates = SNDRV_PCM_RATE_KNOT, |
1329 | .formats = CS42L73_FORMATS, | 1326 | .formats = CS42L73_FORMATS, |
1330 | }, | 1327 | }, |
1331 | .ops = &cs42l73_ops, | 1328 | .ops = &cs42l73_ops, |
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index e62e294a8033..01e55fc72307 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c | |||
@@ -307,29 +307,29 @@ static const char * const da7210_hpf_cutoff_txt[] = { | |||
307 | "Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi" | 307 | "Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi" |
308 | }; | 308 | }; |
309 | 309 | ||
310 | static const struct soc_enum da7210_dac_hpf_cutoff = | 310 | static SOC_ENUM_SINGLE_DECL(da7210_dac_hpf_cutoff, |
311 | SOC_ENUM_SINGLE(DA7210_DAC_HPF, 0, 4, da7210_hpf_cutoff_txt); | 311 | DA7210_DAC_HPF, 0, da7210_hpf_cutoff_txt); |
312 | 312 | ||
313 | static const struct soc_enum da7210_adc_hpf_cutoff = | 313 | static SOC_ENUM_SINGLE_DECL(da7210_adc_hpf_cutoff, |
314 | SOC_ENUM_SINGLE(DA7210_ADC_HPF, 0, 4, da7210_hpf_cutoff_txt); | 314 | DA7210_ADC_HPF, 0, da7210_hpf_cutoff_txt); |
315 | 315 | ||
316 | /* ADC and DAC voice (8kHz) high pass cutoff value */ | 316 | /* ADC and DAC voice (8kHz) high pass cutoff value */ |
317 | static const char * const da7210_vf_cutoff_txt[] = { | 317 | static const char * const da7210_vf_cutoff_txt[] = { |
318 | "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" | 318 | "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" |
319 | }; | 319 | }; |
320 | 320 | ||
321 | static const struct soc_enum da7210_dac_vf_cutoff = | 321 | static SOC_ENUM_SINGLE_DECL(da7210_dac_vf_cutoff, |
322 | SOC_ENUM_SINGLE(DA7210_DAC_HPF, 4, 8, da7210_vf_cutoff_txt); | 322 | DA7210_DAC_HPF, 4, da7210_vf_cutoff_txt); |
323 | 323 | ||
324 | static const struct soc_enum da7210_adc_vf_cutoff = | 324 | static SOC_ENUM_SINGLE_DECL(da7210_adc_vf_cutoff, |
325 | SOC_ENUM_SINGLE(DA7210_ADC_HPF, 4, 8, da7210_vf_cutoff_txt); | 325 | DA7210_ADC_HPF, 4, da7210_vf_cutoff_txt); |
326 | 326 | ||
327 | static const char *da7210_hp_mode_txt[] = { | 327 | static const char *da7210_hp_mode_txt[] = { |
328 | "Class H", "Class G" | 328 | "Class H", "Class G" |
329 | }; | 329 | }; |
330 | 330 | ||
331 | static const struct soc_enum da7210_hp_mode_sel = | 331 | static SOC_ENUM_SINGLE_DECL(da7210_hp_mode_sel, |
332 | SOC_ENUM_SINGLE(DA7210_HP_CFG, 0, 2, da7210_hp_mode_txt); | 332 | DA7210_HP_CFG, 0, da7210_hp_mode_txt); |
333 | 333 | ||
334 | /* ALC can be enabled only if noise suppression is disabled */ | 334 | /* ALC can be enabled only if noise suppression is disabled */ |
335 | static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, | 335 | static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, |
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index f295b6569910..f4d965ebc29e 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c | |||
@@ -1268,11 +1268,23 @@ static struct snd_soc_dai_driver da732x_dai[] = { | |||
1268 | }, | 1268 | }, |
1269 | }; | 1269 | }; |
1270 | 1270 | ||
1271 | static bool da732x_volatile(struct device *dev, unsigned int reg) | ||
1272 | { | ||
1273 | switch (reg) { | ||
1274 | case DA732X_REG_HPL_DAC_OFF_CNTL: | ||
1275 | case DA732X_REG_HPR_DAC_OFF_CNTL: | ||
1276 | return true; | ||
1277 | default: | ||
1278 | return false; | ||
1279 | } | ||
1280 | } | ||
1281 | |||
1271 | static const struct regmap_config da732x_regmap = { | 1282 | static const struct regmap_config da732x_regmap = { |
1272 | .reg_bits = 8, | 1283 | .reg_bits = 8, |
1273 | .val_bits = 8, | 1284 | .val_bits = 8, |
1274 | 1285 | ||
1275 | .max_register = DA732X_MAX_REG, | 1286 | .max_register = DA732X_MAX_REG, |
1287 | .volatile_reg = da732x_volatile, | ||
1276 | .reg_defaults = da732x_reg_cache, | 1288 | .reg_defaults = da732x_reg_cache, |
1277 | .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache), | 1289 | .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache), |
1278 | .cache_type = REGCACHE_RBTREE, | 1290 | .cache_type = REGCACHE_RBTREE, |
diff --git a/sound/soc/codecs/da732x.h b/sound/soc/codecs/da732x.h index c8ce5475de22..1dceafeec415 100644 --- a/sound/soc/codecs/da732x.h +++ b/sound/soc/codecs/da732x.h | |||
@@ -113,9 +113,6 @@ | |||
113 | #define DA732X_EQ_OVERALL_VOL_DB_MIN -1800 | 113 | #define DA732X_EQ_OVERALL_VOL_DB_MIN -1800 |
114 | #define DA732X_EQ_OVERALL_VOL_DB_INC 600 | 114 | #define DA732X_EQ_OVERALL_VOL_DB_INC 600 |
115 | 115 | ||
116 | #define DA732X_SOC_ENUM_DOUBLE_R(xreg, xrreg, xmax, xtext) \ | ||
117 | {.reg = xreg, .reg2 = xrreg, .max = xmax, .texts = xtext} | ||
118 | |||
119 | enum da732x_sysctl { | 116 | enum da732x_sysctl { |
120 | DA732X_SR_8KHZ = 0x1, | 117 | DA732X_SR_8KHZ = 0x1, |
121 | DA732X_SR_11_025KHZ = 0x2, | 118 | DA732X_SR_11_025KHZ = 0x2, |
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index 52b79a487ac7..422812613a28 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c | |||
@@ -1523,8 +1523,15 @@ static int da9055_remove(struct i2c_client *client) | |||
1523 | return 0; | 1523 | return 0; |
1524 | } | 1524 | } |
1525 | 1525 | ||
1526 | /* | ||
1527 | * DO NOT change the device Ids. The naming is intentionally specific as both | ||
1528 | * the CODEC and PMIC parts of this chip are instantiated separately as I2C | ||
1529 | * devices (both have configurable I2C addresses, and are to all intents and | ||
1530 | * purposes separate). As a result there are specific DA9055 Ids for CODEC | ||
1531 | * and PMIC, which must be different to operate together. | ||
1532 | */ | ||
1526 | static const struct i2c_device_id da9055_i2c_id[] = { | 1533 | static const struct i2c_device_id da9055_i2c_id[] = { |
1527 | { "da9055", 0 }, | 1534 | { "da9055-codec", 0 }, |
1528 | { } | 1535 | { } |
1529 | }; | 1536 | }; |
1530 | MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); | 1537 | MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); |
@@ -1532,7 +1539,7 @@ MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); | |||
1532 | /* I2C codec control layer */ | 1539 | /* I2C codec control layer */ |
1533 | static struct i2c_driver da9055_i2c_driver = { | 1540 | static struct i2c_driver da9055_i2c_driver = { |
1534 | .driver = { | 1541 | .driver = { |
1535 | .name = "da9055", | 1542 | .name = "da9055-codec", |
1536 | .owner = THIS_MODULE, | 1543 | .owner = THIS_MODULE, |
1537 | }, | 1544 | }, |
1538 | .probe = da9055_i2c_probe, | 1545 | .probe = da9055_i2c_probe, |
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index 5839048ec467..cb736ddc446d 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c | |||
@@ -140,13 +140,17 @@ static const char *isabelle_rx1_texts[] = {"VRX1", "ARX1"}; | |||
140 | static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"}; | 140 | static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"}; |
141 | 141 | ||
142 | static const struct soc_enum isabelle_rx1_enum[] = { | 142 | static const struct soc_enum isabelle_rx1_enum[] = { |
143 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3, 1, isabelle_rx1_texts), | 143 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3, |
144 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5, 1, isabelle_rx1_texts), | 144 | ARRAY_SIZE(isabelle_rx1_texts), isabelle_rx1_texts), |
145 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5, | ||
146 | ARRAY_SIZE(isabelle_rx1_texts), isabelle_rx1_texts), | ||
145 | }; | 147 | }; |
146 | 148 | ||
147 | static const struct soc_enum isabelle_rx2_enum[] = { | 149 | static const struct soc_enum isabelle_rx2_enum[] = { |
148 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, 1, isabelle_rx2_texts), | 150 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, |
149 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, 1, isabelle_rx2_texts), | 151 | ARRAY_SIZE(isabelle_rx2_texts), isabelle_rx2_texts), |
152 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, | ||
153 | ARRAY_SIZE(isabelle_rx2_texts), isabelle_rx2_texts), | ||
150 | }; | 154 | }; |
151 | 155 | ||
152 | /* Headset DAC playback switches */ | 156 | /* Headset DAC playback switches */ |
@@ -161,13 +165,17 @@ static const char *isabelle_atx_texts[] = {"AMIC1", "DMIC"}; | |||
161 | static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"}; | 165 | static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"}; |
162 | 166 | ||
163 | static const struct soc_enum isabelle_atx_enum[] = { | 167 | static const struct soc_enum isabelle_atx_enum[] = { |
164 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, 1, isabelle_atx_texts), | 168 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, |
165 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_atx_texts), | 169 | ARRAY_SIZE(isabelle_atx_texts), isabelle_atx_texts), |
170 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, | ||
171 | ARRAY_SIZE(isabelle_atx_texts), isabelle_atx_texts), | ||
166 | }; | 172 | }; |
167 | 173 | ||
168 | static const struct soc_enum isabelle_vtx_enum[] = { | 174 | static const struct soc_enum isabelle_vtx_enum[] = { |
169 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, 1, isabelle_vtx_texts), | 175 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, |
170 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_vtx_texts), | 176 | ARRAY_SIZE(isabelle_vtx_texts), isabelle_vtx_texts), |
177 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, | ||
178 | ARRAY_SIZE(isabelle_vtx_texts), isabelle_vtx_texts), | ||
171 | }; | 179 | }; |
172 | 180 | ||
173 | static const struct snd_kcontrol_new atx_mux_controls = | 181 | static const struct snd_kcontrol_new atx_mux_controls = |
@@ -183,17 +191,13 @@ static const char *isabelle_amic1_texts[] = { | |||
183 | /* Left analog microphone selection */ | 191 | /* Left analog microphone selection */ |
184 | static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"}; | 192 | static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"}; |
185 | 193 | ||
186 | static const struct soc_enum isabelle_amic1_enum[] = { | 194 | static SOC_ENUM_SINGLE_DECL(isabelle_amic1_enum, |
187 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 5, | 195 | ISABELLE_AMIC_CFG_REG, 5, |
188 | ARRAY_SIZE(isabelle_amic1_texts), | 196 | isabelle_amic1_texts); |
189 | isabelle_amic1_texts), | ||
190 | }; | ||
191 | 197 | ||
192 | static const struct soc_enum isabelle_amic2_enum[] = { | 198 | static SOC_ENUM_SINGLE_DECL(isabelle_amic2_enum, |
193 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 4, | 199 | ISABELLE_AMIC_CFG_REG, 4, |
194 | ARRAY_SIZE(isabelle_amic2_texts), | 200 | isabelle_amic2_texts); |
195 | isabelle_amic2_texts), | ||
196 | }; | ||
197 | 201 | ||
198 | static const struct snd_kcontrol_new amic1_control = | 202 | static const struct snd_kcontrol_new amic1_control = |
199 | SOC_DAPM_ENUM("Route", isabelle_amic1_enum); | 203 | SOC_DAPM_ENUM("Route", isabelle_amic1_enum); |
@@ -206,16 +210,20 @@ static const char *isabelle_st_audio_texts[] = {"ATX1", "ATX2"}; | |||
206 | static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"}; | 210 | static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"}; |
207 | 211 | ||
208 | static const struct soc_enum isabelle_st_audio_enum[] = { | 212 | static const struct soc_enum isabelle_st_audio_enum[] = { |
209 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7, 1, | 213 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7, |
214 | ARRAY_SIZE(isabelle_st_audio_texts), | ||
210 | isabelle_st_audio_texts), | 215 | isabelle_st_audio_texts), |
211 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7, 1, | 216 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7, |
217 | ARRAY_SIZE(isabelle_st_audio_texts), | ||
212 | isabelle_st_audio_texts), | 218 | isabelle_st_audio_texts), |
213 | }; | 219 | }; |
214 | 220 | ||
215 | static const struct soc_enum isabelle_st_voice_enum[] = { | 221 | static const struct soc_enum isabelle_st_voice_enum[] = { |
216 | SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7, 1, | 222 | SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7, |
223 | ARRAY_SIZE(isabelle_st_voice_texts), | ||
217 | isabelle_st_voice_texts), | 224 | isabelle_st_voice_texts), |
218 | SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7, 1, | 225 | SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7, |
226 | ARRAY_SIZE(isabelle_st_voice_texts), | ||
219 | isabelle_st_voice_texts), | 227 | isabelle_st_voice_texts), |
220 | }; | 228 | }; |
221 | 229 | ||
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index e19490cfb3a8..6b7fe5e54881 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c | |||
@@ -195,18 +195,18 @@ struct lm49453_priv { | |||
195 | 195 | ||
196 | static const char *lm49453_mic2mode_text[] = {"Single Ended", "Differential"}; | 196 | static const char *lm49453_mic2mode_text[] = {"Single Ended", "Differential"}; |
197 | 197 | ||
198 | static const SOC_ENUM_SINGLE_DECL(lm49453_mic2mode_enum, LM49453_P0_MICR_REG, 5, | 198 | static SOC_ENUM_SINGLE_DECL(lm49453_mic2mode_enum, LM49453_P0_MICR_REG, 5, |
199 | lm49453_mic2mode_text); | 199 | lm49453_mic2mode_text); |
200 | 200 | ||
201 | static const char *lm49453_dmic_cfg_text[] = {"DMICDAT1", "DMICDAT2"}; | 201 | static const char *lm49453_dmic_cfg_text[] = {"DMICDAT1", "DMICDAT2"}; |
202 | 202 | ||
203 | static const SOC_ENUM_SINGLE_DECL(lm49453_dmic12_cfg_enum, | 203 | static SOC_ENUM_SINGLE_DECL(lm49453_dmic12_cfg_enum, |
204 | LM49453_P0_DIGITAL_MIC1_CONFIG_REG, | 204 | LM49453_P0_DIGITAL_MIC1_CONFIG_REG, 7, |
205 | 7, lm49453_dmic_cfg_text); | 205 | lm49453_dmic_cfg_text); |
206 | 206 | ||
207 | static const SOC_ENUM_SINGLE_DECL(lm49453_dmic34_cfg_enum, | 207 | static SOC_ENUM_SINGLE_DECL(lm49453_dmic34_cfg_enum, |
208 | LM49453_P0_DIGITAL_MIC2_CONFIG_REG, | 208 | LM49453_P0_DIGITAL_MIC2_CONFIG_REG, 7, |
209 | 7, lm49453_dmic_cfg_text); | 209 | lm49453_dmic_cfg_text); |
210 | 210 | ||
211 | /* MUX Controls */ | 211 | /* MUX Controls */ |
212 | static const char *lm49453_adcl_mux_text[] = { "MIC1", "Aux_L" }; | 212 | static const char *lm49453_adcl_mux_text[] = { "MIC1", "Aux_L" }; |
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index ee660e2d3df3..bb1ecfc4459b 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -1849,7 +1849,7 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec) | |||
1849 | 1849 | ||
1850 | /* Now point the soc_enum to .texts array items */ | 1850 | /* Now point the soc_enum to .texts array items */ |
1851 | max98088->eq_enum.texts = max98088->eq_texts; | 1851 | max98088->eq_enum.texts = max98088->eq_texts; |
1852 | max98088->eq_enum.max = max98088->eq_textcnt; | 1852 | max98088->eq_enum.items = max98088->eq_textcnt; |
1853 | 1853 | ||
1854 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); | 1854 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); |
1855 | if (ret != 0) | 1855 | if (ret != 0) |
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 51f9b3d16b41..f363de19be07 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c | |||
@@ -336,6 +336,7 @@ static bool max98090_readable_register(struct device *dev, unsigned int reg) | |||
336 | case M98090_REG_RECORD_TDM_SLOT: | 336 | case M98090_REG_RECORD_TDM_SLOT: |
337 | case M98090_REG_SAMPLE_RATE: | 337 | case M98090_REG_SAMPLE_RATE: |
338 | case M98090_REG_DMIC34_BIQUAD_BASE ... M98090_REG_DMIC34_BIQUAD_BASE + 0x0E: | 338 | case M98090_REG_DMIC34_BIQUAD_BASE ... M98090_REG_DMIC34_BIQUAD_BASE + 0x0E: |
339 | case M98090_REG_REVISION_ID: | ||
339 | return true; | 340 | return true; |
340 | default: | 341 | default: |
341 | return false; | 342 | return false; |
@@ -512,65 +513,75 @@ static const char *max98090_perf_pwr_text[] = | |||
512 | static const char *max98090_pwr_perf_text[] = | 513 | static const char *max98090_pwr_perf_text[] = |
513 | { "Low Power", "High Performance" }; | 514 | { "Low Power", "High Performance" }; |
514 | 515 | ||
515 | static const struct soc_enum max98090_vcmbandgap_enum = | 516 | static SOC_ENUM_SINGLE_DECL(max98090_vcmbandgap_enum, |
516 | SOC_ENUM_SINGLE(M98090_REG_BIAS_CONTROL, M98090_VCM_MODE_SHIFT, | 517 | M98090_REG_BIAS_CONTROL, |
517 | ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); | 518 | M98090_VCM_MODE_SHIFT, |
519 | max98090_pwr_perf_text); | ||
518 | 520 | ||
519 | static const char *max98090_osr128_text[] = { "64*fs", "128*fs" }; | 521 | static const char *max98090_osr128_text[] = { "64*fs", "128*fs" }; |
520 | 522 | ||
521 | static const struct soc_enum max98090_osr128_enum = | 523 | static SOC_ENUM_SINGLE_DECL(max98090_osr128_enum, |
522 | SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_OSR128_SHIFT, | 524 | M98090_REG_ADC_CONTROL, |
523 | ARRAY_SIZE(max98090_osr128_text), max98090_osr128_text); | 525 | M98090_OSR128_SHIFT, |
526 | max98090_osr128_text); | ||
524 | 527 | ||
525 | static const char *max98090_mode_text[] = { "Voice", "Music" }; | 528 | static const char *max98090_mode_text[] = { "Voice", "Music" }; |
526 | 529 | ||
527 | static const struct soc_enum max98090_mode_enum = | 530 | static SOC_ENUM_SINGLE_DECL(max98090_mode_enum, |
528 | SOC_ENUM_SINGLE(M98090_REG_FILTER_CONFIG, M98090_MODE_SHIFT, | 531 | M98090_REG_FILTER_CONFIG, |
529 | ARRAY_SIZE(max98090_mode_text), max98090_mode_text); | 532 | M98090_MODE_SHIFT, |
533 | max98090_mode_text); | ||
530 | 534 | ||
531 | static const struct soc_enum max98090_filter_dmic34mode_enum = | 535 | static SOC_ENUM_SINGLE_DECL(max98090_filter_dmic34mode_enum, |
532 | SOC_ENUM_SINGLE(M98090_REG_FILTER_CONFIG, | 536 | M98090_REG_FILTER_CONFIG, |
533 | M98090_FLT_DMIC34MODE_SHIFT, | 537 | M98090_FLT_DMIC34MODE_SHIFT, |
534 | ARRAY_SIZE(max98090_mode_text), max98090_mode_text); | 538 | max98090_mode_text); |
535 | 539 | ||
536 | static const char *max98090_drcatk_text[] = | 540 | static const char *max98090_drcatk_text[] = |
537 | { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" }; | 541 | { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" }; |
538 | 542 | ||
539 | static const struct soc_enum max98090_drcatk_enum = | 543 | static SOC_ENUM_SINGLE_DECL(max98090_drcatk_enum, |
540 | SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCATK_SHIFT, | 544 | M98090_REG_DRC_TIMING, |
541 | ARRAY_SIZE(max98090_drcatk_text), max98090_drcatk_text); | 545 | M98090_DRCATK_SHIFT, |
546 | max98090_drcatk_text); | ||
542 | 547 | ||
543 | static const char *max98090_drcrls_text[] = | 548 | static const char *max98090_drcrls_text[] = |
544 | { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" }; | 549 | { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" }; |
545 | 550 | ||
546 | static const struct soc_enum max98090_drcrls_enum = | 551 | static SOC_ENUM_SINGLE_DECL(max98090_drcrls_enum, |
547 | SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCRLS_SHIFT, | 552 | M98090_REG_DRC_TIMING, |
548 | ARRAY_SIZE(max98090_drcrls_text), max98090_drcrls_text); | 553 | M98090_DRCRLS_SHIFT, |
554 | max98090_drcrls_text); | ||
549 | 555 | ||
550 | static const char *max98090_alccmp_text[] = | 556 | static const char *max98090_alccmp_text[] = |
551 | { "1:1", "1:1.5", "1:2", "1:4", "1:INF" }; | 557 | { "1:1", "1:1.5", "1:2", "1:4", "1:INF" }; |
552 | 558 | ||
553 | static const struct soc_enum max98090_alccmp_enum = | 559 | static SOC_ENUM_SINGLE_DECL(max98090_alccmp_enum, |
554 | SOC_ENUM_SINGLE(M98090_REG_DRC_COMPRESSOR, M98090_DRCCMP_SHIFT, | 560 | M98090_REG_DRC_COMPRESSOR, |
555 | ARRAY_SIZE(max98090_alccmp_text), max98090_alccmp_text); | 561 | M98090_DRCCMP_SHIFT, |
562 | max98090_alccmp_text); | ||
556 | 563 | ||
557 | static const char *max98090_drcexp_text[] = { "1:1", "2:1", "3:1" }; | 564 | static const char *max98090_drcexp_text[] = { "1:1", "2:1", "3:1" }; |
558 | 565 | ||
559 | static const struct soc_enum max98090_drcexp_enum = | 566 | static SOC_ENUM_SINGLE_DECL(max98090_drcexp_enum, |
560 | SOC_ENUM_SINGLE(M98090_REG_DRC_EXPANDER, M98090_DRCEXP_SHIFT, | 567 | M98090_REG_DRC_EXPANDER, |
561 | ARRAY_SIZE(max98090_drcexp_text), max98090_drcexp_text); | 568 | M98090_DRCEXP_SHIFT, |
569 | max98090_drcexp_text); | ||
562 | 570 | ||
563 | static const struct soc_enum max98090_dac_perfmode_enum = | 571 | static SOC_ENUM_SINGLE_DECL(max98090_dac_perfmode_enum, |
564 | SOC_ENUM_SINGLE(M98090_REG_DAC_CONTROL, M98090_PERFMODE_SHIFT, | 572 | M98090_REG_DAC_CONTROL, |
565 | ARRAY_SIZE(max98090_perf_pwr_text), max98090_perf_pwr_text); | 573 | M98090_PERFMODE_SHIFT, |
574 | max98090_perf_pwr_text); | ||
566 | 575 | ||
567 | static const struct soc_enum max98090_dachp_enum = | 576 | static SOC_ENUM_SINGLE_DECL(max98090_dachp_enum, |
568 | SOC_ENUM_SINGLE(M98090_REG_DAC_CONTROL, M98090_DACHP_SHIFT, | 577 | M98090_REG_DAC_CONTROL, |
569 | ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); | 578 | M98090_DACHP_SHIFT, |
579 | max98090_pwr_perf_text); | ||
570 | 580 | ||
571 | static const struct soc_enum max98090_adchp_enum = | 581 | static SOC_ENUM_SINGLE_DECL(max98090_adchp_enum, |
572 | SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_ADCHP_SHIFT, | 582 | M98090_REG_ADC_CONTROL, |
573 | ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); | 583 | M98090_ADCHP_SHIFT, |
584 | max98090_pwr_perf_text); | ||
574 | 585 | ||
575 | static const struct snd_kcontrol_new max98090_snd_controls[] = { | 586 | static const struct snd_kcontrol_new max98090_snd_controls[] = { |
576 | SOC_ENUM("MIC Bias VCM Bandgap", max98090_vcmbandgap_enum), | 587 | SOC_ENUM("MIC Bias VCM Bandgap", max98090_vcmbandgap_enum), |
@@ -841,39 +852,42 @@ static int max98090_micinput_event(struct snd_soc_dapm_widget *w, | |||
841 | 852 | ||
842 | static const char *mic1_mux_text[] = { "IN12", "IN56" }; | 853 | static const char *mic1_mux_text[] = { "IN12", "IN56" }; |
843 | 854 | ||
844 | static const struct soc_enum mic1_mux_enum = | 855 | static SOC_ENUM_SINGLE_DECL(mic1_mux_enum, |
845 | SOC_ENUM_SINGLE(M98090_REG_INPUT_MODE, M98090_EXTMIC1_SHIFT, | 856 | M98090_REG_INPUT_MODE, |
846 | ARRAY_SIZE(mic1_mux_text), mic1_mux_text); | 857 | M98090_EXTMIC1_SHIFT, |
858 | mic1_mux_text); | ||
847 | 859 | ||
848 | static const struct snd_kcontrol_new max98090_mic1_mux = | 860 | static const struct snd_kcontrol_new max98090_mic1_mux = |
849 | SOC_DAPM_ENUM("MIC1 Mux", mic1_mux_enum); | 861 | SOC_DAPM_ENUM("MIC1 Mux", mic1_mux_enum); |
850 | 862 | ||
851 | static const char *mic2_mux_text[] = { "IN34", "IN56" }; | 863 | static const char *mic2_mux_text[] = { "IN34", "IN56" }; |
852 | 864 | ||
853 | static const struct soc_enum mic2_mux_enum = | 865 | static SOC_ENUM_SINGLE_DECL(mic2_mux_enum, |
854 | SOC_ENUM_SINGLE(M98090_REG_INPUT_MODE, M98090_EXTMIC2_SHIFT, | 866 | M98090_REG_INPUT_MODE, |
855 | ARRAY_SIZE(mic2_mux_text), mic2_mux_text); | 867 | M98090_EXTMIC2_SHIFT, |
868 | mic2_mux_text); | ||
856 | 869 | ||
857 | static const struct snd_kcontrol_new max98090_mic2_mux = | 870 | static const struct snd_kcontrol_new max98090_mic2_mux = |
858 | SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum); | 871 | SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum); |
859 | 872 | ||
860 | static const char *dmic_mux_text[] = { "ADC", "DMIC" }; | 873 | static const char *dmic_mux_text[] = { "ADC", "DMIC" }; |
861 | 874 | ||
862 | static const struct soc_enum dmic_mux_enum = | 875 | static SOC_ENUM_SINGLE_VIRT_DECL(dmic_mux_enum, dmic_mux_text); |
863 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dmic_mux_text), dmic_mux_text); | ||
864 | 876 | ||
865 | static const struct snd_kcontrol_new max98090_dmic_mux = | 877 | static const struct snd_kcontrol_new max98090_dmic_mux = |
866 | SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum); | 878 | SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum); |
867 | 879 | ||
868 | static const char *max98090_micpre_text[] = { "Off", "On" }; | 880 | static const char *max98090_micpre_text[] = { "Off", "On" }; |
869 | 881 | ||
870 | static const struct soc_enum max98090_pa1en_enum = | 882 | static SOC_ENUM_SINGLE_DECL(max98090_pa1en_enum, |
871 | SOC_ENUM_SINGLE(M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT, | 883 | M98090_REG_MIC1_INPUT_LEVEL, |
872 | ARRAY_SIZE(max98090_micpre_text), max98090_micpre_text); | 884 | M98090_MIC_PA1EN_SHIFT, |
885 | max98090_micpre_text); | ||
873 | 886 | ||
874 | static const struct soc_enum max98090_pa2en_enum = | 887 | static SOC_ENUM_SINGLE_DECL(max98090_pa2en_enum, |
875 | SOC_ENUM_SINGLE(M98090_REG_MIC2_INPUT_LEVEL, M98090_MIC_PA2EN_SHIFT, | 888 | M98090_REG_MIC2_INPUT_LEVEL, |
876 | ARRAY_SIZE(max98090_micpre_text), max98090_micpre_text); | 889 | M98090_MIC_PA2EN_SHIFT, |
890 | max98090_micpre_text); | ||
877 | 891 | ||
878 | /* LINEA mixer switch */ | 892 | /* LINEA mixer switch */ |
879 | static const struct snd_kcontrol_new max98090_linea_mixer_controls[] = { | 893 | static const struct snd_kcontrol_new max98090_linea_mixer_controls[] = { |
@@ -937,13 +951,15 @@ static const struct snd_kcontrol_new max98090_right_adc_mixer_controls[] = { | |||
937 | 951 | ||
938 | static const char *lten_mux_text[] = { "Normal", "Loopthrough" }; | 952 | static const char *lten_mux_text[] = { "Normal", "Loopthrough" }; |
939 | 953 | ||
940 | static const struct soc_enum ltenl_mux_enum = | 954 | static SOC_ENUM_SINGLE_DECL(ltenl_mux_enum, |
941 | SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LTEN_SHIFT, | 955 | M98090_REG_IO_CONFIGURATION, |
942 | ARRAY_SIZE(lten_mux_text), lten_mux_text); | 956 | M98090_LTEN_SHIFT, |
957 | lten_mux_text); | ||
943 | 958 | ||
944 | static const struct soc_enum ltenr_mux_enum = | 959 | static SOC_ENUM_SINGLE_DECL(ltenr_mux_enum, |
945 | SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LTEN_SHIFT, | 960 | M98090_REG_IO_CONFIGURATION, |
946 | ARRAY_SIZE(lten_mux_text), lten_mux_text); | 961 | M98090_LTEN_SHIFT, |
962 | lten_mux_text); | ||
947 | 963 | ||
948 | static const struct snd_kcontrol_new max98090_ltenl_mux = | 964 | static const struct snd_kcontrol_new max98090_ltenl_mux = |
949 | SOC_DAPM_ENUM("LTENL Mux", ltenl_mux_enum); | 965 | SOC_DAPM_ENUM("LTENL Mux", ltenl_mux_enum); |
@@ -953,13 +969,15 @@ static const struct snd_kcontrol_new max98090_ltenr_mux = | |||
953 | 969 | ||
954 | static const char *lben_mux_text[] = { "Normal", "Loopback" }; | 970 | static const char *lben_mux_text[] = { "Normal", "Loopback" }; |
955 | 971 | ||
956 | static const struct soc_enum lbenl_mux_enum = | 972 | static SOC_ENUM_SINGLE_DECL(lbenl_mux_enum, |
957 | SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LBEN_SHIFT, | 973 | M98090_REG_IO_CONFIGURATION, |
958 | ARRAY_SIZE(lben_mux_text), lben_mux_text); | 974 | M98090_LBEN_SHIFT, |
975 | lben_mux_text); | ||
959 | 976 | ||
960 | static const struct soc_enum lbenr_mux_enum = | 977 | static SOC_ENUM_SINGLE_DECL(lbenr_mux_enum, |
961 | SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LBEN_SHIFT, | 978 | M98090_REG_IO_CONFIGURATION, |
962 | ARRAY_SIZE(lben_mux_text), lben_mux_text); | 979 | M98090_LBEN_SHIFT, |
980 | lben_mux_text); | ||
963 | 981 | ||
964 | static const struct snd_kcontrol_new max98090_lbenl_mux = | 982 | static const struct snd_kcontrol_new max98090_lbenl_mux = |
965 | SOC_DAPM_ENUM("LBENL Mux", lbenl_mux_enum); | 983 | SOC_DAPM_ENUM("LBENL Mux", lbenl_mux_enum); |
@@ -971,13 +989,15 @@ static const char *stenl_mux_text[] = { "Normal", "Sidetone Left" }; | |||
971 | 989 | ||
972 | static const char *stenr_mux_text[] = { "Normal", "Sidetone Right" }; | 990 | static const char *stenr_mux_text[] = { "Normal", "Sidetone Right" }; |
973 | 991 | ||
974 | static const struct soc_enum stenl_mux_enum = | 992 | static SOC_ENUM_SINGLE_DECL(stenl_mux_enum, |
975 | SOC_ENUM_SINGLE(M98090_REG_ADC_SIDETONE, M98090_DSTSL_SHIFT, | 993 | M98090_REG_ADC_SIDETONE, |
976 | ARRAY_SIZE(stenl_mux_text), stenl_mux_text); | 994 | M98090_DSTSL_SHIFT, |
995 | stenl_mux_text); | ||
977 | 996 | ||
978 | static const struct soc_enum stenr_mux_enum = | 997 | static SOC_ENUM_SINGLE_DECL(stenr_mux_enum, |
979 | SOC_ENUM_SINGLE(M98090_REG_ADC_SIDETONE, M98090_DSTSR_SHIFT, | 998 | M98090_REG_ADC_SIDETONE, |
980 | ARRAY_SIZE(stenr_mux_text), stenr_mux_text); | 999 | M98090_DSTSR_SHIFT, |
1000 | stenr_mux_text); | ||
981 | 1001 | ||
982 | static const struct snd_kcontrol_new max98090_stenl_mux = | 1002 | static const struct snd_kcontrol_new max98090_stenl_mux = |
983 | SOC_DAPM_ENUM("STENL Mux", stenl_mux_enum); | 1003 | SOC_DAPM_ENUM("STENL Mux", stenl_mux_enum); |
@@ -1085,9 +1105,10 @@ static const struct snd_kcontrol_new max98090_right_rcv_mixer_controls[] = { | |||
1085 | 1105 | ||
1086 | static const char *linmod_mux_text[] = { "Left Only", "Left and Right" }; | 1106 | static const char *linmod_mux_text[] = { "Left Only", "Left and Right" }; |
1087 | 1107 | ||
1088 | static const struct soc_enum linmod_mux_enum = | 1108 | static SOC_ENUM_SINGLE_DECL(linmod_mux_enum, |
1089 | SOC_ENUM_SINGLE(M98090_REG_LOUTR_MIXER, M98090_LINMOD_SHIFT, | 1109 | M98090_REG_LOUTR_MIXER, |
1090 | ARRAY_SIZE(linmod_mux_text), linmod_mux_text); | 1110 | M98090_LINMOD_SHIFT, |
1111 | linmod_mux_text); | ||
1091 | 1112 | ||
1092 | static const struct snd_kcontrol_new max98090_linmod_mux = | 1113 | static const struct snd_kcontrol_new max98090_linmod_mux = |
1093 | SOC_DAPM_ENUM("LINMOD Mux", linmod_mux_enum); | 1114 | SOC_DAPM_ENUM("LINMOD Mux", linmod_mux_enum); |
@@ -1097,16 +1118,18 @@ static const char *mixhpsel_mux_text[] = { "DAC Only", "HP Mixer" }; | |||
1097 | /* | 1118 | /* |
1098 | * This is a mux as it selects the HP output, but to DAPM it is a Mixer enable | 1119 | * This is a mux as it selects the HP output, but to DAPM it is a Mixer enable |
1099 | */ | 1120 | */ |
1100 | static const struct soc_enum mixhplsel_mux_enum = | 1121 | static SOC_ENUM_SINGLE_DECL(mixhplsel_mux_enum, |
1101 | SOC_ENUM_SINGLE(M98090_REG_HP_CONTROL, M98090_MIXHPLSEL_SHIFT, | 1122 | M98090_REG_HP_CONTROL, |
1102 | ARRAY_SIZE(mixhpsel_mux_text), mixhpsel_mux_text); | 1123 | M98090_MIXHPLSEL_SHIFT, |
1124 | mixhpsel_mux_text); | ||
1103 | 1125 | ||
1104 | static const struct snd_kcontrol_new max98090_mixhplsel_mux = | 1126 | static const struct snd_kcontrol_new max98090_mixhplsel_mux = |
1105 | SOC_DAPM_ENUM("MIXHPLSEL Mux", mixhplsel_mux_enum); | 1127 | SOC_DAPM_ENUM("MIXHPLSEL Mux", mixhplsel_mux_enum); |
1106 | 1128 | ||
1107 | static const struct soc_enum mixhprsel_mux_enum = | 1129 | static SOC_ENUM_SINGLE_DECL(mixhprsel_mux_enum, |
1108 | SOC_ENUM_SINGLE(M98090_REG_HP_CONTROL, M98090_MIXHPRSEL_SHIFT, | 1130 | M98090_REG_HP_CONTROL, |
1109 | ARRAY_SIZE(mixhpsel_mux_text), mixhpsel_mux_text); | 1131 | M98090_MIXHPRSEL_SHIFT, |
1132 | mixhpsel_mux_text); | ||
1110 | 1133 | ||
1111 | static const struct snd_kcontrol_new max98090_mixhprsel_mux = | 1134 | static const struct snd_kcontrol_new max98090_mixhprsel_mux = |
1112 | SOC_DAPM_ENUM("MIXHPRSEL Mux", mixhprsel_mux_enum); | 1135 | SOC_DAPM_ENUM("MIXHPRSEL Mux", mixhprsel_mux_enum); |
@@ -1769,16 +1792,6 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec, | |||
1769 | 1792 | ||
1770 | switch (level) { | 1793 | switch (level) { |
1771 | case SND_SOC_BIAS_ON: | 1794 | case SND_SOC_BIAS_ON: |
1772 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
1773 | ret = regcache_sync(max98090->regmap); | ||
1774 | |||
1775 | if (ret != 0) { | ||
1776 | dev_err(codec->dev, | ||
1777 | "Failed to sync cache: %d\n", ret); | ||
1778 | return ret; | ||
1779 | } | ||
1780 | } | ||
1781 | |||
1782 | if (max98090->jack_state == M98090_JACK_STATE_HEADSET) { | 1795 | if (max98090->jack_state == M98090_JACK_STATE_HEADSET) { |
1783 | /* | 1796 | /* |
1784 | * Set to normal bias level. | 1797 | * Set to normal bias level. |
@@ -1792,6 +1805,16 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec, | |||
1792 | break; | 1805 | break; |
1793 | 1806 | ||
1794 | case SND_SOC_BIAS_STANDBY: | 1807 | case SND_SOC_BIAS_STANDBY: |
1808 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
1809 | ret = regcache_sync(max98090->regmap); | ||
1810 | if (ret != 0) { | ||
1811 | dev_err(codec->dev, | ||
1812 | "Failed to sync cache: %d\n", ret); | ||
1813 | return ret; | ||
1814 | } | ||
1815 | } | ||
1816 | break; | ||
1817 | |||
1795 | case SND_SOC_BIAS_OFF: | 1818 | case SND_SOC_BIAS_OFF: |
1796 | /* Set internal pull-up to lowest power mode */ | 1819 | /* Set internal pull-up to lowest power mode */ |
1797 | snd_soc_update_bits(codec, M98090_REG_JACK_DETECT, | 1820 | snd_soc_update_bits(codec, M98090_REG_JACK_DETECT, |
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 3ba1170ebb53..5bce9cde4a6d 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c | |||
@@ -1861,7 +1861,7 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec) | |||
1861 | 1861 | ||
1862 | /* Now point the soc_enum to .texts array items */ | 1862 | /* Now point the soc_enum to .texts array items */ |
1863 | max98095->eq_enum.texts = max98095->eq_texts; | 1863 | max98095->eq_enum.texts = max98095->eq_texts; |
1864 | max98095->eq_enum.max = max98095->eq_textcnt; | 1864 | max98095->eq_enum.items = max98095->eq_textcnt; |
1865 | 1865 | ||
1866 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); | 1866 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); |
1867 | if (ret != 0) | 1867 | if (ret != 0) |
@@ -2016,7 +2016,7 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec) | |||
2016 | 2016 | ||
2017 | /* Now point the soc_enum to .texts array items */ | 2017 | /* Now point the soc_enum to .texts array items */ |
2018 | max98095->bq_enum.texts = max98095->bq_texts; | 2018 | max98095->bq_enum.texts = max98095->bq_texts; |
2019 | max98095->bq_enum.max = max98095->bq_textcnt; | 2019 | max98095->bq_enum.items = max98095->bq_textcnt; |
2020 | 2020 | ||
2021 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); | 2021 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); |
2022 | if (ret != 0) | 2022 | if (ret != 0) |
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 582c2bbd42cb..ec89b8f90a64 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c | |||
@@ -408,8 +408,7 @@ static const char * const adcl_enum_text[] = { | |||
408 | "MC1L", "RXINL", | 408 | "MC1L", "RXINL", |
409 | }; | 409 | }; |
410 | 410 | ||
411 | static const struct soc_enum adcl_enum = | 411 | static SOC_ENUM_SINGLE_VIRT_DECL(adcl_enum, adcl_enum_text); |
412 | SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(adcl_enum_text), adcl_enum_text); | ||
413 | 412 | ||
414 | static const struct snd_kcontrol_new left_input_mux = | 413 | static const struct snd_kcontrol_new left_input_mux = |
415 | SOC_DAPM_ENUM_VIRT("Route", adcl_enum); | 414 | SOC_DAPM_ENUM_VIRT("Route", adcl_enum); |
@@ -418,8 +417,7 @@ static const char * const adcr_enum_text[] = { | |||
418 | "MC1R", "MC2", "RXINR", "TXIN", | 417 | "MC1R", "MC2", "RXINR", "TXIN", |
419 | }; | 418 | }; |
420 | 419 | ||
421 | static const struct soc_enum adcr_enum = | 420 | static SOC_ENUM_SINGLE_VIRT_DECL(adcr_enum, adcr_enum_text); |
422 | SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(adcr_enum_text), adcr_enum_text); | ||
423 | 421 | ||
424 | static const struct snd_kcontrol_new right_input_mux = | 422 | static const struct snd_kcontrol_new right_input_mux = |
425 | SOC_DAPM_ENUM_VIRT("Route", adcr_enum); | 423 | SOC_DAPM_ENUM_VIRT("Route", adcr_enum); |
@@ -430,8 +428,8 @@ static const struct snd_kcontrol_new samp_ctl = | |||
430 | static const char * const speaker_amp_source_text[] = { | 428 | static const char * const speaker_amp_source_text[] = { |
431 | "CODEC", "Right" | 429 | "CODEC", "Right" |
432 | }; | 430 | }; |
433 | static const SOC_ENUM_SINGLE_DECL(speaker_amp_source, MC13783_AUDIO_RX0, 4, | 431 | static SOC_ENUM_SINGLE_DECL(speaker_amp_source, MC13783_AUDIO_RX0, 4, |
434 | speaker_amp_source_text); | 432 | speaker_amp_source_text); |
435 | static const struct snd_kcontrol_new speaker_amp_source_mux = | 433 | static const struct snd_kcontrol_new speaker_amp_source_mux = |
436 | SOC_DAPM_ENUM("Speaker Amp Source MUX", speaker_amp_source); | 434 | SOC_DAPM_ENUM("Speaker Amp Source MUX", speaker_amp_source); |
437 | 435 | ||
@@ -439,8 +437,8 @@ static const char * const headset_amp_source_text[] = { | |||
439 | "CODEC", "Mixer" | 437 | "CODEC", "Mixer" |
440 | }; | 438 | }; |
441 | 439 | ||
442 | static const SOC_ENUM_SINGLE_DECL(headset_amp_source, MC13783_AUDIO_RX0, 11, | 440 | static SOC_ENUM_SINGLE_DECL(headset_amp_source, MC13783_AUDIO_RX0, 11, |
443 | headset_amp_source_text); | 441 | headset_amp_source_text); |
444 | static const struct snd_kcontrol_new headset_amp_source_mux = | 442 | static const struct snd_kcontrol_new headset_amp_source_mux = |
445 | SOC_DAPM_ENUM("Headset Amp Source MUX", headset_amp_source); | 443 | SOC_DAPM_ENUM("Headset Amp Source MUX", headset_amp_source); |
446 | 444 | ||
@@ -580,9 +578,9 @@ static struct snd_soc_dapm_route mc13783_routes[] = { | |||
580 | static const char * const mc13783_3d_mixer[] = {"Stereo", "Phase Mix", | 578 | static const char * const mc13783_3d_mixer[] = {"Stereo", "Phase Mix", |
581 | "Mono", "Mono Mix"}; | 579 | "Mono", "Mono Mix"}; |
582 | 580 | ||
583 | static const struct soc_enum mc13783_enum_3d_mixer = | 581 | static SOC_ENUM_SINGLE_DECL(mc13783_enum_3d_mixer, |
584 | SOC_ENUM_SINGLE(MC13783_AUDIO_RX1, 16, ARRAY_SIZE(mc13783_3d_mixer), | 582 | MC13783_AUDIO_RX1, 16, |
585 | mc13783_3d_mixer); | 583 | mc13783_3d_mixer); |
586 | 584 | ||
587 | static struct snd_kcontrol_new mc13783_control_list[] = { | 585 | static struct snd_kcontrol_new mc13783_control_list[] = { |
588 | SOC_SINGLE("Loudspeaker enable", MC13783_AUDIO_RX0, 5, 1, 0), | 586 | SOC_SINGLE("Loudspeaker enable", MC13783_AUDIO_RX0, 5, 1, 0), |
diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index 73f9c3630e2c..e427544183d7 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c | |||
@@ -172,16 +172,21 @@ static int pcm1681_hw_params(struct snd_pcm_substream *substream, | |||
172 | struct snd_soc_codec *codec = dai->codec; | 172 | struct snd_soc_codec *codec = dai->codec; |
173 | struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); | 173 | struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); |
174 | int val = 0, ret; | 174 | int val = 0, ret; |
175 | int pcm_format = params_format(params); | ||
176 | 175 | ||
177 | priv->rate = params_rate(params); | 176 | priv->rate = params_rate(params); |
178 | 177 | ||
179 | switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { | 178 | switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { |
180 | case SND_SOC_DAIFMT_RIGHT_J: | 179 | case SND_SOC_DAIFMT_RIGHT_J: |
181 | if (pcm_format == SNDRV_PCM_FORMAT_S24_LE) | 180 | switch (params_width(params)) { |
182 | val = 0x00; | 181 | case 24: |
183 | else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE) | 182 | val = 0; |
184 | val = 0x03; | 183 | break; |
184 | case 16: | ||
185 | val = 3; | ||
186 | break; | ||
187 | default: | ||
188 | return -EINVAL; | ||
189 | } | ||
185 | break; | 190 | break; |
186 | case SND_SOC_DAIFMT_I2S: | 191 | case SND_SOC_DAIFMT_I2S: |
187 | val = 0x04; | 192 | val = 0x04; |
diff --git a/sound/soc/codecs/pcm1792a.c b/sound/soc/codecs/pcm1792a.c index 7146653a8e16..3a80ba4452df 100644 --- a/sound/soc/codecs/pcm1792a.c +++ b/sound/soc/codecs/pcm1792a.c | |||
@@ -107,24 +107,35 @@ static int pcm1792a_hw_params(struct snd_pcm_substream *substream, | |||
107 | struct snd_soc_codec *codec = dai->codec; | 107 | struct snd_soc_codec *codec = dai->codec; |
108 | struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec); | 108 | struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec); |
109 | int val = 0, ret; | 109 | int val = 0, ret; |
110 | int pcm_format = params_format(params); | ||
111 | 110 | ||
112 | priv->rate = params_rate(params); | 111 | priv->rate = params_rate(params); |
113 | 112 | ||
114 | switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { | 113 | switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { |
115 | case SND_SOC_DAIFMT_RIGHT_J: | 114 | case SND_SOC_DAIFMT_RIGHT_J: |
116 | if (pcm_format == SNDRV_PCM_FORMAT_S24_LE || | 115 | switch (params_width(params)) { |
117 | pcm_format == SNDRV_PCM_FORMAT_S32_LE) | 116 | case 24: |
118 | val = 0x02; | 117 | case 32: |
119 | else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE) | 118 | val = 2; |
120 | val = 0x00; | 119 | break; |
120 | case 16: | ||
121 | val = 0; | ||
122 | break; | ||
123 | default: | ||
124 | return -EINVAL; | ||
125 | } | ||
121 | break; | 126 | break; |
122 | case SND_SOC_DAIFMT_I2S: | 127 | case SND_SOC_DAIFMT_I2S: |
123 | if (pcm_format == SNDRV_PCM_FORMAT_S24_LE || | 128 | switch (params_width(params)) { |
124 | pcm_format == SNDRV_PCM_FORMAT_S32_LE) | 129 | case 24: |
125 | val = 0x05; | 130 | case 32: |
126 | else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE) | 131 | val = 5; |
127 | val = 0x04; | 132 | break; |
133 | case 16: | ||
134 | val = 4; | ||
135 | break; | ||
136 | default: | ||
137 | return -EINVAL; | ||
138 | } | ||
128 | break; | 139 | break; |
129 | default: | 140 | default: |
130 | dev_err(codec->dev, "Invalid DAI format\n"); | 141 | dev_err(codec->dev, "Invalid DAI format\n"); |
diff --git a/sound/soc/codecs/pcm512x-i2c.c b/sound/soc/codecs/pcm512x-i2c.c new file mode 100644 index 000000000000..4d62230bd378 --- /dev/null +++ b/sound/soc/codecs/pcm512x-i2c.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * Driver for the PCM512x CODECs | ||
3 | * | ||
4 | * Author: Mark Brown <broonie@linaro.org> | ||
5 | * Copyright 2014 Linaro Ltd | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/init.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/i2c.h> | ||
20 | |||
21 | #include "pcm512x.h" | ||
22 | |||
23 | static int pcm512x_i2c_probe(struct i2c_client *i2c, | ||
24 | const struct i2c_device_id *id) | ||
25 | { | ||
26 | struct regmap *regmap; | ||
27 | |||
28 | regmap = devm_regmap_init_i2c(i2c, &pcm512x_regmap); | ||
29 | if (IS_ERR(regmap)) | ||
30 | return PTR_ERR(regmap); | ||
31 | |||
32 | return pcm512x_probe(&i2c->dev, regmap); | ||
33 | } | ||
34 | |||
35 | static int pcm512x_i2c_remove(struct i2c_client *i2c) | ||
36 | { | ||
37 | pcm512x_remove(&i2c->dev); | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static const struct i2c_device_id pcm512x_i2c_id[] = { | ||
42 | { "pcm5121", }, | ||
43 | { "pcm5122", }, | ||
44 | { } | ||
45 | }; | ||
46 | MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id); | ||
47 | |||
48 | static const struct of_device_id pcm512x_of_match[] = { | ||
49 | { .compatible = "ti,pcm5121", }, | ||
50 | { .compatible = "ti,pcm5122", }, | ||
51 | { } | ||
52 | }; | ||
53 | MODULE_DEVICE_TABLE(of, pcm512x_of_match); | ||
54 | |||
55 | static struct i2c_driver pcm512x_i2c_driver = { | ||
56 | .probe = pcm512x_i2c_probe, | ||
57 | .remove = pcm512x_i2c_remove, | ||
58 | .id_table = pcm512x_i2c_id, | ||
59 | .driver = { | ||
60 | .name = "pcm512x", | ||
61 | .owner = THIS_MODULE, | ||
62 | .of_match_table = pcm512x_of_match, | ||
63 | .pm = &pcm512x_pm_ops, | ||
64 | }, | ||
65 | }; | ||
66 | |||
67 | module_i2c_driver(pcm512x_i2c_driver); | ||
68 | |||
69 | MODULE_DESCRIPTION("ASoC PCM512x codec driver - I2C"); | ||
70 | MODULE_AUTHOR("Mark Brown <broonie@linaro.org>"); | ||
71 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/pcm512x-spi.c b/sound/soc/codecs/pcm512x-spi.c new file mode 100644 index 000000000000..f297058c0038 --- /dev/null +++ b/sound/soc/codecs/pcm512x-spi.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Driver for the PCM512x CODECs | ||
3 | * | ||
4 | * Author: Mark Brown <broonie@linaro.org> | ||
5 | * Copyright 2014 Linaro Ltd | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/init.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/spi/spi.h> | ||
20 | |||
21 | #include "pcm512x.h" | ||
22 | |||
23 | static int pcm512x_spi_probe(struct spi_device *spi) | ||
24 | { | ||
25 | struct regmap *regmap; | ||
26 | int ret; | ||
27 | |||
28 | regmap = devm_regmap_init_spi(spi, &pcm512x_regmap); | ||
29 | if (IS_ERR(regmap)) { | ||
30 | ret = PTR_ERR(regmap); | ||
31 | return ret; | ||
32 | } | ||
33 | |||
34 | return pcm512x_probe(&spi->dev, regmap); | ||
35 | } | ||
36 | |||
37 | static int pcm512x_spi_remove(struct spi_device *spi) | ||
38 | { | ||
39 | pcm512x_remove(&spi->dev); | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static const struct spi_device_id pcm512x_spi_id[] = { | ||
44 | { "pcm5121", }, | ||
45 | { "pcm5122", }, | ||
46 | { }, | ||
47 | }; | ||
48 | MODULE_DEVICE_TABLE(spi, pcm512x_spi_id); | ||
49 | |||
50 | static const struct of_device_id pcm512x_of_match[] = { | ||
51 | { .compatible = "ti,pcm5121", }, | ||
52 | { .compatible = "ti,pcm5122", }, | ||
53 | { } | ||
54 | }; | ||
55 | MODULE_DEVICE_TABLE(of, pcm512x_of_match); | ||
56 | |||
57 | static struct spi_driver pcm512x_spi_driver = { | ||
58 | .probe = pcm512x_spi_probe, | ||
59 | .remove = pcm512x_spi_remove, | ||
60 | .id_table = pcm512x_spi_id, | ||
61 | .driver = { | ||
62 | .name = "pcm512x", | ||
63 | .owner = THIS_MODULE, | ||
64 | .of_match_table = pcm512x_of_match, | ||
65 | .pm = &pcm512x_pm_ops, | ||
66 | }, | ||
67 | }; | ||
68 | |||
69 | module_spi_driver(pcm512x_spi_driver); | ||
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c new file mode 100644 index 000000000000..4b4c0c7bb918 --- /dev/null +++ b/sound/soc/codecs/pcm512x.c | |||
@@ -0,0 +1,589 @@ | |||
1 | /* | ||
2 | * Driver for the PCM512x CODECs | ||
3 | * | ||
4 | * Author: Mark Brown <broonie@linaro.org> | ||
5 | * Copyright 2014 Linaro Ltd | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/clk.h> | ||
21 | #include <linux/pm_runtime.h> | ||
22 | #include <linux/regmap.h> | ||
23 | #include <linux/regulator/consumer.h> | ||
24 | #include <sound/soc.h> | ||
25 | #include <sound/soc-dapm.h> | ||
26 | #include <sound/tlv.h> | ||
27 | |||
28 | #include "pcm512x.h" | ||
29 | |||
30 | #define PCM512x_NUM_SUPPLIES 3 | ||
31 | static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = { | ||
32 | "AVDD", | ||
33 | "DVDD", | ||
34 | "CPVDD", | ||
35 | }; | ||
36 | |||
37 | struct pcm512x_priv { | ||
38 | struct regmap *regmap; | ||
39 | struct clk *sclk; | ||
40 | struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES]; | ||
41 | struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES]; | ||
42 | }; | ||
43 | |||
44 | /* | ||
45 | * We can't use the same notifier block for more than one supply and | ||
46 | * there's no way I can see to get from a callback to the caller | ||
47 | * except container_of(). | ||
48 | */ | ||
49 | #define PCM512x_REGULATOR_EVENT(n) \ | ||
50 | static int pcm512x_regulator_event_##n(struct notifier_block *nb, \ | ||
51 | unsigned long event, void *data) \ | ||
52 | { \ | ||
53 | struct pcm512x_priv *pcm512x = container_of(nb, struct pcm512x_priv, \ | ||
54 | supply_nb[n]); \ | ||
55 | if (event & REGULATOR_EVENT_DISABLE) { \ | ||
56 | regcache_mark_dirty(pcm512x->regmap); \ | ||
57 | regcache_cache_only(pcm512x->regmap, true); \ | ||
58 | } \ | ||
59 | return 0; \ | ||
60 | } | ||
61 | |||
62 | PCM512x_REGULATOR_EVENT(0) | ||
63 | PCM512x_REGULATOR_EVENT(1) | ||
64 | PCM512x_REGULATOR_EVENT(2) | ||
65 | |||
66 | static const struct reg_default pcm512x_reg_defaults[] = { | ||
67 | { PCM512x_RESET, 0x00 }, | ||
68 | { PCM512x_POWER, 0x00 }, | ||
69 | { PCM512x_MUTE, 0x00 }, | ||
70 | { PCM512x_DSP, 0x00 }, | ||
71 | { PCM512x_PLL_REF, 0x00 }, | ||
72 | { PCM512x_DAC_ROUTING, 0x11 }, | ||
73 | { PCM512x_DSP_PROGRAM, 0x01 }, | ||
74 | { PCM512x_CLKDET, 0x00 }, | ||
75 | { PCM512x_AUTO_MUTE, 0x00 }, | ||
76 | { PCM512x_ERROR_DETECT, 0x00 }, | ||
77 | { PCM512x_DIGITAL_VOLUME_1, 0x00 }, | ||
78 | { PCM512x_DIGITAL_VOLUME_2, 0x30 }, | ||
79 | { PCM512x_DIGITAL_VOLUME_3, 0x30 }, | ||
80 | { PCM512x_DIGITAL_MUTE_1, 0x22 }, | ||
81 | { PCM512x_DIGITAL_MUTE_2, 0x00 }, | ||
82 | { PCM512x_DIGITAL_MUTE_3, 0x07 }, | ||
83 | { PCM512x_OUTPUT_AMPLITUDE, 0x00 }, | ||
84 | { PCM512x_ANALOG_GAIN_CTRL, 0x00 }, | ||
85 | { PCM512x_UNDERVOLTAGE_PROT, 0x00 }, | ||
86 | { PCM512x_ANALOG_MUTE_CTRL, 0x00 }, | ||
87 | { PCM512x_ANALOG_GAIN_BOOST, 0x00 }, | ||
88 | { PCM512x_VCOM_CTRL_1, 0x00 }, | ||
89 | { PCM512x_VCOM_CTRL_2, 0x01 }, | ||
90 | }; | ||
91 | |||
92 | static bool pcm512x_readable(struct device *dev, unsigned int reg) | ||
93 | { | ||
94 | switch (reg) { | ||
95 | case PCM512x_RESET: | ||
96 | case PCM512x_POWER: | ||
97 | case PCM512x_MUTE: | ||
98 | case PCM512x_PLL_EN: | ||
99 | case PCM512x_SPI_MISO_FUNCTION: | ||
100 | case PCM512x_DSP: | ||
101 | case PCM512x_GPIO_EN: | ||
102 | case PCM512x_BCLK_LRCLK_CFG: | ||
103 | case PCM512x_DSP_GPIO_INPUT: | ||
104 | case PCM512x_MASTER_MODE: | ||
105 | case PCM512x_PLL_REF: | ||
106 | case PCM512x_PLL_COEFF_0: | ||
107 | case PCM512x_PLL_COEFF_1: | ||
108 | case PCM512x_PLL_COEFF_2: | ||
109 | case PCM512x_PLL_COEFF_3: | ||
110 | case PCM512x_PLL_COEFF_4: | ||
111 | case PCM512x_DSP_CLKDIV: | ||
112 | case PCM512x_DAC_CLKDIV: | ||
113 | case PCM512x_NCP_CLKDIV: | ||
114 | case PCM512x_OSR_CLKDIV: | ||
115 | case PCM512x_MASTER_CLKDIV_1: | ||
116 | case PCM512x_MASTER_CLKDIV_2: | ||
117 | case PCM512x_FS_SPEED_MODE: | ||
118 | case PCM512x_IDAC_1: | ||
119 | case PCM512x_IDAC_2: | ||
120 | case PCM512x_ERROR_DETECT: | ||
121 | case PCM512x_I2S_1: | ||
122 | case PCM512x_I2S_2: | ||
123 | case PCM512x_DAC_ROUTING: | ||
124 | case PCM512x_DSP_PROGRAM: | ||
125 | case PCM512x_CLKDET: | ||
126 | case PCM512x_AUTO_MUTE: | ||
127 | case PCM512x_DIGITAL_VOLUME_1: | ||
128 | case PCM512x_DIGITAL_VOLUME_2: | ||
129 | case PCM512x_DIGITAL_VOLUME_3: | ||
130 | case PCM512x_DIGITAL_MUTE_1: | ||
131 | case PCM512x_DIGITAL_MUTE_2: | ||
132 | case PCM512x_DIGITAL_MUTE_3: | ||
133 | case PCM512x_GPIO_OUTPUT_1: | ||
134 | case PCM512x_GPIO_OUTPUT_2: | ||
135 | case PCM512x_GPIO_OUTPUT_3: | ||
136 | case PCM512x_GPIO_OUTPUT_4: | ||
137 | case PCM512x_GPIO_OUTPUT_5: | ||
138 | case PCM512x_GPIO_OUTPUT_6: | ||
139 | case PCM512x_GPIO_CONTROL_1: | ||
140 | case PCM512x_GPIO_CONTROL_2: | ||
141 | case PCM512x_OVERFLOW: | ||
142 | case PCM512x_RATE_DET_1: | ||
143 | case PCM512x_RATE_DET_2: | ||
144 | case PCM512x_RATE_DET_3: | ||
145 | case PCM512x_RATE_DET_4: | ||
146 | case PCM512x_ANALOG_MUTE_DET: | ||
147 | case PCM512x_GPIN: | ||
148 | case PCM512x_DIGITAL_MUTE_DET: | ||
149 | case PCM512x_OUTPUT_AMPLITUDE: | ||
150 | case PCM512x_ANALOG_GAIN_CTRL: | ||
151 | case PCM512x_UNDERVOLTAGE_PROT: | ||
152 | case PCM512x_ANALOG_MUTE_CTRL: | ||
153 | case PCM512x_ANALOG_GAIN_BOOST: | ||
154 | case PCM512x_VCOM_CTRL_1: | ||
155 | case PCM512x_VCOM_CTRL_2: | ||
156 | case PCM512x_CRAM_CTRL: | ||
157 | return true; | ||
158 | default: | ||
159 | /* There are 256 raw register addresses */ | ||
160 | return reg < 0xff; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | static bool pcm512x_volatile(struct device *dev, unsigned int reg) | ||
165 | { | ||
166 | switch (reg) { | ||
167 | case PCM512x_PLL_EN: | ||
168 | case PCM512x_OVERFLOW: | ||
169 | case PCM512x_RATE_DET_1: | ||
170 | case PCM512x_RATE_DET_2: | ||
171 | case PCM512x_RATE_DET_3: | ||
172 | case PCM512x_RATE_DET_4: | ||
173 | case PCM512x_ANALOG_MUTE_DET: | ||
174 | case PCM512x_GPIN: | ||
175 | case PCM512x_DIGITAL_MUTE_DET: | ||
176 | case PCM512x_CRAM_CTRL: | ||
177 | return true; | ||
178 | default: | ||
179 | /* There are 256 raw register addresses */ | ||
180 | return reg < 0xff; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -10350, 50, 1); | ||
185 | static const DECLARE_TLV_DB_SCALE(analog_tlv, -600, 600, 0); | ||
186 | static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0); | ||
187 | |||
188 | static const char * const pcm512x_dsp_program_texts[] = { | ||
189 | "FIR interpolation with de-emphasis", | ||
190 | "Low latency IIR with de-emphasis", | ||
191 | "Fixed process flow", | ||
192 | "High attenuation with de-emphasis", | ||
193 | "Ringing-less low latency FIR", | ||
194 | }; | ||
195 | |||
196 | static const unsigned int pcm512x_dsp_program_values[] = { | ||
197 | 1, | ||
198 | 2, | ||
199 | 3, | ||
200 | 5, | ||
201 | 7, | ||
202 | }; | ||
203 | |||
204 | static SOC_VALUE_ENUM_SINGLE_DECL(pcm512x_dsp_program, | ||
205 | PCM512x_DSP_PROGRAM, 0, 0x1f, | ||
206 | pcm512x_dsp_program_texts, | ||
207 | pcm512x_dsp_program_values); | ||
208 | |||
209 | static const char * const pcm512x_clk_missing_text[] = { | ||
210 | "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s" | ||
211 | }; | ||
212 | |||
213 | static const struct soc_enum pcm512x_clk_missing = | ||
214 | SOC_ENUM_SINGLE(PCM512x_CLKDET, 0, 8, pcm512x_clk_missing_text); | ||
215 | |||
216 | static const char * const pcm512x_autom_text[] = { | ||
217 | "21ms", "106ms", "213ms", "533ms", "1.07s", "2.13s", "5.33s", "10.66s" | ||
218 | }; | ||
219 | |||
220 | static const struct soc_enum pcm512x_autom_l = | ||
221 | SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATML_SHIFT, 8, | ||
222 | pcm512x_autom_text); | ||
223 | |||
224 | static const struct soc_enum pcm512x_autom_r = | ||
225 | SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATMR_SHIFT, 8, | ||
226 | pcm512x_autom_text); | ||
227 | |||
228 | static const char * const pcm512x_ramp_rate_text[] = { | ||
229 | "1 sample/update", "2 samples/update", "4 samples/update", | ||
230 | "Immediate" | ||
231 | }; | ||
232 | |||
233 | static const struct soc_enum pcm512x_vndf = | ||
234 | SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDF_SHIFT, 4, | ||
235 | pcm512x_ramp_rate_text); | ||
236 | |||
237 | static const struct soc_enum pcm512x_vnuf = | ||
238 | SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUF_SHIFT, 4, | ||
239 | pcm512x_ramp_rate_text); | ||
240 | |||
241 | static const struct soc_enum pcm512x_vedf = | ||
242 | SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDF_SHIFT, 4, | ||
243 | pcm512x_ramp_rate_text); | ||
244 | |||
245 | static const char * const pcm512x_ramp_step_text[] = { | ||
246 | "4dB/step", "2dB/step", "1dB/step", "0.5dB/step" | ||
247 | }; | ||
248 | |||
249 | static const struct soc_enum pcm512x_vnds = | ||
250 | SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDS_SHIFT, 4, | ||
251 | pcm512x_ramp_step_text); | ||
252 | |||
253 | static const struct soc_enum pcm512x_vnus = | ||
254 | SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUS_SHIFT, 4, | ||
255 | pcm512x_ramp_step_text); | ||
256 | |||
257 | static const struct soc_enum pcm512x_veds = | ||
258 | SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4, | ||
259 | pcm512x_ramp_step_text); | ||
260 | |||
261 | static const struct snd_kcontrol_new pcm512x_controls[] = { | ||
262 | SOC_DOUBLE_R_TLV("Playback Digital Volume", PCM512x_DIGITAL_VOLUME_2, | ||
263 | PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv), | ||
264 | SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL, | ||
265 | PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), | ||
266 | SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, | ||
267 | PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv), | ||
268 | SOC_DOUBLE("Playback Digital Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, | ||
269 | PCM512x_RQMR_SHIFT, 1, 1), | ||
270 | |||
271 | SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), | ||
272 | SOC_VALUE_ENUM("DSP Program", pcm512x_dsp_program), | ||
273 | |||
274 | SOC_ENUM("Clock Missing Period", pcm512x_clk_missing), | ||
275 | SOC_ENUM("Auto Mute Time Left", pcm512x_autom_l), | ||
276 | SOC_ENUM("Auto Mute Time Right", pcm512x_autom_r), | ||
277 | SOC_SINGLE("Auto Mute Mono Switch", PCM512x_DIGITAL_MUTE_3, | ||
278 | PCM512x_ACTL_SHIFT, 1, 0), | ||
279 | SOC_DOUBLE("Auto Mute Switch", PCM512x_DIGITAL_MUTE_3, PCM512x_AMLE_SHIFT, | ||
280 | PCM512x_AMLR_SHIFT, 1, 0), | ||
281 | |||
282 | SOC_ENUM("Volume Ramp Down Rate", pcm512x_vndf), | ||
283 | SOC_ENUM("Volume Ramp Down Step", pcm512x_vnds), | ||
284 | SOC_ENUM("Volume Ramp Up Rate", pcm512x_vnuf), | ||
285 | SOC_ENUM("Volume Ramp Up Step", pcm512x_vnus), | ||
286 | SOC_ENUM("Volume Ramp Down Emergency Rate", pcm512x_vedf), | ||
287 | SOC_ENUM("Volume Ramp Down Emergency Step", pcm512x_veds), | ||
288 | }; | ||
289 | |||
290 | static const struct snd_soc_dapm_widget pcm512x_dapm_widgets[] = { | ||
291 | SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0), | ||
292 | SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0), | ||
293 | |||
294 | SND_SOC_DAPM_OUTPUT("OUTL"), | ||
295 | SND_SOC_DAPM_OUTPUT("OUTR"), | ||
296 | }; | ||
297 | |||
298 | static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = { | ||
299 | { "DACL", NULL, "Playback" }, | ||
300 | { "DACR", NULL, "Playback" }, | ||
301 | |||
302 | { "OUTL", NULL, "DACL" }, | ||
303 | { "OUTR", NULL, "DACR" }, | ||
304 | }; | ||
305 | |||
306 | static int pcm512x_set_bias_level(struct snd_soc_codec *codec, | ||
307 | enum snd_soc_bias_level level) | ||
308 | { | ||
309 | struct pcm512x_priv *pcm512x = dev_get_drvdata(codec->dev); | ||
310 | int ret; | ||
311 | |||
312 | switch (level) { | ||
313 | case SND_SOC_BIAS_ON: | ||
314 | case SND_SOC_BIAS_PREPARE: | ||
315 | break; | ||
316 | |||
317 | case SND_SOC_BIAS_STANDBY: | ||
318 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, | ||
319 | PCM512x_RQST, 0); | ||
320 | if (ret != 0) { | ||
321 | dev_err(codec->dev, "Failed to remove standby: %d\n", | ||
322 | ret); | ||
323 | return ret; | ||
324 | } | ||
325 | break; | ||
326 | |||
327 | case SND_SOC_BIAS_OFF: | ||
328 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, | ||
329 | PCM512x_RQST, PCM512x_RQST); | ||
330 | if (ret != 0) { | ||
331 | dev_err(codec->dev, "Failed to request standby: %d\n", | ||
332 | ret); | ||
333 | return ret; | ||
334 | } | ||
335 | break; | ||
336 | } | ||
337 | |||
338 | codec->dapm.bias_level = level; | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static struct snd_soc_dai_driver pcm512x_dai = { | ||
344 | .name = "pcm512x-hifi", | ||
345 | .playback = { | ||
346 | .stream_name = "Playback", | ||
347 | .channels_min = 2, | ||
348 | .channels_max = 2, | ||
349 | .rates = SNDRV_PCM_RATE_8000_192000, | ||
350 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | ||
351 | SNDRV_PCM_FMTBIT_S24_LE | | ||
352 | SNDRV_PCM_FMTBIT_S32_LE | ||
353 | }, | ||
354 | }; | ||
355 | |||
356 | static struct snd_soc_codec_driver pcm512x_codec_driver = { | ||
357 | .set_bias_level = pcm512x_set_bias_level, | ||
358 | .idle_bias_off = true, | ||
359 | |||
360 | .controls = pcm512x_controls, | ||
361 | .num_controls = ARRAY_SIZE(pcm512x_controls), | ||
362 | .dapm_widgets = pcm512x_dapm_widgets, | ||
363 | .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets), | ||
364 | .dapm_routes = pcm512x_dapm_routes, | ||
365 | .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes), | ||
366 | }; | ||
367 | |||
368 | static const struct regmap_range_cfg pcm512x_range = { | ||
369 | .name = "Pages", .range_min = PCM512x_VIRT_BASE, | ||
370 | .range_max = PCM512x_MAX_REGISTER, | ||
371 | .selector_reg = PCM512x_PAGE, | ||
372 | .selector_mask = 0xff, | ||
373 | .window_start = 0, .window_len = 0x100, | ||
374 | }; | ||
375 | |||
376 | const struct regmap_config pcm512x_regmap = { | ||
377 | .reg_bits = 8, | ||
378 | .val_bits = 8, | ||
379 | |||
380 | .readable_reg = pcm512x_readable, | ||
381 | .volatile_reg = pcm512x_volatile, | ||
382 | |||
383 | .ranges = &pcm512x_range, | ||
384 | .num_ranges = 1, | ||
385 | |||
386 | .max_register = PCM512x_MAX_REGISTER, | ||
387 | .reg_defaults = pcm512x_reg_defaults, | ||
388 | .num_reg_defaults = ARRAY_SIZE(pcm512x_reg_defaults), | ||
389 | .cache_type = REGCACHE_RBTREE, | ||
390 | }; | ||
391 | EXPORT_SYMBOL_GPL(pcm512x_regmap); | ||
392 | |||
393 | int pcm512x_probe(struct device *dev, struct regmap *regmap) | ||
394 | { | ||
395 | struct pcm512x_priv *pcm512x; | ||
396 | int i, ret; | ||
397 | |||
398 | pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL); | ||
399 | if (!pcm512x) | ||
400 | return -ENOMEM; | ||
401 | |||
402 | dev_set_drvdata(dev, pcm512x); | ||
403 | pcm512x->regmap = regmap; | ||
404 | |||
405 | for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) | ||
406 | pcm512x->supplies[i].supply = pcm512x_supply_names[i]; | ||
407 | |||
408 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pcm512x->supplies), | ||
409 | pcm512x->supplies); | ||
410 | if (ret != 0) { | ||
411 | dev_err(dev, "Failed to get supplies: %d\n", ret); | ||
412 | return ret; | ||
413 | } | ||
414 | |||
415 | pcm512x->supply_nb[0].notifier_call = pcm512x_regulator_event_0; | ||
416 | pcm512x->supply_nb[1].notifier_call = pcm512x_regulator_event_1; | ||
417 | pcm512x->supply_nb[2].notifier_call = pcm512x_regulator_event_2; | ||
418 | |||
419 | for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) { | ||
420 | ret = regulator_register_notifier(pcm512x->supplies[i].consumer, | ||
421 | &pcm512x->supply_nb[i]); | ||
422 | if (ret != 0) { | ||
423 | dev_err(dev, | ||
424 | "Failed to register regulator notifier: %d\n", | ||
425 | ret); | ||
426 | } | ||
427 | } | ||
428 | |||
429 | ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies), | ||
430 | pcm512x->supplies); | ||
431 | if (ret != 0) { | ||
432 | dev_err(dev, "Failed to enable supplies: %d\n", ret); | ||
433 | return ret; | ||
434 | } | ||
435 | |||
436 | /* Reset the device, verifying I/O in the process for I2C */ | ||
437 | ret = regmap_write(regmap, PCM512x_RESET, | ||
438 | PCM512x_RSTM | PCM512x_RSTR); | ||
439 | if (ret != 0) { | ||
440 | dev_err(dev, "Failed to reset device: %d\n", ret); | ||
441 | goto err; | ||
442 | } | ||
443 | |||
444 | ret = regmap_write(regmap, PCM512x_RESET, 0); | ||
445 | if (ret != 0) { | ||
446 | dev_err(dev, "Failed to reset device: %d\n", ret); | ||
447 | goto err; | ||
448 | } | ||
449 | |||
450 | pcm512x->sclk = devm_clk_get(dev, NULL); | ||
451 | if (IS_ERR(pcm512x->sclk)) { | ||
452 | if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) | ||
453 | return -EPROBE_DEFER; | ||
454 | |||
455 | dev_info(dev, "No SCLK, using BCLK: %ld\n", | ||
456 | PTR_ERR(pcm512x->sclk)); | ||
457 | |||
458 | /* Disable reporting of missing SCLK as an error */ | ||
459 | regmap_update_bits(regmap, PCM512x_ERROR_DETECT, | ||
460 | PCM512x_IDCH, PCM512x_IDCH); | ||
461 | |||
462 | /* Switch PLL input to BCLK */ | ||
463 | regmap_update_bits(regmap, PCM512x_PLL_REF, | ||
464 | PCM512x_SREF, PCM512x_SREF); | ||
465 | } else { | ||
466 | ret = clk_prepare_enable(pcm512x->sclk); | ||
467 | if (ret != 0) { | ||
468 | dev_err(dev, "Failed to enable SCLK: %d\n", ret); | ||
469 | return ret; | ||
470 | } | ||
471 | } | ||
472 | |||
473 | /* Default to standby mode */ | ||
474 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, | ||
475 | PCM512x_RQST, PCM512x_RQST); | ||
476 | if (ret != 0) { | ||
477 | dev_err(dev, "Failed to request standby: %d\n", | ||
478 | ret); | ||
479 | goto err_clk; | ||
480 | } | ||
481 | |||
482 | pm_runtime_set_active(dev); | ||
483 | pm_runtime_enable(dev); | ||
484 | pm_runtime_idle(dev); | ||
485 | |||
486 | ret = snd_soc_register_codec(dev, &pcm512x_codec_driver, | ||
487 | &pcm512x_dai, 1); | ||
488 | if (ret != 0) { | ||
489 | dev_err(dev, "Failed to register CODEC: %d\n", ret); | ||
490 | goto err_pm; | ||
491 | } | ||
492 | |||
493 | return 0; | ||
494 | |||
495 | err_pm: | ||
496 | pm_runtime_disable(dev); | ||
497 | err_clk: | ||
498 | if (!IS_ERR(pcm512x->sclk)) | ||
499 | clk_disable_unprepare(pcm512x->sclk); | ||
500 | err: | ||
501 | regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies), | ||
502 | pcm512x->supplies); | ||
503 | return ret; | ||
504 | } | ||
505 | EXPORT_SYMBOL_GPL(pcm512x_probe); | ||
506 | |||
507 | void pcm512x_remove(struct device *dev) | ||
508 | { | ||
509 | struct pcm512x_priv *pcm512x = dev_get_drvdata(dev); | ||
510 | |||
511 | snd_soc_unregister_codec(dev); | ||
512 | pm_runtime_disable(dev); | ||
513 | if (!IS_ERR(pcm512x->sclk)) | ||
514 | clk_disable_unprepare(pcm512x->sclk); | ||
515 | regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies), | ||
516 | pcm512x->supplies); | ||
517 | } | ||
518 | EXPORT_SYMBOL_GPL(pcm512x_remove); | ||
519 | |||
520 | static int pcm512x_suspend(struct device *dev) | ||
521 | { | ||
522 | struct pcm512x_priv *pcm512x = dev_get_drvdata(dev); | ||
523 | int ret; | ||
524 | |||
525 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, | ||
526 | PCM512x_RQPD, PCM512x_RQPD); | ||
527 | if (ret != 0) { | ||
528 | dev_err(dev, "Failed to request power down: %d\n", ret); | ||
529 | return ret; | ||
530 | } | ||
531 | |||
532 | ret = regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies), | ||
533 | pcm512x->supplies); | ||
534 | if (ret != 0) { | ||
535 | dev_err(dev, "Failed to disable supplies: %d\n", ret); | ||
536 | return ret; | ||
537 | } | ||
538 | |||
539 | if (!IS_ERR(pcm512x->sclk)) | ||
540 | clk_disable_unprepare(pcm512x->sclk); | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static int pcm512x_resume(struct device *dev) | ||
546 | { | ||
547 | struct pcm512x_priv *pcm512x = dev_get_drvdata(dev); | ||
548 | int ret; | ||
549 | |||
550 | if (!IS_ERR(pcm512x->sclk)) { | ||
551 | ret = clk_prepare_enable(pcm512x->sclk); | ||
552 | if (ret != 0) { | ||
553 | dev_err(dev, "Failed to enable SCLK: %d\n", ret); | ||
554 | return ret; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies), | ||
559 | pcm512x->supplies); | ||
560 | if (ret != 0) { | ||
561 | dev_err(dev, "Failed to enable supplies: %d\n", ret); | ||
562 | return ret; | ||
563 | } | ||
564 | |||
565 | regcache_cache_only(pcm512x->regmap, false); | ||
566 | ret = regcache_sync(pcm512x->regmap); | ||
567 | if (ret != 0) { | ||
568 | dev_err(dev, "Failed to sync cache: %d\n", ret); | ||
569 | return ret; | ||
570 | } | ||
571 | |||
572 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, | ||
573 | PCM512x_RQPD, 0); | ||
574 | if (ret != 0) { | ||
575 | dev_err(dev, "Failed to remove power down: %d\n", ret); | ||
576 | return ret; | ||
577 | } | ||
578 | |||
579 | return 0; | ||
580 | } | ||
581 | |||
582 | const struct dev_pm_ops pcm512x_pm_ops = { | ||
583 | SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL) | ||
584 | }; | ||
585 | EXPORT_SYMBOL_GPL(pcm512x_pm_ops); | ||
586 | |||
587 | MODULE_DESCRIPTION("ASoC PCM512x codec driver"); | ||
588 | MODULE_AUTHOR("Mark Brown <broonie@linaro.org>"); | ||
589 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/pcm512x.h b/sound/soc/codecs/pcm512x.h new file mode 100644 index 000000000000..6ee76aaca09a --- /dev/null +++ b/sound/soc/codecs/pcm512x.h | |||
@@ -0,0 +1,171 @@ | |||
1 | /* | ||
2 | * Driver for the PCM512x CODECs | ||
3 | * | ||
4 | * Author: Mark Brown <broonie@linaro.org> | ||
5 | * Copyright 2014 Linaro Ltd | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #ifndef _SND_SOC_PCM512X | ||
18 | #define _SND_SOC_PCM512X | ||
19 | |||
20 | #include <linux/pm.h> | ||
21 | #include <linux/regmap.h> | ||
22 | |||
23 | #define PCM512x_VIRT_BASE 0x100 | ||
24 | #define PCM512x_PAGE_LEN 0x100 | ||
25 | #define PCM512x_PAGE_BASE(n) (PCM512x_VIRT_BASE + (PCM512x_PAGE_LEN * n)) | ||
26 | |||
27 | #define PCM512x_PAGE 0 | ||
28 | |||
29 | #define PCM512x_RESET (PCM512x_PAGE_BASE(0) + 1) | ||
30 | #define PCM512x_POWER (PCM512x_PAGE_BASE(0) + 2) | ||
31 | #define PCM512x_MUTE (PCM512x_PAGE_BASE(0) + 3) | ||
32 | #define PCM512x_PLL_EN (PCM512x_PAGE_BASE(0) + 4) | ||
33 | #define PCM512x_SPI_MISO_FUNCTION (PCM512x_PAGE_BASE(0) + 6) | ||
34 | #define PCM512x_DSP (PCM512x_PAGE_BASE(0) + 7) | ||
35 | #define PCM512x_GPIO_EN (PCM512x_PAGE_BASE(0) + 8) | ||
36 | #define PCM512x_BCLK_LRCLK_CFG (PCM512x_PAGE_BASE(0) + 9) | ||
37 | #define PCM512x_DSP_GPIO_INPUT (PCM512x_PAGE_BASE(0) + 10) | ||
38 | #define PCM512x_MASTER_MODE (PCM512x_PAGE_BASE(0) + 12) | ||
39 | #define PCM512x_PLL_REF (PCM512x_PAGE_BASE(0) + 13) | ||
40 | #define PCM512x_PLL_COEFF_0 (PCM512x_PAGE_BASE(0) + 20) | ||
41 | #define PCM512x_PLL_COEFF_1 (PCM512x_PAGE_BASE(0) + 21) | ||
42 | #define PCM512x_PLL_COEFF_2 (PCM512x_PAGE_BASE(0) + 22) | ||
43 | #define PCM512x_PLL_COEFF_3 (PCM512x_PAGE_BASE(0) + 23) | ||
44 | #define PCM512x_PLL_COEFF_4 (PCM512x_PAGE_BASE(0) + 24) | ||
45 | #define PCM512x_DSP_CLKDIV (PCM512x_PAGE_BASE(0) + 27) | ||
46 | #define PCM512x_DAC_CLKDIV (PCM512x_PAGE_BASE(0) + 28) | ||
47 | #define PCM512x_NCP_CLKDIV (PCM512x_PAGE_BASE(0) + 29) | ||
48 | #define PCM512x_OSR_CLKDIV (PCM512x_PAGE_BASE(0) + 30) | ||
49 | #define PCM512x_MASTER_CLKDIV_1 (PCM512x_PAGE_BASE(0) + 32) | ||
50 | #define PCM512x_MASTER_CLKDIV_2 (PCM512x_PAGE_BASE(0) + 33) | ||
51 | #define PCM512x_FS_SPEED_MODE (PCM512x_PAGE_BASE(0) + 34) | ||
52 | #define PCM512x_IDAC_1 (PCM512x_PAGE_BASE(0) + 35) | ||
53 | #define PCM512x_IDAC_2 (PCM512x_PAGE_BASE(0) + 36) | ||
54 | #define PCM512x_ERROR_DETECT (PCM512x_PAGE_BASE(0) + 37) | ||
55 | #define PCM512x_I2S_1 (PCM512x_PAGE_BASE(0) + 40) | ||
56 | #define PCM512x_I2S_2 (PCM512x_PAGE_BASE(0) + 41) | ||
57 | #define PCM512x_DAC_ROUTING (PCM512x_PAGE_BASE(0) + 42) | ||
58 | #define PCM512x_DSP_PROGRAM (PCM512x_PAGE_BASE(0) + 43) | ||
59 | #define PCM512x_CLKDET (PCM512x_PAGE_BASE(0) + 44) | ||
60 | #define PCM512x_AUTO_MUTE (PCM512x_PAGE_BASE(0) + 59) | ||
61 | #define PCM512x_DIGITAL_VOLUME_1 (PCM512x_PAGE_BASE(0) + 60) | ||
62 | #define PCM512x_DIGITAL_VOLUME_2 (PCM512x_PAGE_BASE(0) + 61) | ||
63 | #define PCM512x_DIGITAL_VOLUME_3 (PCM512x_PAGE_BASE(0) + 62) | ||
64 | #define PCM512x_DIGITAL_MUTE_1 (PCM512x_PAGE_BASE(0) + 63) | ||
65 | #define PCM512x_DIGITAL_MUTE_2 (PCM512x_PAGE_BASE(0) + 64) | ||
66 | #define PCM512x_DIGITAL_MUTE_3 (PCM512x_PAGE_BASE(0) + 65) | ||
67 | #define PCM512x_GPIO_OUTPUT_1 (PCM512x_PAGE_BASE(0) + 80) | ||
68 | #define PCM512x_GPIO_OUTPUT_2 (PCM512x_PAGE_BASE(0) + 81) | ||
69 | #define PCM512x_GPIO_OUTPUT_3 (PCM512x_PAGE_BASE(0) + 82) | ||
70 | #define PCM512x_GPIO_OUTPUT_4 (PCM512x_PAGE_BASE(0) + 83) | ||
71 | #define PCM512x_GPIO_OUTPUT_5 (PCM512x_PAGE_BASE(0) + 84) | ||
72 | #define PCM512x_GPIO_OUTPUT_6 (PCM512x_PAGE_BASE(0) + 85) | ||
73 | #define PCM512x_GPIO_CONTROL_1 (PCM512x_PAGE_BASE(0) + 86) | ||
74 | #define PCM512x_GPIO_CONTROL_2 (PCM512x_PAGE_BASE(0) + 87) | ||
75 | #define PCM512x_OVERFLOW (PCM512x_PAGE_BASE(0) + 90) | ||
76 | #define PCM512x_RATE_DET_1 (PCM512x_PAGE_BASE(0) + 91) | ||
77 | #define PCM512x_RATE_DET_2 (PCM512x_PAGE_BASE(0) + 92) | ||
78 | #define PCM512x_RATE_DET_3 (PCM512x_PAGE_BASE(0) + 93) | ||
79 | #define PCM512x_RATE_DET_4 (PCM512x_PAGE_BASE(0) + 94) | ||
80 | #define PCM512x_ANALOG_MUTE_DET (PCM512x_PAGE_BASE(0) + 108) | ||
81 | #define PCM512x_GPIN (PCM512x_PAGE_BASE(0) + 119) | ||
82 | #define PCM512x_DIGITAL_MUTE_DET (PCM512x_PAGE_BASE(0) + 120) | ||
83 | |||
84 | #define PCM512x_OUTPUT_AMPLITUDE (PCM512x_PAGE_BASE(1) + 1) | ||
85 | #define PCM512x_ANALOG_GAIN_CTRL (PCM512x_PAGE_BASE(1) + 2) | ||
86 | #define PCM512x_UNDERVOLTAGE_PROT (PCM512x_PAGE_BASE(1) + 5) | ||
87 | #define PCM512x_ANALOG_MUTE_CTRL (PCM512x_PAGE_BASE(1) + 6) | ||
88 | #define PCM512x_ANALOG_GAIN_BOOST (PCM512x_PAGE_BASE(1) + 7) | ||
89 | #define PCM512x_VCOM_CTRL_1 (PCM512x_PAGE_BASE(1) + 8) | ||
90 | #define PCM512x_VCOM_CTRL_2 (PCM512x_PAGE_BASE(1) + 9) | ||
91 | |||
92 | #define PCM512x_CRAM_CTRL (PCM512x_PAGE_BASE(44) + 1) | ||
93 | |||
94 | #define PCM512x_MAX_REGISTER (PCM512x_PAGE_BASE(44) + 1) | ||
95 | |||
96 | /* Page 0, Register 1 - reset */ | ||
97 | #define PCM512x_RSTR (1 << 0) | ||
98 | #define PCM512x_RSTM (1 << 4) | ||
99 | |||
100 | /* Page 0, Register 2 - power */ | ||
101 | #define PCM512x_RQPD (1 << 0) | ||
102 | #define PCM512x_RQPD_SHIFT 0 | ||
103 | #define PCM512x_RQST (1 << 4) | ||
104 | #define PCM512x_RQST_SHIFT 4 | ||
105 | |||
106 | /* Page 0, Register 3 - mute */ | ||
107 | #define PCM512x_RQMR_SHIFT 0 | ||
108 | #define PCM512x_RQML_SHIFT 4 | ||
109 | |||
110 | /* Page 0, Register 4 - PLL */ | ||
111 | #define PCM512x_PLCE (1 << 0) | ||
112 | #define PCM512x_RLCE_SHIFT 0 | ||
113 | #define PCM512x_PLCK (1 << 4) | ||
114 | #define PCM512x_PLCK_SHIFT 4 | ||
115 | |||
116 | /* Page 0, Register 7 - DSP */ | ||
117 | #define PCM512x_SDSL (1 << 0) | ||
118 | #define PCM512x_SDSL_SHIFT 0 | ||
119 | #define PCM512x_DEMP (1 << 4) | ||
120 | #define PCM512x_DEMP_SHIFT 4 | ||
121 | |||
122 | /* Page 0, Register 13 - PLL reference */ | ||
123 | #define PCM512x_SREF (1 << 4) | ||
124 | |||
125 | /* Page 0, Register 37 - Error detection */ | ||
126 | #define PCM512x_IPLK (1 << 0) | ||
127 | #define PCM512x_DCAS (1 << 1) | ||
128 | #define PCM512x_IDCM (1 << 2) | ||
129 | #define PCM512x_IDCH (1 << 3) | ||
130 | #define PCM512x_IDSK (1 << 4) | ||
131 | #define PCM512x_IDBK (1 << 5) | ||
132 | #define PCM512x_IDFS (1 << 6) | ||
133 | |||
134 | /* Page 0, Register 42 - DAC routing */ | ||
135 | #define PCM512x_AUPR_SHIFT 0 | ||
136 | #define PCM512x_AUPL_SHIFT 4 | ||
137 | |||
138 | /* Page 0, Register 59 - auto mute */ | ||
139 | #define PCM512x_ATMR_SHIFT 0 | ||
140 | #define PCM512x_ATML_SHIFT 4 | ||
141 | |||
142 | /* Page 0, Register 63 - ramp rates */ | ||
143 | #define PCM512x_VNDF_SHIFT 6 | ||
144 | #define PCM512x_VNDS_SHIFT 4 | ||
145 | #define PCM512x_VNUF_SHIFT 2 | ||
146 | #define PCM512x_VNUS_SHIFT 0 | ||
147 | |||
148 | /* Page 0, Register 64 - emergency ramp rates */ | ||
149 | #define PCM512x_VEDF_SHIFT 6 | ||
150 | #define PCM512x_VEDS_SHIFT 4 | ||
151 | |||
152 | /* Page 0, Register 65 - Digital mute enables */ | ||
153 | #define PCM512x_ACTL_SHIFT 2 | ||
154 | #define PCM512x_AMLE_SHIFT 1 | ||
155 | #define PCM512x_AMLR_SHIFT 0 | ||
156 | |||
157 | /* Page 1, Register 2 - analog volume control */ | ||
158 | #define PCM512x_RAGN_SHIFT 0 | ||
159 | #define PCM512x_LAGN_SHIFT 4 | ||
160 | |||
161 | /* Page 1, Register 7 - analog boost control */ | ||
162 | #define PCM512x_AGBR_SHIFT 0 | ||
163 | #define PCM512x_AGBL_SHIFT 4 | ||
164 | |||
165 | extern const struct dev_pm_ops pcm512x_pm_ops; | ||
166 | extern const struct regmap_config pcm512x_regmap; | ||
167 | |||
168 | int pcm512x_probe(struct device *dev, struct regmap *regmap); | ||
169 | void pcm512x_remove(struct device *dev); | ||
170 | |||
171 | #endif | ||
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 912c9cbc2724..ce199d375209 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c | |||
@@ -210,26 +210,22 @@ static int rt5631_dmic_put(struct snd_kcontrol *kcontrol, | |||
210 | static const char *rt5631_input_mode[] = { | 210 | static const char *rt5631_input_mode[] = { |
211 | "Single ended", "Differential"}; | 211 | "Single ended", "Differential"}; |
212 | 212 | ||
213 | static const SOC_ENUM_SINGLE_DECL( | 213 | static SOC_ENUM_SINGLE_DECL(rt5631_mic1_mode_enum, RT5631_MIC_CTRL_1, |
214 | rt5631_mic1_mode_enum, RT5631_MIC_CTRL_1, | 214 | RT5631_MIC1_DIFF_INPUT_SHIFT, rt5631_input_mode); |
215 | RT5631_MIC1_DIFF_INPUT_SHIFT, rt5631_input_mode); | ||
216 | 215 | ||
217 | static const SOC_ENUM_SINGLE_DECL( | 216 | static SOC_ENUM_SINGLE_DECL(rt5631_mic2_mode_enum, RT5631_MIC_CTRL_1, |
218 | rt5631_mic2_mode_enum, RT5631_MIC_CTRL_1, | 217 | RT5631_MIC2_DIFF_INPUT_SHIFT, rt5631_input_mode); |
219 | RT5631_MIC2_DIFF_INPUT_SHIFT, rt5631_input_mode); | ||
220 | 218 | ||
221 | /* MONO Input Type */ | 219 | /* MONO Input Type */ |
222 | static const SOC_ENUM_SINGLE_DECL( | 220 | static SOC_ENUM_SINGLE_DECL(rt5631_monoin_mode_enum, RT5631_MONO_INPUT_VOL, |
223 | rt5631_monoin_mode_enum, RT5631_MONO_INPUT_VOL, | 221 | RT5631_MONO_DIFF_INPUT_SHIFT, rt5631_input_mode); |
224 | RT5631_MONO_DIFF_INPUT_SHIFT, rt5631_input_mode); | ||
225 | 222 | ||
226 | /* SPK Ratio Gain Control */ | 223 | /* SPK Ratio Gain Control */ |
227 | static const char *rt5631_spk_ratio[] = {"1.00x", "1.09x", "1.27x", "1.44x", | 224 | static const char *rt5631_spk_ratio[] = {"1.00x", "1.09x", "1.27x", "1.44x", |
228 | "1.56x", "1.68x", "1.99x", "2.34x"}; | 225 | "1.56x", "1.68x", "1.99x", "2.34x"}; |
229 | 226 | ||
230 | static const SOC_ENUM_SINGLE_DECL( | 227 | static SOC_ENUM_SINGLE_DECL(rt5631_spk_ratio_enum, RT5631_GEN_PUR_CTRL_REG, |
231 | rt5631_spk_ratio_enum, RT5631_GEN_PUR_CTRL_REG, | 228 | RT5631_SPK_AMP_RATIO_CTRL_SHIFT, rt5631_spk_ratio); |
232 | RT5631_SPK_AMP_RATIO_CTRL_SHIFT, rt5631_spk_ratio); | ||
233 | 229 | ||
234 | static const struct snd_kcontrol_new rt5631_snd_controls[] = { | 230 | static const struct snd_kcontrol_new rt5631_snd_controls[] = { |
235 | /* MIC */ | 231 | /* MIC */ |
@@ -759,9 +755,8 @@ static const struct snd_kcontrol_new rt5631_monomix_mixer_controls[] = { | |||
759 | /* Left SPK Volume Input */ | 755 | /* Left SPK Volume Input */ |
760 | static const char *rt5631_spkvoll_sel[] = {"Vmid", "SPKMIXL"}; | 756 | static const char *rt5631_spkvoll_sel[] = {"Vmid", "SPKMIXL"}; |
761 | 757 | ||
762 | static const SOC_ENUM_SINGLE_DECL( | 758 | static SOC_ENUM_SINGLE_DECL(rt5631_spkvoll_enum, RT5631_SPK_OUT_VOL, |
763 | rt5631_spkvoll_enum, RT5631_SPK_OUT_VOL, | 759 | RT5631_L_EN_SHIFT, rt5631_spkvoll_sel); |
764 | RT5631_L_EN_SHIFT, rt5631_spkvoll_sel); | ||
765 | 760 | ||
766 | static const struct snd_kcontrol_new rt5631_spkvoll_mux_control = | 761 | static const struct snd_kcontrol_new rt5631_spkvoll_mux_control = |
767 | SOC_DAPM_ENUM("Left SPKVOL SRC", rt5631_spkvoll_enum); | 762 | SOC_DAPM_ENUM("Left SPKVOL SRC", rt5631_spkvoll_enum); |
@@ -769,9 +764,8 @@ static const struct snd_kcontrol_new rt5631_spkvoll_mux_control = | |||
769 | /* Left HP Volume Input */ | 764 | /* Left HP Volume Input */ |
770 | static const char *rt5631_hpvoll_sel[] = {"Vmid", "OUTMIXL"}; | 765 | static const char *rt5631_hpvoll_sel[] = {"Vmid", "OUTMIXL"}; |
771 | 766 | ||
772 | static const SOC_ENUM_SINGLE_DECL( | 767 | static SOC_ENUM_SINGLE_DECL(rt5631_hpvoll_enum, RT5631_HP_OUT_VOL, |
773 | rt5631_hpvoll_enum, RT5631_HP_OUT_VOL, | 768 | RT5631_L_EN_SHIFT, rt5631_hpvoll_sel); |
774 | RT5631_L_EN_SHIFT, rt5631_hpvoll_sel); | ||
775 | 769 | ||
776 | static const struct snd_kcontrol_new rt5631_hpvoll_mux_control = | 770 | static const struct snd_kcontrol_new rt5631_hpvoll_mux_control = |
777 | SOC_DAPM_ENUM("Left HPVOL SRC", rt5631_hpvoll_enum); | 771 | SOC_DAPM_ENUM("Left HPVOL SRC", rt5631_hpvoll_enum); |
@@ -779,9 +773,8 @@ static const struct snd_kcontrol_new rt5631_hpvoll_mux_control = | |||
779 | /* Left Out Volume Input */ | 773 | /* Left Out Volume Input */ |
780 | static const char *rt5631_outvoll_sel[] = {"Vmid", "OUTMIXL"}; | 774 | static const char *rt5631_outvoll_sel[] = {"Vmid", "OUTMIXL"}; |
781 | 775 | ||
782 | static const SOC_ENUM_SINGLE_DECL( | 776 | static SOC_ENUM_SINGLE_DECL(rt5631_outvoll_enum, RT5631_MONO_AXO_1_2_VOL, |
783 | rt5631_outvoll_enum, RT5631_MONO_AXO_1_2_VOL, | 777 | RT5631_L_EN_SHIFT, rt5631_outvoll_sel); |
784 | RT5631_L_EN_SHIFT, rt5631_outvoll_sel); | ||
785 | 778 | ||
786 | static const struct snd_kcontrol_new rt5631_outvoll_mux_control = | 779 | static const struct snd_kcontrol_new rt5631_outvoll_mux_control = |
787 | SOC_DAPM_ENUM("Left OUTVOL SRC", rt5631_outvoll_enum); | 780 | SOC_DAPM_ENUM("Left OUTVOL SRC", rt5631_outvoll_enum); |
@@ -789,9 +782,8 @@ static const struct snd_kcontrol_new rt5631_outvoll_mux_control = | |||
789 | /* Right Out Volume Input */ | 782 | /* Right Out Volume Input */ |
790 | static const char *rt5631_outvolr_sel[] = {"Vmid", "OUTMIXR"}; | 783 | static const char *rt5631_outvolr_sel[] = {"Vmid", "OUTMIXR"}; |
791 | 784 | ||
792 | static const SOC_ENUM_SINGLE_DECL( | 785 | static SOC_ENUM_SINGLE_DECL(rt5631_outvolr_enum, RT5631_MONO_AXO_1_2_VOL, |
793 | rt5631_outvolr_enum, RT5631_MONO_AXO_1_2_VOL, | 786 | RT5631_R_EN_SHIFT, rt5631_outvolr_sel); |
794 | RT5631_R_EN_SHIFT, rt5631_outvolr_sel); | ||
795 | 787 | ||
796 | static const struct snd_kcontrol_new rt5631_outvolr_mux_control = | 788 | static const struct snd_kcontrol_new rt5631_outvolr_mux_control = |
797 | SOC_DAPM_ENUM("Right OUTVOL SRC", rt5631_outvolr_enum); | 789 | SOC_DAPM_ENUM("Right OUTVOL SRC", rt5631_outvolr_enum); |
@@ -799,9 +791,8 @@ static const struct snd_kcontrol_new rt5631_outvolr_mux_control = | |||
799 | /* Right HP Volume Input */ | 791 | /* Right HP Volume Input */ |
800 | static const char *rt5631_hpvolr_sel[] = {"Vmid", "OUTMIXR"}; | 792 | static const char *rt5631_hpvolr_sel[] = {"Vmid", "OUTMIXR"}; |
801 | 793 | ||
802 | static const SOC_ENUM_SINGLE_DECL( | 794 | static SOC_ENUM_SINGLE_DECL(rt5631_hpvolr_enum, RT5631_HP_OUT_VOL, |
803 | rt5631_hpvolr_enum, RT5631_HP_OUT_VOL, | 795 | RT5631_R_EN_SHIFT, rt5631_hpvolr_sel); |
804 | RT5631_R_EN_SHIFT, rt5631_hpvolr_sel); | ||
805 | 796 | ||
806 | static const struct snd_kcontrol_new rt5631_hpvolr_mux_control = | 797 | static const struct snd_kcontrol_new rt5631_hpvolr_mux_control = |
807 | SOC_DAPM_ENUM("Right HPVOL SRC", rt5631_hpvolr_enum); | 798 | SOC_DAPM_ENUM("Right HPVOL SRC", rt5631_hpvolr_enum); |
@@ -809,9 +800,8 @@ static const struct snd_kcontrol_new rt5631_hpvolr_mux_control = | |||
809 | /* Right SPK Volume Input */ | 800 | /* Right SPK Volume Input */ |
810 | static const char *rt5631_spkvolr_sel[] = {"Vmid", "SPKMIXR"}; | 801 | static const char *rt5631_spkvolr_sel[] = {"Vmid", "SPKMIXR"}; |
811 | 802 | ||
812 | static const SOC_ENUM_SINGLE_DECL( | 803 | static SOC_ENUM_SINGLE_DECL(rt5631_spkvolr_enum, RT5631_SPK_OUT_VOL, |
813 | rt5631_spkvolr_enum, RT5631_SPK_OUT_VOL, | 804 | RT5631_R_EN_SHIFT, rt5631_spkvolr_sel); |
814 | RT5631_R_EN_SHIFT, rt5631_spkvolr_sel); | ||
815 | 805 | ||
816 | static const struct snd_kcontrol_new rt5631_spkvolr_mux_control = | 806 | static const struct snd_kcontrol_new rt5631_spkvolr_mux_control = |
817 | SOC_DAPM_ENUM("Right SPKVOL SRC", rt5631_spkvolr_enum); | 807 | SOC_DAPM_ENUM("Right SPKVOL SRC", rt5631_spkvolr_enum); |
@@ -820,9 +810,8 @@ static const struct snd_kcontrol_new rt5631_spkvolr_mux_control = | |||
820 | static const char *rt5631_spol_src_sel[] = { | 810 | static const char *rt5631_spol_src_sel[] = { |
821 | "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"}; | 811 | "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"}; |
822 | 812 | ||
823 | static const SOC_ENUM_SINGLE_DECL( | 813 | static SOC_ENUM_SINGLE_DECL(rt5631_spol_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, |
824 | rt5631_spol_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | 814 | RT5631_SPK_L_MUX_SEL_SHIFT, rt5631_spol_src_sel); |
825 | RT5631_SPK_L_MUX_SEL_SHIFT, rt5631_spol_src_sel); | ||
826 | 815 | ||
827 | static const struct snd_kcontrol_new rt5631_spol_mux_control = | 816 | static const struct snd_kcontrol_new rt5631_spol_mux_control = |
828 | SOC_DAPM_ENUM("SPOL SRC", rt5631_spol_src_enum); | 817 | SOC_DAPM_ENUM("SPOL SRC", rt5631_spol_src_enum); |
@@ -831,9 +820,8 @@ static const struct snd_kcontrol_new rt5631_spol_mux_control = | |||
831 | static const char *rt5631_spor_src_sel[] = { | 820 | static const char *rt5631_spor_src_sel[] = { |
832 | "SPORMIX", "MONOIN_RX", "VDAC", "DACR"}; | 821 | "SPORMIX", "MONOIN_RX", "VDAC", "DACR"}; |
833 | 822 | ||
834 | static const SOC_ENUM_SINGLE_DECL( | 823 | static SOC_ENUM_SINGLE_DECL(rt5631_spor_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, |
835 | rt5631_spor_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | 824 | RT5631_SPK_R_MUX_SEL_SHIFT, rt5631_spor_src_sel); |
836 | RT5631_SPK_R_MUX_SEL_SHIFT, rt5631_spor_src_sel); | ||
837 | 825 | ||
838 | static const struct snd_kcontrol_new rt5631_spor_mux_control = | 826 | static const struct snd_kcontrol_new rt5631_spor_mux_control = |
839 | SOC_DAPM_ENUM("SPOR SRC", rt5631_spor_src_enum); | 827 | SOC_DAPM_ENUM("SPOR SRC", rt5631_spor_src_enum); |
@@ -841,9 +829,8 @@ static const struct snd_kcontrol_new rt5631_spor_mux_control = | |||
841 | /* MONO Input */ | 829 | /* MONO Input */ |
842 | static const char *rt5631_mono_src_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"}; | 830 | static const char *rt5631_mono_src_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"}; |
843 | 831 | ||
844 | static const SOC_ENUM_SINGLE_DECL( | 832 | static SOC_ENUM_SINGLE_DECL(rt5631_mono_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, |
845 | rt5631_mono_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | 833 | RT5631_MONO_MUX_SEL_SHIFT, rt5631_mono_src_sel); |
846 | RT5631_MONO_MUX_SEL_SHIFT, rt5631_mono_src_sel); | ||
847 | 834 | ||
848 | static const struct snd_kcontrol_new rt5631_mono_mux_control = | 835 | static const struct snd_kcontrol_new rt5631_mono_mux_control = |
849 | SOC_DAPM_ENUM("MONO SRC", rt5631_mono_src_enum); | 836 | SOC_DAPM_ENUM("MONO SRC", rt5631_mono_src_enum); |
@@ -851,9 +838,8 @@ static const struct snd_kcontrol_new rt5631_mono_mux_control = | |||
851 | /* Left HPO Input */ | 838 | /* Left HPO Input */ |
852 | static const char *rt5631_hpl_src_sel[] = {"Left HPVOL", "Left DAC"}; | 839 | static const char *rt5631_hpl_src_sel[] = {"Left HPVOL", "Left DAC"}; |
853 | 840 | ||
854 | static const SOC_ENUM_SINGLE_DECL( | 841 | static SOC_ENUM_SINGLE_DECL(rt5631_hpl_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, |
855 | rt5631_hpl_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | 842 | RT5631_HP_L_MUX_SEL_SHIFT, rt5631_hpl_src_sel); |
856 | RT5631_HP_L_MUX_SEL_SHIFT, rt5631_hpl_src_sel); | ||
857 | 843 | ||
858 | static const struct snd_kcontrol_new rt5631_hpl_mux_control = | 844 | static const struct snd_kcontrol_new rt5631_hpl_mux_control = |
859 | SOC_DAPM_ENUM("HPL SRC", rt5631_hpl_src_enum); | 845 | SOC_DAPM_ENUM("HPL SRC", rt5631_hpl_src_enum); |
@@ -861,9 +847,8 @@ static const struct snd_kcontrol_new rt5631_hpl_mux_control = | |||
861 | /* Right HPO Input */ | 847 | /* Right HPO Input */ |
862 | static const char *rt5631_hpr_src_sel[] = {"Right HPVOL", "Right DAC"}; | 848 | static const char *rt5631_hpr_src_sel[] = {"Right HPVOL", "Right DAC"}; |
863 | 849 | ||
864 | static const SOC_ENUM_SINGLE_DECL( | 850 | static SOC_ENUM_SINGLE_DECL(rt5631_hpr_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, |
865 | rt5631_hpr_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | 851 | RT5631_HP_R_MUX_SEL_SHIFT, rt5631_hpr_src_sel); |
866 | RT5631_HP_R_MUX_SEL_SHIFT, rt5631_hpr_src_sel); | ||
867 | 852 | ||
868 | static const struct snd_kcontrol_new rt5631_hpr_mux_control = | 853 | static const struct snd_kcontrol_new rt5631_hpr_mux_control = |
869 | SOC_DAPM_ENUM("HPR SRC", rt5631_hpr_src_enum); | 854 | SOC_DAPM_ENUM("HPR SRC", rt5631_hpr_src_enum); |
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index a3fb41179636..1a1e1150237d 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c | |||
@@ -361,25 +361,24 @@ static unsigned int bst_tlv[] = { | |||
361 | static const char * const rt5640_data_select[] = { | 361 | static const char * const rt5640_data_select[] = { |
362 | "Normal", "left copy to right", "right copy to left", "Swap"}; | 362 | "Normal", "left copy to right", "right copy to left", "Swap"}; |
363 | 363 | ||
364 | static const SOC_ENUM_SINGLE_DECL(rt5640_if1_dac_enum, RT5640_DIG_INF_DATA, | 364 | static SOC_ENUM_SINGLE_DECL(rt5640_if1_dac_enum, RT5640_DIG_INF_DATA, |
365 | RT5640_IF1_DAC_SEL_SFT, rt5640_data_select); | 365 | RT5640_IF1_DAC_SEL_SFT, rt5640_data_select); |
366 | 366 | ||
367 | static const SOC_ENUM_SINGLE_DECL(rt5640_if1_adc_enum, RT5640_DIG_INF_DATA, | 367 | static SOC_ENUM_SINGLE_DECL(rt5640_if1_adc_enum, RT5640_DIG_INF_DATA, |
368 | RT5640_IF1_ADC_SEL_SFT, rt5640_data_select); | 368 | RT5640_IF1_ADC_SEL_SFT, rt5640_data_select); |
369 | 369 | ||
370 | static const SOC_ENUM_SINGLE_DECL(rt5640_if2_dac_enum, RT5640_DIG_INF_DATA, | 370 | static SOC_ENUM_SINGLE_DECL(rt5640_if2_dac_enum, RT5640_DIG_INF_DATA, |
371 | RT5640_IF2_DAC_SEL_SFT, rt5640_data_select); | 371 | RT5640_IF2_DAC_SEL_SFT, rt5640_data_select); |
372 | 372 | ||
373 | static const SOC_ENUM_SINGLE_DECL(rt5640_if2_adc_enum, RT5640_DIG_INF_DATA, | 373 | static SOC_ENUM_SINGLE_DECL(rt5640_if2_adc_enum, RT5640_DIG_INF_DATA, |
374 | RT5640_IF2_ADC_SEL_SFT, rt5640_data_select); | 374 | RT5640_IF2_ADC_SEL_SFT, rt5640_data_select); |
375 | 375 | ||
376 | /* Class D speaker gain ratio */ | 376 | /* Class D speaker gain ratio */ |
377 | static const char * const rt5640_clsd_spk_ratio[] = {"1.66x", "1.83x", "1.94x", | 377 | static const char * const rt5640_clsd_spk_ratio[] = {"1.66x", "1.83x", "1.94x", |
378 | "2x", "2.11x", "2.22x", "2.33x", "2.44x", "2.55x", "2.66x", "2.77x"}; | 378 | "2x", "2.11x", "2.22x", "2.33x", "2.44x", "2.55x", "2.66x", "2.77x"}; |
379 | 379 | ||
380 | static const SOC_ENUM_SINGLE_DECL( | 380 | static SOC_ENUM_SINGLE_DECL(rt5640_clsd_spk_ratio_enum, RT5640_CLS_D_OUT, |
381 | rt5640_clsd_spk_ratio_enum, RT5640_CLS_D_OUT, | 381 | RT5640_CLSD_RATIO_SFT, rt5640_clsd_spk_ratio); |
382 | RT5640_CLSD_RATIO_SFT, rt5640_clsd_spk_ratio); | ||
383 | 382 | ||
384 | static const struct snd_kcontrol_new rt5640_snd_controls[] = { | 383 | static const struct snd_kcontrol_new rt5640_snd_controls[] = { |
385 | /* Speaker Output Volume */ | 384 | /* Speaker Output Volume */ |
@@ -753,9 +752,8 @@ static const char * const rt5640_stereo_adc1_src[] = { | |||
753 | "DIG MIX", "ADC" | 752 | "DIG MIX", "ADC" |
754 | }; | 753 | }; |
755 | 754 | ||
756 | static const SOC_ENUM_SINGLE_DECL( | 755 | static SOC_ENUM_SINGLE_DECL(rt5640_stereo_adc1_enum, RT5640_STO_ADC_MIXER, |
757 | rt5640_stereo_adc1_enum, RT5640_STO_ADC_MIXER, | 756 | RT5640_ADC_1_SRC_SFT, rt5640_stereo_adc1_src); |
758 | RT5640_ADC_1_SRC_SFT, rt5640_stereo_adc1_src); | ||
759 | 757 | ||
760 | static const struct snd_kcontrol_new rt5640_sto_adc_1_mux = | 758 | static const struct snd_kcontrol_new rt5640_sto_adc_1_mux = |
761 | SOC_DAPM_ENUM("Stereo ADC1 Mux", rt5640_stereo_adc1_enum); | 759 | SOC_DAPM_ENUM("Stereo ADC1 Mux", rt5640_stereo_adc1_enum); |
@@ -764,9 +762,8 @@ static const char * const rt5640_stereo_adc2_src[] = { | |||
764 | "DMIC1", "DMIC2", "DIG MIX" | 762 | "DMIC1", "DMIC2", "DIG MIX" |
765 | }; | 763 | }; |
766 | 764 | ||
767 | static const SOC_ENUM_SINGLE_DECL( | 765 | static SOC_ENUM_SINGLE_DECL(rt5640_stereo_adc2_enum, RT5640_STO_ADC_MIXER, |
768 | rt5640_stereo_adc2_enum, RT5640_STO_ADC_MIXER, | 766 | RT5640_ADC_2_SRC_SFT, rt5640_stereo_adc2_src); |
769 | RT5640_ADC_2_SRC_SFT, rt5640_stereo_adc2_src); | ||
770 | 767 | ||
771 | static const struct snd_kcontrol_new rt5640_sto_adc_2_mux = | 768 | static const struct snd_kcontrol_new rt5640_sto_adc_2_mux = |
772 | SOC_DAPM_ENUM("Stereo ADC2 Mux", rt5640_stereo_adc2_enum); | 769 | SOC_DAPM_ENUM("Stereo ADC2 Mux", rt5640_stereo_adc2_enum); |
@@ -776,9 +773,8 @@ static const char * const rt5640_mono_adc_l1_src[] = { | |||
776 | "Mono DAC MIXL", "ADCL" | 773 | "Mono DAC MIXL", "ADCL" |
777 | }; | 774 | }; |
778 | 775 | ||
779 | static const SOC_ENUM_SINGLE_DECL( | 776 | static SOC_ENUM_SINGLE_DECL(rt5640_mono_adc_l1_enum, RT5640_MONO_ADC_MIXER, |
780 | rt5640_mono_adc_l1_enum, RT5640_MONO_ADC_MIXER, | 777 | RT5640_MONO_ADC_L1_SRC_SFT, rt5640_mono_adc_l1_src); |
781 | RT5640_MONO_ADC_L1_SRC_SFT, rt5640_mono_adc_l1_src); | ||
782 | 778 | ||
783 | static const struct snd_kcontrol_new rt5640_mono_adc_l1_mux = | 779 | static const struct snd_kcontrol_new rt5640_mono_adc_l1_mux = |
784 | SOC_DAPM_ENUM("Mono ADC1 left source", rt5640_mono_adc_l1_enum); | 780 | SOC_DAPM_ENUM("Mono ADC1 left source", rt5640_mono_adc_l1_enum); |
@@ -787,9 +783,8 @@ static const char * const rt5640_mono_adc_l2_src[] = { | |||
787 | "DMIC L1", "DMIC L2", "Mono DAC MIXL" | 783 | "DMIC L1", "DMIC L2", "Mono DAC MIXL" |
788 | }; | 784 | }; |
789 | 785 | ||
790 | static const SOC_ENUM_SINGLE_DECL( | 786 | static SOC_ENUM_SINGLE_DECL(rt5640_mono_adc_l2_enum, RT5640_MONO_ADC_MIXER, |
791 | rt5640_mono_adc_l2_enum, RT5640_MONO_ADC_MIXER, | 787 | RT5640_MONO_ADC_L2_SRC_SFT, rt5640_mono_adc_l2_src); |
792 | RT5640_MONO_ADC_L2_SRC_SFT, rt5640_mono_adc_l2_src); | ||
793 | 788 | ||
794 | static const struct snd_kcontrol_new rt5640_mono_adc_l2_mux = | 789 | static const struct snd_kcontrol_new rt5640_mono_adc_l2_mux = |
795 | SOC_DAPM_ENUM("Mono ADC2 left source", rt5640_mono_adc_l2_enum); | 790 | SOC_DAPM_ENUM("Mono ADC2 left source", rt5640_mono_adc_l2_enum); |
@@ -798,9 +793,8 @@ static const char * const rt5640_mono_adc_r1_src[] = { | |||
798 | "Mono DAC MIXR", "ADCR" | 793 | "Mono DAC MIXR", "ADCR" |
799 | }; | 794 | }; |
800 | 795 | ||
801 | static const SOC_ENUM_SINGLE_DECL( | 796 | static SOC_ENUM_SINGLE_DECL(rt5640_mono_adc_r1_enum, RT5640_MONO_ADC_MIXER, |
802 | rt5640_mono_adc_r1_enum, RT5640_MONO_ADC_MIXER, | 797 | RT5640_MONO_ADC_R1_SRC_SFT, rt5640_mono_adc_r1_src); |
803 | RT5640_MONO_ADC_R1_SRC_SFT, rt5640_mono_adc_r1_src); | ||
804 | 798 | ||
805 | static const struct snd_kcontrol_new rt5640_mono_adc_r1_mux = | 799 | static const struct snd_kcontrol_new rt5640_mono_adc_r1_mux = |
806 | SOC_DAPM_ENUM("Mono ADC1 right source", rt5640_mono_adc_r1_enum); | 800 | SOC_DAPM_ENUM("Mono ADC1 right source", rt5640_mono_adc_r1_enum); |
@@ -809,9 +803,8 @@ static const char * const rt5640_mono_adc_r2_src[] = { | |||
809 | "DMIC R1", "DMIC R2", "Mono DAC MIXR" | 803 | "DMIC R1", "DMIC R2", "Mono DAC MIXR" |
810 | }; | 804 | }; |
811 | 805 | ||
812 | static const SOC_ENUM_SINGLE_DECL( | 806 | static SOC_ENUM_SINGLE_DECL(rt5640_mono_adc_r2_enum, RT5640_MONO_ADC_MIXER, |
813 | rt5640_mono_adc_r2_enum, RT5640_MONO_ADC_MIXER, | 807 | RT5640_MONO_ADC_R2_SRC_SFT, rt5640_mono_adc_r2_src); |
814 | RT5640_MONO_ADC_R2_SRC_SFT, rt5640_mono_adc_r2_src); | ||
815 | 808 | ||
816 | static const struct snd_kcontrol_new rt5640_mono_adc_r2_mux = | 809 | static const struct snd_kcontrol_new rt5640_mono_adc_r2_mux = |
817 | SOC_DAPM_ENUM("Mono ADC2 right source", rt5640_mono_adc_r2_enum); | 810 | SOC_DAPM_ENUM("Mono ADC2 right source", rt5640_mono_adc_r2_enum); |
@@ -826,9 +819,9 @@ static int rt5640_dac_l2_values[] = { | |||
826 | 3, | 819 | 3, |
827 | }; | 820 | }; |
828 | 821 | ||
829 | static const SOC_VALUE_ENUM_SINGLE_DECL( | 822 | static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dac_l2_enum, |
830 | rt5640_dac_l2_enum, RT5640_DSP_PATH2, RT5640_DAC_L2_SEL_SFT, | 823 | RT5640_DSP_PATH2, RT5640_DAC_L2_SEL_SFT, |
831 | 0x3, rt5640_dac_l2_src, rt5640_dac_l2_values); | 824 | 0x3, rt5640_dac_l2_src, rt5640_dac_l2_values); |
832 | 825 | ||
833 | static const struct snd_kcontrol_new rt5640_dac_l2_mux = | 826 | static const struct snd_kcontrol_new rt5640_dac_l2_mux = |
834 | SOC_DAPM_VALUE_ENUM("DAC2 left channel source", rt5640_dac_l2_enum); | 827 | SOC_DAPM_VALUE_ENUM("DAC2 left channel source", rt5640_dac_l2_enum); |
@@ -841,9 +834,9 @@ static int rt5640_dac_r2_values[] = { | |||
841 | 0, | 834 | 0, |
842 | }; | 835 | }; |
843 | 836 | ||
844 | static const SOC_VALUE_ENUM_SINGLE_DECL( | 837 | static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dac_r2_enum, |
845 | rt5640_dac_r2_enum, RT5640_DSP_PATH2, RT5640_DAC_R2_SEL_SFT, | 838 | RT5640_DSP_PATH2, RT5640_DAC_R2_SEL_SFT, |
846 | 0x3, rt5640_dac_r2_src, rt5640_dac_r2_values); | 839 | 0x3, rt5640_dac_r2_src, rt5640_dac_r2_values); |
847 | 840 | ||
848 | static const struct snd_kcontrol_new rt5640_dac_r2_mux = | 841 | static const struct snd_kcontrol_new rt5640_dac_r2_mux = |
849 | SOC_DAPM_ENUM("DAC2 right channel source", rt5640_dac_r2_enum); | 842 | SOC_DAPM_ENUM("DAC2 right channel source", rt5640_dac_r2_enum); |
@@ -860,9 +853,10 @@ static int rt5640_dai_iis_map_values[] = { | |||
860 | 7, | 853 | 7, |
861 | }; | 854 | }; |
862 | 855 | ||
863 | static const SOC_VALUE_ENUM_SINGLE_DECL( | 856 | static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dai_iis_map_enum, |
864 | rt5640_dai_iis_map_enum, RT5640_I2S1_SDP, RT5640_I2S_IF_SFT, | 857 | RT5640_I2S1_SDP, RT5640_I2S_IF_SFT, |
865 | 0x7, rt5640_dai_iis_map, rt5640_dai_iis_map_values); | 858 | 0x7, rt5640_dai_iis_map, |
859 | rt5640_dai_iis_map_values); | ||
866 | 860 | ||
867 | static const struct snd_kcontrol_new rt5640_dai_mux = | 861 | static const struct snd_kcontrol_new rt5640_dai_mux = |
868 | SOC_DAPM_VALUE_ENUM("DAI select", rt5640_dai_iis_map_enum); | 862 | SOC_DAPM_VALUE_ENUM("DAI select", rt5640_dai_iis_map_enum); |
@@ -872,9 +866,8 @@ static const char * const rt5640_sdi_sel[] = { | |||
872 | "IF1", "IF2" | 866 | "IF1", "IF2" |
873 | }; | 867 | }; |
874 | 868 | ||
875 | static const SOC_ENUM_SINGLE_DECL( | 869 | static SOC_ENUM_SINGLE_DECL(rt5640_sdi_sel_enum, RT5640_I2S2_SDP, |
876 | rt5640_sdi_sel_enum, RT5640_I2S2_SDP, | 870 | RT5640_I2S2_SDI_SFT, rt5640_sdi_sel); |
877 | RT5640_I2S2_SDI_SFT, rt5640_sdi_sel); | ||
878 | 871 | ||
879 | static const struct snd_kcontrol_new rt5640_sdi_mux = | 872 | static const struct snd_kcontrol_new rt5640_sdi_mux = |
880 | SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); | 873 | SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); |
@@ -2093,6 +2086,7 @@ MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id); | |||
2093 | #ifdef CONFIG_ACPI | 2086 | #ifdef CONFIG_ACPI |
2094 | static struct acpi_device_id rt5640_acpi_match[] = { | 2087 | static struct acpi_device_id rt5640_acpi_match[] = { |
2095 | { "INT33CA", 0 }, | 2088 | { "INT33CA", 0 }, |
2089 | { "10EC5640", 0 }, | ||
2096 | { }, | 2090 | { }, |
2097 | }; | 2091 | }; |
2098 | MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match); | 2092 | MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match); |
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 52e7cb08434b..fa2b8e07f420 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c | |||
@@ -210,7 +210,7 @@ out: | |||
210 | static int si476x_codec_probe(struct snd_soc_codec *codec) | 210 | static int si476x_codec_probe(struct snd_soc_codec *codec) |
211 | { | 211 | { |
212 | codec->control_data = dev_get_regmap(codec->dev->parent, NULL); | 212 | codec->control_data = dev_get_regmap(codec->dev->parent, NULL); |
213 | return 0; | 213 | return snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); |
214 | } | 214 | } |
215 | 215 | ||
216 | static struct snd_soc_dai_ops si476x_dai_ops = { | 216 | static struct snd_soc_dai_ops si476x_dai_ops = { |
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index cc8debce752f..806f3d826ffb 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c | |||
@@ -169,19 +169,19 @@ static const char * const ssm2518_drc_hold_time_text[] = { | |||
169 | "682.24 ms", "1364 ms", | 169 | "682.24 ms", "1364 ms", |
170 | }; | 170 | }; |
171 | 171 | ||
172 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_attack_time_enum, | 172 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_attack_time_enum, |
173 | SSM2518_REG_DRC_2, 4, ssm2518_drc_peak_detector_attack_time_text); | 173 | SSM2518_REG_DRC_2, 4, ssm2518_drc_peak_detector_attack_time_text); |
174 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_release_time_enum, | 174 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_release_time_enum, |
175 | SSM2518_REG_DRC_2, 0, ssm2518_drc_peak_detector_release_time_text); | 175 | SSM2518_REG_DRC_2, 0, ssm2518_drc_peak_detector_release_time_text); |
176 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_attack_time_enum, | 176 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_attack_time_enum, |
177 | SSM2518_REG_DRC_6, 4, ssm2518_drc_peak_detector_attack_time_text); | 177 | SSM2518_REG_DRC_6, 4, ssm2518_drc_peak_detector_attack_time_text); |
178 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_decay_time_enum, | 178 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_decay_time_enum, |
179 | SSM2518_REG_DRC_6, 0, ssm2518_drc_peak_detector_release_time_text); | 179 | SSM2518_REG_DRC_6, 0, ssm2518_drc_peak_detector_release_time_text); |
180 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_hold_time_enum, | 180 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_hold_time_enum, |
181 | SSM2518_REG_DRC_7, 4, ssm2518_drc_hold_time_text); | 181 | SSM2518_REG_DRC_7, 4, ssm2518_drc_hold_time_text); |
182 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_noise_gate_hold_time_enum, | 182 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_noise_gate_hold_time_enum, |
183 | SSM2518_REG_DRC_7, 0, ssm2518_drc_hold_time_text); | 183 | SSM2518_REG_DRC_7, 0, ssm2518_drc_hold_time_text); |
184 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_rms_averaging_time_enum, | 184 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_rms_averaging_time_enum, |
185 | SSM2518_REG_DRC_9, 0, ssm2518_drc_peak_detector_release_time_text); | 185 | SSM2518_REG_DRC_9, 0, ssm2518_drc_peak_detector_release_time_text); |
186 | 186 | ||
187 | static const struct snd_kcontrol_new ssm2518_snd_controls[] = { | 187 | static const struct snd_kcontrol_new ssm2518_snd_controls[] = { |
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 06edb396e733..2735361a4c3c 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c | |||
@@ -187,42 +187,42 @@ static const unsigned int sta32x_limiter_drc_release_tlv[] = { | |||
187 | 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), | 187 | 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), |
188 | }; | 188 | }; |
189 | 189 | ||
190 | static const struct soc_enum sta32x_drc_ac_enum = | 190 | static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum, |
191 | SOC_ENUM_SINGLE(STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, | 191 | STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, |
192 | 2, sta32x_drc_ac); | 192 | sta32x_drc_ac); |
193 | static const struct soc_enum sta32x_auto_eq_enum = | 193 | static SOC_ENUM_SINGLE_DECL(sta32x_auto_eq_enum, |
194 | SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT, | 194 | STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT, |
195 | 3, sta32x_auto_eq_mode); | 195 | sta32x_auto_eq_mode); |
196 | static const struct soc_enum sta32x_auto_gc_enum = | 196 | static SOC_ENUM_SINGLE_DECL(sta32x_auto_gc_enum, |
197 | SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT, | 197 | STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT, |
198 | 4, sta32x_auto_gc_mode); | 198 | sta32x_auto_gc_mode); |
199 | static const struct soc_enum sta32x_auto_xo_enum = | 199 | static SOC_ENUM_SINGLE_DECL(sta32x_auto_xo_enum, |
200 | SOC_ENUM_SINGLE(STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT, | 200 | STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT, |
201 | 16, sta32x_auto_xo_mode); | 201 | sta32x_auto_xo_mode); |
202 | static const struct soc_enum sta32x_preset_eq_enum = | 202 | static SOC_ENUM_SINGLE_DECL(sta32x_preset_eq_enum, |
203 | SOC_ENUM_SINGLE(STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT, | 203 | STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT, |
204 | 32, sta32x_preset_eq_mode); | 204 | sta32x_preset_eq_mode); |
205 | static const struct soc_enum sta32x_limiter_ch1_enum = | 205 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch1_enum, |
206 | SOC_ENUM_SINGLE(STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT, | 206 | STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT, |
207 | 3, sta32x_limiter_select); | 207 | sta32x_limiter_select); |
208 | static const struct soc_enum sta32x_limiter_ch2_enum = | 208 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch2_enum, |
209 | SOC_ENUM_SINGLE(STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT, | 209 | STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT, |
210 | 3, sta32x_limiter_select); | 210 | sta32x_limiter_select); |
211 | static const struct soc_enum sta32x_limiter_ch3_enum = | 211 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch3_enum, |
212 | SOC_ENUM_SINGLE(STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT, | 212 | STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT, |
213 | 3, sta32x_limiter_select); | 213 | sta32x_limiter_select); |
214 | static const struct soc_enum sta32x_limiter1_attack_rate_enum = | 214 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_attack_rate_enum, |
215 | SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxA_SHIFT, | 215 | STA32X_L1AR, STA32X_LxA_SHIFT, |
216 | 16, sta32x_limiter_attack_rate); | 216 | sta32x_limiter_attack_rate); |
217 | static const struct soc_enum sta32x_limiter2_attack_rate_enum = | 217 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_attack_rate_enum, |
218 | SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxA_SHIFT, | 218 | STA32X_L2AR, STA32X_LxA_SHIFT, |
219 | 16, sta32x_limiter_attack_rate); | 219 | sta32x_limiter_attack_rate); |
220 | static const struct soc_enum sta32x_limiter1_release_rate_enum = | 220 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_release_rate_enum, |
221 | SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxR_SHIFT, | 221 | STA32X_L1AR, STA32X_LxR_SHIFT, |
222 | 16, sta32x_limiter_release_rate); | 222 | sta32x_limiter_release_rate); |
223 | static const struct soc_enum sta32x_limiter2_release_rate_enum = | 223 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_release_rate_enum, |
224 | SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxR_SHIFT, | 224 | STA32X_L2AR, STA32X_LxR_SHIFT, |
225 | 16, sta32x_limiter_release_rate); | 225 | sta32x_limiter_release_rate); |
226 | 226 | ||
227 | /* byte array controls for setting biquad, mixer, scaling coefficients; | 227 | /* byte array controls for setting biquad, mixer, scaling coefficients; |
228 | * for biquads all five coefficients need to be set in one go, | 228 | * for biquads all five coefficients need to be set in one go, |
@@ -331,7 +331,7 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec) | |||
331 | 331 | ||
332 | static int sta32x_cache_sync(struct snd_soc_codec *codec) | 332 | static int sta32x_cache_sync(struct snd_soc_codec *codec) |
333 | { | 333 | { |
334 | struct sta32x_priv *sta32x = codec->control_data; | 334 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); |
335 | unsigned int mute; | 335 | unsigned int mute; |
336 | int rc; | 336 | int rc; |
337 | 337 | ||
@@ -434,7 +434,7 @@ SOC_SINGLE_TLV("Treble Tone Control", STA32X_TONE, STA32X_TONE_TTC_SHIFT, 15, 0, | |||
434 | SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum), | 434 | SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum), |
435 | SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum), | 435 | SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum), |
436 | SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), | 436 | SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), |
437 | SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), | 437 | SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter2_release_rate_enum), |
438 | 438 | ||
439 | /* depending on mode, the attack/release thresholds have | 439 | /* depending on mode, the attack/release thresholds have |
440 | * two different enum definitions; provide both | 440 | * two different enum definitions; provide both |
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index 40c07be9b581..f15b0e37274c 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c | |||
@@ -141,7 +141,7 @@ static const char *pwm_mode_text[] = { "Binary", "Headphone", "Ternary", | |||
141 | 141 | ||
142 | static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -9150, 50, 0); | 142 | static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -9150, 50, 0); |
143 | static const DECLARE_TLV_DB_SCALE(master_vol_tlv, -12750, 50, 0); | 143 | static const DECLARE_TLV_DB_SCALE(master_vol_tlv, -12750, 50, 0); |
144 | static const SOC_ENUM_SINGLE_DECL(pwm_src, STA529_FFXCFG1, 4, pwm_mode_text); | 144 | static SOC_ENUM_SINGLE_DECL(pwm_src, STA529_FFXCFG1, 4, pwm_mode_text); |
145 | 145 | ||
146 | static const struct snd_kcontrol_new sta529_snd_controls[] = { | 146 | static const struct snd_kcontrol_new sta529_snd_controls[] = { |
147 | SOC_DOUBLE_R_TLV("Digital Playback Volume", STA529_LVOL, STA529_RVOL, 0, | 147 | SOC_DOUBLE_R_TLV("Digital Playback Volume", STA529_LVOL, STA529_RVOL, 0, |
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 5d430cc56f51..458a6aed203e 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c | |||
@@ -400,7 +400,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream, | |||
400 | struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); | 400 | struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); |
401 | 401 | ||
402 | /* deactivate */ | 402 | /* deactivate */ |
403 | if (!codec->active) { | 403 | if (!snd_soc_codec_is_active(codec)) { |
404 | udelay(50); | 404 | udelay(50); |
405 | snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); | 405 | snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); |
406 | } | 406 | } |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 4f358393d6d6..35b2d244e42e 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -461,7 +461,7 @@ static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol, | |||
461 | if (dac33->fifo_mode == ucontrol->value.integer.value[0]) | 461 | if (dac33->fifo_mode == ucontrol->value.integer.value[0]) |
462 | return 0; | 462 | return 0; |
463 | /* Do not allow changes while stream is running*/ | 463 | /* Do not allow changes while stream is running*/ |
464 | if (codec->active) | 464 | if (snd_soc_codec_is_active(codec)) |
465 | return -EPERM; | 465 | return -EPERM; |
466 | 466 | ||
467 | if (ucontrol->value.integer.value[0] < 0 || | 467 | if (ucontrol->value.integer.value[0] < 0 || |
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 00665ada23e2..682e4ac88939 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -965,9 +965,6 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, | |||
965 | { | 965 | { |
966 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 966 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
967 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 967 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
968 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
969 | unsigned short val; | ||
970 | unsigned short mask; | ||
971 | 968 | ||
972 | if (twl4030->configured) { | 969 | if (twl4030->configured) { |
973 | dev_err(codec->dev, | 970 | dev_err(codec->dev, |
@@ -975,19 +972,7 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, | |||
975 | return -EBUSY; | 972 | return -EBUSY; |
976 | } | 973 | } |
977 | 974 | ||
978 | if (ucontrol->value.enumerated.item[0] > e->max - 1) | 975 | return snd_soc_put_enum_double(kcontrol, ucontrol); |
979 | return -EINVAL; | ||
980 | |||
981 | val = ucontrol->value.enumerated.item[0] << e->shift_l; | ||
982 | mask = e->mask << e->shift_l; | ||
983 | if (e->shift_l != e->shift_r) { | ||
984 | if (ucontrol->value.enumerated.item[1] > e->max - 1) | ||
985 | return -EINVAL; | ||
986 | val |= ucontrol->value.enumerated.item[1] << e->shift_r; | ||
987 | mask |= e->mask << e->shift_r; | ||
988 | } | ||
989 | |||
990 | return snd_soc_update_bits(codec, e->reg, mask, val); | ||
991 | } | 976 | } |
992 | 977 | ||
993 | /* | 978 | /* |
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 726df6d43c2b..8e3940dcff20 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c | |||
@@ -108,7 +108,7 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, | |||
108 | /* the interpolator & decimator regs must only be written when the | 108 | /* the interpolator & decimator regs must only be written when the |
109 | * codec DAI is active. | 109 | * codec DAI is active. |
110 | */ | 110 | */ |
111 | if (!codec->active && (reg >= UDA1380_MVOL)) | 111 | if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL)) |
112 | return 0; | 112 | return 0; |
113 | pr_debug("uda1380: hw write %x val %x\n", reg, value); | 113 | pr_debug("uda1380: hw write %x val %x\n", reg, value); |
114 | if (codec->hw_write(codec->control_data, data, 3) == 3) { | 114 | if (codec->hw_write(codec->control_data, data, 3) == 3) { |
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index b7ab2ef567c8..47e96ff30064 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c | |||
@@ -197,7 +197,7 @@ static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol, | |||
197 | return 0; | 197 | return 0; |
198 | 198 | ||
199 | /* Do not allow changes while stream is running */ | 199 | /* Do not allow changes while stream is running */ |
200 | if (codec->active) | 200 | if (snd_soc_codec_is_active(codec)) |
201 | return -EPERM; | 201 | return -EPERM; |
202 | 202 | ||
203 | if (ucontrol->value.integer.value[0] < 0 || | 203 | if (ucontrol->value.integer.value[0] < 0 || |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 4e3e31aaf509..492fe846ae68 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -2100,6 +2100,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100) | |||
2100 | int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | 2100 | int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) |
2101 | { | 2101 | { |
2102 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | 2102 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); |
2103 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
2103 | 2104 | ||
2104 | if (jack) { | 2105 | if (jack) { |
2105 | wm5100->jack = jack; | 2106 | wm5100->jack = jack; |
@@ -2117,9 +2118,14 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | |||
2117 | WM5100_ACCDET_RATE_MASK); | 2118 | WM5100_ACCDET_RATE_MASK); |
2118 | 2119 | ||
2119 | /* We need the charge pump to power MICBIAS */ | 2120 | /* We need the charge pump to power MICBIAS */ |
2120 | snd_soc_dapm_force_enable_pin(&codec->dapm, "CP2"); | 2121 | snd_soc_dapm_mutex_lock(dapm); |
2121 | snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); | 2122 | |
2122 | snd_soc_dapm_sync(&codec->dapm); | 2123 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "CP2"); |
2124 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK"); | ||
2125 | |||
2126 | snd_soc_dapm_sync_unlocked(dapm); | ||
2127 | |||
2128 | snd_soc_dapm_mutex_unlock(dapm); | ||
2123 | 2129 | ||
2124 | /* We start off just enabling microphone detection - even a | 2130 | /* We start off just enabling microphone detection - even a |
2125 | * plain headphone will trigger detection. | 2131 | * plain headphone will trigger detection. |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index ce9c8e14d4bd..34109050ceed 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -582,7 +582,7 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, | |||
582 | { | 582 | { |
583 | struct snd_soc_codec *codec = w->codec; | 583 | struct snd_soc_codec *codec = w->codec; |
584 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | 584 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); |
585 | struct regmap *regmap = codec->control_data; | 585 | struct regmap *regmap = arizona->regmap; |
586 | const struct reg_default *patch = NULL; | 586 | const struct reg_default *patch = NULL; |
587 | int i, patch_size; | 587 | int i, patch_size; |
588 | 588 | ||
@@ -622,13 +622,16 @@ static const unsigned int wm5102_osr_val[] = { | |||
622 | 622 | ||
623 | static const struct soc_enum wm5102_hpout_osr[] = { | 623 | static const struct soc_enum wm5102_hpout_osr[] = { |
624 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, | 624 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, |
625 | ARIZONA_OUT1_OSR_SHIFT, 0x7, 3, | 625 | ARIZONA_OUT1_OSR_SHIFT, 0x7, |
626 | ARRAY_SIZE(wm5102_osr_text), | ||
626 | wm5102_osr_text, wm5102_osr_val), | 627 | wm5102_osr_text, wm5102_osr_val), |
627 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L, | 628 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L, |
628 | ARIZONA_OUT2_OSR_SHIFT, 0x7, 3, | 629 | ARIZONA_OUT2_OSR_SHIFT, 0x7, |
630 | ARRAY_SIZE(wm5102_osr_text), | ||
629 | wm5102_osr_text, wm5102_osr_val), | 631 | wm5102_osr_text, wm5102_osr_val), |
630 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, | 632 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, |
631 | ARIZONA_OUT3_OSR_SHIFT, 0x7, 3, | 633 | ARIZONA_OUT3_OSR_SHIFT, 0x7, |
634 | ARRAY_SIZE(wm5102_osr_text), | ||
632 | wm5102_osr_text, wm5102_osr_val), | 635 | wm5102_osr_text, wm5102_osr_val), |
633 | }; | 636 | }; |
634 | 637 | ||
@@ -685,15 +688,8 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), | |||
685 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), | 688 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), |
686 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), | 689 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), |
687 | 690 | ||
688 | SND_SOC_BYTES_MASK("EQ1 Coefficients", ARIZONA_EQ1_1, 21, | 691 | SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19), |
689 | ARIZONA_EQ1_ENA_MASK), | 692 | SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE, 1, 0), |
690 | SND_SOC_BYTES_MASK("EQ2 Coefficients", ARIZONA_EQ2_1, 21, | ||
691 | ARIZONA_EQ2_ENA_MASK), | ||
692 | SND_SOC_BYTES_MASK("EQ3 Coefficients", ARIZONA_EQ3_1, 21, | ||
693 | ARIZONA_EQ3_ENA_MASK), | ||
694 | SND_SOC_BYTES_MASK("EQ4 Coefficients", ARIZONA_EQ4_1, 21, | ||
695 | ARIZONA_EQ4_ENA_MASK), | ||
696 | |||
697 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, | 693 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, |
698 | 24, 0, eq_tlv), | 694 | 24, 0, eq_tlv), |
699 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, | 695 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, |
@@ -705,6 +701,8 @@ SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT, | |||
705 | SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, | 701 | SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, |
706 | 24, 0, eq_tlv), | 702 | 24, 0, eq_tlv), |
707 | 703 | ||
704 | SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19), | ||
705 | SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE, 1, 0), | ||
708 | SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, | 706 | SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, |
709 | 24, 0, eq_tlv), | 707 | 24, 0, eq_tlv), |
710 | SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, | 708 | SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, |
@@ -716,6 +714,8 @@ SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT, | |||
716 | SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, | 714 | SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, |
717 | 24, 0, eq_tlv), | 715 | 24, 0, eq_tlv), |
718 | 716 | ||
717 | SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19), | ||
718 | SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE, 1, 0), | ||
719 | SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, | 719 | SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, |
720 | 24, 0, eq_tlv), | 720 | 24, 0, eq_tlv), |
721 | SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, | 721 | SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, |
@@ -727,6 +727,8 @@ SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT, | |||
727 | SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, | 727 | SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, |
728 | 24, 0, eq_tlv), | 728 | 24, 0, eq_tlv), |
729 | 729 | ||
730 | SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19), | ||
731 | SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE, 1, 0), | ||
730 | SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, | 732 | SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, |
731 | 24, 0, eq_tlv), | 733 | 24, 0, eq_tlv), |
732 | SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, | 734 | SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, |
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 2c3c962d9a85..d7bf8848174a 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -136,7 +136,7 @@ static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w, | |||
136 | { | 136 | { |
137 | struct snd_soc_codec *codec = w->codec; | 137 | struct snd_soc_codec *codec = w->codec; |
138 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | 138 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); |
139 | struct regmap *regmap = codec->control_data; | 139 | struct regmap *regmap = arizona->regmap; |
140 | const struct reg_default *patch = NULL; | 140 | const struct reg_default *patch = NULL; |
141 | int i, patch_size; | 141 | int i, patch_size; |
142 | 142 | ||
@@ -247,15 +247,8 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), | |||
247 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), | 247 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), |
248 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), | 248 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), |
249 | 249 | ||
250 | SND_SOC_BYTES_MASK("EQ1 Coefficients", ARIZONA_EQ1_1, 21, | 250 | SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19), |
251 | ARIZONA_EQ1_ENA_MASK), | 251 | SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE, 1, 0), |
252 | SND_SOC_BYTES_MASK("EQ2 Coefficients", ARIZONA_EQ2_1, 21, | ||
253 | ARIZONA_EQ2_ENA_MASK), | ||
254 | SND_SOC_BYTES_MASK("EQ3 Coefficients", ARIZONA_EQ3_1, 21, | ||
255 | ARIZONA_EQ3_ENA_MASK), | ||
256 | SND_SOC_BYTES_MASK("EQ4 Coefficients", ARIZONA_EQ4_1, 21, | ||
257 | ARIZONA_EQ4_ENA_MASK), | ||
258 | |||
259 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, | 252 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, |
260 | 24, 0, eq_tlv), | 253 | 24, 0, eq_tlv), |
261 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, | 254 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, |
@@ -267,6 +260,8 @@ SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT, | |||
267 | SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, | 260 | SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, |
268 | 24, 0, eq_tlv), | 261 | 24, 0, eq_tlv), |
269 | 262 | ||
263 | SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19), | ||
264 | SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE, 1, 0), | ||
270 | SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, | 265 | SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, |
271 | 24, 0, eq_tlv), | 266 | 24, 0, eq_tlv), |
272 | SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, | 267 | SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, |
@@ -278,6 +273,8 @@ SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT, | |||
278 | SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, | 273 | SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, |
279 | 24, 0, eq_tlv), | 274 | 24, 0, eq_tlv), |
280 | 275 | ||
276 | SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19), | ||
277 | SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE, 1, 0), | ||
281 | SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, | 278 | SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, |
282 | 24, 0, eq_tlv), | 279 | 24, 0, eq_tlv), |
283 | SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, | 280 | SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, |
@@ -289,6 +286,8 @@ SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT, | |||
289 | SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, | 286 | SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, |
290 | 24, 0, eq_tlv), | 287 | 24, 0, eq_tlv), |
291 | 288 | ||
289 | SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19), | ||
290 | SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE, 1, 0), | ||
292 | SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, | 291 | SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, |
293 | 24, 0, eq_tlv), | 292 | 24, 0, eq_tlv), |
294 | SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, | 293 | SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, |
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 48dc7d2fee36..6d684d934f4d 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -117,19 +117,23 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | |||
117 | static const char *wm8400_digital_sidetone[] = | 117 | static const char *wm8400_digital_sidetone[] = |
118 | {"None", "Left ADC", "Right ADC", "Reserved"}; | 118 | {"None", "Left ADC", "Right ADC", "Reserved"}; |
119 | 119 | ||
120 | static const struct soc_enum wm8400_left_digital_sidetone_enum = | 120 | static SOC_ENUM_SINGLE_DECL(wm8400_left_digital_sidetone_enum, |
121 | SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, | 121 | WM8400_DIGITAL_SIDE_TONE, |
122 | WM8400_ADC_TO_DACL_SHIFT, 2, wm8400_digital_sidetone); | 122 | WM8400_ADC_TO_DACL_SHIFT, |
123 | wm8400_digital_sidetone); | ||
123 | 124 | ||
124 | static const struct soc_enum wm8400_right_digital_sidetone_enum = | 125 | static SOC_ENUM_SINGLE_DECL(wm8400_right_digital_sidetone_enum, |
125 | SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, | 126 | WM8400_DIGITAL_SIDE_TONE, |
126 | WM8400_ADC_TO_DACR_SHIFT, 2, wm8400_digital_sidetone); | 127 | WM8400_ADC_TO_DACR_SHIFT, |
128 | wm8400_digital_sidetone); | ||
127 | 129 | ||
128 | static const char *wm8400_adcmode[] = | 130 | static const char *wm8400_adcmode[] = |
129 | {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; | 131 | {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; |
130 | 132 | ||
131 | static const struct soc_enum wm8400_right_adcmode_enum = | 133 | static SOC_ENUM_SINGLE_DECL(wm8400_right_adcmode_enum, |
132 | SOC_ENUM_SINGLE(WM8400_ADC_CTRL, WM8400_ADC_HPF_CUT_SHIFT, 3, wm8400_adcmode); | 134 | WM8400_ADC_CTRL, |
135 | WM8400_ADC_HPF_CUT_SHIFT, | ||
136 | wm8400_adcmode); | ||
133 | 137 | ||
134 | static const struct snd_kcontrol_new wm8400_snd_controls[] = { | 138 | static const struct snd_kcontrol_new wm8400_snd_controls[] = { |
135 | /* INMIXL */ | 139 | /* INMIXL */ |
@@ -422,9 +426,10 @@ SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT, | |||
422 | static const char *wm8400_ainlmux[] = | 426 | static const char *wm8400_ainlmux[] = |
423 | {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; | 427 | {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; |
424 | 428 | ||
425 | static const struct soc_enum wm8400_ainlmux_enum = | 429 | static SOC_ENUM_SINGLE_DECL(wm8400_ainlmux_enum, |
426 | SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINLMODE_SHIFT, | 430 | WM8400_INPUT_MIXER1, |
427 | ARRAY_SIZE(wm8400_ainlmux), wm8400_ainlmux); | 431 | WM8400_AINLMODE_SHIFT, |
432 | wm8400_ainlmux); | ||
428 | 433 | ||
429 | static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls = | 434 | static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls = |
430 | SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); | 435 | SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); |
@@ -435,9 +440,10 @@ SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); | |||
435 | static const char *wm8400_ainrmux[] = | 440 | static const char *wm8400_ainrmux[] = |
436 | {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; | 441 | {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; |
437 | 442 | ||
438 | static const struct soc_enum wm8400_ainrmux_enum = | 443 | static SOC_ENUM_SINGLE_DECL(wm8400_ainrmux_enum, |
439 | SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINRMODE_SHIFT, | 444 | WM8400_INPUT_MIXER1, |
440 | ARRAY_SIZE(wm8400_ainrmux), wm8400_ainrmux); | 445 | WM8400_AINRMODE_SHIFT, |
446 | wm8400_ainrmux); | ||
441 | 447 | ||
442 | static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls = | 448 | static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls = |
443 | SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum); | 449 | SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum); |
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index d99f948c513c..6efcc40a7cb3 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c | |||
@@ -201,7 +201,7 @@ static void wm8711_shutdown(struct snd_pcm_substream *substream, | |||
201 | struct snd_soc_codec *codec = dai->codec; | 201 | struct snd_soc_codec *codec = dai->codec; |
202 | 202 | ||
203 | /* deactivate */ | 203 | /* deactivate */ |
204 | if (!codec->active) { | 204 | if (!snd_soc_codec_is_active(codec)) { |
205 | udelay(50); | 205 | udelay(50); |
206 | snd_soc_write(codec, WM8711_ACTIVE, 0x0); | 206 | snd_soc_write(codec, WM8711_ACTIVE, 0x0); |
207 | } | 207 | } |
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index be85da93a268..5cf4bebc5d89 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -251,7 +251,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol, | |||
251 | if (wm8753->dai_func == ucontrol->value.integer.value[0]) | 251 | if (wm8753->dai_func == ucontrol->value.integer.value[0]) |
252 | return 0; | 252 | return 0; |
253 | 253 | ||
254 | if (codec->active) | 254 | if (snd_soc_codec_is_active(codec)) |
255 | return -EBUSY; | 255 | return -EBUSY; |
256 | 256 | ||
257 | ioctl = snd_soc_read(codec, WM8753_IOCTL); | 257 | ioctl = snd_soc_read(codec, WM8753_IOCTL); |
@@ -1314,7 +1314,7 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute) | |||
1314 | /* the digital mute covers the HiFi and Voice DAC's on the WM8753. | 1314 | /* the digital mute covers the HiFi and Voice DAC's on the WM8753. |
1315 | * make sure we check if they are not both active when we mute */ | 1315 | * make sure we check if they are not both active when we mute */ |
1316 | if (mute && wm8753->dai_func == 1) { | 1316 | if (mute && wm8753->dai_func == 1) { |
1317 | if (!codec->active) | 1317 | if (!snd_soc_codec_is_active(codec)) |
1318 | snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8); | 1318 | snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8); |
1319 | } else { | 1319 | } else { |
1320 | if (mute) | 1320 | if (mute) |
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 89a18d82f303..5bce21013485 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c | |||
@@ -196,8 +196,8 @@ static const char *ain_text[] = { | |||
196 | "AIN5", "AIN6", "AIN7", "AIN8" | 196 | "AIN5", "AIN6", "AIN7", "AIN8" |
197 | }; | 197 | }; |
198 | 198 | ||
199 | static const struct soc_enum ain_enum = | 199 | static SOC_ENUM_DOUBLE_DECL(ain_enum, |
200 | SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text); | 200 | WM8770_ADCMUX, 0, 4, ain_text); |
201 | 201 | ||
202 | static const struct snd_kcontrol_new ain_mux = | 202 | static const struct snd_kcontrol_new ain_mux = |
203 | SOC_DAPM_ENUM("Capture Mux", ain_enum); | 203 | SOC_DAPM_ENUM("Capture Mux", ain_enum); |
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 9bc8206a6807..72d12bbe1a56 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c | |||
@@ -92,7 +92,7 @@ WM8804_REGULATOR_EVENT(0) | |||
92 | WM8804_REGULATOR_EVENT(1) | 92 | WM8804_REGULATOR_EVENT(1) |
93 | 93 | ||
94 | static const char *txsrc_text[] = { "S/PDIF RX", "AIF" }; | 94 | static const char *txsrc_text[] = { "S/PDIF RX", "AIF" }; |
95 | static const SOC_ENUM_SINGLE_EXT_DECL(txsrc, txsrc_text); | 95 | static SOC_ENUM_SINGLE_EXT_DECL(txsrc, txsrc_text); |
96 | 96 | ||
97 | static const struct snd_kcontrol_new wm8804_snd_controls[] = { | 97 | static const struct snd_kcontrol_new wm8804_snd_controls[] = { |
98 | SOC_ENUM_EXT("Input Source", txsrc, txsrc_get, txsrc_put), | 98 | SOC_ENUM_EXT("Input Source", txsrc, txsrc_get, txsrc_put), |
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index e98bc7038a08..43c2201cb901 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c | |||
@@ -304,53 +304,53 @@ static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1); | |||
304 | 304 | ||
305 | static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" }; | 305 | static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" }; |
306 | 306 | ||
307 | static const struct soc_enum mic_bias_level = | 307 | static SOC_ENUM_SINGLE_DECL(mic_bias_level, |
308 | SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt); | 308 | WM8900_REG_INCTL, 8, mic_bias_level_txt); |
309 | 309 | ||
310 | static const char *dac_mute_rate_txt[] = { "Fast", "Slow" }; | 310 | static const char *dac_mute_rate_txt[] = { "Fast", "Slow" }; |
311 | 311 | ||
312 | static const struct soc_enum dac_mute_rate = | 312 | static SOC_ENUM_SINGLE_DECL(dac_mute_rate, |
313 | SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 7, 2, dac_mute_rate_txt); | 313 | WM8900_REG_DACCTRL, 7, dac_mute_rate_txt); |
314 | 314 | ||
315 | static const char *dac_deemphasis_txt[] = { | 315 | static const char *dac_deemphasis_txt[] = { |
316 | "Disabled", "32kHz", "44.1kHz", "48kHz" | 316 | "Disabled", "32kHz", "44.1kHz", "48kHz" |
317 | }; | 317 | }; |
318 | 318 | ||
319 | static const struct soc_enum dac_deemphasis = | 319 | static SOC_ENUM_SINGLE_DECL(dac_deemphasis, |
320 | SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 4, 4, dac_deemphasis_txt); | 320 | WM8900_REG_DACCTRL, 4, dac_deemphasis_txt); |
321 | 321 | ||
322 | static const char *adc_hpf_cut_txt[] = { | 322 | static const char *adc_hpf_cut_txt[] = { |
323 | "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3" | 323 | "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3" |
324 | }; | 324 | }; |
325 | 325 | ||
326 | static const struct soc_enum adc_hpf_cut = | 326 | static SOC_ENUM_SINGLE_DECL(adc_hpf_cut, |
327 | SOC_ENUM_SINGLE(WM8900_REG_ADCCTRL, 5, 4, adc_hpf_cut_txt); | 327 | WM8900_REG_ADCCTRL, 5, adc_hpf_cut_txt); |
328 | 328 | ||
329 | static const char *lr_txt[] = { | 329 | static const char *lr_txt[] = { |
330 | "Left", "Right" | 330 | "Left", "Right" |
331 | }; | 331 | }; |
332 | 332 | ||
333 | static const struct soc_enum aifl_src = | 333 | static SOC_ENUM_SINGLE_DECL(aifl_src, |
334 | SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 15, 2, lr_txt); | 334 | WM8900_REG_AUDIO1, 15, lr_txt); |
335 | 335 | ||
336 | static const struct soc_enum aifr_src = | 336 | static SOC_ENUM_SINGLE_DECL(aifr_src, |
337 | SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 14, 2, lr_txt); | 337 | WM8900_REG_AUDIO1, 14, lr_txt); |
338 | 338 | ||
339 | static const struct soc_enum dacl_src = | 339 | static SOC_ENUM_SINGLE_DECL(dacl_src, |
340 | SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 15, 2, lr_txt); | 340 | WM8900_REG_AUDIO2, 15, lr_txt); |
341 | 341 | ||
342 | static const struct soc_enum dacr_src = | 342 | static SOC_ENUM_SINGLE_DECL(dacr_src, |
343 | SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 14, 2, lr_txt); | 343 | WM8900_REG_AUDIO2, 14, lr_txt); |
344 | 344 | ||
345 | static const char *sidetone_txt[] = { | 345 | static const char *sidetone_txt[] = { |
346 | "Disabled", "Left ADC", "Right ADC" | 346 | "Disabled", "Left ADC", "Right ADC" |
347 | }; | 347 | }; |
348 | 348 | ||
349 | static const struct soc_enum dacl_sidetone = | 349 | static SOC_ENUM_SINGLE_DECL(dacl_sidetone, |
350 | SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 2, 3, sidetone_txt); | 350 | WM8900_REG_SIDETONE, 2, sidetone_txt); |
351 | 351 | ||
352 | static const struct soc_enum dacr_sidetone = | 352 | static SOC_ENUM_SINGLE_DECL(dacr_sidetone, |
353 | SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 0, 3, sidetone_txt); | 353 | WM8900_REG_SIDETONE, 0, sidetone_txt); |
354 | 354 | ||
355 | static const struct snd_kcontrol_new wm8900_snd_controls[] = { | 355 | static const struct snd_kcontrol_new wm8900_snd_controls[] = { |
356 | SOC_ENUM("Mic Bias Level", mic_bias_level), | 356 | SOC_ENUM("Mic Bias Level", mic_bias_level), |
@@ -496,8 +496,8 @@ SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0), | |||
496 | 496 | ||
497 | static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" }; | 497 | static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" }; |
498 | 498 | ||
499 | static const struct soc_enum wm8900_lineout2_lp_mux = | 499 | static SOC_ENUM_SINGLE_DECL(wm8900_lineout2_lp_mux, |
500 | SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm8900_lp_mux); | 500 | WM8900_REG_LOUTMIXCTL1, 1, wm8900_lp_mux); |
501 | 501 | ||
502 | static const struct snd_kcontrol_new wm8900_lineout2_lp = | 502 | static const struct snd_kcontrol_new wm8900_lineout2_lp = |
503 | SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux); | 503 | SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux); |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 53bbfac6a83a..b2664ec901b9 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
@@ -1981,7 +1981,7 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec) | |||
1981 | dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", | 1981 | dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", |
1982 | wm8904->num_retune_mobile_texts); | 1982 | wm8904->num_retune_mobile_texts); |
1983 | 1983 | ||
1984 | wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; | 1984 | wm8904->retune_mobile_enum.items = wm8904->num_retune_mobile_texts; |
1985 | wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; | 1985 | wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; |
1986 | 1986 | ||
1987 | ret = snd_soc_add_codec_controls(codec, &control, 1); | 1987 | ret = snd_soc_add_codec_controls(codec, &control, 1); |
@@ -2022,7 +2022,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec) | |||
2022 | for (i = 0; i < pdata->num_drc_cfgs; i++) | 2022 | for (i = 0; i < pdata->num_drc_cfgs; i++) |
2023 | wm8904->drc_texts[i] = pdata->drc_cfgs[i].name; | 2023 | wm8904->drc_texts[i] = pdata->drc_cfgs[i].name; |
2024 | 2024 | ||
2025 | wm8904->drc_enum.max = pdata->num_drc_cfgs; | 2025 | wm8904->drc_enum.items = pdata->num_drc_cfgs; |
2026 | wm8904->drc_enum.texts = wm8904->drc_texts; | 2026 | wm8904->drc_enum.texts = wm8904->drc_texts; |
2027 | 2027 | ||
2028 | ret = snd_soc_add_codec_controls(codec, &control, 1); | 2028 | ret = snd_soc_add_codec_controls(codec, &control, 1); |
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index b7488f190d2b..7ac2e511403c 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c | |||
@@ -153,7 +153,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, | |||
153 | 153 | ||
154 | data32 &= 0xffffff; | 154 | data32 &= 0xffffff; |
155 | 155 | ||
156 | wm8994_bulk_write(codec->control_data, | 156 | wm8994_bulk_write(wm8994->wm8994, |
157 | data32 & 0xffffff, | 157 | data32 & 0xffffff, |
158 | block_len / 2, | 158 | block_len / 2, |
159 | (void *)(data + 8)); | 159 | (void *)(data + 8)); |
@@ -944,7 +944,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
944 | for (i = 0; i < pdata->num_mbc_cfgs; i++) | 944 | for (i = 0; i < pdata->num_mbc_cfgs; i++) |
945 | wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name; | 945 | wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name; |
946 | 946 | ||
947 | wm8994->mbc_enum.max = pdata->num_mbc_cfgs; | 947 | wm8994->mbc_enum.items = pdata->num_mbc_cfgs; |
948 | wm8994->mbc_enum.texts = wm8994->mbc_texts; | 948 | wm8994->mbc_enum.texts = wm8994->mbc_texts; |
949 | 949 | ||
950 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, | 950 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
@@ -973,7 +973,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
973 | for (i = 0; i < pdata->num_vss_cfgs; i++) | 973 | for (i = 0; i < pdata->num_vss_cfgs; i++) |
974 | wm8994->vss_texts[i] = pdata->vss_cfgs[i].name; | 974 | wm8994->vss_texts[i] = pdata->vss_cfgs[i].name; |
975 | 975 | ||
976 | wm8994->vss_enum.max = pdata->num_vss_cfgs; | 976 | wm8994->vss_enum.items = pdata->num_vss_cfgs; |
977 | wm8994->vss_enum.texts = wm8994->vss_texts; | 977 | wm8994->vss_enum.texts = wm8994->vss_texts; |
978 | 978 | ||
979 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, | 979 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
@@ -1003,7 +1003,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1003 | for (i = 0; i < pdata->num_vss_hpf_cfgs; i++) | 1003 | for (i = 0; i < pdata->num_vss_hpf_cfgs; i++) |
1004 | wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name; | 1004 | wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name; |
1005 | 1005 | ||
1006 | wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; | 1006 | wm8994->vss_hpf_enum.items = pdata->num_vss_hpf_cfgs; |
1007 | wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; | 1007 | wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; |
1008 | 1008 | ||
1009 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, | 1009 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
@@ -1034,7 +1034,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1034 | for (i = 0; i < pdata->num_enh_eq_cfgs; i++) | 1034 | for (i = 0; i < pdata->num_enh_eq_cfgs; i++) |
1035 | wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name; | 1035 | wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name; |
1036 | 1036 | ||
1037 | wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; | 1037 | wm8994->enh_eq_enum.items = pdata->num_enh_eq_cfgs; |
1038 | wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; | 1038 | wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; |
1039 | 1039 | ||
1040 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, | 1040 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 97db3b45b411..9e6233633c44 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -3089,6 +3089,7 @@ static irqreturn_t wm8962_irq(int irq, void *data) | |||
3089 | int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | 3089 | int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) |
3090 | { | 3090 | { |
3091 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 3091 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
3092 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
3092 | int irq_mask, enable; | 3093 | int irq_mask, enable; |
3093 | 3094 | ||
3094 | wm8962->jack = jack; | 3095 | wm8962->jack = jack; |
@@ -3109,14 +3110,18 @@ int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | |||
3109 | snd_soc_jack_report(wm8962->jack, 0, | 3110 | snd_soc_jack_report(wm8962->jack, 0, |
3110 | SND_JACK_MICROPHONE | SND_JACK_BTN_0); | 3111 | SND_JACK_MICROPHONE | SND_JACK_BTN_0); |
3111 | 3112 | ||
3113 | snd_soc_dapm_mutex_lock(dapm); | ||
3114 | |||
3112 | if (jack) { | 3115 | if (jack) { |
3113 | snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); | 3116 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK"); |
3114 | snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS"); | 3117 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS"); |
3115 | } else { | 3118 | } else { |
3116 | snd_soc_dapm_disable_pin(&codec->dapm, "SYSCLK"); | 3119 | snd_soc_dapm_disable_pin_unlocked(dapm, "SYSCLK"); |
3117 | snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS"); | 3120 | snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS"); |
3118 | } | 3121 | } |
3119 | 3122 | ||
3123 | snd_soc_dapm_mutex_unlock(dapm); | ||
3124 | |||
3120 | return 0; | 3125 | return 0; |
3121 | } | 3126 | } |
3122 | EXPORT_SYMBOL_GPL(wm8962_mic_detect); | 3127 | EXPORT_SYMBOL_GPL(wm8962_mic_detect); |
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index d8fc531c0e59..a9e2f465c331 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c | |||
@@ -117,21 +117,21 @@ static const char *wm8978_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"}; | |||
117 | static const char *wm8978_alc3[] = {"ALC", "Limiter"}; | 117 | static const char *wm8978_alc3[] = {"ALC", "Limiter"}; |
118 | static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"}; | 118 | static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"}; |
119 | 119 | ||
120 | static const SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1, | 120 | static SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1, |
121 | wm8978_companding); | 121 | wm8978_companding); |
122 | static const SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL, 3, | 122 | static SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL, 3, |
123 | wm8978_companding); | 123 | wm8978_companding); |
124 | static const SOC_ENUM_SINGLE_DECL(eqmode, WM8978_EQ1, 8, wm8978_eqmode); | 124 | static SOC_ENUM_SINGLE_DECL(eqmode, WM8978_EQ1, 8, wm8978_eqmode); |
125 | static const SOC_ENUM_SINGLE_DECL(eq1, WM8978_EQ1, 5, wm8978_eq1); | 125 | static SOC_ENUM_SINGLE_DECL(eq1, WM8978_EQ1, 5, wm8978_eq1); |
126 | static const SOC_ENUM_SINGLE_DECL(eq2bw, WM8978_EQ2, 8, wm8978_bw); | 126 | static SOC_ENUM_SINGLE_DECL(eq2bw, WM8978_EQ2, 8, wm8978_bw); |
127 | static const SOC_ENUM_SINGLE_DECL(eq2, WM8978_EQ2, 5, wm8978_eq2); | 127 | static SOC_ENUM_SINGLE_DECL(eq2, WM8978_EQ2, 5, wm8978_eq2); |
128 | static const SOC_ENUM_SINGLE_DECL(eq3bw, WM8978_EQ3, 8, wm8978_bw); | 128 | static SOC_ENUM_SINGLE_DECL(eq3bw, WM8978_EQ3, 8, wm8978_bw); |
129 | static const SOC_ENUM_SINGLE_DECL(eq3, WM8978_EQ3, 5, wm8978_eq3); | 129 | static SOC_ENUM_SINGLE_DECL(eq3, WM8978_EQ3, 5, wm8978_eq3); |
130 | static const SOC_ENUM_SINGLE_DECL(eq4bw, WM8978_EQ4, 8, wm8978_bw); | 130 | static SOC_ENUM_SINGLE_DECL(eq4bw, WM8978_EQ4, 8, wm8978_bw); |
131 | static const SOC_ENUM_SINGLE_DECL(eq4, WM8978_EQ4, 5, wm8978_eq4); | 131 | static SOC_ENUM_SINGLE_DECL(eq4, WM8978_EQ4, 5, wm8978_eq4); |
132 | static const SOC_ENUM_SINGLE_DECL(eq5, WM8978_EQ5, 5, wm8978_eq5); | 132 | static SOC_ENUM_SINGLE_DECL(eq5, WM8978_EQ5, 5, wm8978_eq5); |
133 | static const SOC_ENUM_SINGLE_DECL(alc3, WM8978_ALC_CONTROL_3, 8, wm8978_alc3); | 133 | static SOC_ENUM_SINGLE_DECL(alc3, WM8978_ALC_CONTROL_3, 8, wm8978_alc3); |
134 | static const SOC_ENUM_SINGLE_DECL(alc1, WM8978_ALC_CONTROL_1, 7, wm8978_alc1); | 134 | static SOC_ENUM_SINGLE_DECL(alc1, WM8978_ALC_CONTROL_1, 7, wm8978_alc1); |
135 | 135 | ||
136 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1); | 136 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1); |
137 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | 137 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); |
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index aa41ba0dfff4..770e5a705851 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c | |||
@@ -205,49 +205,44 @@ static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); | |||
205 | static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0); | 205 | static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0); |
206 | 206 | ||
207 | static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" }; | 207 | static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" }; |
208 | static const SOC_ENUM_SINGLE_DECL(alc_sel, WM8983_ALC_CONTROL_1, 7, | 208 | static SOC_ENUM_SINGLE_DECL(alc_sel, WM8983_ALC_CONTROL_1, 7, alc_sel_text); |
209 | alc_sel_text); | ||
210 | 209 | ||
211 | static const char *alc_mode_text[] = { "ALC", "Limiter" }; | 210 | static const char *alc_mode_text[] = { "ALC", "Limiter" }; |
212 | static const SOC_ENUM_SINGLE_DECL(alc_mode, WM8983_ALC_CONTROL_3, 8, | 211 | static SOC_ENUM_SINGLE_DECL(alc_mode, WM8983_ALC_CONTROL_3, 8, alc_mode_text); |
213 | alc_mode_text); | ||
214 | 212 | ||
215 | static const char *filter_mode_text[] = { "Audio", "Application" }; | 213 | static const char *filter_mode_text[] = { "Audio", "Application" }; |
216 | static const SOC_ENUM_SINGLE_DECL(filter_mode, WM8983_ADC_CONTROL, 7, | 214 | static SOC_ENUM_SINGLE_DECL(filter_mode, WM8983_ADC_CONTROL, 7, |
217 | filter_mode_text); | 215 | filter_mode_text); |
218 | 216 | ||
219 | static const char *eq_bw_text[] = { "Narrow", "Wide" }; | 217 | static const char *eq_bw_text[] = { "Narrow", "Wide" }; |
220 | static const char *eqmode_text[] = { "Capture", "Playback" }; | 218 | static const char *eqmode_text[] = { "Capture", "Playback" }; |
221 | static const SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text); | 219 | static SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text); |
222 | 220 | ||
223 | static const char *eq1_cutoff_text[] = { | 221 | static const char *eq1_cutoff_text[] = { |
224 | "80Hz", "105Hz", "135Hz", "175Hz" | 222 | "80Hz", "105Hz", "135Hz", "175Hz" |
225 | }; | 223 | }; |
226 | static const SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8983_EQ1_LOW_SHELF, 5, | 224 | static SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8983_EQ1_LOW_SHELF, 5, |
227 | eq1_cutoff_text); | 225 | eq1_cutoff_text); |
228 | static const char *eq2_cutoff_text[] = { | 226 | static const char *eq2_cutoff_text[] = { |
229 | "230Hz", "300Hz", "385Hz", "500Hz" | 227 | "230Hz", "300Hz", "385Hz", "500Hz" |
230 | }; | 228 | }; |
231 | static const SOC_ENUM_SINGLE_DECL(eq2_bw, WM8983_EQ2_PEAK_1, 8, eq_bw_text); | 229 | static SOC_ENUM_SINGLE_DECL(eq2_bw, WM8983_EQ2_PEAK_1, 8, eq_bw_text); |
232 | static const SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8983_EQ2_PEAK_1, 5, | 230 | static SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8983_EQ2_PEAK_1, 5, eq2_cutoff_text); |
233 | eq2_cutoff_text); | ||
234 | static const char *eq3_cutoff_text[] = { | 231 | static const char *eq3_cutoff_text[] = { |
235 | "650Hz", "850Hz", "1.1kHz", "1.4kHz" | 232 | "650Hz", "850Hz", "1.1kHz", "1.4kHz" |
236 | }; | 233 | }; |
237 | static const SOC_ENUM_SINGLE_DECL(eq3_bw, WM8983_EQ3_PEAK_2, 8, eq_bw_text); | 234 | static SOC_ENUM_SINGLE_DECL(eq3_bw, WM8983_EQ3_PEAK_2, 8, eq_bw_text); |
238 | static const SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8983_EQ3_PEAK_2, 5, | 235 | static SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8983_EQ3_PEAK_2, 5, eq3_cutoff_text); |
239 | eq3_cutoff_text); | ||
240 | static const char *eq4_cutoff_text[] = { | 236 | static const char *eq4_cutoff_text[] = { |
241 | "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" | 237 | "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" |
242 | }; | 238 | }; |
243 | static const SOC_ENUM_SINGLE_DECL(eq4_bw, WM8983_EQ4_PEAK_3, 8, eq_bw_text); | 239 | static SOC_ENUM_SINGLE_DECL(eq4_bw, WM8983_EQ4_PEAK_3, 8, eq_bw_text); |
244 | static const SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8983_EQ4_PEAK_3, 5, | 240 | static SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8983_EQ4_PEAK_3, 5, eq4_cutoff_text); |
245 | eq4_cutoff_text); | ||
246 | static const char *eq5_cutoff_text[] = { | 241 | static const char *eq5_cutoff_text[] = { |
247 | "5.3kHz", "6.9kHz", "9kHz", "11.7kHz" | 242 | "5.3kHz", "6.9kHz", "9kHz", "11.7kHz" |
248 | }; | 243 | }; |
249 | static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5, | 244 | static SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5, |
250 | eq5_cutoff_text); | 245 | eq5_cutoff_text); |
251 | 246 | ||
252 | static const char *depth_3d_text[] = { | 247 | static const char *depth_3d_text[] = { |
253 | "Off", | 248 | "Off", |
@@ -267,8 +262,8 @@ static const char *depth_3d_text[] = { | |||
267 | "93.3%", | 262 | "93.3%", |
268 | "100%" | 263 | "100%" |
269 | }; | 264 | }; |
270 | static const SOC_ENUM_SINGLE_DECL(depth_3d, WM8983_3D_CONTROL, 0, | 265 | static SOC_ENUM_SINGLE_DECL(depth_3d, WM8983_3D_CONTROL, 0, |
271 | depth_3d_text); | 266 | depth_3d_text); |
272 | 267 | ||
273 | static const struct snd_kcontrol_new wm8983_snd_controls[] = { | 268 | static const struct snd_kcontrol_new wm8983_snd_controls[] = { |
274 | SOC_SINGLE("Digital Loopback Switch", WM8983_COMPANDING_CONTROL, | 269 | SOC_SINGLE("Digital Loopback Switch", WM8983_COMPANDING_CONTROL, |
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index 271b517911a4..d786f2b39764 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c | |||
@@ -226,52 +226,48 @@ static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); | |||
226 | static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0); | 226 | static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0); |
227 | 227 | ||
228 | static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" }; | 228 | static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" }; |
229 | static const SOC_ENUM_SINGLE_DECL(alc_sel, WM8985_ALC_CONTROL_1, 7, | 229 | static SOC_ENUM_SINGLE_DECL(alc_sel, WM8985_ALC_CONTROL_1, 7, alc_sel_text); |
230 | alc_sel_text); | ||
231 | 230 | ||
232 | static const char *alc_mode_text[] = { "ALC", "Limiter" }; | 231 | static const char *alc_mode_text[] = { "ALC", "Limiter" }; |
233 | static const SOC_ENUM_SINGLE_DECL(alc_mode, WM8985_ALC_CONTROL_3, 8, | 232 | static SOC_ENUM_SINGLE_DECL(alc_mode, WM8985_ALC_CONTROL_3, 8, alc_mode_text); |
234 | alc_mode_text); | ||
235 | 233 | ||
236 | static const char *filter_mode_text[] = { "Audio", "Application" }; | 234 | static const char *filter_mode_text[] = { "Audio", "Application" }; |
237 | static const SOC_ENUM_SINGLE_DECL(filter_mode, WM8985_ADC_CONTROL, 7, | 235 | static SOC_ENUM_SINGLE_DECL(filter_mode, WM8985_ADC_CONTROL, 7, |
238 | filter_mode_text); | 236 | filter_mode_text); |
239 | 237 | ||
240 | static const char *eq_bw_text[] = { "Narrow", "Wide" }; | 238 | static const char *eq_bw_text[] = { "Narrow", "Wide" }; |
241 | static const char *eqmode_text[] = { "Capture", "Playback" }; | 239 | static const char *eqmode_text[] = { "Capture", "Playback" }; |
242 | static const SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text); | 240 | static SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text); |
243 | 241 | ||
244 | static const char *eq1_cutoff_text[] = { | 242 | static const char *eq1_cutoff_text[] = { |
245 | "80Hz", "105Hz", "135Hz", "175Hz" | 243 | "80Hz", "105Hz", "135Hz", "175Hz" |
246 | }; | 244 | }; |
247 | static const SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8985_EQ1_LOW_SHELF, 5, | 245 | static SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8985_EQ1_LOW_SHELF, 5, |
248 | eq1_cutoff_text); | 246 | eq1_cutoff_text); |
249 | static const char *eq2_cutoff_text[] = { | 247 | static const char *eq2_cutoff_text[] = { |
250 | "230Hz", "300Hz", "385Hz", "500Hz" | 248 | "230Hz", "300Hz", "385Hz", "500Hz" |
251 | }; | 249 | }; |
252 | static const SOC_ENUM_SINGLE_DECL(eq2_bw, WM8985_EQ2_PEAK_1, 8, eq_bw_text); | 250 | static SOC_ENUM_SINGLE_DECL(eq2_bw, WM8985_EQ2_PEAK_1, 8, eq_bw_text); |
253 | static const SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8985_EQ2_PEAK_1, 5, | 251 | static SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8985_EQ2_PEAK_1, 5, eq2_cutoff_text); |
254 | eq2_cutoff_text); | ||
255 | static const char *eq3_cutoff_text[] = { | 252 | static const char *eq3_cutoff_text[] = { |
256 | "650Hz", "850Hz", "1.1kHz", "1.4kHz" | 253 | "650Hz", "850Hz", "1.1kHz", "1.4kHz" |
257 | }; | 254 | }; |
258 | static const SOC_ENUM_SINGLE_DECL(eq3_bw, WM8985_EQ3_PEAK_2, 8, eq_bw_text); | 255 | static SOC_ENUM_SINGLE_DECL(eq3_bw, WM8985_EQ3_PEAK_2, 8, eq_bw_text); |
259 | static const SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8985_EQ3_PEAK_2, 5, | 256 | static SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8985_EQ3_PEAK_2, 5, |
260 | eq3_cutoff_text); | 257 | eq3_cutoff_text); |
261 | static const char *eq4_cutoff_text[] = { | 258 | static const char *eq4_cutoff_text[] = { |
262 | "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" | 259 | "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" |
263 | }; | 260 | }; |
264 | static const SOC_ENUM_SINGLE_DECL(eq4_bw, WM8985_EQ4_PEAK_3, 8, eq_bw_text); | 261 | static SOC_ENUM_SINGLE_DECL(eq4_bw, WM8985_EQ4_PEAK_3, 8, eq_bw_text); |
265 | static const SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8985_EQ4_PEAK_3, 5, | 262 | static SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8985_EQ4_PEAK_3, 5, eq4_cutoff_text); |
266 | eq4_cutoff_text); | ||
267 | static const char *eq5_cutoff_text[] = { | 263 | static const char *eq5_cutoff_text[] = { |
268 | "5.3kHz", "6.9kHz", "9kHz", "11.7kHz" | 264 | "5.3kHz", "6.9kHz", "9kHz", "11.7kHz" |
269 | }; | 265 | }; |
270 | static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8985_EQ5_HIGH_SHELF, 5, | 266 | static SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8985_EQ5_HIGH_SHELF, 5, |
271 | eq5_cutoff_text); | 267 | eq5_cutoff_text); |
272 | 268 | ||
273 | static const char *speaker_mode_text[] = { "Class A/B", "Class D" }; | 269 | static const char *speaker_mode_text[] = { "Class A/B", "Class D" }; |
274 | static const SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text); | 270 | static SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text); |
275 | 271 | ||
276 | static const char *depth_3d_text[] = { | 272 | static const char *depth_3d_text[] = { |
277 | "Off", | 273 | "Off", |
@@ -291,8 +287,7 @@ static const char *depth_3d_text[] = { | |||
291 | "93.3%", | 287 | "93.3%", |
292 | "100%" | 288 | "100%" |
293 | }; | 289 | }; |
294 | static const SOC_ENUM_SINGLE_DECL(depth_3d, WM8985_3D_CONTROL, 0, | 290 | static SOC_ENUM_SINGLE_DECL(depth_3d, WM8985_3D_CONTROL, 0, depth_3d_text); |
295 | depth_3d_text); | ||
296 | 291 | ||
297 | static const struct snd_kcontrol_new wm8985_snd_controls[] = { | 292 | static const struct snd_kcontrol_new wm8985_snd_controls[] = { |
298 | SOC_SINGLE("Digital Loopback Switch", WM8985_COMPANDING_CONTROL, | 293 | SOC_SINGLE("Digital Loopback Switch", WM8985_COMPANDING_CONTROL, |
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 433d59a0f3ef..2ee23a39622c 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -1562,7 +1562,6 @@ static int wm8993_remove(struct snd_soc_codec *codec) | |||
1562 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); | 1562 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
1563 | 1563 | ||
1564 | wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1564 | wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1565 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1566 | return 0; | 1565 | return 0; |
1567 | } | 1566 | } |
1568 | 1567 | ||
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b9be9cbc4603..79854cb7feb6 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -265,21 +265,21 @@ static const char *sidetone_hpf_text[] = { | |||
265 | "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz" | 265 | "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz" |
266 | }; | 266 | }; |
267 | 267 | ||
268 | static const struct soc_enum sidetone_hpf = | 268 | static SOC_ENUM_SINGLE_DECL(sidetone_hpf, |
269 | SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text); | 269 | WM8994_SIDETONE, 7, sidetone_hpf_text); |
270 | 270 | ||
271 | static const char *adc_hpf_text[] = { | 271 | static const char *adc_hpf_text[] = { |
272 | "HiFi", "Voice 1", "Voice 2", "Voice 3" | 272 | "HiFi", "Voice 1", "Voice 2", "Voice 3" |
273 | }; | 273 | }; |
274 | 274 | ||
275 | static const struct soc_enum aif1adc1_hpf = | 275 | static SOC_ENUM_SINGLE_DECL(aif1adc1_hpf, |
276 | SOC_ENUM_SINGLE(WM8994_AIF1_ADC1_FILTERS, 13, 4, adc_hpf_text); | 276 | WM8994_AIF1_ADC1_FILTERS, 13, adc_hpf_text); |
277 | 277 | ||
278 | static const struct soc_enum aif1adc2_hpf = | 278 | static SOC_ENUM_SINGLE_DECL(aif1adc2_hpf, |
279 | SOC_ENUM_SINGLE(WM8994_AIF1_ADC2_FILTERS, 13, 4, adc_hpf_text); | 279 | WM8994_AIF1_ADC2_FILTERS, 13, adc_hpf_text); |
280 | 280 | ||
281 | static const struct soc_enum aif2adc_hpf = | 281 | static SOC_ENUM_SINGLE_DECL(aif2adc_hpf, |
282 | SOC_ENUM_SINGLE(WM8994_AIF2_ADC_FILTERS, 13, 4, adc_hpf_text); | 282 | WM8994_AIF2_ADC_FILTERS, 13, adc_hpf_text); |
283 | 283 | ||
284 | static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0); | 284 | static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0); |
285 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); | 285 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); |
@@ -501,39 +501,39 @@ static const char *aif_chan_src_text[] = { | |||
501 | "Left", "Right" | 501 | "Left", "Right" |
502 | }; | 502 | }; |
503 | 503 | ||
504 | static const struct soc_enum aif1adcl_src = | 504 | static SOC_ENUM_SINGLE_DECL(aif1adcl_src, |
505 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text); | 505 | WM8994_AIF1_CONTROL_1, 15, aif_chan_src_text); |
506 | 506 | ||
507 | static const struct soc_enum aif1adcr_src = | 507 | static SOC_ENUM_SINGLE_DECL(aif1adcr_src, |
508 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text); | 508 | WM8994_AIF1_CONTROL_1, 14, aif_chan_src_text); |
509 | 509 | ||
510 | static const struct soc_enum aif2adcl_src = | 510 | static SOC_ENUM_SINGLE_DECL(aif2adcl_src, |
511 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text); | 511 | WM8994_AIF2_CONTROL_1, 15, aif_chan_src_text); |
512 | 512 | ||
513 | static const struct soc_enum aif2adcr_src = | 513 | static SOC_ENUM_SINGLE_DECL(aif2adcr_src, |
514 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text); | 514 | WM8994_AIF2_CONTROL_1, 14, aif_chan_src_text); |
515 | 515 | ||
516 | static const struct soc_enum aif1dacl_src = | 516 | static SOC_ENUM_SINGLE_DECL(aif1dacl_src, |
517 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text); | 517 | WM8994_AIF1_CONTROL_2, 15, aif_chan_src_text); |
518 | 518 | ||
519 | static const struct soc_enum aif1dacr_src = | 519 | static SOC_ENUM_SINGLE_DECL(aif1dacr_src, |
520 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text); | 520 | WM8994_AIF1_CONTROL_2, 14, aif_chan_src_text); |
521 | 521 | ||
522 | static const struct soc_enum aif2dacl_src = | 522 | static SOC_ENUM_SINGLE_DECL(aif2dacl_src, |
523 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text); | 523 | WM8994_AIF2_CONTROL_2, 15, aif_chan_src_text); |
524 | 524 | ||
525 | static const struct soc_enum aif2dacr_src = | 525 | static SOC_ENUM_SINGLE_DECL(aif2dacr_src, |
526 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text); | 526 | WM8994_AIF2_CONTROL_2, 14, aif_chan_src_text); |
527 | 527 | ||
528 | static const char *osr_text[] = { | 528 | static const char *osr_text[] = { |
529 | "Low Power", "High Performance", | 529 | "Low Power", "High Performance", |
530 | }; | 530 | }; |
531 | 531 | ||
532 | static const struct soc_enum dac_osr = | 532 | static SOC_ENUM_SINGLE_DECL(dac_osr, |
533 | SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text); | 533 | WM8994_OVERSAMPLING, 0, osr_text); |
534 | 534 | ||
535 | static const struct soc_enum adc_osr = | 535 | static SOC_ENUM_SINGLE_DECL(adc_osr, |
536 | SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text); | 536 | WM8994_OVERSAMPLING, 1, osr_text); |
537 | 537 | ||
538 | static const struct snd_kcontrol_new wm8994_snd_controls[] = { | 538 | static const struct snd_kcontrol_new wm8994_snd_controls[] = { |
539 | SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, | 539 | SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, |
@@ -690,17 +690,20 @@ static const char *wm8958_ng_text[] = { | |||
690 | "30ms", "125ms", "250ms", "500ms", | 690 | "30ms", "125ms", "250ms", "500ms", |
691 | }; | 691 | }; |
692 | 692 | ||
693 | static const struct soc_enum wm8958_aif1dac1_ng_hold = | 693 | static SOC_ENUM_SINGLE_DECL(wm8958_aif1dac1_ng_hold, |
694 | SOC_ENUM_SINGLE(WM8958_AIF1_DAC1_NOISE_GATE, | 694 | WM8958_AIF1_DAC1_NOISE_GATE, |
695 | WM8958_AIF1DAC1_NG_THR_SHIFT, 4, wm8958_ng_text); | 695 | WM8958_AIF1DAC1_NG_THR_SHIFT, |
696 | wm8958_ng_text); | ||
696 | 697 | ||
697 | static const struct soc_enum wm8958_aif1dac2_ng_hold = | 698 | static SOC_ENUM_SINGLE_DECL(wm8958_aif1dac2_ng_hold, |
698 | SOC_ENUM_SINGLE(WM8958_AIF1_DAC2_NOISE_GATE, | 699 | WM8958_AIF1_DAC2_NOISE_GATE, |
699 | WM8958_AIF1DAC2_NG_THR_SHIFT, 4, wm8958_ng_text); | 700 | WM8958_AIF1DAC2_NG_THR_SHIFT, |
701 | wm8958_ng_text); | ||
700 | 702 | ||
701 | static const struct soc_enum wm8958_aif2dac_ng_hold = | 703 | static SOC_ENUM_SINGLE_DECL(wm8958_aif2dac_ng_hold, |
702 | SOC_ENUM_SINGLE(WM8958_AIF2_DAC_NOISE_GATE, | 704 | WM8958_AIF2_DAC_NOISE_GATE, |
703 | WM8958_AIF2DAC_NG_THR_SHIFT, 4, wm8958_ng_text); | 705 | WM8958_AIF2DAC_NG_THR_SHIFT, |
706 | wm8958_ng_text); | ||
704 | 707 | ||
705 | static const struct snd_kcontrol_new wm8958_snd_controls[] = { | 708 | static const struct snd_kcontrol_new wm8958_snd_controls[] = { |
706 | SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), | 709 | SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), |
@@ -1341,8 +1344,7 @@ static const char *adc_mux_text[] = { | |||
1341 | "DMIC", | 1344 | "DMIC", |
1342 | }; | 1345 | }; |
1343 | 1346 | ||
1344 | static const struct soc_enum adc_enum = | 1347 | static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text); |
1345 | SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text); | ||
1346 | 1348 | ||
1347 | static const struct snd_kcontrol_new adcl_mux = | 1349 | static const struct snd_kcontrol_new adcl_mux = |
1348 | SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); | 1350 | SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); |
@@ -1478,14 +1480,14 @@ static const char *sidetone_text[] = { | |||
1478 | "ADC/DMIC1", "DMIC2", | 1480 | "ADC/DMIC1", "DMIC2", |
1479 | }; | 1481 | }; |
1480 | 1482 | ||
1481 | static const struct soc_enum sidetone1_enum = | 1483 | static SOC_ENUM_SINGLE_DECL(sidetone1_enum, |
1482 | SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text); | 1484 | WM8994_SIDETONE, 0, sidetone_text); |
1483 | 1485 | ||
1484 | static const struct snd_kcontrol_new sidetone1_mux = | 1486 | static const struct snd_kcontrol_new sidetone1_mux = |
1485 | SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); | 1487 | SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); |
1486 | 1488 | ||
1487 | static const struct soc_enum sidetone2_enum = | 1489 | static SOC_ENUM_SINGLE_DECL(sidetone2_enum, |
1488 | SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text); | 1490 | WM8994_SIDETONE, 1, sidetone_text); |
1489 | 1491 | ||
1490 | static const struct snd_kcontrol_new sidetone2_mux = | 1492 | static const struct snd_kcontrol_new sidetone2_mux = |
1491 | SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); | 1493 | SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); |
@@ -1498,22 +1500,24 @@ static const char *loopback_text[] = { | |||
1498 | "None", "ADCDAT", | 1500 | "None", "ADCDAT", |
1499 | }; | 1501 | }; |
1500 | 1502 | ||
1501 | static const struct soc_enum aif1_loopback_enum = | 1503 | static SOC_ENUM_SINGLE_DECL(aif1_loopback_enum, |
1502 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, WM8994_AIF1_LOOPBACK_SHIFT, 2, | 1504 | WM8994_AIF1_CONTROL_2, |
1503 | loopback_text); | 1505 | WM8994_AIF1_LOOPBACK_SHIFT, |
1506 | loopback_text); | ||
1504 | 1507 | ||
1505 | static const struct snd_kcontrol_new aif1_loopback = | 1508 | static const struct snd_kcontrol_new aif1_loopback = |
1506 | SOC_DAPM_ENUM("AIF1 Loopback", aif1_loopback_enum); | 1509 | SOC_DAPM_ENUM("AIF1 Loopback", aif1_loopback_enum); |
1507 | 1510 | ||
1508 | static const struct soc_enum aif2_loopback_enum = | 1511 | static SOC_ENUM_SINGLE_DECL(aif2_loopback_enum, |
1509 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, WM8994_AIF2_LOOPBACK_SHIFT, 2, | 1512 | WM8994_AIF2_CONTROL_2, |
1510 | loopback_text); | 1513 | WM8994_AIF2_LOOPBACK_SHIFT, |
1514 | loopback_text); | ||
1511 | 1515 | ||
1512 | static const struct snd_kcontrol_new aif2_loopback = | 1516 | static const struct snd_kcontrol_new aif2_loopback = |
1513 | SOC_DAPM_ENUM("AIF2 Loopback", aif2_loopback_enum); | 1517 | SOC_DAPM_ENUM("AIF2 Loopback", aif2_loopback_enum); |
1514 | 1518 | ||
1515 | static const struct soc_enum aif1dac_enum = | 1519 | static SOC_ENUM_SINGLE_DECL(aif1dac_enum, |
1516 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text); | 1520 | WM8994_POWER_MANAGEMENT_6, 0, aif1dac_text); |
1517 | 1521 | ||
1518 | static const struct snd_kcontrol_new aif1dac_mux = | 1522 | static const struct snd_kcontrol_new aif1dac_mux = |
1519 | SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum); | 1523 | SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum); |
@@ -1522,8 +1526,8 @@ static const char *aif2dac_text[] = { | |||
1522 | "AIF2DACDAT", "AIF3DACDAT", | 1526 | "AIF2DACDAT", "AIF3DACDAT", |
1523 | }; | 1527 | }; |
1524 | 1528 | ||
1525 | static const struct soc_enum aif2dac_enum = | 1529 | static SOC_ENUM_SINGLE_DECL(aif2dac_enum, |
1526 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text); | 1530 | WM8994_POWER_MANAGEMENT_6, 1, aif2dac_text); |
1527 | 1531 | ||
1528 | static const struct snd_kcontrol_new aif2dac_mux = | 1532 | static const struct snd_kcontrol_new aif2dac_mux = |
1529 | SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum); | 1533 | SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum); |
@@ -1532,8 +1536,8 @@ static const char *aif2adc_text[] = { | |||
1532 | "AIF2ADCDAT", "AIF3DACDAT", | 1536 | "AIF2ADCDAT", "AIF3DACDAT", |
1533 | }; | 1537 | }; |
1534 | 1538 | ||
1535 | static const struct soc_enum aif2adc_enum = | 1539 | static SOC_ENUM_SINGLE_DECL(aif2adc_enum, |
1536 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text); | 1540 | WM8994_POWER_MANAGEMENT_6, 2, aif2adc_text); |
1537 | 1541 | ||
1538 | static const struct snd_kcontrol_new aif2adc_mux = | 1542 | static const struct snd_kcontrol_new aif2adc_mux = |
1539 | SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); | 1543 | SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); |
@@ -1542,14 +1546,14 @@ static const char *aif3adc_text[] = { | |||
1542 | "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM", | 1546 | "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM", |
1543 | }; | 1547 | }; |
1544 | 1548 | ||
1545 | static const struct soc_enum wm8994_aif3adc_enum = | 1549 | static SOC_ENUM_SINGLE_DECL(wm8994_aif3adc_enum, |
1546 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text); | 1550 | WM8994_POWER_MANAGEMENT_6, 3, aif3adc_text); |
1547 | 1551 | ||
1548 | static const struct snd_kcontrol_new wm8994_aif3adc_mux = | 1552 | static const struct snd_kcontrol_new wm8994_aif3adc_mux = |
1549 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum); | 1553 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum); |
1550 | 1554 | ||
1551 | static const struct soc_enum wm8958_aif3adc_enum = | 1555 | static SOC_ENUM_SINGLE_DECL(wm8958_aif3adc_enum, |
1552 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text); | 1556 | WM8994_POWER_MANAGEMENT_6, 3, aif3adc_text); |
1553 | 1557 | ||
1554 | static const struct snd_kcontrol_new wm8958_aif3adc_mux = | 1558 | static const struct snd_kcontrol_new wm8958_aif3adc_mux = |
1555 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum); | 1559 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum); |
@@ -1558,8 +1562,8 @@ static const char *mono_pcm_out_text[] = { | |||
1558 | "None", "AIF2ADCL", "AIF2ADCR", | 1562 | "None", "AIF2ADCL", "AIF2ADCR", |
1559 | }; | 1563 | }; |
1560 | 1564 | ||
1561 | static const struct soc_enum mono_pcm_out_enum = | 1565 | static SOC_ENUM_SINGLE_DECL(mono_pcm_out_enum, |
1562 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text); | 1566 | WM8994_POWER_MANAGEMENT_6, 9, mono_pcm_out_text); |
1563 | 1567 | ||
1564 | static const struct snd_kcontrol_new mono_pcm_out_mux = | 1568 | static const struct snd_kcontrol_new mono_pcm_out_mux = |
1565 | SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum); | 1569 | SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum); |
@@ -1569,14 +1573,14 @@ static const char *aif2dac_src_text[] = { | |||
1569 | }; | 1573 | }; |
1570 | 1574 | ||
1571 | /* Note that these two control shouldn't be simultaneously switched to AIF3 */ | 1575 | /* Note that these two control shouldn't be simultaneously switched to AIF3 */ |
1572 | static const struct soc_enum aif2dacl_src_enum = | 1576 | static SOC_ENUM_SINGLE_DECL(aif2dacl_src_enum, |
1573 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text); | 1577 | WM8994_POWER_MANAGEMENT_6, 7, aif2dac_src_text); |
1574 | 1578 | ||
1575 | static const struct snd_kcontrol_new aif2dacl_src_mux = | 1579 | static const struct snd_kcontrol_new aif2dacl_src_mux = |
1576 | SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum); | 1580 | SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum); |
1577 | 1581 | ||
1578 | static const struct soc_enum aif2dacr_src_enum = | 1582 | static SOC_ENUM_SINGLE_DECL(aif2dacr_src_enum, |
1579 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text); | 1583 | WM8994_POWER_MANAGEMENT_6, 8, aif2dac_src_text); |
1580 | 1584 | ||
1581 | static const struct snd_kcontrol_new aif2dacr_src_mux = | 1585 | static const struct snd_kcontrol_new aif2dacr_src_mux = |
1582 | SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); | 1586 | SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); |
@@ -2549,43 +2553,52 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
2549 | int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode) | 2553 | int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode) |
2550 | { | 2554 | { |
2551 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2555 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2556 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
2552 | 2557 | ||
2553 | switch (mode) { | 2558 | switch (mode) { |
2554 | case WM8994_VMID_NORMAL: | 2559 | case WM8994_VMID_NORMAL: |
2560 | snd_soc_dapm_mutex_lock(dapm); | ||
2561 | |||
2555 | if (wm8994->hubs.lineout1_se) { | 2562 | if (wm8994->hubs.lineout1_se) { |
2556 | snd_soc_dapm_disable_pin(&codec->dapm, | 2563 | snd_soc_dapm_disable_pin_unlocked(dapm, |
2557 | "LINEOUT1N Driver"); | 2564 | "LINEOUT1N Driver"); |
2558 | snd_soc_dapm_disable_pin(&codec->dapm, | 2565 | snd_soc_dapm_disable_pin_unlocked(dapm, |
2559 | "LINEOUT1P Driver"); | 2566 | "LINEOUT1P Driver"); |
2560 | } | 2567 | } |
2561 | if (wm8994->hubs.lineout2_se) { | 2568 | if (wm8994->hubs.lineout2_se) { |
2562 | snd_soc_dapm_disable_pin(&codec->dapm, | 2569 | snd_soc_dapm_disable_pin_unlocked(dapm, |
2563 | "LINEOUT2N Driver"); | 2570 | "LINEOUT2N Driver"); |
2564 | snd_soc_dapm_disable_pin(&codec->dapm, | 2571 | snd_soc_dapm_disable_pin_unlocked(dapm, |
2565 | "LINEOUT2P Driver"); | 2572 | "LINEOUT2P Driver"); |
2566 | } | 2573 | } |
2567 | 2574 | ||
2568 | /* Do the sync with the old mode to allow it to clean up */ | 2575 | /* Do the sync with the old mode to allow it to clean up */ |
2569 | snd_soc_dapm_sync(&codec->dapm); | 2576 | snd_soc_dapm_sync_unlocked(dapm); |
2570 | wm8994->vmid_mode = mode; | 2577 | wm8994->vmid_mode = mode; |
2578 | |||
2579 | snd_soc_dapm_mutex_unlock(dapm); | ||
2571 | break; | 2580 | break; |
2572 | 2581 | ||
2573 | case WM8994_VMID_FORCE: | 2582 | case WM8994_VMID_FORCE: |
2583 | snd_soc_dapm_mutex_lock(dapm); | ||
2584 | |||
2574 | if (wm8994->hubs.lineout1_se) { | 2585 | if (wm8994->hubs.lineout1_se) { |
2575 | snd_soc_dapm_force_enable_pin(&codec->dapm, | 2586 | snd_soc_dapm_force_enable_pin_unlocked(dapm, |
2576 | "LINEOUT1N Driver"); | 2587 | "LINEOUT1N Driver"); |
2577 | snd_soc_dapm_force_enable_pin(&codec->dapm, | 2588 | snd_soc_dapm_force_enable_pin_unlocked(dapm, |
2578 | "LINEOUT1P Driver"); | 2589 | "LINEOUT1P Driver"); |
2579 | } | 2590 | } |
2580 | if (wm8994->hubs.lineout2_se) { | 2591 | if (wm8994->hubs.lineout2_se) { |
2581 | snd_soc_dapm_force_enable_pin(&codec->dapm, | 2592 | snd_soc_dapm_force_enable_pin_unlocked(dapm, |
2582 | "LINEOUT2N Driver"); | 2593 | "LINEOUT2N Driver"); |
2583 | snd_soc_dapm_force_enable_pin(&codec->dapm, | 2594 | snd_soc_dapm_force_enable_pin_unlocked(dapm, |
2584 | "LINEOUT2P Driver"); | 2595 | "LINEOUT2P Driver"); |
2585 | } | 2596 | } |
2586 | 2597 | ||
2587 | wm8994->vmid_mode = mode; | 2598 | wm8994->vmid_mode = mode; |
2588 | snd_soc_dapm_sync(&codec->dapm); | 2599 | snd_soc_dapm_sync_unlocked(dapm); |
2600 | |||
2601 | snd_soc_dapm_mutex_unlock(dapm); | ||
2589 | break; | 2602 | break; |
2590 | 2603 | ||
2591 | default: | 2604 | default: |
@@ -3237,7 +3250,7 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | |||
3237 | dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", | 3250 | dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", |
3238 | wm8994->num_retune_mobile_texts); | 3251 | wm8994->num_retune_mobile_texts); |
3239 | 3252 | ||
3240 | wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; | 3253 | wm8994->retune_mobile_enum.items = wm8994->num_retune_mobile_texts; |
3241 | wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; | 3254 | wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; |
3242 | 3255 | ||
3243 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, | 3256 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, |
@@ -3293,7 +3306,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
3293 | for (i = 0; i < pdata->num_drc_cfgs; i++) | 3306 | for (i = 0; i < pdata->num_drc_cfgs; i++) |
3294 | wm8994->drc_texts[i] = pdata->drc_cfgs[i].name; | 3307 | wm8994->drc_texts[i] = pdata->drc_cfgs[i].name; |
3295 | 3308 | ||
3296 | wm8994->drc_enum.max = pdata->num_drc_cfgs; | 3309 | wm8994->drc_enum.items = pdata->num_drc_cfgs; |
3297 | wm8994->drc_enum.texts = wm8994->drc_texts; | 3310 | wm8994->drc_enum.texts = wm8994->drc_texts; |
3298 | 3311 | ||
3299 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, | 3312 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, |
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 4300caff1783..ddb197dc1d53 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c | |||
@@ -423,24 +423,24 @@ static const char *in1l_text[] = { | |||
423 | "Differential", "Single-ended IN1LN", "Single-ended IN1LP" | 423 | "Differential", "Single-ended IN1LN", "Single-ended IN1LP" |
424 | }; | 424 | }; |
425 | 425 | ||
426 | static const SOC_ENUM_SINGLE_DECL(in1l_enum, WM8995_LEFT_LINE_INPUT_CONTROL, | 426 | static SOC_ENUM_SINGLE_DECL(in1l_enum, WM8995_LEFT_LINE_INPUT_CONTROL, |
427 | 2, in1l_text); | 427 | 2, in1l_text); |
428 | 428 | ||
429 | static const char *in1r_text[] = { | 429 | static const char *in1r_text[] = { |
430 | "Differential", "Single-ended IN1RN", "Single-ended IN1RP" | 430 | "Differential", "Single-ended IN1RN", "Single-ended IN1RP" |
431 | }; | 431 | }; |
432 | 432 | ||
433 | static const SOC_ENUM_SINGLE_DECL(in1r_enum, WM8995_LEFT_LINE_INPUT_CONTROL, | 433 | static SOC_ENUM_SINGLE_DECL(in1r_enum, WM8995_LEFT_LINE_INPUT_CONTROL, |
434 | 0, in1r_text); | 434 | 0, in1r_text); |
435 | 435 | ||
436 | static const char *dmic_src_text[] = { | 436 | static const char *dmic_src_text[] = { |
437 | "DMICDAT1", "DMICDAT2", "DMICDAT3" | 437 | "DMICDAT1", "DMICDAT2", "DMICDAT3" |
438 | }; | 438 | }; |
439 | 439 | ||
440 | static const SOC_ENUM_SINGLE_DECL(dmic_src1_enum, WM8995_POWER_MANAGEMENT_5, | 440 | static SOC_ENUM_SINGLE_DECL(dmic_src1_enum, WM8995_POWER_MANAGEMENT_5, |
441 | 8, dmic_src_text); | 441 | 8, dmic_src_text); |
442 | static const SOC_ENUM_SINGLE_DECL(dmic_src2_enum, WM8995_POWER_MANAGEMENT_5, | 442 | static SOC_ENUM_SINGLE_DECL(dmic_src2_enum, WM8995_POWER_MANAGEMENT_5, |
443 | 6, dmic_src_text); | 443 | 6, dmic_src_text); |
444 | 444 | ||
445 | static const struct snd_kcontrol_new wm8995_snd_controls[] = { | 445 | static const struct snd_kcontrol_new wm8995_snd_controls[] = { |
446 | SOC_DOUBLE_R_TLV("DAC1 Volume", WM8995_DAC1_LEFT_VOLUME, | 446 | SOC_DOUBLE_R_TLV("DAC1 Volume", WM8995_DAC1_LEFT_VOLUME, |
@@ -561,10 +561,8 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w, | |||
561 | struct snd_kcontrol *kcontrol, int event) | 561 | struct snd_kcontrol *kcontrol, int event) |
562 | { | 562 | { |
563 | struct snd_soc_codec *codec; | 563 | struct snd_soc_codec *codec; |
564 | struct wm8995_priv *wm8995; | ||
565 | 564 | ||
566 | codec = w->codec; | 565 | codec = w->codec; |
567 | wm8995 = snd_soc_codec_get_drvdata(codec); | ||
568 | 566 | ||
569 | switch (event) { | 567 | switch (event) { |
570 | case SND_SOC_DAPM_PRE_PMU: | 568 | case SND_SOC_DAPM_PRE_PMU: |
@@ -783,14 +781,12 @@ static const char *sidetone_text[] = { | |||
783 | "ADC/DMIC1", "DMIC2", | 781 | "ADC/DMIC1", "DMIC2", |
784 | }; | 782 | }; |
785 | 783 | ||
786 | static const struct soc_enum sidetone1_enum = | 784 | static SOC_ENUM_SINGLE_DECL(sidetone1_enum, WM8995_SIDETONE, 0, sidetone_text); |
787 | SOC_ENUM_SINGLE(WM8995_SIDETONE, 0, 2, sidetone_text); | ||
788 | 785 | ||
789 | static const struct snd_kcontrol_new sidetone1_mux = | 786 | static const struct snd_kcontrol_new sidetone1_mux = |
790 | SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); | 787 | SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); |
791 | 788 | ||
792 | static const struct soc_enum sidetone2_enum = | 789 | static SOC_ENUM_SINGLE_DECL(sidetone2_enum, WM8995_SIDETONE, 1, sidetone_text); |
793 | SOC_ENUM_SINGLE(WM8995_SIDETONE, 1, 2, sidetone_text); | ||
794 | 790 | ||
795 | static const struct snd_kcontrol_new sidetone2_mux = | 791 | static const struct snd_kcontrol_new sidetone2_mux = |
796 | SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); | 792 | SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); |
@@ -886,8 +882,7 @@ static const char *adc_mux_text[] = { | |||
886 | "DMIC", | 882 | "DMIC", |
887 | }; | 883 | }; |
888 | 884 | ||
889 | static const struct soc_enum adc_enum = | 885 | static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text); |
890 | SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text); | ||
891 | 886 | ||
892 | static const struct snd_kcontrol_new adcl_mux = | 887 | static const struct snd_kcontrol_new adcl_mux = |
893 | SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); | 888 | SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); |
@@ -899,14 +894,14 @@ static const char *spk_src_text[] = { | |||
899 | "DAC1L", "DAC1R", "DAC2L", "DAC2R" | 894 | "DAC1L", "DAC1R", "DAC2L", "DAC2R" |
900 | }; | 895 | }; |
901 | 896 | ||
902 | static const SOC_ENUM_SINGLE_DECL(spk1l_src_enum, WM8995_LEFT_PDM_SPEAKER_1, | 897 | static SOC_ENUM_SINGLE_DECL(spk1l_src_enum, WM8995_LEFT_PDM_SPEAKER_1, |
903 | 0, spk_src_text); | 898 | 0, spk_src_text); |
904 | static const SOC_ENUM_SINGLE_DECL(spk1r_src_enum, WM8995_RIGHT_PDM_SPEAKER_1, | 899 | static SOC_ENUM_SINGLE_DECL(spk1r_src_enum, WM8995_RIGHT_PDM_SPEAKER_1, |
905 | 0, spk_src_text); | 900 | 0, spk_src_text); |
906 | static const SOC_ENUM_SINGLE_DECL(spk2l_src_enum, WM8995_LEFT_PDM_SPEAKER_2, | 901 | static SOC_ENUM_SINGLE_DECL(spk2l_src_enum, WM8995_LEFT_PDM_SPEAKER_2, |
907 | 0, spk_src_text); | 902 | 0, spk_src_text); |
908 | static const SOC_ENUM_SINGLE_DECL(spk2r_src_enum, WM8995_RIGHT_PDM_SPEAKER_2, | 903 | static SOC_ENUM_SINGLE_DECL(spk2r_src_enum, WM8995_RIGHT_PDM_SPEAKER_2, |
909 | 0, spk_src_text); | 904 | 0, spk_src_text); |
910 | 905 | ||
911 | static const struct snd_kcontrol_new spk1l_mux = | 906 | static const struct snd_kcontrol_new spk1l_mux = |
912 | SOC_DAPM_ENUM("SPK1L SRC", spk1l_src_enum); | 907 | SOC_DAPM_ENUM("SPK1L SRC", spk1l_src_enum); |
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 1a7655b0aa22..0330165079a4 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -2251,6 +2251,7 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
2251 | wm8996_polarity_fn polarity_cb) | 2251 | wm8996_polarity_fn polarity_cb) |
2252 | { | 2252 | { |
2253 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | 2253 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); |
2254 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
2254 | 2255 | ||
2255 | wm8996->jack = jack; | 2256 | wm8996->jack = jack; |
2256 | wm8996->detecting = true; | 2257 | wm8996->detecting = true; |
@@ -2267,8 +2268,12 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
2267 | WM8996_MICB2_DISCH, 0); | 2268 | WM8996_MICB2_DISCH, 0); |
2268 | 2269 | ||
2269 | /* LDO2 powers the microphones, SYSCLK clocks detection */ | 2270 | /* LDO2 powers the microphones, SYSCLK clocks detection */ |
2270 | snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); | 2271 | snd_soc_dapm_mutex_lock(dapm); |
2271 | snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); | 2272 | |
2273 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO2"); | ||
2274 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK"); | ||
2275 | |||
2276 | snd_soc_dapm_mutex_unlock(dapm); | ||
2272 | 2277 | ||
2273 | /* We start off just enabling microphone detection - even a | 2278 | /* We start off just enabling microphone detection - even a |
2274 | * plain headphone will trigger detection. | 2279 | * plain headphone will trigger detection. |
@@ -2595,7 +2600,7 @@ static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec) | |||
2595 | dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", | 2600 | dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", |
2596 | wm8996->num_retune_mobile_texts); | 2601 | wm8996->num_retune_mobile_texts); |
2597 | 2602 | ||
2598 | wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts; | 2603 | wm8996->retune_mobile_enum.items = wm8996->num_retune_mobile_texts; |
2599 | wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts; | 2604 | wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts; |
2600 | 2605 | ||
2601 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); | 2606 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); |
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 555115ee2159..e10f44d7fdb7 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c | |||
@@ -86,7 +86,7 @@ static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w, | |||
86 | { | 86 | { |
87 | struct snd_soc_codec *codec = w->codec; | 87 | struct snd_soc_codec *codec = w->codec; |
88 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | 88 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); |
89 | struct regmap *regmap = codec->control_data; | 89 | struct regmap *regmap = arizona->regmap; |
90 | const struct reg_default *patch = NULL; | 90 | const struct reg_default *patch = NULL; |
91 | int i, patch_size; | 91 | int i, patch_size; |
92 | 92 | ||
@@ -123,10 +123,12 @@ static const unsigned int wm8997_osr_val[] = { | |||
123 | 123 | ||
124 | static const struct soc_enum wm8997_hpout_osr[] = { | 124 | static const struct soc_enum wm8997_hpout_osr[] = { |
125 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, | 125 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, |
126 | ARIZONA_OUT1_OSR_SHIFT, 0x7, 3, | 126 | ARIZONA_OUT1_OSR_SHIFT, 0x7, |
127 | ARRAY_SIZE(wm8997_osr_text), | ||
127 | wm8997_osr_text, wm8997_osr_val), | 128 | wm8997_osr_text, wm8997_osr_val), |
128 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, | 129 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, |
129 | ARIZONA_OUT3_OSR_SHIFT, 0x7, 3, | 130 | ARIZONA_OUT3_OSR_SHIFT, 0x7, |
131 | ARRAY_SIZE(wm8997_osr_text), | ||
130 | wm8997_osr_text, wm8997_osr_val), | 132 | wm8997_osr_text, wm8997_osr_val), |
131 | }; | 133 | }; |
132 | 134 | ||
@@ -170,15 +172,8 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), | |||
170 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), | 172 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), |
171 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), | 173 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), |
172 | 174 | ||
173 | SND_SOC_BYTES_MASK("EQ1 Coefficients", ARIZONA_EQ1_1, 21, | 175 | SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19), |
174 | ARIZONA_EQ1_ENA_MASK), | 176 | SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE, 1, 0), |
175 | SND_SOC_BYTES_MASK("EQ2 Coefficients", ARIZONA_EQ2_1, 21, | ||
176 | ARIZONA_EQ2_ENA_MASK), | ||
177 | SND_SOC_BYTES_MASK("EQ3 Coefficients", ARIZONA_EQ3_1, 21, | ||
178 | ARIZONA_EQ3_ENA_MASK), | ||
179 | SND_SOC_BYTES_MASK("EQ4 Coefficients", ARIZONA_EQ4_1, 21, | ||
180 | ARIZONA_EQ4_ENA_MASK), | ||
181 | |||
182 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, | 177 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, |
183 | 24, 0, eq_tlv), | 178 | 24, 0, eq_tlv), |
184 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, | 179 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, |
@@ -190,6 +185,8 @@ SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT, | |||
190 | SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, | 185 | SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, |
191 | 24, 0, eq_tlv), | 186 | 24, 0, eq_tlv), |
192 | 187 | ||
188 | SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19), | ||
189 | SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE, 1, 0), | ||
193 | SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, | 190 | SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, |
194 | 24, 0, eq_tlv), | 191 | 24, 0, eq_tlv), |
195 | SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, | 192 | SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, |
@@ -201,6 +198,8 @@ SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT, | |||
201 | SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, | 198 | SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, |
202 | 24, 0, eq_tlv), | 199 | 24, 0, eq_tlv), |
203 | 200 | ||
201 | SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19), | ||
202 | SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE, 1, 0), | ||
204 | SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, | 203 | SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, |
205 | 24, 0, eq_tlv), | 204 | 24, 0, eq_tlv), |
206 | SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, | 205 | SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, |
@@ -212,6 +211,8 @@ SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT, | |||
212 | SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, | 211 | SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, |
213 | 24, 0, eq_tlv), | 212 | 24, 0, eq_tlv), |
214 | 213 | ||
214 | SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19), | ||
215 | SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE, 1, 0), | ||
215 | SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, | 216 | SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, |
216 | 24, 0, eq_tlv), | 217 | 24, 0, eq_tlv), |
217 | SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, | 218 | SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, |
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 444626fcab40..bb5f7b4e3ebb 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -684,24 +684,38 @@ static int wm_adsp_load(struct wm_adsp *dsp) | |||
684 | } | 684 | } |
685 | 685 | ||
686 | if (reg) { | 686 | if (reg) { |
687 | buf = wm_adsp_buf_alloc(region->data, | 687 | size_t to_write = PAGE_SIZE; |
688 | le32_to_cpu(region->len), | 688 | size_t remain = le32_to_cpu(region->len); |
689 | &buf_list); | 689 | const u8 *data = region->data; |
690 | if (!buf) { | 690 | |
691 | adsp_err(dsp, "Out of memory\n"); | 691 | while (remain > 0) { |
692 | ret = -ENOMEM; | 692 | if (remain < PAGE_SIZE) |
693 | goto out_fw; | 693 | to_write = remain; |
694 | } | 694 | |
695 | buf = wm_adsp_buf_alloc(data, | ||
696 | to_write, | ||
697 | &buf_list); | ||
698 | if (!buf) { | ||
699 | adsp_err(dsp, "Out of memory\n"); | ||
700 | ret = -ENOMEM; | ||
701 | goto out_fw; | ||
702 | } | ||
695 | 703 | ||
696 | ret = regmap_raw_write_async(regmap, reg, buf->buf, | 704 | ret = regmap_raw_write_async(regmap, reg, |
697 | le32_to_cpu(region->len)); | 705 | buf->buf, |
698 | if (ret != 0) { | 706 | to_write); |
699 | adsp_err(dsp, | 707 | if (ret != 0) { |
700 | "%s.%d: Failed to write %d bytes at %d in %s: %d\n", | 708 | adsp_err(dsp, |
701 | file, regions, | 709 | "%s.%d: Failed to write %zd bytes at %d in %s: %d\n", |
702 | le32_to_cpu(region->len), offset, | 710 | file, regions, |
703 | region_name, ret); | 711 | to_write, offset, |
704 | goto out_fw; | 712 | region_name, ret); |
713 | goto out_fw; | ||
714 | } | ||
715 | |||
716 | data += to_write; | ||
717 | reg += to_write / 2; | ||
718 | remain -= to_write; | ||
705 | } | 719 | } |
706 | } | 720 | } |
707 | 721 | ||
@@ -1679,6 +1693,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
1679 | list_del(&alg_region->list); | 1693 | list_del(&alg_region->list); |
1680 | kfree(alg_region); | 1694 | kfree(alg_region); |
1681 | } | 1695 | } |
1696 | |||
1697 | adsp_dbg(dsp, "Shutdown complete\n"); | ||
1682 | break; | 1698 | break; |
1683 | 1699 | ||
1684 | default: | 1700 | default: |
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 70ff3772079f..5e3bc3c6801a 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c | |||
@@ -399,6 +399,7 @@ static struct platform_driver davinci_evm_driver = { | |||
399 | .driver = { | 399 | .driver = { |
400 | .name = "davinci_evm", | 400 | .name = "davinci_evm", |
401 | .owner = THIS_MODULE, | 401 | .owner = THIS_MODULE, |
402 | .pm = &snd_soc_pm_ops, | ||
402 | .of_match_table = of_match_ptr(davinci_evm_dt_ids), | 403 | .of_match_table = of_match_ptr(davinci_evm_dt_ids), |
403 | }, | 404 | }, |
404 | }; | 405 | }; |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index b7858bfa0295..670afa29e30d 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -263,7 +263,9 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
263 | unsigned int fmt) | 263 | unsigned int fmt) |
264 | { | 264 | { |
265 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); | 265 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); |
266 | int ret = 0; | ||
266 | 267 | ||
268 | pm_runtime_get_sync(mcasp->dev); | ||
267 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 269 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
268 | case SND_SOC_DAIFMT_DSP_B: | 270 | case SND_SOC_DAIFMT_DSP_B: |
269 | case SND_SOC_DAIFMT_AC97: | 271 | case SND_SOC_DAIFMT_AC97: |
@@ -317,7 +319,8 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
317 | break; | 319 | break; |
318 | 320 | ||
319 | default: | 321 | default: |
320 | return -EINVAL; | 322 | ret = -EINVAL; |
323 | goto out; | ||
321 | } | 324 | } |
322 | 325 | ||
323 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 326 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
@@ -354,10 +357,12 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
354 | break; | 357 | break; |
355 | 358 | ||
356 | default: | 359 | default: |
357 | return -EINVAL; | 360 | ret = -EINVAL; |
361 | break; | ||
358 | } | 362 | } |
359 | 363 | out: | |
360 | return 0; | 364 | pm_runtime_put_sync(mcasp->dev); |
365 | return ret; | ||
361 | } | 366 | } |
362 | 367 | ||
363 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) | 368 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) |
@@ -448,7 +453,7 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, | |||
448 | return 0; | 453 | return 0; |
449 | } | 454 | } |
450 | 455 | ||
451 | static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, | 456 | static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, |
452 | int channels) | 457 | int channels) |
453 | { | 458 | { |
454 | int i; | 459 | int i; |
@@ -524,12 +529,18 @@ static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, | |||
524 | return 0; | 529 | return 0; |
525 | } | 530 | } |
526 | 531 | ||
527 | static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream) | 532 | static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream) |
528 | { | 533 | { |
529 | int i, active_slots; | 534 | int i, active_slots; |
530 | u32 mask = 0; | 535 | u32 mask = 0; |
531 | u32 busel = 0; | 536 | u32 busel = 0; |
532 | 537 | ||
538 | if ((mcasp->tdm_slots < 2) || (mcasp->tdm_slots > 32)) { | ||
539 | dev_err(mcasp->dev, "tdm slot %d not supported\n", | ||
540 | mcasp->tdm_slots); | ||
541 | return -EINVAL; | ||
542 | } | ||
543 | |||
533 | active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots; | 544 | active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots; |
534 | for (i = 0; i < active_slots; i++) | 545 | for (i = 0; i < active_slots; i++) |
535 | mask |= (1 << i); | 546 | mask |= (1 << i); |
@@ -539,35 +550,21 @@ static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream) | |||
539 | if (!mcasp->dat_port) | 550 | if (!mcasp->dat_port) |
540 | busel = TXSEL; | 551 | busel = TXSEL; |
541 | 552 | ||
542 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 553 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); |
543 | /* bit stream is MSB first with no delay */ | 554 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); |
544 | /* DSP_B mode */ | 555 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, |
545 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); | 556 | FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF)); |
546 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); | 557 | |
547 | 558 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); | |
548 | if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) | 559 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); |
549 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, | 560 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, |
550 | FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF)); | 561 | FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF)); |
551 | else | 562 | |
552 | printk(KERN_ERR "playback tdm slot %d not supported\n", | 563 | return 0; |
553 | mcasp->tdm_slots); | ||
554 | } else { | ||
555 | /* bit stream is MSB first with no delay */ | ||
556 | /* DSP_B mode */ | ||
557 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); | ||
558 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); | ||
559 | |||
560 | if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) | ||
561 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, | ||
562 | FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF)); | ||
563 | else | ||
564 | printk(KERN_ERR "capture tdm slot %d not supported\n", | ||
565 | mcasp->tdm_slots); | ||
566 | } | ||
567 | } | 564 | } |
568 | 565 | ||
569 | /* S/PDIF */ | 566 | /* S/PDIF */ |
570 | static void davinci_hw_dit_param(struct davinci_mcasp *mcasp) | 567 | static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp) |
571 | { | 568 | { |
572 | /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 | 569 | /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 |
573 | and LSB first */ | 570 | and LSB first */ |
@@ -589,6 +586,8 @@ static void davinci_hw_dit_param(struct davinci_mcasp *mcasp) | |||
589 | 586 | ||
590 | /* Enable the DIT */ | 587 | /* Enable the DIT */ |
591 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); | 588 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); |
589 | |||
590 | return 0; | ||
592 | } | 591 | } |
593 | 592 | ||
594 | static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | 593 | static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, |
@@ -605,13 +604,14 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
605 | u8 slots = mcasp->tdm_slots; | 604 | u8 slots = mcasp->tdm_slots; |
606 | u8 active_serializers; | 605 | u8 active_serializers; |
607 | int channels; | 606 | int channels; |
607 | int ret; | ||
608 | struct snd_interval *pcm_channels = hw_param_interval(params, | 608 | struct snd_interval *pcm_channels = hw_param_interval(params, |
609 | SNDRV_PCM_HW_PARAM_CHANNELS); | 609 | SNDRV_PCM_HW_PARAM_CHANNELS); |
610 | channels = pcm_channels->min; | 610 | channels = pcm_channels->min; |
611 | 611 | ||
612 | active_serializers = (channels + slots - 1) / slots; | 612 | active_serializers = (channels + slots - 1) / slots; |
613 | 613 | ||
614 | if (davinci_hw_common_param(mcasp, substream->stream, channels) == -EINVAL) | 614 | if (mcasp_common_hw_param(mcasp, substream->stream, channels) == -EINVAL) |
615 | return -EINVAL; | 615 | return -EINVAL; |
616 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 616 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
617 | fifo_level = mcasp->txnumevt * active_serializers; | 617 | fifo_level = mcasp->txnumevt * active_serializers; |
@@ -619,9 +619,12 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
619 | fifo_level = mcasp->rxnumevt * active_serializers; | 619 | fifo_level = mcasp->rxnumevt * active_serializers; |
620 | 620 | ||
621 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) | 621 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) |
622 | davinci_hw_dit_param(mcasp); | 622 | ret = mcasp_dit_hw_param(mcasp); |
623 | else | 623 | else |
624 | davinci_hw_param(mcasp, substream->stream); | 624 | ret = mcasp_i2s_hw_param(mcasp, substream->stream); |
625 | |||
626 | if (ret) | ||
627 | return ret; | ||
625 | 628 | ||
626 | switch (params_format(params)) { | 629 | switch (params_format(params)) { |
627 | case SNDRV_PCM_FORMAT_U8: | 630 | case SNDRV_PCM_FORMAT_U8: |
@@ -678,19 +681,9 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, | |||
678 | case SNDRV_PCM_TRIGGER_RESUME: | 681 | case SNDRV_PCM_TRIGGER_RESUME: |
679 | case SNDRV_PCM_TRIGGER_START: | 682 | case SNDRV_PCM_TRIGGER_START: |
680 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 683 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
681 | ret = pm_runtime_get_sync(mcasp->dev); | ||
682 | if (IS_ERR_VALUE(ret)) | ||
683 | dev_err(mcasp->dev, "pm_runtime_get_sync() failed\n"); | ||
684 | davinci_mcasp_start(mcasp, substream->stream); | 684 | davinci_mcasp_start(mcasp, substream->stream); |
685 | break; | 685 | break; |
686 | |||
687 | case SNDRV_PCM_TRIGGER_SUSPEND: | 686 | case SNDRV_PCM_TRIGGER_SUSPEND: |
688 | davinci_mcasp_stop(mcasp, substream->stream); | ||
689 | ret = pm_runtime_put_sync(mcasp->dev); | ||
690 | if (IS_ERR_VALUE(ret)) | ||
691 | dev_err(mcasp->dev, "pm_runtime_put_sync() failed\n"); | ||
692 | break; | ||
693 | |||
694 | case SNDRV_PCM_TRIGGER_STOP: | 687 | case SNDRV_PCM_TRIGGER_STOP: |
695 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 688 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
696 | davinci_mcasp_stop(mcasp, substream->stream); | 689 | davinci_mcasp_stop(mcasp, substream->stream); |
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index d0c72ed261e7..c84026c99134 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -326,7 +326,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | |||
326 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, | 326 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, |
327 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); | 327 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); |
328 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, | 328 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, |
329 | ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(tx_mask)); | 329 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask)); |
330 | 330 | ||
331 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, | 331 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, |
332 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); | 332 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); |
@@ -334,7 +334,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | |||
334 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, | 334 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, |
335 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); | 335 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); |
336 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, | 336 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, |
337 | ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(rx_mask)); | 337 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); |
338 | 338 | ||
339 | esai_priv->slot_width = slot_width; | 339 | esai_priv->slot_width = slot_width; |
340 | 340 | ||
diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h index 9c9f957fcae1..75e14033e8d8 100644 --- a/sound/soc/fsl/fsl_esai.h +++ b/sound/soc/fsl/fsl_esai.h | |||
@@ -322,7 +322,7 @@ | |||
322 | #define ESAI_xSMB_xS_SHIFT 0 | 322 | #define ESAI_xSMB_xS_SHIFT 0 |
323 | #define ESAI_xSMB_xS_WIDTH 16 | 323 | #define ESAI_xSMB_xS_WIDTH 16 |
324 | #define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT) | 324 | #define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT) |
325 | #define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMA_xS_MASK) | 325 | #define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMB_xS_MASK) |
326 | 326 | ||
327 | /* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */ | 327 | /* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */ |
328 | #define ESAI_PRRC_PDC_SHIFT 0 | 328 | #define ESAI_PRRC_PDC_SHIFT 0 |
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c index 79cee782dbbf..a2fd7321b5a9 100644 --- a/sound/soc/fsl/imx-mc13783.c +++ b/sound/soc/fsl/imx-mc13783.c | |||
@@ -160,7 +160,6 @@ static struct platform_driver imx_mc13783_audio_driver = { | |||
160 | .driver = { | 160 | .driver = { |
161 | .name = "imx_mc13783", | 161 | .name = "imx_mc13783", |
162 | .owner = THIS_MODULE, | 162 | .owner = THIS_MODULE, |
163 | .pm = &snd_soc_pm_ops, | ||
164 | }, | 163 | }, |
165 | .probe = imx_mc13783_probe, | 164 | .probe = imx_mc13783_probe, |
166 | .remove = imx_mc13783_remove | 165 | .remove = imx_mc13783_remove |
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index f2beae78969f..1cb22dd034eb 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c | |||
@@ -33,8 +33,7 @@ struct imx_sgtl5000_data { | |||
33 | 33 | ||
34 | static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd) | 34 | static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd) |
35 | { | 35 | { |
36 | struct imx_sgtl5000_data *data = container_of(rtd->card, | 36 | struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(rtd->card); |
37 | struct imx_sgtl5000_data, card); | ||
38 | struct device *dev = rtd->card->dev; | 37 | struct device *dev = rtd->card->dev; |
39 | int ret; | 38 | int ret; |
40 | 39 | ||
@@ -159,13 +158,15 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) | |||
159 | data->card.dapm_widgets = imx_sgtl5000_dapm_widgets; | 158 | data->card.dapm_widgets = imx_sgtl5000_dapm_widgets; |
160 | data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets); | 159 | data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets); |
161 | 160 | ||
161 | platform_set_drvdata(pdev, &data->card); | ||
162 | snd_soc_card_set_drvdata(&data->card, data); | ||
163 | |||
162 | ret = devm_snd_soc_register_card(&pdev->dev, &data->card); | 164 | ret = devm_snd_soc_register_card(&pdev->dev, &data->card); |
163 | if (ret) { | 165 | if (ret) { |
164 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); | 166 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); |
165 | goto fail; | 167 | goto fail; |
166 | } | 168 | } |
167 | 169 | ||
168 | platform_set_drvdata(pdev, data); | ||
169 | of_node_put(ssi_np); | 170 | of_node_put(ssi_np); |
170 | of_node_put(codec_np); | 171 | of_node_put(codec_np); |
171 | 172 | ||
@@ -184,7 +185,8 @@ fail: | |||
184 | 185 | ||
185 | static int imx_sgtl5000_remove(struct platform_device *pdev) | 186 | static int imx_sgtl5000_remove(struct platform_device *pdev) |
186 | { | 187 | { |
187 | struct imx_sgtl5000_data *data = platform_get_drvdata(pdev); | 188 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
189 | struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(card); | ||
188 | 190 | ||
189 | clk_put(data->codec_clk); | 191 | clk_put(data->codec_clk); |
190 | 192 | ||
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c index 3fd76bc391de..3a3d17ce6ba4 100644 --- a/sound/soc/fsl/imx-wm8962.c +++ b/sound/soc/fsl/imx-wm8962.c | |||
@@ -71,7 +71,7 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card, | |||
71 | { | 71 | { |
72 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 72 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; |
73 | struct imx_priv *priv = &card_priv; | 73 | struct imx_priv *priv = &card_priv; |
74 | struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev); | 74 | struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); |
75 | struct device *dev = &priv->pdev->dev; | 75 | struct device *dev = &priv->pdev->dev; |
76 | unsigned int pll_out; | 76 | unsigned int pll_out; |
77 | int ret; | 77 | int ret; |
@@ -137,7 +137,7 @@ static int imx_wm8962_late_probe(struct snd_soc_card *card) | |||
137 | { | 137 | { |
138 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 138 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; |
139 | struct imx_priv *priv = &card_priv; | 139 | struct imx_priv *priv = &card_priv; |
140 | struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev); | 140 | struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); |
141 | struct device *dev = &priv->pdev->dev; | 141 | struct device *dev = &priv->pdev->dev; |
142 | int ret; | 142 | int ret; |
143 | 143 | ||
@@ -264,13 +264,15 @@ static int imx_wm8962_probe(struct platform_device *pdev) | |||
264 | data->card.late_probe = imx_wm8962_late_probe; | 264 | data->card.late_probe = imx_wm8962_late_probe; |
265 | data->card.set_bias_level = imx_wm8962_set_bias_level; | 265 | data->card.set_bias_level = imx_wm8962_set_bias_level; |
266 | 266 | ||
267 | platform_set_drvdata(pdev, &data->card); | ||
268 | snd_soc_card_set_drvdata(&data->card, data); | ||
269 | |||
267 | ret = devm_snd_soc_register_card(&pdev->dev, &data->card); | 270 | ret = devm_snd_soc_register_card(&pdev->dev, &data->card); |
268 | if (ret) { | 271 | if (ret) { |
269 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); | 272 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); |
270 | goto clk_fail; | 273 | goto clk_fail; |
271 | } | 274 | } |
272 | 275 | ||
273 | platform_set_drvdata(pdev, data); | ||
274 | of_node_put(ssi_np); | 276 | of_node_put(ssi_np); |
275 | of_node_put(codec_np); | 277 | of_node_put(codec_np); |
276 | 278 | ||
@@ -289,7 +291,8 @@ fail: | |||
289 | 291 | ||
290 | static int imx_wm8962_remove(struct platform_device *pdev) | 292 | static int imx_wm8962_remove(struct platform_device *pdev) |
291 | { | 293 | { |
292 | struct imx_wm8962_data *data = platform_get_drvdata(pdev); | 294 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
295 | struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); | ||
293 | 296 | ||
294 | if (!IS_ERR(data->codec_clk)) | 297 | if (!IS_ERR(data->codec_clk)) |
295 | clk_disable_unprepare(data->codec_clk); | 298 | clk_disable_unprepare(data->codec_clk); |
diff --git a/sound/soc/intel/mfld_machine.c b/sound/soc/intel/mfld_machine.c index d3d4c32434f7..0cef32e9d402 100644 --- a/sound/soc/intel/mfld_machine.c +++ b/sound/soc/intel/mfld_machine.c | |||
@@ -101,20 +101,27 @@ static int headset_set_switch(struct snd_kcontrol *kcontrol, | |||
101 | struct snd_ctl_elem_value *ucontrol) | 101 | struct snd_ctl_elem_value *ucontrol) |
102 | { | 102 | { |
103 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 103 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
104 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
104 | 105 | ||
105 | if (ucontrol->value.integer.value[0] == hs_switch) | 106 | if (ucontrol->value.integer.value[0] == hs_switch) |
106 | return 0; | 107 | return 0; |
107 | 108 | ||
109 | snd_soc_dapm_mutex_lock(dapm); | ||
110 | |||
108 | if (ucontrol->value.integer.value[0]) { | 111 | if (ucontrol->value.integer.value[0]) { |
109 | pr_debug("hs_set HS path\n"); | 112 | pr_debug("hs_set HS path\n"); |
110 | snd_soc_dapm_enable_pin(&codec->dapm, "Headphones"); | 113 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones"); |
111 | snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); | 114 | snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT"); |
112 | } else { | 115 | } else { |
113 | pr_debug("hs_set EP path\n"); | 116 | pr_debug("hs_set EP path\n"); |
114 | snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); | 117 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones"); |
115 | snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); | 118 | snd_soc_dapm_enable_pin_unlocked(dapm, "EPOUT"); |
116 | } | 119 | } |
117 | snd_soc_dapm_sync(&codec->dapm); | 120 | |
121 | snd_soc_dapm_sync_unlocked(dapm); | ||
122 | |||
123 | snd_soc_dapm_mutex_unlock(dapm); | ||
124 | |||
118 | hs_switch = ucontrol->value.integer.value[0]; | 125 | hs_switch = ucontrol->value.integer.value[0]; |
119 | 126 | ||
120 | return 0; | 127 | return 0; |
@@ -122,18 +129,20 @@ static int headset_set_switch(struct snd_kcontrol *kcontrol, | |||
122 | 129 | ||
123 | static void lo_enable_out_pins(struct snd_soc_codec *codec) | 130 | static void lo_enable_out_pins(struct snd_soc_codec *codec) |
124 | { | 131 | { |
125 | snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTL"); | 132 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
126 | snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTR"); | 133 | |
127 | snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTL"); | 134 | snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTL"); |
128 | snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTR"); | 135 | snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTR"); |
129 | snd_soc_dapm_enable_pin(&codec->dapm, "VIB1OUT"); | 136 | snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTL"); |
130 | snd_soc_dapm_enable_pin(&codec->dapm, "VIB2OUT"); | 137 | snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTR"); |
138 | snd_soc_dapm_enable_pin_unlocked(dapm, "VIB1OUT"); | ||
139 | snd_soc_dapm_enable_pin_unlocked(dapm, "VIB2OUT"); | ||
131 | if (hs_switch) { | 140 | if (hs_switch) { |
132 | snd_soc_dapm_enable_pin(&codec->dapm, "Headphones"); | 141 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones"); |
133 | snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); | 142 | snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT"); |
134 | } else { | 143 | } else { |
135 | snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); | 144 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones"); |
136 | snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); | 145 | snd_soc_dapm_enable_pin_unlocked(dapm, "EPOUT"); |
137 | } | 146 | } |
138 | } | 147 | } |
139 | 148 | ||
@@ -148,44 +157,52 @@ static int lo_set_switch(struct snd_kcontrol *kcontrol, | |||
148 | struct snd_ctl_elem_value *ucontrol) | 157 | struct snd_ctl_elem_value *ucontrol) |
149 | { | 158 | { |
150 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 159 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
160 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
151 | 161 | ||
152 | if (ucontrol->value.integer.value[0] == lo_dac) | 162 | if (ucontrol->value.integer.value[0] == lo_dac) |
153 | return 0; | 163 | return 0; |
154 | 164 | ||
165 | snd_soc_dapm_mutex_lock(dapm); | ||
166 | |||
155 | /* we dont want to work with last state of lineout so just enable all | 167 | /* we dont want to work with last state of lineout so just enable all |
156 | * pins and then disable pins not required | 168 | * pins and then disable pins not required |
157 | */ | 169 | */ |
158 | lo_enable_out_pins(codec); | 170 | lo_enable_out_pins(codec); |
171 | |||
159 | switch (ucontrol->value.integer.value[0]) { | 172 | switch (ucontrol->value.integer.value[0]) { |
160 | case 0: | 173 | case 0: |
161 | pr_debug("set vibra path\n"); | 174 | pr_debug("set vibra path\n"); |
162 | snd_soc_dapm_disable_pin(&codec->dapm, "VIB1OUT"); | 175 | snd_soc_dapm_disable_pin_unlocked(dapm, "VIB1OUT"); |
163 | snd_soc_dapm_disable_pin(&codec->dapm, "VIB2OUT"); | 176 | snd_soc_dapm_disable_pin_unlocked(dapm, "VIB2OUT"); |
164 | snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0); | 177 | snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0); |
165 | break; | 178 | break; |
166 | 179 | ||
167 | case 1: | 180 | case 1: |
168 | pr_debug("set hs path\n"); | 181 | pr_debug("set hs path\n"); |
169 | snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); | 182 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones"); |
170 | snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); | 183 | snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT"); |
171 | snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22); | 184 | snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22); |
172 | break; | 185 | break; |
173 | 186 | ||
174 | case 2: | 187 | case 2: |
175 | pr_debug("set spkr path\n"); | 188 | pr_debug("set spkr path\n"); |
176 | snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTL"); | 189 | snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTL"); |
177 | snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTR"); | 190 | snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTR"); |
178 | snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x44); | 191 | snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x44); |
179 | break; | 192 | break; |
180 | 193 | ||
181 | case 3: | 194 | case 3: |
182 | pr_debug("set null path\n"); | 195 | pr_debug("set null path\n"); |
183 | snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTL"); | 196 | snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTL"); |
184 | snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTR"); | 197 | snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTR"); |
185 | snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66); | 198 | snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66); |
186 | break; | 199 | break; |
187 | } | 200 | } |
188 | snd_soc_dapm_sync(&codec->dapm); | 201 | |
202 | snd_soc_dapm_sync_unlocked(dapm); | ||
203 | |||
204 | snd_soc_dapm_mutex_unlock(dapm); | ||
205 | |||
189 | lo_dac = ucontrol->value.integer.value[0]; | 206 | lo_dac = ucontrol->value.integer.value[0]; |
190 | return 0; | 207 | return 0; |
191 | } | 208 | } |
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 629446482a91..8a5363674075 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c | |||
@@ -103,60 +103,62 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, | |||
103 | if (!codec->hw_write) | 103 | if (!codec->hw_write) |
104 | return -EUNATCH; | 104 | return -EUNATCH; |
105 | 105 | ||
106 | if (ucontrol->value.enumerated.item[0] >= control->max) | 106 | if (ucontrol->value.enumerated.item[0] >= control->items) |
107 | return -EINVAL; | 107 | return -EINVAL; |
108 | 108 | ||
109 | mutex_lock(&codec->mutex); | 109 | snd_soc_dapm_mutex_lock(dapm); |
110 | 110 | ||
111 | /* Translate selection to bitmap */ | 111 | /* Translate selection to bitmap */ |
112 | pins = ams_delta_audio_mode_pins[ucontrol->value.enumerated.item[0]]; | 112 | pins = ams_delta_audio_mode_pins[ucontrol->value.enumerated.item[0]]; |
113 | 113 | ||
114 | /* Setup pins after corresponding bits if changed */ | 114 | /* Setup pins after corresponding bits if changed */ |
115 | pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE)); | 115 | pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE)); |
116 | |||
116 | if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) { | 117 | if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) { |
117 | changed = 1; | 118 | changed = 1; |
118 | if (pin) | 119 | if (pin) |
119 | snd_soc_dapm_enable_pin(dapm, "Mouthpiece"); | 120 | snd_soc_dapm_enable_pin_unlocked(dapm, "Mouthpiece"); |
120 | else | 121 | else |
121 | snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); | 122 | snd_soc_dapm_disable_pin_unlocked(dapm, "Mouthpiece"); |
122 | } | 123 | } |
123 | pin = !!(pins & (1 << AMS_DELTA_EARPIECE)); | 124 | pin = !!(pins & (1 << AMS_DELTA_EARPIECE)); |
124 | if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) { | 125 | if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) { |
125 | changed = 1; | 126 | changed = 1; |
126 | if (pin) | 127 | if (pin) |
127 | snd_soc_dapm_enable_pin(dapm, "Earpiece"); | 128 | snd_soc_dapm_enable_pin_unlocked(dapm, "Earpiece"); |
128 | else | 129 | else |
129 | snd_soc_dapm_disable_pin(dapm, "Earpiece"); | 130 | snd_soc_dapm_disable_pin_unlocked(dapm, "Earpiece"); |
130 | } | 131 | } |
131 | pin = !!(pins & (1 << AMS_DELTA_MICROPHONE)); | 132 | pin = !!(pins & (1 << AMS_DELTA_MICROPHONE)); |
132 | if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) { | 133 | if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) { |
133 | changed = 1; | 134 | changed = 1; |
134 | if (pin) | 135 | if (pin) |
135 | snd_soc_dapm_enable_pin(dapm, "Microphone"); | 136 | snd_soc_dapm_enable_pin_unlocked(dapm, "Microphone"); |
136 | else | 137 | else |
137 | snd_soc_dapm_disable_pin(dapm, "Microphone"); | 138 | snd_soc_dapm_disable_pin_unlocked(dapm, "Microphone"); |
138 | } | 139 | } |
139 | pin = !!(pins & (1 << AMS_DELTA_SPEAKER)); | 140 | pin = !!(pins & (1 << AMS_DELTA_SPEAKER)); |
140 | if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) { | 141 | if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) { |
141 | changed = 1; | 142 | changed = 1; |
142 | if (pin) | 143 | if (pin) |
143 | snd_soc_dapm_enable_pin(dapm, "Speaker"); | 144 | snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker"); |
144 | else | 145 | else |
145 | snd_soc_dapm_disable_pin(dapm, "Speaker"); | 146 | snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker"); |
146 | } | 147 | } |
147 | pin = !!(pins & (1 << AMS_DELTA_AGC)); | 148 | pin = !!(pins & (1 << AMS_DELTA_AGC)); |
148 | if (pin != ams_delta_audio_agc) { | 149 | if (pin != ams_delta_audio_agc) { |
149 | ams_delta_audio_agc = pin; | 150 | ams_delta_audio_agc = pin; |
150 | changed = 1; | 151 | changed = 1; |
151 | if (pin) | 152 | if (pin) |
152 | snd_soc_dapm_enable_pin(dapm, "AGCIN"); | 153 | snd_soc_dapm_enable_pin_unlocked(dapm, "AGCIN"); |
153 | else | 154 | else |
154 | snd_soc_dapm_disable_pin(dapm, "AGCIN"); | 155 | snd_soc_dapm_disable_pin_unlocked(dapm, "AGCIN"); |
155 | } | 156 | } |
157 | |||
156 | if (changed) | 158 | if (changed) |
157 | snd_soc_dapm_sync(dapm); | 159 | snd_soc_dapm_sync_unlocked(dapm); |
158 | 160 | ||
159 | mutex_unlock(&codec->mutex); | 161 | snd_soc_dapm_mutex_unlock(dapm); |
160 | 162 | ||
161 | return changed; | 163 | return changed; |
162 | } | 164 | } |
@@ -315,12 +317,17 @@ static void cx81801_close(struct tty_struct *tty) | |||
315 | v253_ops.close(tty); | 317 | v253_ops.close(tty); |
316 | 318 | ||
317 | /* Revert back to default audio input/output constellation */ | 319 | /* Revert back to default audio input/output constellation */ |
318 | snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); | 320 | snd_soc_dapm_mutex_lock(dapm); |
319 | snd_soc_dapm_enable_pin(dapm, "Earpiece"); | 321 | |
320 | snd_soc_dapm_enable_pin(dapm, "Microphone"); | 322 | snd_soc_dapm_disable_pin_unlocked(dapm, "Mouthpiece"); |
321 | snd_soc_dapm_disable_pin(dapm, "Speaker"); | 323 | snd_soc_dapm_enable_pin_unlocked(dapm, "Earpiece"); |
322 | snd_soc_dapm_disable_pin(dapm, "AGCIN"); | 324 | snd_soc_dapm_enable_pin_unlocked(dapm, "Microphone"); |
323 | snd_soc_dapm_sync(dapm); | 325 | snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker"); |
326 | snd_soc_dapm_disable_pin_unlocked(dapm, "AGCIN"); | ||
327 | |||
328 | snd_soc_dapm_sync_unlocked(dapm); | ||
329 | |||
330 | snd_soc_dapm_mutex_unlock(codec); | ||
324 | } | 331 | } |
325 | 332 | ||
326 | /* Line discipline .hangup() */ | 333 | /* Line discipline .hangup() */ |
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 3fde9e402710..fd4d9c809e50 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c | |||
@@ -68,26 +68,30 @@ static void n810_ext_control(struct snd_soc_dapm_context *dapm) | |||
68 | break; | 68 | break; |
69 | } | 69 | } |
70 | 70 | ||
71 | snd_soc_dapm_mutex_lock(dapm); | ||
72 | |||
71 | if (n810_spk_func) | 73 | if (n810_spk_func) |
72 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | 74 | snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk"); |
73 | else | 75 | else |
74 | snd_soc_dapm_disable_pin(dapm, "Ext Spk"); | 76 | snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk"); |
75 | 77 | ||
76 | if (hp) | 78 | if (hp) |
77 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 79 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack"); |
78 | else | 80 | else |
79 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 81 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); |
80 | if (line1l) | 82 | if (line1l) |
81 | snd_soc_dapm_enable_pin(dapm, "LINE1L"); | 83 | snd_soc_dapm_enable_pin_unlocked(dapm, "LINE1L"); |
82 | else | 84 | else |
83 | snd_soc_dapm_disable_pin(dapm, "LINE1L"); | 85 | snd_soc_dapm_disable_pin_unlocked(dapm, "LINE1L"); |
84 | 86 | ||
85 | if (n810_dmic_func) | 87 | if (n810_dmic_func) |
86 | snd_soc_dapm_enable_pin(dapm, "DMic"); | 88 | snd_soc_dapm_enable_pin_unlocked(dapm, "DMic"); |
87 | else | 89 | else |
88 | snd_soc_dapm_disable_pin(dapm, "DMic"); | 90 | snd_soc_dapm_disable_pin_unlocked(dapm, "DMic"); |
91 | |||
92 | snd_soc_dapm_sync_unlocked(dapm); | ||
89 | 93 | ||
90 | snd_soc_dapm_sync(dapm); | 94 | snd_soc_dapm_mutex_unlock(dapm); |
91 | } | 95 | } |
92 | 96 | ||
93 | static int n810_startup(struct snd_pcm_substream *substream) | 97 | static int n810_startup(struct snd_pcm_substream *substream) |
@@ -305,7 +309,9 @@ static int __init n810_soc_init(void) | |||
305 | int err; | 309 | int err; |
306 | struct device *dev; | 310 | struct device *dev; |
307 | 311 | ||
308 | if (!(machine_is_nokia_n810() || machine_is_nokia_n810_wimax())) | 312 | if (!of_have_populated_dt() || |
313 | (!of_machine_is_compatible("nokia,n810") && | ||
314 | !of_machine_is_compatible("nokia,n810-wimax"))) | ||
309 | return -ENODEV; | 315 | return -ENODEV; |
310 | 316 | ||
311 | n810_snd_device = platform_device_alloc("soc-audio", -1); | 317 | n810_snd_device = platform_device_alloc("soc-audio", -1); |
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 611179c3bca4..7fb3d4b10370 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c | |||
@@ -74,26 +74,30 @@ static void rx51_ext_control(struct snd_soc_dapm_context *dapm) | |||
74 | break; | 74 | break; |
75 | } | 75 | } |
76 | 76 | ||
77 | snd_soc_dapm_mutex_lock(dapm); | ||
78 | |||
77 | if (rx51_spk_func) | 79 | if (rx51_spk_func) |
78 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | 80 | snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk"); |
79 | else | 81 | else |
80 | snd_soc_dapm_disable_pin(dapm, "Ext Spk"); | 82 | snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk"); |
81 | if (rx51_dmic_func) | 83 | if (rx51_dmic_func) |
82 | snd_soc_dapm_enable_pin(dapm, "DMic"); | 84 | snd_soc_dapm_enable_pin_unlocked(dapm, "DMic"); |
83 | else | 85 | else |
84 | snd_soc_dapm_disable_pin(dapm, "DMic"); | 86 | snd_soc_dapm_disable_pin_unlocked(dapm, "DMic"); |
85 | if (hp) | 87 | if (hp) |
86 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 88 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack"); |
87 | else | 89 | else |
88 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 90 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); |
89 | if (hs) | 91 | if (hs) |
90 | snd_soc_dapm_enable_pin(dapm, "HS Mic"); | 92 | snd_soc_dapm_enable_pin_unlocked(dapm, "HS Mic"); |
91 | else | 93 | else |
92 | snd_soc_dapm_disable_pin(dapm, "HS Mic"); | 94 | snd_soc_dapm_disable_pin_unlocked(dapm, "HS Mic"); |
93 | 95 | ||
94 | gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout); | 96 | gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout); |
95 | 97 | ||
96 | snd_soc_dapm_sync(dapm); | 98 | snd_soc_dapm_sync_unlocked(dapm); |
99 | |||
100 | snd_soc_dapm_mutex_unlock(dapm); | ||
97 | } | 101 | } |
98 | 102 | ||
99 | static int rx51_startup(struct snd_pcm_substream *substream) | 103 | static int rx51_startup(struct snd_pcm_substream *substream) |
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 1853d41034bf..9d9c8ad57f0e 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c | |||
@@ -47,51 +47,55 @@ static int corgi_spk_func; | |||
47 | 47 | ||
48 | static void corgi_ext_control(struct snd_soc_dapm_context *dapm) | 48 | static void corgi_ext_control(struct snd_soc_dapm_context *dapm) |
49 | { | 49 | { |
50 | snd_soc_dapm_mutex_lock(dapm); | ||
51 | |||
50 | /* set up jack connection */ | 52 | /* set up jack connection */ |
51 | switch (corgi_jack_func) { | 53 | switch (corgi_jack_func) { |
52 | case CORGI_HP: | 54 | case CORGI_HP: |
53 | /* set = unmute headphone */ | 55 | /* set = unmute headphone */ |
54 | gpio_set_value(CORGI_GPIO_MUTE_L, 1); | 56 | gpio_set_value(CORGI_GPIO_MUTE_L, 1); |
55 | gpio_set_value(CORGI_GPIO_MUTE_R, 1); | 57 | gpio_set_value(CORGI_GPIO_MUTE_R, 1); |
56 | snd_soc_dapm_disable_pin(dapm, "Mic Jack"); | 58 | snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack"); |
57 | snd_soc_dapm_disable_pin(dapm, "Line Jack"); | 59 | snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack"); |
58 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 60 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack"); |
59 | snd_soc_dapm_disable_pin(dapm, "Headset Jack"); | 61 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); |
60 | break; | 62 | break; |
61 | case CORGI_MIC: | 63 | case CORGI_MIC: |
62 | /* reset = mute headphone */ | 64 | /* reset = mute headphone */ |
63 | gpio_set_value(CORGI_GPIO_MUTE_L, 0); | 65 | gpio_set_value(CORGI_GPIO_MUTE_L, 0); |
64 | gpio_set_value(CORGI_GPIO_MUTE_R, 0); | 66 | gpio_set_value(CORGI_GPIO_MUTE_R, 0); |
65 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | 67 | snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack"); |
66 | snd_soc_dapm_disable_pin(dapm, "Line Jack"); | 68 | snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack"); |
67 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 69 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); |
68 | snd_soc_dapm_disable_pin(dapm, "Headset Jack"); | 70 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); |
69 | break; | 71 | break; |
70 | case CORGI_LINE: | 72 | case CORGI_LINE: |
71 | gpio_set_value(CORGI_GPIO_MUTE_L, 0); | 73 | gpio_set_value(CORGI_GPIO_MUTE_L, 0); |
72 | gpio_set_value(CORGI_GPIO_MUTE_R, 0); | 74 | gpio_set_value(CORGI_GPIO_MUTE_R, 0); |
73 | snd_soc_dapm_disable_pin(dapm, "Mic Jack"); | 75 | snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack"); |
74 | snd_soc_dapm_enable_pin(dapm, "Line Jack"); | 76 | snd_soc_dapm_enable_pin_unlocked(dapm, "Line Jack"); |
75 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 77 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); |
76 | snd_soc_dapm_disable_pin(dapm, "Headset Jack"); | 78 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); |
77 | break; | 79 | break; |
78 | case CORGI_HEADSET: | 80 | case CORGI_HEADSET: |
79 | gpio_set_value(CORGI_GPIO_MUTE_L, 0); | 81 | gpio_set_value(CORGI_GPIO_MUTE_L, 0); |
80 | gpio_set_value(CORGI_GPIO_MUTE_R, 1); | 82 | gpio_set_value(CORGI_GPIO_MUTE_R, 1); |
81 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | 83 | snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack"); |
82 | snd_soc_dapm_disable_pin(dapm, "Line Jack"); | 84 | snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack"); |
83 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 85 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); |
84 | snd_soc_dapm_enable_pin(dapm, "Headset Jack"); | 86 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack"); |
85 | break; | 87 | break; |
86 | } | 88 | } |
87 | 89 | ||
88 | if (corgi_spk_func == CORGI_SPK_ON) | 90 | if (corgi_spk_func == CORGI_SPK_ON) |
89 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | 91 | snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk"); |
90 | else | 92 | else |
91 | snd_soc_dapm_disable_pin(dapm, "Ext Spk"); | 93 | snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk"); |
92 | 94 | ||
93 | /* signal a DAPM event */ | 95 | /* signal a DAPM event */ |
94 | snd_soc_dapm_sync(dapm); | 96 | snd_soc_dapm_sync_unlocked(dapm); |
97 | |||
98 | snd_soc_dapm_mutex_unlock(dapm); | ||
95 | } | 99 | } |
96 | 100 | ||
97 | static int corgi_startup(struct snd_pcm_substream *substream) | 101 | static int corgi_startup(struct snd_pcm_substream *substream) |
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c index aace19e0fe2c..31242be08823 100644 --- a/sound/soc/pxa/magician.c +++ b/sound/soc/pxa/magician.c | |||
@@ -45,27 +45,31 @@ static void magician_ext_control(struct snd_soc_codec *codec) | |||
45 | { | 45 | { |
46 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 46 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
47 | 47 | ||
48 | snd_soc_dapm_mutex_lock(dapm); | ||
49 | |||
48 | if (magician_spk_switch) | 50 | if (magician_spk_switch) |
49 | snd_soc_dapm_enable_pin(dapm, "Speaker"); | 51 | snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker"); |
50 | else | 52 | else |
51 | snd_soc_dapm_disable_pin(dapm, "Speaker"); | 53 | snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker"); |
52 | if (magician_hp_switch) | 54 | if (magician_hp_switch) |
53 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 55 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack"); |
54 | else | 56 | else |
55 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 57 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); |
56 | 58 | ||
57 | switch (magician_in_sel) { | 59 | switch (magician_in_sel) { |
58 | case MAGICIAN_MIC: | 60 | case MAGICIAN_MIC: |
59 | snd_soc_dapm_disable_pin(dapm, "Headset Mic"); | 61 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Mic"); |
60 | snd_soc_dapm_enable_pin(dapm, "Call Mic"); | 62 | snd_soc_dapm_enable_pin_unlocked(dapm, "Call Mic"); |
61 | break; | 63 | break; |
62 | case MAGICIAN_MIC_EXT: | 64 | case MAGICIAN_MIC_EXT: |
63 | snd_soc_dapm_disable_pin(dapm, "Call Mic"); | 65 | snd_soc_dapm_disable_pin_unlocked(dapm, "Call Mic"); |
64 | snd_soc_dapm_enable_pin(dapm, "Headset Mic"); | 66 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Mic"); |
65 | break; | 67 | break; |
66 | } | 68 | } |
67 | 69 | ||
68 | snd_soc_dapm_sync(dapm); | 70 | snd_soc_dapm_sync_unlocked(dapm); |
71 | |||
72 | snd_soc_dapm_mutex_unlock(dapm); | ||
69 | } | 73 | } |
70 | 74 | ||
71 | static int magician_startup(struct snd_pcm_substream *substream) | 75 | static int magician_startup(struct snd_pcm_substream *substream) |
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index fc052d8247ff..04dbb5a38fa4 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c | |||
@@ -46,61 +46,66 @@ static int spitz_mic_gpio; | |||
46 | 46 | ||
47 | static void spitz_ext_control(struct snd_soc_dapm_context *dapm) | 47 | static void spitz_ext_control(struct snd_soc_dapm_context *dapm) |
48 | { | 48 | { |
49 | snd_soc_dapm_mutex_lock(dapm); | ||
50 | |||
49 | if (spitz_spk_func == SPITZ_SPK_ON) | 51 | if (spitz_spk_func == SPITZ_SPK_ON) |
50 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | 52 | snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk"); |
51 | else | 53 | else |
52 | snd_soc_dapm_disable_pin(dapm, "Ext Spk"); | 54 | snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk"); |
53 | 55 | ||
54 | /* set up jack connection */ | 56 | /* set up jack connection */ |
55 | switch (spitz_jack_func) { | 57 | switch (spitz_jack_func) { |
56 | case SPITZ_HP: | 58 | case SPITZ_HP: |
57 | /* enable and unmute hp jack, disable mic bias */ | 59 | /* enable and unmute hp jack, disable mic bias */ |
58 | snd_soc_dapm_disable_pin(dapm, "Headset Jack"); | 60 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); |
59 | snd_soc_dapm_disable_pin(dapm, "Mic Jack"); | 61 | snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack"); |
60 | snd_soc_dapm_disable_pin(dapm, "Line Jack"); | 62 | snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack"); |
61 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 63 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack"); |
62 | gpio_set_value(SPITZ_GPIO_MUTE_L, 1); | 64 | gpio_set_value(SPITZ_GPIO_MUTE_L, 1); |
63 | gpio_set_value(SPITZ_GPIO_MUTE_R, 1); | 65 | gpio_set_value(SPITZ_GPIO_MUTE_R, 1); |
64 | break; | 66 | break; |
65 | case SPITZ_MIC: | 67 | case SPITZ_MIC: |
66 | /* enable mic jack and bias, mute hp */ | 68 | /* enable mic jack and bias, mute hp */ |
67 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 69 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); |
68 | snd_soc_dapm_disable_pin(dapm, "Headset Jack"); | 70 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); |
69 | snd_soc_dapm_disable_pin(dapm, "Line Jack"); | 71 | snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack"); |
70 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | 72 | snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack"); |
71 | gpio_set_value(SPITZ_GPIO_MUTE_L, 0); | 73 | gpio_set_value(SPITZ_GPIO_MUTE_L, 0); |
72 | gpio_set_value(SPITZ_GPIO_MUTE_R, 0); | 74 | gpio_set_value(SPITZ_GPIO_MUTE_R, 0); |
73 | break; | 75 | break; |
74 | case SPITZ_LINE: | 76 | case SPITZ_LINE: |
75 | /* enable line jack, disable mic bias and mute hp */ | 77 | /* enable line jack, disable mic bias and mute hp */ |
76 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 78 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); |
77 | snd_soc_dapm_disable_pin(dapm, "Headset Jack"); | 79 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); |
78 | snd_soc_dapm_disable_pin(dapm, "Mic Jack"); | 80 | snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack"); |
79 | snd_soc_dapm_enable_pin(dapm, "Line Jack"); | 81 | snd_soc_dapm_enable_pin_unlocked(dapm, "Line Jack"); |
80 | gpio_set_value(SPITZ_GPIO_MUTE_L, 0); | 82 | gpio_set_value(SPITZ_GPIO_MUTE_L, 0); |
81 | gpio_set_value(SPITZ_GPIO_MUTE_R, 0); | 83 | gpio_set_value(SPITZ_GPIO_MUTE_R, 0); |
82 | break; | 84 | break; |
83 | case SPITZ_HEADSET: | 85 | case SPITZ_HEADSET: |
84 | /* enable and unmute headset jack enable mic bias, mute L hp */ | 86 | /* enable and unmute headset jack enable mic bias, mute L hp */ |
85 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 87 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); |
86 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | 88 | snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack"); |
87 | snd_soc_dapm_disable_pin(dapm, "Line Jack"); | 89 | snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack"); |
88 | snd_soc_dapm_enable_pin(dapm, "Headset Jack"); | 90 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack"); |
89 | gpio_set_value(SPITZ_GPIO_MUTE_L, 0); | 91 | gpio_set_value(SPITZ_GPIO_MUTE_L, 0); |
90 | gpio_set_value(SPITZ_GPIO_MUTE_R, 1); | 92 | gpio_set_value(SPITZ_GPIO_MUTE_R, 1); |
91 | break; | 93 | break; |
92 | case SPITZ_HP_OFF: | 94 | case SPITZ_HP_OFF: |
93 | 95 | ||
94 | /* jack removed, everything off */ | 96 | /* jack removed, everything off */ |
95 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 97 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); |
96 | snd_soc_dapm_disable_pin(dapm, "Headset Jack"); | 98 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); |
97 | snd_soc_dapm_disable_pin(dapm, "Mic Jack"); | 99 | snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack"); |
98 | snd_soc_dapm_disable_pin(dapm, "Line Jack"); | 100 | snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack"); |
99 | gpio_set_value(SPITZ_GPIO_MUTE_L, 0); | 101 | gpio_set_value(SPITZ_GPIO_MUTE_L, 0); |
100 | gpio_set_value(SPITZ_GPIO_MUTE_R, 0); | 102 | gpio_set_value(SPITZ_GPIO_MUTE_R, 0); |
101 | break; | 103 | break; |
102 | } | 104 | } |
103 | snd_soc_dapm_sync(dapm); | 105 | |
106 | snd_soc_dapm_sync_unlocked(dapm); | ||
107 | |||
108 | snd_soc_dapm_mutex_unlock(dapm); | ||
104 | } | 109 | } |
105 | 110 | ||
106 | static int spitz_startup(struct snd_pcm_substream *substream) | 111 | static int spitz_startup(struct snd_pcm_substream *substream) |
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index 1d9c2ed223bc..2a4b438ce97c 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c | |||
@@ -48,31 +48,35 @@ static void tosa_ext_control(struct snd_soc_codec *codec) | |||
48 | { | 48 | { |
49 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 49 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
50 | 50 | ||
51 | snd_soc_dapm_mutex_lock(dapm); | ||
52 | |||
51 | /* set up jack connection */ | 53 | /* set up jack connection */ |
52 | switch (tosa_jack_func) { | 54 | switch (tosa_jack_func) { |
53 | case TOSA_HP: | 55 | case TOSA_HP: |
54 | snd_soc_dapm_disable_pin(dapm, "Mic (Internal)"); | 56 | snd_soc_dapm_disable_pin_unlocked(dapm, "Mic (Internal)"); |
55 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 57 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack"); |
56 | snd_soc_dapm_disable_pin(dapm, "Headset Jack"); | 58 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); |
57 | break; | 59 | break; |
58 | case TOSA_MIC_INT: | 60 | case TOSA_MIC_INT: |
59 | snd_soc_dapm_enable_pin(dapm, "Mic (Internal)"); | 61 | snd_soc_dapm_enable_pin_unlocked(dapm, "Mic (Internal)"); |
60 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 62 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); |
61 | snd_soc_dapm_disable_pin(dapm, "Headset Jack"); | 63 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); |
62 | break; | 64 | break; |
63 | case TOSA_HEADSET: | 65 | case TOSA_HEADSET: |
64 | snd_soc_dapm_disable_pin(dapm, "Mic (Internal)"); | 66 | snd_soc_dapm_disable_pin_unlocked(dapm, "Mic (Internal)"); |
65 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 67 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); |
66 | snd_soc_dapm_enable_pin(dapm, "Headset Jack"); | 68 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack"); |
67 | break; | 69 | break; |
68 | } | 70 | } |
69 | 71 | ||
70 | if (tosa_spk_func == TOSA_SPK_ON) | 72 | if (tosa_spk_func == TOSA_SPK_ON) |
71 | snd_soc_dapm_enable_pin(dapm, "Speaker"); | 73 | snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker"); |
72 | else | 74 | else |
73 | snd_soc_dapm_disable_pin(dapm, "Speaker"); | 75 | snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker"); |
76 | |||
77 | snd_soc_dapm_sync_unlocked(dapm); | ||
74 | 78 | ||
75 | snd_soc_dapm_sync(dapm); | 79 | snd_soc_dapm_mutex_unlock(dapm); |
76 | } | 80 | } |
77 | 81 | ||
78 | static int tosa_startup(struct snd_pcm_substream *substream) | 82 | static int tosa_startup(struct snd_pcm_substream *substream) |
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 454f41cfc828..350757400391 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -59,7 +59,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750 | |||
59 | select SND_SOC_WM8750 | 59 | select SND_SOC_WM8750 |
60 | select SND_S3C2412_SOC_I2S | 60 | select SND_S3C2412_SOC_I2S |
61 | help | 61 | help |
62 | Sat Y if you want to add support for SoC audio on the Jive. | 62 | Say Y if you want to add support for SoC audio on the Jive. |
63 | 63 | ||
64 | config SND_SOC_SAMSUNG_SMDK_WM8580 | 64 | config SND_SOC_SAMSUNG_SMDK_WM8580 |
65 | tristate "SoC I2S Audio support for WM8580 on SMDK" | 65 | tristate "SoC I2S Audio support for WM8580 on SMDK" |
@@ -145,11 +145,11 @@ config SND_SOC_SAMSUNG_RX1950_UDA1380 | |||
145 | 145 | ||
146 | config SND_SOC_SAMSUNG_SMDK_WM9713 | 146 | config SND_SOC_SAMSUNG_SMDK_WM9713 |
147 | tristate "SoC AC97 Audio support for SMDK with WM9713" | 147 | tristate "SoC AC97 Audio support for SMDK with WM9713" |
148 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110 || MACH_SMDKV310 || MACH_SMDKC210) | 148 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) |
149 | select SND_SOC_WM9713 | 149 | select SND_SOC_WM9713 |
150 | select SND_SAMSUNG_AC97 | 150 | select SND_SAMSUNG_AC97 |
151 | help | 151 | help |
152 | Sat Y if you want to add support for SoC audio on the SMDK. | 152 | Say Y if you want to add support for SoC audio on the SMDK. |
153 | 153 | ||
154 | config SND_SOC_SMARTQ | 154 | config SND_SOC_SMARTQ |
155 | tristate "SoC I2S Audio support for SmartQ board" | 155 | tristate "SoC I2S Audio support for SmartQ board" |
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 375dc6dfba4e..bfed3e4c45ff 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
@@ -96,8 +96,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec) | |||
96 | { | 96 | { |
97 | dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n", | 97 | dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n", |
98 | codec->name); | 98 | codec->name); |
99 | if (!codec->reg_cache) | 99 | |
100 | return 0; | ||
101 | kfree(codec->reg_cache); | 100 | kfree(codec->reg_cache); |
102 | codec->reg_cache = NULL; | 101 | codec->reg_cache = NULL; |
103 | return 0; | 102 | return 0; |
@@ -117,8 +116,9 @@ int snd_soc_cache_read(struct snd_soc_codec *codec, | |||
117 | return -EINVAL; | 116 | return -EINVAL; |
118 | 117 | ||
119 | mutex_lock(&codec->cache_rw_mutex); | 118 | mutex_lock(&codec->cache_rw_mutex); |
120 | *value = snd_soc_get_cache_val(codec->reg_cache, reg, | 119 | if (!ZERO_OR_NULL_PTR(codec->reg_cache)) |
121 | codec->driver->reg_word_size); | 120 | *value = snd_soc_get_cache_val(codec->reg_cache, reg, |
121 | codec->driver->reg_word_size); | ||
122 | mutex_unlock(&codec->cache_rw_mutex); | 122 | mutex_unlock(&codec->cache_rw_mutex); |
123 | 123 | ||
124 | return 0; | 124 | return 0; |
@@ -136,8 +136,9 @@ int snd_soc_cache_write(struct snd_soc_codec *codec, | |||
136 | unsigned int reg, unsigned int value) | 136 | unsigned int reg, unsigned int value) |
137 | { | 137 | { |
138 | mutex_lock(&codec->cache_rw_mutex); | 138 | mutex_lock(&codec->cache_rw_mutex); |
139 | snd_soc_set_cache_val(codec->reg_cache, reg, value, | 139 | if (!ZERO_OR_NULL_PTR(codec->reg_cache)) |
140 | codec->driver->reg_word_size); | 140 | snd_soc_set_cache_val(codec->reg_cache, reg, value, |
141 | codec->driver->reg_word_size); | ||
141 | mutex_unlock(&codec->cache_rw_mutex); | 142 | mutex_unlock(&codec->cache_rw_mutex); |
142 | 143 | ||
143 | return 0; | 144 | return 0; |
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 5e9690c85d8f..91083e6a6b38 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c | |||
@@ -30,8 +30,6 @@ static int soc_compr_open(struct snd_compr_stream *cstream) | |||
30 | { | 30 | { |
31 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | 31 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; |
32 | struct snd_soc_platform *platform = rtd->platform; | 32 | struct snd_soc_platform *platform = rtd->platform; |
33 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
34 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
35 | int ret = 0; | 33 | int ret = 0; |
36 | 34 | ||
37 | mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); | 35 | mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); |
@@ -52,17 +50,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream) | |||
52 | } | 50 | } |
53 | } | 51 | } |
54 | 52 | ||
55 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { | 53 | snd_soc_runtime_activate(rtd, cstream->direction); |
56 | cpu_dai->playback_active++; | ||
57 | codec_dai->playback_active++; | ||
58 | } else { | ||
59 | cpu_dai->capture_active++; | ||
60 | codec_dai->capture_active++; | ||
61 | } | ||
62 | |||
63 | cpu_dai->active++; | ||
64 | codec_dai->active++; | ||
65 | rtd->codec->active++; | ||
66 | 54 | ||
67 | mutex_unlock(&rtd->pcm_mutex); | 55 | mutex_unlock(&rtd->pcm_mutex); |
68 | 56 | ||
@@ -81,8 +69,6 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) | |||
81 | struct snd_soc_pcm_runtime *fe = cstream->private_data; | 69 | struct snd_soc_pcm_runtime *fe = cstream->private_data; |
82 | struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream; | 70 | struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream; |
83 | struct snd_soc_platform *platform = fe->platform; | 71 | struct snd_soc_platform *platform = fe->platform; |
84 | struct snd_soc_dai *cpu_dai = fe->cpu_dai; | ||
85 | struct snd_soc_dai *codec_dai = fe->codec_dai; | ||
86 | struct snd_soc_dpcm *dpcm; | 72 | struct snd_soc_dpcm *dpcm; |
87 | struct snd_soc_dapm_widget_list *list; | 73 | struct snd_soc_dapm_widget_list *list; |
88 | int stream; | 74 | int stream; |
@@ -140,17 +126,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) | |||
140 | fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; | 126 | fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; |
141 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; | 127 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; |
142 | 128 | ||
143 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { | 129 | snd_soc_runtime_activate(fe, stream); |
144 | cpu_dai->playback_active++; | ||
145 | codec_dai->playback_active++; | ||
146 | } else { | ||
147 | cpu_dai->capture_active++; | ||
148 | codec_dai->capture_active++; | ||
149 | } | ||
150 | |||
151 | cpu_dai->active++; | ||
152 | codec_dai->active++; | ||
153 | fe->codec->active++; | ||
154 | 130 | ||
155 | mutex_unlock(&fe->card->mutex); | 131 | mutex_unlock(&fe->card->mutex); |
156 | 132 | ||
@@ -202,23 +178,18 @@ static int soc_compr_free(struct snd_compr_stream *cstream) | |||
202 | struct snd_soc_platform *platform = rtd->platform; | 178 | struct snd_soc_platform *platform = rtd->platform; |
203 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 179 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
204 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 180 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
205 | struct snd_soc_codec *codec = rtd->codec; | 181 | int stream; |
206 | 182 | ||
207 | mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); | 183 | mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); |
208 | 184 | ||
209 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { | 185 | if (cstream->direction == SND_COMPRESS_PLAYBACK) |
210 | cpu_dai->playback_active--; | 186 | stream = SNDRV_PCM_STREAM_PLAYBACK; |
211 | codec_dai->playback_active--; | 187 | else |
212 | } else { | 188 | stream = SNDRV_PCM_STREAM_CAPTURE; |
213 | cpu_dai->capture_active--; | ||
214 | codec_dai->capture_active--; | ||
215 | } | ||
216 | 189 | ||
217 | snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction); | 190 | snd_soc_runtime_deactivate(rtd, stream); |
218 | 191 | ||
219 | cpu_dai->active--; | 192 | snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction); |
220 | codec_dai->active--; | ||
221 | codec->active--; | ||
222 | 193 | ||
223 | if (!cpu_dai->active) | 194 | if (!cpu_dai->active) |
224 | cpu_dai->rate = 0; | 195 | cpu_dai->rate = 0; |
@@ -235,8 +206,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream) | |||
235 | cpu_dai->runtime = NULL; | 206 | cpu_dai->runtime = NULL; |
236 | 207 | ||
237 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { | 208 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { |
238 | if (!rtd->pmdown_time || codec->ignore_pmdown_time || | 209 | if (snd_soc_runtime_ignore_pmdown_time(rtd)) { |
239 | rtd->dai_link->ignore_pmdown_time) { | ||
240 | snd_soc_dapm_stream_event(rtd, | 210 | snd_soc_dapm_stream_event(rtd, |
241 | SNDRV_PCM_STREAM_PLAYBACK, | 211 | SNDRV_PCM_STREAM_PLAYBACK, |
242 | SND_SOC_DAPM_STREAM_STOP); | 212 | SND_SOC_DAPM_STREAM_STOP); |
@@ -261,26 +231,17 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream) | |||
261 | { | 231 | { |
262 | struct snd_soc_pcm_runtime *fe = cstream->private_data; | 232 | struct snd_soc_pcm_runtime *fe = cstream->private_data; |
263 | struct snd_soc_platform *platform = fe->platform; | 233 | struct snd_soc_platform *platform = fe->platform; |
264 | struct snd_soc_dai *cpu_dai = fe->cpu_dai; | ||
265 | struct snd_soc_dai *codec_dai = fe->codec_dai; | ||
266 | struct snd_soc_dpcm *dpcm; | 234 | struct snd_soc_dpcm *dpcm; |
267 | int stream, ret; | 235 | int stream, ret; |
268 | 236 | ||
269 | mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); | 237 | mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); |
270 | 238 | ||
271 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { | 239 | if (cstream->direction == SND_COMPRESS_PLAYBACK) |
272 | stream = SNDRV_PCM_STREAM_PLAYBACK; | 240 | stream = SNDRV_PCM_STREAM_PLAYBACK; |
273 | cpu_dai->playback_active--; | 241 | else |
274 | codec_dai->playback_active--; | ||
275 | } else { | ||
276 | stream = SNDRV_PCM_STREAM_CAPTURE; | 242 | stream = SNDRV_PCM_STREAM_CAPTURE; |
277 | cpu_dai->capture_active--; | ||
278 | codec_dai->capture_active--; | ||
279 | } | ||
280 | 243 | ||
281 | cpu_dai->active--; | 244 | snd_soc_runtime_deactivate(fe, stream); |
282 | codec_dai->active--; | ||
283 | fe->codec->active--; | ||
284 | 245 | ||
285 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; | 246 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; |
286 | 247 | ||
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index fe1df50805a3..4ba0959a0d7b 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -56,7 +56,6 @@ EXPORT_SYMBOL_GPL(snd_soc_debugfs_root); | |||
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | static DEFINE_MUTEX(client_mutex); | 58 | static DEFINE_MUTEX(client_mutex); |
59 | static LIST_HEAD(dai_list); | ||
60 | static LIST_HEAD(platform_list); | 59 | static LIST_HEAD(platform_list); |
61 | static LIST_HEAD(codec_list); | 60 | static LIST_HEAD(codec_list); |
62 | static LIST_HEAD(component_list); | 61 | static LIST_HEAD(component_list); |
@@ -370,18 +369,22 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf, | |||
370 | { | 369 | { |
371 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 370 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); |
372 | ssize_t len, ret = 0; | 371 | ssize_t len, ret = 0; |
372 | struct snd_soc_component *component; | ||
373 | struct snd_soc_dai *dai; | 373 | struct snd_soc_dai *dai; |
374 | 374 | ||
375 | if (!buf) | 375 | if (!buf) |
376 | return -ENOMEM; | 376 | return -ENOMEM; |
377 | 377 | ||
378 | list_for_each_entry(dai, &dai_list, list) { | 378 | list_for_each_entry(component, &component_list, list) { |
379 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", dai->name); | 379 | list_for_each_entry(dai, &component->dai_list, list) { |
380 | if (len >= 0) | 380 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", |
381 | ret += len; | 381 | dai->name); |
382 | if (ret > PAGE_SIZE) { | 382 | if (len >= 0) |
383 | ret = PAGE_SIZE; | 383 | ret += len; |
384 | break; | 384 | if (ret > PAGE_SIZE) { |
385 | ret = PAGE_SIZE; | ||
386 | break; | ||
387 | } | ||
385 | } | 388 | } |
386 | } | 389 | } |
387 | 390 | ||
@@ -855,6 +858,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
855 | { | 858 | { |
856 | struct snd_soc_dai_link *dai_link = &card->dai_link[num]; | 859 | struct snd_soc_dai_link *dai_link = &card->dai_link[num]; |
857 | struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; | 860 | struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; |
861 | struct snd_soc_component *component; | ||
858 | struct snd_soc_codec *codec; | 862 | struct snd_soc_codec *codec; |
859 | struct snd_soc_platform *platform; | 863 | struct snd_soc_platform *platform; |
860 | struct snd_soc_dai *codec_dai, *cpu_dai; | 864 | struct snd_soc_dai *codec_dai, *cpu_dai; |
@@ -863,18 +867,20 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
863 | dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); | 867 | dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); |
864 | 868 | ||
865 | /* Find CPU DAI from registered DAIs*/ | 869 | /* Find CPU DAI from registered DAIs*/ |
866 | list_for_each_entry(cpu_dai, &dai_list, list) { | 870 | list_for_each_entry(component, &component_list, list) { |
867 | if (dai_link->cpu_of_node && | 871 | if (dai_link->cpu_of_node && |
868 | (cpu_dai->dev->of_node != dai_link->cpu_of_node)) | 872 | component->dev->of_node != dai_link->cpu_of_node) |
869 | continue; | 873 | continue; |
870 | if (dai_link->cpu_name && | 874 | if (dai_link->cpu_name && |
871 | strcmp(dev_name(cpu_dai->dev), dai_link->cpu_name)) | 875 | strcmp(dev_name(component->dev), dai_link->cpu_name)) |
872 | continue; | ||
873 | if (dai_link->cpu_dai_name && | ||
874 | strcmp(cpu_dai->name, dai_link->cpu_dai_name)) | ||
875 | continue; | 876 | continue; |
877 | list_for_each_entry(cpu_dai, &component->dai_list, list) { | ||
878 | if (dai_link->cpu_dai_name && | ||
879 | strcmp(cpu_dai->name, dai_link->cpu_dai_name)) | ||
880 | continue; | ||
876 | 881 | ||
877 | rtd->cpu_dai = cpu_dai; | 882 | rtd->cpu_dai = cpu_dai; |
883 | } | ||
878 | } | 884 | } |
879 | 885 | ||
880 | if (!rtd->cpu_dai) { | 886 | if (!rtd->cpu_dai) { |
@@ -899,12 +905,10 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
899 | * CODEC found, so find CODEC DAI from registered DAIs from | 905 | * CODEC found, so find CODEC DAI from registered DAIs from |
900 | * this CODEC | 906 | * this CODEC |
901 | */ | 907 | */ |
902 | list_for_each_entry(codec_dai, &dai_list, list) { | 908 | list_for_each_entry(codec_dai, &codec->component.dai_list, list) { |
903 | if (codec->dev == codec_dai->dev && | 909 | if (!strcmp(codec_dai->name, dai_link->codec_dai_name)) { |
904 | !strcmp(codec_dai->name, | ||
905 | dai_link->codec_dai_name)) { | ||
906 | |||
907 | rtd->codec_dai = codec_dai; | 910 | rtd->codec_dai = codec_dai; |
911 | break; | ||
908 | } | 912 | } |
909 | } | 913 | } |
910 | 914 | ||
@@ -1128,12 +1132,8 @@ static int soc_probe_codec(struct snd_soc_card *card, | |||
1128 | driver->num_dapm_widgets); | 1132 | driver->num_dapm_widgets); |
1129 | 1133 | ||
1130 | /* Create DAPM widgets for each DAI stream */ | 1134 | /* Create DAPM widgets for each DAI stream */ |
1131 | list_for_each_entry(dai, &dai_list, list) { | 1135 | list_for_each_entry(dai, &codec->component.dai_list, list) |
1132 | if (dai->dev != codec->dev) | ||
1133 | continue; | ||
1134 | |||
1135 | snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); | 1136 | snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); |
1136 | } | ||
1137 | 1137 | ||
1138 | codec->dapm.idle_bias_off = driver->idle_bias_off; | 1138 | codec->dapm.idle_bias_off = driver->idle_bias_off; |
1139 | 1139 | ||
@@ -1180,6 +1180,7 @@ static int soc_probe_platform(struct snd_soc_card *card, | |||
1180 | { | 1180 | { |
1181 | int ret = 0; | 1181 | int ret = 0; |
1182 | const struct snd_soc_platform_driver *driver = platform->driver; | 1182 | const struct snd_soc_platform_driver *driver = platform->driver; |
1183 | struct snd_soc_component *component; | ||
1183 | struct snd_soc_dai *dai; | 1184 | struct snd_soc_dai *dai; |
1184 | 1185 | ||
1185 | platform->card = card; | 1186 | platform->card = card; |
@@ -1195,11 +1196,11 @@ static int soc_probe_platform(struct snd_soc_card *card, | |||
1195 | driver->dapm_widgets, driver->num_dapm_widgets); | 1196 | driver->dapm_widgets, driver->num_dapm_widgets); |
1196 | 1197 | ||
1197 | /* Create DAPM widgets for each DAI stream */ | 1198 | /* Create DAPM widgets for each DAI stream */ |
1198 | list_for_each_entry(dai, &dai_list, list) { | 1199 | list_for_each_entry(component, &component_list, list) { |
1199 | if (dai->dev != platform->dev) | 1200 | if (component->dev != platform->dev) |
1200 | continue; | 1201 | continue; |
1201 | 1202 | list_for_each_entry(dai, &component->dai_list, list) | |
1202 | snd_soc_dapm_new_dai_widgets(&platform->dapm, dai); | 1203 | snd_soc_dapm_new_dai_widgets(&platform->dapm, dai); |
1203 | } | 1204 | } |
1204 | 1205 | ||
1205 | platform->dapm.idle_bias_off = 1; | 1206 | platform->dapm.idle_bias_off = 1; |
@@ -2571,10 +2572,10 @@ int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, | |||
2571 | 2572 | ||
2572 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2573 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
2573 | uinfo->count = e->shift_l == e->shift_r ? 1 : 2; | 2574 | uinfo->count = e->shift_l == e->shift_r ? 1 : 2; |
2574 | uinfo->value.enumerated.items = e->max; | 2575 | uinfo->value.enumerated.items = e->items; |
2575 | 2576 | ||
2576 | if (uinfo->value.enumerated.item > e->max - 1) | 2577 | if (uinfo->value.enumerated.item >= e->items) |
2577 | uinfo->value.enumerated.item = e->max - 1; | 2578 | uinfo->value.enumerated.item = e->items - 1; |
2578 | strlcpy(uinfo->value.enumerated.name, | 2579 | strlcpy(uinfo->value.enumerated.name, |
2579 | e->texts[uinfo->value.enumerated.item], | 2580 | e->texts[uinfo->value.enumerated.item], |
2580 | sizeof(uinfo->value.enumerated.name)); | 2581 | sizeof(uinfo->value.enumerated.name)); |
@@ -2596,14 +2597,18 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, | |||
2596 | { | 2597 | { |
2597 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2598 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
2598 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 2599 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
2599 | unsigned int val; | 2600 | unsigned int val, item; |
2601 | unsigned int reg_val; | ||
2600 | 2602 | ||
2601 | val = snd_soc_read(codec, e->reg); | 2603 | reg_val = snd_soc_read(codec, e->reg); |
2602 | ucontrol->value.enumerated.item[0] | 2604 | val = (reg_val >> e->shift_l) & e->mask; |
2603 | = (val >> e->shift_l) & e->mask; | 2605 | item = snd_soc_enum_val_to_item(e, val); |
2604 | if (e->shift_l != e->shift_r) | 2606 | ucontrol->value.enumerated.item[0] = item; |
2605 | ucontrol->value.enumerated.item[1] = | 2607 | if (e->shift_l != e->shift_r) { |
2606 | (val >> e->shift_r) & e->mask; | 2608 | val = (reg_val >> e->shift_l) & e->mask; |
2609 | item = snd_soc_enum_val_to_item(e, val); | ||
2610 | ucontrol->value.enumerated.item[1] = item; | ||
2611 | } | ||
2607 | 2612 | ||
2608 | return 0; | 2613 | return 0; |
2609 | } | 2614 | } |
@@ -2623,17 +2628,18 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, | |||
2623 | { | 2628 | { |
2624 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2629 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
2625 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 2630 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
2631 | unsigned int *item = ucontrol->value.enumerated.item; | ||
2626 | unsigned int val; | 2632 | unsigned int val; |
2627 | unsigned int mask; | 2633 | unsigned int mask; |
2628 | 2634 | ||
2629 | if (ucontrol->value.enumerated.item[0] > e->max - 1) | 2635 | if (item[0] >= e->items) |
2630 | return -EINVAL; | 2636 | return -EINVAL; |
2631 | val = ucontrol->value.enumerated.item[0] << e->shift_l; | 2637 | val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; |
2632 | mask = e->mask << e->shift_l; | 2638 | mask = e->mask << e->shift_l; |
2633 | if (e->shift_l != e->shift_r) { | 2639 | if (e->shift_l != e->shift_r) { |
2634 | if (ucontrol->value.enumerated.item[1] > e->max - 1) | 2640 | if (item[1] >= e->items) |
2635 | return -EINVAL; | 2641 | return -EINVAL; |
2636 | val |= ucontrol->value.enumerated.item[1] << e->shift_r; | 2642 | val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; |
2637 | mask |= e->mask << e->shift_r; | 2643 | mask |= e->mask << e->shift_r; |
2638 | } | 2644 | } |
2639 | 2645 | ||
@@ -2642,78 +2648,46 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, | |||
2642 | EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); | 2648 | EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); |
2643 | 2649 | ||
2644 | /** | 2650 | /** |
2645 | * snd_soc_get_value_enum_double - semi enumerated double mixer get callback | 2651 | * snd_soc_read_signed - Read a codec register and interprete as signed value |
2646 | * @kcontrol: mixer control | 2652 | * @codec: codec |
2647 | * @ucontrol: control element information | 2653 | * @reg: Register to read |
2648 | * | 2654 | * @mask: Mask to use after shifting the register value |
2649 | * Callback to get the value of a double semi enumerated mixer. | 2655 | * @shift: Right shift of register value |
2656 | * @sign_bit: Bit that describes if a number is negative or not. | ||
2650 | * | 2657 | * |
2651 | * Semi enumerated mixer: the enumerated items are referred as values. Can be | 2658 | * This functions reads a codec register. The register value is shifted right |
2652 | * used for handling bitfield coded enumeration for example. | 2659 | * by 'shift' bits and masked with the given 'mask'. Afterwards it translates |
2660 | * the given registervalue into a signed integer if sign_bit is non-zero. | ||
2653 | * | 2661 | * |
2654 | * Returns 0 for success. | 2662 | * Returns the register value as signed int. |
2655 | */ | 2663 | */ |
2656 | int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol, | 2664 | static int snd_soc_read_signed(struct snd_soc_codec *codec, unsigned int reg, |
2657 | struct snd_ctl_elem_value *ucontrol) | 2665 | unsigned int mask, unsigned int shift, unsigned int sign_bit) |
2658 | { | 2666 | { |
2659 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2667 | int ret; |
2660 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 2668 | unsigned int val; |
2661 | unsigned int reg_val, val, mux; | ||
2662 | 2669 | ||
2663 | reg_val = snd_soc_read(codec, e->reg); | 2670 | val = (snd_soc_read(codec, reg) >> shift) & mask; |
2664 | val = (reg_val >> e->shift_l) & e->mask; | ||
2665 | for (mux = 0; mux < e->max; mux++) { | ||
2666 | if (val == e->values[mux]) | ||
2667 | break; | ||
2668 | } | ||
2669 | ucontrol->value.enumerated.item[0] = mux; | ||
2670 | if (e->shift_l != e->shift_r) { | ||
2671 | val = (reg_val >> e->shift_r) & e->mask; | ||
2672 | for (mux = 0; mux < e->max; mux++) { | ||
2673 | if (val == e->values[mux]) | ||
2674 | break; | ||
2675 | } | ||
2676 | ucontrol->value.enumerated.item[1] = mux; | ||
2677 | } | ||
2678 | 2671 | ||
2679 | return 0; | 2672 | if (!sign_bit) |
2680 | } | 2673 | return val; |
2681 | EXPORT_SYMBOL_GPL(snd_soc_get_value_enum_double); | ||
2682 | 2674 | ||
2683 | /** | 2675 | /* non-negative number */ |
2684 | * snd_soc_put_value_enum_double - semi enumerated double mixer put callback | 2676 | if (!(val & BIT(sign_bit))) |
2685 | * @kcontrol: mixer control | 2677 | return val; |
2686 | * @ucontrol: control element information | ||
2687 | * | ||
2688 | * Callback to set the value of a double semi enumerated mixer. | ||
2689 | * | ||
2690 | * Semi enumerated mixer: the enumerated items are referred as values. Can be | ||
2691 | * used for handling bitfield coded enumeration for example. | ||
2692 | * | ||
2693 | * Returns 0 for success. | ||
2694 | */ | ||
2695 | int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol, | ||
2696 | struct snd_ctl_elem_value *ucontrol) | ||
2697 | { | ||
2698 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2699 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
2700 | unsigned int val; | ||
2701 | unsigned int mask; | ||
2702 | 2678 | ||
2703 | if (ucontrol->value.enumerated.item[0] > e->max - 1) | 2679 | ret = val; |
2704 | return -EINVAL; | ||
2705 | val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l; | ||
2706 | mask = e->mask << e->shift_l; | ||
2707 | if (e->shift_l != e->shift_r) { | ||
2708 | if (ucontrol->value.enumerated.item[1] > e->max - 1) | ||
2709 | return -EINVAL; | ||
2710 | val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r; | ||
2711 | mask |= e->mask << e->shift_r; | ||
2712 | } | ||
2713 | 2680 | ||
2714 | return snd_soc_update_bits_locked(codec, e->reg, mask, val); | 2681 | /* |
2682 | * The register most probably does not contain a full-sized int. | ||
2683 | * Instead we have an arbitrary number of bits in a signed | ||
2684 | * representation which has to be translated into a full-sized int. | ||
2685 | * This is done by filling up all bits above the sign-bit. | ||
2686 | */ | ||
2687 | ret |= ~((int)(BIT(sign_bit) - 1)); | ||
2688 | |||
2689 | return ret; | ||
2715 | } | 2690 | } |
2716 | EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double); | ||
2717 | 2691 | ||
2718 | /** | 2692 | /** |
2719 | * snd_soc_info_volsw - single mixer info callback | 2693 | * snd_soc_info_volsw - single mixer info callback |
@@ -2743,7 +2717,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, | |||
2743 | 2717 | ||
2744 | uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; | 2718 | uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; |
2745 | uinfo->value.integer.min = 0; | 2719 | uinfo->value.integer.min = 0; |
2746 | uinfo->value.integer.max = platform_max; | 2720 | uinfo->value.integer.max = platform_max - mc->min; |
2747 | return 0; | 2721 | return 0; |
2748 | } | 2722 | } |
2749 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw); | 2723 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw); |
@@ -2769,11 +2743,16 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, | |||
2769 | unsigned int shift = mc->shift; | 2743 | unsigned int shift = mc->shift; |
2770 | unsigned int rshift = mc->rshift; | 2744 | unsigned int rshift = mc->rshift; |
2771 | int max = mc->max; | 2745 | int max = mc->max; |
2746 | int min = mc->min; | ||
2747 | int sign_bit = mc->sign_bit; | ||
2772 | unsigned int mask = (1 << fls(max)) - 1; | 2748 | unsigned int mask = (1 << fls(max)) - 1; |
2773 | unsigned int invert = mc->invert; | 2749 | unsigned int invert = mc->invert; |
2774 | 2750 | ||
2775 | ucontrol->value.integer.value[0] = | 2751 | if (sign_bit) |
2776 | (snd_soc_read(codec, reg) >> shift) & mask; | 2752 | mask = BIT(sign_bit + 1) - 1; |
2753 | |||
2754 | ucontrol->value.integer.value[0] = snd_soc_read_signed(codec, reg, mask, | ||
2755 | shift, sign_bit) - min; | ||
2777 | if (invert) | 2756 | if (invert) |
2778 | ucontrol->value.integer.value[0] = | 2757 | ucontrol->value.integer.value[0] = |
2779 | max - ucontrol->value.integer.value[0]; | 2758 | max - ucontrol->value.integer.value[0]; |
@@ -2781,10 +2760,12 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, | |||
2781 | if (snd_soc_volsw_is_stereo(mc)) { | 2760 | if (snd_soc_volsw_is_stereo(mc)) { |
2782 | if (reg == reg2) | 2761 | if (reg == reg2) |
2783 | ucontrol->value.integer.value[1] = | 2762 | ucontrol->value.integer.value[1] = |
2784 | (snd_soc_read(codec, reg) >> rshift) & mask; | 2763 | snd_soc_read_signed(codec, reg, mask, rshift, |
2764 | sign_bit) - min; | ||
2785 | else | 2765 | else |
2786 | ucontrol->value.integer.value[1] = | 2766 | ucontrol->value.integer.value[1] = |
2787 | (snd_soc_read(codec, reg2) >> shift) & mask; | 2767 | snd_soc_read_signed(codec, reg2, mask, shift, |
2768 | sign_bit) - min; | ||
2788 | if (invert) | 2769 | if (invert) |
2789 | ucontrol->value.integer.value[1] = | 2770 | ucontrol->value.integer.value[1] = |
2790 | max - ucontrol->value.integer.value[1]; | 2771 | max - ucontrol->value.integer.value[1]; |
@@ -2815,20 +2796,25 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, | |||
2815 | unsigned int shift = mc->shift; | 2796 | unsigned int shift = mc->shift; |
2816 | unsigned int rshift = mc->rshift; | 2797 | unsigned int rshift = mc->rshift; |
2817 | int max = mc->max; | 2798 | int max = mc->max; |
2799 | int min = mc->min; | ||
2800 | unsigned int sign_bit = mc->sign_bit; | ||
2818 | unsigned int mask = (1 << fls(max)) - 1; | 2801 | unsigned int mask = (1 << fls(max)) - 1; |
2819 | unsigned int invert = mc->invert; | 2802 | unsigned int invert = mc->invert; |
2820 | int err; | 2803 | int err; |
2821 | bool type_2r = 0; | 2804 | bool type_2r = false; |
2822 | unsigned int val2 = 0; | 2805 | unsigned int val2 = 0; |
2823 | unsigned int val, val_mask; | 2806 | unsigned int val, val_mask; |
2824 | 2807 | ||
2825 | val = (ucontrol->value.integer.value[0] & mask); | 2808 | if (sign_bit) |
2809 | mask = BIT(sign_bit + 1) - 1; | ||
2810 | |||
2811 | val = ((ucontrol->value.integer.value[0] + min) & mask); | ||
2826 | if (invert) | 2812 | if (invert) |
2827 | val = max - val; | 2813 | val = max - val; |
2828 | val_mask = mask << shift; | 2814 | val_mask = mask << shift; |
2829 | val = val << shift; | 2815 | val = val << shift; |
2830 | if (snd_soc_volsw_is_stereo(mc)) { | 2816 | if (snd_soc_volsw_is_stereo(mc)) { |
2831 | val2 = (ucontrol->value.integer.value[1] & mask); | 2817 | val2 = ((ucontrol->value.integer.value[1] + min) & mask); |
2832 | if (invert) | 2818 | if (invert) |
2833 | val2 = max - val2; | 2819 | val2 = max - val2; |
2834 | if (reg == reg2) { | 2820 | if (reg == reg2) { |
@@ -2836,7 +2822,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, | |||
2836 | val |= val2 << rshift; | 2822 | val |= val2 << rshift; |
2837 | } else { | 2823 | } else { |
2838 | val2 = val2 << shift; | 2824 | val2 = val2 << shift; |
2839 | type_2r = 1; | 2825 | type_2r = true; |
2840 | } | 2826 | } |
2841 | } | 2827 | } |
2842 | err = snd_soc_update_bits_locked(codec, reg, val_mask, val); | 2828 | err = snd_soc_update_bits_locked(codec, reg, val_mask, val); |
@@ -3234,7 +3220,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, | |||
3234 | struct soc_bytes *params = (void *)kcontrol->private_value; | 3220 | struct soc_bytes *params = (void *)kcontrol->private_value; |
3235 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 3221 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
3236 | int ret, len; | 3222 | int ret, len; |
3237 | unsigned int val; | 3223 | unsigned int val, mask; |
3238 | void *data; | 3224 | void *data; |
3239 | 3225 | ||
3240 | if (!codec->using_regmap) | 3226 | if (!codec->using_regmap) |
@@ -3264,12 +3250,36 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, | |||
3264 | ((u8 *)data)[0] |= val; | 3250 | ((u8 *)data)[0] |= val; |
3265 | break; | 3251 | break; |
3266 | case 2: | 3252 | case 2: |
3267 | ((u16 *)data)[0] &= cpu_to_be16(~params->mask); | 3253 | mask = ~params->mask; |
3268 | ((u16 *)data)[0] |= cpu_to_be16(val); | 3254 | ret = regmap_parse_val(codec->control_data, |
3255 | &mask, &mask); | ||
3256 | if (ret != 0) | ||
3257 | goto out; | ||
3258 | |||
3259 | ((u16 *)data)[0] &= mask; | ||
3260 | |||
3261 | ret = regmap_parse_val(codec->control_data, | ||
3262 | &val, &val); | ||
3263 | if (ret != 0) | ||
3264 | goto out; | ||
3265 | |||
3266 | ((u16 *)data)[0] |= val; | ||
3269 | break; | 3267 | break; |
3270 | case 4: | 3268 | case 4: |
3271 | ((u32 *)data)[0] &= cpu_to_be32(~params->mask); | 3269 | mask = ~params->mask; |
3272 | ((u32 *)data)[0] |= cpu_to_be32(val); | 3270 | ret = regmap_parse_val(codec->control_data, |
3271 | &mask, &mask); | ||
3272 | if (ret != 0) | ||
3273 | goto out; | ||
3274 | |||
3275 | ((u32 *)data)[0] &= mask; | ||
3276 | |||
3277 | ret = regmap_parse_val(codec->control_data, | ||
3278 | &val, &val); | ||
3279 | if (ret != 0) | ||
3280 | goto out; | ||
3281 | |||
3282 | ((u32 *)data)[0] |= val; | ||
3273 | break; | 3283 | break; |
3274 | default: | 3284 | default: |
3275 | ret = -EINVAL; | 3285 | ret = -EINVAL; |
@@ -3626,7 +3636,7 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, | |||
3626 | return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask, | 3636 | return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask, |
3627 | slots, slot_width); | 3637 | slots, slot_width); |
3628 | else | 3638 | else |
3629 | return -EINVAL; | 3639 | return -ENOTSUPP; |
3630 | } | 3640 | } |
3631 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); | 3641 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); |
3632 | 3642 | ||
@@ -3882,95 +3892,42 @@ static inline char *fmt_multiple_name(struct device *dev, | |||
3882 | } | 3892 | } |
3883 | 3893 | ||
3884 | /** | 3894 | /** |
3885 | * snd_soc_register_dai - Register a DAI with the ASoC core | 3895 | * snd_soc_unregister_dai - Unregister DAIs from the ASoC core |
3886 | * | 3896 | * |
3887 | * @dai: DAI to register | 3897 | * @component: The component for which the DAIs should be unregistered |
3888 | */ | 3898 | */ |
3889 | static int snd_soc_register_dai(struct device *dev, | 3899 | static void snd_soc_unregister_dais(struct snd_soc_component *component) |
3890 | struct snd_soc_dai_driver *dai_drv) | ||
3891 | { | 3900 | { |
3892 | struct snd_soc_codec *codec; | 3901 | struct snd_soc_dai *dai, *_dai; |
3893 | struct snd_soc_dai *dai; | ||
3894 | |||
3895 | dev_dbg(dev, "ASoC: dai register %s\n", dev_name(dev)); | ||
3896 | |||
3897 | dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); | ||
3898 | if (dai == NULL) | ||
3899 | return -ENOMEM; | ||
3900 | 3902 | ||
3901 | /* create DAI component name */ | 3903 | list_for_each_entry_safe(dai, _dai, &component->dai_list, list) { |
3902 | dai->name = fmt_single_name(dev, &dai->id); | 3904 | dev_dbg(component->dev, "ASoC: Unregistered DAI '%s'\n", |
3903 | if (dai->name == NULL) { | 3905 | dai->name); |
3906 | list_del(&dai->list); | ||
3907 | kfree(dai->name); | ||
3904 | kfree(dai); | 3908 | kfree(dai); |
3905 | return -ENOMEM; | ||
3906 | } | ||
3907 | |||
3908 | dai->dev = dev; | ||
3909 | dai->driver = dai_drv; | ||
3910 | dai->dapm.dev = dev; | ||
3911 | if (!dai->driver->ops) | ||
3912 | dai->driver->ops = &null_dai_ops; | ||
3913 | |||
3914 | mutex_lock(&client_mutex); | ||
3915 | |||
3916 | list_for_each_entry(codec, &codec_list, list) { | ||
3917 | if (codec->dev == dev) { | ||
3918 | dev_dbg(dev, "ASoC: Mapped DAI %s to CODEC %s\n", | ||
3919 | dai->name, codec->name); | ||
3920 | dai->codec = codec; | ||
3921 | break; | ||
3922 | } | ||
3923 | } | ||
3924 | |||
3925 | if (!dai->codec) | ||
3926 | dai->dapm.idle_bias_off = 1; | ||
3927 | |||
3928 | list_add(&dai->list, &dai_list); | ||
3929 | |||
3930 | mutex_unlock(&client_mutex); | ||
3931 | |||
3932 | dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name); | ||
3933 | |||
3934 | return 0; | ||
3935 | } | ||
3936 | |||
3937 | /** | ||
3938 | * snd_soc_unregister_dai - Unregister a DAI from the ASoC core | ||
3939 | * | ||
3940 | * @dai: DAI to unregister | ||
3941 | */ | ||
3942 | static void snd_soc_unregister_dai(struct device *dev) | ||
3943 | { | ||
3944 | struct snd_soc_dai *dai; | ||
3945 | |||
3946 | list_for_each_entry(dai, &dai_list, list) { | ||
3947 | if (dev == dai->dev) | ||
3948 | goto found; | ||
3949 | } | 3909 | } |
3950 | return; | ||
3951 | |||
3952 | found: | ||
3953 | mutex_lock(&client_mutex); | ||
3954 | list_del(&dai->list); | ||
3955 | mutex_unlock(&client_mutex); | ||
3956 | |||
3957 | dev_dbg(dev, "ASoC: Unregistered DAI '%s'\n", dai->name); | ||
3958 | kfree(dai->name); | ||
3959 | kfree(dai); | ||
3960 | } | 3910 | } |
3961 | 3911 | ||
3962 | /** | 3912 | /** |
3963 | * snd_soc_register_dais - Register multiple DAIs with the ASoC core | 3913 | * snd_soc_register_dais - Register a DAI with the ASoC core |
3964 | * | 3914 | * |
3965 | * @dai: Array of DAIs to register | 3915 | * @component: The component the DAIs are registered for |
3916 | * @codec: The CODEC that the DAIs are registered for, NULL if the component is | ||
3917 | * not a CODEC. | ||
3918 | * @dai_drv: DAI driver to use for the DAIs | ||
3966 | * @count: Number of DAIs | 3919 | * @count: Number of DAIs |
3920 | * @legacy_dai_naming: Use the legacy naming scheme and let the DAI inherit the | ||
3921 | * parent's name. | ||
3967 | */ | 3922 | */ |
3968 | static int snd_soc_register_dais(struct device *dev, | 3923 | static int snd_soc_register_dais(struct snd_soc_component *component, |
3969 | struct snd_soc_dai_driver *dai_drv, size_t count) | 3924 | struct snd_soc_codec *codec, struct snd_soc_dai_driver *dai_drv, |
3925 | size_t count, bool legacy_dai_naming) | ||
3970 | { | 3926 | { |
3971 | struct snd_soc_codec *codec; | 3927 | struct device *dev = component->dev; |
3972 | struct snd_soc_dai *dai; | 3928 | struct snd_soc_dai *dai; |
3973 | int i, ret = 0; | 3929 | unsigned int i; |
3930 | int ret; | ||
3974 | 3931 | ||
3975 | dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count); | 3932 | dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count); |
3976 | 3933 | ||
@@ -3982,70 +3939,54 @@ static int snd_soc_register_dais(struct device *dev, | |||
3982 | goto err; | 3939 | goto err; |
3983 | } | 3940 | } |
3984 | 3941 | ||
3985 | /* create DAI component name */ | 3942 | /* |
3986 | dai->name = fmt_multiple_name(dev, &dai_drv[i]); | 3943 | * Back in the old days when we still had component-less DAIs, |
3944 | * instead of having a static name, component-less DAIs would | ||
3945 | * inherit the name of the parent device so it is possible to | ||
3946 | * register multiple instances of the DAI. We still need to keep | ||
3947 | * the same naming style even though those DAIs are not | ||
3948 | * component-less anymore. | ||
3949 | */ | ||
3950 | if (count == 1 && legacy_dai_naming) { | ||
3951 | dai->name = fmt_single_name(dev, &dai->id); | ||
3952 | } else { | ||
3953 | dai->name = fmt_multiple_name(dev, &dai_drv[i]); | ||
3954 | if (dai_drv[i].id) | ||
3955 | dai->id = dai_drv[i].id; | ||
3956 | else | ||
3957 | dai->id = i; | ||
3958 | } | ||
3987 | if (dai->name == NULL) { | 3959 | if (dai->name == NULL) { |
3988 | kfree(dai); | 3960 | kfree(dai); |
3989 | ret = -EINVAL; | 3961 | ret = -ENOMEM; |
3990 | goto err; | 3962 | goto err; |
3991 | } | 3963 | } |
3992 | 3964 | ||
3965 | dai->component = component; | ||
3966 | dai->codec = codec; | ||
3993 | dai->dev = dev; | 3967 | dai->dev = dev; |
3994 | dai->driver = &dai_drv[i]; | 3968 | dai->driver = &dai_drv[i]; |
3995 | if (dai->driver->id) | ||
3996 | dai->id = dai->driver->id; | ||
3997 | else | ||
3998 | dai->id = i; | ||
3999 | dai->dapm.dev = dev; | 3969 | dai->dapm.dev = dev; |
4000 | if (!dai->driver->ops) | 3970 | if (!dai->driver->ops) |
4001 | dai->driver->ops = &null_dai_ops; | 3971 | dai->driver->ops = &null_dai_ops; |
4002 | 3972 | ||
4003 | mutex_lock(&client_mutex); | ||
4004 | |||
4005 | list_for_each_entry(codec, &codec_list, list) { | ||
4006 | if (codec->dev == dev) { | ||
4007 | dev_dbg(dev, | ||
4008 | "ASoC: Mapped DAI %s to CODEC %s\n", | ||
4009 | dai->name, codec->name); | ||
4010 | dai->codec = codec; | ||
4011 | break; | ||
4012 | } | ||
4013 | } | ||
4014 | |||
4015 | if (!dai->codec) | 3973 | if (!dai->codec) |
4016 | dai->dapm.idle_bias_off = 1; | 3974 | dai->dapm.idle_bias_off = 1; |
4017 | 3975 | ||
4018 | list_add(&dai->list, &dai_list); | 3976 | list_add(&dai->list, &component->dai_list); |
4019 | 3977 | ||
4020 | mutex_unlock(&client_mutex); | 3978 | dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name); |
4021 | |||
4022 | dev_dbg(dai->dev, "ASoC: Registered DAI '%s'\n", dai->name); | ||
4023 | } | 3979 | } |
4024 | 3980 | ||
4025 | return 0; | 3981 | return 0; |
4026 | 3982 | ||
4027 | err: | 3983 | err: |
4028 | for (i--; i >= 0; i--) | 3984 | snd_soc_unregister_dais(component); |
4029 | snd_soc_unregister_dai(dev); | ||
4030 | 3985 | ||
4031 | return ret; | 3986 | return ret; |
4032 | } | 3987 | } |
4033 | 3988 | ||
4034 | /** | 3989 | /** |
4035 | * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core | ||
4036 | * | ||
4037 | * @dai: Array of DAIs to unregister | ||
4038 | * @count: Number of DAIs | ||
4039 | */ | ||
4040 | static void snd_soc_unregister_dais(struct device *dev, size_t count) | ||
4041 | { | ||
4042 | int i; | ||
4043 | |||
4044 | for (i = 0; i < count; i++) | ||
4045 | snd_soc_unregister_dai(dev); | ||
4046 | } | ||
4047 | |||
4048 | /** | ||
4049 | * snd_soc_register_component - Register a component with the ASoC core | 3990 | * snd_soc_register_component - Register a component with the ASoC core |
4050 | * | 3991 | * |
4051 | */ | 3992 | */ |
@@ -4053,6 +3994,7 @@ static int | |||
4053 | __snd_soc_register_component(struct device *dev, | 3994 | __snd_soc_register_component(struct device *dev, |
4054 | struct snd_soc_component *cmpnt, | 3995 | struct snd_soc_component *cmpnt, |
4055 | const struct snd_soc_component_driver *cmpnt_drv, | 3996 | const struct snd_soc_component_driver *cmpnt_drv, |
3997 | struct snd_soc_codec *codec, | ||
4056 | struct snd_soc_dai_driver *dai_drv, | 3998 | struct snd_soc_dai_driver *dai_drv, |
4057 | int num_dai, bool allow_single_dai) | 3999 | int num_dai, bool allow_single_dai) |
4058 | { | 4000 | { |
@@ -4075,20 +4017,10 @@ __snd_soc_register_component(struct device *dev, | |||
4075 | cmpnt->driver = cmpnt_drv; | 4017 | cmpnt->driver = cmpnt_drv; |
4076 | cmpnt->dai_drv = dai_drv; | 4018 | cmpnt->dai_drv = dai_drv; |
4077 | cmpnt->num_dai = num_dai; | 4019 | cmpnt->num_dai = num_dai; |
4020 | INIT_LIST_HEAD(&cmpnt->dai_list); | ||
4078 | 4021 | ||
4079 | /* | 4022 | ret = snd_soc_register_dais(cmpnt, codec, dai_drv, num_dai, |
4080 | * snd_soc_register_dai() uses fmt_single_name(), and | 4023 | allow_single_dai); |
4081 | * snd_soc_register_dais() uses fmt_multiple_name() | ||
4082 | * for dai->name which is used for name based matching | ||
4083 | * | ||
4084 | * this function is used from cpu/codec. | ||
4085 | * allow_single_dai flag can ignore "codec" driver reworking | ||
4086 | * since it had been used snd_soc_register_dais(), | ||
4087 | */ | ||
4088 | if ((1 == num_dai) && allow_single_dai) | ||
4089 | ret = snd_soc_register_dai(dev, dai_drv); | ||
4090 | else | ||
4091 | ret = snd_soc_register_dais(dev, dai_drv, num_dai); | ||
4092 | if (ret < 0) { | 4024 | if (ret < 0) { |
4093 | dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret); | 4025 | dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret); |
4094 | goto error_component_name; | 4026 | goto error_component_name; |
@@ -4121,7 +4053,9 @@ int snd_soc_register_component(struct device *dev, | |||
4121 | return -ENOMEM; | 4053 | return -ENOMEM; |
4122 | } | 4054 | } |
4123 | 4055 | ||
4124 | return __snd_soc_register_component(dev, cmpnt, cmpnt_drv, | 4056 | cmpnt->ignore_pmdown_time = true; |
4057 | |||
4058 | return __snd_soc_register_component(dev, cmpnt, cmpnt_drv, NULL, | ||
4125 | dai_drv, num_dai, true); | 4059 | dai_drv, num_dai, true); |
4126 | } | 4060 | } |
4127 | EXPORT_SYMBOL_GPL(snd_soc_register_component); | 4061 | EXPORT_SYMBOL_GPL(snd_soc_register_component); |
@@ -4141,7 +4075,7 @@ void snd_soc_unregister_component(struct device *dev) | |||
4141 | return; | 4075 | return; |
4142 | 4076 | ||
4143 | found: | 4077 | found: |
4144 | snd_soc_unregister_dais(dev, cmpnt->num_dai); | 4078 | snd_soc_unregister_dais(cmpnt); |
4145 | 4079 | ||
4146 | mutex_lock(&client_mutex); | 4080 | mutex_lock(&client_mutex); |
4147 | list_del(&cmpnt->list); | 4081 | list_del(&cmpnt->list); |
@@ -4319,7 +4253,7 @@ int snd_soc_register_codec(struct device *dev, | |||
4319 | codec->volatile_register = codec_drv->volatile_register; | 4253 | codec->volatile_register = codec_drv->volatile_register; |
4320 | codec->readable_register = codec_drv->readable_register; | 4254 | codec->readable_register = codec_drv->readable_register; |
4321 | codec->writable_register = codec_drv->writable_register; | 4255 | codec->writable_register = codec_drv->writable_register; |
4322 | codec->ignore_pmdown_time = codec_drv->ignore_pmdown_time; | 4256 | codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; |
4323 | codec->dapm.bias_level = SND_SOC_BIAS_OFF; | 4257 | codec->dapm.bias_level = SND_SOC_BIAS_OFF; |
4324 | codec->dapm.dev = dev; | 4258 | codec->dapm.dev = dev; |
4325 | codec->dapm.codec = codec; | 4259 | codec->dapm.codec = codec; |
@@ -4342,7 +4276,7 @@ int snd_soc_register_codec(struct device *dev, | |||
4342 | /* register component */ | 4276 | /* register component */ |
4343 | ret = __snd_soc_register_component(dev, &codec->component, | 4277 | ret = __snd_soc_register_component(dev, &codec->component, |
4344 | &codec_drv->component_driver, | 4278 | &codec_drv->component_driver, |
4345 | dai_drv, num_dai, false); | 4279 | codec, dai_drv, num_dai, false); |
4346 | if (ret < 0) { | 4280 | if (ret < 0) { |
4347 | dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret); | 4281 | dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret); |
4348 | goto fail_codec_name; | 4282 | goto fail_codec_name; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index dc8ff13187f7..c8a780d0d057 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -70,8 +70,6 @@ static int dapm_up_seq[] = { | |||
70 | [snd_soc_dapm_aif_out] = 4, | 70 | [snd_soc_dapm_aif_out] = 4, |
71 | [snd_soc_dapm_mic] = 5, | 71 | [snd_soc_dapm_mic] = 5, |
72 | [snd_soc_dapm_mux] = 6, | 72 | [snd_soc_dapm_mux] = 6, |
73 | [snd_soc_dapm_virt_mux] = 6, | ||
74 | [snd_soc_dapm_value_mux] = 6, | ||
75 | [snd_soc_dapm_dac] = 7, | 73 | [snd_soc_dapm_dac] = 7, |
76 | [snd_soc_dapm_switch] = 8, | 74 | [snd_soc_dapm_switch] = 8, |
77 | [snd_soc_dapm_mixer] = 8, | 75 | [snd_soc_dapm_mixer] = 8, |
@@ -102,8 +100,6 @@ static int dapm_down_seq[] = { | |||
102 | [snd_soc_dapm_mic] = 7, | 100 | [snd_soc_dapm_mic] = 7, |
103 | [snd_soc_dapm_micbias] = 8, | 101 | [snd_soc_dapm_micbias] = 8, |
104 | [snd_soc_dapm_mux] = 9, | 102 | [snd_soc_dapm_mux] = 9, |
105 | [snd_soc_dapm_virt_mux] = 9, | ||
106 | [snd_soc_dapm_value_mux] = 9, | ||
107 | [snd_soc_dapm_aif_in] = 10, | 103 | [snd_soc_dapm_aif_in] = 10, |
108 | [snd_soc_dapm_aif_out] = 10, | 104 | [snd_soc_dapm_aif_out] = 10, |
109 | [snd_soc_dapm_dai_in] = 10, | 105 | [snd_soc_dapm_dai_in] = 10, |
@@ -115,6 +111,12 @@ static int dapm_down_seq[] = { | |||
115 | [snd_soc_dapm_post] = 14, | 111 | [snd_soc_dapm_post] = 14, |
116 | }; | 112 | }; |
117 | 113 | ||
114 | static void dapm_assert_locked(struct snd_soc_dapm_context *dapm) | ||
115 | { | ||
116 | if (dapm->card && dapm->card->instantiated) | ||
117 | lockdep_assert_held(&dapm->card->dapm_mutex); | ||
118 | } | ||
119 | |||
118 | static void pop_wait(u32 pop_time) | 120 | static void pop_wait(u32 pop_time) |
119 | { | 121 | { |
120 | if (pop_time) | 122 | if (pop_time) |
@@ -146,15 +148,16 @@ static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w) | |||
146 | return !list_empty(&w->dirty); | 148 | return !list_empty(&w->dirty); |
147 | } | 149 | } |
148 | 150 | ||
149 | void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason) | 151 | static void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason) |
150 | { | 152 | { |
153 | dapm_assert_locked(w->dapm); | ||
154 | |||
151 | if (!dapm_dirty_widget(w)) { | 155 | if (!dapm_dirty_widget(w)) { |
152 | dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n", | 156 | dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n", |
153 | w->name, reason); | 157 | w->name, reason); |
154 | list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty); | 158 | list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty); |
155 | } | 159 | } |
156 | } | 160 | } |
157 | EXPORT_SYMBOL_GPL(dapm_mark_dirty); | ||
158 | 161 | ||
159 | void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm) | 162 | void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm) |
160 | { | 163 | { |
@@ -361,6 +364,8 @@ static void dapm_reset(struct snd_soc_card *card) | |||
361 | { | 364 | { |
362 | struct snd_soc_dapm_widget *w; | 365 | struct snd_soc_dapm_widget *w; |
363 | 366 | ||
367 | lockdep_assert_held(&card->dapm_mutex); | ||
368 | |||
364 | memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); | 369 | memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); |
365 | 370 | ||
366 | list_for_each_entry(w, &card->widgets, list) { | 371 | list_for_each_entry(w, &card->widgets, list) { |
@@ -386,7 +391,8 @@ static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg, | |||
386 | return -1; | 391 | return -1; |
387 | } | 392 | } |
388 | 393 | ||
389 | static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val) | 394 | static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, |
395 | unsigned int val) | ||
390 | { | 396 | { |
391 | if (w->codec) | 397 | if (w->codec) |
392 | return snd_soc_write(w->codec, reg, val); | 398 | return snd_soc_write(w->codec, reg, val); |
@@ -498,131 +504,40 @@ out: | |||
498 | return ret; | 504 | return ret; |
499 | } | 505 | } |
500 | 506 | ||
501 | /* set up initial codec paths */ | 507 | /* connect mux widget to its interconnecting audio paths */ |
502 | static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | 508 | static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, |
503 | struct snd_soc_dapm_path *p, int i) | 509 | struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, |
510 | struct snd_soc_dapm_path *path, const char *control_name, | ||
511 | const struct snd_kcontrol_new *kcontrol) | ||
504 | { | 512 | { |
505 | switch (w->id) { | 513 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
506 | case snd_soc_dapm_switch: | 514 | unsigned int val, item; |
507 | case snd_soc_dapm_mixer: | 515 | int i; |
508 | case snd_soc_dapm_mixer_named_ctl: { | ||
509 | int val; | ||
510 | struct soc_mixer_control *mc = (struct soc_mixer_control *) | ||
511 | w->kcontrol_news[i].private_value; | ||
512 | int reg = mc->reg; | ||
513 | unsigned int shift = mc->shift; | ||
514 | int max = mc->max; | ||
515 | unsigned int mask = (1 << fls(max)) - 1; | ||
516 | unsigned int invert = mc->invert; | ||
517 | |||
518 | if (reg != SND_SOC_NOPM) { | ||
519 | soc_widget_read(w, reg, &val); | ||
520 | val = (val >> shift) & mask; | ||
521 | if (invert) | ||
522 | val = max - val; | ||
523 | p->connect = !!val; | ||
524 | } else { | ||
525 | p->connect = 0; | ||
526 | } | ||
527 | |||
528 | } | ||
529 | break; | ||
530 | case snd_soc_dapm_mux: { | ||
531 | struct soc_enum *e = (struct soc_enum *) | ||
532 | w->kcontrol_news[i].private_value; | ||
533 | int val, item; | ||
534 | |||
535 | soc_widget_read(w, e->reg, &val); | ||
536 | item = (val >> e->shift_l) & e->mask; | ||
537 | |||
538 | if (item < e->max && !strcmp(p->name, e->texts[item])) | ||
539 | p->connect = 1; | ||
540 | else | ||
541 | p->connect = 0; | ||
542 | } | ||
543 | break; | ||
544 | case snd_soc_dapm_virt_mux: { | ||
545 | struct soc_enum *e = (struct soc_enum *) | ||
546 | w->kcontrol_news[i].private_value; | ||
547 | 516 | ||
548 | p->connect = 0; | 517 | if (e->reg != SND_SOC_NOPM) { |
518 | soc_widget_read(dest, e->reg, &val); | ||
519 | val = (val >> e->shift_l) & e->mask; | ||
520 | item = snd_soc_enum_val_to_item(e, val); | ||
521 | } else { | ||
549 | /* since a virtual mux has no backing registers to | 522 | /* since a virtual mux has no backing registers to |
550 | * decide which path to connect, it will try to match | 523 | * decide which path to connect, it will try to match |
551 | * with the first enumeration. This is to ensure | 524 | * with the first enumeration. This is to ensure |
552 | * that the default mux choice (the first) will be | 525 | * that the default mux choice (the first) will be |
553 | * correctly powered up during initialization. | 526 | * correctly powered up during initialization. |
554 | */ | 527 | */ |
555 | if (!strcmp(p->name, e->texts[0])) | 528 | item = 0; |
556 | p->connect = 1; | ||
557 | } | ||
558 | break; | ||
559 | case snd_soc_dapm_value_mux: { | ||
560 | struct soc_enum *e = (struct soc_enum *) | ||
561 | w->kcontrol_news[i].private_value; | ||
562 | int val, item; | ||
563 | |||
564 | soc_widget_read(w, e->reg, &val); | ||
565 | val = (val >> e->shift_l) & e->mask; | ||
566 | for (item = 0; item < e->max; item++) { | ||
567 | if (val == e->values[item]) | ||
568 | break; | ||
569 | } | ||
570 | |||
571 | if (item < e->max && !strcmp(p->name, e->texts[item])) | ||
572 | p->connect = 1; | ||
573 | else | ||
574 | p->connect = 0; | ||
575 | } | ||
576 | break; | ||
577 | /* does not affect routing - always connected */ | ||
578 | case snd_soc_dapm_pga: | ||
579 | case snd_soc_dapm_out_drv: | ||
580 | case snd_soc_dapm_output: | ||
581 | case snd_soc_dapm_adc: | ||
582 | case snd_soc_dapm_input: | ||
583 | case snd_soc_dapm_siggen: | ||
584 | case snd_soc_dapm_dac: | ||
585 | case snd_soc_dapm_micbias: | ||
586 | case snd_soc_dapm_vmid: | ||
587 | case snd_soc_dapm_supply: | ||
588 | case snd_soc_dapm_regulator_supply: | ||
589 | case snd_soc_dapm_clock_supply: | ||
590 | case snd_soc_dapm_aif_in: | ||
591 | case snd_soc_dapm_aif_out: | ||
592 | case snd_soc_dapm_dai_in: | ||
593 | case snd_soc_dapm_dai_out: | ||
594 | case snd_soc_dapm_hp: | ||
595 | case snd_soc_dapm_mic: | ||
596 | case snd_soc_dapm_spk: | ||
597 | case snd_soc_dapm_line: | ||
598 | case snd_soc_dapm_dai_link: | ||
599 | case snd_soc_dapm_kcontrol: | ||
600 | p->connect = 1; | ||
601 | break; | ||
602 | /* does affect routing - dynamically connected */ | ||
603 | case snd_soc_dapm_pre: | ||
604 | case snd_soc_dapm_post: | ||
605 | p->connect = 0; | ||
606 | break; | ||
607 | } | 529 | } |
608 | } | ||
609 | |||
610 | /* connect mux widget to its interconnecting audio paths */ | ||
611 | static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, | ||
612 | struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, | ||
613 | struct snd_soc_dapm_path *path, const char *control_name, | ||
614 | const struct snd_kcontrol_new *kcontrol) | ||
615 | { | ||
616 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
617 | int i; | ||
618 | 530 | ||
619 | for (i = 0; i < e->max; i++) { | 531 | for (i = 0; i < e->items; i++) { |
620 | if (!(strcmp(control_name, e->texts[i]))) { | 532 | if (!(strcmp(control_name, e->texts[i]))) { |
621 | list_add(&path->list, &dapm->card->paths); | 533 | list_add(&path->list, &dapm->card->paths); |
622 | list_add(&path->list_sink, &dest->sources); | 534 | list_add(&path->list_sink, &dest->sources); |
623 | list_add(&path->list_source, &src->sinks); | 535 | list_add(&path->list_source, &src->sinks); |
624 | path->name = (char*)e->texts[i]; | 536 | path->name = (char*)e->texts[i]; |
625 | dapm_set_path_status(dest, path, 0); | 537 | if (i == item) |
538 | path->connect = 1; | ||
539 | else | ||
540 | path->connect = 0; | ||
626 | return 0; | 541 | return 0; |
627 | } | 542 | } |
628 | } | 543 | } |
@@ -630,6 +545,30 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, | |||
630 | return -ENODEV; | 545 | return -ENODEV; |
631 | } | 546 | } |
632 | 547 | ||
548 | /* set up initial codec paths */ | ||
549 | static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w, | ||
550 | struct snd_soc_dapm_path *p, int i) | ||
551 | { | ||
552 | struct soc_mixer_control *mc = (struct soc_mixer_control *) | ||
553 | w->kcontrol_news[i].private_value; | ||
554 | unsigned int reg = mc->reg; | ||
555 | unsigned int shift = mc->shift; | ||
556 | unsigned int max = mc->max; | ||
557 | unsigned int mask = (1 << fls(max)) - 1; | ||
558 | unsigned int invert = mc->invert; | ||
559 | unsigned int val; | ||
560 | |||
561 | if (reg != SND_SOC_NOPM) { | ||
562 | soc_widget_read(w, reg, &val); | ||
563 | val = (val >> shift) & mask; | ||
564 | if (invert) | ||
565 | val = max - val; | ||
566 | p->connect = !!val; | ||
567 | } else { | ||
568 | p->connect = 0; | ||
569 | } | ||
570 | } | ||
571 | |||
633 | /* connect mixer widget to its interconnecting audio paths */ | 572 | /* connect mixer widget to its interconnecting audio paths */ |
634 | static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, | 573 | static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, |
635 | struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, | 574 | struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, |
@@ -644,7 +583,7 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, | |||
644 | list_add(&path->list_sink, &dest->sources); | 583 | list_add(&path->list_sink, &dest->sources); |
645 | list_add(&path->list_source, &src->sinks); | 584 | list_add(&path->list_source, &src->sinks); |
646 | path->name = dest->kcontrol_news[i].name; | 585 | path->name = dest->kcontrol_news[i].name; |
647 | dapm_set_path_status(dest, path, i); | 586 | dapm_set_mixer_path_status(dest, path, i); |
648 | return 0; | 587 | return 0; |
649 | } | 588 | } |
650 | } | 589 | } |
@@ -723,8 +662,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w, | |||
723 | kcname_in_long_name = true; | 662 | kcname_in_long_name = true; |
724 | break; | 663 | break; |
725 | case snd_soc_dapm_mux: | 664 | case snd_soc_dapm_mux: |
726 | case snd_soc_dapm_virt_mux: | ||
727 | case snd_soc_dapm_value_mux: | ||
728 | wname_in_long_name = true; | 665 | wname_in_long_name = true; |
729 | kcname_in_long_name = false; | 666 | kcname_in_long_name = false; |
730 | break; | 667 | break; |
@@ -1218,7 +1155,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, | |||
1218 | ret = regulator_allow_bypass(w->regulator, false); | 1155 | ret = regulator_allow_bypass(w->regulator, false); |
1219 | if (ret != 0) | 1156 | if (ret != 0) |
1220 | dev_warn(w->dapm->dev, | 1157 | dev_warn(w->dapm->dev, |
1221 | "ASoC: Failed to bypass %s: %d\n", | 1158 | "ASoC: Failed to unbypass %s: %d\n", |
1222 | w->name, ret); | 1159 | w->name, ret); |
1223 | } | 1160 | } |
1224 | 1161 | ||
@@ -1228,7 +1165,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, | |||
1228 | ret = regulator_allow_bypass(w->regulator, true); | 1165 | ret = regulator_allow_bypass(w->regulator, true); |
1229 | if (ret != 0) | 1166 | if (ret != 0) |
1230 | dev_warn(w->dapm->dev, | 1167 | dev_warn(w->dapm->dev, |
1231 | "ASoC: Failed to unbypass %s: %d\n", | 1168 | "ASoC: Failed to bypass %s: %d\n", |
1232 | w->name, ret); | 1169 | w->name, ret); |
1233 | } | 1170 | } |
1234 | 1171 | ||
@@ -1823,6 +1760,8 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event) | |||
1823 | ASYNC_DOMAIN_EXCLUSIVE(async_domain); | 1760 | ASYNC_DOMAIN_EXCLUSIVE(async_domain); |
1824 | enum snd_soc_bias_level bias; | 1761 | enum snd_soc_bias_level bias; |
1825 | 1762 | ||
1763 | lockdep_assert_held(&card->dapm_mutex); | ||
1764 | |||
1826 | trace_snd_soc_dapm_start(card); | 1765 | trace_snd_soc_dapm_start(card); |
1827 | 1766 | ||
1828 | list_for_each_entry(d, &card->dapm_list, list) { | 1767 | list_for_each_entry(d, &card->dapm_list, list) { |
@@ -1897,10 +1836,14 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event) | |||
1897 | 1836 | ||
1898 | trace_snd_soc_dapm_walk_done(card); | 1837 | trace_snd_soc_dapm_walk_done(card); |
1899 | 1838 | ||
1900 | /* Run all the bias changes in parallel */ | 1839 | /* Run card bias changes at first */ |
1901 | list_for_each_entry(d, &card->dapm_list, list) | 1840 | dapm_pre_sequence_async(&card->dapm, 0); |
1902 | async_schedule_domain(dapm_pre_sequence_async, d, | 1841 | /* Run other bias changes in parallel */ |
1903 | &async_domain); | 1842 | list_for_each_entry(d, &card->dapm_list, list) { |
1843 | if (d != &card->dapm) | ||
1844 | async_schedule_domain(dapm_pre_sequence_async, d, | ||
1845 | &async_domain); | ||
1846 | } | ||
1904 | async_synchronize_full_domain(&async_domain); | 1847 | async_synchronize_full_domain(&async_domain); |
1905 | 1848 | ||
1906 | list_for_each_entry(w, &down_list, power_list) { | 1849 | list_for_each_entry(w, &down_list, power_list) { |
@@ -1920,10 +1863,14 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event) | |||
1920 | dapm_seq_run(card, &up_list, event, true); | 1863 | dapm_seq_run(card, &up_list, event, true); |
1921 | 1864 | ||
1922 | /* Run all the bias changes in parallel */ | 1865 | /* Run all the bias changes in parallel */ |
1923 | list_for_each_entry(d, &card->dapm_list, list) | 1866 | list_for_each_entry(d, &card->dapm_list, list) { |
1924 | async_schedule_domain(dapm_post_sequence_async, d, | 1867 | if (d != &card->dapm) |
1925 | &async_domain); | 1868 | async_schedule_domain(dapm_post_sequence_async, d, |
1869 | &async_domain); | ||
1870 | } | ||
1926 | async_synchronize_full_domain(&async_domain); | 1871 | async_synchronize_full_domain(&async_domain); |
1872 | /* Run card bias changes at last */ | ||
1873 | dapm_post_sequence_async(&card->dapm, 0); | ||
1927 | 1874 | ||
1928 | /* do we need to notify any clients that DAPM event is complete */ | 1875 | /* do we need to notify any clients that DAPM event is complete */ |
1929 | list_for_each_entry(d, &card->dapm_list, list) { | 1876 | list_for_each_entry(d, &card->dapm_list, list) { |
@@ -2110,6 +2057,8 @@ static int soc_dapm_mux_update_power(struct snd_soc_card *card, | |||
2110 | struct snd_soc_dapm_path *path; | 2057 | struct snd_soc_dapm_path *path; |
2111 | int found = 0; | 2058 | int found = 0; |
2112 | 2059 | ||
2060 | lockdep_assert_held(&card->dapm_mutex); | ||
2061 | |||
2113 | /* find dapm widget path assoc with kcontrol */ | 2062 | /* find dapm widget path assoc with kcontrol */ |
2114 | dapm_kcontrol_for_each_path(path, kcontrol) { | 2063 | dapm_kcontrol_for_each_path(path, kcontrol) { |
2115 | if (!path->name || !e->texts[mux]) | 2064 | if (!path->name || !e->texts[mux]) |
@@ -2160,6 +2109,8 @@ static int soc_dapm_mixer_update_power(struct snd_soc_card *card, | |||
2160 | struct snd_soc_dapm_path *path; | 2109 | struct snd_soc_dapm_path *path; |
2161 | int found = 0; | 2110 | int found = 0; |
2162 | 2111 | ||
2112 | lockdep_assert_held(&card->dapm_mutex); | ||
2113 | |||
2163 | /* find dapm widget path assoc with kcontrol */ | 2114 | /* find dapm widget path assoc with kcontrol */ |
2164 | dapm_kcontrol_for_each_path(path, kcontrol) { | 2115 | dapm_kcontrol_for_each_path(path, kcontrol) { |
2165 | found = 1; | 2116 | found = 1; |
@@ -2325,6 +2276,8 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, | |||
2325 | { | 2276 | { |
2326 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); | 2277 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); |
2327 | 2278 | ||
2279 | dapm_assert_locked(dapm); | ||
2280 | |||
2328 | if (!w) { | 2281 | if (!w) { |
2329 | dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin); | 2282 | dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin); |
2330 | return -EINVAL; | 2283 | return -EINVAL; |
@@ -2341,18 +2294,18 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, | |||
2341 | } | 2294 | } |
2342 | 2295 | ||
2343 | /** | 2296 | /** |
2344 | * snd_soc_dapm_sync - scan and power dapm paths | 2297 | * snd_soc_dapm_sync_unlocked - scan and power dapm paths |
2345 | * @dapm: DAPM context | 2298 | * @dapm: DAPM context |
2346 | * | 2299 | * |
2347 | * Walks all dapm audio paths and powers widgets according to their | 2300 | * Walks all dapm audio paths and powers widgets according to their |
2348 | * stream or path usage. | 2301 | * stream or path usage. |
2349 | * | 2302 | * |
2303 | * Requires external locking. | ||
2304 | * | ||
2350 | * Returns 0 for success. | 2305 | * Returns 0 for success. |
2351 | */ | 2306 | */ |
2352 | int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) | 2307 | int snd_soc_dapm_sync_unlocked(struct snd_soc_dapm_context *dapm) |
2353 | { | 2308 | { |
2354 | int ret; | ||
2355 | |||
2356 | /* | 2309 | /* |
2357 | * Suppress early reports (eg, jacks syncing their state) to avoid | 2310 | * Suppress early reports (eg, jacks syncing their state) to avoid |
2358 | * silly DAPM runs during card startup. | 2311 | * silly DAPM runs during card startup. |
@@ -2360,8 +2313,25 @@ int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) | |||
2360 | if (!dapm->card || !dapm->card->instantiated) | 2313 | if (!dapm->card || !dapm->card->instantiated) |
2361 | return 0; | 2314 | return 0; |
2362 | 2315 | ||
2316 | return dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP); | ||
2317 | } | ||
2318 | EXPORT_SYMBOL_GPL(snd_soc_dapm_sync_unlocked); | ||
2319 | |||
2320 | /** | ||
2321 | * snd_soc_dapm_sync - scan and power dapm paths | ||
2322 | * @dapm: DAPM context | ||
2323 | * | ||
2324 | * Walks all dapm audio paths and powers widgets according to their | ||
2325 | * stream or path usage. | ||
2326 | * | ||
2327 | * Returns 0 for success. | ||
2328 | */ | ||
2329 | int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) | ||
2330 | { | ||
2331 | int ret; | ||
2332 | |||
2363 | mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | 2333 | mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); |
2364 | ret = dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP); | 2334 | ret = snd_soc_dapm_sync_unlocked(dapm); |
2365 | mutex_unlock(&dapm->card->dapm_mutex); | 2335 | mutex_unlock(&dapm->card->dapm_mutex); |
2366 | return ret; | 2336 | return ret; |
2367 | } | 2337 | } |
@@ -2444,8 +2414,6 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, | |||
2444 | path->connect = 1; | 2414 | path->connect = 1; |
2445 | return 0; | 2415 | return 0; |
2446 | case snd_soc_dapm_mux: | 2416 | case snd_soc_dapm_mux: |
2447 | case snd_soc_dapm_virt_mux: | ||
2448 | case snd_soc_dapm_value_mux: | ||
2449 | ret = dapm_connect_mux(dapm, wsource, wsink, path, control, | 2417 | ret = dapm_connect_mux(dapm, wsource, wsink, path, control, |
2450 | &wsink->kcontrol_news[0]); | 2418 | &wsink->kcontrol_news[0]); |
2451 | if (ret != 0) | 2419 | if (ret != 0) |
@@ -2772,8 +2740,6 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card) | |||
2772 | dapm_new_mixer(w); | 2740 | dapm_new_mixer(w); |
2773 | break; | 2741 | break; |
2774 | case snd_soc_dapm_mux: | 2742 | case snd_soc_dapm_mux: |
2775 | case snd_soc_dapm_virt_mux: | ||
2776 | case snd_soc_dapm_value_mux: | ||
2777 | dapm_new_mux(w); | 2743 | dapm_new_mux(w); |
2778 | break; | 2744 | break; |
2779 | case snd_soc_dapm_pga: | 2745 | case snd_soc_dapm_pga: |
@@ -2935,213 +2901,75 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, | |||
2935 | { | 2901 | { |
2936 | struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); | 2902 | struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); |
2937 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 2903 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
2938 | unsigned int val; | 2904 | unsigned int reg_val, val; |
2939 | |||
2940 | val = snd_soc_read(codec, e->reg); | ||
2941 | ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask; | ||
2942 | if (e->shift_l != e->shift_r) | ||
2943 | ucontrol->value.enumerated.item[1] = | ||
2944 | (val >> e->shift_r) & e->mask; | ||
2945 | |||
2946 | return 0; | ||
2947 | } | ||
2948 | EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double); | ||
2949 | |||
2950 | /** | ||
2951 | * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback | ||
2952 | * @kcontrol: mixer control | ||
2953 | * @ucontrol: control element information | ||
2954 | * | ||
2955 | * Callback to set the value of a dapm enumerated double mixer control. | ||
2956 | * | ||
2957 | * Returns 0 for success. | ||
2958 | */ | ||
2959 | int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, | ||
2960 | struct snd_ctl_elem_value *ucontrol) | ||
2961 | { | ||
2962 | struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); | ||
2963 | struct snd_soc_card *card = codec->card; | ||
2964 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
2965 | unsigned int val, mux, change; | ||
2966 | unsigned int mask; | ||
2967 | struct snd_soc_dapm_update update; | ||
2968 | int ret = 0; | ||
2969 | |||
2970 | if (ucontrol->value.enumerated.item[0] > e->max - 1) | ||
2971 | return -EINVAL; | ||
2972 | mux = ucontrol->value.enumerated.item[0]; | ||
2973 | val = mux << e->shift_l; | ||
2974 | mask = e->mask << e->shift_l; | ||
2975 | if (e->shift_l != e->shift_r) { | ||
2976 | if (ucontrol->value.enumerated.item[1] > e->max - 1) | ||
2977 | return -EINVAL; | ||
2978 | val |= ucontrol->value.enumerated.item[1] << e->shift_r; | ||
2979 | mask |= e->mask << e->shift_r; | ||
2980 | } | ||
2981 | |||
2982 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
2983 | |||
2984 | change = snd_soc_test_bits(codec, e->reg, mask, val); | ||
2985 | if (change) { | ||
2986 | update.kcontrol = kcontrol; | ||
2987 | update.reg = e->reg; | ||
2988 | update.mask = mask; | ||
2989 | update.val = val; | ||
2990 | card->update = &update; | ||
2991 | |||
2992 | ret = soc_dapm_mux_update_power(card, kcontrol, mux, e); | ||
2993 | |||
2994 | card->update = NULL; | ||
2995 | } | ||
2996 | |||
2997 | mutex_unlock(&card->dapm_mutex); | ||
2998 | 2905 | ||
2999 | if (ret > 0) | 2906 | if (e->reg != SND_SOC_NOPM) |
3000 | soc_dpcm_runtime_update(card); | 2907 | reg_val = snd_soc_read(codec, e->reg); |
3001 | 2908 | else | |
3002 | return change; | 2909 | reg_val = dapm_kcontrol_get_value(kcontrol); |
3003 | } | ||
3004 | EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); | ||
3005 | |||
3006 | /** | ||
3007 | * snd_soc_dapm_get_enum_virt - Get virtual DAPM mux | ||
3008 | * @kcontrol: mixer control | ||
3009 | * @ucontrol: control element information | ||
3010 | * | ||
3011 | * Returns 0 for success. | ||
3012 | */ | ||
3013 | int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol, | ||
3014 | struct snd_ctl_elem_value *ucontrol) | ||
3015 | { | ||
3016 | ucontrol->value.enumerated.item[0] = dapm_kcontrol_get_value(kcontrol); | ||
3017 | return 0; | ||
3018 | } | ||
3019 | EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt); | ||
3020 | |||
3021 | /** | ||
3022 | * snd_soc_dapm_put_enum_virt - Set virtual DAPM mux | ||
3023 | * @kcontrol: mixer control | ||
3024 | * @ucontrol: control element information | ||
3025 | * | ||
3026 | * Returns 0 for success. | ||
3027 | */ | ||
3028 | int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol, | ||
3029 | struct snd_ctl_elem_value *ucontrol) | ||
3030 | { | ||
3031 | struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); | ||
3032 | struct snd_soc_card *card = codec->card; | ||
3033 | unsigned int value; | ||
3034 | struct soc_enum *e = | ||
3035 | (struct soc_enum *)kcontrol->private_value; | ||
3036 | int change; | ||
3037 | int ret = 0; | ||
3038 | |||
3039 | if (ucontrol->value.enumerated.item[0] >= e->max) | ||
3040 | return -EINVAL; | ||
3041 | |||
3042 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
3043 | |||
3044 | value = ucontrol->value.enumerated.item[0]; | ||
3045 | change = dapm_kcontrol_set_value(kcontrol, value); | ||
3046 | if (change) | ||
3047 | ret = soc_dapm_mux_update_power(card, kcontrol, value, e); | ||
3048 | |||
3049 | mutex_unlock(&card->dapm_mutex); | ||
3050 | |||
3051 | if (ret > 0) | ||
3052 | soc_dpcm_runtime_update(card); | ||
3053 | |||
3054 | return change; | ||
3055 | } | ||
3056 | EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt); | ||
3057 | |||
3058 | /** | ||
3059 | * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get | ||
3060 | * callback | ||
3061 | * @kcontrol: mixer control | ||
3062 | * @ucontrol: control element information | ||
3063 | * | ||
3064 | * Callback to get the value of a dapm semi enumerated double mixer control. | ||
3065 | * | ||
3066 | * Semi enumerated mixer: the enumerated items are referred as values. Can be | ||
3067 | * used for handling bitfield coded enumeration for example. | ||
3068 | * | ||
3069 | * Returns 0 for success. | ||
3070 | */ | ||
3071 | int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol, | ||
3072 | struct snd_ctl_elem_value *ucontrol) | ||
3073 | { | ||
3074 | struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); | ||
3075 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
3076 | unsigned int reg_val, val, mux; | ||
3077 | 2910 | ||
3078 | reg_val = snd_soc_read(codec, e->reg); | ||
3079 | val = (reg_val >> e->shift_l) & e->mask; | 2911 | val = (reg_val >> e->shift_l) & e->mask; |
3080 | for (mux = 0; mux < e->max; mux++) { | 2912 | ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val); |
3081 | if (val == e->values[mux]) | ||
3082 | break; | ||
3083 | } | ||
3084 | ucontrol->value.enumerated.item[0] = mux; | ||
3085 | if (e->shift_l != e->shift_r) { | 2913 | if (e->shift_l != e->shift_r) { |
3086 | val = (reg_val >> e->shift_r) & e->mask; | 2914 | val = (reg_val >> e->shift_r) & e->mask; |
3087 | for (mux = 0; mux < e->max; mux++) { | 2915 | val = snd_soc_enum_val_to_item(e, val); |
3088 | if (val == e->values[mux]) | 2916 | ucontrol->value.enumerated.item[1] = val; |
3089 | break; | ||
3090 | } | ||
3091 | ucontrol->value.enumerated.item[1] = mux; | ||
3092 | } | 2917 | } |
3093 | 2918 | ||
3094 | return 0; | 2919 | return 0; |
3095 | } | 2920 | } |
3096 | EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double); | 2921 | EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double); |
3097 | 2922 | ||
3098 | /** | 2923 | /** |
3099 | * snd_soc_dapm_put_value_enum_double - dapm semi enumerated double mixer set | 2924 | * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback |
3100 | * callback | ||
3101 | * @kcontrol: mixer control | 2925 | * @kcontrol: mixer control |
3102 | * @ucontrol: control element information | 2926 | * @ucontrol: control element information |
3103 | * | 2927 | * |
3104 | * Callback to set the value of a dapm semi enumerated double mixer control. | 2928 | * Callback to set the value of a dapm enumerated double mixer control. |
3105 | * | ||
3106 | * Semi enumerated mixer: the enumerated items are referred as values. Can be | ||
3107 | * used for handling bitfield coded enumeration for example. | ||
3108 | * | 2929 | * |
3109 | * Returns 0 for success. | 2930 | * Returns 0 for success. |
3110 | */ | 2931 | */ |
3111 | int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, | 2932 | int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, |
3112 | struct snd_ctl_elem_value *ucontrol) | 2933 | struct snd_ctl_elem_value *ucontrol) |
3113 | { | 2934 | { |
3114 | struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); | 2935 | struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); |
3115 | struct snd_soc_card *card = codec->card; | 2936 | struct snd_soc_card *card = codec->card; |
3116 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 2937 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
3117 | unsigned int val, mux, change; | 2938 | unsigned int *item = ucontrol->value.enumerated.item; |
2939 | unsigned int val, change; | ||
3118 | unsigned int mask; | 2940 | unsigned int mask; |
3119 | struct snd_soc_dapm_update update; | 2941 | struct snd_soc_dapm_update update; |
3120 | int ret = 0; | 2942 | int ret = 0; |
3121 | 2943 | ||
3122 | if (ucontrol->value.enumerated.item[0] > e->max - 1) | 2944 | if (item[0] >= e->items) |
3123 | return -EINVAL; | 2945 | return -EINVAL; |
3124 | mux = ucontrol->value.enumerated.item[0]; | 2946 | |
3125 | val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l; | 2947 | val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; |
3126 | mask = e->mask << e->shift_l; | 2948 | mask = e->mask << e->shift_l; |
3127 | if (e->shift_l != e->shift_r) { | 2949 | if (e->shift_l != e->shift_r) { |
3128 | if (ucontrol->value.enumerated.item[1] > e->max - 1) | 2950 | if (item[1] > e->items) |
3129 | return -EINVAL; | 2951 | return -EINVAL; |
3130 | val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r; | 2952 | val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l; |
3131 | mask |= e->mask << e->shift_r; | 2953 | mask |= e->mask << e->shift_r; |
3132 | } | 2954 | } |
3133 | 2955 | ||
3134 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | 2956 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); |
3135 | 2957 | ||
3136 | change = snd_soc_test_bits(codec, e->reg, mask, val); | 2958 | if (e->reg != SND_SOC_NOPM) |
2959 | change = snd_soc_test_bits(codec, e->reg, mask, val); | ||
2960 | else | ||
2961 | change = dapm_kcontrol_set_value(kcontrol, val); | ||
2962 | |||
3137 | if (change) { | 2963 | if (change) { |
3138 | update.kcontrol = kcontrol; | 2964 | if (e->reg != SND_SOC_NOPM) { |
3139 | update.reg = e->reg; | 2965 | update.kcontrol = kcontrol; |
3140 | update.mask = mask; | 2966 | update.reg = e->reg; |
3141 | update.val = val; | 2967 | update.mask = mask; |
3142 | card->update = &update; | 2968 | update.val = val; |
2969 | card->update = &update; | ||
2970 | } | ||
3143 | 2971 | ||
3144 | ret = soc_dapm_mux_update_power(card, kcontrol, mux, e); | 2972 | ret = soc_dapm_mux_update_power(card, kcontrol, item[0], e); |
3145 | 2973 | ||
3146 | card->update = NULL; | 2974 | card->update = NULL; |
3147 | } | 2975 | } |
@@ -3153,7 +2981,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, | |||
3153 | 2981 | ||
3154 | return change; | 2982 | return change; |
3155 | } | 2983 | } |
3156 | EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); | 2984 | EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); |
3157 | 2985 | ||
3158 | /** | 2986 | /** |
3159 | * snd_soc_dapm_info_pin_switch - Info for a pin switch | 2987 | * snd_soc_dapm_info_pin_switch - Info for a pin switch |
@@ -3210,15 +3038,11 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, | |||
3210 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); | 3038 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
3211 | const char *pin = (const char *)kcontrol->private_value; | 3039 | const char *pin = (const char *)kcontrol->private_value; |
3212 | 3040 | ||
3213 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
3214 | |||
3215 | if (ucontrol->value.integer.value[0]) | 3041 | if (ucontrol->value.integer.value[0]) |
3216 | snd_soc_dapm_enable_pin(&card->dapm, pin); | 3042 | snd_soc_dapm_enable_pin(&card->dapm, pin); |
3217 | else | 3043 | else |
3218 | snd_soc_dapm_disable_pin(&card->dapm, pin); | 3044 | snd_soc_dapm_disable_pin(&card->dapm, pin); |
3219 | 3045 | ||
3220 | mutex_unlock(&card->dapm_mutex); | ||
3221 | |||
3222 | snd_soc_dapm_sync(&card->dapm); | 3046 | snd_soc_dapm_sync(&card->dapm); |
3223 | return 0; | 3047 | return 0; |
3224 | } | 3048 | } |
@@ -3248,7 +3072,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
3248 | ret = regulator_allow_bypass(w->regulator, true); | 3072 | ret = regulator_allow_bypass(w->regulator, true); |
3249 | if (ret != 0) | 3073 | if (ret != 0) |
3250 | dev_warn(w->dapm->dev, | 3074 | dev_warn(w->dapm->dev, |
3251 | "ASoC: Failed to unbypass %s: %d\n", | 3075 | "ASoC: Failed to bypass %s: %d\n", |
3252 | w->name, ret); | 3076 | w->name, ret); |
3253 | } | 3077 | } |
3254 | break; | 3078 | break; |
@@ -3287,8 +3111,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
3287 | w->power_check = dapm_generic_check_power; | 3111 | w->power_check = dapm_generic_check_power; |
3288 | break; | 3112 | break; |
3289 | case snd_soc_dapm_mux: | 3113 | case snd_soc_dapm_mux: |
3290 | case snd_soc_dapm_virt_mux: | ||
3291 | case snd_soc_dapm_value_mux: | ||
3292 | w->power_check = dapm_generic_check_power; | 3114 | w->power_check = dapm_generic_check_power; |
3293 | break; | 3115 | break; |
3294 | case snd_soc_dapm_dai_out: | 3116 | case snd_soc_dapm_dai_out: |
@@ -3767,23 +3589,52 @@ void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, | |||
3767 | } | 3589 | } |
3768 | 3590 | ||
3769 | /** | 3591 | /** |
3592 | * snd_soc_dapm_enable_pin_unlocked - enable pin. | ||
3593 | * @dapm: DAPM context | ||
3594 | * @pin: pin name | ||
3595 | * | ||
3596 | * Enables input/output pin and its parents or children widgets iff there is | ||
3597 | * a valid audio route and active audio stream. | ||
3598 | * | ||
3599 | * Requires external locking. | ||
3600 | * | ||
3601 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | ||
3602 | * do any widget power switching. | ||
3603 | */ | ||
3604 | int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
3605 | const char *pin) | ||
3606 | { | ||
3607 | return snd_soc_dapm_set_pin(dapm, pin, 1); | ||
3608 | } | ||
3609 | EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin_unlocked); | ||
3610 | |||
3611 | /** | ||
3770 | * snd_soc_dapm_enable_pin - enable pin. | 3612 | * snd_soc_dapm_enable_pin - enable pin. |
3771 | * @dapm: DAPM context | 3613 | * @dapm: DAPM context |
3772 | * @pin: pin name | 3614 | * @pin: pin name |
3773 | * | 3615 | * |
3774 | * Enables input/output pin and its parents or children widgets iff there is | 3616 | * Enables input/output pin and its parents or children widgets iff there is |
3775 | * a valid audio route and active audio stream. | 3617 | * a valid audio route and active audio stream. |
3618 | * | ||
3776 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | 3619 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to |
3777 | * do any widget power switching. | 3620 | * do any widget power switching. |
3778 | */ | 3621 | */ |
3779 | int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) | 3622 | int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) |
3780 | { | 3623 | { |
3781 | return snd_soc_dapm_set_pin(dapm, pin, 1); | 3624 | int ret; |
3625 | |||
3626 | mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
3627 | |||
3628 | ret = snd_soc_dapm_set_pin(dapm, pin, 1); | ||
3629 | |||
3630 | mutex_unlock(&dapm->card->dapm_mutex); | ||
3631 | |||
3632 | return ret; | ||
3782 | } | 3633 | } |
3783 | EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); | 3634 | EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); |
3784 | 3635 | ||
3785 | /** | 3636 | /** |
3786 | * snd_soc_dapm_force_enable_pin - force a pin to be enabled | 3637 | * snd_soc_dapm_force_enable_pin_unlocked - force a pin to be enabled |
3787 | * @dapm: DAPM context | 3638 | * @dapm: DAPM context |
3788 | * @pin: pin name | 3639 | * @pin: pin name |
3789 | * | 3640 | * |
@@ -3791,11 +3642,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); | |||
3791 | * intended for use with microphone bias supplies used in microphone | 3642 | * intended for use with microphone bias supplies used in microphone |
3792 | * jack detection. | 3643 | * jack detection. |
3793 | * | 3644 | * |
3645 | * Requires external locking. | ||
3646 | * | ||
3794 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | 3647 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to |
3795 | * do any widget power switching. | 3648 | * do any widget power switching. |
3796 | */ | 3649 | */ |
3797 | int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | 3650 | int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, |
3798 | const char *pin) | 3651 | const char *pin) |
3799 | { | 3652 | { |
3800 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); | 3653 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); |
3801 | 3654 | ||
@@ -3811,25 +3664,103 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | |||
3811 | 3664 | ||
3812 | return 0; | 3665 | return 0; |
3813 | } | 3666 | } |
3667 | EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin_unlocked); | ||
3668 | |||
3669 | /** | ||
3670 | * snd_soc_dapm_force_enable_pin - force a pin to be enabled | ||
3671 | * @dapm: DAPM context | ||
3672 | * @pin: pin name | ||
3673 | * | ||
3674 | * Enables input/output pin regardless of any other state. This is | ||
3675 | * intended for use with microphone bias supplies used in microphone | ||
3676 | * jack detection. | ||
3677 | * | ||
3678 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | ||
3679 | * do any widget power switching. | ||
3680 | */ | ||
3681 | int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | ||
3682 | const char *pin) | ||
3683 | { | ||
3684 | int ret; | ||
3685 | |||
3686 | mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
3687 | |||
3688 | ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, pin); | ||
3689 | |||
3690 | mutex_unlock(&dapm->card->dapm_mutex); | ||
3691 | |||
3692 | return ret; | ||
3693 | } | ||
3814 | EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); | 3694 | EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); |
3815 | 3695 | ||
3816 | /** | 3696 | /** |
3697 | * snd_soc_dapm_disable_pin_unlocked - disable pin. | ||
3698 | * @dapm: DAPM context | ||
3699 | * @pin: pin name | ||
3700 | * | ||
3701 | * Disables input/output pin and its parents or children widgets. | ||
3702 | * | ||
3703 | * Requires external locking. | ||
3704 | * | ||
3705 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | ||
3706 | * do any widget power switching. | ||
3707 | */ | ||
3708 | int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
3709 | const char *pin) | ||
3710 | { | ||
3711 | return snd_soc_dapm_set_pin(dapm, pin, 0); | ||
3712 | } | ||
3713 | EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin_unlocked); | ||
3714 | |||
3715 | /** | ||
3817 | * snd_soc_dapm_disable_pin - disable pin. | 3716 | * snd_soc_dapm_disable_pin - disable pin. |
3818 | * @dapm: DAPM context | 3717 | * @dapm: DAPM context |
3819 | * @pin: pin name | 3718 | * @pin: pin name |
3820 | * | 3719 | * |
3821 | * Disables input/output pin and its parents or children widgets. | 3720 | * Disables input/output pin and its parents or children widgets. |
3721 | * | ||
3822 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | 3722 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to |
3823 | * do any widget power switching. | 3723 | * do any widget power switching. |
3824 | */ | 3724 | */ |
3825 | int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, | 3725 | int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, |
3826 | const char *pin) | 3726 | const char *pin) |
3827 | { | 3727 | { |
3828 | return snd_soc_dapm_set_pin(dapm, pin, 0); | 3728 | int ret; |
3729 | |||
3730 | mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
3731 | |||
3732 | ret = snd_soc_dapm_set_pin(dapm, pin, 0); | ||
3733 | |||
3734 | mutex_unlock(&dapm->card->dapm_mutex); | ||
3735 | |||
3736 | return ret; | ||
3829 | } | 3737 | } |
3830 | EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); | 3738 | EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); |
3831 | 3739 | ||
3832 | /** | 3740 | /** |
3741 | * snd_soc_dapm_nc_pin_unlocked - permanently disable pin. | ||
3742 | * @dapm: DAPM context | ||
3743 | * @pin: pin name | ||
3744 | * | ||
3745 | * Marks the specified pin as being not connected, disabling it along | ||
3746 | * any parent or child widgets. At present this is identical to | ||
3747 | * snd_soc_dapm_disable_pin() but in future it will be extended to do | ||
3748 | * additional things such as disabling controls which only affect | ||
3749 | * paths through the pin. | ||
3750 | * | ||
3751 | * Requires external locking. | ||
3752 | * | ||
3753 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | ||
3754 | * do any widget power switching. | ||
3755 | */ | ||
3756 | int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
3757 | const char *pin) | ||
3758 | { | ||
3759 | return snd_soc_dapm_set_pin(dapm, pin, 0); | ||
3760 | } | ||
3761 | EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin_unlocked); | ||
3762 | |||
3763 | /** | ||
3833 | * snd_soc_dapm_nc_pin - permanently disable pin. | 3764 | * snd_soc_dapm_nc_pin - permanently disable pin. |
3834 | * @dapm: DAPM context | 3765 | * @dapm: DAPM context |
3835 | * @pin: pin name | 3766 | * @pin: pin name |
@@ -3845,7 +3776,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); | |||
3845 | */ | 3776 | */ |
3846 | int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) | 3777 | int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) |
3847 | { | 3778 | { |
3848 | return snd_soc_dapm_set_pin(dapm, pin, 0); | 3779 | int ret; |
3780 | |||
3781 | mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
3782 | |||
3783 | ret = snd_soc_dapm_set_pin(dapm, pin, 0); | ||
3784 | |||
3785 | mutex_unlock(&dapm->card->dapm_mutex); | ||
3786 | |||
3787 | return ret; | ||
3849 | } | 3788 | } |
3850 | EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); | 3789 | EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); |
3851 | 3790 | ||
@@ -3985,7 +3924,7 @@ void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm) | |||
3985 | } | 3924 | } |
3986 | EXPORT_SYMBOL_GPL(snd_soc_dapm_free); | 3925 | EXPORT_SYMBOL_GPL(snd_soc_dapm_free); |
3987 | 3926 | ||
3988 | static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) | 3927 | static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm) |
3989 | { | 3928 | { |
3990 | struct snd_soc_card *card = dapm->card; | 3929 | struct snd_soc_card *card = dapm->card; |
3991 | struct snd_soc_dapm_widget *w; | 3930 | struct snd_soc_dapm_widget *w; |
@@ -4025,14 +3964,21 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) | |||
4025 | */ | 3964 | */ |
4026 | void snd_soc_dapm_shutdown(struct snd_soc_card *card) | 3965 | void snd_soc_dapm_shutdown(struct snd_soc_card *card) |
4027 | { | 3966 | { |
4028 | struct snd_soc_codec *codec; | 3967 | struct snd_soc_dapm_context *dapm; |
4029 | 3968 | ||
4030 | list_for_each_entry(codec, &card->codec_dev_list, card_list) { | 3969 | list_for_each_entry(dapm, &card->dapm_list, list) { |
4031 | soc_dapm_shutdown_codec(&codec->dapm); | 3970 | if (dapm != &card->dapm) { |
4032 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) | 3971 | soc_dapm_shutdown_dapm(dapm); |
4033 | snd_soc_dapm_set_bias_level(&codec->dapm, | 3972 | if (dapm->bias_level == SND_SOC_BIAS_STANDBY) |
4034 | SND_SOC_BIAS_OFF); | 3973 | snd_soc_dapm_set_bias_level(dapm, |
3974 | SND_SOC_BIAS_OFF); | ||
3975 | } | ||
4035 | } | 3976 | } |
3977 | |||
3978 | soc_dapm_shutdown_dapm(&card->dapm); | ||
3979 | if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY) | ||
3980 | snd_soc_dapm_set_bias_level(&card->dapm, | ||
3981 | SND_SOC_BIAS_OFF); | ||
4036 | } | 3982 | } |
4037 | 3983 | ||
4038 | /* Module information */ | 3984 | /* Module information */ |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 47e1ce771e65..330eaf007d89 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -35,6 +35,86 @@ | |||
35 | #define DPCM_MAX_BE_USERS 8 | 35 | #define DPCM_MAX_BE_USERS 8 |
36 | 36 | ||
37 | /** | 37 | /** |
38 | * snd_soc_runtime_activate() - Increment active count for PCM runtime components | ||
39 | * @rtd: ASoC PCM runtime that is activated | ||
40 | * @stream: Direction of the PCM stream | ||
41 | * | ||
42 | * Increments the active count for all the DAIs and components attached to a PCM | ||
43 | * runtime. Should typically be called when a stream is opened. | ||
44 | * | ||
45 | * Must be called with the rtd->pcm_mutex being held | ||
46 | */ | ||
47 | void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream) | ||
48 | { | ||
49 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
50 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
51 | |||
52 | lockdep_assert_held(&rtd->pcm_mutex); | ||
53 | |||
54 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
55 | cpu_dai->playback_active++; | ||
56 | codec_dai->playback_active++; | ||
57 | } else { | ||
58 | cpu_dai->capture_active++; | ||
59 | codec_dai->capture_active++; | ||
60 | } | ||
61 | |||
62 | cpu_dai->active++; | ||
63 | codec_dai->active++; | ||
64 | cpu_dai->component->active++; | ||
65 | codec_dai->component->active++; | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | * snd_soc_runtime_deactivate() - Decrement active count for PCM runtime components | ||
70 | * @rtd: ASoC PCM runtime that is deactivated | ||
71 | * @stream: Direction of the PCM stream | ||
72 | * | ||
73 | * Decrements the active count for all the DAIs and components attached to a PCM | ||
74 | * runtime. Should typically be called when a stream is closed. | ||
75 | * | ||
76 | * Must be called with the rtd->pcm_mutex being held | ||
77 | */ | ||
78 | void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream) | ||
79 | { | ||
80 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
81 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
82 | |||
83 | lockdep_assert_held(&rtd->pcm_mutex); | ||
84 | |||
85 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
86 | cpu_dai->playback_active--; | ||
87 | codec_dai->playback_active--; | ||
88 | } else { | ||
89 | cpu_dai->capture_active--; | ||
90 | codec_dai->capture_active--; | ||
91 | } | ||
92 | |||
93 | cpu_dai->active--; | ||
94 | codec_dai->active--; | ||
95 | cpu_dai->component->active--; | ||
96 | codec_dai->component->active--; | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * snd_soc_runtime_ignore_pmdown_time() - Check whether to ignore the power down delay | ||
101 | * @rtd: The ASoC PCM runtime that should be checked. | ||
102 | * | ||
103 | * This function checks whether the power down delay should be ignored for a | ||
104 | * specific PCM runtime. Returns true if the delay is 0, if it the DAI link has | ||
105 | * been configured to ignore the delay, or if none of the components benefits | ||
106 | * from having the delay. | ||
107 | */ | ||
108 | bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd) | ||
109 | { | ||
110 | if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time) | ||
111 | return true; | ||
112 | |||
113 | return rtd->cpu_dai->component->ignore_pmdown_time && | ||
114 | rtd->codec_dai->component->ignore_pmdown_time; | ||
115 | } | ||
116 | |||
117 | /** | ||
38 | * snd_soc_set_runtime_hwparams - set the runtime hardware parameters | 118 | * snd_soc_set_runtime_hwparams - set the runtime hardware parameters |
39 | * @substream: the pcm substream | 119 | * @substream: the pcm substream |
40 | * @hw: the hardware parameters | 120 | * @hw: the hardware parameters |
@@ -378,16 +458,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
378 | runtime->hw.rate_max); | 458 | runtime->hw.rate_max); |
379 | 459 | ||
380 | dynamic: | 460 | dynamic: |
381 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 461 | |
382 | cpu_dai->playback_active++; | 462 | snd_soc_runtime_activate(rtd, substream->stream); |
383 | codec_dai->playback_active++; | 463 | |
384 | } else { | ||
385 | cpu_dai->capture_active++; | ||
386 | codec_dai->capture_active++; | ||
387 | } | ||
388 | cpu_dai->active++; | ||
389 | codec_dai->active++; | ||
390 | rtd->codec->active++; | ||
391 | mutex_unlock(&rtd->pcm_mutex); | 464 | mutex_unlock(&rtd->pcm_mutex); |
392 | return 0; | 465 | return 0; |
393 | 466 | ||
@@ -459,21 +532,10 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) | |||
459 | struct snd_soc_platform *platform = rtd->platform; | 532 | struct snd_soc_platform *platform = rtd->platform; |
460 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 533 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
461 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 534 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
462 | struct snd_soc_codec *codec = rtd->codec; | ||
463 | 535 | ||
464 | mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); | 536 | mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); |
465 | 537 | ||
466 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 538 | snd_soc_runtime_deactivate(rtd, substream->stream); |
467 | cpu_dai->playback_active--; | ||
468 | codec_dai->playback_active--; | ||
469 | } else { | ||
470 | cpu_dai->capture_active--; | ||
471 | codec_dai->capture_active--; | ||
472 | } | ||
473 | |||
474 | cpu_dai->active--; | ||
475 | codec_dai->active--; | ||
476 | codec->active--; | ||
477 | 539 | ||
478 | /* clear the corresponding DAIs rate when inactive */ | 540 | /* clear the corresponding DAIs rate when inactive */ |
479 | if (!cpu_dai->active) | 541 | if (!cpu_dai->active) |
@@ -496,8 +558,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) | |||
496 | cpu_dai->runtime = NULL; | 558 | cpu_dai->runtime = NULL; |
497 | 559 | ||
498 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 560 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
499 | if (!rtd->pmdown_time || codec->ignore_pmdown_time || | 561 | if (snd_soc_runtime_ignore_pmdown_time(rtd)) { |
500 | rtd->dai_link->ignore_pmdown_time) { | ||
501 | /* powered down playback stream now */ | 562 | /* powered down playback stream now */ |
502 | snd_soc_dapm_stream_event(rtd, | 563 | snd_soc_dapm_stream_event(rtd, |
503 | SNDRV_PCM_STREAM_PLAYBACK, | 564 | SNDRV_PCM_STREAM_PLAYBACK, |
@@ -1989,6 +2050,7 @@ int soc_dpcm_runtime_update(struct snd_soc_card *card) | |||
1989 | 2050 | ||
1990 | paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); | 2051 | paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); |
1991 | if (paths < 0) { | 2052 | if (paths < 0) { |
2053 | dpcm_path_put(&list); | ||
1992 | dev_warn(fe->dev, "ASoC: %s no valid %s path\n", | 2054 | dev_warn(fe->dev, "ASoC: %s no valid %s path\n", |
1993 | fe->dai_link->name, "playback"); | 2055 | fe->dai_link->name, "playback"); |
1994 | mutex_unlock(&card->mutex); | 2056 | mutex_unlock(&card->mutex); |
@@ -2018,6 +2080,7 @@ capture: | |||
2018 | 2080 | ||
2019 | paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); | 2081 | paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); |
2020 | if (paths < 0) { | 2082 | if (paths < 0) { |
2083 | dpcm_path_put(&list); | ||
2021 | dev_warn(fe->dev, "ASoC: %s no valid %s path\n", | 2084 | dev_warn(fe->dev, "ASoC: %s no valid %s path\n", |
2022 | fe->dai_link->name, "capture"); | 2085 | fe->dai_link->name, "capture"); |
2023 | mutex_unlock(&card->mutex); | 2086 | mutex_unlock(&card->mutex); |
@@ -2082,6 +2145,7 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) | |||
2082 | fe->dpcm[stream].runtime = fe_substream->runtime; | 2145 | fe->dpcm[stream].runtime = fe_substream->runtime; |
2083 | 2146 | ||
2084 | if (dpcm_path_get(fe, stream, &list) <= 0) { | 2147 | if (dpcm_path_get(fe, stream, &list) <= 0) { |
2148 | dpcm_path_put(&list); | ||
2085 | dev_dbg(fe->dev, "ASoC: %s no valid %s route\n", | 2149 | dev_dbg(fe->dev, "ASoC: %s no valid %s route\n", |
2086 | fe->dai_link->name, stream ? "capture" : "playback"); | 2150 | fe->dai_link->name, stream ? "capture" : "playback"); |
2087 | } | 2151 | } |
diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c index fe99f461aff0..19cca043e6e4 100644 --- a/sound/soc/spear/spdif_out.c +++ b/sound/soc/spear/spdif_out.c | |||
@@ -213,10 +213,7 @@ static int spdif_digital_mute(struct snd_soc_dai *dai, int mute) | |||
213 | static int spdif_mute_get(struct snd_kcontrol *kcontrol, | 213 | static int spdif_mute_get(struct snd_kcontrol *kcontrol, |
214 | struct snd_ctl_elem_value *ucontrol) | 214 | struct snd_ctl_elem_value *ucontrol) |
215 | { | 215 | { |
216 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 216 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); |
217 | struct snd_soc_card *card = codec->card; | ||
218 | struct snd_soc_pcm_runtime *rtd = card->rtd; | ||
219 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
220 | struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai); | 217 | struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai); |
221 | 218 | ||
222 | ucontrol->value.integer.value[0] = host->saved_params.mute; | 219 | ucontrol->value.integer.value[0] = host->saved_params.mute; |
@@ -226,10 +223,7 @@ static int spdif_mute_get(struct snd_kcontrol *kcontrol, | |||
226 | static int spdif_mute_put(struct snd_kcontrol *kcontrol, | 223 | static int spdif_mute_put(struct snd_kcontrol *kcontrol, |
227 | struct snd_ctl_elem_value *ucontrol) | 224 | struct snd_ctl_elem_value *ucontrol) |
228 | { | 225 | { |
229 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 226 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); |
230 | struct snd_soc_card *card = codec->card; | ||
231 | struct snd_soc_pcm_runtime *rtd = card->rtd; | ||
232 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
233 | struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai); | 227 | struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai); |
234 | 228 | ||
235 | if (host->saved_params.mute == ucontrol->value.integer.value[0]) | 229 | if (host->saved_params.mute == ucontrol->value.integer.value[0]) |
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index e0305a148568..9edd68db9f48 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c | |||
@@ -183,14 +183,16 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev) | |||
183 | irq = platform_get_irq(pdev, 0); | 183 | irq = platform_get_irq(pdev, 0); |
184 | if (irq < 0) | 184 | if (irq < 0) |
185 | return irq; | 185 | return irq; |
186 | |||
187 | drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); | ||
188 | if (!drvdata) | ||
189 | return -ENOMEM; | ||
190 | |||
186 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 191 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
187 | drvdata->base = devm_ioremap_resource(&pdev->dev, r); | 192 | drvdata->base = devm_ioremap_resource(&pdev->dev, r); |
188 | if (IS_ERR(drvdata->base)) | 193 | if (IS_ERR(drvdata->base)) |
189 | return PTR_ERR(drvdata->base); | 194 | return PTR_ERR(drvdata->base); |
190 | 195 | ||
191 | drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); | ||
192 | if (!drvdata) | ||
193 | return -ENOMEM; | ||
194 | platform_set_drvdata(pdev, drvdata); | 196 | platform_set_drvdata(pdev, drvdata); |
195 | drvdata->physbase = r->start; | 197 | drvdata->physbase = r->start; |
196 | if (sizeof(drvdata->physbase) > sizeof(r->start) && | 198 | if (sizeof(drvdata->physbase) > sizeof(r->start) && |
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index de9408b83f75..e05a86b7c0da 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
@@ -14,6 +14,7 @@ config SND_USB_AUDIO | |||
14 | select SND_HWDEP | 14 | select SND_HWDEP |
15 | select SND_RAWMIDI | 15 | select SND_RAWMIDI |
16 | select SND_PCM | 16 | select SND_PCM |
17 | select BITREVERSE | ||
17 | help | 18 | help |
18 | Say Y here to include support for USB audio and USB MIDI | 19 | Say Y here to include support for USB audio and USB MIDI |
19 | devices. | 20 | devices. |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 44b0ba4feab3..1bed780e21d9 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -883,6 +883,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, | |||
883 | } | 883 | } |
884 | break; | 884 | break; |
885 | 885 | ||
886 | case USB_ID(0x046d, 0x0807): /* Logitech Webcam C500 */ | ||
886 | case USB_ID(0x046d, 0x0808): | 887 | case USB_ID(0x046d, 0x0808): |
887 | case USB_ID(0x046d, 0x0809): | 888 | case USB_ID(0x046d, 0x0809): |
888 | case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ | 889 | case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ |
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index 32af6b741ef5..d1d72ff50347 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c | |||
@@ -328,6 +328,11 @@ static struct usbmix_name_map gamecom780_map[] = { | |||
328 | {} | 328 | {} |
329 | }; | 329 | }; |
330 | 330 | ||
331 | static const struct usbmix_name_map kef_x300a_map[] = { | ||
332 | { 10, NULL }, /* firmware locks up (?) when we try to access this FU */ | ||
333 | { 0 } | ||
334 | }; | ||
335 | |||
331 | /* | 336 | /* |
332 | * Control map entries | 337 | * Control map entries |
333 | */ | 338 | */ |
@@ -419,6 +424,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { | |||
419 | .id = USB_ID(0x200c, 0x1018), | 424 | .id = USB_ID(0x200c, 0x1018), |
420 | .map = ebox44_map, | 425 | .map = ebox44_map, |
421 | }, | 426 | }, |
427 | { | ||
428 | .id = USB_ID(0x27ac, 0x1000), | ||
429 | .map = kef_x300a_map, | ||
430 | }, | ||
422 | { 0 } /* terminator */ | 431 | { 0 } /* terminator */ |
423 | }; | 432 | }; |
424 | 433 | ||