diff options
Diffstat (limited to 'sound')
121 files changed, 5591 insertions, 1823 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 70d4848b5cd0..d010de12335e 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -95,6 +95,7 @@ int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset) | |||
95 | EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset); | 95 | EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset); |
96 | 96 | ||
97 | #ifdef CONFIG_PM | 97 | #ifdef CONFIG_PM |
98 | #define codec_in_pm(codec) ((codec)->in_pm) | ||
98 | static void hda_power_work(struct work_struct *work); | 99 | static void hda_power_work(struct work_struct *work); |
99 | static void hda_keep_power_on(struct hda_codec *codec); | 100 | static void hda_keep_power_on(struct hda_codec *codec); |
100 | #define hda_codec_is_power_on(codec) ((codec)->power_on) | 101 | #define hda_codec_is_power_on(codec) ((codec)->power_on) |
@@ -104,6 +105,7 @@ static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up) | |||
104 | bus->ops.pm_notify(bus, power_up); | 105 | bus->ops.pm_notify(bus, power_up); |
105 | } | 106 | } |
106 | #else | 107 | #else |
108 | #define codec_in_pm(codec) 0 | ||
107 | static inline void hda_keep_power_on(struct hda_codec *codec) {} | 109 | static inline void hda_keep_power_on(struct hda_codec *codec) {} |
108 | #define hda_codec_is_power_on(codec) 1 | 110 | #define hda_codec_is_power_on(codec) 1 |
109 | #define hda_call_pm_notify(bus, state) {} | 111 | #define hda_call_pm_notify(bus, state) {} |
@@ -228,7 +230,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, | |||
228 | } | 230 | } |
229 | mutex_unlock(&bus->cmd_mutex); | 231 | mutex_unlock(&bus->cmd_mutex); |
230 | snd_hda_power_down(codec); | 232 | snd_hda_power_down(codec); |
231 | if (res && *res == -1 && bus->rirb_error) { | 233 | if (!codec_in_pm(codec) && res && *res == -1 && bus->rirb_error) { |
232 | if (bus->response_reset) { | 234 | if (bus->response_reset) { |
233 | snd_printd("hda_codec: resetting BUS due to " | 235 | snd_printd("hda_codec: resetting BUS due to " |
234 | "fatal communication error\n"); | 236 | "fatal communication error\n"); |
@@ -238,7 +240,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, | |||
238 | goto again; | 240 | goto again; |
239 | } | 241 | } |
240 | /* clear reset-flag when the communication gets recovered */ | 242 | /* clear reset-flag when the communication gets recovered */ |
241 | if (!err) | 243 | if (!err || codec_in_pm(codec)) |
242 | bus->response_reset = 0; | 244 | bus->response_reset = 0; |
243 | return err; | 245 | return err; |
244 | } | 246 | } |
@@ -3616,6 +3618,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) | |||
3616 | { | 3618 | { |
3617 | unsigned int state; | 3619 | unsigned int state; |
3618 | 3620 | ||
3621 | codec->in_pm = 1; | ||
3622 | |||
3619 | if (codec->patch_ops.suspend) | 3623 | if (codec->patch_ops.suspend) |
3620 | codec->patch_ops.suspend(codec); | 3624 | codec->patch_ops.suspend(codec); |
3621 | hda_cleanup_all_streams(codec); | 3625 | hda_cleanup_all_streams(codec); |
@@ -3630,6 +3634,7 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) | |||
3630 | codec->power_transition = 0; | 3634 | codec->power_transition = 0; |
3631 | codec->power_jiffies = jiffies; | 3635 | codec->power_jiffies = jiffies; |
3632 | spin_unlock(&codec->power_lock); | 3636 | spin_unlock(&codec->power_lock); |
3637 | codec->in_pm = 0; | ||
3633 | return state; | 3638 | return state; |
3634 | } | 3639 | } |
3635 | 3640 | ||
@@ -3638,6 +3643,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) | |||
3638 | */ | 3643 | */ |
3639 | static void hda_call_codec_resume(struct hda_codec *codec) | 3644 | static void hda_call_codec_resume(struct hda_codec *codec) |
3640 | { | 3645 | { |
3646 | codec->in_pm = 1; | ||
3647 | |||
3641 | /* set as if powered on for avoiding re-entering the resume | 3648 | /* set as if powered on for avoiding re-entering the resume |
3642 | * in the resume / power-save sequence | 3649 | * in the resume / power-save sequence |
3643 | */ | 3650 | */ |
@@ -3656,6 +3663,8 @@ static void hda_call_codec_resume(struct hda_codec *codec) | |||
3656 | snd_hda_codec_resume_cache(codec); | 3663 | snd_hda_codec_resume_cache(codec); |
3657 | } | 3664 | } |
3658 | snd_hda_jack_report_sync(codec); | 3665 | snd_hda_jack_report_sync(codec); |
3666 | |||
3667 | codec->in_pm = 0; | ||
3659 | snd_hda_power_down(codec); /* flag down before returning */ | 3668 | snd_hda_power_down(codec); /* flag down before returning */ |
3660 | } | 3669 | } |
3661 | #endif /* CONFIG_PM */ | 3670 | #endif /* CONFIG_PM */ |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 507fe8a917b6..4f4e545c0f4b 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -869,6 +869,7 @@ struct hda_codec { | |||
869 | unsigned int power_on :1; /* current (global) power-state */ | 869 | unsigned int power_on :1; /* current (global) power-state */ |
870 | unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ | 870 | unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ |
871 | unsigned int pm_down_notified:1; /* PM notified to controller */ | 871 | unsigned int pm_down_notified:1; /* PM notified to controller */ |
872 | unsigned int in_pm:1; /* suspend/resume being performed */ | ||
872 | int power_transition; /* power-state in transition */ | 873 | int power_transition; /* power-state in transition */ |
873 | int power_count; /* current (global) power refcount */ | 874 | int power_count; /* current (global) power refcount */ |
874 | struct delayed_work power_work; /* delayed task for powerdown */ | 875 | struct delayed_work power_work; /* delayed task for powerdown */ |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index cd2dbaf1be78..f9d870e554d9 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -556,6 +556,12 @@ enum { | |||
556 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ | 556 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ |
557 | #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ | 557 | #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ |
558 | #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ | 558 | #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ |
559 | #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ | ||
560 | |||
561 | /* quirks for Intel PCH */ | ||
562 | #define AZX_DCAPS_INTEL_PCH \ | ||
563 | (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \ | ||
564 | AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_PM_RUNTIME) | ||
559 | 565 | ||
560 | /* quirks for ATI SB / AMD Hudson */ | 566 | /* quirks for ATI SB / AMD Hudson */ |
561 | #define AZX_DCAPS_PRESET_ATI_SB \ | 567 | #define AZX_DCAPS_PRESET_ATI_SB \ |
@@ -2433,6 +2439,9 @@ static void azx_power_notify(struct hda_bus *bus, bool power_up) | |||
2433 | { | 2439 | { |
2434 | struct azx *chip = bus->private_data; | 2440 | struct azx *chip = bus->private_data; |
2435 | 2441 | ||
2442 | if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) | ||
2443 | return; | ||
2444 | |||
2436 | if (power_up) | 2445 | if (power_up) |
2437 | pm_runtime_get_sync(&chip->pci->dev); | 2446 | pm_runtime_get_sync(&chip->pci->dev); |
2438 | else | 2447 | else |
@@ -2548,7 +2557,8 @@ static int azx_runtime_suspend(struct device *dev) | |||
2548 | struct snd_card *card = dev_get_drvdata(dev); | 2557 | struct snd_card *card = dev_get_drvdata(dev); |
2549 | struct azx *chip = card->private_data; | 2558 | struct azx *chip = card->private_data; |
2550 | 2559 | ||
2551 | if (!power_save_controller) | 2560 | if (!power_save_controller || |
2561 | !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) | ||
2552 | return -EAGAIN; | 2562 | return -EAGAIN; |
2553 | 2563 | ||
2554 | azx_stop_chip(chip); | 2564 | azx_stop_chip(chip); |
@@ -3429,39 +3439,30 @@ static void __devexit azx_remove(struct pci_dev *pci) | |||
3429 | static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | 3439 | static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { |
3430 | /* CPT */ | 3440 | /* CPT */ |
3431 | { PCI_DEVICE(0x8086, 0x1c20), | 3441 | { PCI_DEVICE(0x8086, 0x1c20), |
3432 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3442 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, |
3433 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, | ||
3434 | /* PBG */ | 3443 | /* PBG */ |
3435 | { PCI_DEVICE(0x8086, 0x1d20), | 3444 | { PCI_DEVICE(0x8086, 0x1d20), |
3436 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3445 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, |
3437 | AZX_DCAPS_BUFSIZE}, | ||
3438 | /* Panther Point */ | 3446 | /* Panther Point */ |
3439 | { PCI_DEVICE(0x8086, 0x1e20), | 3447 | { PCI_DEVICE(0x8086, 0x1e20), |
3440 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3448 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, |
3441 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, | ||
3442 | /* Lynx Point */ | 3449 | /* Lynx Point */ |
3443 | { PCI_DEVICE(0x8086, 0x8c20), | 3450 | { PCI_DEVICE(0x8086, 0x8c20), |
3444 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3451 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, |
3445 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, | ||
3446 | /* Lynx Point-LP */ | 3452 | /* Lynx Point-LP */ |
3447 | { PCI_DEVICE(0x8086, 0x9c20), | 3453 | { PCI_DEVICE(0x8086, 0x9c20), |
3448 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3454 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, |
3449 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, | ||
3450 | /* Lynx Point-LP */ | 3455 | /* Lynx Point-LP */ |
3451 | { PCI_DEVICE(0x8086, 0x9c21), | 3456 | { PCI_DEVICE(0x8086, 0x9c21), |
3452 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3457 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, |
3453 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, | ||
3454 | /* Haswell */ | 3458 | /* Haswell */ |
3455 | { PCI_DEVICE(0x8086, 0x0c0c), | 3459 | { PCI_DEVICE(0x8086, 0x0c0c), |
3456 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | 3460 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, |
3457 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, | ||
3458 | { PCI_DEVICE(0x8086, 0x0d0c), | 3461 | { PCI_DEVICE(0x8086, 0x0d0c), |
3459 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | 3462 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, |
3460 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, | ||
3461 | /* 5 Series/3400 */ | 3463 | /* 5 Series/3400 */ |
3462 | { PCI_DEVICE(0x8086, 0x3b56), | 3464 | { PCI_DEVICE(0x8086, 0x3b56), |
3463 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | 3465 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, |
3464 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, | ||
3465 | /* SCH */ | 3466 | /* SCH */ |
3466 | { PCI_DEVICE(0x8086, 0x811b), | 3467 | { PCI_DEVICE(0x8086, 0x811b), |
3467 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | 3468 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index d5f3a26d608d..3bcb67172358 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -466,6 +466,7 @@ static int parse_output(struct hda_codec *codec) | |||
466 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | 466 | memcpy(cfg->speaker_pins, cfg->line_out_pins, |
467 | sizeof(cfg->speaker_pins)); | 467 | sizeof(cfg->speaker_pins)); |
468 | cfg->line_outs = 0; | 468 | cfg->line_outs = 0; |
469 | memset(cfg->line_out_pins, 0, sizeof(cfg->line_out_pins)); | ||
469 | } | 470 | } |
470 | 471 | ||
471 | return 0; | 472 | return 0; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 68fd49294b26..ad68d223f8af 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -7065,6 +7065,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
7065 | { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, | 7065 | { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, |
7066 | { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, | 7066 | { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, |
7067 | { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, | 7067 | { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, |
7068 | { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, | ||
7068 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | 7069 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
7069 | .patch = patch_alc861 }, | 7070 | .patch = patch_alc861 }, |
7070 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, | 7071 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, |
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index 72b09cfd3dc3..d1b691bf8e2d 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig | |||
@@ -6,6 +6,14 @@ config SND_ATMEL_SOC | |||
6 | the ATMEL SSC interface. You will also need | 6 | the ATMEL SSC interface. You will also need |
7 | to select the audio interfaces to support below. | 7 | to select the audio interfaces to support below. |
8 | 8 | ||
9 | config SND_ATMEL_SOC_PDC | ||
10 | tristate | ||
11 | depends on SND_ATMEL_SOC | ||
12 | |||
13 | config SND_ATMEL_SOC_DMA | ||
14 | tristate | ||
15 | depends on SND_ATMEL_SOC | ||
16 | |||
9 | config SND_ATMEL_SOC_SSC | 17 | config SND_ATMEL_SOC_SSC |
10 | tristate | 18 | tristate |
11 | depends on SND_ATMEL_SOC | 19 | depends on SND_ATMEL_SOC |
@@ -16,8 +24,8 @@ config SND_ATMEL_SOC_SSC | |||
16 | 24 | ||
17 | config SND_AT91_SOC_SAM9G20_WM8731 | 25 | config SND_AT91_SOC_SAM9G20_WM8731 |
18 | tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" | 26 | tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" |
19 | depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \ | 27 | depends on ATMEL_SSC && SND_ATMEL_SOC && AT91_PROGRAMMABLE_CLOCKS |
20 | AT91_PROGRAMMABLE_CLOCKS | 28 | select SND_ATMEL_SOC_PDC |
21 | select SND_ATMEL_SOC_SSC | 29 | select SND_ATMEL_SOC_SSC |
22 | select SND_SOC_WM8731 | 30 | select SND_SOC_WM8731 |
23 | help | 31 | help |
@@ -27,6 +35,7 @@ config SND_AT91_SOC_SAM9G20_WM8731 | |||
27 | config SND_AT91_SOC_AFEB9260 | 35 | config SND_AT91_SOC_AFEB9260 |
28 | tristate "SoC Audio support for AFEB9260 board" | 36 | tristate "SoC Audio support for AFEB9260 board" |
29 | depends on ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC | 37 | depends on ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC |
38 | select SND_ATMEL_SOC_PDC | ||
30 | select SND_ATMEL_SOC_SSC | 39 | select SND_ATMEL_SOC_SSC |
31 | select SND_SOC_TLV320AIC23 | 40 | select SND_SOC_TLV320AIC23 |
32 | help | 41 | help |
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile index a5c0bf19da78..41967ccb6f41 100644 --- a/sound/soc/atmel/Makefile +++ b/sound/soc/atmel/Makefile | |||
@@ -1,8 +1,12 @@ | |||
1 | # AT91 Platform Support | 1 | # AT91 Platform Support |
2 | snd-soc-atmel-pcm-objs := atmel-pcm.o | 2 | snd-soc-atmel-pcm-objs := atmel-pcm.o |
3 | snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o | ||
4 | snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o | ||
3 | snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o | 5 | snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o |
4 | 6 | ||
5 | obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o | 7 | obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o |
8 | obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o | ||
9 | obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o | ||
6 | obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o | 10 | obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o |
7 | 11 | ||
8 | # AT91 Machine Support | 12 | # AT91 Machine Support |
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c new file mode 100644 index 000000000000..30184a4a147a --- /dev/null +++ b/sound/soc/atmel/atmel-pcm-dma.c | |||
@@ -0,0 +1,240 @@ | |||
1 | /* | ||
2 | * atmel-pcm-dma.c -- ALSA PCM DMA support for the Atmel SoC. | ||
3 | * | ||
4 | * Copyright (C) 2012 Atmel | ||
5 | * | ||
6 | * Author: Bo Shen <voice.shen@atmel.com> | ||
7 | * | ||
8 | * Based on atmel-pcm by: | ||
9 | * Sedji Gaouaou <sedji.gaouaou@atmel.com> | ||
10 | * Copyright 2008 Atmel | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/dma-mapping.h> | ||
32 | #include <linux/dmaengine.h> | ||
33 | #include <linux/atmel-ssc.h> | ||
34 | #include <linux/platform_data/dma-atmel.h> | ||
35 | |||
36 | #include <sound/core.h> | ||
37 | #include <sound/pcm.h> | ||
38 | #include <sound/pcm_params.h> | ||
39 | #include <sound/soc.h> | ||
40 | #include <sound/dmaengine_pcm.h> | ||
41 | |||
42 | #include "atmel-pcm.h" | ||
43 | |||
44 | /*--------------------------------------------------------------------------*\ | ||
45 | * Hardware definition | ||
46 | \*--------------------------------------------------------------------------*/ | ||
47 | static const struct snd_pcm_hardware atmel_pcm_dma_hardware = { | ||
48 | .info = SNDRV_PCM_INFO_MMAP | | ||
49 | SNDRV_PCM_INFO_MMAP_VALID | | ||
50 | SNDRV_PCM_INFO_INTERLEAVED | | ||
51 | SNDRV_PCM_INFO_RESUME | | ||
52 | SNDRV_PCM_INFO_PAUSE, | ||
53 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
54 | .period_bytes_min = 256, /* lighting DMA overhead */ | ||
55 | .period_bytes_max = 2 * 0xffff, /* if 2 bytes format */ | ||
56 | .periods_min = 8, | ||
57 | .periods_max = 1024, /* no limit */ | ||
58 | .buffer_bytes_max = ATMEL_SSC_DMABUF_SIZE, | ||
59 | }; | ||
60 | |||
61 | /** | ||
62 | * atmel_pcm_dma_irq: SSC interrupt handler for DMAENGINE enabled SSC | ||
63 | * | ||
64 | * We use DMAENGINE to send/receive data to/from SSC so this ISR is only to | ||
65 | * check if any overrun occured. | ||
66 | */ | ||
67 | static void atmel_pcm_dma_irq(u32 ssc_sr, | ||
68 | struct snd_pcm_substream *substream) | ||
69 | { | ||
70 | struct atmel_pcm_dma_params *prtd; | ||
71 | |||
72 | prtd = snd_dmaengine_pcm_get_data(substream); | ||
73 | |||
74 | if (ssc_sr & prtd->mask->ssc_error) { | ||
75 | if (snd_pcm_running(substream)) | ||
76 | pr_warn("atmel-pcm: buffer %s on %s (SSC_SR=%#x)\n", | ||
77 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK | ||
78 | ? "underrun" : "overrun", prtd->name, | ||
79 | ssc_sr); | ||
80 | |||
81 | /* stop RX and capture: will be enabled again at restart */ | ||
82 | ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_disable); | ||
83 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | ||
84 | |||
85 | /* now drain RHR and read status to remove xrun condition */ | ||
86 | ssc_readx(prtd->ssc->regs, SSC_RHR); | ||
87 | ssc_readx(prtd->ssc->regs, SSC_SR); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | /*--------------------------------------------------------------------------*\ | ||
92 | * DMAENGINE operations | ||
93 | \*--------------------------------------------------------------------------*/ | ||
94 | static bool filter(struct dma_chan *chan, void *slave) | ||
95 | { | ||
96 | struct at_dma_slave *sl = slave; | ||
97 | |||
98 | if (sl->dma_dev == chan->device->dev) { | ||
99 | chan->private = sl; | ||
100 | return true; | ||
101 | } else { | ||
102 | return false; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, | ||
107 | struct snd_pcm_hw_params *params) | ||
108 | { | ||
109 | struct atmel_pcm_dma_params *prtd; | ||
110 | struct ssc_device *ssc; | ||
111 | struct dma_chan *dma_chan; | ||
112 | struct dma_slave_config slave_config; | ||
113 | int ret; | ||
114 | |||
115 | prtd = snd_dmaengine_pcm_get_data(substream); | ||
116 | ssc = prtd->ssc; | ||
117 | |||
118 | ret = snd_hwparams_to_dma_slave_config(substream, params, | ||
119 | &slave_config); | ||
120 | if (ret) { | ||
121 | pr_err("atmel-pcm: hwparams to dma slave configure failed\n"); | ||
122 | return ret; | ||
123 | } | ||
124 | |||
125 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
126 | slave_config.dst_addr = (dma_addr_t)ssc->phybase + SSC_THR; | ||
127 | slave_config.dst_maxburst = 1; | ||
128 | } else { | ||
129 | slave_config.src_addr = (dma_addr_t)ssc->phybase + SSC_RHR; | ||
130 | slave_config.src_maxburst = 1; | ||
131 | } | ||
132 | |||
133 | slave_config.device_fc = false; | ||
134 | |||
135 | dma_chan = snd_dmaengine_pcm_get_chan(substream); | ||
136 | if (dmaengine_slave_config(dma_chan, &slave_config)) { | ||
137 | pr_err("atmel-pcm: failed to configure dma channel\n"); | ||
138 | ret = -EBUSY; | ||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, | ||
146 | struct snd_pcm_hw_params *params) | ||
147 | { | ||
148 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
149 | struct atmel_pcm_dma_params *prtd; | ||
150 | struct ssc_device *ssc; | ||
151 | struct at_dma_slave *sdata = NULL; | ||
152 | int ret; | ||
153 | |||
154 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
155 | |||
156 | prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
157 | ssc = prtd->ssc; | ||
158 | if (ssc->pdev) | ||
159 | sdata = ssc->pdev->dev.platform_data; | ||
160 | |||
161 | ret = snd_dmaengine_pcm_open(substream, filter, sdata); | ||
162 | if (ret) { | ||
163 | pr_err("atmel-pcm: dmaengine pcm open failed\n"); | ||
164 | return -EINVAL; | ||
165 | } | ||
166 | |||
167 | snd_dmaengine_pcm_set_data(substream, prtd); | ||
168 | |||
169 | ret = atmel_pcm_configure_dma(substream, params); | ||
170 | if (ret) { | ||
171 | pr_err("atmel-pcm: failed to configure dmai\n"); | ||
172 | goto err; | ||
173 | } | ||
174 | |||
175 | prtd->dma_intr_handler = atmel_pcm_dma_irq; | ||
176 | |||
177 | return 0; | ||
178 | err: | ||
179 | snd_dmaengine_pcm_close(substream); | ||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream) | ||
184 | { | ||
185 | struct atmel_pcm_dma_params *prtd; | ||
186 | |||
187 | prtd = snd_dmaengine_pcm_get_data(substream); | ||
188 | |||
189 | ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error); | ||
190 | ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable); | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static int atmel_pcm_open(struct snd_pcm_substream *substream) | ||
196 | { | ||
197 | snd_soc_set_runtime_hwparams(substream, &atmel_pcm_dma_hardware); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static int atmel_pcm_close(struct snd_pcm_substream *substream) | ||
203 | { | ||
204 | snd_dmaengine_pcm_close(substream); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static struct snd_pcm_ops atmel_pcm_ops = { | ||
210 | .open = atmel_pcm_open, | ||
211 | .close = atmel_pcm_close, | ||
212 | .ioctl = snd_pcm_lib_ioctl, | ||
213 | .hw_params = atmel_pcm_hw_params, | ||
214 | .prepare = atmel_pcm_dma_prepare, | ||
215 | .trigger = snd_dmaengine_pcm_trigger, | ||
216 | .pointer = snd_dmaengine_pcm_pointer_no_residue, | ||
217 | .mmap = atmel_pcm_mmap, | ||
218 | }; | ||
219 | |||
220 | static struct snd_soc_platform_driver atmel_soc_platform = { | ||
221 | .ops = &atmel_pcm_ops, | ||
222 | .pcm_new = atmel_pcm_new, | ||
223 | .pcm_free = atmel_pcm_free, | ||
224 | }; | ||
225 | |||
226 | int atmel_pcm_dma_platform_register(struct device *dev) | ||
227 | { | ||
228 | return snd_soc_register_platform(dev, &atmel_soc_platform); | ||
229 | } | ||
230 | EXPORT_SYMBOL(atmel_pcm_dma_platform_register); | ||
231 | |||
232 | void atmel_pcm_dma_platform_unregister(struct device *dev) | ||
233 | { | ||
234 | snd_soc_unregister_platform(dev); | ||
235 | } | ||
236 | EXPORT_SYMBOL(atmel_pcm_dma_platform_unregister); | ||
237 | |||
238 | MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>"); | ||
239 | MODULE_DESCRIPTION("Atmel DMA based PCM module"); | ||
240 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c new file mode 100644 index 000000000000..6a293c713a38 --- /dev/null +++ b/sound/soc/atmel/atmel-pcm-pdc.c | |||
@@ -0,0 +1,401 @@ | |||
1 | /* | ||
2 | * atmel-pcm.c -- ALSA PCM interface for the Atmel atmel SoC. | ||
3 | * | ||
4 | * Copyright (C) 2005 SAN People | ||
5 | * Copyright (C) 2008 Atmel | ||
6 | * | ||
7 | * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com> | ||
8 | * | ||
9 | * Based on at91-pcm. by: | ||
10 | * Frank Mandarino <fmandarino@endrelia.com> | ||
11 | * Copyright 2006 Endrelia Technologies Inc. | ||
12 | * | ||
13 | * Based on pxa2xx-pcm.c by: | ||
14 | * | ||
15 | * Author: Nicolas Pitre | ||
16 | * Created: Nov 30, 2004 | ||
17 | * Copyright: (C) 2004 MontaVista Software, Inc. | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or modify | ||
20 | * it under the terms of the GNU General Public License as published by | ||
21 | * the Free Software Foundation; either version 2 of the License, or | ||
22 | * (at your option) any later version. | ||
23 | * | ||
24 | * This program is distributed in the hope that it will be useful, | ||
25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
27 | * GNU General Public License for more details. | ||
28 | * | ||
29 | * You should have received a copy of the GNU General Public License | ||
30 | * along with this program; if not, write to the Free Software | ||
31 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
32 | */ | ||
33 | |||
34 | #include <linux/module.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/dma-mapping.h> | ||
39 | #include <linux/atmel_pdc.h> | ||
40 | #include <linux/atmel-ssc.h> | ||
41 | |||
42 | #include <sound/core.h> | ||
43 | #include <sound/pcm.h> | ||
44 | #include <sound/pcm_params.h> | ||
45 | #include <sound/soc.h> | ||
46 | |||
47 | #include "atmel-pcm.h" | ||
48 | |||
49 | |||
50 | /*--------------------------------------------------------------------------*\ | ||
51 | * Hardware definition | ||
52 | \*--------------------------------------------------------------------------*/ | ||
53 | /* TODO: These values were taken from the AT91 platform driver, check | ||
54 | * them against real values for AT32 | ||
55 | */ | ||
56 | static const struct snd_pcm_hardware atmel_pcm_hardware = { | ||
57 | .info = SNDRV_PCM_INFO_MMAP | | ||
58 | SNDRV_PCM_INFO_MMAP_VALID | | ||
59 | SNDRV_PCM_INFO_INTERLEAVED | | ||
60 | SNDRV_PCM_INFO_PAUSE, | ||
61 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
62 | .period_bytes_min = 32, | ||
63 | .period_bytes_max = 8192, | ||
64 | .periods_min = 2, | ||
65 | .periods_max = 1024, | ||
66 | .buffer_bytes_max = ATMEL_SSC_DMABUF_SIZE, | ||
67 | }; | ||
68 | |||
69 | |||
70 | /*--------------------------------------------------------------------------*\ | ||
71 | * Data types | ||
72 | \*--------------------------------------------------------------------------*/ | ||
73 | struct atmel_runtime_data { | ||
74 | struct atmel_pcm_dma_params *params; | ||
75 | dma_addr_t dma_buffer; /* physical address of dma buffer */ | ||
76 | dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */ | ||
77 | size_t period_size; | ||
78 | |||
79 | dma_addr_t period_ptr; /* physical address of next period */ | ||
80 | |||
81 | /* PDC register save */ | ||
82 | u32 pdc_xpr_save; | ||
83 | u32 pdc_xcr_save; | ||
84 | u32 pdc_xnpr_save; | ||
85 | u32 pdc_xncr_save; | ||
86 | }; | ||
87 | |||
88 | /*--------------------------------------------------------------------------*\ | ||
89 | * ISR | ||
90 | \*--------------------------------------------------------------------------*/ | ||
91 | static void atmel_pcm_dma_irq(u32 ssc_sr, | ||
92 | struct snd_pcm_substream *substream) | ||
93 | { | ||
94 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
95 | struct atmel_pcm_dma_params *params = prtd->params; | ||
96 | static int count; | ||
97 | |||
98 | count++; | ||
99 | |||
100 | if (ssc_sr & params->mask->ssc_endbuf) { | ||
101 | pr_warn("atmel-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n", | ||
102 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK | ||
103 | ? "underrun" : "overrun", | ||
104 | params->name, ssc_sr, count); | ||
105 | |||
106 | /* re-start the PDC */ | ||
107 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
108 | params->mask->pdc_disable); | ||
109 | prtd->period_ptr += prtd->period_size; | ||
110 | if (prtd->period_ptr >= prtd->dma_buffer_end) | ||
111 | prtd->period_ptr = prtd->dma_buffer; | ||
112 | |||
113 | ssc_writex(params->ssc->regs, params->pdc->xpr, | ||
114 | prtd->period_ptr); | ||
115 | ssc_writex(params->ssc->regs, params->pdc->xcr, | ||
116 | prtd->period_size / params->pdc_xfer_size); | ||
117 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
118 | params->mask->pdc_enable); | ||
119 | } | ||
120 | |||
121 | if (ssc_sr & params->mask->ssc_endx) { | ||
122 | /* Load the PDC next pointer and counter registers */ | ||
123 | prtd->period_ptr += prtd->period_size; | ||
124 | if (prtd->period_ptr >= prtd->dma_buffer_end) | ||
125 | prtd->period_ptr = prtd->dma_buffer; | ||
126 | |||
127 | ssc_writex(params->ssc->regs, params->pdc->xnpr, | ||
128 | prtd->period_ptr); | ||
129 | ssc_writex(params->ssc->regs, params->pdc->xncr, | ||
130 | prtd->period_size / params->pdc_xfer_size); | ||
131 | } | ||
132 | |||
133 | snd_pcm_period_elapsed(substream); | ||
134 | } | ||
135 | |||
136 | |||
137 | /*--------------------------------------------------------------------------*\ | ||
138 | * PCM operations | ||
139 | \*--------------------------------------------------------------------------*/ | ||
140 | static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, | ||
141 | struct snd_pcm_hw_params *params) | ||
142 | { | ||
143 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
144 | struct atmel_runtime_data *prtd = runtime->private_data; | ||
145 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
146 | |||
147 | /* this may get called several times by oss emulation | ||
148 | * with different params */ | ||
149 | |||
150 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
151 | runtime->dma_bytes = params_buffer_bytes(params); | ||
152 | |||
153 | prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
154 | prtd->params->dma_intr_handler = atmel_pcm_dma_irq; | ||
155 | |||
156 | prtd->dma_buffer = runtime->dma_addr; | ||
157 | prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes; | ||
158 | prtd->period_size = params_period_bytes(params); | ||
159 | |||
160 | pr_debug("atmel-pcm: " | ||
161 | "hw_params: DMA for %s initialized " | ||
162 | "(dma_bytes=%u, period_size=%u)\n", | ||
163 | prtd->params->name, | ||
164 | runtime->dma_bytes, | ||
165 | prtd->period_size); | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int atmel_pcm_hw_free(struct snd_pcm_substream *substream) | ||
170 | { | ||
171 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
172 | struct atmel_pcm_dma_params *params = prtd->params; | ||
173 | |||
174 | if (params != NULL) { | ||
175 | ssc_writex(params->ssc->regs, SSC_PDC_PTCR, | ||
176 | params->mask->pdc_disable); | ||
177 | prtd->params->dma_intr_handler = NULL; | ||
178 | } | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int atmel_pcm_prepare(struct snd_pcm_substream *substream) | ||
184 | { | ||
185 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
186 | struct atmel_pcm_dma_params *params = prtd->params; | ||
187 | |||
188 | ssc_writex(params->ssc->regs, SSC_IDR, | ||
189 | params->mask->ssc_endx | params->mask->ssc_endbuf); | ||
190 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
191 | params->mask->pdc_disable); | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static int atmel_pcm_trigger(struct snd_pcm_substream *substream, | ||
196 | int cmd) | ||
197 | { | ||
198 | struct snd_pcm_runtime *rtd = substream->runtime; | ||
199 | struct atmel_runtime_data *prtd = rtd->private_data; | ||
200 | struct atmel_pcm_dma_params *params = prtd->params; | ||
201 | int ret = 0; | ||
202 | |||
203 | pr_debug("atmel-pcm:buffer_size = %ld," | ||
204 | "dma_area = %p, dma_bytes = %u\n", | ||
205 | rtd->buffer_size, rtd->dma_area, rtd->dma_bytes); | ||
206 | |||
207 | switch (cmd) { | ||
208 | case SNDRV_PCM_TRIGGER_START: | ||
209 | prtd->period_ptr = prtd->dma_buffer; | ||
210 | |||
211 | ssc_writex(params->ssc->regs, params->pdc->xpr, | ||
212 | prtd->period_ptr); | ||
213 | ssc_writex(params->ssc->regs, params->pdc->xcr, | ||
214 | prtd->period_size / params->pdc_xfer_size); | ||
215 | |||
216 | prtd->period_ptr += prtd->period_size; | ||
217 | ssc_writex(params->ssc->regs, params->pdc->xnpr, | ||
218 | prtd->period_ptr); | ||
219 | ssc_writex(params->ssc->regs, params->pdc->xncr, | ||
220 | prtd->period_size / params->pdc_xfer_size); | ||
221 | |||
222 | pr_debug("atmel-pcm: trigger: " | ||
223 | "period_ptr=%lx, xpr=%u, " | ||
224 | "xcr=%u, xnpr=%u, xncr=%u\n", | ||
225 | (unsigned long)prtd->period_ptr, | ||
226 | ssc_readx(params->ssc->regs, params->pdc->xpr), | ||
227 | ssc_readx(params->ssc->regs, params->pdc->xcr), | ||
228 | ssc_readx(params->ssc->regs, params->pdc->xnpr), | ||
229 | ssc_readx(params->ssc->regs, params->pdc->xncr)); | ||
230 | |||
231 | ssc_writex(params->ssc->regs, SSC_IER, | ||
232 | params->mask->ssc_endx | params->mask->ssc_endbuf); | ||
233 | ssc_writex(params->ssc->regs, SSC_PDC_PTCR, | ||
234 | params->mask->pdc_enable); | ||
235 | |||
236 | pr_debug("sr=%u imr=%u\n", | ||
237 | ssc_readx(params->ssc->regs, SSC_SR), | ||
238 | ssc_readx(params->ssc->regs, SSC_IER)); | ||
239 | break; /* SNDRV_PCM_TRIGGER_START */ | ||
240 | |||
241 | case SNDRV_PCM_TRIGGER_STOP: | ||
242 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
243 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
244 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
245 | params->mask->pdc_disable); | ||
246 | break; | ||
247 | |||
248 | case SNDRV_PCM_TRIGGER_RESUME: | ||
249 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
250 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
251 | params->mask->pdc_enable); | ||
252 | break; | ||
253 | |||
254 | default: | ||
255 | ret = -EINVAL; | ||
256 | } | ||
257 | |||
258 | return ret; | ||
259 | } | ||
260 | |||
261 | static snd_pcm_uframes_t atmel_pcm_pointer( | ||
262 | struct snd_pcm_substream *substream) | ||
263 | { | ||
264 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
265 | struct atmel_runtime_data *prtd = runtime->private_data; | ||
266 | struct atmel_pcm_dma_params *params = prtd->params; | ||
267 | dma_addr_t ptr; | ||
268 | snd_pcm_uframes_t x; | ||
269 | |||
270 | ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr); | ||
271 | x = bytes_to_frames(runtime, ptr - prtd->dma_buffer); | ||
272 | |||
273 | if (x == runtime->buffer_size) | ||
274 | x = 0; | ||
275 | |||
276 | return x; | ||
277 | } | ||
278 | |||
279 | static int atmel_pcm_open(struct snd_pcm_substream *substream) | ||
280 | { | ||
281 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
282 | struct atmel_runtime_data *prtd; | ||
283 | int ret = 0; | ||
284 | |||
285 | snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware); | ||
286 | |||
287 | /* ensure that buffer size is a multiple of period size */ | ||
288 | ret = snd_pcm_hw_constraint_integer(runtime, | ||
289 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
290 | if (ret < 0) | ||
291 | goto out; | ||
292 | |||
293 | prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL); | ||
294 | if (prtd == NULL) { | ||
295 | ret = -ENOMEM; | ||
296 | goto out; | ||
297 | } | ||
298 | runtime->private_data = prtd; | ||
299 | |||
300 | out: | ||
301 | return ret; | ||
302 | } | ||
303 | |||
304 | static int atmel_pcm_close(struct snd_pcm_substream *substream) | ||
305 | { | ||
306 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
307 | |||
308 | kfree(prtd); | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static struct snd_pcm_ops atmel_pcm_ops = { | ||
313 | .open = atmel_pcm_open, | ||
314 | .close = atmel_pcm_close, | ||
315 | .ioctl = snd_pcm_lib_ioctl, | ||
316 | .hw_params = atmel_pcm_hw_params, | ||
317 | .hw_free = atmel_pcm_hw_free, | ||
318 | .prepare = atmel_pcm_prepare, | ||
319 | .trigger = atmel_pcm_trigger, | ||
320 | .pointer = atmel_pcm_pointer, | ||
321 | .mmap = atmel_pcm_mmap, | ||
322 | }; | ||
323 | |||
324 | |||
325 | /*--------------------------------------------------------------------------*\ | ||
326 | * ASoC platform driver | ||
327 | \*--------------------------------------------------------------------------*/ | ||
328 | #ifdef CONFIG_PM | ||
329 | static int atmel_pcm_suspend(struct snd_soc_dai *dai) | ||
330 | { | ||
331 | struct snd_pcm_runtime *runtime = dai->runtime; | ||
332 | struct atmel_runtime_data *prtd; | ||
333 | struct atmel_pcm_dma_params *params; | ||
334 | |||
335 | if (!runtime) | ||
336 | return 0; | ||
337 | |||
338 | prtd = runtime->private_data; | ||
339 | params = prtd->params; | ||
340 | |||
341 | /* disable the PDC and save the PDC registers */ | ||
342 | |||
343 | ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable); | ||
344 | |||
345 | prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr); | ||
346 | prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr); | ||
347 | prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr); | ||
348 | prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr); | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static int atmel_pcm_resume(struct snd_soc_dai *dai) | ||
354 | { | ||
355 | struct snd_pcm_runtime *runtime = dai->runtime; | ||
356 | struct atmel_runtime_data *prtd; | ||
357 | struct atmel_pcm_dma_params *params; | ||
358 | |||
359 | if (!runtime) | ||
360 | return 0; | ||
361 | |||
362 | prtd = runtime->private_data; | ||
363 | params = prtd->params; | ||
364 | |||
365 | /* restore the PDC registers and enable the PDC */ | ||
366 | ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save); | ||
367 | ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save); | ||
368 | ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save); | ||
369 | ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save); | ||
370 | |||
371 | ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable); | ||
372 | return 0; | ||
373 | } | ||
374 | #else | ||
375 | #define atmel_pcm_suspend NULL | ||
376 | #define atmel_pcm_resume NULL | ||
377 | #endif | ||
378 | |||
379 | static struct snd_soc_platform_driver atmel_soc_platform = { | ||
380 | .ops = &atmel_pcm_ops, | ||
381 | .pcm_new = atmel_pcm_new, | ||
382 | .pcm_free = atmel_pcm_free, | ||
383 | .suspend = atmel_pcm_suspend, | ||
384 | .resume = atmel_pcm_resume, | ||
385 | }; | ||
386 | |||
387 | int atmel_pcm_pdc_platform_register(struct device *dev) | ||
388 | { | ||
389 | return snd_soc_register_platform(dev, &atmel_soc_platform); | ||
390 | } | ||
391 | EXPORT_SYMBOL(atmel_pcm_pdc_platform_register); | ||
392 | |||
393 | void atmel_pcm_pdc_platform_unregister(struct device *dev) | ||
394 | { | ||
395 | snd_soc_unregister_platform(dev); | ||
396 | } | ||
397 | EXPORT_SYMBOL(atmel_pcm_pdc_platform_unregister); | ||
398 | |||
399 | MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); | ||
400 | MODULE_DESCRIPTION("Atmel PCM module"); | ||
401 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c index 9b84f985770e..e99f1811300a 100644 --- a/sound/soc/atmel/atmel-pcm.c +++ b/sound/soc/atmel/atmel-pcm.c | |||
@@ -32,80 +32,25 @@ | |||
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/init.h> | ||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/dma-mapping.h> | 35 | #include <linux/dma-mapping.h> |
39 | #include <linux/atmel_pdc.h> | ||
40 | #include <linux/atmel-ssc.h> | ||
41 | |||
42 | #include <sound/core.h> | ||
43 | #include <sound/pcm.h> | 36 | #include <sound/pcm.h> |
44 | #include <sound/pcm_params.h> | ||
45 | #include <sound/soc.h> | 37 | #include <sound/soc.h> |
46 | |||
47 | #include "atmel-pcm.h" | 38 | #include "atmel-pcm.h" |
48 | 39 | ||
49 | |||
50 | /*--------------------------------------------------------------------------*\ | ||
51 | * Hardware definition | ||
52 | \*--------------------------------------------------------------------------*/ | ||
53 | /* TODO: These values were taken from the AT91 platform driver, check | ||
54 | * them against real values for AT32 | ||
55 | */ | ||
56 | static const struct snd_pcm_hardware atmel_pcm_hardware = { | ||
57 | .info = SNDRV_PCM_INFO_MMAP | | ||
58 | SNDRV_PCM_INFO_MMAP_VALID | | ||
59 | SNDRV_PCM_INFO_INTERLEAVED | | ||
60 | SNDRV_PCM_INFO_PAUSE, | ||
61 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
62 | .period_bytes_min = 32, | ||
63 | .period_bytes_max = 8192, | ||
64 | .periods_min = 2, | ||
65 | .periods_max = 1024, | ||
66 | .buffer_bytes_max = 32 * 1024, | ||
67 | }; | ||
68 | |||
69 | |||
70 | /*--------------------------------------------------------------------------*\ | ||
71 | * Data types | ||
72 | \*--------------------------------------------------------------------------*/ | ||
73 | struct atmel_runtime_data { | ||
74 | struct atmel_pcm_dma_params *params; | ||
75 | dma_addr_t dma_buffer; /* physical address of dma buffer */ | ||
76 | dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */ | ||
77 | size_t period_size; | ||
78 | |||
79 | dma_addr_t period_ptr; /* physical address of next period */ | ||
80 | |||
81 | /* PDC register save */ | ||
82 | u32 pdc_xpr_save; | ||
83 | u32 pdc_xcr_save; | ||
84 | u32 pdc_xnpr_save; | ||
85 | u32 pdc_xncr_save; | ||
86 | }; | ||
87 | |||
88 | |||
89 | /*--------------------------------------------------------------------------*\ | ||
90 | * Helper functions | ||
91 | \*--------------------------------------------------------------------------*/ | ||
92 | static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, | 40 | static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, |
93 | int stream) | 41 | int stream) |
94 | { | 42 | { |
95 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | 43 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; |
96 | struct snd_dma_buffer *buf = &substream->dma_buffer; | 44 | struct snd_dma_buffer *buf = &substream->dma_buffer; |
97 | size_t size = atmel_pcm_hardware.buffer_bytes_max; | 45 | size_t size = ATMEL_SSC_DMABUF_SIZE; |
98 | 46 | ||
99 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | 47 | buf->dev.type = SNDRV_DMA_TYPE_DEV; |
100 | buf->dev.dev = pcm->card->dev; | 48 | buf->dev.dev = pcm->card->dev; |
101 | buf->private_data = NULL; | 49 | buf->private_data = NULL; |
102 | buf->area = dma_alloc_coherent(pcm->card->dev, size, | 50 | buf->area = dma_alloc_coherent(pcm->card->dev, size, |
103 | &buf->addr, GFP_KERNEL); | 51 | &buf->addr, GFP_KERNEL); |
104 | pr_debug("atmel-pcm:" | 52 | pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%d\n", |
105 | "preallocate_dma_buffer: area=%p, addr=%p, size=%d\n", | 53 | (void *)buf->area, (void *)buf->addr, size); |
106 | (void *) buf->area, | ||
107 | (void *) buf->addr, | ||
108 | size); | ||
109 | 54 | ||
110 | if (!buf->area) | 55 | if (!buf->area) |
111 | return -ENOMEM; | 56 | return -ENOMEM; |
@@ -113,258 +58,19 @@ static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, | |||
113 | buf->bytes = size; | 58 | buf->bytes = size; |
114 | return 0; | 59 | return 0; |
115 | } | 60 | } |
116 | /*--------------------------------------------------------------------------*\ | ||
117 | * ISR | ||
118 | \*--------------------------------------------------------------------------*/ | ||
119 | static void atmel_pcm_dma_irq(u32 ssc_sr, | ||
120 | struct snd_pcm_substream *substream) | ||
121 | { | ||
122 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
123 | struct atmel_pcm_dma_params *params = prtd->params; | ||
124 | static int count; | ||
125 | |||
126 | count++; | ||
127 | |||
128 | if (ssc_sr & params->mask->ssc_endbuf) { | ||
129 | pr_warning("atmel-pcm: buffer %s on %s" | ||
130 | " (SSC_SR=%#x, count=%d)\n", | ||
131 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK | ||
132 | ? "underrun" : "overrun", | ||
133 | params->name, ssc_sr, count); | ||
134 | |||
135 | /* re-start the PDC */ | ||
136 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
137 | params->mask->pdc_disable); | ||
138 | prtd->period_ptr += prtd->period_size; | ||
139 | if (prtd->period_ptr >= prtd->dma_buffer_end) | ||
140 | prtd->period_ptr = prtd->dma_buffer; | ||
141 | |||
142 | ssc_writex(params->ssc->regs, params->pdc->xpr, | ||
143 | prtd->period_ptr); | ||
144 | ssc_writex(params->ssc->regs, params->pdc->xcr, | ||
145 | prtd->period_size / params->pdc_xfer_size); | ||
146 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
147 | params->mask->pdc_enable); | ||
148 | } | ||
149 | |||
150 | if (ssc_sr & params->mask->ssc_endx) { | ||
151 | /* Load the PDC next pointer and counter registers */ | ||
152 | prtd->period_ptr += prtd->period_size; | ||
153 | if (prtd->period_ptr >= prtd->dma_buffer_end) | ||
154 | prtd->period_ptr = prtd->dma_buffer; | ||
155 | |||
156 | ssc_writex(params->ssc->regs, params->pdc->xnpr, | ||
157 | prtd->period_ptr); | ||
158 | ssc_writex(params->ssc->regs, params->pdc->xncr, | ||
159 | prtd->period_size / params->pdc_xfer_size); | ||
160 | } | ||
161 | |||
162 | snd_pcm_period_elapsed(substream); | ||
163 | } | ||
164 | |||
165 | |||
166 | /*--------------------------------------------------------------------------*\ | ||
167 | * PCM operations | ||
168 | \*--------------------------------------------------------------------------*/ | ||
169 | static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, | ||
170 | struct snd_pcm_hw_params *params) | ||
171 | { | ||
172 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
173 | struct atmel_runtime_data *prtd = runtime->private_data; | ||
174 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
175 | |||
176 | /* this may get called several times by oss emulation | ||
177 | * with different params */ | ||
178 | |||
179 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
180 | runtime->dma_bytes = params_buffer_bytes(params); | ||
181 | |||
182 | prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
183 | prtd->params->dma_intr_handler = atmel_pcm_dma_irq; | ||
184 | |||
185 | prtd->dma_buffer = runtime->dma_addr; | ||
186 | prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes; | ||
187 | prtd->period_size = params_period_bytes(params); | ||
188 | |||
189 | pr_debug("atmel-pcm: " | ||
190 | "hw_params: DMA for %s initialized " | ||
191 | "(dma_bytes=%u, period_size=%u)\n", | ||
192 | prtd->params->name, | ||
193 | runtime->dma_bytes, | ||
194 | prtd->period_size); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int atmel_pcm_hw_free(struct snd_pcm_substream *substream) | ||
199 | { | ||
200 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
201 | struct atmel_pcm_dma_params *params = prtd->params; | ||
202 | |||
203 | if (params != NULL) { | ||
204 | ssc_writex(params->ssc->regs, SSC_PDC_PTCR, | ||
205 | params->mask->pdc_disable); | ||
206 | prtd->params->dma_intr_handler = NULL; | ||
207 | } | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int atmel_pcm_prepare(struct snd_pcm_substream *substream) | ||
213 | { | ||
214 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
215 | struct atmel_pcm_dma_params *params = prtd->params; | ||
216 | |||
217 | ssc_writex(params->ssc->regs, SSC_IDR, | ||
218 | params->mask->ssc_endx | params->mask->ssc_endbuf); | ||
219 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
220 | params->mask->pdc_disable); | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int atmel_pcm_trigger(struct snd_pcm_substream *substream, | ||
225 | int cmd) | ||
226 | { | ||
227 | struct snd_pcm_runtime *rtd = substream->runtime; | ||
228 | struct atmel_runtime_data *prtd = rtd->private_data; | ||
229 | struct atmel_pcm_dma_params *params = prtd->params; | ||
230 | int ret = 0; | ||
231 | |||
232 | pr_debug("atmel-pcm:buffer_size = %ld," | ||
233 | "dma_area = %p, dma_bytes = %u\n", | ||
234 | rtd->buffer_size, rtd->dma_area, rtd->dma_bytes); | ||
235 | |||
236 | switch (cmd) { | ||
237 | case SNDRV_PCM_TRIGGER_START: | ||
238 | prtd->period_ptr = prtd->dma_buffer; | ||
239 | |||
240 | ssc_writex(params->ssc->regs, params->pdc->xpr, | ||
241 | prtd->period_ptr); | ||
242 | ssc_writex(params->ssc->regs, params->pdc->xcr, | ||
243 | prtd->period_size / params->pdc_xfer_size); | ||
244 | |||
245 | prtd->period_ptr += prtd->period_size; | ||
246 | ssc_writex(params->ssc->regs, params->pdc->xnpr, | ||
247 | prtd->period_ptr); | ||
248 | ssc_writex(params->ssc->regs, params->pdc->xncr, | ||
249 | prtd->period_size / params->pdc_xfer_size); | ||
250 | |||
251 | pr_debug("atmel-pcm: trigger: " | ||
252 | "period_ptr=%lx, xpr=%u, " | ||
253 | "xcr=%u, xnpr=%u, xncr=%u\n", | ||
254 | (unsigned long)prtd->period_ptr, | ||
255 | ssc_readx(params->ssc->regs, params->pdc->xpr), | ||
256 | ssc_readx(params->ssc->regs, params->pdc->xcr), | ||
257 | ssc_readx(params->ssc->regs, params->pdc->xnpr), | ||
258 | ssc_readx(params->ssc->regs, params->pdc->xncr)); | ||
259 | |||
260 | ssc_writex(params->ssc->regs, SSC_IER, | ||
261 | params->mask->ssc_endx | params->mask->ssc_endbuf); | ||
262 | ssc_writex(params->ssc->regs, SSC_PDC_PTCR, | ||
263 | params->mask->pdc_enable); | ||
264 | |||
265 | pr_debug("sr=%u imr=%u\n", | ||
266 | ssc_readx(params->ssc->regs, SSC_SR), | ||
267 | ssc_readx(params->ssc->regs, SSC_IER)); | ||
268 | break; /* SNDRV_PCM_TRIGGER_START */ | ||
269 | |||
270 | case SNDRV_PCM_TRIGGER_STOP: | ||
271 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
272 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
273 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
274 | params->mask->pdc_disable); | ||
275 | break; | ||
276 | |||
277 | case SNDRV_PCM_TRIGGER_RESUME: | ||
278 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
279 | ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, | ||
280 | params->mask->pdc_enable); | ||
281 | break; | ||
282 | |||
283 | default: | ||
284 | ret = -EINVAL; | ||
285 | } | ||
286 | 61 | ||
287 | return ret; | 62 | int atmel_pcm_mmap(struct snd_pcm_substream *substream, |
288 | } | ||
289 | |||
290 | static snd_pcm_uframes_t atmel_pcm_pointer( | ||
291 | struct snd_pcm_substream *substream) | ||
292 | { | ||
293 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
294 | struct atmel_runtime_data *prtd = runtime->private_data; | ||
295 | struct atmel_pcm_dma_params *params = prtd->params; | ||
296 | dma_addr_t ptr; | ||
297 | snd_pcm_uframes_t x; | ||
298 | |||
299 | ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr); | ||
300 | x = bytes_to_frames(runtime, ptr - prtd->dma_buffer); | ||
301 | |||
302 | if (x == runtime->buffer_size) | ||
303 | x = 0; | ||
304 | |||
305 | return x; | ||
306 | } | ||
307 | |||
308 | static int atmel_pcm_open(struct snd_pcm_substream *substream) | ||
309 | { | ||
310 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
311 | struct atmel_runtime_data *prtd; | ||
312 | int ret = 0; | ||
313 | |||
314 | snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware); | ||
315 | |||
316 | /* ensure that buffer size is a multiple of period size */ | ||
317 | ret = snd_pcm_hw_constraint_integer(runtime, | ||
318 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
319 | if (ret < 0) | ||
320 | goto out; | ||
321 | |||
322 | prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL); | ||
323 | if (prtd == NULL) { | ||
324 | ret = -ENOMEM; | ||
325 | goto out; | ||
326 | } | ||
327 | runtime->private_data = prtd; | ||
328 | |||
329 | out: | ||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | static int atmel_pcm_close(struct snd_pcm_substream *substream) | ||
334 | { | ||
335 | struct atmel_runtime_data *prtd = substream->runtime->private_data; | ||
336 | |||
337 | kfree(prtd); | ||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static int atmel_pcm_mmap(struct snd_pcm_substream *substream, | ||
342 | struct vm_area_struct *vma) | 63 | struct vm_area_struct *vma) |
343 | { | 64 | { |
344 | return remap_pfn_range(vma, vma->vm_start, | 65 | return remap_pfn_range(vma, vma->vm_start, |
345 | substream->dma_buffer.addr >> PAGE_SHIFT, | 66 | substream->dma_buffer.addr >> PAGE_SHIFT, |
346 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | 67 | vma->vm_end - vma->vm_start, vma->vm_page_prot); |
347 | } | 68 | } |
69 | EXPORT_SYMBOL_GPL(atmel_pcm_mmap); | ||
348 | 70 | ||
349 | static struct snd_pcm_ops atmel_pcm_ops = { | ||
350 | .open = atmel_pcm_open, | ||
351 | .close = atmel_pcm_close, | ||
352 | .ioctl = snd_pcm_lib_ioctl, | ||
353 | .hw_params = atmel_pcm_hw_params, | ||
354 | .hw_free = atmel_pcm_hw_free, | ||
355 | .prepare = atmel_pcm_prepare, | ||
356 | .trigger = atmel_pcm_trigger, | ||
357 | .pointer = atmel_pcm_pointer, | ||
358 | .mmap = atmel_pcm_mmap, | ||
359 | }; | ||
360 | |||
361 | |||
362 | /*--------------------------------------------------------------------------*\ | ||
363 | * ASoC platform driver | ||
364 | \*--------------------------------------------------------------------------*/ | ||
365 | static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32); | 71 | static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32); |
366 | 72 | ||
367 | static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) | 73 | int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) |
368 | { | 74 | { |
369 | struct snd_card *card = rtd->card->snd_card; | 75 | struct snd_card *card = rtd->card->snd_card; |
370 | struct snd_pcm *pcm = rtd->pcm; | 76 | struct snd_pcm *pcm = rtd->pcm; |
@@ -376,6 +82,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
376 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | 82 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); |
377 | 83 | ||
378 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | 84 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { |
85 | pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n"); | ||
379 | ret = atmel_pcm_preallocate_dma_buffer(pcm, | 86 | ret = atmel_pcm_preallocate_dma_buffer(pcm, |
380 | SNDRV_PCM_STREAM_PLAYBACK); | 87 | SNDRV_PCM_STREAM_PLAYBACK); |
381 | if (ret) | 88 | if (ret) |
@@ -383,8 +90,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
383 | } | 90 | } |
384 | 91 | ||
385 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | 92 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { |
386 | pr_debug("atmel-pcm:" | 93 | pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n"); |
387 | "Allocating PCM capture DMA buffer\n"); | ||
388 | ret = atmel_pcm_preallocate_dma_buffer(pcm, | 94 | ret = atmel_pcm_preallocate_dma_buffer(pcm, |
389 | SNDRV_PCM_STREAM_CAPTURE); | 95 | SNDRV_PCM_STREAM_CAPTURE); |
390 | if (ret) | 96 | if (ret) |
@@ -393,8 +99,9 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
393 | out: | 99 | out: |
394 | return ret; | 100 | return ret; |
395 | } | 101 | } |
102 | EXPORT_SYMBOL_GPL(atmel_pcm_new); | ||
396 | 103 | ||
397 | static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm) | 104 | void atmel_pcm_free(struct snd_pcm *pcm) |
398 | { | 105 | { |
399 | struct snd_pcm_substream *substream; | 106 | struct snd_pcm_substream *substream; |
400 | struct snd_dma_buffer *buf; | 107 | struct snd_dma_buffer *buf; |
@@ -413,89 +120,5 @@ static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm) | |||
413 | buf->area = NULL; | 120 | buf->area = NULL; |
414 | } | 121 | } |
415 | } | 122 | } |
123 | EXPORT_SYMBOL_GPL(atmel_pcm_free); | ||
416 | 124 | ||
417 | #ifdef CONFIG_PM | ||
418 | static int atmel_pcm_suspend(struct snd_soc_dai *dai) | ||
419 | { | ||
420 | struct snd_pcm_runtime *runtime = dai->runtime; | ||
421 | struct atmel_runtime_data *prtd; | ||
422 | struct atmel_pcm_dma_params *params; | ||
423 | |||
424 | if (!runtime) | ||
425 | return 0; | ||
426 | |||
427 | prtd = runtime->private_data; | ||
428 | params = prtd->params; | ||
429 | |||
430 | /* disable the PDC and save the PDC registers */ | ||
431 | |||
432 | ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable); | ||
433 | |||
434 | prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr); | ||
435 | prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr); | ||
436 | prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr); | ||
437 | prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr); | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | static int atmel_pcm_resume(struct snd_soc_dai *dai) | ||
443 | { | ||
444 | struct snd_pcm_runtime *runtime = dai->runtime; | ||
445 | struct atmel_runtime_data *prtd; | ||
446 | struct atmel_pcm_dma_params *params; | ||
447 | |||
448 | if (!runtime) | ||
449 | return 0; | ||
450 | |||
451 | prtd = runtime->private_data; | ||
452 | params = prtd->params; | ||
453 | |||
454 | /* restore the PDC registers and enable the PDC */ | ||
455 | ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save); | ||
456 | ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save); | ||
457 | ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save); | ||
458 | ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save); | ||
459 | |||
460 | ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable); | ||
461 | return 0; | ||
462 | } | ||
463 | #else | ||
464 | #define atmel_pcm_suspend NULL | ||
465 | #define atmel_pcm_resume NULL | ||
466 | #endif | ||
467 | |||
468 | static struct snd_soc_platform_driver atmel_soc_platform = { | ||
469 | .ops = &atmel_pcm_ops, | ||
470 | .pcm_new = atmel_pcm_new, | ||
471 | .pcm_free = atmel_pcm_free_dma_buffers, | ||
472 | .suspend = atmel_pcm_suspend, | ||
473 | .resume = atmel_pcm_resume, | ||
474 | }; | ||
475 | |||
476 | static int __devinit atmel_soc_platform_probe(struct platform_device *pdev) | ||
477 | { | ||
478 | return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform); | ||
479 | } | ||
480 | |||
481 | static int __devexit atmel_soc_platform_remove(struct platform_device *pdev) | ||
482 | { | ||
483 | snd_soc_unregister_platform(&pdev->dev); | ||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static struct platform_driver atmel_pcm_driver = { | ||
488 | .driver = { | ||
489 | .name = "atmel-pcm-audio", | ||
490 | .owner = THIS_MODULE, | ||
491 | }, | ||
492 | |||
493 | .probe = atmel_soc_platform_probe, | ||
494 | .remove = __devexit_p(atmel_soc_platform_remove), | ||
495 | }; | ||
496 | |||
497 | module_platform_driver(atmel_pcm_driver); | ||
498 | |||
499 | MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); | ||
500 | MODULE_DESCRIPTION("Atmel PCM module"); | ||
501 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h index 5e0a95e64329..bb45d20e7250 100644 --- a/sound/soc/atmel/atmel-pcm.h +++ b/sound/soc/atmel/atmel-pcm.h | |||
@@ -36,6 +36,8 @@ | |||
36 | 36 | ||
37 | #include <linux/atmel-ssc.h> | 37 | #include <linux/atmel-ssc.h> |
38 | 38 | ||
39 | #define ATMEL_SSC_DMABUF_SIZE (64 * 1024) | ||
40 | |||
39 | /* | 41 | /* |
40 | * Registers and status bits that are required by the PCM driver. | 42 | * Registers and status bits that are required by the PCM driver. |
41 | */ | 43 | */ |
@@ -50,6 +52,7 @@ struct atmel_pdc_regs { | |||
50 | struct atmel_ssc_mask { | 52 | struct atmel_ssc_mask { |
51 | u32 ssc_enable; /* SSC recv/trans enable */ | 53 | u32 ssc_enable; /* SSC recv/trans enable */ |
52 | u32 ssc_disable; /* SSC recv/trans disable */ | 54 | u32 ssc_disable; /* SSC recv/trans disable */ |
55 | u32 ssc_error; /* SSC error conditions */ | ||
53 | u32 ssc_endx; /* SSC ENDTX or ENDRX */ | 56 | u32 ssc_endx; /* SSC ENDTX or ENDRX */ |
54 | u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */ | 57 | u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */ |
55 | u32 pdc_enable; /* PDC recv/trans enable */ | 58 | u32 pdc_enable; /* PDC recv/trans enable */ |
@@ -80,4 +83,35 @@ struct atmel_pcm_dma_params { | |||
80 | #define ssc_readx(base, reg) (__raw_readl((base) + (reg))) | 83 | #define ssc_readx(base, reg) (__raw_readl((base) + (reg))) |
81 | #define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg)) | 84 | #define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg)) |
82 | 85 | ||
86 | int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd); | ||
87 | void atmel_pcm_free(struct snd_pcm *pcm); | ||
88 | int atmel_pcm_mmap(struct snd_pcm_substream *substream, | ||
89 | struct vm_area_struct *vma); | ||
90 | |||
91 | #ifdef CONFIG_SND_ATMEL_SOC_PDC | ||
92 | int atmel_pcm_pdc_platform_register(struct device *dev); | ||
93 | void atmel_pcm_pdc_platform_unregister(struct device *dev); | ||
94 | #else | ||
95 | static inline int atmel_pcm_pdc_platform_register(struct device *dev) | ||
96 | { | ||
97 | return 0; | ||
98 | } | ||
99 | static inline void atmel_pcm_pdc_platform_unregister(struct device *dev) | ||
100 | { | ||
101 | } | ||
102 | #endif | ||
103 | |||
104 | #ifdef CONFIG_SND_ATMEL_SOC_DMA | ||
105 | int atmel_pcm_dma_platform_register(struct device *dev); | ||
106 | void atmel_pcm_dma_platform_unregister(struct device *dev); | ||
107 | #else | ||
108 | static inline int atmel_pcm_dma_platform_register(struct device *dev) | ||
109 | { | ||
110 | return 0; | ||
111 | } | ||
112 | static inline void atmel_pcm_dma_platform_unregister(struct device *dev) | ||
113 | { | ||
114 | } | ||
115 | #endif | ||
116 | |||
83 | #endif /* _ATMEL_PCM_H */ | 117 | #endif /* _ATMEL_PCM_H */ |
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index 354341ec0f42..1c7663422054 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c | |||
@@ -48,11 +48,7 @@ | |||
48 | #include "atmel_ssc_dai.h" | 48 | #include "atmel_ssc_dai.h" |
49 | 49 | ||
50 | 50 | ||
51 | #if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) | ||
52 | #define NUM_SSC_DEVICES 1 | ||
53 | #else | ||
54 | #define NUM_SSC_DEVICES 3 | 51 | #define NUM_SSC_DEVICES 3 |
55 | #endif | ||
56 | 52 | ||
57 | /* | 53 | /* |
58 | * SSC PDC registers required by the PCM DMA engine. | 54 | * SSC PDC registers required by the PCM DMA engine. |
@@ -107,7 +103,6 @@ static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = { | |||
107 | .pdc = &pdc_rx_reg, | 103 | .pdc = &pdc_rx_reg, |
108 | .mask = &ssc_rx_mask, | 104 | .mask = &ssc_rx_mask, |
109 | } }, | 105 | } }, |
110 | #if NUM_SSC_DEVICES == 3 | ||
111 | {{ | 106 | {{ |
112 | .name = "SSC1 PCM out", | 107 | .name = "SSC1 PCM out", |
113 | .pdc = &pdc_tx_reg, | 108 | .pdc = &pdc_tx_reg, |
@@ -128,7 +123,6 @@ static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = { | |||
128 | .pdc = &pdc_rx_reg, | 123 | .pdc = &pdc_rx_reg, |
129 | .mask = &ssc_rx_mask, | 124 | .mask = &ssc_rx_mask, |
130 | } }, | 125 | } }, |
131 | #endif | ||
132 | }; | 126 | }; |
133 | 127 | ||
134 | 128 | ||
@@ -139,7 +133,6 @@ static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = { | |||
139 | .dir_mask = SSC_DIR_MASK_UNUSED, | 133 | .dir_mask = SSC_DIR_MASK_UNUSED, |
140 | .initialized = 0, | 134 | .initialized = 0, |
141 | }, | 135 | }, |
142 | #if NUM_SSC_DEVICES == 3 | ||
143 | { | 136 | { |
144 | .name = "ssc1", | 137 | .name = "ssc1", |
145 | .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock), | 138 | .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock), |
@@ -152,7 +145,6 @@ static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = { | |||
152 | .dir_mask = SSC_DIR_MASK_UNUSED, | 145 | .dir_mask = SSC_DIR_MASK_UNUSED, |
153 | .initialized = 0, | 146 | .initialized = 0, |
154 | }, | 147 | }, |
155 | #endif | ||
156 | }; | 148 | }; |
157 | 149 | ||
158 | 150 | ||
@@ -690,27 +682,9 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai) | |||
690 | static int atmel_ssc_probe(struct snd_soc_dai *dai) | 682 | static int atmel_ssc_probe(struct snd_soc_dai *dai) |
691 | { | 683 | { |
692 | struct atmel_ssc_info *ssc_p = &ssc_info[dai->id]; | 684 | struct atmel_ssc_info *ssc_p = &ssc_info[dai->id]; |
693 | int ret = 0; | ||
694 | 685 | ||
695 | snd_soc_dai_set_drvdata(dai, ssc_p); | 686 | snd_soc_dai_set_drvdata(dai, ssc_p); |
696 | 687 | ||
697 | /* | ||
698 | * Request SSC device | ||
699 | */ | ||
700 | ssc_p->ssc = ssc_request(dai->id); | ||
701 | if (IS_ERR(ssc_p->ssc)) { | ||
702 | printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id); | ||
703 | ret = PTR_ERR(ssc_p->ssc); | ||
704 | } | ||
705 | |||
706 | return ret; | ||
707 | } | ||
708 | |||
709 | static int atmel_ssc_remove(struct snd_soc_dai *dai) | ||
710 | { | ||
711 | struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai); | ||
712 | |||
713 | ssc_free(ssc_p->ssc); | ||
714 | return 0; | 688 | return 0; |
715 | } | 689 | } |
716 | 690 | ||
@@ -728,30 +702,8 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = { | |||
728 | .set_clkdiv = atmel_ssc_set_dai_clkdiv, | 702 | .set_clkdiv = atmel_ssc_set_dai_clkdiv, |
729 | }; | 703 | }; |
730 | 704 | ||
731 | static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = { | 705 | static struct snd_soc_dai_driver atmel_ssc_dai = { |
732 | { | ||
733 | .name = "atmel-ssc-dai.0", | ||
734 | .probe = atmel_ssc_probe, | ||
735 | .remove = atmel_ssc_remove, | ||
736 | .suspend = atmel_ssc_suspend, | ||
737 | .resume = atmel_ssc_resume, | ||
738 | .playback = { | ||
739 | .channels_min = 1, | ||
740 | .channels_max = 2, | ||
741 | .rates = ATMEL_SSC_RATES, | ||
742 | .formats = ATMEL_SSC_FORMATS,}, | ||
743 | .capture = { | ||
744 | .channels_min = 1, | ||
745 | .channels_max = 2, | ||
746 | .rates = ATMEL_SSC_RATES, | ||
747 | .formats = ATMEL_SSC_FORMATS,}, | ||
748 | .ops = &atmel_ssc_dai_ops, | ||
749 | }, | ||
750 | #if NUM_SSC_DEVICES == 3 | ||
751 | { | ||
752 | .name = "atmel-ssc-dai.1", | ||
753 | .probe = atmel_ssc_probe, | 706 | .probe = atmel_ssc_probe, |
754 | .remove = atmel_ssc_remove, | ||
755 | .suspend = atmel_ssc_suspend, | 707 | .suspend = atmel_ssc_suspend, |
756 | .resume = atmel_ssc_resume, | 708 | .resume = atmel_ssc_resume, |
757 | .playback = { | 709 | .playback = { |
@@ -765,50 +717,50 @@ static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = { | |||
765 | .rates = ATMEL_SSC_RATES, | 717 | .rates = ATMEL_SSC_RATES, |
766 | .formats = ATMEL_SSC_FORMATS,}, | 718 | .formats = ATMEL_SSC_FORMATS,}, |
767 | .ops = &atmel_ssc_dai_ops, | 719 | .ops = &atmel_ssc_dai_ops, |
768 | }, | ||
769 | { | ||
770 | .name = "atmel-ssc-dai.2", | ||
771 | .probe = atmel_ssc_probe, | ||
772 | .remove = atmel_ssc_remove, | ||
773 | .suspend = atmel_ssc_suspend, | ||
774 | .resume = atmel_ssc_resume, | ||
775 | .playback = { | ||
776 | .channels_min = 1, | ||
777 | .channels_max = 2, | ||
778 | .rates = ATMEL_SSC_RATES, | ||
779 | .formats = ATMEL_SSC_FORMATS,}, | ||
780 | .capture = { | ||
781 | .channels_min = 1, | ||
782 | .channels_max = 2, | ||
783 | .rates = ATMEL_SSC_RATES, | ||
784 | .formats = ATMEL_SSC_FORMATS,}, | ||
785 | .ops = &atmel_ssc_dai_ops, | ||
786 | }, | ||
787 | #endif | ||
788 | }; | 720 | }; |
789 | 721 | ||
790 | static __devinit int asoc_ssc_probe(struct platform_device *pdev) | 722 | static int asoc_ssc_init(struct device *dev) |
791 | { | 723 | { |
792 | BUG_ON(pdev->id < 0); | 724 | struct platform_device *pdev = to_platform_device(dev); |
793 | BUG_ON(pdev->id >= ARRAY_SIZE(atmel_ssc_dai)); | 725 | struct ssc_device *ssc = platform_get_drvdata(pdev); |
794 | return snd_soc_register_dai(&pdev->dev, &atmel_ssc_dai[pdev->id]); | 726 | int ret; |
795 | } | 727 | |
728 | ret = snd_soc_register_dai(dev, &atmel_ssc_dai); | ||
729 | if (ret) { | ||
730 | dev_err(dev, "Could not register DAI: %d\n", ret); | ||
731 | goto err; | ||
732 | } | ||
733 | |||
734 | if (ssc->pdata->use_dma) | ||
735 | ret = atmel_pcm_dma_platform_register(dev); | ||
736 | else | ||
737 | ret = atmel_pcm_pdc_platform_register(dev); | ||
738 | |||
739 | if (ret) { | ||
740 | dev_err(dev, "Could not register PCM: %d\n", ret); | ||
741 | goto err_unregister_dai; | ||
742 | }; | ||
796 | 743 | ||
797 | static int __devexit asoc_ssc_remove(struct platform_device *pdev) | ||
798 | { | ||
799 | snd_soc_unregister_dai(&pdev->dev); | ||
800 | return 0; | 744 | return 0; |
745 | |||
746 | err_unregister_dai: | ||
747 | snd_soc_unregister_dai(dev); | ||
748 | err: | ||
749 | return ret; | ||
801 | } | 750 | } |
802 | 751 | ||
803 | static struct platform_driver asoc_ssc_driver = { | 752 | static void asoc_ssc_exit(struct device *dev) |
804 | .driver = { | 753 | { |
805 | .name = "atmel-ssc-dai", | 754 | struct platform_device *pdev = to_platform_device(dev); |
806 | .owner = THIS_MODULE, | 755 | struct ssc_device *ssc = platform_get_drvdata(pdev); |
807 | }, | ||
808 | 756 | ||
809 | .probe = asoc_ssc_probe, | 757 | if (ssc->pdata->use_dma) |
810 | .remove = __devexit_p(asoc_ssc_remove), | 758 | atmel_pcm_dma_platform_unregister(dev); |
811 | }; | 759 | else |
760 | atmel_pcm_pdc_platform_unregister(dev); | ||
761 | |||
762 | snd_soc_unregister_dai(dev); | ||
763 | } | ||
812 | 764 | ||
813 | /** | 765 | /** |
814 | * atmel_ssc_set_audio - Allocate the specified SSC for audio use. | 766 | * atmel_ssc_set_audio - Allocate the specified SSC for audio use. |
@@ -816,50 +768,32 @@ static struct platform_driver asoc_ssc_driver = { | |||
816 | int atmel_ssc_set_audio(int ssc_id) | 768 | int atmel_ssc_set_audio(int ssc_id) |
817 | { | 769 | { |
818 | struct ssc_device *ssc; | 770 | struct ssc_device *ssc; |
819 | static struct platform_device *dma_pdev; | ||
820 | struct platform_device *ssc_pdev; | ||
821 | int ret; | 771 | int ret; |
822 | 772 | ||
823 | if (ssc_id < 0 || ssc_id >= ARRAY_SIZE(atmel_ssc_dai)) | ||
824 | return -EINVAL; | ||
825 | |||
826 | /* Allocate a dummy device for DMA if we don't have one already */ | ||
827 | if (!dma_pdev) { | ||
828 | dma_pdev = platform_device_alloc("atmel-pcm-audio", -1); | ||
829 | if (!dma_pdev) | ||
830 | return -ENOMEM; | ||
831 | |||
832 | ret = platform_device_add(dma_pdev); | ||
833 | if (ret < 0) { | ||
834 | platform_device_put(dma_pdev); | ||
835 | dma_pdev = NULL; | ||
836 | return ret; | ||
837 | } | ||
838 | } | ||
839 | |||
840 | ssc_pdev = platform_device_alloc("atmel-ssc-dai", ssc_id); | ||
841 | if (!ssc_pdev) | ||
842 | return -ENOMEM; | ||
843 | |||
844 | /* If we can grab the SSC briefly to parent the DAI device off it */ | 773 | /* If we can grab the SSC briefly to parent the DAI device off it */ |
845 | ssc = ssc_request(ssc_id); | 774 | ssc = ssc_request(ssc_id); |
846 | if (IS_ERR(ssc)) | 775 | if (IS_ERR(ssc)) { |
847 | pr_warn("Unable to parent ASoC SSC DAI on SSC: %ld\n", | 776 | pr_err("Unable to parent ASoC SSC DAI on SSC: %ld\n", |
848 | PTR_ERR(ssc)); | 777 | PTR_ERR(ssc)); |
849 | else { | 778 | return PTR_ERR(ssc); |
850 | ssc_pdev->dev.parent = &(ssc->pdev->dev); | 779 | } else { |
851 | ssc_free(ssc); | 780 | ssc_info[ssc_id].ssc = ssc; |
852 | } | 781 | } |
853 | 782 | ||
854 | ret = platform_device_add(ssc_pdev); | 783 | ret = asoc_ssc_init(&ssc->pdev->dev); |
855 | if (ret < 0) | ||
856 | platform_device_put(ssc_pdev); | ||
857 | 784 | ||
858 | return ret; | 785 | return ret; |
859 | } | 786 | } |
860 | EXPORT_SYMBOL_GPL(atmel_ssc_set_audio); | 787 | EXPORT_SYMBOL_GPL(atmel_ssc_set_audio); |
861 | 788 | ||
862 | module_platform_driver(asoc_ssc_driver); | 789 | void atmel_ssc_put_audio(int ssc_id) |
790 | { | ||
791 | struct ssc_device *ssc = ssc_info[ssc_id].ssc; | ||
792 | |||
793 | ssc_free(ssc); | ||
794 | asoc_ssc_exit(&ssc->pdev->dev); | ||
795 | } | ||
796 | EXPORT_SYMBOL_GPL(atmel_ssc_put_audio); | ||
863 | 797 | ||
864 | /* Module information */ | 798 | /* Module information */ |
865 | MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com"); | 799 | MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com"); |
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h index 5d4f0f9b4d9a..b1f08d511495 100644 --- a/sound/soc/atmel/atmel_ssc_dai.h +++ b/sound/soc/atmel/atmel_ssc_dai.h | |||
@@ -117,6 +117,7 @@ struct atmel_ssc_info { | |||
117 | struct atmel_ssc_state ssc_state; | 117 | struct atmel_ssc_state ssc_state; |
118 | }; | 118 | }; |
119 | 119 | ||
120 | int atmel_ssc_set_audio(int ssc); | 120 | int atmel_ssc_set_audio(int ssc_id); |
121 | void atmel_ssc_put_audio(int ssc_id); | ||
121 | 122 | ||
122 | #endif /* _AT91_SSC_DAI_H */ | 123 | #endif /* _AT91_SSC_DAI_H */ |
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index c88351488f45..0744610e53dd 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
39 | #include <linux/i2c.h> | 39 | #include <linux/i2c.h> |
40 | 40 | ||
41 | #include <linux/pinctrl/consumer.h> | ||
42 | |||
41 | #include <linux/atmel-ssc.h> | 43 | #include <linux/atmel-ssc.h> |
42 | 44 | ||
43 | #include <sound/core.h> | 45 | #include <sound/core.h> |
@@ -179,10 +181,10 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) | |||
179 | static struct snd_soc_dai_link at91sam9g20ek_dai = { | 181 | static struct snd_soc_dai_link at91sam9g20ek_dai = { |
180 | .name = "WM8731", | 182 | .name = "WM8731", |
181 | .stream_name = "WM8731 PCM", | 183 | .stream_name = "WM8731 PCM", |
182 | .cpu_dai_name = "atmel-ssc-dai.0", | 184 | .cpu_dai_name = "at91rm9200_ssc.0", |
183 | .codec_dai_name = "wm8731-hifi", | 185 | .codec_dai_name = "wm8731-hifi", |
184 | .init = at91sam9g20ek_wm8731_init, | 186 | .init = at91sam9g20ek_wm8731_init, |
185 | .platform_name = "atmel-pcm-audio", | 187 | .platform_name = "at91rm9200_ssc.0", |
186 | .codec_name = "wm8731.0-001b", | 188 | .codec_name = "wm8731.0-001b", |
187 | .ops = &at91sam9g20ek_ops, | 189 | .ops = &at91sam9g20ek_ops, |
188 | }; | 190 | }; |
@@ -195,20 +197,31 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = { | |||
195 | .set_bias_level = at91sam9g20ek_set_bias_level, | 197 | .set_bias_level = at91sam9g20ek_set_bias_level, |
196 | }; | 198 | }; |
197 | 199 | ||
198 | static struct platform_device *at91sam9g20ek_snd_device; | 200 | static int __devinit at91sam9g20ek_audio_probe(struct platform_device *pdev) |
199 | |||
200 | static int __init at91sam9g20ek_init(void) | ||
201 | { | 201 | { |
202 | struct device_node *np = pdev->dev.of_node; | ||
203 | struct device_node *codec_np, *cpu_np; | ||
202 | struct clk *pllb; | 204 | struct clk *pllb; |
205 | struct snd_soc_card *card = &snd_soc_at91sam9g20ek; | ||
206 | struct pinctrl *pinctrl; | ||
203 | int ret; | 207 | int ret; |
204 | 208 | ||
205 | if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc())) | 209 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); |
206 | return -ENODEV; | 210 | if (IS_ERR(pinctrl)) { |
211 | dev_err(&pdev->dev, "Failed to request pinctrl for mck\n"); | ||
212 | return PTR_ERR(pinctrl); | ||
213 | } | ||
214 | |||
215 | if (!np) { | ||
216 | if (!(machine_is_at91sam9g20ek() || | ||
217 | machine_is_at91sam9g20ek_2mmc())) | ||
218 | return -ENODEV; | ||
219 | } | ||
207 | 220 | ||
208 | ret = atmel_ssc_set_audio(0); | 221 | ret = atmel_ssc_set_audio(0); |
209 | if (ret != 0) { | 222 | if (ret) { |
210 | pr_err("Failed to set SSC 0 for audio: %d\n", ret); | 223 | dev_err(&pdev->dev, "ssc channel is not valid\n"); |
211 | return ret; | 224 | return -EINVAL; |
212 | } | 225 | } |
213 | 226 | ||
214 | /* | 227 | /* |
@@ -236,45 +249,92 @@ static int __init at91sam9g20ek_init(void) | |||
236 | 249 | ||
237 | clk_set_rate(mclk, MCLK_RATE); | 250 | clk_set_rate(mclk, MCLK_RATE); |
238 | 251 | ||
239 | at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1); | 252 | card->dev = &pdev->dev; |
240 | if (!at91sam9g20ek_snd_device) { | 253 | |
241 | printk(KERN_ERR "ASoC: Platform device allocation failed\n"); | 254 | /* Parse device node info */ |
242 | ret = -ENOMEM; | 255 | if (np) { |
243 | goto err_mclk; | 256 | ret = snd_soc_of_parse_card_name(card, "atmel,model"); |
257 | if (ret) | ||
258 | goto err; | ||
259 | |||
260 | ret = snd_soc_of_parse_audio_routing(card, | ||
261 | "atmel,audio-routing"); | ||
262 | if (ret) | ||
263 | goto err; | ||
264 | |||
265 | /* Parse codec info */ | ||
266 | at91sam9g20ek_dai.codec_name = NULL; | ||
267 | codec_np = of_parse_phandle(np, "atmel,audio-codec", 0); | ||
268 | if (!codec_np) { | ||
269 | dev_err(&pdev->dev, "codec info missing\n"); | ||
270 | return -EINVAL; | ||
271 | } | ||
272 | at91sam9g20ek_dai.codec_of_node = codec_np; | ||
273 | |||
274 | /* Parse dai and platform info */ | ||
275 | at91sam9g20ek_dai.cpu_dai_name = NULL; | ||
276 | at91sam9g20ek_dai.platform_name = NULL; | ||
277 | cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0); | ||
278 | if (!cpu_np) { | ||
279 | dev_err(&pdev->dev, "dai and pcm info missing\n"); | ||
280 | return -EINVAL; | ||
281 | } | ||
282 | at91sam9g20ek_dai.cpu_of_node = cpu_np; | ||
283 | at91sam9g20ek_dai.platform_of_node = cpu_np; | ||
284 | |||
285 | of_node_put(codec_np); | ||
286 | of_node_put(cpu_np); | ||
244 | } | 287 | } |
245 | 288 | ||
246 | platform_set_drvdata(at91sam9g20ek_snd_device, | 289 | ret = snd_soc_register_card(card); |
247 | &snd_soc_at91sam9g20ek); | ||
248 | |||
249 | ret = platform_device_add(at91sam9g20ek_snd_device); | ||
250 | if (ret) { | 290 | if (ret) { |
251 | printk(KERN_ERR "ASoC: Platform device allocation failed\n"); | 291 | printk(KERN_ERR "ASoC: snd_soc_register_card() failed\n"); |
252 | goto err_device_add; | ||
253 | } | 292 | } |
254 | 293 | ||
255 | return ret; | 294 | return ret; |
256 | 295 | ||
257 | err_device_add: | ||
258 | platform_device_put(at91sam9g20ek_snd_device); | ||
259 | err_mclk: | 296 | err_mclk: |
260 | clk_put(mclk); | 297 | clk_put(mclk); |
261 | mclk = NULL; | 298 | mclk = NULL; |
262 | err: | 299 | err: |
300 | atmel_ssc_put_audio(0); | ||
263 | return ret; | 301 | return ret; |
264 | } | 302 | } |
265 | 303 | ||
266 | static void __exit at91sam9g20ek_exit(void) | 304 | static int __devexit at91sam9g20ek_audio_remove(struct platform_device *pdev) |
267 | { | 305 | { |
268 | platform_device_unregister(at91sam9g20ek_snd_device); | 306 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
269 | at91sam9g20ek_snd_device = NULL; | 307 | |
308 | atmel_ssc_put_audio(0); | ||
309 | snd_soc_unregister_card(card); | ||
270 | clk_put(mclk); | 310 | clk_put(mclk); |
271 | mclk = NULL; | 311 | mclk = NULL; |
312 | |||
313 | return 0; | ||
272 | } | 314 | } |
273 | 315 | ||
274 | module_init(at91sam9g20ek_init); | 316 | #ifdef CONFIG_OF |
275 | module_exit(at91sam9g20ek_exit); | 317 | static const struct of_device_id at91sam9g20ek_wm8731_dt_ids[] = { |
318 | { .compatible = "atmel,at91sam9g20ek-wm8731-audio", }, | ||
319 | { } | ||
320 | }; | ||
321 | MODULE_DEVICE_TABLE(of, at91sam9g20ek_wm8731_dt_ids); | ||
322 | #endif | ||
323 | |||
324 | static struct platform_driver at91sam9g20ek_audio_driver = { | ||
325 | .driver = { | ||
326 | .name = "at91sam9g20ek-audio", | ||
327 | .owner = THIS_MODULE, | ||
328 | .of_match_table = of_match_ptr(at91sam9g20ek_wm8731_dt_ids), | ||
329 | }, | ||
330 | .probe = at91sam9g20ek_audio_probe, | ||
331 | .remove = __devexit_p(at91sam9g20ek_audio_remove), | ||
332 | }; | ||
333 | |||
334 | module_platform_driver(at91sam9g20ek_audio_driver); | ||
276 | 335 | ||
277 | /* Module information */ | 336 | /* Module information */ |
278 | MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); | 337 | MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); |
279 | MODULE_DESCRIPTION("ALSA SoC AT91SAM9G20EK_WM8731"); | 338 | MODULE_DESCRIPTION("ALSA SoC AT91SAM9G20EK_WM8731"); |
339 | MODULE_ALIAS("platform:at91sam9g20ek-audio"); | ||
280 | MODULE_LICENSE("GPL"); | 340 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index b92759a39361..3a847828932a 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -44,6 +44,7 @@ config SND_SOC_ALL_CODECS | |||
44 | select SND_SOC_LM4857 if I2C | 44 | select SND_SOC_LM4857 if I2C |
45 | select SND_SOC_LM49453 if I2C | 45 | select SND_SOC_LM49453 if I2C |
46 | select SND_SOC_MAX98088 if I2C | 46 | select SND_SOC_MAX98088 if I2C |
47 | select SND_SOC_MAX98090 if I2C | ||
47 | select SND_SOC_MAX98095 if I2C | 48 | select SND_SOC_MAX98095 if I2C |
48 | select SND_SOC_MAX9850 if I2C | 49 | select SND_SOC_MAX9850 if I2C |
49 | select SND_SOC_MAX9768 if I2C | 50 | select SND_SOC_MAX9768 if I2C |
@@ -54,6 +55,7 @@ config SND_SOC_ALL_CODECS | |||
54 | select SND_SOC_PCM3008 | 55 | select SND_SOC_PCM3008 |
55 | select SND_SOC_RT5631 if I2C | 56 | select SND_SOC_RT5631 if I2C |
56 | select SND_SOC_SGTL5000 if I2C | 57 | select SND_SOC_SGTL5000 if I2C |
58 | select SND_SOC_SI476X if MFD_SI476X_CORE | ||
57 | select SND_SOC_SN95031 if INTEL_SCU_IPC | 59 | select SND_SOC_SN95031 if INTEL_SCU_IPC |
58 | select SND_SOC_SPDIF | 60 | select SND_SOC_SPDIF |
59 | select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI | 61 | select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI |
@@ -146,6 +148,13 @@ config SND_SOC_WM_HUBS | |||
146 | default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y | 148 | default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y |
147 | default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m | 149 | default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m |
148 | 150 | ||
151 | config SND_SOC_WM_ADSP | ||
152 | tristate | ||
153 | default y if SND_SOC_WM5102=y | ||
154 | default y if SND_SOC_WM2200=y | ||
155 | default m if SND_SOC_WM5102=m | ||
156 | default m if SND_SOC_WM2200=m | ||
157 | |||
149 | config SND_SOC_AB8500_CODEC | 158 | config SND_SOC_AB8500_CODEC |
150 | tristate | 159 | tristate |
151 | 160 | ||
@@ -229,6 +238,7 @@ config SND_SOC_CX20442 | |||
229 | tristate | 238 | tristate |
230 | 239 | ||
231 | config SND_SOC_JZ4740_CODEC | 240 | config SND_SOC_JZ4740_CODEC |
241 | select REGMAP_MMIO | ||
232 | tristate | 242 | tristate |
233 | 243 | ||
234 | config SND_SOC_L3 | 244 | config SND_SOC_L3 |
@@ -258,6 +268,9 @@ config SND_SOC_LM49453 | |||
258 | config SND_SOC_MAX98088 | 268 | config SND_SOC_MAX98088 |
259 | tristate | 269 | tristate |
260 | 270 | ||
271 | config SND_SOC_MAX98090 | ||
272 | tristate | ||
273 | |||
261 | config SND_SOC_MAX98095 | 274 | config SND_SOC_MAX98095 |
262 | tristate | 275 | tristate |
263 | 276 | ||
@@ -277,6 +290,9 @@ config SND_SOC_RT5631 | |||
277 | config SND_SOC_SGTL5000 | 290 | config SND_SOC_SGTL5000 |
278 | tristate | 291 | tristate |
279 | 292 | ||
293 | config SND_SOC_SI476X | ||
294 | tristate | ||
295 | |||
280 | config SND_SOC_SIGMADSP | 296 | config SND_SOC_SIGMADSP |
281 | tristate | 297 | tristate |
282 | select CRC32 | 298 | select CRC32 |
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 9bd4d95aab4f..f6e8e36cceb7 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -34,6 +34,7 @@ snd-soc-lm4857-objs := lm4857.o | |||
34 | snd-soc-lm49453-objs := lm49453.o | 34 | snd-soc-lm49453-objs := lm49453.o |
35 | snd-soc-max9768-objs := max9768.o | 35 | snd-soc-max9768-objs := max9768.o |
36 | snd-soc-max98088-objs := max98088.o | 36 | snd-soc-max98088-objs := max98088.o |
37 | snd-soc-max98090-objs := max98090.o | ||
37 | snd-soc-max98095-objs := max98095.o | 38 | snd-soc-max98095-objs := max98095.o |
38 | snd-soc-max9850-objs := max9850.o | 39 | snd-soc-max9850-objs := max9850.o |
39 | snd-soc-mc13783-objs := mc13783.o | 40 | snd-soc-mc13783-objs := mc13783.o |
@@ -45,6 +46,7 @@ snd-soc-sgtl5000-objs := sgtl5000.o | |||
45 | snd-soc-alc5623-objs := alc5623.o | 46 | snd-soc-alc5623-objs := alc5623.o |
46 | snd-soc-alc5632-objs := alc5632.o | 47 | snd-soc-alc5632-objs := alc5632.o |
47 | snd-soc-sigmadsp-objs := sigmadsp.o | 48 | snd-soc-sigmadsp-objs := sigmadsp.o |
49 | snd-soc-si476x-objs := si476x.o | ||
48 | snd-soc-sn95031-objs := sn95031.o | 50 | snd-soc-sn95031-objs := sn95031.o |
49 | snd-soc-spdif-tx-objs := spdif_transciever.o | 51 | snd-soc-spdif-tx-objs := spdif_transciever.o |
50 | snd-soc-spdif-rx-objs := spdif_receiver.o | 52 | snd-soc-spdif-rx-objs := spdif_receiver.o |
@@ -62,6 +64,7 @@ snd-soc-twl6040-objs := twl6040.o | |||
62 | snd-soc-uda134x-objs := uda134x.o | 64 | snd-soc-uda134x-objs := uda134x.o |
63 | snd-soc-uda1380-objs := uda1380.o | 65 | snd-soc-uda1380-objs := uda1380.o |
64 | snd-soc-wl1273-objs := wl1273.o | 66 | snd-soc-wl1273-objs := wl1273.o |
67 | snd-soc-wm-adsp-objs := wm_adsp.o | ||
65 | snd-soc-wm0010-objs := wm0010.o | 68 | snd-soc-wm0010-objs := wm0010.o |
66 | snd-soc-wm1250-ev1-objs := wm1250-ev1.o | 69 | snd-soc-wm1250-ev1-objs := wm1250-ev1.o |
67 | snd-soc-wm2000-objs := wm2000.o | 70 | snd-soc-wm2000-objs := wm2000.o |
@@ -155,6 +158,7 @@ obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o | |||
155 | obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o | 158 | obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o |
156 | obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o | 159 | obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o |
157 | obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o | 160 | obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o |
161 | obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o | ||
158 | obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o | 162 | obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o |
159 | obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o | 163 | obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o |
160 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o | 164 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o |
@@ -164,6 +168,7 @@ obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o | |||
164 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o | 168 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o |
165 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o | 169 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o |
166 | obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o | 170 | obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o |
171 | obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o | ||
167 | obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o | 172 | obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o |
168 | obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o | 173 | obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o |
169 | obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o | 174 | obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o |
@@ -229,6 +234,7 @@ obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o | |||
229 | obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o | 234 | obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o |
230 | obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o | 235 | obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o |
231 | obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o | 236 | obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o |
237 | obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o | ||
232 | obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o | 238 | obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o |
233 | 239 | ||
234 | # Amp | 240 | # Amp |
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index af547490b4f7..4d96090db662 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -2356,7 +2356,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai, | |||
2356 | return 0; | 2356 | return 0; |
2357 | } | 2357 | } |
2358 | 2358 | ||
2359 | struct snd_soc_dai_driver ab8500_codec_dai[] = { | 2359 | static struct snd_soc_dai_driver ab8500_codec_dai[] = { |
2360 | { | 2360 | { |
2361 | .name = "ab8500-codec-dai.0", | 2361 | .name = "ab8500-codec-dai.0", |
2362 | .id = 0, | 2362 | .id = 0, |
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index 31d4483245d0..4b11b82b2273 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <sound/soc.h> | 15 | #include <sound/soc.h> |
16 | #include <sound/initval.h> | 16 | #include <sound/initval.h> |
17 | #include <linux/spi/spi.h> | 17 | #include <linux/spi/spi.h> |
18 | #include <linux/of_device.h> | ||
19 | #include <linux/of_gpio.h> | ||
18 | #include <sound/asoundef.h> | 20 | #include <sound/asoundef.h> |
19 | 21 | ||
20 | /* AK4104 registers addresses */ | 22 | /* AK4104 registers addresses */ |
@@ -98,14 +100,32 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, | |||
98 | val = 0; | 100 | val = 0; |
99 | 101 | ||
100 | switch (params_rate(params)) { | 102 | switch (params_rate(params)) { |
103 | case 22050: | ||
104 | val |= IEC958_AES3_CON_FS_22050; | ||
105 | break; | ||
106 | case 24000: | ||
107 | val |= IEC958_AES3_CON_FS_24000; | ||
108 | break; | ||
109 | case 32000: | ||
110 | val |= IEC958_AES3_CON_FS_32000; | ||
111 | break; | ||
101 | case 44100: | 112 | case 44100: |
102 | val |= IEC958_AES3_CON_FS_44100; | 113 | val |= IEC958_AES3_CON_FS_44100; |
103 | break; | 114 | break; |
104 | case 48000: | 115 | case 48000: |
105 | val |= IEC958_AES3_CON_FS_48000; | 116 | val |= IEC958_AES3_CON_FS_48000; |
106 | break; | 117 | break; |
107 | case 32000: | 118 | case 88200: |
108 | val |= IEC958_AES3_CON_FS_32000; | 119 | val |= IEC958_AES3_CON_FS_88200; |
120 | break; | ||
121 | case 96000: | ||
122 | val |= IEC958_AES3_CON_FS_96000; | ||
123 | break; | ||
124 | case 176400: | ||
125 | val |= IEC958_AES3_CON_FS_176400; | ||
126 | break; | ||
127 | case 192000: | ||
128 | val |= IEC958_AES3_CON_FS_192000; | ||
109 | break; | 129 | break; |
110 | default: | 130 | default: |
111 | dev_err(codec->dev, "unsupported sampling rate\n"); | 131 | dev_err(codec->dev, "unsupported sampling rate\n"); |
@@ -186,6 +206,7 @@ static const struct regmap_config ak4104_regmap = { | |||
186 | 206 | ||
187 | static int ak4104_spi_probe(struct spi_device *spi) | 207 | static int ak4104_spi_probe(struct spi_device *spi) |
188 | { | 208 | { |
209 | struct device_node *np = spi->dev.of_node; | ||
189 | struct ak4104_private *ak4104; | 210 | struct ak4104_private *ak4104; |
190 | unsigned int val; | 211 | unsigned int val; |
191 | int ret; | 212 | int ret; |
@@ -201,49 +222,59 @@ static int ak4104_spi_probe(struct spi_device *spi) | |||
201 | if (ak4104 == NULL) | 222 | if (ak4104 == NULL) |
202 | return -ENOMEM; | 223 | return -ENOMEM; |
203 | 224 | ||
204 | ak4104->regmap = regmap_init_spi(spi, &ak4104_regmap); | 225 | ak4104->regmap = devm_regmap_init_spi(spi, &ak4104_regmap); |
205 | if (IS_ERR(ak4104->regmap)) { | 226 | if (IS_ERR(ak4104->regmap)) { |
206 | ret = PTR_ERR(ak4104->regmap); | 227 | ret = PTR_ERR(ak4104->regmap); |
207 | return ret; | 228 | return ret; |
208 | } | 229 | } |
209 | 230 | ||
231 | if (np) { | ||
232 | enum of_gpio_flags flags; | ||
233 | int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); | ||
234 | |||
235 | if (gpio_is_valid(gpio)) { | ||
236 | ret = devm_gpio_request_one(&spi->dev, gpio, | ||
237 | flags & OF_GPIO_ACTIVE_LOW ? | ||
238 | GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, | ||
239 | "ak4104 reset"); | ||
240 | if (ret < 0) | ||
241 | return ret; | ||
242 | } | ||
243 | } | ||
244 | |||
210 | /* read the 'reserved' register - according to the datasheet, it | 245 | /* read the 'reserved' register - according to the datasheet, it |
211 | * should contain 0x5b. Not a good way to verify the presence of | 246 | * should contain 0x5b. Not a good way to verify the presence of |
212 | * the device, but there is no hardware ID register. */ | 247 | * the device, but there is no hardware ID register. */ |
213 | ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val); | 248 | ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val); |
214 | if (ret != 0) | 249 | if (ret != 0) |
215 | goto err; | 250 | return ret; |
216 | if (val != AK4104_RESERVED_VAL) { | 251 | if (val != AK4104_RESERVED_VAL) |
217 | ret = -ENODEV; | 252 | return -ENODEV; |
218 | goto err; | ||
219 | } | ||
220 | 253 | ||
221 | spi_set_drvdata(spi, ak4104); | 254 | spi_set_drvdata(spi, ak4104); |
222 | 255 | ||
223 | ret = snd_soc_register_codec(&spi->dev, | 256 | ret = snd_soc_register_codec(&spi->dev, |
224 | &soc_codec_device_ak4104, &ak4104_dai, 1); | 257 | &soc_codec_device_ak4104, &ak4104_dai, 1); |
225 | if (ret != 0) | ||
226 | goto err; | ||
227 | |||
228 | return 0; | ||
229 | |||
230 | err: | ||
231 | regmap_exit(ak4104->regmap); | ||
232 | return ret; | 258 | return ret; |
233 | } | 259 | } |
234 | 260 | ||
235 | static int __devexit ak4104_spi_remove(struct spi_device *spi) | 261 | static int __devexit ak4104_spi_remove(struct spi_device *spi) |
236 | { | 262 | { |
237 | struct ak4104_private *ak4101 = spi_get_drvdata(spi); | ||
238 | regmap_exit(ak4101->regmap); | ||
239 | snd_soc_unregister_codec(&spi->dev); | 263 | snd_soc_unregister_codec(&spi->dev); |
240 | return 0; | 264 | return 0; |
241 | } | 265 | } |
242 | 266 | ||
267 | static const struct of_device_id ak4104_of_match[] = { | ||
268 | { .compatible = "asahi-kasei,ak4104", }, | ||
269 | { } | ||
270 | }; | ||
271 | MODULE_DEVICE_TABLE(of, ak4104_of_match); | ||
272 | |||
243 | static struct spi_driver ak4104_spi_driver = { | 273 | static struct spi_driver ak4104_spi_driver = { |
244 | .driver = { | 274 | .driver = { |
245 | .name = DRV_NAME, | 275 | .name = DRV_NAME, |
246 | .owner = THIS_MODULE, | 276 | .owner = THIS_MODULE, |
277 | .of_match_table = ak4104_of_match, | ||
247 | }, | 278 | }, |
248 | .probe = ak4104_spi_probe, | 279 | .probe = ak4104_spi_probe, |
249 | .remove = __devexit_p(ak4104_spi_remove), | 280 | .remove = __devexit_p(ak4104_spi_remove), |
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 618fdc30f73e..fc5581063b2d 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c | |||
@@ -447,7 +447,7 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, | |||
447 | if (ak4535 == NULL) | 447 | if (ak4535 == NULL) |
448 | return -ENOMEM; | 448 | return -ENOMEM; |
449 | 449 | ||
450 | ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap); | 450 | ak4535->regmap = devm_regmap_init_i2c(i2c, &ak4535_regmap); |
451 | if (IS_ERR(ak4535->regmap)) { | 451 | if (IS_ERR(ak4535->regmap)) { |
452 | ret = PTR_ERR(ak4535->regmap); | 452 | ret = PTR_ERR(ak4535->regmap); |
453 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); | 453 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); |
@@ -458,18 +458,13 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, | |||
458 | 458 | ||
459 | ret = snd_soc_register_codec(&i2c->dev, | 459 | ret = snd_soc_register_codec(&i2c->dev, |
460 | &soc_codec_dev_ak4535, &ak4535_dai, 1); | 460 | &soc_codec_dev_ak4535, &ak4535_dai, 1); |
461 | if (ret != 0) | ||
462 | regmap_exit(ak4535->regmap); | ||
463 | 461 | ||
464 | return ret; | 462 | return ret; |
465 | } | 463 | } |
466 | 464 | ||
467 | static __devexit int ak4535_i2c_remove(struct i2c_client *client) | 465 | static __devexit int ak4535_i2c_remove(struct i2c_client *client) |
468 | { | 466 | { |
469 | struct ak4535_priv *ak4535 = i2c_get_clientdata(client); | ||
470 | |||
471 | snd_soc_unregister_codec(&client->dev); | 467 | snd_soc_unregister_codec(&client->dev); |
472 | regmap_exit(ak4535->regmap); | ||
473 | return 0; | 468 | return 0; |
474 | } | 469 | } |
475 | 470 | ||
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index b3e24f289421..546466abb77f 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
@@ -194,12 +194,6 @@ static const struct snd_soc_dapm_route ak4642_intercon[] = { | |||
194 | {"LINEOUT Mixer", "DACL", "DAC"}, | 194 | {"LINEOUT Mixer", "DACL", "DAC"}, |
195 | }; | 195 | }; |
196 | 196 | ||
197 | /* codec private data */ | ||
198 | struct ak4642_priv { | ||
199 | unsigned int sysclk; | ||
200 | enum snd_soc_control_type control_type; | ||
201 | }; | ||
202 | |||
203 | /* | 197 | /* |
204 | * ak4642 register cache | 198 | * ak4642 register cache |
205 | */ | 199 | */ |
@@ -468,10 +462,9 @@ static int ak4642_resume(struct snd_soc_codec *codec) | |||
468 | 462 | ||
469 | static int ak4642_probe(struct snd_soc_codec *codec) | 463 | static int ak4642_probe(struct snd_soc_codec *codec) |
470 | { | 464 | { |
471 | struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec); | ||
472 | int ret; | 465 | int ret; |
473 | 466 | ||
474 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type); | 467 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); |
475 | if (ret < 0) { | 468 | if (ret < 0) { |
476 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 469 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
477 | return ret; | 470 | return ret; |
@@ -523,21 +516,9 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4648 = { | |||
523 | static __devinit int ak4642_i2c_probe(struct i2c_client *i2c, | 516 | static __devinit int ak4642_i2c_probe(struct i2c_client *i2c, |
524 | const struct i2c_device_id *id) | 517 | const struct i2c_device_id *id) |
525 | { | 518 | { |
526 | struct ak4642_priv *ak4642; | 519 | return snd_soc_register_codec(&i2c->dev, |
527 | int ret; | ||
528 | |||
529 | ak4642 = devm_kzalloc(&i2c->dev, sizeof(struct ak4642_priv), | ||
530 | GFP_KERNEL); | ||
531 | if (!ak4642) | ||
532 | return -ENOMEM; | ||
533 | |||
534 | i2c_set_clientdata(i2c, ak4642); | ||
535 | ak4642->control_type = SND_SOC_I2C; | ||
536 | |||
537 | ret = snd_soc_register_codec(&i2c->dev, | ||
538 | (struct snd_soc_codec_driver *)id->driver_data, | 520 | (struct snd_soc_codec_driver *)id->driver_data, |
539 | &ak4642_dai, 1); | 521 | &ak4642_dai, 1); |
540 | return ret; | ||
541 | } | 522 | } |
542 | 523 | ||
543 | static __devexit int ak4642_i2c_remove(struct i2c_client *client) | 524 | static __devexit int ak4642_i2c_remove(struct i2c_client *client) |
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index c03b65af3059..adf397b9d0e6 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -226,6 +226,31 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values); | |||
226 | const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); | 226 | const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); |
227 | EXPORT_SYMBOL_GPL(arizona_mixer_tlv); | 227 | EXPORT_SYMBOL_GPL(arizona_mixer_tlv); |
228 | 228 | ||
229 | static const char *arizona_vol_ramp_text[] = { | ||
230 | "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", | ||
231 | "15ms/6dB", "30ms/6dB", | ||
232 | }; | ||
233 | |||
234 | const struct soc_enum arizona_in_vd_ramp = | ||
235 | SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, | ||
236 | ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); | ||
237 | EXPORT_SYMBOL_GPL(arizona_in_vd_ramp); | ||
238 | |||
239 | const struct soc_enum arizona_in_vi_ramp = | ||
240 | SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, | ||
241 | ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); | ||
242 | EXPORT_SYMBOL_GPL(arizona_in_vi_ramp); | ||
243 | |||
244 | const struct soc_enum arizona_out_vd_ramp = | ||
245 | SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, | ||
246 | ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); | ||
247 | EXPORT_SYMBOL_GPL(arizona_out_vd_ramp); | ||
248 | |||
249 | const struct soc_enum arizona_out_vi_ramp = | ||
250 | SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, | ||
251 | ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); | ||
252 | EXPORT_SYMBOL_GPL(arizona_out_vi_ramp); | ||
253 | |||
229 | static const char *arizona_lhpf_mode_text[] = { | 254 | static const char *arizona_lhpf_mode_text[] = { |
230 | "Low-pass", "High-pass" | 255 | "Low-pass", "High-pass" |
231 | }; | 256 | }; |
@@ -268,7 +293,7 @@ EXPORT_SYMBOL_GPL(arizona_out_ev); | |||
268 | static unsigned int arizona_sysclk_48k_rates[] = { | 293 | static unsigned int arizona_sysclk_48k_rates[] = { |
269 | 6144000, | 294 | 6144000, |
270 | 12288000, | 295 | 12288000, |
271 | 22579200, | 296 | 24576000, |
272 | 49152000, | 297 | 49152000, |
273 | 73728000, | 298 | 73728000, |
274 | 98304000, | 299 | 98304000, |
@@ -278,7 +303,7 @@ static unsigned int arizona_sysclk_48k_rates[] = { | |||
278 | static unsigned int arizona_sysclk_44k1_rates[] = { | 303 | static unsigned int arizona_sysclk_44k1_rates[] = { |
279 | 5644800, | 304 | 5644800, |
280 | 11289600, | 305 | 11289600, |
281 | 24576000, | 306 | 22579200, |
282 | 45158400, | 307 | 45158400, |
283 | 67737600, | 308 | 67737600, |
284 | 90316800, | 309 | 90316800, |
@@ -380,6 +405,18 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
380 | case 49152000: | 405 | case 49152000: |
381 | val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; | 406 | val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; |
382 | break; | 407 | break; |
408 | case 67737600: | ||
409 | case 73728000: | ||
410 | val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT; | ||
411 | break; | ||
412 | case 90316800: | ||
413 | case 98304000: | ||
414 | val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; | ||
415 | break; | ||
416 | case 135475200: | ||
417 | case 147456000: | ||
418 | val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; | ||
419 | break; | ||
383 | default: | 420 | default: |
384 | return -EINVAL; | 421 | return -EINVAL; |
385 | } | 422 | } |
@@ -737,6 +774,9 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, | |||
737 | return -EBUSY; | 774 | return -EBUSY; |
738 | } | 775 | } |
739 | 776 | ||
777 | dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1, | ||
778 | arizona_dai_clk_str(clk_id)); | ||
779 | |||
740 | memset(&routes, 0, sizeof(routes)); | 780 | memset(&routes, 0, sizeof(routes)); |
741 | routes[0].sink = dai->driver->capture.stream_name; | 781 | routes[0].sink = dai->driver->capture.stream_name; |
742 | routes[1].sink = dai->driver->playback.stream_name; | 782 | routes[1].sink = dai->driver->playback.stream_name; |
@@ -749,6 +789,8 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, | |||
749 | routes[1].source = arizona_dai_clk_str(clk_id); | 789 | routes[1].source = arizona_dai_clk_str(clk_id); |
750 | snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); | 790 | snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); |
751 | 791 | ||
792 | dai_priv->clk = clk_id; | ||
793 | |||
752 | return snd_soc_dapm_sync(&codec->dapm); | 794 | return snd_soc_dapm_sync(&codec->dapm); |
753 | } | 795 | } |
754 | 796 | ||
@@ -925,6 +967,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
925 | bool ena; | 967 | bool ena; |
926 | int ret; | 968 | int ret; |
927 | 969 | ||
970 | if (fll->fref == Fref && fll->fout == Fout) | ||
971 | return 0; | ||
972 | |||
928 | ret = regmap_read(arizona->regmap, fll->base + 1, ®); | 973 | ret = regmap_read(arizona->regmap, fll->base + 1, ®); |
929 | if (ret != 0) { | 974 | if (ret != 0) { |
930 | arizona_fll_err(fll, "Failed to read current state: %d\n", | 975 | arizona_fll_err(fll, "Failed to read current state: %d\n", |
@@ -970,6 +1015,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
970 | if (ena) | 1015 | if (ena) |
971 | pm_runtime_put_autosuspend(arizona->dev); | 1016 | pm_runtime_put_autosuspend(arizona->dev); |
972 | 1017 | ||
1018 | fll->fref = Fref; | ||
1019 | fll->fout = Fout; | ||
1020 | |||
973 | return 0; | 1021 | return 0; |
974 | } | 1022 | } |
975 | 1023 | ||
@@ -998,10 +1046,13 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
998 | ARIZONA_FLL1_SYNC_ENA); | 1046 | ARIZONA_FLL1_SYNC_ENA); |
999 | 1047 | ||
1000 | ret = wait_for_completion_timeout(&fll->ok, | 1048 | ret = wait_for_completion_timeout(&fll->ok, |
1001 | msecs_to_jiffies(25)); | 1049 | msecs_to_jiffies(250)); |
1002 | if (ret == 0) | 1050 | if (ret == 0) |
1003 | arizona_fll_warn(fll, "Timed out waiting for lock\n"); | 1051 | arizona_fll_warn(fll, "Timed out waiting for lock\n"); |
1004 | 1052 | ||
1053 | fll->fref = Fref; | ||
1054 | fll->fout = Fout; | ||
1055 | |||
1005 | return 0; | 1056 | return 0; |
1006 | } | 1057 | } |
1007 | EXPORT_SYMBOL_GPL(arizona_set_fll); | 1058 | EXPORT_SYMBOL_GPL(arizona_set_fll); |
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 36ec64946120..41dae1ed3b71 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h | |||
@@ -17,6 +17,8 @@ | |||
17 | 17 | ||
18 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
19 | 19 | ||
20 | #include "wm_adsp.h" | ||
21 | |||
20 | #define ARIZONA_CLK_SYSCLK 1 | 22 | #define ARIZONA_CLK_SYSCLK 1 |
21 | #define ARIZONA_CLK_ASYNCCLK 2 | 23 | #define ARIZONA_CLK_ASYNCCLK 2 |
22 | #define ARIZONA_CLK_OPCLK 3 | 24 | #define ARIZONA_CLK_OPCLK 3 |
@@ -46,15 +48,18 @@ | |||
46 | #define ARIZONA_MIXER_VOL_SHIFT 1 | 48 | #define ARIZONA_MIXER_VOL_SHIFT 1 |
47 | #define ARIZONA_MIXER_VOL_WIDTH 7 | 49 | #define ARIZONA_MIXER_VOL_WIDTH 7 |
48 | 50 | ||
49 | #define ARIZONA_MAX_DAI 3 | 51 | #define ARIZONA_MAX_DAI 4 |
52 | #define ARIZONA_MAX_ADSP 4 | ||
50 | 53 | ||
51 | struct arizona; | 54 | struct arizona; |
55 | struct wm_adsp; | ||
52 | 56 | ||
53 | struct arizona_dai_priv { | 57 | struct arizona_dai_priv { |
54 | int clk; | 58 | int clk; |
55 | }; | 59 | }; |
56 | 60 | ||
57 | struct arizona_priv { | 61 | struct arizona_priv { |
62 | struct wm_adsp adsp[ARIZONA_MAX_ADSP]; | ||
58 | struct arizona *arizona; | 63 | struct arizona *arizona; |
59 | int sysclk; | 64 | int sysclk; |
60 | int asyncclk; | 65 | int asyncclk; |
@@ -89,19 +94,30 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; | |||
89 | const struct snd_kcontrol_new name##_mux = \ | 94 | const struct snd_kcontrol_new name##_mux = \ |
90 | SOC_DAPM_VALUE_ENUM("Route", name##_enum) | 95 | SOC_DAPM_VALUE_ENUM("Route", name##_enum) |
91 | 96 | ||
97 | #define ARIZONA_MUX_ENUMS(name, base_reg) \ | ||
98 | static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \ | ||
99 | static ARIZONA_MUX_CTL_DECL(name) | ||
100 | |||
92 | #define ARIZONA_MIXER_ENUMS(name, base_reg) \ | 101 | #define ARIZONA_MIXER_ENUMS(name, base_reg) \ |
93 | static ARIZONA_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ | 102 | ARIZONA_MUX_ENUMS(name##_in1, base_reg); \ |
94 | static ARIZONA_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \ | 103 | ARIZONA_MUX_ENUMS(name##_in2, base_reg + 2); \ |
95 | static ARIZONA_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \ | 104 | ARIZONA_MUX_ENUMS(name##_in3, base_reg + 4); \ |
96 | static ARIZONA_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \ | 105 | ARIZONA_MUX_ENUMS(name##_in4, base_reg + 6) |
97 | static ARIZONA_MUX_CTL_DECL(name##_in1); \ | 106 | |
98 | static ARIZONA_MUX_CTL_DECL(name##_in2); \ | 107 | #define ARIZONA_DSP_AUX_ENUMS(name, base_reg) \ |
99 | static ARIZONA_MUX_CTL_DECL(name##_in3); \ | 108 | ARIZONA_MUX_ENUMS(name##_aux1, base_reg); \ |
100 | static ARIZONA_MUX_CTL_DECL(name##_in4) | 109 | ARIZONA_MUX_ENUMS(name##_aux2, base_reg + 8); \ |
110 | ARIZONA_MUX_ENUMS(name##_aux3, base_reg + 16); \ | ||
111 | ARIZONA_MUX_ENUMS(name##_aux4, base_reg + 24); \ | ||
112 | ARIZONA_MUX_ENUMS(name##_aux5, base_reg + 32); \ | ||
113 | ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40) | ||
101 | 114 | ||
102 | #define ARIZONA_MUX(name, ctrl) \ | 115 | #define ARIZONA_MUX(name, ctrl) \ |
103 | SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) | 116 | SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) |
104 | 117 | ||
118 | #define ARIZONA_MUX_WIDGETS(name, name_str) \ | ||
119 | ARIZONA_MUX(name_str " Input", &name##_mux) | ||
120 | |||
105 | #define ARIZONA_MIXER_WIDGETS(name, name_str) \ | 121 | #define ARIZONA_MIXER_WIDGETS(name, name_str) \ |
106 | ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \ | 122 | ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \ |
107 | ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \ | 123 | ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \ |
@@ -109,6 +125,19 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; | |||
109 | ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \ | 125 | ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \ |
110 | SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) | 126 | SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) |
111 | 127 | ||
128 | #define ARIZONA_DSP_WIDGETS(name, name_str) \ | ||
129 | ARIZONA_MIXER_WIDGETS(name##L, name_str "L"), \ | ||
130 | ARIZONA_MIXER_WIDGETS(name##R, name_str "R"), \ | ||
131 | ARIZONA_MUX(name_str " Aux 1", &name##_aux1_mux), \ | ||
132 | ARIZONA_MUX(name_str " Aux 2", &name##_aux2_mux), \ | ||
133 | ARIZONA_MUX(name_str " Aux 3", &name##_aux3_mux), \ | ||
134 | ARIZONA_MUX(name_str " Aux 4", &name##_aux4_mux), \ | ||
135 | ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \ | ||
136 | ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux) | ||
137 | |||
138 | #define ARIZONA_MUX_ROUTES(name) \ | ||
139 | ARIZONA_MIXER_INPUT_ROUTES(name " Input") | ||
140 | |||
112 | #define ARIZONA_MIXER_ROUTES(widget, name) \ | 141 | #define ARIZONA_MIXER_ROUTES(widget, name) \ |
113 | { widget, NULL, name " Mixer" }, \ | 142 | { widget, NULL, name " Mixer" }, \ |
114 | { name " Mixer", NULL, name " Input 1" }, \ | 143 | { name " Mixer", NULL, name " Input 1" }, \ |
@@ -120,6 +149,28 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; | |||
120 | ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \ | 149 | ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \ |
121 | ARIZONA_MIXER_INPUT_ROUTES(name " Input 4") | 150 | ARIZONA_MIXER_INPUT_ROUTES(name " Input 4") |
122 | 151 | ||
152 | #define ARIZONA_DSP_ROUTES(name) \ | ||
153 | { name, NULL, name " Aux 1" }, \ | ||
154 | { name, NULL, name " Aux 2" }, \ | ||
155 | { name, NULL, name " Aux 3" }, \ | ||
156 | { name, NULL, name " Aux 4" }, \ | ||
157 | { name, NULL, name " Aux 5" }, \ | ||
158 | { name, NULL, name " Aux 6" }, \ | ||
159 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \ | ||
160 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \ | ||
161 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \ | ||
162 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \ | ||
163 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \ | ||
164 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \ | ||
165 | ARIZONA_MIXER_ROUTES(name, name "L"), \ | ||
166 | ARIZONA_MIXER_ROUTES(name, name "R") | ||
167 | |||
168 | extern const struct soc_enum arizona_in_vi_ramp; | ||
169 | extern const struct soc_enum arizona_in_vd_ramp; | ||
170 | |||
171 | extern const struct soc_enum arizona_out_vi_ramp; | ||
172 | extern const struct soc_enum arizona_out_vd_ramp; | ||
173 | |||
123 | extern const struct soc_enum arizona_lhpf1_mode; | 174 | extern const struct soc_enum arizona_lhpf1_mode; |
124 | extern const struct soc_enum arizona_lhpf2_mode; | 175 | extern const struct soc_enum arizona_lhpf2_mode; |
125 | extern const struct soc_enum arizona_lhpf3_mode; | 176 | extern const struct soc_enum arizona_lhpf3_mode; |
@@ -146,6 +197,8 @@ struct arizona_fll { | |||
146 | unsigned int vco_mult; | 197 | unsigned int vco_mult; |
147 | struct completion lock; | 198 | struct completion lock; |
148 | struct completion ok; | 199 | struct completion ok; |
200 | unsigned int fref; | ||
201 | unsigned int fout; | ||
149 | 202 | ||
150 | char lock_name[ARIZONA_FLL_NAME_LEN]; | 203 | char lock_name[ARIZONA_FLL_NAME_LEN]; |
151 | char clock_ok_name[ARIZONA_FLL_NAME_LEN]; | 204 | char clock_ok_name[ARIZONA_FLL_NAME_LEN]; |
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index f994af34f552..6ad3878db8fc 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
@@ -474,18 +474,28 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
474 | struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; | 474 | struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; |
475 | int ret; | 475 | int ret; |
476 | int gpio_nreset = -EINVAL; | 476 | int gpio_nreset = -EINVAL; |
477 | int amutec_eq_bmutec = 0; | ||
477 | 478 | ||
478 | #ifdef CONFIG_OF | 479 | #ifdef CONFIG_OF |
479 | if (of_match_device(cs4271_dt_ids, codec->dev)) | 480 | if (of_match_device(cs4271_dt_ids, codec->dev)) { |
480 | gpio_nreset = of_get_named_gpio(codec->dev->of_node, | 481 | gpio_nreset = of_get_named_gpio(codec->dev->of_node, |
481 | "reset-gpio", 0); | 482 | "reset-gpio", 0); |
483 | |||
484 | if (!of_get_property(codec->dev->of_node, | ||
485 | "cirrus,amutec-eq-bmutec", NULL)) | ||
486 | amutec_eq_bmutec = 1; | ||
487 | } | ||
482 | #endif | 488 | #endif |
483 | 489 | ||
484 | if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset)) | 490 | if (cs4271plat) { |
485 | gpio_nreset = cs4271plat->gpio_nreset; | 491 | if (gpio_is_valid(cs4271plat->gpio_nreset)) |
492 | gpio_nreset = cs4271plat->gpio_nreset; | ||
493 | |||
494 | amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec; | ||
495 | } | ||
486 | 496 | ||
487 | if (gpio_nreset >= 0) | 497 | if (gpio_nreset >= 0) |
488 | if (gpio_request(gpio_nreset, "CS4271 Reset")) | 498 | if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset")) |
489 | gpio_nreset = -EINVAL; | 499 | gpio_nreset = -EINVAL; |
490 | if (gpio_nreset >= 0) { | 500 | if (gpio_nreset >= 0) { |
491 | /* Reset codec */ | 501 | /* Reset codec */ |
@@ -528,6 +538,11 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
528 | /* Power-up sequence requires 85 uS */ | 538 | /* Power-up sequence requires 85 uS */ |
529 | udelay(85); | 539 | udelay(85); |
530 | 540 | ||
541 | if (amutec_eq_bmutec) | ||
542 | snd_soc_update_bits(codec, CS4271_MODE2, | ||
543 | CS4271_MODE2_MUTECAEQUB, | ||
544 | CS4271_MODE2_MUTECAEQUB); | ||
545 | |||
531 | return snd_soc_add_codec_controls(codec, cs4271_snd_controls, | 546 | return snd_soc_add_codec_controls(codec, cs4271_snd_controls, |
532 | ARRAY_SIZE(cs4271_snd_controls)); | 547 | ARRAY_SIZE(cs4271_snd_controls)); |
533 | } | 548 | } |
@@ -535,15 +550,10 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
535 | static int cs4271_remove(struct snd_soc_codec *codec) | 550 | static int cs4271_remove(struct snd_soc_codec *codec) |
536 | { | 551 | { |
537 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); | 552 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); |
538 | int gpio_nreset; | ||
539 | |||
540 | gpio_nreset = cs4271->gpio_nreset; | ||
541 | 553 | ||
542 | if (gpio_is_valid(gpio_nreset)) { | 554 | if (gpio_is_valid(cs4271->gpio_nreset)) |
543 | /* Set codec to the reset state */ | 555 | /* Set codec to the reset state */ |
544 | gpio_set_value(gpio_nreset, 0); | 556 | gpio_set_value(cs4271->gpio_nreset, 0); |
545 | gpio_free(gpio_nreset); | ||
546 | } | ||
547 | 557 | ||
548 | return 0; | 558 | return 0; |
549 | }; | 559 | }; |
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index af5db7080519..843c1eb72faf 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c | |||
@@ -1231,7 +1231,7 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, | |||
1231 | 1231 | ||
1232 | i2c_set_clientdata(i2c, da7210); | 1232 | i2c_set_clientdata(i2c, da7210); |
1233 | 1233 | ||
1234 | da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap_config_i2c); | 1234 | da7210->regmap = devm_regmap_init_i2c(i2c, &da7210_regmap_config_i2c); |
1235 | if (IS_ERR(da7210->regmap)) { | 1235 | if (IS_ERR(da7210->regmap)) { |
1236 | ret = PTR_ERR(da7210->regmap); | 1236 | ret = PTR_ERR(da7210->regmap); |
1237 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); | 1237 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); |
@@ -1245,24 +1245,15 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, | |||
1245 | 1245 | ||
1246 | ret = snd_soc_register_codec(&i2c->dev, | 1246 | ret = snd_soc_register_codec(&i2c->dev, |
1247 | &soc_codec_dev_da7210, &da7210_dai, 1); | 1247 | &soc_codec_dev_da7210, &da7210_dai, 1); |
1248 | if (ret < 0) { | 1248 | if (ret < 0) |
1249 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); | 1249 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); |
1250 | goto err_regmap; | ||
1251 | } | ||
1252 | return ret; | ||
1253 | |||
1254 | err_regmap: | ||
1255 | regmap_exit(da7210->regmap); | ||
1256 | 1250 | ||
1257 | return ret; | 1251 | return ret; |
1258 | } | 1252 | } |
1259 | 1253 | ||
1260 | static int __devexit da7210_i2c_remove(struct i2c_client *client) | 1254 | static int __devexit da7210_i2c_remove(struct i2c_client *client) |
1261 | { | 1255 | { |
1262 | struct da7210_priv *da7210 = i2c_get_clientdata(client); | ||
1263 | |||
1264 | snd_soc_unregister_codec(&client->dev); | 1256 | snd_soc_unregister_codec(&client->dev); |
1265 | regmap_exit(da7210->regmap); | ||
1266 | return 0; | 1257 | return 0; |
1267 | } | 1258 | } |
1268 | 1259 | ||
@@ -1346,24 +1337,15 @@ static int __devinit da7210_spi_probe(struct spi_device *spi) | |||
1346 | if (ret != 0) | 1337 | if (ret != 0) |
1347 | dev_warn(&spi->dev, "Failed to apply regmap patch: %d\n", ret); | 1338 | dev_warn(&spi->dev, "Failed to apply regmap patch: %d\n", ret); |
1348 | 1339 | ||
1349 | ret = snd_soc_register_codec(&spi->dev, | 1340 | ret = snd_soc_register_codec(&spi->dev, |
1350 | &soc_codec_dev_da7210, &da7210_dai, 1); | 1341 | &soc_codec_dev_da7210, &da7210_dai, 1); |
1351 | if (ret < 0) | ||
1352 | goto err_regmap; | ||
1353 | |||
1354 | return ret; | ||
1355 | |||
1356 | err_regmap: | ||
1357 | regmap_exit(da7210->regmap); | ||
1358 | 1342 | ||
1359 | return ret; | 1343 | return ret; |
1360 | } | 1344 | } |
1361 | 1345 | ||
1362 | static int __devexit da7210_spi_remove(struct spi_device *spi) | 1346 | static int __devexit da7210_spi_remove(struct spi_device *spi) |
1363 | { | 1347 | { |
1364 | struct da7210_priv *da7210 = spi_get_drvdata(spi); | ||
1365 | snd_soc_unregister_codec(&spi->dev); | 1348 | snd_soc_unregister_codec(&spi->dev); |
1366 | regmap_exit(da7210->regmap); | ||
1367 | return 0; | 1349 | return 0; |
1368 | } | 1350 | } |
1369 | 1351 | ||
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index f379b085c392..d3a6de2e757b 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c | |||
@@ -173,6 +173,7 @@ | |||
173 | #define DA9055_AIF_FORMAT_I2S_MODE (0 << 0) | 173 | #define DA9055_AIF_FORMAT_I2S_MODE (0 << 0) |
174 | #define DA9055_AIF_FORMAT_LEFT_J (1 << 0) | 174 | #define DA9055_AIF_FORMAT_LEFT_J (1 << 0) |
175 | #define DA9055_AIF_FORMAT_RIGHT_J (2 << 0) | 175 | #define DA9055_AIF_FORMAT_RIGHT_J (2 << 0) |
176 | #define DA9055_AIF_FORMAT_DSP (3 << 0) | ||
176 | #define DA9055_AIF_WORD_S16_LE (0 << 2) | 177 | #define DA9055_AIF_WORD_S16_LE (0 << 2) |
177 | #define DA9055_AIF_WORD_S20_3LE (1 << 2) | 178 | #define DA9055_AIF_WORD_S20_3LE (1 << 2) |
178 | #define DA9055_AIF_WORD_S24_LE (2 << 2) | 179 | #define DA9055_AIF_WORD_S24_LE (2 << 2) |
@@ -752,6 +753,17 @@ static const struct snd_kcontrol_new da9055_dapm_mixoutr_controls[] = { | |||
752 | 6, 1, 0), | 753 | 6, 1, 0), |
753 | }; | 754 | }; |
754 | 755 | ||
756 | /* Headphone Output Enable */ | ||
757 | static const struct snd_kcontrol_new da9055_dapm_hp_l_control = | ||
758 | SOC_DAPM_SINGLE("Switch", DA9055_HP_L_CTRL, 3, 1, 0); | ||
759 | |||
760 | static const struct snd_kcontrol_new da9055_dapm_hp_r_control = | ||
761 | SOC_DAPM_SINGLE("Switch", DA9055_HP_R_CTRL, 3, 1, 0); | ||
762 | |||
763 | /* Lineout Output Enable */ | ||
764 | static const struct snd_kcontrol_new da9055_dapm_lineout_control = | ||
765 | SOC_DAPM_SINGLE("Switch", DA9055_LINE_CTRL, 3, 1, 0); | ||
766 | |||
755 | /* DAPM widgets */ | 767 | /* DAPM widgets */ |
756 | static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = { | 768 | static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = { |
757 | /* Input Side */ | 769 | /* Input Side */ |
@@ -816,6 +828,14 @@ static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = { | |||
816 | &da9055_dapm_mixoutr_controls[0], | 828 | &da9055_dapm_mixoutr_controls[0], |
817 | ARRAY_SIZE(da9055_dapm_mixoutr_controls)), | 829 | ARRAY_SIZE(da9055_dapm_mixoutr_controls)), |
818 | 830 | ||
831 | /* Output Enable Switches */ | ||
832 | SND_SOC_DAPM_SWITCH("Headphone Left Enable", SND_SOC_NOPM, 0, 0, | ||
833 | &da9055_dapm_hp_l_control), | ||
834 | SND_SOC_DAPM_SWITCH("Headphone Right Enable", SND_SOC_NOPM, 0, 0, | ||
835 | &da9055_dapm_hp_r_control), | ||
836 | SND_SOC_DAPM_SWITCH("Lineout Enable", SND_SOC_NOPM, 0, 0, | ||
837 | &da9055_dapm_lineout_control), | ||
838 | |||
819 | /* Output PGAs */ | 839 | /* Output PGAs */ |
820 | SND_SOC_DAPM_PGA("MIXOUT Left", DA9055_MIXOUT_L_CTRL, 7, 0, NULL, 0), | 840 | SND_SOC_DAPM_PGA("MIXOUT Left", DA9055_MIXOUT_L_CTRL, 7, 0, NULL, 0), |
821 | SND_SOC_DAPM_PGA("MIXOUT Right", DA9055_MIXOUT_R_CTRL, 7, 0, NULL, 0), | 841 | SND_SOC_DAPM_PGA("MIXOUT Right", DA9055_MIXOUT_R_CTRL, 7, 0, NULL, 0), |
@@ -901,17 +921,20 @@ static const struct snd_soc_dapm_route da9055_audio_map[] = { | |||
901 | {"Out Mixer Right", "DAC Right Switch", "DAC Right"}, | 921 | {"Out Mixer Right", "DAC Right Switch", "DAC Right"}, |
902 | 922 | ||
903 | {"MIXOUT Left", NULL, "Out Mixer Left"}, | 923 | {"MIXOUT Left", NULL, "Out Mixer Left"}, |
904 | {"Headphone Left", NULL, "MIXOUT Left"}, | 924 | {"Headphone Left Enable", "Switch", "MIXOUT Left"}, |
925 | {"Headphone Left", NULL, "Headphone Left Enable"}, | ||
905 | {"Headphone Left", NULL, "Charge Pump"}, | 926 | {"Headphone Left", NULL, "Charge Pump"}, |
906 | {"HPL", NULL, "Headphone Left"}, | 927 | {"HPL", NULL, "Headphone Left"}, |
907 | 928 | ||
908 | {"MIXOUT Right", NULL, "Out Mixer Right"}, | 929 | {"MIXOUT Right", NULL, "Out Mixer Right"}, |
909 | {"Headphone Right", NULL, "MIXOUT Right"}, | 930 | {"Headphone Right Enable", "Switch", "MIXOUT Right"}, |
931 | {"Headphone Right", NULL, "Headphone Right Enable"}, | ||
910 | {"Headphone Right", NULL, "Charge Pump"}, | 932 | {"Headphone Right", NULL, "Charge Pump"}, |
911 | {"HPR", NULL, "Headphone Right"}, | 933 | {"HPR", NULL, "Headphone Right"}, |
912 | 934 | ||
913 | {"MIXOUT Right", NULL, "Out Mixer Right"}, | 935 | {"MIXOUT Right", NULL, "Out Mixer Right"}, |
914 | {"Lineout", NULL, "MIXOUT Right"}, | 936 | {"Lineout Enable", "Switch", "MIXOUT Right"}, |
937 | {"Lineout", NULL, "Lineout Enable"}, | ||
915 | {"LINE", NULL, "Lineout"}, | 938 | {"LINE", NULL, "Lineout"}, |
916 | }; | 939 | }; |
917 | 940 | ||
@@ -1175,6 +1198,9 @@ static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |||
1175 | case SND_SOC_DAIFMT_RIGHT_J: | 1198 | case SND_SOC_DAIFMT_RIGHT_J: |
1176 | aif_ctrl = DA9055_AIF_FORMAT_RIGHT_J; | 1199 | aif_ctrl = DA9055_AIF_FORMAT_RIGHT_J; |
1177 | break; | 1200 | break; |
1201 | case SND_SOC_DAIFMT_DSP_A: | ||
1202 | aif_ctrl = DA9055_AIF_FORMAT_DSP; | ||
1203 | break; | ||
1178 | default: | 1204 | default: |
1179 | return -EINVAL; | 1205 | return -EINVAL; |
1180 | } | 1206 | } |
@@ -1390,8 +1416,7 @@ static int da9055_probe(struct snd_soc_codec *codec) | |||
1390 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | 1416 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); |
1391 | 1417 | ||
1392 | /* | 1418 | /* |
1393 | * There are two separate control bits for input and output mixers as | 1419 | * There are two separate control bits for input and output mixers. |
1394 | * well as headphone and line outs. | ||
1395 | * One to enable corresponding amplifier and other to enable its | 1420 | * One to enable corresponding amplifier and other to enable its |
1396 | * output. As amplifier bits are related to power control, they are | 1421 | * output. As amplifier bits are related to power control, they are |
1397 | * being managed by DAPM while other (non power related) bits are | 1422 | * being managed by DAPM while other (non power related) bits are |
@@ -1407,14 +1432,6 @@ static int da9055_probe(struct snd_soc_codec *codec) | |||
1407 | snd_soc_update_bits(codec, DA9055_MIXOUT_R_CTRL, | 1432 | snd_soc_update_bits(codec, DA9055_MIXOUT_R_CTRL, |
1408 | DA9055_MIXOUT_R_MIX_EN, DA9055_MIXOUT_R_MIX_EN); | 1433 | DA9055_MIXOUT_R_MIX_EN, DA9055_MIXOUT_R_MIX_EN); |
1409 | 1434 | ||
1410 | snd_soc_update_bits(codec, DA9055_HP_L_CTRL, | ||
1411 | DA9055_HP_L_AMP_OE, DA9055_HP_L_AMP_OE); | ||
1412 | snd_soc_update_bits(codec, DA9055_HP_R_CTRL, | ||
1413 | DA9055_HP_R_AMP_OE, DA9055_HP_R_AMP_OE); | ||
1414 | |||
1415 | snd_soc_update_bits(codec, DA9055_LINE_CTRL, | ||
1416 | DA9055_LINE_AMP_OE, DA9055_LINE_AMP_OE); | ||
1417 | |||
1418 | /* Set this as per your system configuration */ | 1435 | /* Set this as per your system configuration */ |
1419 | snd_soc_write(codec, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ); | 1436 | snd_soc_write(codec, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ); |
1420 | 1437 | ||
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 85d9cabe6d55..9ad1da36887e 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/regmap.h> | ||
19 | 20 | ||
20 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
21 | 22 | ||
@@ -24,9 +25,10 @@ | |||
24 | #include <sound/pcm_params.h> | 25 | #include <sound/pcm_params.h> |
25 | #include <sound/initval.h> | 26 | #include <sound/initval.h> |
26 | #include <sound/soc.h> | 27 | #include <sound/soc.h> |
28 | #include <sound/tlv.h> | ||
27 | 29 | ||
28 | #define JZ4740_REG_CODEC_1 0x0 | 30 | #define JZ4740_REG_CODEC_1 0x0 |
29 | #define JZ4740_REG_CODEC_2 0x1 | 31 | #define JZ4740_REG_CODEC_2 0x4 |
30 | 32 | ||
31 | #define JZ4740_CODEC_1_LINE_ENABLE BIT(29) | 33 | #define JZ4740_CODEC_1_LINE_ENABLE BIT(29) |
32 | #define JZ4740_CODEC_1_MIC_ENABLE BIT(28) | 34 | #define JZ4740_CODEC_1_MIC_ENABLE BIT(28) |
@@ -67,43 +69,36 @@ | |||
67 | #define JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET 4 | 69 | #define JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET 4 |
68 | #define JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET 0 | 70 | #define JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET 0 |
69 | 71 | ||
70 | static const uint32_t jz4740_codec_regs[] = { | 72 | static const struct reg_default jz4740_codec_reg_defaults[] = { |
71 | 0x021b2302, 0x00170803, | 73 | { JZ4740_REG_CODEC_1, 0x021b2302 }, |
74 | { JZ4740_REG_CODEC_2, 0x00170803 }, | ||
72 | }; | 75 | }; |
73 | 76 | ||
74 | struct jz4740_codec { | 77 | struct jz4740_codec { |
75 | void __iomem *base; | 78 | struct regmap *regmap; |
76 | struct resource *mem; | ||
77 | }; | 79 | }; |
78 | 80 | ||
79 | static unsigned int jz4740_codec_read(struct snd_soc_codec *codec, | 81 | static const unsigned int jz4740_mic_tlv[] = { |
80 | unsigned int reg) | 82 | TLV_DB_RANGE_HEAD(2), |
81 | { | 83 | 0, 2, TLV_DB_SCALE_ITEM(0, 600, 0), |
82 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); | 84 | 3, 3, TLV_DB_SCALE_ITEM(2000, 0, 0), |
83 | return readl(jz4740_codec->base + (reg << 2)); | 85 | }; |
84 | } | ||
85 | |||
86 | static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg, | ||
87 | unsigned int val) | ||
88 | { | ||
89 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); | ||
90 | u32 *cache = codec->reg_cache; | ||
91 | |||
92 | cache[reg] = val; | ||
93 | writel(val, jz4740_codec->base + (reg << 2)); | ||
94 | 86 | ||
95 | return 0; | 87 | static const DECLARE_TLV_DB_SCALE(jz4740_out_tlv, 0, 200, 0); |
96 | } | 88 | static const DECLARE_TLV_DB_SCALE(jz4740_in_tlv, -3450, 150, 0); |
97 | 89 | ||
98 | static const struct snd_kcontrol_new jz4740_codec_controls[] = { | 90 | static const struct snd_kcontrol_new jz4740_codec_controls[] = { |
99 | SOC_SINGLE("Master Playback Volume", JZ4740_REG_CODEC_2, | 91 | SOC_SINGLE_TLV("Master Playback Volume", JZ4740_REG_CODEC_2, |
100 | JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET, 3, 0), | 92 | JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET, 3, 0, |
101 | SOC_SINGLE("Master Capture Volume", JZ4740_REG_CODEC_2, | 93 | jz4740_out_tlv), |
102 | JZ4740_CODEC_2_INPUT_VOLUME_OFFSET, 31, 0), | 94 | SOC_SINGLE_TLV("Master Capture Volume", JZ4740_REG_CODEC_2, |
95 | JZ4740_CODEC_2_INPUT_VOLUME_OFFSET, 31, 0, | ||
96 | jz4740_in_tlv), | ||
103 | SOC_SINGLE("Master Playback Switch", JZ4740_REG_CODEC_1, | 97 | SOC_SINGLE("Master Playback Switch", JZ4740_REG_CODEC_1, |
104 | JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET, 1, 1), | 98 | JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET, 1, 1), |
105 | SOC_SINGLE("Mic Capture Volume", JZ4740_REG_CODEC_2, | 99 | SOC_SINGLE_TLV("Mic Capture Volume", JZ4740_REG_CODEC_2, |
106 | JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET, 3, 0), | 100 | JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET, 3, 0, |
101 | jz4740_mic_tlv), | ||
107 | }; | 102 | }; |
108 | 103 | ||
109 | static const struct snd_kcontrol_new jz4740_codec_output_controls[] = { | 104 | static const struct snd_kcontrol_new jz4740_codec_output_controls[] = { |
@@ -163,8 +158,8 @@ static const struct snd_soc_dapm_route jz4740_codec_dapm_routes[] = { | |||
163 | static int jz4740_codec_hw_params(struct snd_pcm_substream *substream, | 158 | static int jz4740_codec_hw_params(struct snd_pcm_substream *substream, |
164 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 159 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
165 | { | 160 | { |
161 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(dai->codec); | ||
166 | uint32_t val; | 162 | uint32_t val; |
167 | struct snd_soc_codec *codec = dai->codec; | ||
168 | 163 | ||
169 | switch (params_rate(params)) { | 164 | switch (params_rate(params)) { |
170 | case 8000: | 165 | case 8000: |
@@ -200,7 +195,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream, | |||
200 | 195 | ||
201 | val <<= JZ4740_CODEC_2_SAMPLE_RATE_OFFSET; | 196 | val <<= JZ4740_CODEC_2_SAMPLE_RATE_OFFSET; |
202 | 197 | ||
203 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_2, | 198 | regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_2, |
204 | JZ4740_CODEC_2_SAMPLE_RATE_MASK, val); | 199 | JZ4740_CODEC_2_SAMPLE_RATE_MASK, val); |
205 | 200 | ||
206 | return 0; | 201 | return 0; |
@@ -230,25 +225,23 @@ static struct snd_soc_dai_driver jz4740_codec_dai = { | |||
230 | .symmetric_rates = 1, | 225 | .symmetric_rates = 1, |
231 | }; | 226 | }; |
232 | 227 | ||
233 | static void jz4740_codec_wakeup(struct snd_soc_codec *codec) | 228 | static void jz4740_codec_wakeup(struct regmap *regmap) |
234 | { | 229 | { |
235 | int i; | 230 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, |
236 | uint32_t *cache = codec->reg_cache; | ||
237 | |||
238 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, | ||
239 | JZ4740_CODEC_1_RESET, JZ4740_CODEC_1_RESET); | 231 | JZ4740_CODEC_1_RESET, JZ4740_CODEC_1_RESET); |
240 | udelay(2); | 232 | udelay(2); |
241 | 233 | ||
242 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, | 234 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, |
243 | JZ4740_CODEC_1_SUSPEND | JZ4740_CODEC_1_RESET, 0); | 235 | JZ4740_CODEC_1_SUSPEND | JZ4740_CODEC_1_RESET, 0); |
244 | 236 | ||
245 | for (i = 0; i < ARRAY_SIZE(jz4740_codec_regs); ++i) | 237 | regcache_sync(regmap); |
246 | jz4740_codec_write(codec, i, cache[i]); | ||
247 | } | 238 | } |
248 | 239 | ||
249 | static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, | 240 | static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, |
250 | enum snd_soc_bias_level level) | 241 | enum snd_soc_bias_level level) |
251 | { | 242 | { |
243 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); | ||
244 | struct regmap *regmap = jz4740_codec->regmap; | ||
252 | unsigned int mask; | 245 | unsigned int mask; |
253 | unsigned int value; | 246 | unsigned int value; |
254 | 247 | ||
@@ -261,12 +254,12 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, | |||
261 | JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; | 254 | JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; |
262 | value = 0; | 255 | value = 0; |
263 | 256 | ||
264 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); | 257 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value); |
265 | break; | 258 | break; |
266 | case SND_SOC_BIAS_STANDBY: | 259 | case SND_SOC_BIAS_STANDBY: |
267 | /* The only way to clear the suspend flag is to reset the codec */ | 260 | /* The only way to clear the suspend flag is to reset the codec */ |
268 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) | 261 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) |
269 | jz4740_codec_wakeup(codec); | 262 | jz4740_codec_wakeup(regmap); |
270 | 263 | ||
271 | mask = JZ4740_CODEC_1_VREF_DISABLE | | 264 | mask = JZ4740_CODEC_1_VREF_DISABLE | |
272 | JZ4740_CODEC_1_VREF_AMP_DISABLE | | 265 | JZ4740_CODEC_1_VREF_AMP_DISABLE | |
@@ -275,13 +268,14 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, | |||
275 | JZ4740_CODEC_1_VREF_AMP_DISABLE | | 268 | JZ4740_CODEC_1_VREF_AMP_DISABLE | |
276 | JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; | 269 | JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; |
277 | 270 | ||
278 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); | 271 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value); |
279 | break; | 272 | break; |
280 | case SND_SOC_BIAS_OFF: | 273 | case SND_SOC_BIAS_OFF: |
281 | mask = JZ4740_CODEC_1_SUSPEND; | 274 | mask = JZ4740_CODEC_1_SUSPEND; |
282 | value = JZ4740_CODEC_1_SUSPEND; | 275 | value = JZ4740_CODEC_1_SUSPEND; |
283 | 276 | ||
284 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); | 277 | regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value); |
278 | regcache_mark_dirty(regmap); | ||
285 | break; | 279 | break; |
286 | default: | 280 | default: |
287 | break; | 281 | break; |
@@ -294,7 +288,9 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, | |||
294 | 288 | ||
295 | static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) | 289 | static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) |
296 | { | 290 | { |
297 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, | 291 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); |
292 | |||
293 | regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_1, | ||
298 | JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); | 294 | JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); |
299 | 295 | ||
300 | jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 296 | jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
@@ -331,12 +327,7 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { | |||
331 | .remove = jz4740_codec_dev_remove, | 327 | .remove = jz4740_codec_dev_remove, |
332 | .suspend = jz4740_codec_suspend, | 328 | .suspend = jz4740_codec_suspend, |
333 | .resume = jz4740_codec_resume, | 329 | .resume = jz4740_codec_resume, |
334 | .read = jz4740_codec_read, | ||
335 | .write = jz4740_codec_write, | ||
336 | .set_bias_level = jz4740_codec_set_bias_level, | 330 | .set_bias_level = jz4740_codec_set_bias_level, |
337 | .reg_cache_default = jz4740_codec_regs, | ||
338 | .reg_word_size = sizeof(u32), | ||
339 | .reg_cache_size = 2, | ||
340 | 331 | ||
341 | .controls = jz4740_codec_controls, | 332 | .controls = jz4740_codec_controls, |
342 | .num_controls = ARRAY_SIZE(jz4740_codec_controls), | 333 | .num_controls = ARRAY_SIZE(jz4740_codec_controls), |
@@ -346,11 +337,23 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { | |||
346 | .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes), | 337 | .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes), |
347 | }; | 338 | }; |
348 | 339 | ||
340 | static const struct regmap_config jz4740_codec_regmap_config = { | ||
341 | .reg_bits = 32, | ||
342 | .reg_stride = 4, | ||
343 | .val_bits = 32, | ||
344 | .max_register = JZ4740_REG_CODEC_2, | ||
345 | |||
346 | .reg_defaults = jz4740_codec_reg_defaults, | ||
347 | .num_reg_defaults = ARRAY_SIZE(jz4740_codec_reg_defaults), | ||
348 | .cache_type = REGCACHE_RBTREE, | ||
349 | }; | ||
350 | |||
349 | static int __devinit jz4740_codec_probe(struct platform_device *pdev) | 351 | static int __devinit jz4740_codec_probe(struct platform_device *pdev) |
350 | { | 352 | { |
351 | int ret; | 353 | int ret; |
352 | struct jz4740_codec *jz4740_codec; | 354 | struct jz4740_codec *jz4740_codec; |
353 | struct resource *mem; | 355 | struct resource *mem; |
356 | void __iomem *base; | ||
354 | 357 | ||
355 | jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec), | 358 | jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec), |
356 | GFP_KERNEL); | 359 | GFP_KERNEL); |
@@ -358,56 +361,29 @@ static int __devinit jz4740_codec_probe(struct platform_device *pdev) | |||
358 | return -ENOMEM; | 361 | return -ENOMEM; |
359 | 362 | ||
360 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 363 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
361 | if (!mem) { | 364 | base = devm_request_and_ioremap(&pdev->dev, mem); |
362 | dev_err(&pdev->dev, "Failed to get mmio memory resource\n"); | 365 | if (!base) |
363 | ret = -ENOENT; | 366 | return -EBUSY; |
364 | goto err_out; | ||
365 | } | ||
366 | |||
367 | mem = request_mem_region(mem->start, resource_size(mem), pdev->name); | ||
368 | if (!mem) { | ||
369 | dev_err(&pdev->dev, "Failed to request mmio memory region\n"); | ||
370 | ret = -EBUSY; | ||
371 | goto err_out; | ||
372 | } | ||
373 | 367 | ||
374 | jz4740_codec->base = ioremap(mem->start, resource_size(mem)); | 368 | jz4740_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base, |
375 | if (!jz4740_codec->base) { | 369 | &jz4740_codec_regmap_config); |
376 | dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); | 370 | if (IS_ERR(jz4740_codec->regmap)) |
377 | ret = -EBUSY; | 371 | return PTR_ERR(jz4740_codec->regmap); |
378 | goto err_release_mem_region; | ||
379 | } | ||
380 | jz4740_codec->mem = mem; | ||
381 | 372 | ||
382 | platform_set_drvdata(pdev, jz4740_codec); | 373 | platform_set_drvdata(pdev, jz4740_codec); |
383 | 374 | ||
384 | ret = snd_soc_register_codec(&pdev->dev, | 375 | ret = snd_soc_register_codec(&pdev->dev, |
385 | &soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1); | 376 | &soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1); |
386 | if (ret) { | 377 | if (ret) |
387 | dev_err(&pdev->dev, "Failed to register codec\n"); | 378 | dev_err(&pdev->dev, "Failed to register codec\n"); |
388 | goto err_iounmap; | ||
389 | } | ||
390 | 379 | ||
391 | return 0; | ||
392 | |||
393 | err_iounmap: | ||
394 | iounmap(jz4740_codec->base); | ||
395 | err_release_mem_region: | ||
396 | release_mem_region(mem->start, resource_size(mem)); | ||
397 | err_out: | ||
398 | return ret; | 380 | return ret; |
399 | } | 381 | } |
400 | 382 | ||
401 | static int __devexit jz4740_codec_remove(struct platform_device *pdev) | 383 | static int __devexit jz4740_codec_remove(struct platform_device *pdev) |
402 | { | 384 | { |
403 | struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev); | ||
404 | struct resource *mem = jz4740_codec->mem; | ||
405 | |||
406 | snd_soc_unregister_codec(&pdev->dev); | 385 | snd_soc_unregister_codec(&pdev->dev); |
407 | 386 | ||
408 | iounmap(jz4740_codec->base); | ||
409 | release_mem_region(mem->start, resource_size(mem)); | ||
410 | |||
411 | platform_set_drvdata(pdev, NULL); | 387 | platform_set_drvdata(pdev, NULL); |
412 | 388 | ||
413 | return 0; | 389 | return 0; |
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index 99b0a9dcff34..096b6aa87f0f 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c | |||
@@ -1497,7 +1497,7 @@ static __devinit int lm49453_i2c_probe(struct i2c_client *i2c, | |||
1497 | 1497 | ||
1498 | i2c_set_clientdata(i2c, lm49453); | 1498 | i2c_set_clientdata(i2c, lm49453); |
1499 | 1499 | ||
1500 | lm49453->regmap = regmap_init_i2c(i2c, &lm49453_regmap_config); | 1500 | lm49453->regmap = devm_regmap_init_i2c(i2c, &lm49453_regmap_config); |
1501 | if (IS_ERR(lm49453->regmap)) { | 1501 | if (IS_ERR(lm49453->regmap)) { |
1502 | ret = PTR_ERR(lm49453->regmap); | 1502 | ret = PTR_ERR(lm49453->regmap); |
1503 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 1503 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
@@ -1508,21 +1508,15 @@ static __devinit int lm49453_i2c_probe(struct i2c_client *i2c, | |||
1508 | ret = snd_soc_register_codec(&i2c->dev, | 1508 | ret = snd_soc_register_codec(&i2c->dev, |
1509 | &soc_codec_dev_lm49453, | 1509 | &soc_codec_dev_lm49453, |
1510 | lm49453_dai, ARRAY_SIZE(lm49453_dai)); | 1510 | lm49453_dai, ARRAY_SIZE(lm49453_dai)); |
1511 | if (ret < 0) { | 1511 | if (ret < 0) |
1512 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); | 1512 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); |
1513 | regmap_exit(lm49453->regmap); | ||
1514 | return ret; | ||
1515 | } | ||
1516 | 1513 | ||
1517 | return ret; | 1514 | return ret; |
1518 | } | 1515 | } |
1519 | 1516 | ||
1520 | static int __devexit lm49453_i2c_remove(struct i2c_client *client) | 1517 | static int __devexit lm49453_i2c_remove(struct i2c_client *client) |
1521 | { | 1518 | { |
1522 | struct lm49453_priv *lm49453 = i2c_get_clientdata(client); | ||
1523 | |||
1524 | snd_soc_unregister_codec(&client->dev); | 1519 | snd_soc_unregister_codec(&client->dev); |
1525 | regmap_exit(lm49453->regmap); | ||
1526 | return 0; | 1520 | return 0; |
1527 | } | 1521 | } |
1528 | 1522 | ||
diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c index 17b3ec2d05cb..a777de6a1b23 100644 --- a/sound/soc/codecs/max9768.c +++ b/sound/soc/codecs/max9768.c | |||
@@ -187,7 +187,7 @@ static int __devinit max9768_i2c_probe(struct i2c_client *client, | |||
187 | 187 | ||
188 | i2c_set_clientdata(client, max9768); | 188 | i2c_set_clientdata(client, max9768); |
189 | 189 | ||
190 | max9768->regmap = regmap_init_i2c(client, &max9768_i2c_regmap_config); | 190 | max9768->regmap = devm_regmap_init_i2c(client, &max9768_i2c_regmap_config); |
191 | if (IS_ERR(max9768->regmap)) { | 191 | if (IS_ERR(max9768->regmap)) { |
192 | err = PTR_ERR(max9768->regmap); | 192 | err = PTR_ERR(max9768->regmap); |
193 | goto err_gpio_free; | 193 | goto err_gpio_free; |
@@ -195,12 +195,10 @@ static int __devinit max9768_i2c_probe(struct i2c_client *client, | |||
195 | 195 | ||
196 | err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0); | 196 | err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0); |
197 | if (err) | 197 | if (err) |
198 | goto err_regmap_free; | 198 | goto err_gpio_free; |
199 | 199 | ||
200 | return 0; | 200 | return 0; |
201 | 201 | ||
202 | err_regmap_free: | ||
203 | regmap_exit(max9768->regmap); | ||
204 | err_gpio_free: | 202 | err_gpio_free: |
205 | if (gpio_is_valid(max9768->shdn_gpio)) | 203 | if (gpio_is_valid(max9768->shdn_gpio)) |
206 | gpio_free(max9768->shdn_gpio); | 204 | gpio_free(max9768->shdn_gpio); |
@@ -215,7 +213,6 @@ static int __devexit max9768_i2c_remove(struct i2c_client *client) | |||
215 | struct max9768 *max9768 = i2c_get_clientdata(client); | 213 | struct max9768 *max9768 = i2c_get_clientdata(client); |
216 | 214 | ||
217 | snd_soc_unregister_codec(&client->dev); | 215 | snd_soc_unregister_codec(&client->dev); |
218 | regmap_exit(max9768->regmap); | ||
219 | 216 | ||
220 | if (gpio_is_valid(max9768->shdn_gpio)) | 217 | if (gpio_is_valid(max9768->shdn_gpio)) |
221 | gpio_free(max9768->shdn_gpio); | 218 | gpio_free(max9768->shdn_gpio); |
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 3264a5169306..b858264235c4 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -2098,13 +2098,13 @@ static const struct i2c_device_id max98088_i2c_id[] = { | |||
2098 | MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); | 2098 | MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); |
2099 | 2099 | ||
2100 | static struct i2c_driver max98088_i2c_driver = { | 2100 | static struct i2c_driver max98088_i2c_driver = { |
2101 | .driver = { | 2101 | .driver = { |
2102 | .name = "max98088", | 2102 | .name = "max98088", |
2103 | .owner = THIS_MODULE, | 2103 | .owner = THIS_MODULE, |
2104 | }, | 2104 | }, |
2105 | .probe = max98088_i2c_probe, | 2105 | .probe = max98088_i2c_probe, |
2106 | .remove = __devexit_p(max98088_i2c_remove), | 2106 | .remove = max98088_i2c_remove, |
2107 | .id_table = max98088_i2c_id, | 2107 | .id_table = max98088_i2c_id, |
2108 | }; | 2108 | }; |
2109 | 2109 | ||
2110 | module_i2c_driver(max98088_i2c_driver); | 2110 | module_i2c_driver(max98088_i2c_driver); |
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c new file mode 100644 index 000000000000..c9772ca3da4f --- /dev/null +++ b/sound/soc/codecs/max98090.c | |||
@@ -0,0 +1,577 @@ | |||
1 | /* | ||
2 | * max98090.c -- MAX98090 ALSA SoC Audio driver | ||
3 | * based on Rev0p8 datasheet | ||
4 | * | ||
5 | * Copyright (C) 2012 Renesas Solutions Corp. | ||
6 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
7 | * | ||
8 | * Based on | ||
9 | * | ||
10 | * max98095.c | ||
11 | * Copyright 2011 Maxim Integrated Products | ||
12 | * | ||
13 | * https://github.com/hardkernel/linux/commit/\ | ||
14 | * 3417d7166b17113b3b33b0a337c74d1c7cc313df#sound/soc/codecs/max98090.c | ||
15 | * Copyright 2011 Maxim Integrated Products | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or modify | ||
18 | * it under the terms of the GNU General Public License version 2 as | ||
19 | * published by the Free Software Foundation. | ||
20 | */ | ||
21 | |||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/regmap.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include <sound/tlv.h> | ||
27 | |||
28 | /* | ||
29 | * | ||
30 | * MAX98090 Registers Definition | ||
31 | * | ||
32 | */ | ||
33 | |||
34 | /* RESET / STATUS / INTERRUPT REGISTERS */ | ||
35 | #define MAX98090_0x00_SW_RESET 0x00 | ||
36 | #define MAX98090_0x01_INT_STS 0x01 | ||
37 | #define MAX98090_0x02_JACK_STS 0x02 | ||
38 | #define MAX98090_0x03_INT_MASK 0x03 | ||
39 | |||
40 | /* QUICK SETUP REGISTERS */ | ||
41 | #define MAX98090_0x04_SYS_CLK 0x04 | ||
42 | #define MAX98090_0x05_SAMPLE_RATE 0x05 | ||
43 | #define MAX98090_0x06_DAI_IF 0x06 | ||
44 | #define MAX98090_0x07_DAC_PATH 0x07 | ||
45 | #define MAX98090_0x08_MIC_TO_ADC 0x08 | ||
46 | #define MAX98090_0x09_LINE_TO_ADC 0x09 | ||
47 | #define MAX98090_0x0A_ANALOG_MIC_LOOP 0x0A | ||
48 | #define MAX98090_0x0B_ANALOG_LINE_LOOP 0x0B | ||
49 | |||
50 | /* ANALOG INPUT CONFIGURATION REGISTERS */ | ||
51 | #define MAX98090_0x0D_INPUT_CONFIG 0x0D | ||
52 | #define MAX98090_0x0E_LINE_IN_LVL 0x0E | ||
53 | #define MAX98090_0x0F_LINI_IN_CFG 0x0F | ||
54 | #define MAX98090_0x10_MIC1_IN_LVL 0x10 | ||
55 | #define MAX98090_0x11_MIC2_IN_LVL 0x11 | ||
56 | |||
57 | /* MICROPHONE CONFIGURATION REGISTERS */ | ||
58 | #define MAX98090_0x12_MIC_BIAS_VOL 0x12 | ||
59 | #define MAX98090_0x13_DIGITAL_MIC_CFG 0x13 | ||
60 | #define MAX98090_0x14_DIGITAL_MIC_MODE 0x14 | ||
61 | |||
62 | /* ADC PATH AND CONFIGURATION REGISTERS */ | ||
63 | #define MAX98090_0x15_L_ADC_MIX 0x15 | ||
64 | #define MAX98090_0x16_R_ADC_MIX 0x16 | ||
65 | #define MAX98090_0x17_L_ADC_LVL 0x17 | ||
66 | #define MAX98090_0x18_R_ADC_LVL 0x18 | ||
67 | #define MAX98090_0x19_ADC_BIQUAD_LVL 0x19 | ||
68 | #define MAX98090_0x1A_ADC_SIDETONE 0x1A | ||
69 | |||
70 | /* CLOCK CONFIGURATION REGISTERS */ | ||
71 | #define MAX98090_0x1B_SYS_CLK 0x1B | ||
72 | #define MAX98090_0x1C_CLK_MODE 0x1C | ||
73 | #define MAX98090_0x1D_ANY_CLK1 0x1D | ||
74 | #define MAX98090_0x1E_ANY_CLK2 0x1E | ||
75 | #define MAX98090_0x1F_ANY_CLK3 0x1F | ||
76 | #define MAX98090_0x20_ANY_CLK4 0x20 | ||
77 | #define MAX98090_0x21_MASTER_MODE 0x21 | ||
78 | |||
79 | /* INTERFACE CONTROL REGISTERS */ | ||
80 | #define MAX98090_0x22_DAI_IF_FMT 0x22 | ||
81 | #define MAX98090_0x23_DAI_TDM_FMT1 0x23 | ||
82 | #define MAX98090_0x24_DAI_TDM_FMT2 0x24 | ||
83 | #define MAX98090_0x25_DAI_IO_CFG 0x25 | ||
84 | #define MAX98090_0x26_FILTER_CFG 0x26 | ||
85 | #define MAX98090_0x27_DAI_PLAYBACK_LVL 0x27 | ||
86 | #define MAX98090_0x28_EQ_PLAYBACK_LVL 0x28 | ||
87 | |||
88 | /* HEADPHONE CONTROL REGISTERS */ | ||
89 | #define MAX98090_0x29_L_HP_MIX 0x29 | ||
90 | #define MAX98090_0x2A_R_HP_MIX 0x2A | ||
91 | #define MAX98090_0x2B_HP_CTR 0x2B | ||
92 | #define MAX98090_0x2C_L_HP_VOL 0x2C | ||
93 | #define MAX98090_0x2D_R_HP_VOL 0x2D | ||
94 | |||
95 | /* SPEAKER CONFIGURATION REGISTERS */ | ||
96 | #define MAX98090_0x2E_L_SPK_MIX 0x2E | ||
97 | #define MAX98090_0x2F_R_SPK_MIX 0x2F | ||
98 | #define MAX98090_0x30_SPK_CTR 0x30 | ||
99 | #define MAX98090_0x31_L_SPK_VOL 0x31 | ||
100 | #define MAX98090_0x32_R_SPK_VOL 0x32 | ||
101 | |||
102 | /* ALC CONFIGURATION REGISTERS */ | ||
103 | #define MAX98090_0x33_ALC_TIMING 0x33 | ||
104 | #define MAX98090_0x34_ALC_COMPRESSOR 0x34 | ||
105 | #define MAX98090_0x35_ALC_EXPANDER 0x35 | ||
106 | #define MAX98090_0x36_ALC_GAIN 0x36 | ||
107 | |||
108 | /* RECEIVER AND LINE_OUTPUT REGISTERS */ | ||
109 | #define MAX98090_0x37_RCV_LOUT_L_MIX 0x37 | ||
110 | #define MAX98090_0x38_RCV_LOUT_L_CNTL 0x38 | ||
111 | #define MAX98090_0x39_RCV_LOUT_L_VOL 0x39 | ||
112 | #define MAX98090_0x3A_LOUT_R_MIX 0x3A | ||
113 | #define MAX98090_0x3B_LOUT_R_CNTL 0x3B | ||
114 | #define MAX98090_0x3C_LOUT_R_VOL 0x3C | ||
115 | |||
116 | /* JACK DETECT AND ENABLE REGISTERS */ | ||
117 | #define MAX98090_0x3D_JACK_DETECT 0x3D | ||
118 | #define MAX98090_0x3E_IN_ENABLE 0x3E | ||
119 | #define MAX98090_0x3F_OUT_ENABLE 0x3F | ||
120 | #define MAX98090_0x40_LVL_CTR 0x40 | ||
121 | #define MAX98090_0x41_DSP_FILTER_ENABLE 0x41 | ||
122 | |||
123 | /* BIAS AND POWER MODE CONFIGURATION REGISTERS */ | ||
124 | #define MAX98090_0x42_BIAS_CTR 0x42 | ||
125 | #define MAX98090_0x43_DAC_CTR 0x43 | ||
126 | #define MAX98090_0x44_ADC_CTR 0x44 | ||
127 | #define MAX98090_0x45_DEV_SHUTDOWN 0x45 | ||
128 | |||
129 | /* REVISION ID REGISTER */ | ||
130 | #define MAX98090_0xFF_REV_ID 0xFF | ||
131 | |||
132 | #define MAX98090_REG_MAX_CACHED 0x45 | ||
133 | #define MAX98090_REG_END 0xFF | ||
134 | |||
135 | /* | ||
136 | * | ||
137 | * MAX98090 Registers Bit Fields | ||
138 | * | ||
139 | */ | ||
140 | |||
141 | /* MAX98090_0x06_DAI_IF */ | ||
142 | #define MAX98090_DAI_IF_MASK 0x3F | ||
143 | #define MAX98090_RJ_M (1 << 5) | ||
144 | #define MAX98090_RJ_S (1 << 4) | ||
145 | #define MAX98090_LJ_M (1 << 3) | ||
146 | #define MAX98090_LJ_S (1 << 2) | ||
147 | #define MAX98090_I2S_M (1 << 1) | ||
148 | #define MAX98090_I2S_S (1 << 0) | ||
149 | |||
150 | /* MAX98090_0x45_DEV_SHUTDOWN */ | ||
151 | #define MAX98090_SHDNRUN (1 << 7) | ||
152 | |||
153 | /* codec private data */ | ||
154 | struct max98090_priv { | ||
155 | struct regmap *regmap; | ||
156 | }; | ||
157 | |||
158 | static const struct reg_default max98090_reg_defaults[] = { | ||
159 | /* RESET / STATUS / INTERRUPT REGISTERS */ | ||
160 | {MAX98090_0x00_SW_RESET, 0x00}, | ||
161 | {MAX98090_0x01_INT_STS, 0x00}, | ||
162 | {MAX98090_0x02_JACK_STS, 0x00}, | ||
163 | {MAX98090_0x03_INT_MASK, 0x04}, | ||
164 | |||
165 | /* QUICK SETUP REGISTERS */ | ||
166 | {MAX98090_0x04_SYS_CLK, 0x00}, | ||
167 | {MAX98090_0x05_SAMPLE_RATE, 0x00}, | ||
168 | {MAX98090_0x06_DAI_IF, 0x00}, | ||
169 | {MAX98090_0x07_DAC_PATH, 0x00}, | ||
170 | {MAX98090_0x08_MIC_TO_ADC, 0x00}, | ||
171 | {MAX98090_0x09_LINE_TO_ADC, 0x00}, | ||
172 | {MAX98090_0x0A_ANALOG_MIC_LOOP, 0x00}, | ||
173 | {MAX98090_0x0B_ANALOG_LINE_LOOP, 0x00}, | ||
174 | |||
175 | /* ANALOG INPUT CONFIGURATION REGISTERS */ | ||
176 | {MAX98090_0x0D_INPUT_CONFIG, 0x00}, | ||
177 | {MAX98090_0x0E_LINE_IN_LVL, 0x1B}, | ||
178 | {MAX98090_0x0F_LINI_IN_CFG, 0x00}, | ||
179 | {MAX98090_0x10_MIC1_IN_LVL, 0x11}, | ||
180 | {MAX98090_0x11_MIC2_IN_LVL, 0x11}, | ||
181 | |||
182 | /* MICROPHONE CONFIGURATION REGISTERS */ | ||
183 | {MAX98090_0x12_MIC_BIAS_VOL, 0x00}, | ||
184 | {MAX98090_0x13_DIGITAL_MIC_CFG, 0x00}, | ||
185 | {MAX98090_0x14_DIGITAL_MIC_MODE, 0x00}, | ||
186 | |||
187 | /* ADC PATH AND CONFIGURATION REGISTERS */ | ||
188 | {MAX98090_0x15_L_ADC_MIX, 0x00}, | ||
189 | {MAX98090_0x16_R_ADC_MIX, 0x00}, | ||
190 | {MAX98090_0x17_L_ADC_LVL, 0x03}, | ||
191 | {MAX98090_0x18_R_ADC_LVL, 0x03}, | ||
192 | {MAX98090_0x19_ADC_BIQUAD_LVL, 0x00}, | ||
193 | {MAX98090_0x1A_ADC_SIDETONE, 0x00}, | ||
194 | |||
195 | /* CLOCK CONFIGURATION REGISTERS */ | ||
196 | {MAX98090_0x1B_SYS_CLK, 0x00}, | ||
197 | {MAX98090_0x1C_CLK_MODE, 0x00}, | ||
198 | {MAX98090_0x1D_ANY_CLK1, 0x00}, | ||
199 | {MAX98090_0x1E_ANY_CLK2, 0x00}, | ||
200 | {MAX98090_0x1F_ANY_CLK3, 0x00}, | ||
201 | {MAX98090_0x20_ANY_CLK4, 0x00}, | ||
202 | {MAX98090_0x21_MASTER_MODE, 0x00}, | ||
203 | |||
204 | /* INTERFACE CONTROL REGISTERS */ | ||
205 | {MAX98090_0x22_DAI_IF_FMT, 0x00}, | ||
206 | {MAX98090_0x23_DAI_TDM_FMT1, 0x00}, | ||
207 | {MAX98090_0x24_DAI_TDM_FMT2, 0x00}, | ||
208 | {MAX98090_0x25_DAI_IO_CFG, 0x00}, | ||
209 | {MAX98090_0x26_FILTER_CFG, 0x80}, | ||
210 | {MAX98090_0x27_DAI_PLAYBACK_LVL, 0x00}, | ||
211 | {MAX98090_0x28_EQ_PLAYBACK_LVL, 0x00}, | ||
212 | |||
213 | /* HEADPHONE CONTROL REGISTERS */ | ||
214 | {MAX98090_0x29_L_HP_MIX, 0x00}, | ||
215 | {MAX98090_0x2A_R_HP_MIX, 0x00}, | ||
216 | {MAX98090_0x2B_HP_CTR, 0x00}, | ||
217 | {MAX98090_0x2C_L_HP_VOL, 0x1A}, | ||
218 | {MAX98090_0x2D_R_HP_VOL, 0x1A}, | ||
219 | |||
220 | /* SPEAKER CONFIGURATION REGISTERS */ | ||
221 | {MAX98090_0x2E_L_SPK_MIX, 0x00}, | ||
222 | {MAX98090_0x2F_R_SPK_MIX, 0x00}, | ||
223 | {MAX98090_0x30_SPK_CTR, 0x00}, | ||
224 | {MAX98090_0x31_L_SPK_VOL, 0x2C}, | ||
225 | {MAX98090_0x32_R_SPK_VOL, 0x2C}, | ||
226 | |||
227 | /* ALC CONFIGURATION REGISTERS */ | ||
228 | {MAX98090_0x33_ALC_TIMING, 0x00}, | ||
229 | {MAX98090_0x34_ALC_COMPRESSOR, 0x00}, | ||
230 | {MAX98090_0x35_ALC_EXPANDER, 0x00}, | ||
231 | {MAX98090_0x36_ALC_GAIN, 0x00}, | ||
232 | |||
233 | /* RECEIVER AND LINE_OUTPUT REGISTERS */ | ||
234 | {MAX98090_0x37_RCV_LOUT_L_MIX, 0x00}, | ||
235 | {MAX98090_0x38_RCV_LOUT_L_CNTL, 0x00}, | ||
236 | {MAX98090_0x39_RCV_LOUT_L_VOL, 0x15}, | ||
237 | {MAX98090_0x3A_LOUT_R_MIX, 0x00}, | ||
238 | {MAX98090_0x3B_LOUT_R_CNTL, 0x00}, | ||
239 | {MAX98090_0x3C_LOUT_R_VOL, 0x15}, | ||
240 | |||
241 | /* JACK DETECT AND ENABLE REGISTERS */ | ||
242 | {MAX98090_0x3D_JACK_DETECT, 0x00}, | ||
243 | {MAX98090_0x3E_IN_ENABLE, 0x00}, | ||
244 | {MAX98090_0x3F_OUT_ENABLE, 0x00}, | ||
245 | {MAX98090_0x40_LVL_CTR, 0x00}, | ||
246 | {MAX98090_0x41_DSP_FILTER_ENABLE, 0x00}, | ||
247 | |||
248 | /* BIAS AND POWER MODE CONFIGURATION REGISTERS */ | ||
249 | {MAX98090_0x42_BIAS_CTR, 0x00}, | ||
250 | {MAX98090_0x43_DAC_CTR, 0x00}, | ||
251 | {MAX98090_0x44_ADC_CTR, 0x06}, | ||
252 | {MAX98090_0x45_DEV_SHUTDOWN, 0x00}, | ||
253 | }; | ||
254 | |||
255 | static const unsigned int max98090_hp_tlv[] = { | ||
256 | TLV_DB_RANGE_HEAD(5), | ||
257 | 0x0, 0x6, TLV_DB_SCALE_ITEM(-6700, 400, 0), | ||
258 | 0x7, 0xE, TLV_DB_SCALE_ITEM(-4000, 300, 0), | ||
259 | 0xF, 0x15, TLV_DB_SCALE_ITEM(-1700, 200, 0), | ||
260 | 0x16, 0x1B, TLV_DB_SCALE_ITEM(-400, 100, 0), | ||
261 | 0x1C, 0x1F, TLV_DB_SCALE_ITEM(150, 50, 0), | ||
262 | }; | ||
263 | |||
264 | static struct snd_kcontrol_new max98090_snd_controls[] = { | ||
265 | SOC_DOUBLE_R_TLV("Headphone Volume", MAX98090_0x2C_L_HP_VOL, | ||
266 | MAX98090_0x2D_R_HP_VOL, 0, 31, 0, max98090_hp_tlv), | ||
267 | }; | ||
268 | |||
269 | /* Left HeadPhone Mixer Switch */ | ||
270 | static struct snd_kcontrol_new max98090_left_hp_mixer_controls[] = { | ||
271 | SOC_DAPM_SINGLE("DACR Switch", MAX98090_0x29_L_HP_MIX, 1, 1, 0), | ||
272 | SOC_DAPM_SINGLE("DACL Switch", MAX98090_0x29_L_HP_MIX, 0, 1, 0), | ||
273 | }; | ||
274 | |||
275 | /* Right HeadPhone Mixer Switch */ | ||
276 | static struct snd_kcontrol_new max98090_right_hp_mixer_controls[] = { | ||
277 | SOC_DAPM_SINGLE("DACR Switch", MAX98090_0x2A_R_HP_MIX, 1, 1, 0), | ||
278 | SOC_DAPM_SINGLE("DACL Switch", MAX98090_0x2A_R_HP_MIX, 0, 1, 0), | ||
279 | }; | ||
280 | |||
281 | static struct snd_soc_dapm_widget max98090_dapm_widgets[] = { | ||
282 | /* Output */ | ||
283 | SND_SOC_DAPM_OUTPUT("HPL"), | ||
284 | SND_SOC_DAPM_OUTPUT("HPR"), | ||
285 | |||
286 | /* PGA */ | ||
287 | SND_SOC_DAPM_PGA("HPL Out", MAX98090_0x3F_OUT_ENABLE, 7, 0, NULL, 0), | ||
288 | SND_SOC_DAPM_PGA("HPR Out", MAX98090_0x3F_OUT_ENABLE, 6, 0, NULL, 0), | ||
289 | |||
290 | /* Mixer */ | ||
291 | SND_SOC_DAPM_MIXER("HPL Mixer", SND_SOC_NOPM, 0, 0, | ||
292 | max98090_left_hp_mixer_controls, | ||
293 | ARRAY_SIZE(max98090_left_hp_mixer_controls)), | ||
294 | |||
295 | SND_SOC_DAPM_MIXER("HPR Mixer", SND_SOC_NOPM, 0, 0, | ||
296 | max98090_right_hp_mixer_controls, | ||
297 | ARRAY_SIZE(max98090_right_hp_mixer_controls)), | ||
298 | |||
299 | /* DAC */ | ||
300 | SND_SOC_DAPM_DAC("DACL", "Hifi Playback", MAX98090_0x3F_OUT_ENABLE, 0, 0), | ||
301 | SND_SOC_DAPM_DAC("DACR", "Hifi Playback", MAX98090_0x3F_OUT_ENABLE, 1, 0), | ||
302 | }; | ||
303 | |||
304 | static struct snd_soc_dapm_route max98090_audio_map[] = { | ||
305 | /* Output */ | ||
306 | {"HPL", NULL, "HPL Out"}, | ||
307 | {"HPR", NULL, "HPR Out"}, | ||
308 | |||
309 | /* PGA */ | ||
310 | {"HPL Out", NULL, "HPL Mixer"}, | ||
311 | {"HPR Out", NULL, "HPR Mixer"}, | ||
312 | |||
313 | /* Mixer*/ | ||
314 | {"HPL Mixer", "DACR Switch", "DACR"}, | ||
315 | {"HPL Mixer", "DACL Switch", "DACL"}, | ||
316 | |||
317 | {"HPR Mixer", "DACR Switch", "DACR"}, | ||
318 | {"HPR Mixer", "DACL Switch", "DACL"}, | ||
319 | }; | ||
320 | |||
321 | static bool max98090_volatile(struct device *dev, unsigned int reg) | ||
322 | { | ||
323 | if ((reg == MAX98090_0x01_INT_STS) || | ||
324 | (reg == MAX98090_0x02_JACK_STS) || | ||
325 | (reg > MAX98090_REG_MAX_CACHED)) | ||
326 | return true; | ||
327 | |||
328 | return false; | ||
329 | } | ||
330 | |||
331 | static int max98090_dai_hw_params(struct snd_pcm_substream *substream, | ||
332 | struct snd_pcm_hw_params *params, | ||
333 | struct snd_soc_dai *dai) | ||
334 | { | ||
335 | struct snd_soc_codec *codec = dai->codec; | ||
336 | unsigned int val; | ||
337 | |||
338 | switch (params_rate(params)) { | ||
339 | case 96000: | ||
340 | val = 1 << 5; | ||
341 | break; | ||
342 | case 32000: | ||
343 | val = 1 << 4; | ||
344 | break; | ||
345 | case 48000: | ||
346 | val = 1 << 3; | ||
347 | break; | ||
348 | case 44100: | ||
349 | val = 1 << 2; | ||
350 | break; | ||
351 | case 16000: | ||
352 | val = 1 << 1; | ||
353 | break; | ||
354 | case 8000: | ||
355 | val = 1 << 0; | ||
356 | break; | ||
357 | default: | ||
358 | dev_err(codec->dev, "unsupported rate\n"); | ||
359 | return -EINVAL; | ||
360 | } | ||
361 | snd_soc_update_bits(codec, MAX98090_0x05_SAMPLE_RATE, 0x03F, val); | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static int max98090_dai_set_sysclk(struct snd_soc_dai *dai, | ||
367 | int clk_id, unsigned int freq, int dir) | ||
368 | { | ||
369 | struct snd_soc_codec *codec = dai->codec; | ||
370 | unsigned int val; | ||
371 | |||
372 | snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN, | ||
373 | MAX98090_SHDNRUN, 0); | ||
374 | |||
375 | switch (freq) { | ||
376 | case 26000000: | ||
377 | val = 1 << 7; | ||
378 | break; | ||
379 | case 19200000: | ||
380 | val = 1 << 6; | ||
381 | break; | ||
382 | case 13000000: | ||
383 | val = 1 << 5; | ||
384 | break; | ||
385 | case 12288000: | ||
386 | val = 1 << 4; | ||
387 | break; | ||
388 | case 12000000: | ||
389 | val = 1 << 3; | ||
390 | break; | ||
391 | case 11289600: | ||
392 | val = 1 << 2; | ||
393 | break; | ||
394 | default: | ||
395 | dev_err(codec->dev, "Invalid master clock frequency\n"); | ||
396 | return -EINVAL; | ||
397 | } | ||
398 | snd_soc_update_bits(codec, MAX98090_0x04_SYS_CLK, 0xFD, val); | ||
399 | |||
400 | snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN, | ||
401 | MAX98090_SHDNRUN, MAX98090_SHDNRUN); | ||
402 | |||
403 | dev_dbg(dai->dev, "sysclk is %uHz\n", freq); | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static int max98090_dai_set_fmt(struct snd_soc_dai *dai, | ||
409 | unsigned int fmt) | ||
410 | { | ||
411 | struct snd_soc_codec *codec = dai->codec; | ||
412 | int is_master; | ||
413 | u8 val; | ||
414 | |||
415 | /* master/slave mode */ | ||
416 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
417 | case SND_SOC_DAIFMT_CBM_CFM: | ||
418 | is_master = 1; | ||
419 | break; | ||
420 | case SND_SOC_DAIFMT_CBS_CFS: | ||
421 | is_master = 0; | ||
422 | break; | ||
423 | default: | ||
424 | dev_err(codec->dev, "unsupported clock\n"); | ||
425 | return -EINVAL; | ||
426 | } | ||
427 | |||
428 | /* format */ | ||
429 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
430 | case SND_SOC_DAIFMT_I2S: | ||
431 | val = (is_master) ? MAX98090_I2S_M : MAX98090_I2S_S; | ||
432 | break; | ||
433 | case SND_SOC_DAIFMT_RIGHT_J: | ||
434 | val = (is_master) ? MAX98090_RJ_M : MAX98090_RJ_S; | ||
435 | break; | ||
436 | case SND_SOC_DAIFMT_LEFT_J: | ||
437 | val = (is_master) ? MAX98090_LJ_M : MAX98090_LJ_S; | ||
438 | break; | ||
439 | default: | ||
440 | dev_err(codec->dev, "unsupported format\n"); | ||
441 | return -EINVAL; | ||
442 | } | ||
443 | snd_soc_update_bits(codec, MAX98090_0x06_DAI_IF, | ||
444 | MAX98090_DAI_IF_MASK, val); | ||
445 | |||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | #define MAX98090_RATES SNDRV_PCM_RATE_8000_96000 | ||
450 | #define MAX98090_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) | ||
451 | |||
452 | static struct snd_soc_dai_ops max98090_dai_ops = { | ||
453 | .set_sysclk = max98090_dai_set_sysclk, | ||
454 | .set_fmt = max98090_dai_set_fmt, | ||
455 | .hw_params = max98090_dai_hw_params, | ||
456 | }; | ||
457 | |||
458 | static struct snd_soc_dai_driver max98090_dai = { | ||
459 | .name = "max98090-Hifi", | ||
460 | .playback = { | ||
461 | .stream_name = "Playback", | ||
462 | .channels_min = 1, | ||
463 | .channels_max = 2, | ||
464 | .rates = MAX98090_RATES, | ||
465 | .formats = MAX98090_FORMATS, | ||
466 | }, | ||
467 | .ops = &max98090_dai_ops, | ||
468 | }; | ||
469 | |||
470 | static int max98090_probe(struct snd_soc_codec *codec) | ||
471 | { | ||
472 | struct max98090_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
473 | struct device *dev = codec->dev; | ||
474 | int ret; | ||
475 | |||
476 | codec->control_data = priv->regmap; | ||
477 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
478 | if (ret < 0) { | ||
479 | dev_err(dev, "Failed to set cache I/O: %d\n", ret); | ||
480 | return ret; | ||
481 | } | ||
482 | |||
483 | /* Device active */ | ||
484 | snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN, | ||
485 | MAX98090_SHDNRUN, MAX98090_SHDNRUN); | ||
486 | |||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | static int max98090_remove(struct snd_soc_codec *codec) | ||
491 | { | ||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | static struct snd_soc_codec_driver soc_codec_dev_max98090 = { | ||
496 | .probe = max98090_probe, | ||
497 | .remove = max98090_remove, | ||
498 | .controls = max98090_snd_controls, | ||
499 | .num_controls = ARRAY_SIZE(max98090_snd_controls), | ||
500 | .dapm_widgets = max98090_dapm_widgets, | ||
501 | .num_dapm_widgets = ARRAY_SIZE(max98090_dapm_widgets), | ||
502 | .dapm_routes = max98090_audio_map, | ||
503 | .num_dapm_routes = ARRAY_SIZE(max98090_audio_map), | ||
504 | }; | ||
505 | |||
506 | static const struct regmap_config max98090_regmap = { | ||
507 | .reg_bits = 8, | ||
508 | .val_bits = 8, | ||
509 | .max_register = MAX98090_REG_END, | ||
510 | .volatile_reg = max98090_volatile, | ||
511 | .cache_type = REGCACHE_RBTREE, | ||
512 | .reg_defaults = max98090_reg_defaults, | ||
513 | .num_reg_defaults = ARRAY_SIZE(max98090_reg_defaults), | ||
514 | }; | ||
515 | |||
516 | static int max98090_i2c_probe(struct i2c_client *i2c, | ||
517 | const struct i2c_device_id *id) | ||
518 | { | ||
519 | struct max98090_priv *priv; | ||
520 | struct device *dev = &i2c->dev; | ||
521 | unsigned int val; | ||
522 | int ret; | ||
523 | |||
524 | priv = devm_kzalloc(dev, sizeof(struct max98090_priv), | ||
525 | GFP_KERNEL); | ||
526 | if (!priv) | ||
527 | return -ENOMEM; | ||
528 | |||
529 | priv->regmap = devm_regmap_init_i2c(i2c, &max98090_regmap); | ||
530 | if (IS_ERR(priv->regmap)) { | ||
531 | ret = PTR_ERR(priv->regmap); | ||
532 | dev_err(dev, "Failed to init regmap: %d\n", ret); | ||
533 | return ret; | ||
534 | } | ||
535 | |||
536 | i2c_set_clientdata(i2c, priv); | ||
537 | |||
538 | ret = regmap_read(priv->regmap, MAX98090_0xFF_REV_ID, &val); | ||
539 | if (ret < 0) { | ||
540 | dev_err(dev, "Failed to read device revision: %d\n", ret); | ||
541 | return ret; | ||
542 | } | ||
543 | dev_info(dev, "revision 0x%02x\n", val); | ||
544 | |||
545 | ret = snd_soc_register_codec(dev, | ||
546 | &soc_codec_dev_max98090, | ||
547 | &max98090_dai, 1); | ||
548 | |||
549 | return ret; | ||
550 | } | ||
551 | |||
552 | static int max98090_i2c_remove(struct i2c_client *client) | ||
553 | { | ||
554 | snd_soc_unregister_codec(&client->dev); | ||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static const struct i2c_device_id max98090_i2c_id[] = { | ||
559 | { "max98090", 0 }, | ||
560 | { } | ||
561 | }; | ||
562 | MODULE_DEVICE_TABLE(i2c, max98090_i2c_id); | ||
563 | |||
564 | static struct i2c_driver max98090_i2c_driver = { | ||
565 | .driver = { | ||
566 | .name = "max98090", | ||
567 | .owner = THIS_MODULE, | ||
568 | }, | ||
569 | .probe = max98090_i2c_probe, | ||
570 | .remove = max98090_i2c_remove, | ||
571 | .id_table = max98090_i2c_id, | ||
572 | }; | ||
573 | module_i2c_driver(max98090_i2c_driver); | ||
574 | |||
575 | MODULE_DESCRIPTION("ALSA SoC MAX98090 driver"); | ||
576 | MODULE_AUTHOR("Peter Hsiang, Kuninori Morimoto"); | ||
577 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 960d0e93cce9..d6ca615489ee 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c | |||
@@ -1382,7 +1382,7 @@ static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream, | |||
1382 | timesofbclk); | 1382 | timesofbclk); |
1383 | if (coeff < 0) { | 1383 | if (coeff < 0) { |
1384 | dev_err(codec->dev, "Fail to get coeff\n"); | 1384 | dev_err(codec->dev, "Fail to get coeff\n"); |
1385 | return -EINVAL; | 1385 | return coeff; |
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | switch (params_format(params)) { | 1388 | switch (params_format(params)) { |
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c new file mode 100644 index 000000000000..38145ba74db8 --- /dev/null +++ b/sound/soc/codecs/si476x.c | |||
@@ -0,0 +1,255 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/slab.h> | ||
3 | #include <sound/pcm.h> | ||
4 | #include <sound/pcm_params.h> | ||
5 | #include <sound/soc.h> | ||
6 | #include <sound/initval.h> | ||
7 | |||
8 | #include <linux/i2c.h> | ||
9 | |||
10 | #include <linux/mfd/si476x-core.h> | ||
11 | |||
12 | enum si476x_audio_registers { | ||
13 | SI476X_DIGITAL_IO_OUTPUT_FORMAT = 0x0203, | ||
14 | SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE = 0x0202, | ||
15 | }; | ||
16 | |||
17 | enum si476x_digital_io_output_format { | ||
18 | SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT = 11, | ||
19 | SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT = 8, | ||
20 | }; | ||
21 | |||
22 | #define SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK ((0b111 << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | \ | ||
23 | (0b111 << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT)) | ||
24 | #define SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK (0b1111110) | ||
25 | |||
26 | enum si476x_daudio_formats { | ||
27 | SI476X_DAUDIO_MODE_I2S = (0x0 << 1), | ||
28 | SI476X_DAUDIO_MODE_DSP_A = (0x6 << 1), | ||
29 | SI476X_DAUDIO_MODE_DSP_B = (0x7 << 1), | ||
30 | SI476X_DAUDIO_MODE_LEFT_J = (0x8 << 1), | ||
31 | SI476X_DAUDIO_MODE_RIGHT_J = (0x9 << 1), | ||
32 | |||
33 | SI476X_DAUDIO_MODE_IB = (1 << 5), | ||
34 | SI476X_DAUDIO_MODE_IF = (1 << 6), | ||
35 | }; | ||
36 | |||
37 | enum si476x_pcm_format { | ||
38 | SI476X_PCM_FORMAT_S8 = 2, | ||
39 | SI476X_PCM_FORMAT_S16_LE = 4, | ||
40 | SI476X_PCM_FORMAT_S20_3LE = 5, | ||
41 | SI476X_PCM_FORMAT_S24_LE = 6, | ||
42 | }; | ||
43 | |||
44 | static unsigned int si476x_codec_read(struct snd_soc_codec *codec, | ||
45 | unsigned int reg) | ||
46 | { | ||
47 | int err; | ||
48 | struct si476x_core *core = codec->control_data; | ||
49 | |||
50 | si476x_core_lock(core); | ||
51 | err = si476x_core_cmd_get_property(core, reg); | ||
52 | si476x_core_unlock(core); | ||
53 | |||
54 | return err; | ||
55 | } | ||
56 | |||
57 | static int si476x_codec_write(struct snd_soc_codec *codec, | ||
58 | unsigned int reg, unsigned int val) | ||
59 | { | ||
60 | int err; | ||
61 | struct si476x_core *core = codec->control_data; | ||
62 | |||
63 | si476x_core_lock(core); | ||
64 | err = si476x_core_cmd_set_property(core, reg, val); | ||
65 | si476x_core_unlock(core); | ||
66 | |||
67 | return err; | ||
68 | } | ||
69 | |||
70 | static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
71 | unsigned int fmt) | ||
72 | { | ||
73 | int err; | ||
74 | u16 format = 0; | ||
75 | |||
76 | if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) | ||
77 | return -EINVAL; | ||
78 | |||
79 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
80 | case SND_SOC_DAIFMT_DSP_A: | ||
81 | format |= SI476X_DAUDIO_MODE_DSP_A; | ||
82 | break; | ||
83 | case SND_SOC_DAIFMT_DSP_B: | ||
84 | format |= SI476X_DAUDIO_MODE_DSP_B; | ||
85 | break; | ||
86 | case SND_SOC_DAIFMT_I2S: | ||
87 | format |= SI476X_DAUDIO_MODE_I2S; | ||
88 | break; | ||
89 | case SND_SOC_DAIFMT_RIGHT_J: | ||
90 | format |= SI476X_DAUDIO_MODE_RIGHT_J; | ||
91 | break; | ||
92 | case SND_SOC_DAIFMT_LEFT_J: | ||
93 | format |= SI476X_DAUDIO_MODE_LEFT_J; | ||
94 | break; | ||
95 | default: | ||
96 | return -EINVAL; | ||
97 | } | ||
98 | |||
99 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
100 | case SND_SOC_DAIFMT_DSP_A: | ||
101 | case SND_SOC_DAIFMT_DSP_B: | ||
102 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
103 | case SND_SOC_DAIFMT_NB_NF: | ||
104 | break; | ||
105 | case SND_SOC_DAIFMT_IB_NF: | ||
106 | format |= SI476X_DAUDIO_MODE_IB; | ||
107 | break; | ||
108 | default: | ||
109 | return -EINVAL; | ||
110 | } | ||
111 | break; | ||
112 | case SND_SOC_DAIFMT_I2S: | ||
113 | case SND_SOC_DAIFMT_RIGHT_J: | ||
114 | case SND_SOC_DAIFMT_LEFT_J: | ||
115 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
116 | case SND_SOC_DAIFMT_NB_NF: | ||
117 | break; | ||
118 | case SND_SOC_DAIFMT_IB_IF: | ||
119 | format |= SI476X_DAUDIO_MODE_IB | | ||
120 | SI476X_DAUDIO_MODE_IF; | ||
121 | break; | ||
122 | case SND_SOC_DAIFMT_IB_NF: | ||
123 | format |= SI476X_DAUDIO_MODE_IB; | ||
124 | break; | ||
125 | case SND_SOC_DAIFMT_NB_IF: | ||
126 | format |= SI476X_DAUDIO_MODE_IF; | ||
127 | break; | ||
128 | default: | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | break; | ||
132 | default: | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | |||
136 | err = snd_soc_update_bits(codec_dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT, | ||
137 | SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK, | ||
138 | format); | ||
139 | if (err < 0) { | ||
140 | dev_err(codec_dai->codec->dev, "Failed to set output format\n"); | ||
141 | return err; | ||
142 | } | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static int si476x_codec_hw_params(struct snd_pcm_substream *substream, | ||
148 | struct snd_pcm_hw_params *params, | ||
149 | struct snd_soc_dai *dai) | ||
150 | { | ||
151 | int rate, width, err; | ||
152 | |||
153 | rate = params_rate(params); | ||
154 | if (rate < 32000 || rate > 48000) { | ||
155 | dev_err(dai->codec->dev, "Rate: %d is not supported\n", rate); | ||
156 | return -EINVAL; | ||
157 | } | ||
158 | |||
159 | switch (params_format(params)) { | ||
160 | case SNDRV_PCM_FORMAT_S8: | ||
161 | width = SI476X_PCM_FORMAT_S8; | ||
162 | case SNDRV_PCM_FORMAT_S16_LE: | ||
163 | width = SI476X_PCM_FORMAT_S16_LE; | ||
164 | break; | ||
165 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
166 | width = SI476X_PCM_FORMAT_S20_3LE; | ||
167 | break; | ||
168 | case SNDRV_PCM_FORMAT_S24_LE: | ||
169 | width = SI476X_PCM_FORMAT_S24_LE; | ||
170 | break; | ||
171 | default: | ||
172 | return -EINVAL; | ||
173 | } | ||
174 | |||
175 | err = snd_soc_write(dai->codec, SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE, | ||
176 | rate); | ||
177 | if (err < 0) { | ||
178 | dev_err(dai->codec->dev, "Failed to set sample rate\n"); | ||
179 | return err; | ||
180 | } | ||
181 | |||
182 | err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT, | ||
183 | SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK, | ||
184 | (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | | ||
185 | (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT)); | ||
186 | if (err < 0) { | ||
187 | dev_err(dai->codec->dev, "Failed to set output width\n"); | ||
188 | return err; | ||
189 | } | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static int si476x_codec_probe(struct snd_soc_codec *codec) | ||
195 | { | ||
196 | codec->control_data = i2c_mfd_cell_to_core(codec->dev); | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static struct snd_soc_dai_ops si476x_dai_ops = { | ||
201 | .hw_params = si476x_codec_hw_params, | ||
202 | .set_fmt = si476x_codec_set_dai_fmt, | ||
203 | }; | ||
204 | |||
205 | static struct snd_soc_dai_driver si476x_dai = { | ||
206 | .name = "si476x-codec", | ||
207 | .capture = { | ||
208 | .stream_name = "Capture", | ||
209 | .channels_min = 2, | ||
210 | .channels_max = 2, | ||
211 | |||
212 | .rates = SNDRV_PCM_RATE_32000 | | ||
213 | SNDRV_PCM_RATE_44100 | | ||
214 | SNDRV_PCM_RATE_48000, | ||
215 | .formats = SNDRV_PCM_FMTBIT_S8 | | ||
216 | SNDRV_PCM_FMTBIT_S16_LE | | ||
217 | SNDRV_PCM_FMTBIT_S20_3LE | | ||
218 | SNDRV_PCM_FMTBIT_S24_LE | ||
219 | }, | ||
220 | .ops = &si476x_dai_ops, | ||
221 | }; | ||
222 | |||
223 | static struct snd_soc_codec_driver soc_codec_dev_si476x = { | ||
224 | .probe = si476x_codec_probe, | ||
225 | .read = si476x_codec_read, | ||
226 | .write = si476x_codec_write, | ||
227 | }; | ||
228 | |||
229 | static int __devinit si476x_platform_probe(struct platform_device *pdev) | ||
230 | { | ||
231 | return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_si476x, | ||
232 | &si476x_dai, 1); | ||
233 | } | ||
234 | |||
235 | static int __devexit si476x_platform_remove(struct platform_device *pdev) | ||
236 | { | ||
237 | snd_soc_unregister_codec(&pdev->dev); | ||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | MODULE_ALIAS("platform:si476x-codec"); | ||
242 | |||
243 | static struct platform_driver si476x_platform_driver = { | ||
244 | .driver = { | ||
245 | .name = "si476x-codec", | ||
246 | .owner = THIS_MODULE, | ||
247 | }, | ||
248 | .probe = si476x_platform_probe, | ||
249 | .remove = __devexit_p(si476x_platform_remove), | ||
250 | }; | ||
251 | module_platform_driver(si476x_platform_driver); | ||
252 | |||
253 | MODULE_AUTHOR("Andrey Smirnov <andrey.smirnov@convergeddevices.net>"); | ||
254 | MODULE_DESCRIPTION("ASoC Si4761/64 codec driver"); | ||
255 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index f230292ba96b..e39e08d5d8e4 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/pm.h> | 30 | #include <linux/pm.h> |
31 | #include <linux/gpio.h> | ||
31 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
32 | #include <linux/cdev.h> | 33 | #include <linux/cdev.h> |
33 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
@@ -65,6 +66,7 @@ struct aic32x4_priv { | |||
65 | u32 power_cfg; | 66 | u32 power_cfg; |
66 | u32 micpga_routing; | 67 | u32 micpga_routing; |
67 | bool swapdacs; | 68 | bool swapdacs; |
69 | int rstn_gpio; | ||
68 | }; | 70 | }; |
69 | 71 | ||
70 | /* 0dB min, 1dB steps */ | 72 | /* 0dB min, 1dB steps */ |
@@ -627,10 +629,20 @@ static int aic32x4_probe(struct snd_soc_codec *codec) | |||
627 | { | 629 | { |
628 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | 630 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); |
629 | u32 tmp_reg; | 631 | u32 tmp_reg; |
632 | int ret; | ||
630 | 633 | ||
631 | codec->hw_write = (hw_write_t) i2c_master_send; | 634 | codec->hw_write = (hw_write_t) i2c_master_send; |
632 | codec->control_data = aic32x4->control_data; | 635 | codec->control_data = aic32x4->control_data; |
633 | 636 | ||
637 | if (aic32x4->rstn_gpio >= 0) { | ||
638 | ret = devm_gpio_request_one(codec->dev, aic32x4->rstn_gpio, | ||
639 | GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); | ||
640 | if (ret != 0) | ||
641 | return ret; | ||
642 | ndelay(10); | ||
643 | gpio_set_value(aic32x4->rstn_gpio, 1); | ||
644 | } | ||
645 | |||
634 | snd_soc_write(codec, AIC32X4_RESET, 0x01); | 646 | snd_soc_write(codec, AIC32X4_RESET, 0x01); |
635 | 647 | ||
636 | /* Power platform configuration */ | 648 | /* Power platform configuration */ |
@@ -675,6 +687,16 @@ static int aic32x4_probe(struct snd_soc_codec *codec) | |||
675 | ARRAY_SIZE(aic32x4_snd_controls)); | 687 | ARRAY_SIZE(aic32x4_snd_controls)); |
676 | aic32x4_add_widgets(codec); | 688 | aic32x4_add_widgets(codec); |
677 | 689 | ||
690 | /* | ||
691 | * Workaround: for an unknown reason, the ADC needs to be powered up | ||
692 | * and down for the first capture to work properly. It seems related to | ||
693 | * a HW BUG or some kind of behavior not documented in the datasheet. | ||
694 | */ | ||
695 | tmp_reg = snd_soc_read(codec, AIC32X4_ADCSETUP); | ||
696 | snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg | | ||
697 | AIC32X4_LADC_EN | AIC32X4_RADC_EN); | ||
698 | snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg); | ||
699 | |||
678 | return 0; | 700 | return 0; |
679 | } | 701 | } |
680 | 702 | ||
@@ -713,10 +735,12 @@ static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c, | |||
713 | aic32x4->power_cfg = pdata->power_cfg; | 735 | aic32x4->power_cfg = pdata->power_cfg; |
714 | aic32x4->swapdacs = pdata->swapdacs; | 736 | aic32x4->swapdacs = pdata->swapdacs; |
715 | aic32x4->micpga_routing = pdata->micpga_routing; | 737 | aic32x4->micpga_routing = pdata->micpga_routing; |
738 | aic32x4->rstn_gpio = pdata->rstn_gpio; | ||
716 | } else { | 739 | } else { |
717 | aic32x4->power_cfg = 0; | 740 | aic32x4->power_cfg = 0; |
718 | aic32x4->swapdacs = false; | 741 | aic32x4->swapdacs = false; |
719 | aic32x4->micpga_routing = 0; | 742 | aic32x4->micpga_routing = 0; |
743 | aic32x4->rstn_gpio = -1; | ||
720 | } | 744 | } |
721 | 745 | ||
722 | ret = snd_soc_register_codec(&i2c->dev, | 746 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/tlv320aic32x4.h b/sound/soc/codecs/tlv320aic32x4.h index aae2b2440398..35774223fd91 100644 --- a/sound/soc/codecs/tlv320aic32x4.h +++ b/sound/soc/codecs/tlv320aic32x4.h | |||
@@ -94,6 +94,9 @@ | |||
94 | #define AIC32X4_WORD_LEN_24BITS 0x02 | 94 | #define AIC32X4_WORD_LEN_24BITS 0x02 |
95 | #define AIC32X4_WORD_LEN_32BITS 0x03 | 95 | #define AIC32X4_WORD_LEN_32BITS 0x03 |
96 | 96 | ||
97 | #define AIC32X4_LADC_EN (1 << 7) | ||
98 | #define AIC32X4_RADC_EN (1 << 6) | ||
99 | |||
97 | #define AIC32X4_I2S_MODE 0x00 | 100 | #define AIC32X4_I2S_MODE 0x00 |
98 | #define AIC32X4_DSP_MODE 0x01 | 101 | #define AIC32X4_DSP_MODE 0x01 |
99 | #define AIC32X4_RIGHT_JUSTIFIED_MODE 0x02 | 102 | #define AIC32X4_RIGHT_JUSTIFIED_MODE 0x02 |
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index 99afc003a084..40256b526259 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c | |||
@@ -31,6 +31,9 @@ | |||
31 | 31 | ||
32 | #define DEVICE_ID_WM0010 10 | 32 | #define DEVICE_ID_WM0010 10 |
33 | 33 | ||
34 | /* We only support v1 of the .dfw INFO record */ | ||
35 | #define INFO_VERSION 1 | ||
36 | |||
34 | enum dfw_cmd { | 37 | enum dfw_cmd { |
35 | DFW_CMD_FUSE = 0x01, | 38 | DFW_CMD_FUSE = 0x01, |
36 | DFW_CMD_CODE_HDR, | 39 | DFW_CMD_CODE_HDR, |
@@ -46,6 +49,13 @@ struct dfw_binrec { | |||
46 | uint8_t data[0]; | 49 | uint8_t data[0]; |
47 | } __packed; | 50 | } __packed; |
48 | 51 | ||
52 | struct dfw_inforec { | ||
53 | u8 info_version; | ||
54 | u8 tool_major_version; | ||
55 | u8 tool_minor_version; | ||
56 | u8 dsp_target; | ||
57 | }; | ||
58 | |||
49 | struct dfw_pllrec { | 59 | struct dfw_pllrec { |
50 | u8 command; | 60 | u8 command; |
51 | u32 length:24; | 61 | u32 length:24; |
@@ -97,7 +107,6 @@ struct wm0010_priv { | |||
97 | 107 | ||
98 | enum wm0010_state state; | 108 | enum wm0010_state state; |
99 | bool boot_failed; | 109 | bool boot_failed; |
100 | int boot_done; | ||
101 | bool ready; | 110 | bool ready; |
102 | bool pll_running; | 111 | bool pll_running; |
103 | int max_spi_freq; | 112 | int max_spi_freq; |
@@ -234,7 +243,7 @@ static void wm0010_boot_xfer_complete(void *data) | |||
234 | break; | 243 | break; |
235 | 244 | ||
236 | case 0x55555555: | 245 | case 0x55555555: |
237 | if (wm0010->boot_done == 0) | 246 | if (wm0010->state < WM0010_STAGE2) |
238 | break; | 247 | break; |
239 | dev_err(codec->dev, | 248 | dev_err(codec->dev, |
240 | "%d: ROM bootloader running in stage 2\n", i); | 249 | "%d: ROM bootloader running in stage 2\n", i); |
@@ -321,7 +330,6 @@ static void wm0010_boot_xfer_complete(void *data) | |||
321 | break; | 330 | break; |
322 | } | 331 | } |
323 | 332 | ||
324 | wm0010->boot_done++; | ||
325 | if (xfer->done) | 333 | if (xfer->done) |
326 | complete(xfer->done); | 334 | complete(xfer->done); |
327 | } | 335 | } |
@@ -334,94 +342,198 @@ static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len) | |||
334 | data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i])); | 342 | data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i])); |
335 | } | 343 | } |
336 | 344 | ||
337 | static int wm0010_boot(struct snd_soc_codec *codec) | 345 | static int wm0010_firmware_load(char *name, struct snd_soc_codec *codec) |
338 | { | 346 | { |
339 | struct spi_device *spi = to_spi_device(codec->dev); | 347 | struct spi_device *spi = to_spi_device(codec->dev); |
340 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | 348 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); |
341 | unsigned long flags; | ||
342 | struct list_head xfer_list; | 349 | struct list_head xfer_list; |
343 | struct wm0010_boot_xfer *xfer; | 350 | struct wm0010_boot_xfer *xfer; |
344 | int ret; | 351 | int ret; |
345 | struct completion done; | 352 | struct completion done; |
346 | const struct firmware *fw; | 353 | const struct firmware *fw; |
347 | const struct dfw_binrec *rec; | 354 | const struct dfw_binrec *rec; |
348 | struct spi_message m; | 355 | const struct dfw_inforec *inforec; |
349 | struct spi_transfer t; | 356 | u64 *img; |
350 | struct dfw_pllrec pll_rec; | 357 | u8 *out, dsp; |
351 | u32 *img, *p; | ||
352 | u64 *img_swap; | ||
353 | u8 *out; | ||
354 | u32 len, offset; | 358 | u32 len, offset; |
355 | int i; | ||
356 | 359 | ||
357 | spin_lock_irqsave(&wm0010->irq_lock, flags); | 360 | INIT_LIST_HEAD(&xfer_list); |
358 | if (wm0010->state != WM0010_POWER_OFF) | ||
359 | dev_warn(wm0010->dev, "DSP already powered up!\n"); | ||
360 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
361 | 361 | ||
362 | if (wm0010->sysclk > 26000000) { | 362 | ret = request_firmware(&fw, name, codec->dev); |
363 | dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n"); | 363 | if (ret != 0) { |
364 | ret = -ECANCELED; | 364 | dev_err(codec->dev, "Failed to request application: %d\n", |
365 | goto err; | 365 | ret); |
366 | return ret; | ||
366 | } | 367 | } |
367 | 368 | ||
368 | INIT_LIST_HEAD(&xfer_list); | 369 | rec = (const struct dfw_binrec *)fw->data; |
370 | inforec = (const struct dfw_inforec *)rec->data; | ||
371 | offset = 0; | ||
372 | dsp = inforec->dsp_target; | ||
373 | wm0010->boot_failed = false; | ||
374 | BUG_ON(!list_empty(&xfer_list)); | ||
375 | init_completion(&done); | ||
369 | 376 | ||
370 | mutex_lock(&wm0010->lock); | 377 | /* First record should be INFO */ |
371 | wm0010->pll_running = false; | 378 | if (rec->command != DFW_CMD_INFO) { |
379 | dev_err(codec->dev, "First record not INFO\r\n"); | ||
380 | ret = -EINVAL; | ||
381 | goto abort; | ||
382 | } | ||
372 | 383 | ||
373 | dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq); | 384 | if (inforec->info_version != INFO_VERSION) { |
385 | dev_err(codec->dev, | ||
386 | "Unsupported version (%02d) of INFO record\r\n", | ||
387 | inforec->info_version); | ||
388 | ret = -EINVAL; | ||
389 | goto abort; | ||
390 | } | ||
374 | 391 | ||
375 | ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies), | 392 | dev_dbg(codec->dev, "Version v%02d INFO record found\r\n", |
376 | wm0010->core_supplies); | 393 | inforec->info_version); |
377 | if (ret != 0) { | 394 | |
378 | dev_err(&spi->dev, "Failed to enable core supplies: %d\n", | 395 | /* Check it's a DSP file */ |
379 | ret); | 396 | if (dsp != DEVICE_ID_WM0010) { |
380 | mutex_unlock(&wm0010->lock); | 397 | dev_err(codec->dev, "Not a WM0010 firmware file.\r\n"); |
381 | goto err; | 398 | ret = -EINVAL; |
399 | goto abort; | ||
382 | } | 400 | } |
383 | 401 | ||
384 | ret = regulator_enable(wm0010->dbvdd); | 402 | /* Skip the info record as we don't need to send it */ |
385 | if (ret != 0) { | 403 | offset += ((rec->length) + 8); |
386 | dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret); | 404 | rec = (void *)&rec->data[rec->length]; |
387 | goto err_core; | 405 | |
406 | while (offset < fw->size) { | ||
407 | dev_dbg(codec->dev, | ||
408 | "Packet: command %d, data length = 0x%x\r\n", | ||
409 | rec->command, rec->length); | ||
410 | len = rec->length + 8; | ||
411 | |||
412 | out = kzalloc(len, GFP_KERNEL); | ||
413 | if (!out) { | ||
414 | dev_err(codec->dev, | ||
415 | "Failed to allocate RX buffer\n"); | ||
416 | ret = -ENOMEM; | ||
417 | goto abort1; | ||
418 | } | ||
419 | |||
420 | img = kzalloc(len, GFP_KERNEL); | ||
421 | if (!img) { | ||
422 | dev_err(codec->dev, | ||
423 | "Failed to allocate image buffer\n"); | ||
424 | ret = -ENOMEM; | ||
425 | goto abort1; | ||
426 | } | ||
427 | |||
428 | byte_swap_64((u64 *)&rec->command, img, len); | ||
429 | |||
430 | xfer = kzalloc(sizeof(*xfer), GFP_KERNEL); | ||
431 | if (!xfer) { | ||
432 | dev_err(codec->dev, "Failed to allocate xfer\n"); | ||
433 | ret = -ENOMEM; | ||
434 | goto abort1; | ||
435 | } | ||
436 | |||
437 | xfer->codec = codec; | ||
438 | list_add_tail(&xfer->list, &xfer_list); | ||
439 | |||
440 | spi_message_init(&xfer->m); | ||
441 | xfer->m.complete = wm0010_boot_xfer_complete; | ||
442 | xfer->m.context = xfer; | ||
443 | xfer->t.tx_buf = img; | ||
444 | xfer->t.rx_buf = out; | ||
445 | xfer->t.len = len; | ||
446 | xfer->t.bits_per_word = 8; | ||
447 | |||
448 | if (!wm0010->pll_running) { | ||
449 | xfer->t.speed_hz = wm0010->sysclk / 6; | ||
450 | } else { | ||
451 | xfer->t.speed_hz = wm0010->max_spi_freq; | ||
452 | |||
453 | if (wm0010->board_max_spi_speed && | ||
454 | (wm0010->board_max_spi_speed < wm0010->max_spi_freq)) | ||
455 | xfer->t.speed_hz = wm0010->board_max_spi_speed; | ||
456 | } | ||
457 | |||
458 | /* Store max usable spi frequency for later use */ | ||
459 | wm0010->max_spi_freq = xfer->t.speed_hz; | ||
460 | |||
461 | spi_message_add_tail(&xfer->t, &xfer->m); | ||
462 | |||
463 | offset += ((rec->length) + 8); | ||
464 | rec = (void *)&rec->data[rec->length]; | ||
465 | |||
466 | if (offset >= fw->size) { | ||
467 | dev_dbg(codec->dev, "All transfers scheduled\n"); | ||
468 | xfer->done = &done; | ||
469 | } | ||
470 | |||
471 | ret = spi_async(spi, &xfer->m); | ||
472 | if (ret != 0) { | ||
473 | dev_err(codec->dev, "Write failed: %d\n", ret); | ||
474 | goto abort1; | ||
475 | } | ||
476 | |||
477 | if (wm0010->boot_failed) { | ||
478 | dev_dbg(codec->dev, "Boot fail!\n"); | ||
479 | ret = -EINVAL; | ||
480 | goto abort1; | ||
481 | } | ||
388 | } | 482 | } |
389 | 483 | ||
390 | /* Release reset */ | 484 | wait_for_completion(&done); |
391 | gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value); | 485 | |
392 | spin_lock_irqsave(&wm0010->irq_lock, flags); | 486 | ret = 0; |
393 | wm0010->state = WM0010_OUT_OF_RESET; | 487 | |
394 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | 488 | abort1: |
489 | while (!list_empty(&xfer_list)) { | ||
490 | xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer, | ||
491 | list); | ||
492 | kfree(xfer->t.rx_buf); | ||
493 | kfree(xfer->t.tx_buf); | ||
494 | list_del(&xfer->list); | ||
495 | kfree(xfer); | ||
496 | } | ||
497 | |||
498 | abort: | ||
499 | release_firmware(fw); | ||
500 | return ret; | ||
501 | } | ||
502 | |||
503 | static int wm0010_stage2_load(struct snd_soc_codec *codec) | ||
504 | { | ||
505 | struct spi_device *spi = to_spi_device(codec->dev); | ||
506 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | ||
507 | const struct firmware *fw; | ||
508 | struct spi_message m; | ||
509 | struct spi_transfer t; | ||
510 | u32 *img; | ||
511 | u8 *out; | ||
512 | int i; | ||
513 | int ret = 0; | ||
395 | 514 | ||
396 | /* First the bootloader */ | ||
397 | ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev); | 515 | ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev); |
398 | if (ret != 0) { | 516 | if (ret != 0) { |
399 | dev_err(codec->dev, "Failed to request stage2 loader: %d\n", | 517 | dev_err(codec->dev, "Failed to request stage2 loader: %d\n", |
400 | ret); | 518 | ret); |
401 | goto abort; | 519 | return ret; |
402 | } | 520 | } |
403 | 521 | ||
404 | if (!wait_for_completion_timeout(&wm0010->boot_completion, | ||
405 | msecs_to_jiffies(10))) | ||
406 | dev_err(codec->dev, "Failed to get interrupt from DSP\n"); | ||
407 | |||
408 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
409 | wm0010->state = WM0010_BOOTROM; | ||
410 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
411 | |||
412 | dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size); | 522 | dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size); |
413 | 523 | ||
414 | /* Copy to local buffer first as vmalloc causes problems for dma */ | 524 | /* Copy to local buffer first as vmalloc causes problems for dma */ |
415 | img = kzalloc(fw->size, GFP_KERNEL); | 525 | img = kzalloc(fw->size, GFP_KERNEL); |
416 | if (!img) { | 526 | if (!img) { |
417 | dev_err(codec->dev, "Failed to allocate image buffer\n"); | 527 | dev_err(codec->dev, "Failed to allocate image buffer\n"); |
418 | goto abort; | 528 | ret = -ENOMEM; |
529 | goto abort2; | ||
419 | } | 530 | } |
420 | 531 | ||
421 | out = kzalloc(fw->size, GFP_KERNEL); | 532 | out = kzalloc(fw->size, GFP_KERNEL); |
422 | if (!out) { | 533 | if (!out) { |
423 | dev_err(codec->dev, "Failed to allocate output buffer\n"); | 534 | dev_err(codec->dev, "Failed to allocate output buffer\n"); |
424 | goto abort; | 535 | ret = -ENOMEM; |
536 | goto abort1; | ||
425 | } | 537 | } |
426 | 538 | ||
427 | memcpy(img, &fw->data[0], fw->size); | 539 | memcpy(img, &fw->data[0], fw->size); |
@@ -447,20 +559,97 @@ static int wm0010_boot(struct snd_soc_codec *codec) | |||
447 | /* Look for errors from the boot ROM */ | 559 | /* Look for errors from the boot ROM */ |
448 | for (i = 0; i < fw->size; i++) { | 560 | for (i = 0; i < fw->size; i++) { |
449 | if (out[i] != 0x55) { | 561 | if (out[i] != 0x55) { |
450 | ret = -EBUSY; | ||
451 | dev_err(codec->dev, "Boot ROM error: %x in %d\n", | 562 | dev_err(codec->dev, "Boot ROM error: %x in %d\n", |
452 | out[i], i); | 563 | out[i], i); |
453 | wm0010_mark_boot_failure(wm0010); | 564 | wm0010_mark_boot_failure(wm0010); |
565 | ret = -EBUSY; | ||
454 | goto abort; | 566 | goto abort; |
455 | } | 567 | } |
456 | } | 568 | } |
457 | 569 | abort: | |
458 | release_firmware(fw); | ||
459 | kfree(img); | ||
460 | kfree(out); | 570 | kfree(out); |
571 | abort1: | ||
572 | kfree(img); | ||
573 | abort2: | ||
574 | release_firmware(fw); | ||
575 | |||
576 | return ret; | ||
577 | } | ||
578 | |||
579 | static int wm0010_boot(struct snd_soc_codec *codec) | ||
580 | { | ||
581 | struct spi_device *spi = to_spi_device(codec->dev); | ||
582 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | ||
583 | unsigned long flags; | ||
584 | int ret; | ||
585 | const struct firmware *fw; | ||
586 | struct spi_message m; | ||
587 | struct spi_transfer t; | ||
588 | struct dfw_pllrec pll_rec; | ||
589 | u32 *p, len; | ||
590 | u64 *img_swap; | ||
591 | u8 *out; | ||
592 | int i; | ||
593 | |||
594 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
595 | if (wm0010->state != WM0010_POWER_OFF) | ||
596 | dev_warn(wm0010->dev, "DSP already powered up!\n"); | ||
597 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
598 | |||
599 | if (wm0010->sysclk > 26000000) { | ||
600 | dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n"); | ||
601 | ret = -ECANCELED; | ||
602 | goto err; | ||
603 | } | ||
604 | |||
605 | mutex_lock(&wm0010->lock); | ||
606 | wm0010->pll_running = false; | ||
607 | |||
608 | dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq); | ||
609 | |||
610 | ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies), | ||
611 | wm0010->core_supplies); | ||
612 | if (ret != 0) { | ||
613 | dev_err(&spi->dev, "Failed to enable core supplies: %d\n", | ||
614 | ret); | ||
615 | mutex_unlock(&wm0010->lock); | ||
616 | goto err; | ||
617 | } | ||
618 | |||
619 | ret = regulator_enable(wm0010->dbvdd); | ||
620 | if (ret != 0) { | ||
621 | dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret); | ||
622 | goto err_core; | ||
623 | } | ||
624 | |||
625 | /* Release reset */ | ||
626 | gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value); | ||
627 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
628 | wm0010->state = WM0010_OUT_OF_RESET; | ||
629 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
630 | |||
631 | /* First the bootloader */ | ||
632 | ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev); | ||
633 | if (ret != 0) { | ||
634 | dev_err(codec->dev, "Failed to request stage2 loader: %d\n", | ||
635 | ret); | ||
636 | goto abort; | ||
637 | } | ||
638 | |||
639 | if (!wait_for_completion_timeout(&wm0010->boot_completion, | ||
640 | msecs_to_jiffies(20))) | ||
641 | dev_err(codec->dev, "Failed to get interrupt from DSP\n"); | ||
642 | |||
643 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
644 | wm0010->state = WM0010_BOOTROM; | ||
645 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
646 | |||
647 | ret = wm0010_stage2_load(codec); | ||
648 | if (ret) | ||
649 | goto abort; | ||
461 | 650 | ||
462 | if (!wait_for_completion_timeout(&wm0010->boot_completion, | 651 | if (!wait_for_completion_timeout(&wm0010->boot_completion, |
463 | msecs_to_jiffies(10))) | 652 | msecs_to_jiffies(20))) |
464 | dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n"); | 653 | dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n"); |
465 | 654 | ||
466 | spin_lock_irqsave(&wm0010->irq_lock, flags); | 655 | spin_lock_irqsave(&wm0010->irq_lock, flags); |
@@ -535,110 +724,10 @@ static int wm0010_boot(struct snd_soc_codec *codec) | |||
535 | } else | 724 | } else |
536 | dev_dbg(codec->dev, "Not enabling DSP PLL."); | 725 | dev_dbg(codec->dev, "Not enabling DSP PLL."); |
537 | 726 | ||
538 | ret = request_firmware(&fw, "wm0010.dfw", codec->dev); | 727 | ret = wm0010_firmware_load("wm0010.dfw", codec); |
539 | if (ret != 0) { | ||
540 | dev_err(codec->dev, "Failed to request application: %d\n", | ||
541 | ret); | ||
542 | goto abort; | ||
543 | } | ||
544 | |||
545 | rec = (const struct dfw_binrec *)fw->data; | ||
546 | offset = 0; | ||
547 | wm0010->boot_done = 0; | ||
548 | wm0010->boot_failed = false; | ||
549 | BUG_ON(!list_empty(&xfer_list)); | ||
550 | init_completion(&done); | ||
551 | 728 | ||
552 | /* First record should be INFO */ | 729 | if (ret != 0) |
553 | if (rec->command != DFW_CMD_INFO) { | ||
554 | dev_err(codec->dev, "First record not INFO\r\n"); | ||
555 | goto abort; | ||
556 | } | ||
557 | |||
558 | /* Check it's a 0010 file */ | ||
559 | if (rec->data[0] != DEVICE_ID_WM0010) { | ||
560 | dev_err(codec->dev, "Not a WM0010 firmware file.\r\n"); | ||
561 | goto abort; | 730 | goto abort; |
562 | } | ||
563 | |||
564 | /* Skip the info record as we don't need to send it */ | ||
565 | offset += ((rec->length) + 8); | ||
566 | rec = (void *)&rec->data[rec->length]; | ||
567 | |||
568 | while (offset < fw->size) { | ||
569 | dev_dbg(codec->dev, | ||
570 | "Packet: command %d, data length = 0x%x\r\n", | ||
571 | rec->command, rec->length); | ||
572 | len = rec->length + 8; | ||
573 | |||
574 | out = kzalloc(len, GFP_KERNEL); | ||
575 | if (!out) { | ||
576 | dev_err(codec->dev, | ||
577 | "Failed to allocate RX buffer\n"); | ||
578 | goto abort; | ||
579 | } | ||
580 | |||
581 | img_swap = kzalloc(len, GFP_KERNEL); | ||
582 | if (!img_swap) { | ||
583 | dev_err(codec->dev, | ||
584 | "Failed to allocate image buffer\n"); | ||
585 | goto abort; | ||
586 | } | ||
587 | |||
588 | /* We need to re-order for 0010 */ | ||
589 | byte_swap_64((u64 *)&rec->command, img_swap, len); | ||
590 | |||
591 | xfer = kzalloc(sizeof(*xfer), GFP_KERNEL); | ||
592 | if (!xfer) { | ||
593 | dev_err(codec->dev, "Failed to allocate xfer\n"); | ||
594 | goto abort; | ||
595 | } | ||
596 | |||
597 | xfer->codec = codec; | ||
598 | list_add_tail(&xfer->list, &xfer_list); | ||
599 | |||
600 | spi_message_init(&xfer->m); | ||
601 | xfer->m.complete = wm0010_boot_xfer_complete; | ||
602 | xfer->m.context = xfer; | ||
603 | xfer->t.tx_buf = img_swap; | ||
604 | xfer->t.rx_buf = out; | ||
605 | xfer->t.len = len; | ||
606 | xfer->t.bits_per_word = 8; | ||
607 | |||
608 | if (!wm0010->pll_running) { | ||
609 | xfer->t.speed_hz = wm0010->sysclk / 6; | ||
610 | } else { | ||
611 | xfer->t.speed_hz = wm0010->max_spi_freq; | ||
612 | |||
613 | if (wm0010->board_max_spi_speed && | ||
614 | (wm0010->board_max_spi_speed < wm0010->max_spi_freq)) | ||
615 | xfer->t.speed_hz = wm0010->board_max_spi_speed; | ||
616 | } | ||
617 | |||
618 | /* Store max usable spi frequency for later use */ | ||
619 | wm0010->max_spi_freq = xfer->t.speed_hz; | ||
620 | |||
621 | spi_message_add_tail(&xfer->t, &xfer->m); | ||
622 | |||
623 | offset += ((rec->length) + 8); | ||
624 | rec = (void *)&rec->data[rec->length]; | ||
625 | |||
626 | if (offset >= fw->size) { | ||
627 | dev_dbg(codec->dev, "All transfers scheduled\n"); | ||
628 | xfer->done = &done; | ||
629 | } | ||
630 | |||
631 | ret = spi_async(spi, &xfer->m); | ||
632 | if (ret != 0) { | ||
633 | dev_err(codec->dev, "Write failed: %d\n", ret); | ||
634 | goto abort; | ||
635 | } | ||
636 | |||
637 | if (wm0010->boot_failed) | ||
638 | goto abort; | ||
639 | } | ||
640 | |||
641 | wait_for_completion(&done); | ||
642 | 731 | ||
643 | spin_lock_irqsave(&wm0010->irq_lock, flags); | 732 | spin_lock_irqsave(&wm0010->irq_lock, flags); |
644 | wm0010->state = WM0010_FIRMWARE; | 733 | wm0010->state = WM0010_FIRMWARE; |
@@ -646,17 +735,6 @@ static int wm0010_boot(struct snd_soc_codec *codec) | |||
646 | 735 | ||
647 | mutex_unlock(&wm0010->lock); | 736 | mutex_unlock(&wm0010->lock); |
648 | 737 | ||
649 | release_firmware(fw); | ||
650 | |||
651 | while (!list_empty(&xfer_list)) { | ||
652 | xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer, | ||
653 | list); | ||
654 | kfree(xfer->t.rx_buf); | ||
655 | kfree(xfer->t.tx_buf); | ||
656 | list_del(&xfer->list); | ||
657 | kfree(xfer); | ||
658 | } | ||
659 | |||
660 | return 0; | 738 | return 0; |
661 | 739 | ||
662 | abort: | 740 | abort: |
@@ -784,7 +862,6 @@ static irqreturn_t wm0010_irq(int irq, void *data) | |||
784 | struct wm0010_priv *wm0010 = data; | 862 | struct wm0010_priv *wm0010 = data; |
785 | 863 | ||
786 | switch (wm0010->state) { | 864 | switch (wm0010->state) { |
787 | case WM0010_POWER_OFF: | ||
788 | case WM0010_OUT_OF_RESET: | 865 | case WM0010_OUT_OF_RESET: |
789 | case WM0010_BOOTROM: | 866 | case WM0010_BOOTROM: |
790 | case WM0010_STAGE2: | 867 | case WM0010_STAGE2: |
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 683dc43b1d87..02750ab020de 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -646,7 +646,7 @@ static const struct snd_kcontrol_new wm2000_controls[] = { | |||
646 | static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w, | 646 | static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w, |
647 | struct snd_kcontrol *kcontrol, int event) | 647 | struct snd_kcontrol *kcontrol, int event) |
648 | { | 648 | { |
649 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 649 | struct snd_soc_codec *codec = w->codec; |
650 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); | 650 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); |
651 | 651 | ||
652 | if (SND_SOC_DAPM_EVENT_ON(event)) | 652 | if (SND_SOC_DAPM_EVENT_ON(event)) |
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index eab64a193989..ff45b02a9dff 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/firmware.h> | ||
18 | #include <linux/gcd.h> | 19 | #include <linux/gcd.h> |
19 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
20 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
@@ -32,6 +33,40 @@ | |||
32 | #include <sound/wm2200.h> | 33 | #include <sound/wm2200.h> |
33 | 34 | ||
34 | #include "wm2200.h" | 35 | #include "wm2200.h" |
36 | #include "wmfw.h" | ||
37 | #include "wm_adsp.h" | ||
38 | |||
39 | #define WM2200_DSP_CONTROL_1 0x00 | ||
40 | #define WM2200_DSP_CONTROL_2 0x02 | ||
41 | #define WM2200_DSP_CONTROL_3 0x03 | ||
42 | #define WM2200_DSP_CONTROL_4 0x04 | ||
43 | #define WM2200_DSP_CONTROL_5 0x06 | ||
44 | #define WM2200_DSP_CONTROL_6 0x07 | ||
45 | #define WM2200_DSP_CONTROL_7 0x08 | ||
46 | #define WM2200_DSP_CONTROL_8 0x09 | ||
47 | #define WM2200_DSP_CONTROL_9 0x0A | ||
48 | #define WM2200_DSP_CONTROL_10 0x0B | ||
49 | #define WM2200_DSP_CONTROL_11 0x0C | ||
50 | #define WM2200_DSP_CONTROL_12 0x0D | ||
51 | #define WM2200_DSP_CONTROL_13 0x0F | ||
52 | #define WM2200_DSP_CONTROL_14 0x10 | ||
53 | #define WM2200_DSP_CONTROL_15 0x11 | ||
54 | #define WM2200_DSP_CONTROL_16 0x12 | ||
55 | #define WM2200_DSP_CONTROL_17 0x13 | ||
56 | #define WM2200_DSP_CONTROL_18 0x14 | ||
57 | #define WM2200_DSP_CONTROL_19 0x16 | ||
58 | #define WM2200_DSP_CONTROL_20 0x17 | ||
59 | #define WM2200_DSP_CONTROL_21 0x18 | ||
60 | #define WM2200_DSP_CONTROL_22 0x1A | ||
61 | #define WM2200_DSP_CONTROL_23 0x1B | ||
62 | #define WM2200_DSP_CONTROL_24 0x1C | ||
63 | #define WM2200_DSP_CONTROL_25 0x1E | ||
64 | #define WM2200_DSP_CONTROL_26 0x20 | ||
65 | #define WM2200_DSP_CONTROL_27 0x21 | ||
66 | #define WM2200_DSP_CONTROL_28 0x22 | ||
67 | #define WM2200_DSP_CONTROL_29 0x23 | ||
68 | #define WM2200_DSP_CONTROL_30 0x24 | ||
69 | #define WM2200_DSP_CONTROL_31 0x26 | ||
35 | 70 | ||
36 | /* The code assumes DCVDD is generated internally */ | 71 | /* The code assumes DCVDD is generated internally */ |
37 | #define WM2200_NUM_CORE_SUPPLIES 2 | 72 | #define WM2200_NUM_CORE_SUPPLIES 2 |
@@ -49,6 +84,7 @@ struct wm2200_fll { | |||
49 | 84 | ||
50 | /* codec private data */ | 85 | /* codec private data */ |
51 | struct wm2200_priv { | 86 | struct wm2200_priv { |
87 | struct wm_adsp dsp[2]; | ||
52 | struct regmap *regmap; | 88 | struct regmap *regmap; |
53 | struct device *dev; | 89 | struct device *dev; |
54 | struct snd_soc_codec *codec; | 90 | struct snd_soc_codec *codec; |
@@ -64,6 +100,72 @@ struct wm2200_priv { | |||
64 | int sysclk; | 100 | int sysclk; |
65 | }; | 101 | }; |
66 | 102 | ||
103 | #define WM2200_DSP_RANGE_BASE (WM2200_MAX_REGISTER + 1) | ||
104 | #define WM2200_DSP_SPACING 12288 | ||
105 | |||
106 | #define WM2200_DSP1_DM_BASE (WM2200_DSP_RANGE_BASE + (0 * WM2200_DSP_SPACING)) | ||
107 | #define WM2200_DSP1_PM_BASE (WM2200_DSP_RANGE_BASE + (1 * WM2200_DSP_SPACING)) | ||
108 | #define WM2200_DSP1_ZM_BASE (WM2200_DSP_RANGE_BASE + (2 * WM2200_DSP_SPACING)) | ||
109 | #define WM2200_DSP2_DM_BASE (WM2200_DSP_RANGE_BASE + (3 * WM2200_DSP_SPACING)) | ||
110 | #define WM2200_DSP2_PM_BASE (WM2200_DSP_RANGE_BASE + (4 * WM2200_DSP_SPACING)) | ||
111 | #define WM2200_DSP2_ZM_BASE (WM2200_DSP_RANGE_BASE + (5 * WM2200_DSP_SPACING)) | ||
112 | |||
113 | static const struct regmap_range_cfg wm2200_ranges[] = { | ||
114 | { .name = "DSP1DM", .range_min = WM2200_DSP1_DM_BASE, | ||
115 | .range_max = WM2200_DSP1_DM_BASE + 12287, | ||
116 | .selector_reg = WM2200_DSP1_CONTROL_3, | ||
117 | .selector_mask = WM2200_DSP1_PAGE_BASE_DM_0_MASK, | ||
118 | .selector_shift = WM2200_DSP1_PAGE_BASE_DM_0_SHIFT, | ||
119 | .window_start = WM2200_DSP1_DM_0, .window_len = 2048, }, | ||
120 | |||
121 | { .name = "DSP1PM", .range_min = WM2200_DSP1_PM_BASE, | ||
122 | .range_max = WM2200_DSP1_PM_BASE + 12287, | ||
123 | .selector_reg = WM2200_DSP1_CONTROL_2, | ||
124 | .selector_mask = WM2200_DSP1_PAGE_BASE_PM_0_MASK, | ||
125 | .selector_shift = WM2200_DSP1_PAGE_BASE_PM_0_SHIFT, | ||
126 | .window_start = WM2200_DSP1_PM_0, .window_len = 768, }, | ||
127 | |||
128 | { .name = "DSP1ZM", .range_min = WM2200_DSP1_ZM_BASE, | ||
129 | .range_max = WM2200_DSP1_ZM_BASE + 2047, | ||
130 | .selector_reg = WM2200_DSP1_CONTROL_4, | ||
131 | .selector_mask = WM2200_DSP1_PAGE_BASE_ZM_0_MASK, | ||
132 | .selector_shift = WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT, | ||
133 | .window_start = WM2200_DSP1_ZM_0, .window_len = 1024, }, | ||
134 | |||
135 | { .name = "DSP2DM", .range_min = WM2200_DSP2_DM_BASE, | ||
136 | .range_max = WM2200_DSP2_DM_BASE + 4095, | ||
137 | .selector_reg = WM2200_DSP2_CONTROL_3, | ||
138 | .selector_mask = WM2200_DSP2_PAGE_BASE_DM_0_MASK, | ||
139 | .selector_shift = WM2200_DSP2_PAGE_BASE_DM_0_SHIFT, | ||
140 | .window_start = WM2200_DSP2_DM_0, .window_len = 2048, }, | ||
141 | |||
142 | { .name = "DSP2PM", .range_min = WM2200_DSP2_PM_BASE, | ||
143 | .range_max = WM2200_DSP2_PM_BASE + 11287, | ||
144 | .selector_reg = WM2200_DSP2_CONTROL_2, | ||
145 | .selector_mask = WM2200_DSP2_PAGE_BASE_PM_0_MASK, | ||
146 | .selector_shift = WM2200_DSP2_PAGE_BASE_PM_0_SHIFT, | ||
147 | .window_start = WM2200_DSP2_PM_0, .window_len = 768, }, | ||
148 | |||
149 | { .name = "DSP2ZM", .range_min = WM2200_DSP2_ZM_BASE, | ||
150 | .range_max = WM2200_DSP2_ZM_BASE + 2047, | ||
151 | .selector_reg = WM2200_DSP2_CONTROL_4, | ||
152 | .selector_mask = WM2200_DSP2_PAGE_BASE_ZM_0_MASK, | ||
153 | .selector_shift = WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT, | ||
154 | .window_start = WM2200_DSP2_ZM_0, .window_len = 1024, }, | ||
155 | }; | ||
156 | |||
157 | static const struct wm_adsp_region wm2200_dsp1_regions[] = { | ||
158 | { .type = WMFW_ADSP1_PM, .base = WM2200_DSP1_PM_BASE }, | ||
159 | { .type = WMFW_ADSP1_DM, .base = WM2200_DSP1_DM_BASE }, | ||
160 | { .type = WMFW_ADSP1_ZM, .base = WM2200_DSP1_ZM_BASE }, | ||
161 | }; | ||
162 | |||
163 | static const struct wm_adsp_region wm2200_dsp2_regions[] = { | ||
164 | { .type = WMFW_ADSP1_PM, .base = WM2200_DSP2_PM_BASE }, | ||
165 | { .type = WMFW_ADSP1_DM, .base = WM2200_DSP2_DM_BASE }, | ||
166 | { .type = WMFW_ADSP1_ZM, .base = WM2200_DSP2_ZM_BASE }, | ||
167 | }; | ||
168 | |||
67 | static struct reg_default wm2200_reg_defaults[] = { | 169 | static struct reg_default wm2200_reg_defaults[] = { |
68 | { 0x000B, 0x0000 }, /* R11 - Tone Generator 1 */ | 170 | { 0x000B, 0x0000 }, /* R11 - Tone Generator 1 */ |
69 | { 0x0102, 0x0000 }, /* R258 - Clocking 3 */ | 171 | { 0x0102, 0x0000 }, /* R258 - Clocking 3 */ |
@@ -407,6 +509,16 @@ static struct reg_default wm2200_reg_defaults[] = { | |||
407 | 509 | ||
408 | static bool wm2200_volatile_register(struct device *dev, unsigned int reg) | 510 | static bool wm2200_volatile_register(struct device *dev, unsigned int reg) |
409 | { | 511 | { |
512 | int i; | ||
513 | |||
514 | for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++) | ||
515 | if ((reg >= wm2200_ranges[i].window_start && | ||
516 | reg <= wm2200_ranges[i].window_start + | ||
517 | wm2200_ranges[i].window_len) || | ||
518 | (reg >= wm2200_ranges[i].range_min && | ||
519 | reg <= wm2200_ranges[i].range_max)) | ||
520 | return true; | ||
521 | |||
410 | switch (reg) { | 522 | switch (reg) { |
411 | case WM2200_SOFTWARE_RESET: | 523 | case WM2200_SOFTWARE_RESET: |
412 | case WM2200_DEVICE_REVISION: | 524 | case WM2200_DEVICE_REVISION: |
@@ -423,6 +535,16 @@ static bool wm2200_volatile_register(struct device *dev, unsigned int reg) | |||
423 | 535 | ||
424 | static bool wm2200_readable_register(struct device *dev, unsigned int reg) | 536 | static bool wm2200_readable_register(struct device *dev, unsigned int reg) |
425 | { | 537 | { |
538 | int i; | ||
539 | |||
540 | for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++) | ||
541 | if ((reg >= wm2200_ranges[i].window_start && | ||
542 | reg <= wm2200_ranges[i].window_start + | ||
543 | wm2200_ranges[i].window_len) || | ||
544 | (reg >= wm2200_ranges[i].range_min && | ||
545 | reg <= wm2200_ranges[i].range_max)) | ||
546 | return true; | ||
547 | |||
426 | switch (reg) { | 548 | switch (reg) { |
427 | case WM2200_SOFTWARE_RESET: | 549 | case WM2200_SOFTWARE_RESET: |
428 | case WM2200_DEVICE_REVISION: | 550 | case WM2200_DEVICE_REVISION: |
@@ -880,7 +1002,7 @@ static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0); | |||
880 | static const char *wm2200_mixer_texts[] = { | 1002 | static const char *wm2200_mixer_texts[] = { |
881 | "None", | 1003 | "None", |
882 | "Tone Generator", | 1004 | "Tone Generator", |
883 | "AEC loopback", | 1005 | "AEC Loopback", |
884 | "IN1L", | 1006 | "IN1L", |
885 | "IN1R", | 1007 | "IN1R", |
886 | "IN2L", | 1008 | "IN2L", |
@@ -976,6 +1098,20 @@ static int wm2200_mixer_values[] = { | |||
976 | static WM2200_MUX_CTL_DECL(name##_in3); \ | 1098 | static WM2200_MUX_CTL_DECL(name##_in3); \ |
977 | static WM2200_MUX_CTL_DECL(name##_in4) | 1099 | static WM2200_MUX_CTL_DECL(name##_in4) |
978 | 1100 | ||
1101 | #define WM2200_DSP_ENUMS(name, base_reg) \ | ||
1102 | static WM2200_MUX_ENUM_DECL(name##_aux1_enum, base_reg); \ | ||
1103 | static WM2200_MUX_ENUM_DECL(name##_aux2_enum, base_reg + 1); \ | ||
1104 | static WM2200_MUX_ENUM_DECL(name##_aux3_enum, base_reg + 2); \ | ||
1105 | static WM2200_MUX_ENUM_DECL(name##_aux4_enum, base_reg + 3); \ | ||
1106 | static WM2200_MUX_ENUM_DECL(name##_aux5_enum, base_reg + 4); \ | ||
1107 | static WM2200_MUX_ENUM_DECL(name##_aux6_enum, base_reg + 5); \ | ||
1108 | static WM2200_MUX_CTL_DECL(name##_aux1); \ | ||
1109 | static WM2200_MUX_CTL_DECL(name##_aux2); \ | ||
1110 | static WM2200_MUX_CTL_DECL(name##_aux3); \ | ||
1111 | static WM2200_MUX_CTL_DECL(name##_aux4); \ | ||
1112 | static WM2200_MUX_CTL_DECL(name##_aux5); \ | ||
1113 | static WM2200_MUX_CTL_DECL(name##_aux6); | ||
1114 | |||
979 | static const struct snd_kcontrol_new wm2200_snd_controls[] = { | 1115 | static const struct snd_kcontrol_new wm2200_snd_controls[] = { |
980 | SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL, | 1116 | SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL, |
981 | WM2200_IN1_OSR_SHIFT, 1, 0), | 1117 | WM2200_IN1_OSR_SHIFT, 1, 0), |
@@ -1051,6 +1187,9 @@ WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE); | |||
1051 | WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE); | 1187 | WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE); |
1052 | WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE); | 1188 | WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE); |
1053 | 1189 | ||
1190 | WM2200_DSP_ENUMS(DSP1, WM2200_DSP1AUX1MIX_INPUT_1_SOURCE); | ||
1191 | WM2200_DSP_ENUMS(DSP2, WM2200_DSP2AUX1MIX_INPUT_1_SOURCE); | ||
1192 | |||
1054 | WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE); | 1193 | WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE); |
1055 | WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); | 1194 | WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); |
1056 | 1195 | ||
@@ -1064,8 +1203,19 @@ WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); | |||
1064 | WM2200_MUX(name_str " Input 4", &name##_in4_mux), \ | 1203 | WM2200_MUX(name_str " Input 4", &name##_in4_mux), \ |
1065 | SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) | 1204 | SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) |
1066 | 1205 | ||
1206 | #define WM2200_DSP_WIDGETS(name, name_str) \ | ||
1207 | WM2200_MIXER_WIDGETS(name##L, name_str "L"), \ | ||
1208 | WM2200_MIXER_WIDGETS(name##R, name_str "R"), \ | ||
1209 | WM2200_MUX(name_str " Aux 1", &name##_aux1_mux), \ | ||
1210 | WM2200_MUX(name_str " Aux 2", &name##_aux2_mux), \ | ||
1211 | WM2200_MUX(name_str " Aux 3", &name##_aux3_mux), \ | ||
1212 | WM2200_MUX(name_str " Aux 4", &name##_aux4_mux), \ | ||
1213 | WM2200_MUX(name_str " Aux 5", &name##_aux5_mux), \ | ||
1214 | WM2200_MUX(name_str " Aux 6", &name##_aux6_mux) | ||
1215 | |||
1067 | #define WM2200_MIXER_INPUT_ROUTES(name) \ | 1216 | #define WM2200_MIXER_INPUT_ROUTES(name) \ |
1068 | { name, "Tone Generator", "Tone Generator" }, \ | 1217 | { name, "Tone Generator", "Tone Generator" }, \ |
1218 | { name, "AEC Loopback", "AEC Loopback" }, \ | ||
1069 | { name, "IN1L", "IN1L PGA" }, \ | 1219 | { name, "IN1L", "IN1L PGA" }, \ |
1070 | { name, "IN1R", "IN1R PGA" }, \ | 1220 | { name, "IN1R", "IN1R PGA" }, \ |
1071 | { name, "IN2L", "IN2L PGA" }, \ | 1221 | { name, "IN2L", "IN2L PGA" }, \ |
@@ -1106,6 +1256,33 @@ WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); | |||
1106 | WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \ | 1256 | WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \ |
1107 | WM2200_MIXER_INPUT_ROUTES(name " Input 4") | 1257 | WM2200_MIXER_INPUT_ROUTES(name " Input 4") |
1108 | 1258 | ||
1259 | #define WM2200_DSP_AUX_ROUTES(name) \ | ||
1260 | { name, NULL, name " Aux 1" }, \ | ||
1261 | { name, NULL, name " Aux 2" }, \ | ||
1262 | { name, NULL, name " Aux 3" }, \ | ||
1263 | { name, NULL, name " Aux 4" }, \ | ||
1264 | { name, NULL, name " Aux 5" }, \ | ||
1265 | { name, NULL, name " Aux 6" }, \ | ||
1266 | WM2200_MIXER_INPUT_ROUTES(name " Aux 1"), \ | ||
1267 | WM2200_MIXER_INPUT_ROUTES(name " Aux 2"), \ | ||
1268 | WM2200_MIXER_INPUT_ROUTES(name " Aux 3"), \ | ||
1269 | WM2200_MIXER_INPUT_ROUTES(name " Aux 4"), \ | ||
1270 | WM2200_MIXER_INPUT_ROUTES(name " Aux 5"), \ | ||
1271 | WM2200_MIXER_INPUT_ROUTES(name " Aux 6") | ||
1272 | |||
1273 | static const char *wm2200_aec_loopback_texts[] = { | ||
1274 | "OUT1L", "OUT1R", "OUT2L", "OUT2R", | ||
1275 | }; | ||
1276 | |||
1277 | static const struct soc_enum wm2200_aec_loopback = | ||
1278 | SOC_ENUM_SINGLE(WM2200_DAC_AEC_CONTROL_1, | ||
1279 | WM2200_AEC_LOOPBACK_SRC_SHIFT, | ||
1280 | ARRAY_SIZE(wm2200_aec_loopback_texts), | ||
1281 | wm2200_aec_loopback_texts); | ||
1282 | |||
1283 | static const struct snd_kcontrol_new wm2200_aec_loopback_mux = | ||
1284 | SOC_DAPM_ENUM("AEC Loopback", wm2200_aec_loopback); | ||
1285 | |||
1109 | static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = { | 1286 | static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = { |
1110 | SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0, | 1287 | SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0, |
1111 | NULL, 0), | 1288 | NULL, 0), |
@@ -1165,8 +1342,8 @@ SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0, | |||
1165 | SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0, | 1342 | SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0, |
1166 | NULL, 0), | 1343 | NULL, 0), |
1167 | 1344 | ||
1168 | SND_SOC_DAPM_PGA_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0), | 1345 | WM_ADSP1("DSP1", 0), |
1169 | SND_SOC_DAPM_PGA_E("DSP2", SND_SOC_NOPM, 1, 0, NULL, 0, NULL, 0), | 1346 | WM_ADSP1("DSP2", 1), |
1170 | 1347 | ||
1171 | SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, | 1348 | SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, |
1172 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0), | 1349 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0), |
@@ -1181,6 +1358,9 @@ SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4, | |||
1181 | SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5, | 1358 | SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5, |
1182 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0), | 1359 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0), |
1183 | 1360 | ||
1361 | SND_SOC_DAPM_MUX("AEC Loopback", WM2200_DAC_AEC_CONTROL_1, | ||
1362 | WM2200_AEC_LOOPBACK_ENA_SHIFT, 0, &wm2200_aec_loopback_mux), | ||
1363 | |||
1184 | SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES, | 1364 | SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES, |
1185 | WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0), | 1365 | WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0), |
1186 | SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES, | 1366 | SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES, |
@@ -1231,10 +1411,8 @@ WM2200_MIXER_WIDGETS(EQR, "EQR"), | |||
1231 | WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"), | 1411 | WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"), |
1232 | WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"), | 1412 | WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"), |
1233 | 1413 | ||
1234 | WM2200_MIXER_WIDGETS(DSP1L, "DSP1L"), | 1414 | WM2200_DSP_WIDGETS(DSP1, "DSP1"), |
1235 | WM2200_MIXER_WIDGETS(DSP1R, "DSP1R"), | 1415 | WM2200_DSP_WIDGETS(DSP2, "DSP2"), |
1236 | WM2200_MIXER_WIDGETS(DSP2L, "DSP2L"), | ||
1237 | WM2200_MIXER_WIDGETS(DSP2R, "DSP2R"), | ||
1238 | 1416 | ||
1239 | WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"), | 1417 | WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"), |
1240 | WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"), | 1418 | WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"), |
@@ -1326,11 +1504,19 @@ static const struct snd_soc_dapm_route wm2200_dapm_routes[] = { | |||
1326 | { "SPK", NULL, "OUT2L" }, | 1504 | { "SPK", NULL, "OUT2L" }, |
1327 | { "SPK", NULL, "OUT2R" }, | 1505 | { "SPK", NULL, "OUT2R" }, |
1328 | 1506 | ||
1507 | { "AEC Loopback", "OUT1L", "OUT1L" }, | ||
1508 | { "AEC Loopback", "OUT1R", "OUT1R" }, | ||
1509 | { "AEC Loopback", "OUT2L", "OUT2L" }, | ||
1510 | { "AEC Loopback", "OUT2R", "OUT2R" }, | ||
1511 | |||
1329 | WM2200_MIXER_ROUTES("DSP1", "DSP1L"), | 1512 | WM2200_MIXER_ROUTES("DSP1", "DSP1L"), |
1330 | WM2200_MIXER_ROUTES("DSP1", "DSP1R"), | 1513 | WM2200_MIXER_ROUTES("DSP1", "DSP1R"), |
1331 | WM2200_MIXER_ROUTES("DSP2", "DSP2L"), | 1514 | WM2200_MIXER_ROUTES("DSP2", "DSP2L"), |
1332 | WM2200_MIXER_ROUTES("DSP2", "DSP2R"), | 1515 | WM2200_MIXER_ROUTES("DSP2", "DSP2R"), |
1333 | 1516 | ||
1517 | WM2200_DSP_AUX_ROUTES("DSP1"), | ||
1518 | WM2200_DSP_AUX_ROUTES("DSP2"), | ||
1519 | |||
1334 | WM2200_MIXER_ROUTES("OUT1L", "OUT1L"), | 1520 | WM2200_MIXER_ROUTES("OUT1L", "OUT1L"), |
1335 | WM2200_MIXER_ROUTES("OUT1R", "OUT1R"), | 1521 | WM2200_MIXER_ROUTES("OUT1R", "OUT1R"), |
1336 | WM2200_MIXER_ROUTES("OUT2L", "OUT2L"), | 1522 | WM2200_MIXER_ROUTES("OUT2L", "OUT2L"), |
@@ -1968,12 +2154,15 @@ static const struct regmap_config wm2200_regmap = { | |||
1968 | .reg_bits = 16, | 2154 | .reg_bits = 16, |
1969 | .val_bits = 16, | 2155 | .val_bits = 16, |
1970 | 2156 | ||
1971 | .max_register = WM2200_MAX_REGISTER, | 2157 | .max_register = WM2200_MAX_REGISTER + (ARRAY_SIZE(wm2200_ranges) * |
2158 | WM2200_DSP_SPACING), | ||
1972 | .reg_defaults = wm2200_reg_defaults, | 2159 | .reg_defaults = wm2200_reg_defaults, |
1973 | .num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults), | 2160 | .num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults), |
1974 | .volatile_reg = wm2200_volatile_register, | 2161 | .volatile_reg = wm2200_volatile_register, |
1975 | .readable_reg = wm2200_readable_register, | 2162 | .readable_reg = wm2200_readable_register, |
1976 | .cache_type = REGCACHE_RBTREE, | 2163 | .cache_type = REGCACHE_RBTREE, |
2164 | .ranges = wm2200_ranges, | ||
2165 | .num_ranges = ARRAY_SIZE(wm2200_ranges), | ||
1977 | }; | 2166 | }; |
1978 | 2167 | ||
1979 | static const unsigned int wm2200_dig_vu[] = { | 2168 | static const unsigned int wm2200_dig_vu[] = { |
@@ -2011,14 +2200,30 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, | |||
2011 | wm2200->dev = &i2c->dev; | 2200 | wm2200->dev = &i2c->dev; |
2012 | init_completion(&wm2200->fll_lock); | 2201 | init_completion(&wm2200->fll_lock); |
2013 | 2202 | ||
2014 | wm2200->regmap = regmap_init_i2c(i2c, &wm2200_regmap); | 2203 | wm2200->regmap = devm_regmap_init_i2c(i2c, &wm2200_regmap); |
2015 | if (IS_ERR(wm2200->regmap)) { | 2204 | if (IS_ERR(wm2200->regmap)) { |
2016 | ret = PTR_ERR(wm2200->regmap); | 2205 | ret = PTR_ERR(wm2200->regmap); |
2017 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 2206 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
2018 | ret); | 2207 | ret); |
2019 | goto err; | 2208 | return ret; |
2209 | } | ||
2210 | |||
2211 | for (i = 0; i < 2; i++) { | ||
2212 | wm2200->dsp[i].type = WMFW_ADSP1; | ||
2213 | wm2200->dsp[i].part = "wm2200"; | ||
2214 | wm2200->dsp[i].num = i + 1; | ||
2215 | wm2200->dsp[i].dev = &i2c->dev; | ||
2216 | wm2200->dsp[i].regmap = wm2200->regmap; | ||
2020 | } | 2217 | } |
2021 | 2218 | ||
2219 | wm2200->dsp[0].base = WM2200_DSP1_CONTROL_1; | ||
2220 | wm2200->dsp[0].mem = wm2200_dsp1_regions; | ||
2221 | wm2200->dsp[0].num_mems = ARRAY_SIZE(wm2200_dsp1_regions); | ||
2222 | |||
2223 | wm2200->dsp[1].base = WM2200_DSP2_CONTROL_1; | ||
2224 | wm2200->dsp[1].mem = wm2200_dsp2_regions; | ||
2225 | wm2200->dsp[1].num_mems = ARRAY_SIZE(wm2200_dsp2_regions); | ||
2226 | |||
2022 | if (pdata) | 2227 | if (pdata) |
2023 | wm2200->pdata = *pdata; | 2228 | wm2200->pdata = *pdata; |
2024 | 2229 | ||
@@ -2027,12 +2232,13 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, | |||
2027 | for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++) | 2232 | for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++) |
2028 | wm2200->core_supplies[i].supply = wm2200_core_supply_names[i]; | 2233 | wm2200->core_supplies[i].supply = wm2200_core_supply_names[i]; |
2029 | 2234 | ||
2030 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm2200->core_supplies), | 2235 | ret = devm_regulator_bulk_get(&i2c->dev, |
2031 | wm2200->core_supplies); | 2236 | ARRAY_SIZE(wm2200->core_supplies), |
2237 | wm2200->core_supplies); | ||
2032 | if (ret != 0) { | 2238 | if (ret != 0) { |
2033 | dev_err(&i2c->dev, "Failed to request core supplies: %d\n", | 2239 | dev_err(&i2c->dev, "Failed to request core supplies: %d\n", |
2034 | ret); | 2240 | ret); |
2035 | goto err_regmap; | 2241 | return ret; |
2036 | } | 2242 | } |
2037 | 2243 | ||
2038 | ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies), | 2244 | ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies), |
@@ -2040,12 +2246,13 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, | |||
2040 | if (ret != 0) { | 2246 | if (ret != 0) { |
2041 | dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", | 2247 | dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", |
2042 | ret); | 2248 | ret); |
2043 | goto err_core; | 2249 | return ret; |
2044 | } | 2250 | } |
2045 | 2251 | ||
2046 | if (wm2200->pdata.ldo_ena) { | 2252 | if (wm2200->pdata.ldo_ena) { |
2047 | ret = gpio_request_one(wm2200->pdata.ldo_ena, | 2253 | ret = devm_gpio_request_one(&i2c->dev, wm2200->pdata.ldo_ena, |
2048 | GPIOF_OUT_INIT_HIGH, "WM2200 LDOENA"); | 2254 | GPIOF_OUT_INIT_HIGH, |
2255 | "WM2200 LDOENA"); | ||
2049 | if (ret < 0) { | 2256 | if (ret < 0) { |
2050 | dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", | 2257 | dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", |
2051 | wm2200->pdata.ldo_ena, ret); | 2258 | wm2200->pdata.ldo_ena, ret); |
@@ -2055,8 +2262,9 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, | |||
2055 | } | 2262 | } |
2056 | 2263 | ||
2057 | if (wm2200->pdata.reset) { | 2264 | if (wm2200->pdata.reset) { |
2058 | ret = gpio_request_one(wm2200->pdata.reset, | 2265 | ret = devm_gpio_request_one(&i2c->dev, wm2200->pdata.reset, |
2059 | GPIOF_OUT_INIT_HIGH, "WM2200 /RESET"); | 2266 | GPIOF_OUT_INIT_HIGH, |
2267 | "WM2200 /RESET"); | ||
2060 | if (ret < 0) { | 2268 | if (ret < 0) { |
2061 | dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", | 2269 | dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", |
2062 | wm2200->pdata.reset, ret); | 2270 | wm2200->pdata.reset, ret); |
@@ -2166,24 +2374,14 @@ static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, | |||
2166 | err_pm_runtime: | 2374 | err_pm_runtime: |
2167 | pm_runtime_disable(&i2c->dev); | 2375 | pm_runtime_disable(&i2c->dev); |
2168 | err_reset: | 2376 | err_reset: |
2169 | if (wm2200->pdata.reset) { | 2377 | if (wm2200->pdata.reset) |
2170 | gpio_set_value_cansleep(wm2200->pdata.reset, 0); | 2378 | gpio_set_value_cansleep(wm2200->pdata.reset, 0); |
2171 | gpio_free(wm2200->pdata.reset); | ||
2172 | } | ||
2173 | err_ldo: | 2379 | err_ldo: |
2174 | if (wm2200->pdata.ldo_ena) { | 2380 | if (wm2200->pdata.ldo_ena) |
2175 | gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); | 2381 | gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); |
2176 | gpio_free(wm2200->pdata.ldo_ena); | ||
2177 | } | ||
2178 | err_enable: | 2382 | err_enable: |
2179 | regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), | 2383 | regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), |
2180 | wm2200->core_supplies); | 2384 | wm2200->core_supplies); |
2181 | err_core: | ||
2182 | regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies), | ||
2183 | wm2200->core_supplies); | ||
2184 | err_regmap: | ||
2185 | regmap_exit(wm2200->regmap); | ||
2186 | err: | ||
2187 | return ret; | 2385 | return ret; |
2188 | } | 2386 | } |
2189 | 2387 | ||
@@ -2194,17 +2392,10 @@ static __devexit int wm2200_i2c_remove(struct i2c_client *i2c) | |||
2194 | snd_soc_unregister_codec(&i2c->dev); | 2392 | snd_soc_unregister_codec(&i2c->dev); |
2195 | if (i2c->irq) | 2393 | if (i2c->irq) |
2196 | free_irq(i2c->irq, wm2200); | 2394 | free_irq(i2c->irq, wm2200); |
2197 | if (wm2200->pdata.reset) { | 2395 | if (wm2200->pdata.reset) |
2198 | gpio_set_value_cansleep(wm2200->pdata.reset, 0); | 2396 | gpio_set_value_cansleep(wm2200->pdata.reset, 0); |
2199 | gpio_free(wm2200->pdata.reset); | 2397 | if (wm2200->pdata.ldo_ena) |
2200 | } | ||
2201 | if (wm2200->pdata.ldo_ena) { | ||
2202 | gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); | 2398 | gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); |
2203 | gpio_free(wm2200->pdata.ldo_ena); | ||
2204 | } | ||
2205 | regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies), | ||
2206 | wm2200->core_supplies); | ||
2207 | regmap_exit(wm2200->regmap); | ||
2208 | 2399 | ||
2209 | return 0; | 2400 | return 0; |
2210 | } | 2401 | } |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 7f567585832e..9f57996ff272 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -1233,7 +1233,7 @@ static const struct snd_soc_dapm_route wm5100_dapm_routes[] = { | |||
1233 | { "PWM2", NULL, "PWM2 Driver" }, | 1233 | { "PWM2", NULL, "PWM2 Driver" }, |
1234 | }; | 1234 | }; |
1235 | 1235 | ||
1236 | static const __devinitconst struct reg_default wm5100_reva_patches[] = { | 1236 | static const struct reg_default wm5100_reva_patches[] = { |
1237 | { WM5100_AUDIO_IF_1_10, 0 }, | 1237 | { WM5100_AUDIO_IF_1_10, 0 }, |
1238 | { WM5100_AUDIO_IF_1_11, 1 }, | 1238 | { WM5100_AUDIO_IF_1_11, 1 }, |
1239 | { WM5100_AUDIO_IF_1_12, 2 }, | 1239 | { WM5100_AUDIO_IF_1_12, 2 }, |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 7394e73fa43c..27f7e38e7eca 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include "arizona.h" | 32 | #include "arizona.h" |
33 | #include "wm5102.h" | 33 | #include "wm5102.h" |
34 | #include "wm_adsp.h" | ||
34 | 35 | ||
35 | struct wm5102_priv { | 36 | struct wm5102_priv { |
36 | struct arizona_priv core; | 37 | struct arizona_priv core; |
@@ -42,6 +43,13 @@ static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | |||
42 | static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); | 43 | static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); |
43 | static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); | 44 | static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); |
44 | 45 | ||
46 | static const struct wm_adsp_region wm5102_dsp1_regions[] = { | ||
47 | { .type = WMFW_ADSP2_PM, .base = 0x100000 }, | ||
48 | { .type = WMFW_ADSP2_ZM, .base = 0x180000 }, | ||
49 | { .type = WMFW_ADSP2_XM, .base = 0x190000 }, | ||
50 | { .type = WMFW_ADSP2_YM, .base = 0x1a8000 }, | ||
51 | }; | ||
52 | |||
45 | static const struct reg_default wm5102_sysclk_reva_patch[] = { | 53 | static const struct reg_default wm5102_sysclk_reva_patch[] = { |
46 | { 0x3000, 0x2225 }, | 54 | { 0x3000, 0x2225 }, |
47 | { 0x3001, 0x3a03 }, | 55 | { 0x3001, 0x3a03 }, |
@@ -627,11 +635,23 @@ SOC_DOUBLE_R_TLV("IN3 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L, | |||
627 | ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_DIG_VOL_SHIFT, | 635 | ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_DIG_VOL_SHIFT, |
628 | 0xbf, 0, digital_tlv), | 636 | 0xbf, 0, digital_tlv), |
629 | 637 | ||
638 | SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp), | ||
639 | SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp), | ||
640 | |||
630 | ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE), | 641 | ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE), |
631 | ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), | 642 | ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), |
632 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), | 643 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), |
633 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), | 644 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), |
634 | 645 | ||
646 | SND_SOC_BYTES_MASK("EQ1 Coefficeints", ARIZONA_EQ1_1, 21, | ||
647 | ARIZONA_EQ1_ENA_MASK), | ||
648 | SND_SOC_BYTES_MASK("EQ2 Coefficeints", ARIZONA_EQ2_1, 21, | ||
649 | ARIZONA_EQ2_ENA_MASK), | ||
650 | SND_SOC_BYTES_MASK("EQ3 Coefficeints", ARIZONA_EQ3_1, 21, | ||
651 | ARIZONA_EQ3_ENA_MASK), | ||
652 | SND_SOC_BYTES_MASK("EQ4 Coefficeints", ARIZONA_EQ4_1, 21, | ||
653 | ARIZONA_EQ4_ENA_MASK), | ||
654 | |||
635 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, | 655 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, |
636 | 24, 0, eq_tlv), | 656 | 24, 0, eq_tlv), |
637 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, | 657 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, |
@@ -687,6 +707,14 @@ ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), | |||
687 | ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), | 707 | ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), |
688 | ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), | 708 | ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), |
689 | 709 | ||
710 | SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1), | ||
711 | SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1), | ||
712 | SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1), | ||
713 | SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1), | ||
714 | |||
715 | ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), | ||
716 | ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), | ||
717 | |||
690 | SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode), | 718 | SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode), |
691 | SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), | 719 | SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), |
692 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), | 720 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), |
@@ -708,14 +736,6 @@ ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE), | |||
708 | ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), | 736 | ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), |
709 | ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), | 737 | ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), |
710 | 738 | ||
711 | SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L, | ||
712 | ARIZONA_OUT1_OSR_SHIFT, 1, 0), | ||
713 | SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L, | ||
714 | ARIZONA_OUT2_OSR_SHIFT, 1, 0), | ||
715 | SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L, | ||
716 | ARIZONA_OUT3_OSR_SHIFT, 1, 0), | ||
717 | SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L, | ||
718 | ARIZONA_OUT4_OSR_SHIFT, 1, 0), | ||
719 | SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, | 739 | SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, |
720 | ARIZONA_OUT5_OSR_SHIFT, 1, 0), | 740 | ARIZONA_OUT5_OSR_SHIFT, 1, 0), |
721 | 741 | ||
@@ -745,16 +765,8 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, | |||
745 | ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, | 765 | ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, |
746 | 0xbf, 0, digital_tlv), | 766 | 0xbf, 0, digital_tlv), |
747 | 767 | ||
748 | SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L, | 768 | SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), |
749 | ARIZONA_OUTPUT_PATH_CONFIG_1R, | 769 | SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), |
750 | ARIZONA_OUT1L_PGA_VOL_SHIFT, | ||
751 | 0x34, 0x40, 0, ana_tlv), | ||
752 | SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L, | ||
753 | ARIZONA_OUTPUT_PATH_CONFIG_2R, | ||
754 | ARIZONA_OUT2L_PGA_VOL_SHIFT, | ||
755 | 0x34, 0x40, 0, ana_tlv), | ||
756 | SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L, | ||
757 | ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv), | ||
758 | 770 | ||
759 | SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, | 771 | SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, |
760 | ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), | 772 | ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), |
@@ -819,11 +831,15 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE); | |||
819 | ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); | 831 | ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); |
820 | ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); | 832 | ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); |
821 | 833 | ||
822 | ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); | 834 | ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); |
823 | ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); | 835 | ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); |
824 | ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); | 836 | ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); |
825 | ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); | 837 | ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); |
838 | |||
839 | ARIZONA_MIXER_ENUMS(DSP1L, ARIZONA_DSP1LMIX_INPUT_1_SOURCE); | ||
840 | ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE); | ||
826 | 841 | ||
842 | ARIZONA_DSP_AUX_ENUMS(DSP1, ARIZONA_DSP1AUX1MIX_INPUT_1_SOURCE); | ||
827 | 843 | ||
828 | static const char *wm5102_aec_loopback_texts[] = { | 844 | static const char *wm5102_aec_loopback_texts[] = { |
829 | "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT", | 845 | "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT", |
@@ -864,6 +880,7 @@ SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), | |||
864 | 880 | ||
865 | SND_SOC_DAPM_SIGGEN("TONE"), | 881 | SND_SOC_DAPM_SIGGEN("TONE"), |
866 | SND_SOC_DAPM_SIGGEN("NOISE"), | 882 | SND_SOC_DAPM_SIGGEN("NOISE"), |
883 | SND_SOC_DAPM_SIGGEN("HAPTICS"), | ||
867 | 884 | ||
868 | SND_SOC_DAPM_INPUT("IN1L"), | 885 | SND_SOC_DAPM_INPUT("IN1L"), |
869 | SND_SOC_DAPM_INPUT("IN1R"), | 886 | SND_SOC_DAPM_INPUT("IN1R"), |
@@ -894,9 +911,9 @@ SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, | |||
894 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, | 911 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, |
895 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), | 912 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), |
896 | SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2, | 913 | SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2, |
897 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), | 914 | ARIZONA_MICB2_ENA_SHIFT, 0, NULL, 0), |
898 | SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3, | 915 | SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3, |
899 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), | 916 | ARIZONA_MICB3_ENA_SHIFT, 0, NULL, 0), |
900 | 917 | ||
901 | SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR, | 918 | SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR, |
902 | ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0), | 919 | ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0), |
@@ -996,6 +1013,8 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0, | |||
996 | SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, | 1013 | SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, |
997 | ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), | 1014 | ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), |
998 | 1015 | ||
1016 | ARIZONA_DSP_WIDGETS(DSP1, "DSP1"), | ||
1017 | |||
999 | SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, | 1018 | SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, |
1000 | ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), | 1019 | ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), |
1001 | 1020 | ||
@@ -1071,10 +1090,12 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), | |||
1071 | ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), | 1090 | ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), |
1072 | ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), | 1091 | ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), |
1073 | 1092 | ||
1074 | ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"), | 1093 | ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"), |
1075 | ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"), | 1094 | ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"), |
1076 | ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"), | 1095 | ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"), |
1077 | ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"), | 1096 | ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"), |
1097 | |||
1098 | WM_ADSP2("DSP1", 0), | ||
1078 | 1099 | ||
1079 | SND_SOC_DAPM_OUTPUT("HPOUT1L"), | 1100 | SND_SOC_DAPM_OUTPUT("HPOUT1L"), |
1080 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), | 1101 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), |
@@ -1094,6 +1115,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"), | |||
1094 | { name, "Noise Generator", "Noise Generator" }, \ | 1115 | { name, "Noise Generator", "Noise Generator" }, \ |
1095 | { name, "Tone Generator 1", "Tone Generator 1" }, \ | 1116 | { name, "Tone Generator 1", "Tone Generator 1" }, \ |
1096 | { name, "Tone Generator 2", "Tone Generator 2" }, \ | 1117 | { name, "Tone Generator 2", "Tone Generator 2" }, \ |
1118 | { name, "Haptics", "HAPTICS" }, \ | ||
1097 | { name, "AEC", "AEC Loopback" }, \ | 1119 | { name, "AEC", "AEC Loopback" }, \ |
1098 | { name, "IN1L", "IN1L PGA" }, \ | 1120 | { name, "IN1L", "IN1L PGA" }, \ |
1099 | { name, "IN1R", "IN1R PGA" }, \ | 1121 | { name, "IN1R", "IN1R PGA" }, \ |
@@ -1127,7 +1149,13 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"), | |||
1127 | { name, "ASRC1L", "ASRC1L" }, \ | 1149 | { name, "ASRC1L", "ASRC1L" }, \ |
1128 | { name, "ASRC1R", "ASRC1R" }, \ | 1150 | { name, "ASRC1R", "ASRC1R" }, \ |
1129 | { name, "ASRC2L", "ASRC2L" }, \ | 1151 | { name, "ASRC2L", "ASRC2L" }, \ |
1130 | { name, "ASRC2R", "ASRC2R" } | 1152 | { name, "ASRC2R", "ASRC2R" }, \ |
1153 | { name, "DSP1.1", "DSP1" }, \ | ||
1154 | { name, "DSP1.2", "DSP1" }, \ | ||
1155 | { name, "DSP1.3", "DSP1" }, \ | ||
1156 | { name, "DSP1.4", "DSP1" }, \ | ||
1157 | { name, "DSP1.5", "DSP1" }, \ | ||
1158 | { name, "DSP1.6", "DSP1" } | ||
1131 | 1159 | ||
1132 | static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | 1160 | static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { |
1133 | { "AIF2 Capture", NULL, "DBVDD2" }, | 1161 | { "AIF2 Capture", NULL, "DBVDD2" }, |
@@ -1213,6 +1241,11 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
1213 | { "IN3L PGA", NULL, "IN3L" }, | 1241 | { "IN3L PGA", NULL, "IN3L" }, |
1214 | { "IN3R PGA", NULL, "IN3R" }, | 1242 | { "IN3R PGA", NULL, "IN3R" }, |
1215 | 1243 | ||
1244 | { "ASRC1L", NULL, "ASRC1L Input" }, | ||
1245 | { "ASRC1R", NULL, "ASRC1R Input" }, | ||
1246 | { "ASRC2L", NULL, "ASRC2L Input" }, | ||
1247 | { "ASRC2R", NULL, "ASRC2R Input" }, | ||
1248 | |||
1216 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), | 1249 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), |
1217 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), | 1250 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), |
1218 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), | 1251 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), |
@@ -1255,10 +1288,12 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
1255 | ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), | 1288 | ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), |
1256 | ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), | 1289 | ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), |
1257 | 1290 | ||
1258 | ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"), | 1291 | ARIZONA_MUX_ROUTES("ASRC1L"), |
1259 | ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"), | 1292 | ARIZONA_MUX_ROUTES("ASRC1R"), |
1260 | ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), | 1293 | ARIZONA_MUX_ROUTES("ASRC2L"), |
1261 | ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), | 1294 | ARIZONA_MUX_ROUTES("ASRC2R"), |
1295 | |||
1296 | ARIZONA_DSP_ROUTES("DSP1"), | ||
1262 | 1297 | ||
1263 | { "AEC Loopback", "HPOUT1L", "OUT1L" }, | 1298 | { "AEC Loopback", "HPOUT1L", "OUT1L" }, |
1264 | { "AEC Loopback", "HPOUT1R", "OUT1R" }, | 1299 | { "AEC Loopback", "HPOUT1R", "OUT1R" }, |
@@ -1377,9 +1412,28 @@ static struct snd_soc_dai_driver wm5102_dai[] = { | |||
1377 | static int wm5102_codec_probe(struct snd_soc_codec *codec) | 1412 | static int wm5102_codec_probe(struct snd_soc_codec *codec) |
1378 | { | 1413 | { |
1379 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); | 1414 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); |
1415 | int ret; | ||
1380 | 1416 | ||
1381 | codec->control_data = priv->core.arizona->regmap; | 1417 | codec->control_data = priv->core.arizona->regmap; |
1382 | return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); | 1418 | |
1419 | ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); | ||
1420 | if (ret != 0) | ||
1421 | return ret; | ||
1422 | |||
1423 | snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); | ||
1424 | |||
1425 | priv->core.arizona->dapm = &codec->dapm; | ||
1426 | |||
1427 | return 0; | ||
1428 | } | ||
1429 | |||
1430 | static int wm5102_codec_remove(struct snd_soc_codec *codec) | ||
1431 | { | ||
1432 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
1433 | |||
1434 | priv->core.arizona->dapm = NULL; | ||
1435 | |||
1436 | return 0; | ||
1383 | } | 1437 | } |
1384 | 1438 | ||
1385 | #define WM5102_DIG_VU 0x0200 | 1439 | #define WM5102_DIG_VU 0x0200 |
@@ -1406,6 +1460,7 @@ static unsigned int wm5102_digital_vu[] = { | |||
1406 | 1460 | ||
1407 | static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { | 1461 | static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { |
1408 | .probe = wm5102_codec_probe, | 1462 | .probe = wm5102_codec_probe, |
1463 | .remove = wm5102_codec_remove, | ||
1409 | 1464 | ||
1410 | .idle_bias_off = true, | 1465 | .idle_bias_off = true, |
1411 | 1466 | ||
@@ -1424,7 +1479,7 @@ static int __devinit wm5102_probe(struct platform_device *pdev) | |||
1424 | { | 1479 | { |
1425 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); | 1480 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); |
1426 | struct wm5102_priv *wm5102; | 1481 | struct wm5102_priv *wm5102; |
1427 | int i; | 1482 | int i, ret; |
1428 | 1483 | ||
1429 | wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv), | 1484 | wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv), |
1430 | GFP_KERNEL); | 1485 | GFP_KERNEL); |
@@ -1434,6 +1489,19 @@ static int __devinit wm5102_probe(struct platform_device *pdev) | |||
1434 | 1489 | ||
1435 | wm5102->core.arizona = arizona; | 1490 | wm5102->core.arizona = arizona; |
1436 | 1491 | ||
1492 | wm5102->core.adsp[0].part = "wm5102"; | ||
1493 | wm5102->core.adsp[0].num = 1; | ||
1494 | wm5102->core.adsp[0].type = WMFW_ADSP2; | ||
1495 | wm5102->core.adsp[0].base = ARIZONA_DSP1_CONTROL_1; | ||
1496 | wm5102->core.adsp[0].dev = arizona->dev; | ||
1497 | wm5102->core.adsp[0].regmap = arizona->regmap; | ||
1498 | wm5102->core.adsp[0].mem = wm5102_dsp1_regions; | ||
1499 | wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions); | ||
1500 | |||
1501 | ret = wm_adsp2_init(&wm5102->core.adsp[0], true); | ||
1502 | if (ret != 0) | ||
1503 | return ret; | ||
1504 | |||
1437 | for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++) | 1505 | for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++) |
1438 | wm5102->fll[i].vco_mult = 1; | 1506 | wm5102->fll[i].vco_mult = 1; |
1439 | 1507 | ||
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 9211e4192f71..c57dc7468300 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -84,11 +84,23 @@ SOC_DOUBLE_R_TLV("IN4 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_4L, | |||
84 | ARIZONA_ADC_DIGITAL_VOLUME_4R, ARIZONA_IN4L_DIG_VOL_SHIFT, | 84 | ARIZONA_ADC_DIGITAL_VOLUME_4R, ARIZONA_IN4L_DIG_VOL_SHIFT, |
85 | 0xbf, 0, digital_tlv), | 85 | 0xbf, 0, digital_tlv), |
86 | 86 | ||
87 | SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp), | ||
88 | SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp), | ||
89 | |||
87 | ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE), | 90 | ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE), |
88 | ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), | 91 | ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), |
89 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), | 92 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), |
90 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), | 93 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), |
91 | 94 | ||
95 | SND_SOC_BYTES_MASK("EQ1 Coefficeints", ARIZONA_EQ1_1, 21, | ||
96 | ARIZONA_EQ1_ENA_MASK), | ||
97 | SND_SOC_BYTES_MASK("EQ2 Coefficeints", ARIZONA_EQ2_1, 21, | ||
98 | ARIZONA_EQ2_ENA_MASK), | ||
99 | SND_SOC_BYTES_MASK("EQ3 Coefficeints", ARIZONA_EQ3_1, 21, | ||
100 | ARIZONA_EQ3_ENA_MASK), | ||
101 | SND_SOC_BYTES_MASK("EQ4 Coefficeints", ARIZONA_EQ4_1, 21, | ||
102 | ARIZONA_EQ4_ENA_MASK), | ||
103 | |||
92 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, | 104 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, |
93 | 24, 0, eq_tlv), | 105 | 24, 0, eq_tlv), |
94 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, | 106 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, |
@@ -148,6 +160,11 @@ ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), | |||
148 | ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), | 160 | ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), |
149 | ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), | 161 | ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), |
150 | 162 | ||
163 | SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1), | ||
164 | SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1), | ||
165 | SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1), | ||
166 | SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1), | ||
167 | |||
151 | SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode), | 168 | SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode), |
152 | SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), | 169 | SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), |
153 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), | 170 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), |
@@ -243,6 +260,9 @@ SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, | |||
243 | SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT, | 260 | SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT, |
244 | ARIZONA_SPK2R_MUTE_SHIFT, 1, 1), | 261 | ARIZONA_SPK2R_MUTE_SHIFT, 1, 1), |
245 | 262 | ||
263 | SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), | ||
264 | SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), | ||
265 | |||
246 | ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE), | 266 | ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE), |
247 | ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE), | 267 | ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE), |
248 | ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE), | 268 | ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE), |
@@ -308,10 +328,10 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE); | |||
308 | ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); | 328 | ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); |
309 | ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); | 329 | ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); |
310 | 330 | ||
311 | ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); | 331 | ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); |
312 | ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); | 332 | ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); |
313 | ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); | 333 | ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); |
314 | ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); | 334 | ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); |
315 | 335 | ||
316 | static const char *wm5110_aec_loopback_texts[] = { | 336 | static const char *wm5110_aec_loopback_texts[] = { |
317 | "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R", | 337 | "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R", |
@@ -352,6 +372,7 @@ SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), | |||
352 | 372 | ||
353 | SND_SOC_DAPM_SIGGEN("TONE"), | 373 | SND_SOC_DAPM_SIGGEN("TONE"), |
354 | SND_SOC_DAPM_SIGGEN("NOISE"), | 374 | SND_SOC_DAPM_SIGGEN("NOISE"), |
375 | SND_SOC_DAPM_SIGGEN("HAPTICS"), | ||
355 | 376 | ||
356 | SND_SOC_DAPM_INPUT("IN1L"), | 377 | SND_SOC_DAPM_INPUT("IN1L"), |
357 | SND_SOC_DAPM_INPUT("IN1R"), | 378 | SND_SOC_DAPM_INPUT("IN1R"), |
@@ -585,10 +606,10 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), | |||
585 | ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), | 606 | ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), |
586 | ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), | 607 | ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), |
587 | 608 | ||
588 | ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"), | 609 | ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"), |
589 | ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"), | 610 | ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"), |
590 | ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"), | 611 | ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"), |
591 | ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"), | 612 | ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"), |
592 | 613 | ||
593 | SND_SOC_DAPM_OUTPUT("HPOUT1L"), | 614 | SND_SOC_DAPM_OUTPUT("HPOUT1L"), |
594 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), | 615 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), |
@@ -610,6 +631,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT2R"), | |||
610 | { name, "Noise Generator", "Noise Generator" }, \ | 631 | { name, "Noise Generator", "Noise Generator" }, \ |
611 | { name, "Tone Generator 1", "Tone Generator 1" }, \ | 632 | { name, "Tone Generator 1", "Tone Generator 1" }, \ |
612 | { name, "Tone Generator 2", "Tone Generator 2" }, \ | 633 | { name, "Tone Generator 2", "Tone Generator 2" }, \ |
634 | { name, "Haptics", "HAPTICS" }, \ | ||
613 | { name, "AEC", "AEC Loopback" }, \ | 635 | { name, "AEC", "AEC Loopback" }, \ |
614 | { name, "IN1L", "IN1L PGA" }, \ | 636 | { name, "IN1L", "IN1L PGA" }, \ |
615 | { name, "IN1R", "IN1R PGA" }, \ | 637 | { name, "IN1R", "IN1R PGA" }, \ |
@@ -786,10 +808,10 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { | |||
786 | ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), | 808 | ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), |
787 | ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), | 809 | ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), |
788 | 810 | ||
789 | ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"), | 811 | ARIZONA_MUX_ROUTES("ASRC1L"), |
790 | ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"), | 812 | ARIZONA_MUX_ROUTES("ASRC1R"), |
791 | ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), | 813 | ARIZONA_MUX_ROUTES("ASRC2L"), |
792 | ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), | 814 | ARIZONA_MUX_ROUTES("ASRC2R"), |
793 | 815 | ||
794 | { "HPOUT1L", NULL, "OUT1L" }, | 816 | { "HPOUT1L", NULL, "OUT1L" }, |
795 | { "HPOUT1R", NULL, "OUT1R" }, | 817 | { "HPOUT1R", NULL, "OUT1R" }, |
@@ -902,9 +924,29 @@ static struct snd_soc_dai_driver wm5110_dai[] = { | |||
902 | static int wm5110_codec_probe(struct snd_soc_codec *codec) | 924 | static int wm5110_codec_probe(struct snd_soc_codec *codec) |
903 | { | 925 | { |
904 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); | 926 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); |
927 | int ret; | ||
905 | 928 | ||
906 | codec->control_data = priv->core.arizona->regmap; | 929 | codec->control_data = priv->core.arizona->regmap; |
907 | return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); | 930 | priv->core.arizona->dapm = &codec->dapm; |
931 | |||
932 | ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); | ||
933 | if (ret != 0) | ||
934 | return ret; | ||
935 | |||
936 | snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); | ||
937 | |||
938 | priv->core.arizona->dapm = &codec->dapm; | ||
939 | |||
940 | return 0; | ||
941 | } | ||
942 | |||
943 | static int wm5110_codec_remove(struct snd_soc_codec *codec) | ||
944 | { | ||
945 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
946 | |||
947 | priv->core.arizona->dapm = NULL; | ||
948 | |||
949 | return 0; | ||
908 | } | 950 | } |
909 | 951 | ||
910 | #define WM5110_DIG_VU 0x0200 | 952 | #define WM5110_DIG_VU 0x0200 |
@@ -935,6 +977,7 @@ static unsigned int wm5110_digital_vu[] = { | |||
935 | 977 | ||
936 | static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { | 978 | static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { |
937 | .probe = wm5110_codec_probe, | 979 | .probe = wm5110_codec_probe, |
980 | .remove = wm5110_codec_remove, | ||
938 | 981 | ||
939 | .idle_bias_off = true, | 982 | .idle_bias_off = true, |
940 | 983 | ||
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index a4cae060bf26..32b8f0852f6e 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -1500,7 +1500,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) | |||
1500 | for (i = 0; i < ARRAY_SIZE(supply_names); i++) | 1500 | for (i = 0; i < ARRAY_SIZE(supply_names); i++) |
1501 | priv->supplies[i].supply = supply_names[i]; | 1501 | priv->supplies[i].supply = supply_names[i]; |
1502 | 1502 | ||
1503 | ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies), | 1503 | ret = devm_regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies), |
1504 | priv->supplies); | 1504 | priv->supplies); |
1505 | if (ret != 0) | 1505 | if (ret != 0) |
1506 | return ret; | 1506 | return ret; |
@@ -1607,8 +1607,6 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) | |||
1607 | 1607 | ||
1608 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); | 1608 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); |
1609 | 1609 | ||
1610 | regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies); | ||
1611 | |||
1612 | return 0; | 1610 | return 0; |
1613 | } | 1611 | } |
1614 | 1612 | ||
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 5d277a915f81..262c44082eb0 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -1373,7 +1373,7 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) | |||
1373 | codec->control_data = priv->wm8400 = wm8400; | 1373 | codec->control_data = priv->wm8400 = wm8400; |
1374 | priv->codec = codec; | 1374 | priv->codec = codec; |
1375 | 1375 | ||
1376 | ret = regulator_bulk_get(wm8400->dev, | 1376 | ret = devm_regulator_bulk_get(wm8400->dev, |
1377 | ARRAY_SIZE(power), &power[0]); | 1377 | ARRAY_SIZE(power), &power[0]); |
1378 | if (ret != 0) { | 1378 | if (ret != 0) { |
1379 | dev_err(codec->dev, "Failed to get regulators: %d\n", ret); | 1379 | dev_err(codec->dev, "Failed to get regulators: %d\n", ret); |
@@ -1398,15 +1398,9 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) | |||
1398 | snd_soc_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1398 | snd_soc_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
1399 | snd_soc_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1399 | snd_soc_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
1400 | 1400 | ||
1401 | if (!schedule_work(&priv->work)) { | 1401 | if (!schedule_work(&priv->work)) |
1402 | ret = -EINVAL; | 1402 | return -EINVAL; |
1403 | goto err_regulator; | ||
1404 | } | ||
1405 | return 0; | 1403 | return 0; |
1406 | |||
1407 | err_regulator: | ||
1408 | regulator_bulk_free(ARRAY_SIZE(power), power); | ||
1409 | return ret; | ||
1410 | } | 1404 | } |
1411 | 1405 | ||
1412 | static int wm8400_codec_remove(struct snd_soc_codec *codec) | 1406 | static int wm8400_codec_remove(struct snd_soc_codec *codec) |
@@ -1417,8 +1411,6 @@ static int wm8400_codec_remove(struct snd_soc_codec *codec) | |||
1417 | snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, | 1411 | snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, |
1418 | reg & (~WM8400_CODEC_ENA)); | 1412 | reg & (~WM8400_CODEC_ENA)); |
1419 | 1413 | ||
1420 | regulator_bulk_free(ARRAY_SIZE(power), power); | ||
1421 | |||
1422 | return 0; | 1414 | return 0; |
1423 | } | 1415 | } |
1424 | 1416 | ||
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index c12a54e72e89..923e7e1f6704 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c | |||
@@ -608,10 +608,7 @@ static int wm8510_probe(struct snd_soc_codec *codec) | |||
608 | /* power down chip */ | 608 | /* power down chip */ |
609 | static int wm8510_remove(struct snd_soc_codec *codec) | 609 | static int wm8510_remove(struct snd_soc_codec *codec) |
610 | { | 610 | { |
611 | struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec); | ||
612 | |||
613 | wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); | 611 | wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); |
614 | kfree(wm8510); | ||
615 | return 0; | 612 | return 0; |
616 | } | 613 | } |
617 | 614 | ||
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 4281a0802138..99b8ebe93424 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c | |||
@@ -522,7 +522,7 @@ static int wm8741_i2c_probe(struct i2c_client *i2c, | |||
522 | return ret; | 522 | return ret; |
523 | } | 523 | } |
524 | 524 | ||
525 | wm8741->regmap = regmap_init_i2c(i2c, &wm8741_regmap); | 525 | wm8741->regmap = devm_regmap_init_i2c(i2c, &wm8741_regmap); |
526 | if (IS_ERR(wm8741->regmap)) { | 526 | if (IS_ERR(wm8741->regmap)) { |
527 | ret = PTR_ERR(wm8741->regmap); | 527 | ret = PTR_ERR(wm8741->regmap); |
528 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); | 528 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); |
@@ -582,7 +582,7 @@ static int __devinit wm8741_spi_probe(struct spi_device *spi) | |||
582 | return ret; | 582 | return ret; |
583 | } | 583 | } |
584 | 584 | ||
585 | wm8741->regmap = regmap_init_spi(spi, &wm8741_regmap); | 585 | wm8741->regmap = devm_regmap_init_spi(spi, &wm8741_regmap); |
586 | if (IS_ERR(wm8741->regmap)) { | 586 | if (IS_ERR(wm8741->regmap)) { |
587 | ret = PTR_ERR(wm8741->regmap); | 587 | ret = PTR_ERR(wm8741->regmap); |
588 | dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); | 588 | dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); |
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 89151ca5e776..7665d68c4558 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/regmap.h> | ||
21 | #include <linux/spi/spi.h> | 22 | #include <linux/spi/spi.h> |
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | #include <linux/of_device.h> | 24 | #include <linux/of_device.h> |
@@ -34,24 +35,55 @@ | |||
34 | * We can't read the WM8750 register space when we | 35 | * We can't read the WM8750 register space when we |
35 | * are using 2 wire for device control, so we cache them instead. | 36 | * are using 2 wire for device control, so we cache them instead. |
36 | */ | 37 | */ |
37 | static const u16 wm8750_reg[] = { | 38 | static const struct reg_default wm8750_reg_defaults[] = { |
38 | 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ | 39 | { 0, 0x0097 }, |
39 | 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ | 40 | { 1, 0x0097 }, |
40 | 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ | 41 | { 2, 0x0079 }, |
41 | 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ | 42 | { 3, 0x0079 }, |
42 | 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ | 43 | { 4, 0x0000 }, |
43 | 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ | 44 | { 5, 0x0008 }, |
44 | 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ | 45 | { 6, 0x0000 }, |
45 | 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ | 46 | { 7, 0x000a }, |
46 | 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ | 47 | { 8, 0x0000 }, |
47 | 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ | 48 | { 9, 0x0000 }, |
48 | 0x0079, 0x0079, 0x0079, /* 40 */ | 49 | { 10, 0x00ff }, |
50 | { 11, 0x00ff }, | ||
51 | { 12, 0x000f }, | ||
52 | { 13, 0x000f }, | ||
53 | { 14, 0x0000 }, | ||
54 | { 15, 0x0000 }, | ||
55 | { 16, 0x0000 }, | ||
56 | { 17, 0x007b }, | ||
57 | { 18, 0x0000 }, | ||
58 | { 19, 0x0032 }, | ||
59 | { 20, 0x0000 }, | ||
60 | { 21, 0x00c3 }, | ||
61 | { 22, 0x00c3 }, | ||
62 | { 23, 0x00c0 }, | ||
63 | { 24, 0x0000 }, | ||
64 | { 25, 0x0000 }, | ||
65 | { 26, 0x0000 }, | ||
66 | { 27, 0x0000 }, | ||
67 | { 28, 0x0000 }, | ||
68 | { 29, 0x0000 }, | ||
69 | { 30, 0x0000 }, | ||
70 | { 31, 0x0000 }, | ||
71 | { 32, 0x0000 }, | ||
72 | { 33, 0x0000 }, | ||
73 | { 34, 0x0050 }, | ||
74 | { 35, 0x0050 }, | ||
75 | { 36, 0x0050 }, | ||
76 | { 37, 0x0050 }, | ||
77 | { 38, 0x0050 }, | ||
78 | { 39, 0x0050 }, | ||
79 | { 40, 0x0079 }, | ||
80 | { 41, 0x0079 }, | ||
81 | { 42, 0x0079 }, | ||
49 | }; | 82 | }; |
50 | 83 | ||
51 | /* codec private data */ | 84 | /* codec private data */ |
52 | struct wm8750_priv { | 85 | struct wm8750_priv { |
53 | unsigned int sysclk; | 86 | unsigned int sysclk; |
54 | enum snd_soc_control_type control_type; | ||
55 | }; | 87 | }; |
56 | 88 | ||
57 | #define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) | 89 | #define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) |
@@ -668,10 +700,9 @@ static int wm8750_resume(struct snd_soc_codec *codec) | |||
668 | 700 | ||
669 | static int wm8750_probe(struct snd_soc_codec *codec) | 701 | static int wm8750_probe(struct snd_soc_codec *codec) |
670 | { | 702 | { |
671 | struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); | ||
672 | int ret; | 703 | int ret; |
673 | 704 | ||
674 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type); | 705 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
675 | if (ret < 0) { | 706 | if (ret < 0) { |
676 | printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret); | 707 | printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret); |
677 | return ret; | 708 | return ret; |
@@ -711,9 +742,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8750 = { | |||
711 | .suspend = wm8750_suspend, | 742 | .suspend = wm8750_suspend, |
712 | .resume = wm8750_resume, | 743 | .resume = wm8750_resume, |
713 | .set_bias_level = wm8750_set_bias_level, | 744 | .set_bias_level = wm8750_set_bias_level, |
714 | .reg_cache_size = ARRAY_SIZE(wm8750_reg), | ||
715 | .reg_word_size = sizeof(u16), | ||
716 | .reg_cache_default = wm8750_reg, | ||
717 | 745 | ||
718 | .controls = wm8750_snd_controls, | 746 | .controls = wm8750_snd_controls, |
719 | .num_controls = ARRAY_SIZE(wm8750_snd_controls), | 747 | .num_controls = ARRAY_SIZE(wm8750_snd_controls), |
@@ -730,10 +758,21 @@ static const struct of_device_id wm8750_of_match[] = { | |||
730 | }; | 758 | }; |
731 | MODULE_DEVICE_TABLE(of, wm8750_of_match); | 759 | MODULE_DEVICE_TABLE(of, wm8750_of_match); |
732 | 760 | ||
761 | static const struct regmap_config wm8750_regmap = { | ||
762 | .reg_bits = 7, | ||
763 | .val_bits = 9, | ||
764 | .max_register = WM8750_MOUTV, | ||
765 | |||
766 | .reg_defaults = wm8750_reg_defaults, | ||
767 | .num_reg_defaults = ARRAY_SIZE(wm8750_reg_defaults), | ||
768 | .cache_type = REGCACHE_RBTREE, | ||
769 | }; | ||
770 | |||
733 | #if defined(CONFIG_SPI_MASTER) | 771 | #if defined(CONFIG_SPI_MASTER) |
734 | static int __devinit wm8750_spi_probe(struct spi_device *spi) | 772 | static int __devinit wm8750_spi_probe(struct spi_device *spi) |
735 | { | 773 | { |
736 | struct wm8750_priv *wm8750; | 774 | struct wm8750_priv *wm8750; |
775 | struct regmap *regmap; | ||
737 | int ret; | 776 | int ret; |
738 | 777 | ||
739 | wm8750 = devm_kzalloc(&spi->dev, sizeof(struct wm8750_priv), | 778 | wm8750 = devm_kzalloc(&spi->dev, sizeof(struct wm8750_priv), |
@@ -741,7 +780,10 @@ static int __devinit wm8750_spi_probe(struct spi_device *spi) | |||
741 | if (wm8750 == NULL) | 780 | if (wm8750 == NULL) |
742 | return -ENOMEM; | 781 | return -ENOMEM; |
743 | 782 | ||
744 | wm8750->control_type = SND_SOC_SPI; | 783 | regmap = devm_regmap_init_spi(spi, &wm8750_regmap); |
784 | if (IS_ERR(regmap)) | ||
785 | return PTR_ERR(regmap); | ||
786 | |||
745 | spi_set_drvdata(spi, wm8750); | 787 | spi_set_drvdata(spi, wm8750); |
746 | 788 | ||
747 | ret = snd_soc_register_codec(&spi->dev, | 789 | ret = snd_soc_register_codec(&spi->dev, |
@@ -779,6 +821,7 @@ static __devinit int wm8750_i2c_probe(struct i2c_client *i2c, | |||
779 | const struct i2c_device_id *id) | 821 | const struct i2c_device_id *id) |
780 | { | 822 | { |
781 | struct wm8750_priv *wm8750; | 823 | struct wm8750_priv *wm8750; |
824 | struct regmap *regmap; | ||
782 | int ret; | 825 | int ret; |
783 | 826 | ||
784 | wm8750 = devm_kzalloc(&i2c->dev, sizeof(struct wm8750_priv), | 827 | wm8750 = devm_kzalloc(&i2c->dev, sizeof(struct wm8750_priv), |
@@ -787,7 +830,10 @@ static __devinit int wm8750_i2c_probe(struct i2c_client *i2c, | |||
787 | return -ENOMEM; | 830 | return -ENOMEM; |
788 | 831 | ||
789 | i2c_set_clientdata(i2c, wm8750); | 832 | i2c_set_clientdata(i2c, wm8750); |
790 | wm8750->control_type = SND_SOC_I2C; | 833 | |
834 | regmap = devm_regmap_init_i2c(i2c, &wm8750_regmap); | ||
835 | if (IS_ERR(regmap)) | ||
836 | return PTR_ERR(regmap); | ||
791 | 837 | ||
792 | ret = snd_soc_register_codec(&i2c->dev, | 838 | ret = snd_soc_register_codec(&i2c->dev, |
793 | &soc_codec_dev_wm8750, &wm8750_dai, 1); | 839 | &soc_codec_dev_wm8750, &wm8750_dai, 1); |
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c new file mode 100644 index 000000000000..ffc89fab96fb --- /dev/null +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -0,0 +1,699 @@ | |||
1 | /* | ||
2 | * wm_adsp.c -- Wolfson ADSP support | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics plc | ||
5 | * | ||
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/moduleparam.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/firmware.h> | ||
18 | #include <linux/pm.h> | ||
19 | #include <linux/pm_runtime.h> | ||
20 | #include <linux/regmap.h> | ||
21 | #include <linux/regulator/consumer.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <sound/core.h> | ||
24 | #include <sound/pcm.h> | ||
25 | #include <sound/pcm_params.h> | ||
26 | #include <sound/soc.h> | ||
27 | #include <sound/jack.h> | ||
28 | #include <sound/initval.h> | ||
29 | #include <sound/tlv.h> | ||
30 | |||
31 | #include <linux/mfd/arizona/registers.h> | ||
32 | |||
33 | #include "wm_adsp.h" | ||
34 | |||
35 | #define adsp_crit(_dsp, fmt, ...) \ | ||
36 | dev_crit(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) | ||
37 | #define adsp_err(_dsp, fmt, ...) \ | ||
38 | dev_err(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) | ||
39 | #define adsp_warn(_dsp, fmt, ...) \ | ||
40 | dev_warn(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) | ||
41 | #define adsp_info(_dsp, fmt, ...) \ | ||
42 | dev_info(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) | ||
43 | #define adsp_dbg(_dsp, fmt, ...) \ | ||
44 | dev_dbg(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) | ||
45 | |||
46 | #define ADSP1_CONTROL_1 0x00 | ||
47 | #define ADSP1_CONTROL_2 0x02 | ||
48 | #define ADSP1_CONTROL_3 0x03 | ||
49 | #define ADSP1_CONTROL_4 0x04 | ||
50 | #define ADSP1_CONTROL_5 0x06 | ||
51 | #define ADSP1_CONTROL_6 0x07 | ||
52 | #define ADSP1_CONTROL_7 0x08 | ||
53 | #define ADSP1_CONTROL_8 0x09 | ||
54 | #define ADSP1_CONTROL_9 0x0A | ||
55 | #define ADSP1_CONTROL_10 0x0B | ||
56 | #define ADSP1_CONTROL_11 0x0C | ||
57 | #define ADSP1_CONTROL_12 0x0D | ||
58 | #define ADSP1_CONTROL_13 0x0F | ||
59 | #define ADSP1_CONTROL_14 0x10 | ||
60 | #define ADSP1_CONTROL_15 0x11 | ||
61 | #define ADSP1_CONTROL_16 0x12 | ||
62 | #define ADSP1_CONTROL_17 0x13 | ||
63 | #define ADSP1_CONTROL_18 0x14 | ||
64 | #define ADSP1_CONTROL_19 0x16 | ||
65 | #define ADSP1_CONTROL_20 0x17 | ||
66 | #define ADSP1_CONTROL_21 0x18 | ||
67 | #define ADSP1_CONTROL_22 0x1A | ||
68 | #define ADSP1_CONTROL_23 0x1B | ||
69 | #define ADSP1_CONTROL_24 0x1C | ||
70 | #define ADSP1_CONTROL_25 0x1E | ||
71 | #define ADSP1_CONTROL_26 0x20 | ||
72 | #define ADSP1_CONTROL_27 0x21 | ||
73 | #define ADSP1_CONTROL_28 0x22 | ||
74 | #define ADSP1_CONTROL_29 0x23 | ||
75 | #define ADSP1_CONTROL_30 0x24 | ||
76 | #define ADSP1_CONTROL_31 0x26 | ||
77 | |||
78 | /* | ||
79 | * ADSP1 Control 19 | ||
80 | */ | ||
81 | #define ADSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ | ||
82 | #define ADSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ | ||
83 | #define ADSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ | ||
84 | |||
85 | |||
86 | /* | ||
87 | * ADSP1 Control 30 | ||
88 | */ | ||
89 | #define ADSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ | ||
90 | #define ADSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ | ||
91 | #define ADSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ | ||
92 | #define ADSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ | ||
93 | #define ADSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ | ||
94 | #define ADSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ | ||
95 | #define ADSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ | ||
96 | #define ADSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ | ||
97 | #define ADSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ | ||
98 | #define ADSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ | ||
99 | #define ADSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ | ||
100 | #define ADSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ | ||
101 | #define ADSP1_START 0x0001 /* DSP1_START */ | ||
102 | #define ADSP1_START_MASK 0x0001 /* DSP1_START */ | ||
103 | #define ADSP1_START_SHIFT 0 /* DSP1_START */ | ||
104 | #define ADSP1_START_WIDTH 1 /* DSP1_START */ | ||
105 | |||
106 | #define ADSP2_CONTROL 0 | ||
107 | #define ADSP2_CLOCKING 1 | ||
108 | #define ADSP2_STATUS1 4 | ||
109 | |||
110 | /* | ||
111 | * ADSP2 Control | ||
112 | */ | ||
113 | |||
114 | #define ADSP2_MEM_ENA 0x0010 /* DSP1_MEM_ENA */ | ||
115 | #define ADSP2_MEM_ENA_MASK 0x0010 /* DSP1_MEM_ENA */ | ||
116 | #define ADSP2_MEM_ENA_SHIFT 4 /* DSP1_MEM_ENA */ | ||
117 | #define ADSP2_MEM_ENA_WIDTH 1 /* DSP1_MEM_ENA */ | ||
118 | #define ADSP2_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ | ||
119 | #define ADSP2_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ | ||
120 | #define ADSP2_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ | ||
121 | #define ADSP2_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ | ||
122 | #define ADSP2_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ | ||
123 | #define ADSP2_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ | ||
124 | #define ADSP2_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ | ||
125 | #define ADSP2_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ | ||
126 | #define ADSP2_START 0x0001 /* DSP1_START */ | ||
127 | #define ADSP2_START_MASK 0x0001 /* DSP1_START */ | ||
128 | #define ADSP2_START_SHIFT 0 /* DSP1_START */ | ||
129 | #define ADSP2_START_WIDTH 1 /* DSP1_START */ | ||
130 | |||
131 | /* | ||
132 | * ADSP2 clocking | ||
133 | */ | ||
134 | #define ADSP2_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ | ||
135 | #define ADSP2_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ | ||
136 | #define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ | ||
137 | |||
138 | /* | ||
139 | * ADSP2 Status 1 | ||
140 | */ | ||
141 | #define ADSP2_RAM_RDY 0x0001 | ||
142 | #define ADSP2_RAM_RDY_MASK 0x0001 | ||
143 | #define ADSP2_RAM_RDY_SHIFT 0 | ||
144 | #define ADSP2_RAM_RDY_WIDTH 1 | ||
145 | |||
146 | |||
147 | static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, | ||
148 | int type) | ||
149 | { | ||
150 | int i; | ||
151 | |||
152 | for (i = 0; i < dsp->num_mems; i++) | ||
153 | if (dsp->mem[i].type == type) | ||
154 | return &dsp->mem[i]; | ||
155 | |||
156 | return NULL; | ||
157 | } | ||
158 | |||
159 | static int wm_adsp_load(struct wm_adsp *dsp) | ||
160 | { | ||
161 | const struct firmware *firmware; | ||
162 | struct regmap *regmap = dsp->regmap; | ||
163 | unsigned int pos = 0; | ||
164 | const struct wmfw_header *header; | ||
165 | const struct wmfw_adsp1_sizes *adsp1_sizes; | ||
166 | const struct wmfw_adsp2_sizes *adsp2_sizes; | ||
167 | const struct wmfw_footer *footer; | ||
168 | const struct wmfw_region *region; | ||
169 | const struct wm_adsp_region *mem; | ||
170 | const char *region_name; | ||
171 | char *file, *text; | ||
172 | unsigned int reg; | ||
173 | int regions = 0; | ||
174 | int ret, offset, type, sizes; | ||
175 | |||
176 | file = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
177 | if (file == NULL) | ||
178 | return -ENOMEM; | ||
179 | |||
180 | snprintf(file, PAGE_SIZE, "%s-dsp%d.wmfw", dsp->part, dsp->num); | ||
181 | file[PAGE_SIZE - 1] = '\0'; | ||
182 | |||
183 | ret = request_firmware(&firmware, file, dsp->dev); | ||
184 | if (ret != 0) { | ||
185 | adsp_err(dsp, "Failed to request '%s'\n", file); | ||
186 | goto out; | ||
187 | } | ||
188 | ret = -EINVAL; | ||
189 | |||
190 | pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); | ||
191 | if (pos >= firmware->size) { | ||
192 | adsp_err(dsp, "%s: file too short, %zu bytes\n", | ||
193 | file, firmware->size); | ||
194 | goto out_fw; | ||
195 | } | ||
196 | |||
197 | header = (void*)&firmware->data[0]; | ||
198 | |||
199 | if (memcmp(&header->magic[0], "WMFW", 4) != 0) { | ||
200 | adsp_err(dsp, "%s: invalid magic\n", file); | ||
201 | goto out_fw; | ||
202 | } | ||
203 | |||
204 | if (header->ver != 0) { | ||
205 | adsp_err(dsp, "%s: unknown file format %d\n", | ||
206 | file, header->ver); | ||
207 | goto out_fw; | ||
208 | } | ||
209 | |||
210 | if (header->core != dsp->type) { | ||
211 | adsp_err(dsp, "%s: invalid core %d != %d\n", | ||
212 | file, header->core, dsp->type); | ||
213 | goto out_fw; | ||
214 | } | ||
215 | |||
216 | switch (dsp->type) { | ||
217 | case WMFW_ADSP1: | ||
218 | pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); | ||
219 | adsp1_sizes = (void *)&(header[1]); | ||
220 | footer = (void *)&(adsp1_sizes[1]); | ||
221 | sizes = sizeof(*adsp1_sizes); | ||
222 | |||
223 | adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", | ||
224 | file, le32_to_cpu(adsp1_sizes->dm), | ||
225 | le32_to_cpu(adsp1_sizes->pm), | ||
226 | le32_to_cpu(adsp1_sizes->zm)); | ||
227 | break; | ||
228 | |||
229 | case WMFW_ADSP2: | ||
230 | pos = sizeof(*header) + sizeof(*adsp2_sizes) + sizeof(*footer); | ||
231 | adsp2_sizes = (void *)&(header[1]); | ||
232 | footer = (void *)&(adsp2_sizes[1]); | ||
233 | sizes = sizeof(*adsp2_sizes); | ||
234 | |||
235 | adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", | ||
236 | file, le32_to_cpu(adsp2_sizes->xm), | ||
237 | le32_to_cpu(adsp2_sizes->ym), | ||
238 | le32_to_cpu(adsp2_sizes->pm), | ||
239 | le32_to_cpu(adsp2_sizes->zm)); | ||
240 | break; | ||
241 | |||
242 | default: | ||
243 | BUG_ON(NULL == "Unknown DSP type"); | ||
244 | goto out_fw; | ||
245 | } | ||
246 | |||
247 | if (le32_to_cpu(header->len) != sizeof(*header) + | ||
248 | sizes + sizeof(*footer)) { | ||
249 | adsp_err(dsp, "%s: unexpected header length %d\n", | ||
250 | file, le32_to_cpu(header->len)); | ||
251 | goto out_fw; | ||
252 | } | ||
253 | |||
254 | adsp_dbg(dsp, "%s: timestamp %llu\n", file, | ||
255 | le64_to_cpu(footer->timestamp)); | ||
256 | |||
257 | while (pos < firmware->size && | ||
258 | pos - firmware->size > sizeof(*region)) { | ||
259 | region = (void *)&(firmware->data[pos]); | ||
260 | region_name = "Unknown"; | ||
261 | reg = 0; | ||
262 | text = NULL; | ||
263 | offset = le32_to_cpu(region->offset) & 0xffffff; | ||
264 | type = be32_to_cpu(region->type) & 0xff; | ||
265 | mem = wm_adsp_find_region(dsp, type); | ||
266 | |||
267 | switch (type) { | ||
268 | case WMFW_NAME_TEXT: | ||
269 | region_name = "Firmware name"; | ||
270 | text = kzalloc(le32_to_cpu(region->len) + 1, | ||
271 | GFP_KERNEL); | ||
272 | break; | ||
273 | case WMFW_INFO_TEXT: | ||
274 | region_name = "Information"; | ||
275 | text = kzalloc(le32_to_cpu(region->len) + 1, | ||
276 | GFP_KERNEL); | ||
277 | break; | ||
278 | case WMFW_ABSOLUTE: | ||
279 | region_name = "Absolute"; | ||
280 | reg = offset; | ||
281 | break; | ||
282 | case WMFW_ADSP1_PM: | ||
283 | BUG_ON(!mem); | ||
284 | region_name = "PM"; | ||
285 | reg = mem->base + (offset * 3); | ||
286 | break; | ||
287 | case WMFW_ADSP1_DM: | ||
288 | BUG_ON(!mem); | ||
289 | region_name = "DM"; | ||
290 | reg = mem->base + (offset * 2); | ||
291 | break; | ||
292 | case WMFW_ADSP2_XM: | ||
293 | BUG_ON(!mem); | ||
294 | region_name = "XM"; | ||
295 | reg = mem->base + (offset * 2); | ||
296 | break; | ||
297 | case WMFW_ADSP2_YM: | ||
298 | BUG_ON(!mem); | ||
299 | region_name = "YM"; | ||
300 | reg = mem->base + (offset * 2); | ||
301 | break; | ||
302 | case WMFW_ADSP1_ZM: | ||
303 | BUG_ON(!mem); | ||
304 | region_name = "ZM"; | ||
305 | reg = mem->base + (offset * 2); | ||
306 | break; | ||
307 | default: | ||
308 | adsp_warn(dsp, | ||
309 | "%s.%d: Unknown region type %x at %d(%x)\n", | ||
310 | file, regions, type, pos, pos); | ||
311 | break; | ||
312 | } | ||
313 | |||
314 | adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, | ||
315 | regions, le32_to_cpu(region->len), offset, | ||
316 | region_name); | ||
317 | |||
318 | if (text) { | ||
319 | memcpy(text, region->data, le32_to_cpu(region->len)); | ||
320 | adsp_info(dsp, "%s: %s\n", file, text); | ||
321 | kfree(text); | ||
322 | } | ||
323 | |||
324 | if (reg) { | ||
325 | ret = regmap_raw_write(regmap, reg, region->data, | ||
326 | le32_to_cpu(region->len)); | ||
327 | if (ret != 0) { | ||
328 | adsp_err(dsp, | ||
329 | "%s.%d: Failed to write %d bytes at %d in %s: %d\n", | ||
330 | file, regions, | ||
331 | le32_to_cpu(region->len), offset, | ||
332 | region_name, ret); | ||
333 | goto out_fw; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | pos += le32_to_cpu(region->len) + sizeof(*region); | ||
338 | regions++; | ||
339 | } | ||
340 | |||
341 | if (pos > firmware->size) | ||
342 | adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", | ||
343 | file, regions, pos - firmware->size); | ||
344 | |||
345 | out_fw: | ||
346 | release_firmware(firmware); | ||
347 | out: | ||
348 | kfree(file); | ||
349 | |||
350 | return ret; | ||
351 | } | ||
352 | |||
353 | static int wm_adsp_load_coeff(struct wm_adsp *dsp) | ||
354 | { | ||
355 | struct regmap *regmap = dsp->regmap; | ||
356 | struct wmfw_coeff_hdr *hdr; | ||
357 | struct wmfw_coeff_item *blk; | ||
358 | const struct firmware *firmware; | ||
359 | const char *region_name; | ||
360 | int ret, pos, blocks, type, offset, reg; | ||
361 | char *file; | ||
362 | |||
363 | file = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
364 | if (file == NULL) | ||
365 | return -ENOMEM; | ||
366 | |||
367 | snprintf(file, PAGE_SIZE, "%s-dsp%d.bin", dsp->part, dsp->num); | ||
368 | file[PAGE_SIZE - 1] = '\0'; | ||
369 | |||
370 | ret = request_firmware(&firmware, file, dsp->dev); | ||
371 | if (ret != 0) { | ||
372 | adsp_warn(dsp, "Failed to request '%s'\n", file); | ||
373 | ret = 0; | ||
374 | goto out; | ||
375 | } | ||
376 | ret = -EINVAL; | ||
377 | |||
378 | if (sizeof(*hdr) >= firmware->size) { | ||
379 | adsp_err(dsp, "%s: file too short, %zu bytes\n", | ||
380 | file, firmware->size); | ||
381 | goto out_fw; | ||
382 | } | ||
383 | |||
384 | hdr = (void*)&firmware->data[0]; | ||
385 | if (memcmp(hdr->magic, "WMDR", 4) != 0) { | ||
386 | adsp_err(dsp, "%s: invalid magic\n", file); | ||
387 | return -EINVAL; | ||
388 | } | ||
389 | |||
390 | adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, | ||
391 | (le32_to_cpu(hdr->ver) >> 16) & 0xff, | ||
392 | (le32_to_cpu(hdr->ver) >> 8) & 0xff, | ||
393 | le32_to_cpu(hdr->ver) & 0xff); | ||
394 | |||
395 | pos = le32_to_cpu(hdr->len); | ||
396 | |||
397 | blocks = 0; | ||
398 | while (pos < firmware->size && | ||
399 | pos - firmware->size > sizeof(*blk)) { | ||
400 | blk = (void*)(&firmware->data[pos]); | ||
401 | |||
402 | type = be32_to_cpu(blk->type) & 0xff; | ||
403 | offset = le32_to_cpu(blk->offset) & 0xffffff; | ||
404 | |||
405 | adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", | ||
406 | file, blocks, le32_to_cpu(blk->id), | ||
407 | (le32_to_cpu(blk->ver) >> 16) & 0xff, | ||
408 | (le32_to_cpu(blk->ver) >> 8) & 0xff, | ||
409 | le32_to_cpu(blk->ver) & 0xff); | ||
410 | adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", | ||
411 | file, blocks, le32_to_cpu(blk->len), offset, type); | ||
412 | |||
413 | reg = 0; | ||
414 | region_name = "Unknown"; | ||
415 | switch (type) { | ||
416 | case WMFW_NAME_TEXT: | ||
417 | case WMFW_INFO_TEXT: | ||
418 | break; | ||
419 | case WMFW_ABSOLUTE: | ||
420 | region_name = "register"; | ||
421 | reg = offset; | ||
422 | break; | ||
423 | default: | ||
424 | adsp_err(dsp, "Unknown region type %x\n", type); | ||
425 | break; | ||
426 | } | ||
427 | |||
428 | if (reg) { | ||
429 | ret = regmap_raw_write(regmap, reg, blk->data, | ||
430 | le32_to_cpu(blk->len)); | ||
431 | if (ret != 0) { | ||
432 | adsp_err(dsp, | ||
433 | "%s.%d: Failed to write to %x in %s\n", | ||
434 | file, blocks, reg, region_name); | ||
435 | } | ||
436 | } | ||
437 | |||
438 | pos += le32_to_cpu(blk->len) + sizeof(*blk); | ||
439 | blocks++; | ||
440 | } | ||
441 | |||
442 | if (pos > firmware->size) | ||
443 | adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", | ||
444 | file, blocks, pos - firmware->size); | ||
445 | |||
446 | out_fw: | ||
447 | release_firmware(firmware); | ||
448 | out: | ||
449 | kfree(file); | ||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | int wm_adsp1_event(struct snd_soc_dapm_widget *w, | ||
454 | struct snd_kcontrol *kcontrol, | ||
455 | int event) | ||
456 | { | ||
457 | struct snd_soc_codec *codec = w->codec; | ||
458 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); | ||
459 | struct wm_adsp *dsp = &dsps[w->shift]; | ||
460 | int ret; | ||
461 | |||
462 | switch (event) { | ||
463 | case SND_SOC_DAPM_POST_PMU: | ||
464 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | ||
465 | ADSP1_SYS_ENA, ADSP1_SYS_ENA); | ||
466 | |||
467 | ret = wm_adsp_load(dsp); | ||
468 | if (ret != 0) | ||
469 | goto err; | ||
470 | |||
471 | ret = wm_adsp_load_coeff(dsp); | ||
472 | if (ret != 0) | ||
473 | goto err; | ||
474 | |||
475 | /* Start the core running */ | ||
476 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | ||
477 | ADSP1_CORE_ENA | ADSP1_START, | ||
478 | ADSP1_CORE_ENA | ADSP1_START); | ||
479 | break; | ||
480 | |||
481 | case SND_SOC_DAPM_PRE_PMD: | ||
482 | /* Halt the core */ | ||
483 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | ||
484 | ADSP1_CORE_ENA | ADSP1_START, 0); | ||
485 | |||
486 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, | ||
487 | ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); | ||
488 | |||
489 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | ||
490 | ADSP1_SYS_ENA, 0); | ||
491 | break; | ||
492 | |||
493 | default: | ||
494 | break; | ||
495 | } | ||
496 | |||
497 | return 0; | ||
498 | |||
499 | err: | ||
500 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | ||
501 | ADSP1_SYS_ENA, 0); | ||
502 | return ret; | ||
503 | } | ||
504 | EXPORT_SYMBOL_GPL(wm_adsp1_event); | ||
505 | |||
506 | static int wm_adsp2_ena(struct wm_adsp *dsp) | ||
507 | { | ||
508 | unsigned int val; | ||
509 | int ret, count; | ||
510 | |||
511 | ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | ||
512 | ADSP2_SYS_ENA, ADSP2_SYS_ENA); | ||
513 | if (ret != 0) | ||
514 | return ret; | ||
515 | |||
516 | /* Wait for the RAM to start, should be near instantaneous */ | ||
517 | count = 0; | ||
518 | do { | ||
519 | ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, | ||
520 | &val); | ||
521 | if (ret != 0) | ||
522 | return ret; | ||
523 | } while (!(val & ADSP2_RAM_RDY) && ++count < 10); | ||
524 | |||
525 | if (!(val & ADSP2_RAM_RDY)) { | ||
526 | adsp_err(dsp, "Failed to start DSP RAM\n"); | ||
527 | return -EBUSY; | ||
528 | } | ||
529 | |||
530 | adsp_dbg(dsp, "RAM ready after %d polls\n", count); | ||
531 | adsp_info(dsp, "RAM ready after %d polls\n", count); | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | int wm_adsp2_event(struct snd_soc_dapm_widget *w, | ||
537 | struct snd_kcontrol *kcontrol, int event) | ||
538 | { | ||
539 | struct snd_soc_codec *codec = w->codec; | ||
540 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); | ||
541 | struct wm_adsp *dsp = &dsps[w->shift]; | ||
542 | unsigned int val; | ||
543 | int ret; | ||
544 | |||
545 | switch (event) { | ||
546 | case SND_SOC_DAPM_POST_PMU: | ||
547 | /* | ||
548 | * For simplicity set the DSP clock rate to be the | ||
549 | * SYSCLK rate rather than making it configurable. | ||
550 | */ | ||
551 | ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val); | ||
552 | if (ret != 0) { | ||
553 | adsp_err(dsp, "Failed to read SYSCLK state: %d\n", | ||
554 | ret); | ||
555 | return ret; | ||
556 | } | ||
557 | val = (val & ARIZONA_SYSCLK_FREQ_MASK) | ||
558 | >> ARIZONA_SYSCLK_FREQ_SHIFT; | ||
559 | |||
560 | ret = regmap_update_bits(dsp->regmap, | ||
561 | dsp->base + ADSP2_CLOCKING, | ||
562 | ADSP2_CLK_SEL_MASK, val); | ||
563 | if (ret != 0) { | ||
564 | adsp_err(dsp, "Failed to set clock rate: %d\n", | ||
565 | ret); | ||
566 | return ret; | ||
567 | } | ||
568 | |||
569 | if (dsp->dvfs) { | ||
570 | ret = regmap_read(dsp->regmap, | ||
571 | dsp->base + ADSP2_CLOCKING, &val); | ||
572 | if (ret != 0) { | ||
573 | dev_err(dsp->dev, | ||
574 | "Failed to read clocking: %d\n", ret); | ||
575 | return ret; | ||
576 | } | ||
577 | |||
578 | if ((val & ADSP2_CLK_SEL_MASK) >= 3) { | ||
579 | ret = regulator_enable(dsp->dvfs); | ||
580 | if (ret != 0) { | ||
581 | dev_err(dsp->dev, | ||
582 | "Failed to enable supply: %d\n", | ||
583 | ret); | ||
584 | return ret; | ||
585 | } | ||
586 | |||
587 | ret = regulator_set_voltage(dsp->dvfs, | ||
588 | 1800000, | ||
589 | 1800000); | ||
590 | if (ret != 0) { | ||
591 | dev_err(dsp->dev, | ||
592 | "Failed to raise supply: %d\n", | ||
593 | ret); | ||
594 | return ret; | ||
595 | } | ||
596 | } | ||
597 | } | ||
598 | |||
599 | ret = wm_adsp2_ena(dsp); | ||
600 | if (ret != 0) | ||
601 | return ret; | ||
602 | |||
603 | ret = wm_adsp_load(dsp); | ||
604 | if (ret != 0) | ||
605 | goto err; | ||
606 | |||
607 | ret = wm_adsp_load_coeff(dsp); | ||
608 | if (ret != 0) | ||
609 | goto err; | ||
610 | |||
611 | ret = regmap_update_bits(dsp->regmap, | ||
612 | dsp->base + ADSP2_CONTROL, | ||
613 | ADSP2_CORE_ENA | ADSP2_START, | ||
614 | ADSP2_CORE_ENA | ADSP2_START); | ||
615 | if (ret != 0) | ||
616 | goto err; | ||
617 | break; | ||
618 | |||
619 | case SND_SOC_DAPM_PRE_PMD: | ||
620 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | ||
621 | ADSP2_SYS_ENA | ADSP2_CORE_ENA | | ||
622 | ADSP2_START, 0); | ||
623 | |||
624 | if (dsp->dvfs) { | ||
625 | ret = regulator_set_voltage(dsp->dvfs, 1200000, | ||
626 | 1800000); | ||
627 | if (ret != 0) | ||
628 | dev_warn(dsp->dev, | ||
629 | "Failed to lower supply: %d\n", | ||
630 | ret); | ||
631 | |||
632 | ret = regulator_disable(dsp->dvfs); | ||
633 | if (ret != 0) | ||
634 | dev_err(dsp->dev, | ||
635 | "Failed to enable supply: %d\n", | ||
636 | ret); | ||
637 | } | ||
638 | break; | ||
639 | |||
640 | default: | ||
641 | break; | ||
642 | } | ||
643 | |||
644 | return 0; | ||
645 | err: | ||
646 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | ||
647 | ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); | ||
648 | return ret; | ||
649 | } | ||
650 | EXPORT_SYMBOL_GPL(wm_adsp2_event); | ||
651 | |||
652 | int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) | ||
653 | { | ||
654 | int ret; | ||
655 | |||
656 | /* | ||
657 | * Disable the DSP memory by default when in reset for a small | ||
658 | * power saving. | ||
659 | */ | ||
660 | ret = regmap_update_bits(adsp->regmap, adsp->base + ADSP2_CONTROL, | ||
661 | ADSP2_MEM_ENA, 0); | ||
662 | if (ret != 0) { | ||
663 | adsp_err(adsp, "Failed to clear memory retention: %d\n", ret); | ||
664 | return ret; | ||
665 | } | ||
666 | |||
667 | if (dvfs) { | ||
668 | adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); | ||
669 | if (IS_ERR(adsp->dvfs)) { | ||
670 | ret = PTR_ERR(adsp->dvfs); | ||
671 | dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); | ||
672 | return ret; | ||
673 | } | ||
674 | |||
675 | ret = regulator_enable(adsp->dvfs); | ||
676 | if (ret != 0) { | ||
677 | dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", | ||
678 | ret); | ||
679 | return ret; | ||
680 | } | ||
681 | |||
682 | ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); | ||
683 | if (ret != 0) { | ||
684 | dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", | ||
685 | ret); | ||
686 | return ret; | ||
687 | } | ||
688 | |||
689 | ret = regulator_disable(adsp->dvfs); | ||
690 | if (ret != 0) { | ||
691 | dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", | ||
692 | ret); | ||
693 | return ret; | ||
694 | } | ||
695 | } | ||
696 | |||
697 | return 0; | ||
698 | } | ||
699 | EXPORT_SYMBOL_GPL(wm_adsp2_init); | ||
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h new file mode 100644 index 000000000000..ffd29a4609e2 --- /dev/null +++ b/sound/soc/codecs/wm_adsp.h | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * wm_adsp.h -- Wolfson ADSP support | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics plc | ||
5 | * | ||
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __WM_ADSP_H | ||
14 | #define __WM_ADSP_H | ||
15 | |||
16 | #include <sound/soc.h> | ||
17 | #include <sound/soc-dapm.h> | ||
18 | |||
19 | #include "wmfw.h" | ||
20 | |||
21 | struct regulator; | ||
22 | |||
23 | struct wm_adsp_region { | ||
24 | int type; | ||
25 | unsigned int base; | ||
26 | }; | ||
27 | |||
28 | struct wm_adsp { | ||
29 | const char *part; | ||
30 | int num; | ||
31 | int type; | ||
32 | struct device *dev; | ||
33 | struct regmap *regmap; | ||
34 | |||
35 | int base; | ||
36 | |||
37 | const struct wm_adsp_region *mem; | ||
38 | int num_mems; | ||
39 | |||
40 | struct regulator *dvfs; | ||
41 | }; | ||
42 | |||
43 | #define WM_ADSP1(wname, num) \ | ||
44 | { .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ | ||
45 | .shift = num, .event = wm_adsp1_event, \ | ||
46 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } | ||
47 | |||
48 | #define WM_ADSP2(wname, num) \ | ||
49 | { .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ | ||
50 | .shift = num, .event = wm_adsp2_event, \ | ||
51 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } | ||
52 | |||
53 | int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); | ||
54 | int wm_adsp1_event(struct snd_soc_dapm_widget *w, | ||
55 | struct snd_kcontrol *kcontrol, int event); | ||
56 | int wm_adsp2_event(struct snd_soc_dapm_widget *w, | ||
57 | struct snd_kcontrol *kcontrol, int event); | ||
58 | |||
59 | #endif | ||
diff --git a/sound/soc/codecs/wmfw.h b/sound/soc/codecs/wmfw.h new file mode 100644 index 000000000000..5632ded67fdd --- /dev/null +++ b/sound/soc/codecs/wmfw.h | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * wmfw.h - Wolfson firmware format information | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics plc | ||
5 | * | ||
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __WMFW_H | ||
14 | #define __WMFW_H | ||
15 | |||
16 | #include <linux/types.h> | ||
17 | |||
18 | struct wmfw_header { | ||
19 | char magic[4]; | ||
20 | __le32 len; | ||
21 | __le16 rev; | ||
22 | u8 core; | ||
23 | u8 ver; | ||
24 | } __packed; | ||
25 | |||
26 | struct wmfw_footer { | ||
27 | __le64 timestamp; | ||
28 | __le32 checksum; | ||
29 | } __packed; | ||
30 | |||
31 | struct wmfw_adsp1_sizes { | ||
32 | __le32 dm; | ||
33 | __le32 pm; | ||
34 | __le32 zm; | ||
35 | } __packed; | ||
36 | |||
37 | struct wmfw_adsp2_sizes { | ||
38 | __le32 xm; | ||
39 | __le32 ym; | ||
40 | __le32 pm; | ||
41 | __le32 zm; | ||
42 | } __packed; | ||
43 | |||
44 | struct wmfw_region { | ||
45 | union { | ||
46 | __be32 type; | ||
47 | __le32 offset; | ||
48 | }; | ||
49 | __le32 len; | ||
50 | u8 data[]; | ||
51 | } __packed; | ||
52 | |||
53 | struct wmfw_id_hdr { | ||
54 | __be32 core_id; | ||
55 | __be32 core_rev; | ||
56 | __be32 id; | ||
57 | __be32 ver; | ||
58 | } __packed; | ||
59 | |||
60 | struct wmfw_adsp1_id_hdr { | ||
61 | struct wmfw_id_hdr fw; | ||
62 | __be32 zm; | ||
63 | __be32 dm; | ||
64 | __be32 algs; | ||
65 | } __packed; | ||
66 | |||
67 | struct wmfw_adsp2_id_hdr { | ||
68 | struct wmfw_id_hdr fw; | ||
69 | __be32 zm; | ||
70 | __be32 xm; | ||
71 | __be32 ym; | ||
72 | __be32 algs; | ||
73 | } __packed; | ||
74 | |||
75 | struct wmfw_alg_hdr { | ||
76 | __be32 id; | ||
77 | __be32 ver; | ||
78 | } __packed; | ||
79 | |||
80 | struct wmfw_adsp1_alg_hdr { | ||
81 | struct wmfw_alg_hdr alg; | ||
82 | __be32 zm; | ||
83 | __be32 dm; | ||
84 | } __packed; | ||
85 | |||
86 | struct wmfw_adsp2_alg_hdr { | ||
87 | struct wmfw_alg_hdr alg; | ||
88 | __be32 zm; | ||
89 | __be32 xm; | ||
90 | __be32 ym; | ||
91 | } __packed; | ||
92 | |||
93 | struct wmfw_coeff_hdr { | ||
94 | u8 magic[4]; | ||
95 | __le32 len; | ||
96 | __le32 ver; | ||
97 | u8 data[]; | ||
98 | } __packed; | ||
99 | |||
100 | struct wmfw_coeff_item { | ||
101 | union { | ||
102 | __be32 type; | ||
103 | __le32 offset; | ||
104 | }; | ||
105 | __le32 id; | ||
106 | __le32 ver; | ||
107 | __le32 sr; | ||
108 | __le32 len; | ||
109 | u8 data[]; | ||
110 | } __packed; | ||
111 | |||
112 | #define WMFW_ADSP1 1 | ||
113 | #define WMFW_ADSP2 2 | ||
114 | |||
115 | #define WMFW_ABSOLUTE 0xf0 | ||
116 | #define WMFW_NAME_TEXT 0xfe | ||
117 | #define WMFW_INFO_TEXT 0xff | ||
118 | |||
119 | #define WMFW_ADSP1_PM 2 | ||
120 | #define WMFW_ADSP1_DM 3 | ||
121 | #define WMFW_ADSP1_ZM 4 | ||
122 | |||
123 | #define WMFW_ADSP2_PM 2 | ||
124 | #define WMFW_ADSP2_ZM 4 | ||
125 | #define WMFW_ADSP2_XM 5 | ||
126 | #define WMFW_ADSP2_YM 6 | ||
127 | |||
128 | #endif | ||
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 6fac5af13298..d55e6477bff0 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c | |||
@@ -71,6 +71,11 @@ static int evm_hw_params(struct snd_pcm_substream *substream, | |||
71 | if (ret < 0) | 71 | if (ret < 0) |
72 | return ret; | 72 | return ret; |
73 | 73 | ||
74 | /* set the CPU system clock */ | ||
75 | ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT); | ||
76 | if (ret < 0) | ||
77 | return ret; | ||
78 | |||
74 | return 0; | 79 | return 0; |
75 | } | 80 | } |
76 | 81 | ||
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 714e51e5be5b..55e2bf652bef 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -199,6 +199,7 @@ | |||
199 | #define ACLKXE BIT(5) | 199 | #define ACLKXE BIT(5) |
200 | #define TX_ASYNC BIT(6) | 200 | #define TX_ASYNC BIT(6) |
201 | #define ACLKXPOL BIT(7) | 201 | #define ACLKXPOL BIT(7) |
202 | #define ACLKXDIV_MASK 0x1f | ||
202 | 203 | ||
203 | /* | 204 | /* |
204 | * DAVINCI_MCASP_ACLKRCTL_REG Receive Clock Control Register Bits | 205 | * DAVINCI_MCASP_ACLKRCTL_REG Receive Clock Control Register Bits |
@@ -207,6 +208,7 @@ | |||
207 | #define ACLKRE BIT(5) | 208 | #define ACLKRE BIT(5) |
208 | #define RX_ASYNC BIT(6) | 209 | #define RX_ASYNC BIT(6) |
209 | #define ACLKRPOL BIT(7) | 210 | #define ACLKRPOL BIT(7) |
211 | #define ACLKRDIV_MASK 0x1f | ||
210 | 212 | ||
211 | /* | 213 | /* |
212 | * DAVINCI_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control | 214 | * DAVINCI_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control |
@@ -215,6 +217,7 @@ | |||
215 | #define AHCLKXDIV(val) (val) | 217 | #define AHCLKXDIV(val) (val) |
216 | #define AHCLKXPOL BIT(14) | 218 | #define AHCLKXPOL BIT(14) |
217 | #define AHCLKXE BIT(15) | 219 | #define AHCLKXE BIT(15) |
220 | #define AHCLKXDIV_MASK 0xfff | ||
218 | 221 | ||
219 | /* | 222 | /* |
220 | * DAVINCI_MCASP_AHCLKRCTL_REG - High Frequency Receive Clock Control | 223 | * DAVINCI_MCASP_AHCLKRCTL_REG - High Frequency Receive Clock Control |
@@ -223,6 +226,7 @@ | |||
223 | #define AHCLKRDIV(val) (val) | 226 | #define AHCLKRDIV(val) (val) |
224 | #define AHCLKRPOL BIT(14) | 227 | #define AHCLKRPOL BIT(14) |
225 | #define AHCLKRE BIT(15) | 228 | #define AHCLKRE BIT(15) |
229 | #define AHCLKRDIV_MASK 0xfff | ||
226 | 230 | ||
227 | /* | 231 | /* |
228 | * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits | 232 | * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits |
@@ -473,6 +477,23 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
473 | struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); | 477 | struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); |
474 | void __iomem *base = dev->base; | 478 | void __iomem *base = dev->base; |
475 | 479 | ||
480 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
481 | case SND_SOC_DAIFMT_DSP_B: | ||
482 | case SND_SOC_DAIFMT_AC97: | ||
483 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); | ||
484 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); | ||
485 | break; | ||
486 | default: | ||
487 | /* configure a full-word SYNC pulse (LRCLK) */ | ||
488 | mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); | ||
489 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); | ||
490 | |||
491 | /* make 1st data bit occur one ACLK cycle after the frame sync */ | ||
492 | mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, FSXDLY(1)); | ||
493 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, FSRDLY(1)); | ||
494 | break; | ||
495 | } | ||
496 | |||
476 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 497 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
477 | case SND_SOC_DAIFMT_CBS_CFS: | 498 | case SND_SOC_DAIFMT_CBS_CFS: |
478 | /* codec is clock and frame slave */ | 499 | /* codec is clock and frame slave */ |
@@ -482,8 +503,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
482 | mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); | 503 | mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); |
483 | mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); | 504 | mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); |
484 | 505 | ||
485 | mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, | 506 | mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, ACLKX | AFSX); |
486 | ACLKX | AHCLKX | AFSX); | ||
487 | break; | 507 | break; |
488 | case SND_SOC_DAIFMT_CBM_CFS: | 508 | case SND_SOC_DAIFMT_CBM_CFS: |
489 | /* codec is clock master and frame slave */ | 509 | /* codec is clock master and frame slave */ |
@@ -554,59 +574,75 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
554 | return 0; | 574 | return 0; |
555 | } | 575 | } |
556 | 576 | ||
557 | static int davinci_config_channel_size(struct davinci_audio_dev *dev, | 577 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) |
558 | int channel_size) | ||
559 | { | 578 | { |
560 | u32 fmt = 0; | 579 | struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai); |
561 | u32 mask, rotate; | ||
562 | |||
563 | switch (channel_size) { | ||
564 | case DAVINCI_AUDIO_WORD_8: | ||
565 | fmt = 0x03; | ||
566 | rotate = 6; | ||
567 | mask = 0x000000ff; | ||
568 | break; | ||
569 | 580 | ||
570 | case DAVINCI_AUDIO_WORD_12: | 581 | switch (div_id) { |
571 | fmt = 0x05; | 582 | case 0: /* MCLK divider */ |
572 | rotate = 5; | 583 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, |
573 | mask = 0x00000fff; | 584 | AHCLKXDIV(div - 1), AHCLKXDIV_MASK); |
585 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, | ||
586 | AHCLKRDIV(div - 1), AHCLKRDIV_MASK); | ||
574 | break; | 587 | break; |
575 | 588 | ||
576 | case DAVINCI_AUDIO_WORD_16: | 589 | case 1: /* BCLK divider */ |
577 | fmt = 0x07; | 590 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, |
578 | rotate = 4; | 591 | ACLKXDIV(div - 1), ACLKXDIV_MASK); |
579 | mask = 0x0000ffff; | 592 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_ACLKRCTL_REG, |
593 | ACLKRDIV(div - 1), ACLKRDIV_MASK); | ||
580 | break; | 594 | break; |
581 | 595 | ||
582 | case DAVINCI_AUDIO_WORD_20: | 596 | case 2: /* BCLK/LRCLK ratio */ |
583 | fmt = 0x09; | 597 | dev->bclk_lrclk_ratio = div; |
584 | rotate = 3; | ||
585 | mask = 0x000fffff; | ||
586 | break; | 598 | break; |
587 | 599 | ||
588 | case DAVINCI_AUDIO_WORD_24: | 600 | default: |
589 | fmt = 0x0B; | 601 | return -EINVAL; |
590 | rotate = 2; | 602 | } |
591 | mask = 0x00ffffff; | ||
592 | break; | ||
593 | 603 | ||
594 | case DAVINCI_AUDIO_WORD_28: | 604 | return 0; |
595 | fmt = 0x0D; | 605 | } |
596 | rotate = 1; | ||
597 | mask = 0x0fffffff; | ||
598 | break; | ||
599 | 606 | ||
600 | case DAVINCI_AUDIO_WORD_32: | 607 | static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, |
601 | fmt = 0x0F; | 608 | unsigned int freq, int dir) |
602 | rotate = 0; | 609 | { |
603 | mask = 0xffffffff; | 610 | struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai); |
604 | break; | ||
605 | 611 | ||
606 | default: | 612 | if (dir == SND_SOC_CLOCK_OUT) { |
607 | return -EINVAL; | 613 | mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); |
614 | mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); | ||
615 | mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AHCLKX); | ||
616 | } else { | ||
617 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); | ||
618 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); | ||
619 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AHCLKX); | ||
608 | } | 620 | } |
609 | 621 | ||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | static int davinci_config_channel_size(struct davinci_audio_dev *dev, | ||
626 | int word_length) | ||
627 | { | ||
628 | u32 fmt; | ||
629 | u32 rotate = (32 - word_length) / 4; | ||
630 | u32 mask = (1ULL << word_length) - 1; | ||
631 | |||
632 | /* | ||
633 | * if s BCLK-to-LRCLK ratio has been configured via the set_clkdiv() | ||
634 | * callback, take it into account here. That allows us to for example | ||
635 | * send 32 bits per channel to the codec, while only 16 of them carry | ||
636 | * audio payload. | ||
637 | * The clock ratio is given for a full period of data (both left and | ||
638 | * right channels), so it has to be divided by 2. | ||
639 | */ | ||
640 | if (dev->bclk_lrclk_ratio) | ||
641 | word_length = dev->bclk_lrclk_ratio / 2; | ||
642 | |||
643 | /* mapping of the XSSZ bit-field as described in the datasheet */ | ||
644 | fmt = (word_length >> 1) - 1; | ||
645 | |||
610 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, | 646 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, |
611 | RXSSZ(fmt), RXSSZ(0x0F)); | 647 | RXSSZ(fmt), RXSSZ(0x0F)); |
612 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, | 648 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, |
@@ -709,8 +745,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
709 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 745 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
710 | /* bit stream is MSB first with no delay */ | 746 | /* bit stream is MSB first with no delay */ |
711 | /* DSP_B mode */ | 747 | /* DSP_B mode */ |
712 | mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, | ||
713 | AHCLKXE); | ||
714 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask); | 748 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask); |
715 | mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD); | 749 | mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD); |
716 | 750 | ||
@@ -720,14 +754,10 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
720 | else | 754 | else |
721 | printk(KERN_ERR "playback tdm slot %d not supported\n", | 755 | printk(KERN_ERR "playback tdm slot %d not supported\n", |
722 | dev->tdm_slots); | 756 | dev->tdm_slots); |
723 | |||
724 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); | ||
725 | } else { | 757 | } else { |
726 | /* bit stream is MSB first with no delay */ | 758 | /* bit stream is MSB first with no delay */ |
727 | /* DSP_B mode */ | 759 | /* DSP_B mode */ |
728 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD); | 760 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD); |
729 | mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, | ||
730 | AHCLKRE); | ||
731 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask); | 761 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask); |
732 | 762 | ||
733 | if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32)) | 763 | if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32)) |
@@ -736,8 +766,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
736 | else | 766 | else |
737 | printk(KERN_ERR "capture tdm slot %d not supported\n", | 767 | printk(KERN_ERR "capture tdm slot %d not supported\n", |
738 | dev->tdm_slots); | 768 | dev->tdm_slots); |
739 | |||
740 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); | ||
741 | } | 769 | } |
742 | } | 770 | } |
743 | 771 | ||
@@ -800,19 +828,27 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
800 | case SNDRV_PCM_FORMAT_U8: | 828 | case SNDRV_PCM_FORMAT_U8: |
801 | case SNDRV_PCM_FORMAT_S8: | 829 | case SNDRV_PCM_FORMAT_S8: |
802 | dma_params->data_type = 1; | 830 | dma_params->data_type = 1; |
803 | word_length = DAVINCI_AUDIO_WORD_8; | 831 | word_length = 8; |
804 | break; | 832 | break; |
805 | 833 | ||
806 | case SNDRV_PCM_FORMAT_U16_LE: | 834 | case SNDRV_PCM_FORMAT_U16_LE: |
807 | case SNDRV_PCM_FORMAT_S16_LE: | 835 | case SNDRV_PCM_FORMAT_S16_LE: |
808 | dma_params->data_type = 2; | 836 | dma_params->data_type = 2; |
809 | word_length = DAVINCI_AUDIO_WORD_16; | 837 | word_length = 16; |
838 | break; | ||
839 | |||
840 | case SNDRV_PCM_FORMAT_U24_3LE: | ||
841 | case SNDRV_PCM_FORMAT_S24_3LE: | ||
842 | dma_params->data_type = 3; | ||
843 | word_length = 24; | ||
810 | break; | 844 | break; |
811 | 845 | ||
846 | case SNDRV_PCM_FORMAT_U24_LE: | ||
847 | case SNDRV_PCM_FORMAT_S24_LE: | ||
812 | case SNDRV_PCM_FORMAT_U32_LE: | 848 | case SNDRV_PCM_FORMAT_U32_LE: |
813 | case SNDRV_PCM_FORMAT_S32_LE: | 849 | case SNDRV_PCM_FORMAT_S32_LE: |
814 | dma_params->data_type = 4; | 850 | dma_params->data_type = 4; |
815 | word_length = DAVINCI_AUDIO_WORD_32; | 851 | word_length = 32; |
816 | break; | 852 | break; |
817 | 853 | ||
818 | default: | 854 | default: |
@@ -880,13 +916,18 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { | |||
880 | .trigger = davinci_mcasp_trigger, | 916 | .trigger = davinci_mcasp_trigger, |
881 | .hw_params = davinci_mcasp_hw_params, | 917 | .hw_params = davinci_mcasp_hw_params, |
882 | .set_fmt = davinci_mcasp_set_dai_fmt, | 918 | .set_fmt = davinci_mcasp_set_dai_fmt, |
883 | 919 | .set_clkdiv = davinci_mcasp_set_clkdiv, | |
920 | .set_sysclk = davinci_mcasp_set_sysclk, | ||
884 | }; | 921 | }; |
885 | 922 | ||
886 | #define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \ | 923 | #define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \ |
887 | SNDRV_PCM_FMTBIT_U8 | \ | 924 | SNDRV_PCM_FMTBIT_U8 | \ |
888 | SNDRV_PCM_FMTBIT_S16_LE | \ | 925 | SNDRV_PCM_FMTBIT_S16_LE | \ |
889 | SNDRV_PCM_FMTBIT_U16_LE | \ | 926 | SNDRV_PCM_FMTBIT_U16_LE | \ |
927 | SNDRV_PCM_FMTBIT_S24_LE | \ | ||
928 | SNDRV_PCM_FMTBIT_U24_LE | \ | ||
929 | SNDRV_PCM_FMTBIT_S24_3LE | \ | ||
930 | SNDRV_PCM_FMTBIT_U24_3LE | \ | ||
890 | SNDRV_PCM_FMTBIT_S32_LE | \ | 931 | SNDRV_PCM_FMTBIT_S32_LE | \ |
891 | SNDRV_PCM_FMTBIT_U32_LE) | 932 | SNDRV_PCM_FMTBIT_U32_LE) |
892 | 933 | ||
@@ -1089,7 +1130,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1089 | dev->tdm_slots = pdata->tdm_slots; | 1130 | dev->tdm_slots = pdata->tdm_slots; |
1090 | dev->num_serializer = pdata->num_serializer; | 1131 | dev->num_serializer = pdata->num_serializer; |
1091 | dev->serial_dir = pdata->serial_dir; | 1132 | dev->serial_dir = pdata->serial_dir; |
1092 | dev->codec_fmt = pdata->codec_fmt; | ||
1093 | dev->version = pdata->version; | 1133 | dev->version = pdata->version; |
1094 | dev->txnumevt = pdata->txnumevt; | 1134 | dev->txnumevt = pdata->txnumevt; |
1095 | dev->rxnumevt = pdata->rxnumevt; | 1135 | dev->rxnumevt = pdata->rxnumevt; |
@@ -1098,6 +1138,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1098 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; | 1138 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; |
1099 | dma_data->asp_chan_q = pdata->asp_chan_q; | 1139 | dma_data->asp_chan_q = pdata->asp_chan_q; |
1100 | dma_data->ram_chan_q = pdata->ram_chan_q; | 1140 | dma_data->ram_chan_q = pdata->ram_chan_q; |
1141 | dma_data->sram_pool = pdata->sram_pool; | ||
1101 | dma_data->sram_size = pdata->sram_size_playback; | 1142 | dma_data->sram_size = pdata->sram_size_playback; |
1102 | dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + | 1143 | dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + |
1103 | mem->start); | 1144 | mem->start); |
@@ -1115,6 +1156,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1115 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; | 1156 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; |
1116 | dma_data->asp_chan_q = pdata->asp_chan_q; | 1157 | dma_data->asp_chan_q = pdata->asp_chan_q; |
1117 | dma_data->ram_chan_q = pdata->ram_chan_q; | 1158 | dma_data->ram_chan_q = pdata->ram_chan_q; |
1159 | dma_data->sram_pool = pdata->sram_pool; | ||
1118 | dma_data->sram_size = pdata->sram_size_capture; | 1160 | dma_data->sram_size = pdata->sram_size_capture; |
1119 | dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + | 1161 | dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + |
1120 | mem->start); | 1162 | mem->start); |
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index 0de9ed6ce038..0edd3b5a37fd 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h | |||
@@ -23,26 +23,14 @@ | |||
23 | 23 | ||
24 | #include "davinci-pcm.h" | 24 | #include "davinci-pcm.h" |
25 | 25 | ||
26 | #define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000 | 26 | #define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_192000 |
27 | #define DAVINCI_MCASP_I2S_DAI 0 | 27 | #define DAVINCI_MCASP_I2S_DAI 0 |
28 | #define DAVINCI_MCASP_DIT_DAI 1 | 28 | #define DAVINCI_MCASP_DIT_DAI 1 |
29 | 29 | ||
30 | enum { | ||
31 | DAVINCI_AUDIO_WORD_8 = 0, | ||
32 | DAVINCI_AUDIO_WORD_12, | ||
33 | DAVINCI_AUDIO_WORD_16, | ||
34 | DAVINCI_AUDIO_WORD_20, | ||
35 | DAVINCI_AUDIO_WORD_24, | ||
36 | DAVINCI_AUDIO_WORD_32, | ||
37 | DAVINCI_AUDIO_WORD_28, /* This is only valid for McASP */ | ||
38 | }; | ||
39 | |||
40 | struct davinci_audio_dev { | 30 | struct davinci_audio_dev { |
41 | struct davinci_pcm_dma_params dma_params[2]; | 31 | struct davinci_pcm_dma_params dma_params[2]; |
42 | void __iomem *base; | 32 | void __iomem *base; |
43 | int sample_rate; | ||
44 | struct device *dev; | 33 | struct device *dev; |
45 | unsigned int codec_fmt; | ||
46 | 34 | ||
47 | /* McASP specific data */ | 35 | /* McASP specific data */ |
48 | int tdm_slots; | 36 | int tdm_slots; |
@@ -50,6 +38,7 @@ struct davinci_audio_dev { | |||
50 | u8 num_serializer; | 38 | u8 num_serializer; |
51 | u8 *serial_dir; | 39 | u8 *serial_dir; |
52 | u8 version; | 40 | u8 version; |
41 | u8 bclk_lrclk_ratio; | ||
53 | 42 | ||
54 | /* McASP FIFO related */ | 43 | /* McASP FIFO related */ |
55 | u8 txnumevt; | 44 | u8 txnumevt; |
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index 93ea3bf567e1..afab81f844ae 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/genalloc.h> | ||
19 | 20 | ||
20 | #include <sound/core.h> | 21 | #include <sound/core.h> |
21 | #include <sound/pcm.h> | 22 | #include <sound/pcm.h> |
@@ -23,7 +24,6 @@ | |||
23 | #include <sound/soc.h> | 24 | #include <sound/soc.h> |
24 | 25 | ||
25 | #include <asm/dma.h> | 26 | #include <asm/dma.h> |
26 | #include <mach/sram.h> | ||
27 | 27 | ||
28 | #include "davinci-pcm.h" | 28 | #include "davinci-pcm.h" |
29 | 29 | ||
@@ -67,13 +67,9 @@ static struct snd_pcm_hardware pcm_hardware_playback = { | |||
67 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME| | 67 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME| |
68 | SNDRV_PCM_INFO_BATCH), | 68 | SNDRV_PCM_INFO_BATCH), |
69 | .formats = DAVINCI_PCM_FMTBITS, | 69 | .formats = DAVINCI_PCM_FMTBITS, |
70 | .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | | 70 | .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT, |
71 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | | ||
72 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | | ||
73 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | | ||
74 | SNDRV_PCM_RATE_KNOT), | ||
75 | .rate_min = 8000, | 71 | .rate_min = 8000, |
76 | .rate_max = 96000, | 72 | .rate_max = 192000, |
77 | .channels_min = 2, | 73 | .channels_min = 2, |
78 | .channels_max = 384, | 74 | .channels_max = 384, |
79 | .buffer_bytes_max = 128 * 1024, | 75 | .buffer_bytes_max = 128 * 1024, |
@@ -90,13 +86,9 @@ static struct snd_pcm_hardware pcm_hardware_capture = { | |||
90 | SNDRV_PCM_INFO_PAUSE | | 86 | SNDRV_PCM_INFO_PAUSE | |
91 | SNDRV_PCM_INFO_BATCH), | 87 | SNDRV_PCM_INFO_BATCH), |
92 | .formats = DAVINCI_PCM_FMTBITS, | 88 | .formats = DAVINCI_PCM_FMTBITS, |
93 | .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | | 89 | .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT, |
94 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | | ||
95 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | | ||
96 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | | ||
97 | SNDRV_PCM_RATE_KNOT), | ||
98 | .rate_min = 8000, | 90 | .rate_min = 8000, |
99 | .rate_max = 96000, | 91 | .rate_max = 192000, |
100 | .channels_min = 2, | 92 | .channels_min = 2, |
101 | .channels_max = 384, | 93 | .channels_max = 384, |
102 | .buffer_bytes_max = 128 * 1024, | 94 | .buffer_bytes_max = 128 * 1024, |
@@ -259,7 +251,9 @@ static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) | |||
259 | } | 251 | } |
260 | } | 252 | } |
261 | 253 | ||
262 | static int allocate_sram(struct snd_pcm_substream *substream, unsigned size, | 254 | #ifdef CONFIG_GENERIC_ALLOCATOR |
255 | static int allocate_sram(struct snd_pcm_substream *substream, | ||
256 | struct gen_pool *sram_pool, unsigned size, | ||
263 | struct snd_pcm_hardware *ppcm) | 257 | struct snd_pcm_hardware *ppcm) |
264 | { | 258 | { |
265 | struct snd_dma_buffer *buf = &substream->dma_buffer; | 259 | struct snd_dma_buffer *buf = &substream->dma_buffer; |
@@ -271,9 +265,10 @@ static int allocate_sram(struct snd_pcm_substream *substream, unsigned size, | |||
271 | return 0; | 265 | return 0; |
272 | 266 | ||
273 | ppcm->period_bytes_max = size; | 267 | ppcm->period_bytes_max = size; |
274 | iram_virt = sram_alloc(size, &iram_phys); | 268 | iram_virt = (void *)gen_pool_alloc(sram_pool, size); |
275 | if (!iram_virt) | 269 | if (!iram_virt) |
276 | goto exit1; | 270 | goto exit1; |
271 | iram_phys = gen_pool_virt_to_phys(sram_pool, (unsigned)iram_virt); | ||
277 | iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL); | 272 | iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL); |
278 | if (!iram_dma) | 273 | if (!iram_dma) |
279 | goto exit2; | 274 | goto exit2; |
@@ -285,11 +280,33 @@ static int allocate_sram(struct snd_pcm_substream *substream, unsigned size, | |||
285 | return 0; | 280 | return 0; |
286 | exit2: | 281 | exit2: |
287 | if (iram_virt) | 282 | if (iram_virt) |
288 | sram_free(iram_virt, size); | 283 | gen_pool_free(sram_pool, (unsigned)iram_virt, size); |
289 | exit1: | 284 | exit1: |
290 | return -ENOMEM; | 285 | return -ENOMEM; |
291 | } | 286 | } |
292 | 287 | ||
288 | static void davinci_free_sram(struct snd_pcm_substream *substream, | ||
289 | struct snd_dma_buffer *iram_dma) | ||
290 | { | ||
291 | struct davinci_runtime_data *prtd = substream->runtime->private_data; | ||
292 | struct gen_pool *sram_pool = prtd->params->sram_pool; | ||
293 | |||
294 | gen_pool_free(sram_pool, (unsigned) iram_dma->area, iram_dma->bytes); | ||
295 | } | ||
296 | #else | ||
297 | static int allocate_sram(struct snd_pcm_substream *substream, | ||
298 | struct gen_pool *sram_pool, unsigned size, | ||
299 | struct snd_pcm_hardware *ppcm) | ||
300 | { | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static void davinci_free_sram(struct snd_pcm_substream *substream, | ||
305 | struct snd_dma_buffer *iram_dma) | ||
306 | { | ||
307 | } | ||
308 | #endif | ||
309 | |||
293 | /* | 310 | /* |
294 | * Only used with ping/pong. | 311 | * Only used with ping/pong. |
295 | * This is called after runtime->dma_addr, period_bytes and data_type are valid | 312 | * This is called after runtime->dma_addr, period_bytes and data_type are valid |
@@ -676,7 +693,7 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream) | |||
676 | 693 | ||
677 | ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | 694 | ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? |
678 | &pcm_hardware_playback : &pcm_hardware_capture; | 695 | &pcm_hardware_playback : &pcm_hardware_capture; |
679 | allocate_sram(substream, params->sram_size, ppcm); | 696 | allocate_sram(substream, params->sram_pool, params->sram_size, ppcm); |
680 | snd_soc_set_runtime_hwparams(substream, ppcm); | 697 | snd_soc_set_runtime_hwparams(substream, ppcm); |
681 | /* ensure that buffer size is a multiple of period size */ | 698 | /* ensure that buffer size is a multiple of period size */ |
682 | ret = snd_pcm_hw_constraint_integer(runtime, | 699 | ret = snd_pcm_hw_constraint_integer(runtime, |
@@ -819,7 +836,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm) | |||
819 | buf->area = NULL; | 836 | buf->area = NULL; |
820 | iram_dma = buf->private_data; | 837 | iram_dma = buf->private_data; |
821 | if (iram_dma) { | 838 | if (iram_dma) { |
822 | sram_free(iram_dma->area, iram_dma->bytes); | 839 | davinci_free_sram(substream, iram_dma); |
823 | kfree(iram_dma); | 840 | kfree(iram_dma); |
824 | } | 841 | } |
825 | } | 842 | } |
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h index fc4d01cdd8c9..b6ef7039dd09 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #ifndef _DAVINCI_PCM_H | 12 | #ifndef _DAVINCI_PCM_H |
13 | #define _DAVINCI_PCM_H | 13 | #define _DAVINCI_PCM_H |
14 | 14 | ||
15 | #include <linux/genalloc.h> | ||
15 | #include <linux/platform_data/davinci_asp.h> | 16 | #include <linux/platform_data/davinci_asp.h> |
16 | #include <mach/edma.h> | 17 | #include <mach/edma.h> |
17 | 18 | ||
@@ -20,6 +21,7 @@ struct davinci_pcm_dma_params { | |||
20 | unsigned short acnt; | 21 | unsigned short acnt; |
21 | dma_addr_t dma_addr; /* device physical address for DMA */ | 22 | dma_addr_t dma_addr; /* device physical address for DMA */ |
22 | unsigned sram_size; | 23 | unsigned sram_size; |
24 | struct gen_pool *sram_pool; /* SRAM gen_pool for ping pong */ | ||
23 | enum dma_event_q asp_chan_q; /* event queue number for ASP channel */ | 25 | enum dma_event_q asp_chan_q; /* event queue number for ASP channel */ |
24 | enum dma_event_q ram_chan_q; /* event queue number for RAM channel */ | 26 | enum dma_event_q ram_chan_q; /* event queue number for RAM channel */ |
25 | unsigned char data_type; /* xfer data type */ | 27 | unsigned char data_type; /* xfer data type */ |
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 4563b28bd625..3b98159d9645 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig | |||
@@ -46,6 +46,20 @@ config SND_SOC_P1022_DS | |||
46 | This will also include the Wolfson Microelectronics WM8776 codec | 46 | This will also include the Wolfson Microelectronics WM8776 codec |
47 | driver. | 47 | driver. |
48 | 48 | ||
49 | config SND_SOC_P1022_RDK | ||
50 | tristate "ALSA SoC support for the Freescale / iVeia P1022 RDK board" | ||
51 | # I2C is necessary for the WM8960 driver | ||
52 | depends on P1022_RDK && I2C | ||
53 | select SND_SOC_FSL_SSI | ||
54 | select SND_SOC_FSL_UTILS | ||
55 | select SND_SOC_POWERPC_DMA | ||
56 | select SND_SOC_WM8960 | ||
57 | default y if P1022_RDK | ||
58 | help | ||
59 | Say Y if you want to enable audio on the Freescale / iVeia | ||
60 | P1022 RDK board. This will also include the Wolfson | ||
61 | Microelectronics WM8960 codec driver. | ||
62 | |||
49 | config SND_SOC_MPC5200_I2S | 63 | config SND_SOC_MPC5200_I2S |
50 | tristate "Freescale MPC5200 PSC in I2S mode driver" | 64 | tristate "Freescale MPC5200 PSC in I2S mode driver" |
51 | depends on PPC_MPC52xx && PPC_BESTCOMM | 65 | depends on PPC_MPC52xx && PPC_BESTCOMM |
@@ -98,12 +112,12 @@ config SND_SOC_IMX_PCM | |||
98 | tristate | 112 | tristate |
99 | 113 | ||
100 | config SND_SOC_IMX_PCM_FIQ | 114 | config SND_SOC_IMX_PCM_FIQ |
101 | tristate | 115 | bool |
102 | select FIQ | 116 | select FIQ |
103 | select SND_SOC_IMX_PCM | 117 | select SND_SOC_IMX_PCM |
104 | 118 | ||
105 | config SND_SOC_IMX_PCM_DMA | 119 | config SND_SOC_IMX_PCM_DMA |
106 | tristate | 120 | bool |
107 | select SND_SOC_DMAENGINE_PCM | 121 | select SND_SOC_DMAENGINE_PCM |
108 | select SND_SOC_IMX_PCM | 122 | select SND_SOC_IMX_PCM |
109 | 123 | ||
@@ -112,7 +126,7 @@ config SND_SOC_IMX_AUDMUX | |||
112 | 126 | ||
113 | config SND_MXC_SOC_WM1133_EV1 | 127 | config SND_MXC_SOC_WM1133_EV1 |
114 | tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted" | 128 | tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted" |
115 | depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL | 129 | depends on MACH_MX31ADS_WM1133_EV1 |
116 | select SND_SOC_WM8350 | 130 | select SND_SOC_WM8350 |
117 | select SND_SOC_IMX_PCM_FIQ | 131 | select SND_SOC_IMX_PCM_FIQ |
118 | select SND_SOC_IMX_AUDMUX | 132 | select SND_SOC_IMX_AUDMUX |
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index 5f3cf3f52ea0..afd34794db53 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile | |||
@@ -6,6 +6,10 @@ obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += snd-soc-mpc8610-hpcd.o | |||
6 | snd-soc-p1022-ds-objs := p1022_ds.o | 6 | snd-soc-p1022-ds-objs := p1022_ds.o |
7 | obj-$(CONFIG_SND_SOC_P1022_DS) += snd-soc-p1022-ds.o | 7 | obj-$(CONFIG_SND_SOC_P1022_DS) += snd-soc-p1022-ds.o |
8 | 8 | ||
9 | # P1022 RDK Machine Support | ||
10 | snd-soc-p1022-rdk-objs := p1022_rdk.o | ||
11 | obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o | ||
12 | |||
9 | # Freescale PowerPC SSI/DMA Platform Support | 13 | # Freescale PowerPC SSI/DMA Platform Support |
10 | snd-soc-fsl-ssi-objs := fsl_ssi.o | 14 | snd-soc-fsl-ssi-objs := fsl_ssi.o |
11 | snd-soc-fsl-utils-objs := fsl_utils.o | 15 | snd-soc-fsl-utils-objs := fsl_utils.o |
@@ -26,14 +30,18 @@ obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o | |||
26 | # i.MX Platform Support | 30 | # i.MX Platform Support |
27 | snd-soc-imx-ssi-objs := imx-ssi.o | 31 | snd-soc-imx-ssi-objs := imx-ssi.o |
28 | snd-soc-imx-audmux-objs := imx-audmux.o | 32 | snd-soc-imx-audmux-objs := imx-audmux.o |
33 | snd-soc-imx-pcm-objs := imx-pcm.o | ||
34 | ifneq ($(CONFIG_SND_SOC_IMX_PCM_FIQ),) | ||
35 | snd-soc-imx-pcm-objs += imx-pcm-fiq.o | ||
36 | endif | ||
37 | ifneq ($(CONFIG_SND_SOC_IMX_PCM_DMA),) | ||
38 | snd-soc-imx-pcm-objs += imx-pcm-dma.o | ||
39 | endif | ||
29 | 40 | ||
30 | obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o | 41 | obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o |
31 | obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o | 42 | obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o |
32 | 43 | ||
33 | obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o | 44 | obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o |
34 | snd-soc-imx-pcm-y := imx-pcm.o | ||
35 | snd-soc-imx-pcm-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += imx-pcm-fiq.o | ||
36 | snd-soc-imx-pcm-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o | ||
37 | 45 | ||
38 | # i.MX Machine Support | 46 | # i.MX Machine Support |
39 | snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o | 47 | snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o |
diff --git a/sound/soc/fsl/imx-pcm.c b/sound/soc/fsl/imx-pcm.c index 93dc360b1777..d5cd9eff3b48 100644 --- a/sound/soc/fsl/imx-pcm.c +++ b/sound/soc/fsl/imx-pcm.c | |||
@@ -103,3 +103,7 @@ void imx_pcm_free(struct snd_pcm *pcm) | |||
103 | } | 103 | } |
104 | } | 104 | } |
105 | EXPORT_SYMBOL_GPL(imx_pcm_free); | 105 | EXPORT_SYMBOL_GPL(imx_pcm_free); |
106 | |||
107 | MODULE_DESCRIPTION("Freescale i.MX PCM driver"); | ||
108 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | ||
109 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 199408ec4261..3d9b1c427ce9 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c | |||
@@ -162,6 +162,7 @@ static int __devinit imx_sgtl5000_probe(struct platform_device *pdev) | |||
162 | if (ret) | 162 | if (ret) |
163 | goto clk_fail; | 163 | goto clk_fail; |
164 | data->card.num_links = 1; | 164 | data->card.num_links = 1; |
165 | data->card.owner = THIS_MODULE; | ||
165 | data->card.dai_link = &data->dai; | 166 | data->card.dai_link = &data->dai; |
166 | data->card.dapm_widgets = imx_sgtl5000_dapm_widgets; | 167 | data->card.dapm_widgets = imx_sgtl5000_dapm_widgets; |
167 | data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets); | 168 | data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets); |
diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c new file mode 100644 index 000000000000..897e32ffdc42 --- /dev/null +++ b/sound/soc/fsl/p1022_rdk.c | |||
@@ -0,0 +1,392 @@ | |||
1 | /** | ||
2 | * Freescale P1022RDK ALSA SoC Machine driver | ||
3 | * | ||
4 | * Author: Timur Tabi <timur@freescale.com> | ||
5 | * | ||
6 | * Copyright 2012 Freescale Semiconductor, Inc. | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public License | ||
9 | * version 2. This program is licensed "as is" without any warranty of any | ||
10 | * kind, whether express or implied. | ||
11 | * | ||
12 | * Note: in order for audio to work correctly, the output controls need | ||
13 | * to be enabled, because they control the clock. So for playback, for | ||
14 | * example: | ||
15 | * | ||
16 | * amixer sset 'Left Output Mixer PCM' on | ||
17 | * amixer sset 'Right Output Mixer PCM' on | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/of_device.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <sound/soc.h> | ||
25 | #include <asm/fsl_guts.h> | ||
26 | |||
27 | #include "fsl_dma.h" | ||
28 | #include "fsl_ssi.h" | ||
29 | #include "fsl_utils.h" | ||
30 | |||
31 | /* P1022-specific PMUXCR and DMUXCR bit definitions */ | ||
32 | |||
33 | #define CCSR_GUTS_PMUXCR_UART0_I2C1_MASK 0x0001c000 | ||
34 | #define CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI 0x00010000 | ||
35 | #define CCSR_GUTS_PMUXCR_UART0_I2C1_SSI 0x00018000 | ||
36 | |||
37 | #define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK 0x00000c00 | ||
38 | #define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI 0x00000000 | ||
39 | |||
40 | #define CCSR_GUTS_DMUXCR_PAD 1 /* DMA controller/channel set to pad */ | ||
41 | #define CCSR_GUTS_DMUXCR_SSI 2 /* DMA controller/channel set to SSI */ | ||
42 | |||
43 | /* | ||
44 | * Set the DMACR register in the GUTS | ||
45 | * | ||
46 | * The DMACR register determines the source of initiated transfers for each | ||
47 | * channel on each DMA controller. Rather than have a bunch of repetitive | ||
48 | * macros for the bit patterns, we just have a function that calculates | ||
49 | * them. | ||
50 | * | ||
51 | * guts: Pointer to GUTS structure | ||
52 | * co: The DMA controller (0 or 1) | ||
53 | * ch: The channel on the DMA controller (0, 1, 2, or 3) | ||
54 | * device: The device to set as the target (CCSR_GUTS_DMUXCR_xxx) | ||
55 | */ | ||
56 | static inline void guts_set_dmuxcr(struct ccsr_guts __iomem *guts, | ||
57 | unsigned int co, unsigned int ch, unsigned int device) | ||
58 | { | ||
59 | unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch)); | ||
60 | |||
61 | clrsetbits_be32(&guts->dmuxcr, 3 << shift, device << shift); | ||
62 | } | ||
63 | |||
64 | /* There's only one global utilities register */ | ||
65 | static phys_addr_t guts_phys; | ||
66 | |||
67 | /** | ||
68 | * machine_data: machine-specific ASoC device data | ||
69 | * | ||
70 | * This structure contains data for a single sound platform device on an | ||
71 | * P1022 RDK. Some of the data is taken from the device tree. | ||
72 | */ | ||
73 | struct machine_data { | ||
74 | struct snd_soc_dai_link dai[2]; | ||
75 | struct snd_soc_card card; | ||
76 | unsigned int dai_format; | ||
77 | unsigned int codec_clk_direction; | ||
78 | unsigned int cpu_clk_direction; | ||
79 | unsigned int clk_frequency; | ||
80 | unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */ | ||
81 | unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/ | ||
82 | char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */ | ||
83 | }; | ||
84 | |||
85 | /** | ||
86 | * p1022_rdk_machine_probe: initialize the board | ||
87 | * | ||
88 | * This function is used to initialize the board-specific hardware. | ||
89 | * | ||
90 | * Here we program the DMACR and PMUXCR registers. | ||
91 | */ | ||
92 | static int p1022_rdk_machine_probe(struct snd_soc_card *card) | ||
93 | { | ||
94 | struct machine_data *mdata = | ||
95 | container_of(card, struct machine_data, card); | ||
96 | struct ccsr_guts __iomem *guts; | ||
97 | |||
98 | guts = ioremap(guts_phys, sizeof(struct ccsr_guts)); | ||
99 | if (!guts) { | ||
100 | dev_err(card->dev, "could not map global utilities\n"); | ||
101 | return -ENOMEM; | ||
102 | } | ||
103 | |||
104 | /* Enable SSI Tx signal */ | ||
105 | clrsetbits_be32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_UART0_I2C1_MASK, | ||
106 | CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI); | ||
107 | |||
108 | /* Enable SSI Rx signal */ | ||
109 | clrsetbits_be32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK, | ||
110 | CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI); | ||
111 | |||
112 | /* Enable DMA Channel for SSI */ | ||
113 | guts_set_dmuxcr(guts, mdata->dma_id[0], mdata->dma_channel_id[0], | ||
114 | CCSR_GUTS_DMUXCR_SSI); | ||
115 | |||
116 | guts_set_dmuxcr(guts, mdata->dma_id[1], mdata->dma_channel_id[1], | ||
117 | CCSR_GUTS_DMUXCR_SSI); | ||
118 | |||
119 | iounmap(guts); | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * p1022_rdk_startup: program the board with various hardware parameters | ||
126 | * | ||
127 | * This function takes board-specific information, like clock frequencies | ||
128 | * and serial data formats, and passes that information to the codec and | ||
129 | * transport drivers. | ||
130 | */ | ||
131 | static int p1022_rdk_startup(struct snd_pcm_substream *substream) | ||
132 | { | ||
133 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
134 | struct machine_data *mdata = | ||
135 | container_of(rtd->card, struct machine_data, card); | ||
136 | struct device *dev = rtd->card->dev; | ||
137 | int ret = 0; | ||
138 | |||
139 | /* Tell the codec driver what the serial protocol is. */ | ||
140 | ret = snd_soc_dai_set_fmt(rtd->codec_dai, mdata->dai_format); | ||
141 | if (ret < 0) { | ||
142 | dev_err(dev, "could not set codec driver audio format (ret=%i)\n", | ||
143 | ret); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | ret = snd_soc_dai_set_pll(rtd->codec_dai, 0, 0, mdata->clk_frequency, | ||
148 | mdata->clk_frequency); | ||
149 | if (ret < 0) { | ||
150 | dev_err(dev, "could not set codec PLL frequency (ret=%i)\n", | ||
151 | ret); | ||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * p1022_rdk_machine_remove: Remove the sound device | ||
160 | * | ||
161 | * This function is called to remove the sound device for one SSI. We | ||
162 | * de-program the DMACR and PMUXCR register. | ||
163 | */ | ||
164 | static int p1022_rdk_machine_remove(struct snd_soc_card *card) | ||
165 | { | ||
166 | struct machine_data *mdata = | ||
167 | container_of(card, struct machine_data, card); | ||
168 | struct ccsr_guts __iomem *guts; | ||
169 | |||
170 | guts = ioremap(guts_phys, sizeof(struct ccsr_guts)); | ||
171 | if (!guts) { | ||
172 | dev_err(card->dev, "could not map global utilities\n"); | ||
173 | return -ENOMEM; | ||
174 | } | ||
175 | |||
176 | /* Restore the signal routing */ | ||
177 | clrbits32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_UART0_I2C1_MASK); | ||
178 | clrbits32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK); | ||
179 | guts_set_dmuxcr(guts, mdata->dma_id[0], mdata->dma_channel_id[0], 0); | ||
180 | guts_set_dmuxcr(guts, mdata->dma_id[1], mdata->dma_channel_id[1], 0); | ||
181 | |||
182 | iounmap(guts); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * p1022_rdk_ops: ASoC machine driver operations | ||
189 | */ | ||
190 | static struct snd_soc_ops p1022_rdk_ops = { | ||
191 | .startup = p1022_rdk_startup, | ||
192 | }; | ||
193 | |||
194 | /** | ||
195 | * p1022_rdk_probe: platform probe function for the machine driver | ||
196 | * | ||
197 | * Although this is a machine driver, the SSI node is the "master" node with | ||
198 | * respect to audio hardware connections. Therefore, we create a new ASoC | ||
199 | * device for each new SSI node that has a codec attached. | ||
200 | */ | ||
201 | static int p1022_rdk_probe(struct platform_device *pdev) | ||
202 | { | ||
203 | struct device *dev = pdev->dev.parent; | ||
204 | /* ssi_pdev is the platform device for the SSI node that probed us */ | ||
205 | struct platform_device *ssi_pdev = | ||
206 | container_of(dev, struct platform_device, dev); | ||
207 | struct device_node *np = ssi_pdev->dev.of_node; | ||
208 | struct device_node *codec_np = NULL; | ||
209 | struct machine_data *mdata; | ||
210 | const u32 *iprop; | ||
211 | int ret; | ||
212 | |||
213 | /* Find the codec node for this SSI. */ | ||
214 | codec_np = of_parse_phandle(np, "codec-handle", 0); | ||
215 | if (!codec_np) { | ||
216 | dev_err(dev, "could not find codec node\n"); | ||
217 | return -EINVAL; | ||
218 | } | ||
219 | |||
220 | mdata = kzalloc(sizeof(struct machine_data), GFP_KERNEL); | ||
221 | if (!mdata) { | ||
222 | ret = -ENOMEM; | ||
223 | goto error_put; | ||
224 | } | ||
225 | |||
226 | mdata->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev); | ||
227 | mdata->dai[0].ops = &p1022_rdk_ops; | ||
228 | |||
229 | /* ASoC core can match codec with device node */ | ||
230 | mdata->dai[0].codec_of_node = codec_np; | ||
231 | |||
232 | /* | ||
233 | * We register two DAIs per SSI, one for playback and the other for | ||
234 | * capture. We support codecs that have separate DAIs for both playback | ||
235 | * and capture. | ||
236 | */ | ||
237 | memcpy(&mdata->dai[1], &mdata->dai[0], sizeof(struct snd_soc_dai_link)); | ||
238 | |||
239 | /* The DAI names from the codec (snd_soc_dai_driver.name) */ | ||
240 | mdata->dai[0].codec_dai_name = "wm8960-hifi"; | ||
241 | mdata->dai[1].codec_dai_name = mdata->dai[0].codec_dai_name; | ||
242 | |||
243 | /* | ||
244 | * Configure the SSI for I2S slave mode. Older device trees have | ||
245 | * an fsl,mode property, but we ignore that since there's really | ||
246 | * only one way to configure the SSI. | ||
247 | */ | ||
248 | mdata->dai_format = SND_SOC_DAIFMT_NB_NF | | ||
249 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM; | ||
250 | mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; | ||
251 | mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; | ||
252 | |||
253 | /* | ||
254 | * In i2s-slave mode, the codec has its own clock source, so we | ||
255 | * need to get the frequency from the device tree and pass it to | ||
256 | * the codec driver. | ||
257 | */ | ||
258 | iprop = of_get_property(codec_np, "clock-frequency", NULL); | ||
259 | if (!iprop || !*iprop) { | ||
260 | dev_err(&pdev->dev, "codec bus-frequency property is missing or invalid\n"); | ||
261 | ret = -EINVAL; | ||
262 | goto error; | ||
263 | } | ||
264 | mdata->clk_frequency = be32_to_cpup(iprop); | ||
265 | |||
266 | if (!mdata->clk_frequency) { | ||
267 | dev_err(&pdev->dev, "unknown clock frequency\n"); | ||
268 | ret = -EINVAL; | ||
269 | goto error; | ||
270 | } | ||
271 | |||
272 | /* Find the playback DMA channel to use. */ | ||
273 | mdata->dai[0].platform_name = mdata->platform_name[0]; | ||
274 | ret = fsl_asoc_get_dma_channel(np, "fsl,playback-dma", &mdata->dai[0], | ||
275 | &mdata->dma_channel_id[0], | ||
276 | &mdata->dma_id[0]); | ||
277 | if (ret) { | ||
278 | dev_err(&pdev->dev, "missing/invalid playback DMA phandle (ret=%i)\n", | ||
279 | ret); | ||
280 | goto error; | ||
281 | } | ||
282 | |||
283 | /* Find the capture DMA channel to use. */ | ||
284 | mdata->dai[1].platform_name = mdata->platform_name[1]; | ||
285 | ret = fsl_asoc_get_dma_channel(np, "fsl,capture-dma", &mdata->dai[1], | ||
286 | &mdata->dma_channel_id[1], | ||
287 | &mdata->dma_id[1]); | ||
288 | if (ret) { | ||
289 | dev_err(&pdev->dev, "missing/invalid capture DMA phandle (ret=%i)\n", | ||
290 | ret); | ||
291 | goto error; | ||
292 | } | ||
293 | |||
294 | /* Initialize our DAI data structure. */ | ||
295 | mdata->dai[0].stream_name = "playback"; | ||
296 | mdata->dai[1].stream_name = "capture"; | ||
297 | mdata->dai[0].name = mdata->dai[0].stream_name; | ||
298 | mdata->dai[1].name = mdata->dai[1].stream_name; | ||
299 | |||
300 | mdata->card.probe = p1022_rdk_machine_probe; | ||
301 | mdata->card.remove = p1022_rdk_machine_remove; | ||
302 | mdata->card.name = pdev->name; /* The platform driver name */ | ||
303 | mdata->card.owner = THIS_MODULE; | ||
304 | mdata->card.dev = &pdev->dev; | ||
305 | mdata->card.num_links = 2; | ||
306 | mdata->card.dai_link = mdata->dai; | ||
307 | |||
308 | /* Register with ASoC */ | ||
309 | ret = snd_soc_register_card(&mdata->card); | ||
310 | if (ret) { | ||
311 | dev_err(&pdev->dev, "could not register card (ret=%i)\n", ret); | ||
312 | goto error; | ||
313 | } | ||
314 | |||
315 | return 0; | ||
316 | |||
317 | error: | ||
318 | kfree(mdata); | ||
319 | error_put: | ||
320 | of_node_put(codec_np); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * p1022_rdk_remove: remove the platform device | ||
326 | * | ||
327 | * This function is called when the platform device is removed. | ||
328 | */ | ||
329 | static int __devexit p1022_rdk_remove(struct platform_device *pdev) | ||
330 | { | ||
331 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
332 | struct machine_data *mdata = | ||
333 | container_of(card, struct machine_data, card); | ||
334 | |||
335 | snd_soc_unregister_card(card); | ||
336 | kfree(mdata); | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static struct platform_driver p1022_rdk_driver = { | ||
342 | .probe = p1022_rdk_probe, | ||
343 | .remove = __devexit_p(p1022_rdk_remove), | ||
344 | .driver = { | ||
345 | /* | ||
346 | * The name must match 'compatible' property in the device tree, | ||
347 | * in lowercase letters. | ||
348 | */ | ||
349 | .name = "snd-soc-p1022rdk", | ||
350 | .owner = THIS_MODULE, | ||
351 | }, | ||
352 | }; | ||
353 | |||
354 | /** | ||
355 | * p1022_rdk_init: machine driver initialization. | ||
356 | * | ||
357 | * This function is called when this module is loaded. | ||
358 | */ | ||
359 | static int __init p1022_rdk_init(void) | ||
360 | { | ||
361 | struct device_node *guts_np; | ||
362 | struct resource res; | ||
363 | |||
364 | /* Get the physical address of the global utilities registers */ | ||
365 | guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); | ||
366 | if (of_address_to_resource(guts_np, 0, &res)) { | ||
367 | pr_err("snd-soc-p1022rdk: missing/invalid global utils node\n"); | ||
368 | of_node_put(guts_np); | ||
369 | return -EINVAL; | ||
370 | } | ||
371 | guts_phys = res.start; | ||
372 | of_node_put(guts_np); | ||
373 | |||
374 | return platform_driver_register(&p1022_rdk_driver); | ||
375 | } | ||
376 | |||
377 | /** | ||
378 | * p1022_rdk_exit: machine driver exit | ||
379 | * | ||
380 | * This function is called when this driver is unloaded. | ||
381 | */ | ||
382 | static void __exit p1022_rdk_exit(void) | ||
383 | { | ||
384 | platform_driver_unregister(&p1022_rdk_driver); | ||
385 | } | ||
386 | |||
387 | late_initcall(p1022_rdk_init); | ||
388 | module_exit(p1022_rdk_exit); | ||
389 | |||
390 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); | ||
391 | MODULE_DESCRIPTION("Freescale / iVeia P1022 RDK ALSA SoC machine driver"); | ||
392 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c index 4b63ec8eb372..4d261927662f 100644 --- a/sound/soc/fsl/pcm030-audio-fabric.c +++ b/sound/soc/fsl/pcm030-audio-fabric.c | |||
@@ -29,14 +29,14 @@ struct pcm030_audio_data { | |||
29 | 29 | ||
30 | static struct snd_soc_dai_link pcm030_fabric_dai[] = { | 30 | static struct snd_soc_dai_link pcm030_fabric_dai[] = { |
31 | { | 31 | { |
32 | .name = "AC97", | 32 | .name = "AC97.0", |
33 | .stream_name = "AC97 Analog", | 33 | .stream_name = "AC97 Analog", |
34 | .codec_dai_name = "wm9712-hifi", | 34 | .codec_dai_name = "wm9712-hifi", |
35 | .cpu_dai_name = "mpc5200-psc-ac97.0", | 35 | .cpu_dai_name = "mpc5200-psc-ac97.0", |
36 | .codec_name = "wm9712-codec", | 36 | .codec_name = "wm9712-codec", |
37 | }, | 37 | }, |
38 | { | 38 | { |
39 | .name = "AC97", | 39 | .name = "AC97.1", |
40 | .stream_name = "AC97 IEC958", | 40 | .stream_name = "AC97 IEC958", |
41 | .codec_dai_name = "wm9712-aux", | 41 | .codec_dai_name = "wm9712-aux", |
42 | .cpu_dai_name = "mpc5200-psc-ac97.1", | 42 | .cpu_dai_name = "mpc5200-psc-ac97.1", |
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index b9f16598324c..58d5a96b366f 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c | |||
@@ -22,12 +22,16 @@ | |||
22 | #include "kirkwood.h" | 22 | #include "kirkwood.h" |
23 | 23 | ||
24 | #define KIRKWOOD_RATES \ | 24 | #define KIRKWOOD_RATES \ |
25 | (SNDRV_PCM_RATE_44100 | \ | 25 | (SNDRV_PCM_RATE_8000_192000 | \ |
26 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) | 26 | SNDRV_PCM_RATE_CONTINUOUS | \ |
27 | SNDRV_PCM_RATE_KNOT) | ||
28 | |||
27 | #define KIRKWOOD_FORMATS \ | 29 | #define KIRKWOOD_FORMATS \ |
28 | (SNDRV_PCM_FMTBIT_S16_LE | \ | 30 | (SNDRV_PCM_FMTBIT_S16_LE | \ |
29 | SNDRV_PCM_FMTBIT_S24_LE | \ | 31 | SNDRV_PCM_FMTBIT_S24_LE | \ |
30 | SNDRV_PCM_FMTBIT_S32_LE) | 32 | SNDRV_PCM_FMTBIT_S32_LE | \ |
33 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | \ | ||
34 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE) | ||
31 | 35 | ||
32 | struct kirkwood_dma_priv { | 36 | struct kirkwood_dma_priv { |
33 | struct snd_pcm_substream *play_stream; | 37 | struct snd_pcm_substream *play_stream; |
@@ -43,10 +47,10 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = { | |||
43 | SNDRV_PCM_INFO_PAUSE), | 47 | SNDRV_PCM_INFO_PAUSE), |
44 | .formats = KIRKWOOD_FORMATS, | 48 | .formats = KIRKWOOD_FORMATS, |
45 | .rates = KIRKWOOD_RATES, | 49 | .rates = KIRKWOOD_RATES, |
46 | .rate_min = 44100, | 50 | .rate_min = 8000, |
47 | .rate_max = 96000, | 51 | .rate_max = 384000, |
48 | .channels_min = 1, | 52 | .channels_min = 1, |
49 | .channels_max = 2, | 53 | .channels_max = 8, |
50 | .buffer_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS, | 54 | .buffer_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS, |
51 | .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES, | 55 | .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES, |
52 | .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES, | 56 | .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES, |
@@ -71,7 +75,6 @@ static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id) | |||
71 | printk(KERN_WARNING "%s: got err interrupt 0x%lx\n", | 75 | printk(KERN_WARNING "%s: got err interrupt 0x%lx\n", |
72 | __func__, cause); | 76 | __func__, cause); |
73 | writel(cause, priv->io + KIRKWOOD_ERR_CAUSE); | 77 | writel(cause, priv->io + KIRKWOOD_ERR_CAUSE); |
74 | return IRQ_HANDLED; | ||
75 | } | 78 | } |
76 | 79 | ||
77 | /* we've enabled only bytes interrupts ... */ | 80 | /* we've enabled only bytes interrupts ... */ |
@@ -178,7 +181,7 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream) | |||
178 | } | 181 | } |
179 | 182 | ||
180 | dram = mv_mbus_dram_info(); | 183 | dram = mv_mbus_dram_info(); |
181 | addr = virt_to_phys(substream->dma_buffer.area); | 184 | addr = substream->dma_buffer.addr; |
182 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 185 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
183 | prdata->play_stream = substream; | 186 | prdata->play_stream = substream; |
184 | kirkwood_dma_conf_mbus_windows(priv->io, | 187 | kirkwood_dma_conf_mbus_windows(priv->io, |
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 542538d10ab7..d3629d5927e9 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c | |||
@@ -95,10 +95,33 @@ static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate) | |||
95 | do { | 95 | do { |
96 | cpu_relax(); | 96 | cpu_relax(); |
97 | value = readl(io + KIRKWOOD_DCO_SPCR_STATUS); | 97 | value = readl(io + KIRKWOOD_DCO_SPCR_STATUS); |
98 | value &= KIRKWOOD_DCO_SPCR_STATUS; | 98 | value &= KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK; |
99 | } while (value == 0); | 99 | } while (value == 0); |
100 | } | 100 | } |
101 | 101 | ||
102 | static void kirkwood_set_rate(struct snd_soc_dai *dai, | ||
103 | struct kirkwood_dma_data *priv, unsigned long rate) | ||
104 | { | ||
105 | uint32_t clks_ctrl; | ||
106 | |||
107 | if (rate == 44100 || rate == 48000 || rate == 96000) { | ||
108 | /* use internal dco for supported rates */ | ||
109 | dev_dbg(dai->dev, "%s: dco set rate = %lu\n", | ||
110 | __func__, rate); | ||
111 | kirkwood_set_dco(priv->io, rate); | ||
112 | |||
113 | clks_ctrl = KIRKWOOD_MCLK_SOURCE_DCO; | ||
114 | } else if (!IS_ERR(priv->extclk)) { | ||
115 | /* use optional external clk for other rates */ | ||
116 | dev_dbg(dai->dev, "%s: extclk set rate = %lu -> %lu\n", | ||
117 | __func__, rate, 256 * rate); | ||
118 | clk_set_rate(priv->extclk, 256 * rate); | ||
119 | |||
120 | clks_ctrl = KIRKWOOD_MCLK_SOURCE_EXTCLK; | ||
121 | } | ||
122 | writel(clks_ctrl, priv->io + KIRKWOOD_CLOCKS_CTRL); | ||
123 | } | ||
124 | |||
102 | static int kirkwood_i2s_startup(struct snd_pcm_substream *substream, | 125 | static int kirkwood_i2s_startup(struct snd_pcm_substream *substream, |
103 | struct snd_soc_dai *dai) | 126 | struct snd_soc_dai *dai) |
104 | { | 127 | { |
@@ -113,26 +136,21 @@ static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream, | |||
113 | struct snd_soc_dai *dai) | 136 | struct snd_soc_dai *dai) |
114 | { | 137 | { |
115 | struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); | 138 | struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); |
116 | unsigned int i2s_reg, reg; | 139 | uint32_t ctl_play, ctl_rec; |
117 | unsigned long i2s_value, value; | 140 | unsigned int i2s_reg; |
141 | unsigned long i2s_value; | ||
118 | 142 | ||
119 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 143 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
120 | i2s_reg = KIRKWOOD_I2S_PLAYCTL; | 144 | i2s_reg = KIRKWOOD_I2S_PLAYCTL; |
121 | reg = KIRKWOOD_PLAYCTL; | ||
122 | } else { | 145 | } else { |
123 | i2s_reg = KIRKWOOD_I2S_RECCTL; | 146 | i2s_reg = KIRKWOOD_I2S_RECCTL; |
124 | reg = KIRKWOOD_RECCTL; | ||
125 | } | 147 | } |
126 | 148 | ||
127 | /* set dco conf */ | 149 | kirkwood_set_rate(dai, priv, params_rate(params)); |
128 | kirkwood_set_dco(priv->io, params_rate(params)); | ||
129 | 150 | ||
130 | i2s_value = readl(priv->io+i2s_reg); | 151 | i2s_value = readl(priv->io+i2s_reg); |
131 | i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK; | 152 | i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK; |
132 | 153 | ||
133 | value = readl(priv->io+reg); | ||
134 | value &= ~KIRKWOOD_PLAYCTL_SIZE_MASK; | ||
135 | |||
136 | /* | 154 | /* |
137 | * Size settings in play/rec i2s control regs and play/rec control | 155 | * Size settings in play/rec i2s control regs and play/rec control |
138 | * regs must be the same. | 156 | * regs must be the same. |
@@ -140,38 +158,57 @@ static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream, | |||
140 | switch (params_format(params)) { | 158 | switch (params_format(params)) { |
141 | case SNDRV_PCM_FORMAT_S16_LE: | 159 | case SNDRV_PCM_FORMAT_S16_LE: |
142 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16; | 160 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16; |
143 | value |= KIRKWOOD_PLAYCTL_SIZE_16_C; | 161 | ctl_play = KIRKWOOD_PLAYCTL_SIZE_16_C | |
162 | KIRKWOOD_PLAYCTL_I2S_EN; | ||
163 | ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C | | ||
164 | KIRKWOOD_RECCTL_I2S_EN; | ||
144 | break; | 165 | break; |
145 | /* | 166 | /* |
146 | * doesn't work... S20_3LE != kirkwood 20bit format ? | 167 | * doesn't work... S20_3LE != kirkwood 20bit format ? |
147 | * | 168 | * |
148 | case SNDRV_PCM_FORMAT_S20_3LE: | 169 | case SNDRV_PCM_FORMAT_S20_3LE: |
149 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20; | 170 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20; |
150 | value |= KIRKWOOD_PLAYCTL_SIZE_20; | 171 | ctl_play = KIRKWOOD_PLAYCTL_SIZE_20 | |
172 | KIRKWOOD_PLAYCTL_I2S_EN; | ||
173 | ctl_rec = KIRKWOOD_RECCTL_SIZE_20 | | ||
174 | KIRKWOOD_RECCTL_I2S_EN; | ||
151 | break; | 175 | break; |
152 | */ | 176 | */ |
153 | case SNDRV_PCM_FORMAT_S24_LE: | 177 | case SNDRV_PCM_FORMAT_S24_LE: |
154 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24; | 178 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24; |
155 | value |= KIRKWOOD_PLAYCTL_SIZE_24; | 179 | ctl_play = KIRKWOOD_PLAYCTL_SIZE_24 | |
180 | KIRKWOOD_PLAYCTL_I2S_EN; | ||
181 | ctl_rec = KIRKWOOD_RECCTL_SIZE_24 | | ||
182 | KIRKWOOD_RECCTL_I2S_EN; | ||
156 | break; | 183 | break; |
157 | case SNDRV_PCM_FORMAT_S32_LE: | 184 | case SNDRV_PCM_FORMAT_S32_LE: |
158 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32; | 185 | i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32; |
159 | value |= KIRKWOOD_PLAYCTL_SIZE_32; | 186 | ctl_play = KIRKWOOD_PLAYCTL_SIZE_32 | |
187 | KIRKWOOD_PLAYCTL_I2S_EN; | ||
188 | ctl_rec = KIRKWOOD_RECCTL_SIZE_32 | | ||
189 | KIRKWOOD_RECCTL_I2S_EN; | ||
160 | break; | 190 | break; |
161 | default: | 191 | default: |
162 | return -EINVAL; | 192 | return -EINVAL; |
163 | } | 193 | } |
164 | 194 | ||
165 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 195 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
166 | value &= ~KIRKWOOD_PLAYCTL_MONO_MASK; | ||
167 | if (params_channels(params) == 1) | 196 | if (params_channels(params) == 1) |
168 | value |= KIRKWOOD_PLAYCTL_MONO_BOTH; | 197 | ctl_play |= KIRKWOOD_PLAYCTL_MONO_BOTH; |
169 | else | 198 | else |
170 | value |= KIRKWOOD_PLAYCTL_MONO_OFF; | 199 | ctl_play |= KIRKWOOD_PLAYCTL_MONO_OFF; |
200 | |||
201 | priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK | | ||
202 | KIRKWOOD_PLAYCTL_I2S_EN | | ||
203 | KIRKWOOD_PLAYCTL_SPDIF_EN | | ||
204 | KIRKWOOD_PLAYCTL_SIZE_MASK); | ||
205 | priv->ctl_play |= ctl_play; | ||
206 | } else { | ||
207 | priv->ctl_rec &= ~KIRKWOOD_RECCTL_SIZE_MASK; | ||
208 | priv->ctl_rec |= ctl_rec; | ||
171 | } | 209 | } |
172 | 210 | ||
173 | writel(i2s_value, priv->io+i2s_reg); | 211 | writel(i2s_value, priv->io+i2s_reg); |
174 | writel(value, priv->io+reg); | ||
175 | 212 | ||
176 | return 0; | 213 | return 0; |
177 | } | 214 | } |
@@ -180,67 +217,70 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, | |||
180 | int cmd, struct snd_soc_dai *dai) | 217 | int cmd, struct snd_soc_dai *dai) |
181 | { | 218 | { |
182 | struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); | 219 | struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); |
183 | unsigned long value; | 220 | uint32_t ctl, value; |
184 | 221 | ||
185 | /* | 222 | ctl = readl(priv->io + KIRKWOOD_PLAYCTL); |
186 | * specs says KIRKWOOD_PLAYCTL must be read 2 times before | 223 | if (ctl & KIRKWOOD_PLAYCTL_PAUSE) { |
187 | * changing it. So read 1 time here and 1 later. | 224 | unsigned timeout = 5000; |
188 | */ | 225 | /* |
189 | value = readl(priv->io + KIRKWOOD_PLAYCTL); | 226 | * The Armada510 spec says that if we enter pause mode, the |
227 | * busy bit must be read back as clear _twice_. Make sure | ||
228 | * we respect that otherwise we get DMA underruns. | ||
229 | */ | ||
230 | do { | ||
231 | value = ctl; | ||
232 | ctl = readl(priv->io + KIRKWOOD_PLAYCTL); | ||
233 | if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)) | ||
234 | break; | ||
235 | udelay(1); | ||
236 | } while (timeout--); | ||
237 | |||
238 | if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY) | ||
239 | dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n", | ||
240 | ctl); | ||
241 | } | ||
190 | 242 | ||
191 | switch (cmd) { | 243 | switch (cmd) { |
192 | case SNDRV_PCM_TRIGGER_START: | 244 | case SNDRV_PCM_TRIGGER_START: |
193 | /* stop audio, enable interrupts */ | 245 | /* configure */ |
194 | value = readl(priv->io + KIRKWOOD_PLAYCTL); | 246 | ctl = priv->ctl_play; |
195 | value |= KIRKWOOD_PLAYCTL_PAUSE; | 247 | value = ctl & ~(KIRKWOOD_PLAYCTL_I2S_EN | |
248 | KIRKWOOD_PLAYCTL_SPDIF_EN); | ||
196 | writel(value, priv->io + KIRKWOOD_PLAYCTL); | 249 | writel(value, priv->io + KIRKWOOD_PLAYCTL); |
197 | 250 | ||
251 | /* enable interrupts */ | ||
198 | value = readl(priv->io + KIRKWOOD_INT_MASK); | 252 | value = readl(priv->io + KIRKWOOD_INT_MASK); |
199 | value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; | 253 | value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; |
200 | writel(value, priv->io + KIRKWOOD_INT_MASK); | 254 | writel(value, priv->io + KIRKWOOD_INT_MASK); |
201 | 255 | ||
202 | /* configure audio & enable i2s playback */ | 256 | /* enable playback */ |
203 | value = readl(priv->io + KIRKWOOD_PLAYCTL); | 257 | writel(ctl, priv->io + KIRKWOOD_PLAYCTL); |
204 | value &= ~KIRKWOOD_PLAYCTL_BURST_MASK; | ||
205 | value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE | ||
206 | | KIRKWOOD_PLAYCTL_SPDIF_EN); | ||
207 | |||
208 | if (priv->burst == 32) | ||
209 | value |= KIRKWOOD_PLAYCTL_BURST_32; | ||
210 | else | ||
211 | value |= KIRKWOOD_PLAYCTL_BURST_128; | ||
212 | value |= KIRKWOOD_PLAYCTL_I2S_EN; | ||
213 | writel(value, priv->io + KIRKWOOD_PLAYCTL); | ||
214 | break; | 258 | break; |
215 | 259 | ||
216 | case SNDRV_PCM_TRIGGER_STOP: | 260 | case SNDRV_PCM_TRIGGER_STOP: |
217 | /* stop audio, disable interrupts */ | 261 | /* stop audio, disable interrupts */ |
218 | value = readl(priv->io + KIRKWOOD_PLAYCTL); | 262 | ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; |
219 | value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; | 263 | writel(ctl, priv->io + KIRKWOOD_PLAYCTL); |
220 | writel(value, priv->io + KIRKWOOD_PLAYCTL); | ||
221 | 264 | ||
222 | value = readl(priv->io + KIRKWOOD_INT_MASK); | 265 | value = readl(priv->io + KIRKWOOD_INT_MASK); |
223 | value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES; | 266 | value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES; |
224 | writel(value, priv->io + KIRKWOOD_INT_MASK); | 267 | writel(value, priv->io + KIRKWOOD_INT_MASK); |
225 | 268 | ||
226 | /* disable all playbacks */ | 269 | /* disable all playbacks */ |
227 | value = readl(priv->io + KIRKWOOD_PLAYCTL); | 270 | ctl &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN); |
228 | value &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN); | 271 | writel(ctl, priv->io + KIRKWOOD_PLAYCTL); |
229 | writel(value, priv->io + KIRKWOOD_PLAYCTL); | ||
230 | break; | 272 | break; |
231 | 273 | ||
232 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 274 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
233 | case SNDRV_PCM_TRIGGER_SUSPEND: | 275 | case SNDRV_PCM_TRIGGER_SUSPEND: |
234 | value = readl(priv->io + KIRKWOOD_PLAYCTL); | 276 | ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; |
235 | value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; | 277 | writel(ctl, priv->io + KIRKWOOD_PLAYCTL); |
236 | writel(value, priv->io + KIRKWOOD_PLAYCTL); | ||
237 | break; | 278 | break; |
238 | 279 | ||
239 | case SNDRV_PCM_TRIGGER_RESUME: | 280 | case SNDRV_PCM_TRIGGER_RESUME: |
240 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 281 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
241 | value = readl(priv->io + KIRKWOOD_PLAYCTL); | 282 | ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE); |
242 | value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE); | 283 | writel(ctl, priv->io + KIRKWOOD_PLAYCTL); |
243 | writel(value, priv->io + KIRKWOOD_PLAYCTL); | ||
244 | break; | 284 | break; |
245 | 285 | ||
246 | default: | 286 | default: |
@@ -254,35 +294,24 @@ static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream, | |||
254 | int cmd, struct snd_soc_dai *dai) | 294 | int cmd, struct snd_soc_dai *dai) |
255 | { | 295 | { |
256 | struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); | 296 | struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); |
257 | unsigned long value; | 297 | uint32_t ctl, value; |
258 | 298 | ||
259 | value = readl(priv->io + KIRKWOOD_RECCTL); | 299 | value = readl(priv->io + KIRKWOOD_RECCTL); |
260 | 300 | ||
261 | switch (cmd) { | 301 | switch (cmd) { |
262 | case SNDRV_PCM_TRIGGER_START: | 302 | case SNDRV_PCM_TRIGGER_START: |
263 | /* stop audio, enable interrupts */ | 303 | /* configure */ |
264 | value = readl(priv->io + KIRKWOOD_RECCTL); | 304 | ctl = priv->ctl_rec; |
265 | value |= KIRKWOOD_RECCTL_PAUSE; | 305 | value = ctl & ~KIRKWOOD_RECCTL_I2S_EN; |
266 | writel(value, priv->io + KIRKWOOD_RECCTL); | 306 | writel(value, priv->io + KIRKWOOD_RECCTL); |
267 | 307 | ||
308 | /* enable interrupts */ | ||
268 | value = readl(priv->io + KIRKWOOD_INT_MASK); | 309 | value = readl(priv->io + KIRKWOOD_INT_MASK); |
269 | value |= KIRKWOOD_INT_CAUSE_REC_BYTES; | 310 | value |= KIRKWOOD_INT_CAUSE_REC_BYTES; |
270 | writel(value, priv->io + KIRKWOOD_INT_MASK); | 311 | writel(value, priv->io + KIRKWOOD_INT_MASK); |
271 | 312 | ||
272 | /* configure audio & enable i2s record */ | 313 | /* enable record */ |
273 | value = readl(priv->io + KIRKWOOD_RECCTL); | 314 | writel(ctl, priv->io + KIRKWOOD_RECCTL); |
274 | value &= ~KIRKWOOD_RECCTL_BURST_MASK; | ||
275 | value &= ~KIRKWOOD_RECCTL_MONO; | ||
276 | value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE | ||
277 | | KIRKWOOD_RECCTL_SPDIF_EN); | ||
278 | |||
279 | if (priv->burst == 32) | ||
280 | value |= KIRKWOOD_RECCTL_BURST_32; | ||
281 | else | ||
282 | value |= KIRKWOOD_RECCTL_BURST_128; | ||
283 | value |= KIRKWOOD_RECCTL_I2S_EN; | ||
284 | |||
285 | writel(value, priv->io + KIRKWOOD_RECCTL); | ||
286 | break; | 315 | break; |
287 | 316 | ||
288 | case SNDRV_PCM_TRIGGER_STOP: | 317 | case SNDRV_PCM_TRIGGER_STOP: |
@@ -389,90 +418,125 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai = { | |||
389 | .channels_min = 1, | 418 | .channels_min = 1, |
390 | .channels_max = 2, | 419 | .channels_max = 2, |
391 | .rates = KIRKWOOD_I2S_RATES, | 420 | .rates = KIRKWOOD_I2S_RATES, |
392 | .formats = KIRKWOOD_I2S_FORMATS,}, | 421 | .formats = KIRKWOOD_I2S_FORMATS, |
422 | }, | ||
393 | .capture = { | 423 | .capture = { |
394 | .channels_min = 1, | 424 | .channels_min = 1, |
395 | .channels_max = 2, | 425 | .channels_max = 2, |
396 | .rates = KIRKWOOD_I2S_RATES, | 426 | .rates = KIRKWOOD_I2S_RATES, |
397 | .formats = KIRKWOOD_I2S_FORMATS,}, | 427 | .formats = KIRKWOOD_I2S_FORMATS, |
428 | }, | ||
429 | .ops = &kirkwood_i2s_dai_ops, | ||
430 | }; | ||
431 | |||
432 | static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = { | ||
433 | .probe = kirkwood_i2s_probe, | ||
434 | .remove = kirkwood_i2s_remove, | ||
435 | .playback = { | ||
436 | .channels_min = 1, | ||
437 | .channels_max = 2, | ||
438 | .rates = SNDRV_PCM_RATE_8000_192000 | | ||
439 | SNDRV_PCM_RATE_CONTINUOUS | | ||
440 | SNDRV_PCM_RATE_KNOT, | ||
441 | .formats = KIRKWOOD_I2S_FORMATS, | ||
442 | }, | ||
443 | .capture = { | ||
444 | .channels_min = 1, | ||
445 | .channels_max = 2, | ||
446 | .rates = SNDRV_PCM_RATE_8000_192000 | | ||
447 | SNDRV_PCM_RATE_CONTINUOUS | | ||
448 | SNDRV_PCM_RATE_KNOT, | ||
449 | .formats = KIRKWOOD_I2S_FORMATS, | ||
450 | }, | ||
398 | .ops = &kirkwood_i2s_dai_ops, | 451 | .ops = &kirkwood_i2s_dai_ops, |
399 | }; | 452 | }; |
400 | 453 | ||
401 | static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev) | 454 | static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev) |
402 | { | 455 | { |
403 | struct resource *mem; | 456 | struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; |
404 | struct kirkwood_asoc_platform_data *data = | 457 | struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai; |
405 | pdev->dev.platform_data; | ||
406 | struct kirkwood_dma_data *priv; | 458 | struct kirkwood_dma_data *priv; |
459 | struct resource *mem; | ||
407 | int err; | 460 | int err; |
408 | 461 | ||
409 | priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL); | 462 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
410 | if (!priv) { | 463 | if (!priv) { |
411 | dev_err(&pdev->dev, "allocation failed\n"); | 464 | dev_err(&pdev->dev, "allocation failed\n"); |
412 | err = -ENOMEM; | 465 | return -ENOMEM; |
413 | goto error; | ||
414 | } | 466 | } |
415 | dev_set_drvdata(&pdev->dev, priv); | 467 | dev_set_drvdata(&pdev->dev, priv); |
416 | 468 | ||
417 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 469 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
418 | if (!mem) { | 470 | if (!mem) { |
419 | dev_err(&pdev->dev, "platform_get_resource failed\n"); | 471 | dev_err(&pdev->dev, "platform_get_resource failed\n"); |
420 | err = -ENXIO; | 472 | return -ENXIO; |
421 | goto err_alloc; | ||
422 | } | ||
423 | |||
424 | priv->mem = request_mem_region(mem->start, SZ_16K, DRV_NAME); | ||
425 | if (!priv->mem) { | ||
426 | dev_err(&pdev->dev, "request_mem_region failed\n"); | ||
427 | err = -EBUSY; | ||
428 | goto err_alloc; | ||
429 | } | 473 | } |
430 | 474 | ||
431 | priv->io = ioremap(priv->mem->start, SZ_16K); | 475 | priv->io = devm_request_and_ioremap(&pdev->dev, mem); |
432 | if (!priv->io) { | 476 | if (!priv->io) { |
433 | dev_err(&pdev->dev, "ioremap failed\n"); | 477 | dev_err(&pdev->dev, "devm_request_and_ioremap failed\n"); |
434 | err = -ENOMEM; | 478 | return -ENOMEM; |
435 | goto err_iomem; | ||
436 | } | 479 | } |
437 | 480 | ||
438 | priv->irq = platform_get_irq(pdev, 0); | 481 | priv->irq = platform_get_irq(pdev, 0); |
439 | if (priv->irq <= 0) { | 482 | if (priv->irq <= 0) { |
440 | dev_err(&pdev->dev, "platform_get_irq failed\n"); | 483 | dev_err(&pdev->dev, "platform_get_irq failed\n"); |
441 | err = -ENXIO; | 484 | return -ENXIO; |
442 | goto err_ioremap; | ||
443 | } | 485 | } |
444 | 486 | ||
445 | if (!data) { | 487 | if (!data) { |
446 | dev_err(&pdev->dev, "no platform data ?!\n"); | 488 | dev_err(&pdev->dev, "no platform data ?!\n"); |
447 | err = -EINVAL; | 489 | return -EINVAL; |
448 | goto err_ioremap; | ||
449 | } | 490 | } |
450 | 491 | ||
451 | priv->burst = data->burst; | 492 | priv->burst = data->burst; |
452 | 493 | ||
453 | priv->clk = clk_get(&pdev->dev, NULL); | 494 | priv->clk = devm_clk_get(&pdev->dev, NULL); |
454 | if (IS_ERR(priv->clk)) { | 495 | if (IS_ERR(priv->clk)) { |
455 | dev_err(&pdev->dev, "no clock\n"); | 496 | dev_err(&pdev->dev, "no clock\n"); |
456 | err = PTR_ERR(priv->clk); | 497 | return PTR_ERR(priv->clk); |
457 | goto err_ioremap; | 498 | } |
499 | |||
500 | err = clk_prepare_enable(priv->clk); | ||
501 | if (err < 0) | ||
502 | return err; | ||
503 | |||
504 | priv->extclk = clk_get(&pdev->dev, "extclk"); | ||
505 | if (!IS_ERR(priv->extclk)) { | ||
506 | if (priv->extclk == priv->clk) { | ||
507 | clk_put(priv->extclk); | ||
508 | priv->extclk = ERR_PTR(-EINVAL); | ||
509 | } else { | ||
510 | dev_info(&pdev->dev, "found external clock\n"); | ||
511 | clk_prepare_enable(priv->extclk); | ||
512 | soc_dai = &kirkwood_i2s_dai_extclk; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | /* Some sensible defaults - this reflects the powerup values */ | ||
517 | priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24; | ||
518 | priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24; | ||
519 | |||
520 | /* Select the burst size */ | ||
521 | if (data->burst == 32) { | ||
522 | priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32; | ||
523 | priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32; | ||
524 | } else { | ||
525 | priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128; | ||
526 | priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; | ||
458 | } | 527 | } |
459 | clk_prepare_enable(priv->clk); | ||
460 | 528 | ||
461 | err = snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai); | 529 | err = snd_soc_register_dai(&pdev->dev, soc_dai); |
462 | if (!err) | 530 | if (!err) |
463 | return 0; | 531 | return 0; |
464 | dev_err(&pdev->dev, "snd_soc_register_dai failed\n"); | 532 | dev_err(&pdev->dev, "snd_soc_register_dai failed\n"); |
465 | 533 | ||
534 | if (!IS_ERR(priv->extclk)) { | ||
535 | clk_disable_unprepare(priv->extclk); | ||
536 | clk_put(priv->extclk); | ||
537 | } | ||
466 | clk_disable_unprepare(priv->clk); | 538 | clk_disable_unprepare(priv->clk); |
467 | clk_put(priv->clk); | 539 | |
468 | |||
469 | err_ioremap: | ||
470 | iounmap(priv->io); | ||
471 | err_iomem: | ||
472 | release_mem_region(priv->mem->start, SZ_16K); | ||
473 | err_alloc: | ||
474 | kfree(priv); | ||
475 | error: | ||
476 | return err; | 540 | return err; |
477 | } | 541 | } |
478 | 542 | ||
@@ -482,12 +546,11 @@ static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev) | |||
482 | 546 | ||
483 | snd_soc_unregister_dai(&pdev->dev); | 547 | snd_soc_unregister_dai(&pdev->dev); |
484 | 548 | ||
549 | if (!IS_ERR(priv->extclk)) { | ||
550 | clk_disable_unprepare(priv->extclk); | ||
551 | clk_put(priv->extclk); | ||
552 | } | ||
485 | clk_disable_unprepare(priv->clk); | 553 | clk_disable_unprepare(priv->clk); |
486 | clk_put(priv->clk); | ||
487 | |||
488 | iounmap(priv->io); | ||
489 | release_mem_region(priv->mem->start, SZ_16K); | ||
490 | kfree(priv); | ||
491 | 554 | ||
492 | return 0; | 555 | return 0; |
493 | } | 556 | } |
diff --git a/sound/soc/kirkwood/kirkwood.h b/sound/soc/kirkwood/kirkwood.h index f9084d83e6bd..4d92637ddb3f 100644 --- a/sound/soc/kirkwood/kirkwood.h +++ b/sound/soc/kirkwood/kirkwood.h | |||
@@ -77,6 +77,11 @@ | |||
77 | #define KIRKWOOD_DCO_SPCR_STATUS 0x120c | 77 | #define KIRKWOOD_DCO_SPCR_STATUS 0x120c |
78 | #define KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK (1<<16) | 78 | #define KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK (1<<16) |
79 | 79 | ||
80 | #define KIRKWOOD_CLOCKS_CTRL 0x1230 | ||
81 | #define KIRKWOOD_MCLK_SOURCE_MASK (3<<0) | ||
82 | #define KIRKWOOD_MCLK_SOURCE_DCO (0<<0) | ||
83 | #define KIRKWOOD_MCLK_SOURCE_EXTCLK (3<<0) | ||
84 | |||
80 | #define KIRKWOOD_ERR_CAUSE 0x1300 | 85 | #define KIRKWOOD_ERR_CAUSE 0x1300 |
81 | #define KIRKWOOD_ERR_MASK 0x1304 | 86 | #define KIRKWOOD_ERR_MASK 0x1304 |
82 | 87 | ||
@@ -119,11 +124,13 @@ | |||
119 | #define KIRKWOOD_SND_MAX_PERIOD_BYTES 0x4000 | 124 | #define KIRKWOOD_SND_MAX_PERIOD_BYTES 0x4000 |
120 | 125 | ||
121 | struct kirkwood_dma_data { | 126 | struct kirkwood_dma_data { |
122 | struct resource *mem; | ||
123 | void __iomem *io; | 127 | void __iomem *io; |
128 | struct clk *clk; | ||
129 | struct clk *extclk; | ||
130 | uint32_t ctl_play; | ||
131 | uint32_t ctl_rec; | ||
124 | int irq; | 132 | int irq; |
125 | int burst; | 133 | int burst; |
126 | struct clk *clk; | ||
127 | }; | 134 | }; |
128 | 135 | ||
129 | #endif | 136 | #endif |
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index c294fbb523fc..b304e375568a 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c | |||
@@ -229,6 +229,7 @@ int mxs_saif_put_mclk(unsigned int saif_id) | |||
229 | saif->mclk_in_use = 0; | 229 | saif->mclk_in_use = 0; |
230 | return 0; | 230 | return 0; |
231 | } | 231 | } |
232 | EXPORT_SYMBOL_GPL(mxs_saif_put_mclk); | ||
232 | 233 | ||
233 | /* | 234 | /* |
234 | * Get MCLK and set clock rate, then enable it | 235 | * Get MCLK and set clock rate, then enable it |
@@ -282,6 +283,7 @@ int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk, | |||
282 | 283 | ||
283 | return 0; | 284 | return 0; |
284 | } | 285 | } |
286 | EXPORT_SYMBOL_GPL(mxs_saif_get_mclk); | ||
285 | 287 | ||
286 | /* | 288 | /* |
287 | * SAIF DAI format configuration. | 289 | * SAIF DAI format configuration. |
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index afb8d4f1bedf..a9a243860428 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c | |||
@@ -28,8 +28,6 @@ | |||
28 | 28 | ||
29 | #include <linux/platform_data/asoc-ti-mcbsp.h> | 29 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
30 | 30 | ||
31 | #include <plat/cpu.h> | ||
32 | |||
33 | #include "mcbsp.h" | 31 | #include "mcbsp.h" |
34 | 32 | ||
35 | static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val) | 33 | static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val) |
@@ -612,7 +610,7 @@ void omap_mcbsp_free(struct omap_mcbsp *mcbsp) | |||
612 | * system will refuse to enter idle if the CLKS pin source is not reset | 610 | * system will refuse to enter idle if the CLKS pin source is not reset |
613 | * back to internal source. | 611 | * back to internal source. |
614 | */ | 612 | */ |
615 | if (!cpu_class_is_omap1()) | 613 | if (!mcbsp_omap1()) |
616 | omap2_mcbsp_set_clks_src(mcbsp, MCBSP_CLKS_PRCM_SRC); | 614 | omap2_mcbsp_set_clks_src(mcbsp, MCBSP_CLKS_PRCM_SRC); |
617 | 615 | ||
618 | spin_lock(&mcbsp->lock); | 616 | spin_lock(&mcbsp->lock); |
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h index 49a67259ce5a..a89791c239a5 100644 --- a/sound/soc/omap/mcbsp.h +++ b/sound/soc/omap/mcbsp.h | |||
@@ -26,6 +26,12 @@ | |||
26 | 26 | ||
27 | #include "omap-pcm.h" | 27 | #include "omap-pcm.h" |
28 | 28 | ||
29 | #ifdef CONFIG_ARCH_OMAP1 | ||
30 | #define mcbsp_omap1() 1 | ||
31 | #else | ||
32 | #define mcbsp_omap1() 0 | ||
33 | #endif | ||
34 | |||
29 | /* McBSP register numbers. Register address offset = num * reg_step */ | 35 | /* McBSP register numbers. Register address offset = num * reg_step */ |
30 | enum { | 36 | enum { |
31 | /* Common registers */ | 37 | /* Common registers */ |
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index a57a4e68dcc6..1d6ea8609d28 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c | |||
@@ -331,8 +331,8 @@ static __devinit int omap_abe_probe(struct platform_device *pdev) | |||
331 | num_links = 1; | 331 | num_links = 1; |
332 | } | 332 | } |
333 | 333 | ||
334 | of_property_read_u32(node, "ti,jack-detection", | 334 | priv->jack_detection = of_property_read_bool(node, |
335 | &priv->jack_detection); | 335 | "ti,jack-detection"); |
336 | of_property_read_u32(node, "ti,mclk-freq", | 336 | of_property_read_u32(node, "ti,mclk-freq", |
337 | &priv->mclk_freq); | 337 | &priv->mclk_freq); |
338 | if (!priv->mclk_freq) { | 338 | if (!priv->mclk_freq) { |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index a6ee15747859..09167609c93e 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <sound/initval.h> | 34 | #include <sound/initval.h> |
35 | #include <sound/soc.h> | 35 | #include <sound/soc.h> |
36 | 36 | ||
37 | #include <plat/cpu.h> | ||
38 | #include <linux/platform_data/asoc-ti-mcbsp.h> | 37 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
39 | #include "mcbsp.h" | 38 | #include "mcbsp.h" |
40 | #include "omap-mcbsp.h" | 39 | #include "omap-mcbsp.h" |
@@ -512,7 +511,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
512 | regs->srgr2 |= CLKSM; | 511 | regs->srgr2 |= CLKSM; |
513 | break; | 512 | break; |
514 | case OMAP_MCBSP_SYSCLK_CLKS_FCLK: | 513 | case OMAP_MCBSP_SYSCLK_CLKS_FCLK: |
515 | if (cpu_class_is_omap1()) { | 514 | if (mcbsp_omap1()) { |
516 | err = -EINVAL; | 515 | err = -EINVAL; |
517 | break; | 516 | break; |
518 | } | 517 | } |
@@ -520,7 +519,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
520 | MCBSP_CLKS_PRCM_SRC); | 519 | MCBSP_CLKS_PRCM_SRC); |
521 | break; | 520 | break; |
522 | case OMAP_MCBSP_SYSCLK_CLKS_EXT: | 521 | case OMAP_MCBSP_SYSCLK_CLKS_EXT: |
523 | if (cpu_class_is_omap1()) { | 522 | if (mcbsp_omap1()) { |
524 | err = 0; | 523 | err = 0; |
525 | break; | 524 | break; |
526 | } | 525 | } |
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c index 1ff6bb9ade5c..771bff27ac3e 100644 --- a/sound/soc/omap/zoom2.c +++ b/sound/soc/omap/zoom2.c | |||
@@ -37,8 +37,6 @@ | |||
37 | #include "omap-mcbsp.h" | 37 | #include "omap-mcbsp.h" |
38 | #include "omap-pcm.h" | 38 | #include "omap-pcm.h" |
39 | 39 | ||
40 | #define ZOOM2_HEADSET_MUX_GPIO (OMAP_MAX_GPIO_LINES + 15) | ||
41 | |||
42 | static int zoom2_hw_params(struct snd_pcm_substream *substream, | 40 | static int zoom2_hw_params(struct snd_pcm_substream *substream, |
43 | struct snd_pcm_hw_params *params) | 41 | struct snd_pcm_hw_params *params) |
44 | { | 42 | { |
@@ -187,9 +185,6 @@ static int __init zoom2_soc_init(void) | |||
187 | if (ret) | 185 | if (ret) |
188 | goto err1; | 186 | goto err1; |
189 | 187 | ||
190 | BUG_ON(gpio_request(ZOOM2_HEADSET_MUX_GPIO, "hs_mux") < 0); | ||
191 | gpio_direction_output(ZOOM2_HEADSET_MUX_GPIO, 0); | ||
192 | |||
193 | return 0; | 188 | return 0; |
194 | 189 | ||
195 | err1: | 190 | err1: |
@@ -202,8 +197,6 @@ module_init(zoom2_soc_init); | |||
202 | 197 | ||
203 | static void __exit zoom2_soc_exit(void) | 198 | static void __exit zoom2_soc_exit(void) |
204 | { | 199 | { |
205 | gpio_free(ZOOM2_HEADSET_MUX_GPIO); | ||
206 | |||
207 | platform_device_unregister(zoom2_snd_device); | 200 | platform_device_unregister(zoom2_snd_device); |
208 | } | 201 | } |
209 | module_exit(zoom2_soc_exit); | 202 | module_exit(zoom2_soc_exit); |
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 14fbcd30cae5..cd6c7073c50d 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c | |||
@@ -442,7 +442,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev) | |||
442 | ret = -ENODEV; | 442 | ret = -ENODEV; |
443 | goto err2; | 443 | goto err2; |
444 | } | 444 | } |
445 | clk_enable(s3c_ac97.ac97_clk); | 445 | clk_prepare_enable(s3c_ac97.ac97_clk); |
446 | 446 | ||
447 | if (ac97_pdata->cfg_gpio(pdev)) { | 447 | if (ac97_pdata->cfg_gpio(pdev)) { |
448 | dev_err(&pdev->dev, "Unable to configure gpio\n"); | 448 | dev_err(&pdev->dev, "Unable to configure gpio\n"); |
@@ -462,13 +462,20 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev) | |||
462 | if (ret) | 462 | if (ret) |
463 | goto err5; | 463 | goto err5; |
464 | 464 | ||
465 | return 0; | 465 | ret = asoc_dma_platform_register(&pdev->dev); |
466 | if (ret) { | ||
467 | dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); | ||
468 | goto err6; | ||
469 | } | ||
466 | 470 | ||
471 | return 0; | ||
472 | err6: | ||
473 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); | ||
467 | err5: | 474 | err5: |
468 | free_irq(irq_res->start, NULL); | 475 | free_irq(irq_res->start, NULL); |
469 | err4: | 476 | err4: |
470 | err3: | 477 | err3: |
471 | clk_disable(s3c_ac97.ac97_clk); | 478 | clk_disable_unprepare(s3c_ac97.ac97_clk); |
472 | clk_put(s3c_ac97.ac97_clk); | 479 | clk_put(s3c_ac97.ac97_clk); |
473 | err2: | 480 | err2: |
474 | iounmap(s3c_ac97.regs); | 481 | iounmap(s3c_ac97.regs); |
@@ -482,13 +489,14 @@ static __devexit int s3c_ac97_remove(struct platform_device *pdev) | |||
482 | { | 489 | { |
483 | struct resource *mem_res, *irq_res; | 490 | struct resource *mem_res, *irq_res; |
484 | 491 | ||
492 | asoc_dma_platform_unregister(&pdev->dev); | ||
485 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); | 493 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); |
486 | 494 | ||
487 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 495 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
488 | if (irq_res) | 496 | if (irq_res) |
489 | free_irq(irq_res->start, NULL); | 497 | free_irq(irq_res->start, NULL); |
490 | 498 | ||
491 | clk_disable(s3c_ac97.ac97_clk); | 499 | clk_disable_unprepare(s3c_ac97.ac97_clk); |
492 | clk_put(s3c_ac97.ac97_clk); | 500 | clk_put(s3c_ac97.ac97_clk); |
493 | 501 | ||
494 | iounmap(s3c_ac97.regs); | 502 | iounmap(s3c_ac97.regs); |
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index b56b9a3c6169..01c1c5a2d321 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c | |||
@@ -18,15 +18,6 @@ | |||
18 | #include "../codecs/wm5102.h" | 18 | #include "../codecs/wm5102.h" |
19 | #include "../codecs/wm9081.h" | 19 | #include "../codecs/wm9081.h" |
20 | 20 | ||
21 | /* | ||
22 | * 44.1kHz based clocks for the SYSCLK domain, use a very high clock | ||
23 | * to allow all the DSP functionality to be enabled if desired. | ||
24 | */ | ||
25 | #define SYSCLK_RATE (44100 * 1024) | ||
26 | |||
27 | /* 48kHz based clocks for the ASYNC domain */ | ||
28 | #define ASYNCCLK_RATE (48000 * 512) | ||
29 | |||
30 | /* BCLK2 is fixed at this currently */ | 21 | /* BCLK2 is fixed at this currently */ |
31 | #define BCLK2_RATE (64 * 8000) | 22 | #define BCLK2_RATE (64 * 8000) |
32 | 23 | ||
@@ -36,15 +27,40 @@ | |||
36 | */ | 27 | */ |
37 | #define MCLK_RATE 24576000 | 28 | #define MCLK_RATE 24576000 |
38 | 29 | ||
39 | #define WM9081_AUDIO_RATE 44100 | 30 | #define SYS_AUDIO_RATE 44100 |
40 | #define WM9081_MCLK_RATE (WM9081_AUDIO_RATE * 256) | 31 | #define SYS_MCLK_RATE (SYS_AUDIO_RATE * 512) |
32 | |||
33 | #define DAI_AP_DSP 0 | ||
34 | #define DAI_DSP_CODEC 1 | ||
35 | #define DAI_CODEC_CP 2 | ||
36 | #define DAI_CODEC_SUB 3 | ||
37 | |||
38 | struct bells_drvdata { | ||
39 | int sysclk_rate; | ||
40 | int asyncclk_rate; | ||
41 | }; | ||
42 | |||
43 | static struct bells_drvdata wm2200_drvdata = { | ||
44 | .sysclk_rate = 22579200, | ||
45 | }; | ||
46 | |||
47 | static struct bells_drvdata wm5102_drvdata = { | ||
48 | .sysclk_rate = 45158400, | ||
49 | .asyncclk_rate = 49152000, | ||
50 | }; | ||
51 | |||
52 | static struct bells_drvdata wm5110_drvdata = { | ||
53 | .sysclk_rate = 135475200, | ||
54 | .asyncclk_rate = 147456000, | ||
55 | }; | ||
41 | 56 | ||
42 | static int bells_set_bias_level(struct snd_soc_card *card, | 57 | static int bells_set_bias_level(struct snd_soc_card *card, |
43 | struct snd_soc_dapm_context *dapm, | 58 | struct snd_soc_dapm_context *dapm, |
44 | enum snd_soc_bias_level level) | 59 | enum snd_soc_bias_level level) |
45 | { | 60 | { |
46 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 61 | struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai; |
47 | struct snd_soc_codec *codec = codec_dai->codec; | 62 | struct snd_soc_codec *codec = codec_dai->codec; |
63 | struct bells_drvdata *bells = card->drvdata; | ||
48 | int ret; | 64 | int ret; |
49 | 65 | ||
50 | if (dapm->dev != codec_dai->dev) | 66 | if (dapm->dev != codec_dai->dev) |
@@ -52,18 +68,21 @@ static int bells_set_bias_level(struct snd_soc_card *card, | |||
52 | 68 | ||
53 | switch (level) { | 69 | switch (level) { |
54 | case SND_SOC_BIAS_PREPARE: | 70 | case SND_SOC_BIAS_PREPARE: |
55 | if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { | 71 | if (dapm->bias_level != SND_SOC_BIAS_STANDBY) |
56 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, | 72 | break; |
57 | ARIZONA_FLL_SRC_MCLK1, | 73 | |
58 | MCLK_RATE, | 74 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, |
59 | SYSCLK_RATE); | 75 | ARIZONA_FLL_SRC_MCLK1, |
60 | if (ret < 0) | 76 | MCLK_RATE, |
61 | pr_err("Failed to start FLL: %d\n", ret); | 77 | bells->sysclk_rate); |
78 | if (ret < 0) | ||
79 | pr_err("Failed to start FLL: %d\n", ret); | ||
62 | 80 | ||
81 | if (bells->asyncclk_rate) { | ||
63 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, | 82 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, |
64 | ARIZONA_FLL_SRC_AIF2BCLK, | 83 | ARIZONA_FLL_SRC_AIF2BCLK, |
65 | BCLK2_RATE, | 84 | BCLK2_RATE, |
66 | ASYNCCLK_RATE); | 85 | bells->asyncclk_rate); |
67 | if (ret < 0) | 86 | if (ret < 0) |
68 | pr_err("Failed to start FLL: %d\n", ret); | 87 | pr_err("Failed to start FLL: %d\n", ret); |
69 | } | 88 | } |
@@ -80,8 +99,9 @@ static int bells_set_bias_level_post(struct snd_soc_card *card, | |||
80 | struct snd_soc_dapm_context *dapm, | 99 | struct snd_soc_dapm_context *dapm, |
81 | enum snd_soc_bias_level level) | 100 | enum snd_soc_bias_level level) |
82 | { | 101 | { |
83 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 102 | struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai; |
84 | struct snd_soc_codec *codec = codec_dai->codec; | 103 | struct snd_soc_codec *codec = codec_dai->codec; |
104 | struct bells_drvdata *bells = card->drvdata; | ||
85 | int ret; | 105 | int ret; |
86 | 106 | ||
87 | if (dapm->dev != codec_dai->dev) | 107 | if (dapm->dev != codec_dai->dev) |
@@ -95,10 +115,13 @@ static int bells_set_bias_level_post(struct snd_soc_card *card, | |||
95 | return ret; | 115 | return ret; |
96 | } | 116 | } |
97 | 117 | ||
98 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, 0, 0, 0); | 118 | if (bells->asyncclk_rate) { |
99 | if (ret < 0) { | 119 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, |
100 | pr_err("Failed to stop FLL: %d\n", ret); | 120 | 0, 0, 0); |
101 | return ret; | 121 | if (ret < 0) { |
122 | pr_err("Failed to stop FLL: %d\n", ret); | ||
123 | return ret; | ||
124 | } | ||
102 | } | 125 | } |
103 | break; | 126 | break; |
104 | 127 | ||
@@ -113,56 +136,73 @@ static int bells_set_bias_level_post(struct snd_soc_card *card, | |||
113 | 136 | ||
114 | static int bells_late_probe(struct snd_soc_card *card) | 137 | static int bells_late_probe(struct snd_soc_card *card) |
115 | { | 138 | { |
116 | struct snd_soc_codec *codec = card->rtd[0].codec; | 139 | struct bells_drvdata *bells = card->drvdata; |
117 | struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai; | 140 | struct snd_soc_codec *wm0010 = card->rtd[DAI_AP_DSP].codec; |
118 | struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai; | 141 | struct snd_soc_codec *codec = card->rtd[DAI_DSP_CODEC].codec; |
119 | struct snd_soc_dai *aif3_dai = card->rtd[2].cpu_dai; | 142 | struct snd_soc_dai *aif1_dai = card->rtd[DAI_DSP_CODEC].codec_dai; |
120 | struct snd_soc_dai *wm9081_dai = card->rtd[2].codec_dai; | 143 | struct snd_soc_dai *aif2_dai; |
144 | struct snd_soc_dai *aif3_dai; | ||
145 | struct snd_soc_dai *wm9081_dai; | ||
121 | int ret; | 146 | int ret; |
122 | 147 | ||
123 | ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0); | 148 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, |
149 | ARIZONA_CLK_SRC_FLL1, | ||
150 | bells->sysclk_rate, | ||
151 | SND_SOC_CLOCK_IN); | ||
124 | if (ret != 0) { | 152 | if (ret != 0) { |
125 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); | 153 | dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); |
126 | return ret; | 154 | return ret; |
127 | } | 155 | } |
128 | 156 | ||
129 | ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); | 157 | ret = snd_soc_codec_set_sysclk(wm0010, 0, 0, SYS_MCLK_RATE, 0); |
130 | if (ret != 0) { | 158 | if (ret != 0) { |
131 | dev_err(aif2_dai->dev, "Failed to set AIF2 clock: %d\n", ret); | 159 | dev_err(wm0010->dev, "Failed to set WM0010 clock: %d\n", ret); |
132 | return ret; | 160 | return ret; |
133 | } | 161 | } |
134 | 162 | ||
135 | ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0); | 163 | ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0); |
136 | if (ret != 0) { | 164 | if (ret != 0) |
137 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); | 165 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); |
138 | return ret; | ||
139 | } | ||
140 | 166 | ||
141 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, | 167 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0, |
142 | ARIZONA_CLK_SRC_FLL1, SYSCLK_RATE, | 168 | SYS_MCLK_RATE, SND_SOC_CLOCK_OUT); |
169 | if (ret != 0) | ||
170 | dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret); | ||
171 | |||
172 | if (card->num_rtd == DAI_CODEC_CP) | ||
173 | return 0; | ||
174 | |||
175 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK, | ||
176 | ARIZONA_CLK_SRC_FLL2, | ||
177 | bells->asyncclk_rate, | ||
143 | SND_SOC_CLOCK_IN); | 178 | SND_SOC_CLOCK_IN); |
144 | if (ret != 0) { | 179 | if (ret != 0) { |
145 | dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); | 180 | dev_err(codec->dev, "Failed to set ASYNCCLK: %d\n", ret); |
146 | return ret; | 181 | return ret; |
147 | } | 182 | } |
148 | 183 | ||
149 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0, | 184 | aif2_dai = card->rtd[DAI_CODEC_CP].cpu_dai; |
150 | WM9081_MCLK_RATE, SND_SOC_CLOCK_OUT); | 185 | |
186 | ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); | ||
151 | if (ret != 0) { | 187 | if (ret != 0) { |
152 | dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret); | 188 | dev_err(aif2_dai->dev, "Failed to set AIF2 clock: %d\n", ret); |
153 | return ret; | 189 | return ret; |
154 | } | 190 | } |
155 | 191 | ||
156 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK, | 192 | if (card->num_rtd == DAI_CODEC_SUB) |
157 | ARIZONA_CLK_SRC_FLL2, ASYNCCLK_RATE, | 193 | return 0; |
158 | SND_SOC_CLOCK_IN); | 194 | |
195 | aif3_dai = card->rtd[DAI_CODEC_SUB].cpu_dai; | ||
196 | wm9081_dai = card->rtd[DAI_CODEC_SUB].codec_dai; | ||
197 | |||
198 | ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0); | ||
159 | if (ret != 0) { | 199 | if (ret != 0) { |
160 | dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); | 200 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); |
161 | return ret; | 201 | return ret; |
162 | } | 202 | } |
163 | 203 | ||
164 | ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK, | 204 | ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK, |
165 | 0, WM9081_MCLK_RATE, 0); | 205 | 0, SYS_MCLK_RATE, 0); |
166 | if (ret != 0) { | 206 | if (ret != 0) { |
167 | dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret); | 207 | dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret); |
168 | return ret; | 208 | return ret; |
@@ -181,22 +221,57 @@ static const struct snd_soc_pcm_stream baseband_params = { | |||
181 | 221 | ||
182 | static const struct snd_soc_pcm_stream sub_params = { | 222 | static const struct snd_soc_pcm_stream sub_params = { |
183 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | 223 | .formats = SNDRV_PCM_FMTBIT_S32_LE, |
184 | .rate_min = WM9081_AUDIO_RATE, | 224 | .rate_min = SYS_AUDIO_RATE, |
185 | .rate_max = WM9081_AUDIO_RATE, | 225 | .rate_max = SYS_AUDIO_RATE, |
186 | .channels_min = 2, | 226 | .channels_min = 2, |
187 | .channels_max = 2, | 227 | .channels_max = 2, |
188 | }; | 228 | }; |
189 | 229 | ||
230 | static struct snd_soc_dai_link bells_dai_wm2200[] = { | ||
231 | { | ||
232 | .name = "CPU-DSP", | ||
233 | .stream_name = "CPU-DSP", | ||
234 | .cpu_dai_name = "samsung-i2s.0", | ||
235 | .codec_dai_name = "wm0010-sdi1", | ||
236 | .platform_name = "samsung-i2s.0", | ||
237 | .codec_name = "spi0.0", | ||
238 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
239 | | SND_SOC_DAIFMT_CBM_CFM, | ||
240 | }, | ||
241 | { | ||
242 | .name = "DSP-CODEC", | ||
243 | .stream_name = "DSP-CODEC", | ||
244 | .cpu_dai_name = "wm0010-sdi2", | ||
245 | .codec_dai_name = "wm2200", | ||
246 | .codec_name = "wm2200.1-003a", | ||
247 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
248 | | SND_SOC_DAIFMT_CBM_CFM, | ||
249 | .params = &sub_params, | ||
250 | .ignore_suspend = 1, | ||
251 | }, | ||
252 | }; | ||
253 | |||
190 | static struct snd_soc_dai_link bells_dai_wm5102[] = { | 254 | static struct snd_soc_dai_link bells_dai_wm5102[] = { |
191 | { | 255 | { |
192 | .name = "CPU", | 256 | .name = "CPU-DSP", |
193 | .stream_name = "CPU", | 257 | .stream_name = "CPU-DSP", |
194 | .cpu_dai_name = "samsung-i2s.0", | 258 | .cpu_dai_name = "samsung-i2s.0", |
259 | .codec_dai_name = "wm0010-sdi1", | ||
260 | .platform_name = "samsung-i2s.0", | ||
261 | .codec_name = "spi0.0", | ||
262 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
263 | | SND_SOC_DAIFMT_CBM_CFM, | ||
264 | }, | ||
265 | { | ||
266 | .name = "DSP-CODEC", | ||
267 | .stream_name = "DSP-CODEC", | ||
268 | .cpu_dai_name = "wm0010-sdi2", | ||
195 | .codec_dai_name = "wm5102-aif1", | 269 | .codec_dai_name = "wm5102-aif1", |
196 | .platform_name = "samsung-audio", | ||
197 | .codec_name = "wm5102-codec", | 270 | .codec_name = "wm5102-codec", |
198 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 271 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
199 | | SND_SOC_DAIFMT_CBM_CFM, | 272 | | SND_SOC_DAIFMT_CBM_CFM, |
273 | .params = &sub_params, | ||
274 | .ignore_suspend = 1, | ||
200 | }, | 275 | }, |
201 | { | 276 | { |
202 | .name = "Baseband", | 277 | .name = "Baseband", |
@@ -212,7 +287,7 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = { | |||
212 | { | 287 | { |
213 | .name = "Sub", | 288 | .name = "Sub", |
214 | .stream_name = "Sub", | 289 | .stream_name = "Sub", |
215 | .cpu_dai_name = "wm5110-aif3", | 290 | .cpu_dai_name = "wm5102-aif3", |
216 | .codec_dai_name = "wm9081-hifi", | 291 | .codec_dai_name = "wm9081-hifi", |
217 | .codec_name = "wm9081.1-006c", | 292 | .codec_name = "wm9081.1-006c", |
218 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 293 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
@@ -224,14 +299,25 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = { | |||
224 | 299 | ||
225 | static struct snd_soc_dai_link bells_dai_wm5110[] = { | 300 | static struct snd_soc_dai_link bells_dai_wm5110[] = { |
226 | { | 301 | { |
227 | .name = "CPU", | 302 | .name = "CPU-DSP", |
228 | .stream_name = "CPU", | 303 | .stream_name = "CPU-DSP", |
229 | .cpu_dai_name = "samsung-i2s.0", | 304 | .cpu_dai_name = "samsung-i2s.0", |
305 | .codec_dai_name = "wm0010-sdi1", | ||
306 | .platform_name = "samsung-i2s.0", | ||
307 | .codec_name = "spi0.0", | ||
308 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
309 | | SND_SOC_DAIFMT_CBM_CFM, | ||
310 | }, | ||
311 | { | ||
312 | .name = "DSP-CODEC", | ||
313 | .stream_name = "DSP-CODEC", | ||
314 | .cpu_dai_name = "wm0010-sdi2", | ||
230 | .codec_dai_name = "wm5110-aif1", | 315 | .codec_dai_name = "wm5110-aif1", |
231 | .platform_name = "samsung-audio", | ||
232 | .codec_name = "wm5110-codec", | 316 | .codec_name = "wm5110-codec", |
233 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 317 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
234 | | SND_SOC_DAIFMT_CBM_CFM, | 318 | | SND_SOC_DAIFMT_CBM_CFM, |
319 | .params = &sub_params, | ||
320 | .ignore_suspend = 1, | ||
235 | }, | 321 | }, |
236 | { | 322 | { |
237 | .name = "Baseband", | 323 | .name = "Baseband", |
@@ -247,7 +333,7 @@ static struct snd_soc_dai_link bells_dai_wm5110[] = { | |||
247 | { | 333 | { |
248 | .name = "Sub", | 334 | .name = "Sub", |
249 | .stream_name = "Sub", | 335 | .stream_name = "Sub", |
250 | .cpu_dai_name = "wm5102-aif3", | 336 | .cpu_dai_name = "wm5110-aif3", |
251 | .codec_dai_name = "wm9081-hifi", | 337 | .codec_dai_name = "wm9081-hifi", |
252 | .codec_name = "wm9081.1-006c", | 338 | .codec_name = "wm9081.1-006c", |
253 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 339 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
@@ -270,6 +356,24 @@ static struct snd_soc_dapm_route bells_routes[] = { | |||
270 | 356 | ||
271 | static struct snd_soc_card bells_cards[] = { | 357 | static struct snd_soc_card bells_cards[] = { |
272 | { | 358 | { |
359 | .name = "Bells WM2200", | ||
360 | .owner = THIS_MODULE, | ||
361 | .dai_link = bells_dai_wm2200, | ||
362 | .num_links = ARRAY_SIZE(bells_dai_wm2200), | ||
363 | .codec_conf = bells_codec_conf, | ||
364 | .num_configs = ARRAY_SIZE(bells_codec_conf), | ||
365 | |||
366 | .late_probe = bells_late_probe, | ||
367 | |||
368 | .dapm_routes = bells_routes, | ||
369 | .num_dapm_routes = ARRAY_SIZE(bells_routes), | ||
370 | |||
371 | .set_bias_level = bells_set_bias_level, | ||
372 | .set_bias_level_post = bells_set_bias_level_post, | ||
373 | |||
374 | .drvdata = &wm2200_drvdata, | ||
375 | }, | ||
376 | { | ||
273 | .name = "Bells WM5102", | 377 | .name = "Bells WM5102", |
274 | .owner = THIS_MODULE, | 378 | .owner = THIS_MODULE, |
275 | .dai_link = bells_dai_wm5102, | 379 | .dai_link = bells_dai_wm5102, |
@@ -284,6 +388,8 @@ static struct snd_soc_card bells_cards[] = { | |||
284 | 388 | ||
285 | .set_bias_level = bells_set_bias_level, | 389 | .set_bias_level = bells_set_bias_level, |
286 | .set_bias_level_post = bells_set_bias_level_post, | 390 | .set_bias_level_post = bells_set_bias_level_post, |
391 | |||
392 | .drvdata = &wm5102_drvdata, | ||
287 | }, | 393 | }, |
288 | { | 394 | { |
289 | .name = "Bells WM5110", | 395 | .name = "Bells WM5110", |
@@ -300,6 +406,8 @@ static struct snd_soc_card bells_cards[] = { | |||
300 | 406 | ||
301 | .set_bias_level = bells_set_bias_level, | 407 | .set_bias_level = bells_set_bias_level, |
302 | .set_bias_level_post = bells_set_bias_level_post, | 408 | .set_bias_level_post = bells_set_bias_level_post, |
409 | |||
410 | .drvdata = &wm5110_drvdata, | ||
303 | }, | 411 | }, |
304 | }; | 412 | }; |
305 | 413 | ||
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index b70964ea448c..64529904a95f 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c | |||
@@ -432,30 +432,18 @@ static struct snd_soc_platform_driver samsung_asoc_platform = { | |||
432 | .pcm_free = dma_free_dma_buffers, | 432 | .pcm_free = dma_free_dma_buffers, |
433 | }; | 433 | }; |
434 | 434 | ||
435 | static int __devinit samsung_asoc_platform_probe(struct platform_device *pdev) | 435 | int __devinit asoc_dma_platform_register(struct device *dev) |
436 | { | 436 | { |
437 | return snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform); | 437 | return snd_soc_register_platform(dev, &samsung_asoc_platform); |
438 | } | 438 | } |
439 | EXPORT_SYMBOL_GPL(asoc_dma_platform_register); | ||
439 | 440 | ||
440 | static int __devexit samsung_asoc_platform_remove(struct platform_device *pdev) | 441 | void __devexit asoc_dma_platform_unregister(struct device *dev) |
441 | { | 442 | { |
442 | snd_soc_unregister_platform(&pdev->dev); | 443 | snd_soc_unregister_platform(dev); |
443 | return 0; | ||
444 | } | 444 | } |
445 | 445 | EXPORT_SYMBOL_GPL(asoc_dma_platform_unregister); | |
446 | static struct platform_driver asoc_dma_driver = { | ||
447 | .driver = { | ||
448 | .name = "samsung-audio", | ||
449 | .owner = THIS_MODULE, | ||
450 | }, | ||
451 | |||
452 | .probe = samsung_asoc_platform_probe, | ||
453 | .remove = __devexit_p(samsung_asoc_platform_remove), | ||
454 | }; | ||
455 | |||
456 | module_platform_driver(asoc_dma_driver); | ||
457 | 446 | ||
458 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); | 447 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); |
459 | MODULE_DESCRIPTION("Samsung ASoC DMA Driver"); | 448 | MODULE_DESCRIPTION("Samsung ASoC DMA Driver"); |
460 | MODULE_LICENSE("GPL"); | 449 | MODULE_LICENSE("GPL"); |
461 | MODULE_ALIAS("platform:samsung-audio"); | ||
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h index 7d1ead77ef21..73d8c7c8a1e8 100644 --- a/sound/soc/samsung/dma.h +++ b/sound/soc/samsung/dma.h | |||
@@ -21,4 +21,7 @@ struct s3c_dma_params { | |||
21 | struct samsung_dma_ops *ops; | 21 | struct samsung_dma_ops *ops; |
22 | }; | 22 | }; |
23 | 23 | ||
24 | int asoc_dma_platform_register(struct device *dev); | ||
25 | void asoc_dma_platform_unregister(struct device *dev); | ||
26 | |||
24 | #endif | 27 | #endif |
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c index c23c2ae91f58..d37ede58e0a8 100644 --- a/sound/soc/samsung/goni_wm8994.c +++ b/sound/soc/samsung/goni_wm8994.c | |||
@@ -228,7 +228,7 @@ static struct snd_soc_dai_link goni_dai[] = { | |||
228 | .stream_name = "WM8994 HiFi", | 228 | .stream_name = "WM8994 HiFi", |
229 | .cpu_dai_name = "samsung-i2s.0", | 229 | .cpu_dai_name = "samsung-i2s.0", |
230 | .codec_dai_name = "wm8994-aif1", | 230 | .codec_dai_name = "wm8994-aif1", |
231 | .platform_name = "samsung-audio", | 231 | .platform_name = "samsung-i2s.0", |
232 | .codec_name = "wm8994-codec.0-001a", | 232 | .codec_name = "wm8994-codec.0-001a", |
233 | .init = goni_wm8994_init, | 233 | .init = goni_wm8994_init, |
234 | .ops = &goni_hifi_ops, | 234 | .ops = &goni_hifi_ops, |
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index 6e3257717c54..3870e9678b5d 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c | |||
@@ -207,7 +207,7 @@ static struct snd_soc_dai_link h1940_uda1380_dai[] = { | |||
207 | .cpu_dai_name = "s3c24xx-iis", | 207 | .cpu_dai_name = "s3c24xx-iis", |
208 | .codec_dai_name = "uda1380-hifi", | 208 | .codec_dai_name = "uda1380-hifi", |
209 | .init = h1940_uda1380_init, | 209 | .init = h1940_uda1380_init, |
210 | .platform_name = "samsung-audio", | 210 | .platform_name = "s3c24xx-iis", |
211 | .codec_name = "uda1380-codec.0-001a", | 211 | .codec_name = "uda1380-codec.0-001a", |
212 | .ops = &h1940_ops, | 212 | .ops = &h1940_ops, |
213 | }, | 213 | }, |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 40b00a13dcd1..0aa0451823ce 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
@@ -49,8 +49,6 @@ struct i2s_dai { | |||
49 | struct clk *clk; | 49 | struct clk *clk; |
50 | /* Clock for generating I2S signals */ | 50 | /* Clock for generating I2S signals */ |
51 | struct clk *op_clk; | 51 | struct clk *op_clk; |
52 | /* Array of clock names for op_clk */ | ||
53 | const char **src_clk; | ||
54 | /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */ | 52 | /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */ |
55 | struct i2s_dai *pri_dai; | 53 | struct i2s_dai *pri_dai; |
56 | /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */ | 54 | /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */ |
@@ -423,7 +421,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, | |||
423 | if (i2s->op_clk) { | 421 | if (i2s->op_clk) { |
424 | if ((clk_id && !(mod & MOD_IMS_SYSMUX)) || | 422 | if ((clk_id && !(mod & MOD_IMS_SYSMUX)) || |
425 | (!clk_id && (mod & MOD_IMS_SYSMUX))) { | 423 | (!clk_id && (mod & MOD_IMS_SYSMUX))) { |
426 | clk_disable(i2s->op_clk); | 424 | clk_disable_unprepare(i2s->op_clk); |
427 | clk_put(i2s->op_clk); | 425 | clk_put(i2s->op_clk); |
428 | } else { | 426 | } else { |
429 | i2s->rclk_srcrate = | 427 | i2s->rclk_srcrate = |
@@ -432,9 +430,13 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, | |||
432 | } | 430 | } |
433 | } | 431 | } |
434 | 432 | ||
435 | i2s->op_clk = clk_get(&i2s->pdev->dev, | 433 | if (clk_id) |
436 | i2s->src_clk[clk_id]); | 434 | i2s->op_clk = clk_get(&i2s->pdev->dev, |
437 | clk_enable(i2s->op_clk); | 435 | "i2s_opclk1"); |
436 | else | ||
437 | i2s->op_clk = clk_get(&i2s->pdev->dev, | ||
438 | "i2s_opclk0"); | ||
439 | clk_prepare_enable(i2s->op_clk); | ||
438 | i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); | 440 | i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); |
439 | 441 | ||
440 | /* Over-ride the other's */ | 442 | /* Over-ride the other's */ |
@@ -880,7 +882,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) | |||
880 | iounmap(i2s->addr); | 882 | iounmap(i2s->addr); |
881 | return -ENOENT; | 883 | return -ENOENT; |
882 | } | 884 | } |
883 | clk_enable(i2s->clk); | 885 | clk_prepare_enable(i2s->clk); |
884 | 886 | ||
885 | if (other) { | 887 | if (other) { |
886 | other->addr = i2s->addr; | 888 | other->addr = i2s->addr; |
@@ -922,7 +924,7 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) | |||
922 | if (i2s->quirks & QUIRK_NEED_RSTCLR) | 924 | if (i2s->quirks & QUIRK_NEED_RSTCLR) |
923 | writel(0, i2s->addr + I2SCON); | 925 | writel(0, i2s->addr + I2SCON); |
924 | 926 | ||
925 | clk_disable(i2s->clk); | 927 | clk_disable_unprepare(i2s->clk); |
926 | clk_put(i2s->clk); | 928 | clk_put(i2s->clk); |
927 | 929 | ||
928 | iounmap(i2s->addr); | 930 | iounmap(i2s->addr); |
@@ -1007,6 +1009,7 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) | |||
1007 | sec_dai = dev_get_drvdata(&pdev->dev); | 1009 | sec_dai = dev_get_drvdata(&pdev->dev); |
1008 | snd_soc_register_dai(&sec_dai->pdev->dev, | 1010 | snd_soc_register_dai(&sec_dai->pdev->dev, |
1009 | &sec_dai->i2s_dai_drv); | 1011 | &sec_dai->i2s_dai_drv); |
1012 | asoc_dma_platform_register(&pdev->dev); | ||
1010 | return 0; | 1013 | return 0; |
1011 | } | 1014 | } |
1012 | 1015 | ||
@@ -1067,7 +1070,6 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) | |||
1067 | (struct s3c2410_dma_client *)&pri_dai->dma_capture; | 1070 | (struct s3c2410_dma_client *)&pri_dai->dma_capture; |
1068 | pri_dai->dma_playback.channel = dma_pl_chan; | 1071 | pri_dai->dma_playback.channel = dma_pl_chan; |
1069 | pri_dai->dma_capture.channel = dma_cp_chan; | 1072 | pri_dai->dma_capture.channel = dma_cp_chan; |
1070 | pri_dai->src_clk = i2s_cfg->src_clk; | ||
1071 | pri_dai->dma_playback.dma_size = 4; | 1073 | pri_dai->dma_playback.dma_size = 4; |
1072 | pri_dai->dma_capture.dma_size = 4; | 1074 | pri_dai->dma_capture.dma_size = 4; |
1073 | pri_dai->base = regs_base; | 1075 | pri_dai->base = regs_base; |
@@ -1088,7 +1090,6 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) | |||
1088 | (struct s3c2410_dma_client *)&sec_dai->dma_playback; | 1090 | (struct s3c2410_dma_client *)&sec_dai->dma_playback; |
1089 | /* Use iDMA always if SysDMA not provided */ | 1091 | /* Use iDMA always if SysDMA not provided */ |
1090 | sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1; | 1092 | sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1; |
1091 | sec_dai->src_clk = i2s_cfg->src_clk; | ||
1092 | sec_dai->dma_playback.dma_size = 4; | 1093 | sec_dai->dma_playback.dma_size = 4; |
1093 | sec_dai->base = regs_base; | 1094 | sec_dai->base = regs_base; |
1094 | sec_dai->quirks = quirks; | 1095 | sec_dai->quirks = quirks; |
@@ -1107,6 +1108,8 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) | |||
1107 | 1108 | ||
1108 | pm_runtime_enable(&pdev->dev); | 1109 | pm_runtime_enable(&pdev->dev); |
1109 | 1110 | ||
1111 | asoc_dma_platform_register(&pdev->dev); | ||
1112 | |||
1110 | return 0; | 1113 | return 0; |
1111 | err: | 1114 | err: |
1112 | release_mem_region(regs_base, resource_size(res)); | 1115 | release_mem_region(regs_base, resource_size(res)); |
@@ -1135,6 +1138,7 @@ static __devexit int samsung_i2s_remove(struct platform_device *pdev) | |||
1135 | i2s->pri_dai = NULL; | 1138 | i2s->pri_dai = NULL; |
1136 | i2s->sec_dai = NULL; | 1139 | i2s->sec_dai = NULL; |
1137 | 1140 | ||
1141 | asoc_dma_platform_unregister(&pdev->dev); | ||
1138 | snd_soc_unregister_dai(&pdev->dev); | 1142 | snd_soc_unregister_dai(&pdev->dev); |
1139 | 1143 | ||
1140 | return 0; | 1144 | return 0; |
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c index 1578663a1faa..b5f6abd9d221 100644 --- a/sound/soc/samsung/jive_wm8750.c +++ b/sound/soc/samsung/jive_wm8750.c | |||
@@ -118,7 +118,7 @@ static struct snd_soc_dai_link jive_dai = { | |||
118 | .stream_name = "WM8750", | 118 | .stream_name = "WM8750", |
119 | .cpu_dai_name = "s3c2412-i2s", | 119 | .cpu_dai_name = "s3c2412-i2s", |
120 | .codec_dai_name = "wm8750-hifi", | 120 | .codec_dai_name = "wm8750-hifi", |
121 | .platform_name = "samsung-audio", | 121 | .platform_name = "s3c2412-i2s", |
122 | .codec_name = "wm8750.0-001a", | 122 | .codec_name = "wm8750.0-001a", |
123 | .init = jive_wm8750_init, | 123 | .init = jive_wm8750_init, |
124 | .ops = &jive_ops, | 124 | .ops = &jive_ops, |
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c index ee52c8a00779..0908bb05a5e7 100644 --- a/sound/soc/samsung/littlemill.c +++ b/sound/soc/samsung/littlemill.c | |||
@@ -145,7 +145,7 @@ static struct snd_soc_dai_link littlemill_dai[] = { | |||
145 | .stream_name = "CPU", | 145 | .stream_name = "CPU", |
146 | .cpu_dai_name = "samsung-i2s.0", | 146 | .cpu_dai_name = "samsung-i2s.0", |
147 | .codec_dai_name = "wm8994-aif1", | 147 | .codec_dai_name = "wm8994-aif1", |
148 | .platform_name = "samsung-audio", | 148 | .platform_name = "samsung-i2s.0", |
149 | .codec_name = "wm8994-codec", | 149 | .codec_name = "wm8994-codec", |
150 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 150 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
151 | | SND_SOC_DAIFMT_CBM_CFM, | 151 | | SND_SOC_DAIFMT_CBM_CFM, |
diff --git a/sound/soc/samsung/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c index 69c4a5934a4d..9342fc270c2b 100644 --- a/sound/soc/samsung/ln2440sbc_alc650.c +++ b/sound/soc/samsung/ln2440sbc_alc650.c | |||
@@ -28,7 +28,7 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = { | |||
28 | .cpu_dai_name = "samsung-ac97", | 28 | .cpu_dai_name = "samsung-ac97", |
29 | .codec_dai_name = "ac97-hifi", | 29 | .codec_dai_name = "ac97-hifi", |
30 | .codec_name = "ac97-codec", | 30 | .codec_name = "ac97-codec", |
31 | .platform_name = "samsung-audio", | 31 | .platform_name = "samsung-ac97", |
32 | }, | 32 | }, |
33 | }; | 33 | }; |
34 | 34 | ||
diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c index 6abf341c4a2a..a71c31af4e0e 100644 --- a/sound/soc/samsung/lowland.c +++ b/sound/soc/samsung/lowland.c | |||
@@ -99,7 +99,7 @@ static struct snd_soc_dai_link lowland_dai[] = { | |||
99 | .stream_name = "CPU", | 99 | .stream_name = "CPU", |
100 | .cpu_dai_name = "samsung-i2s.0", | 100 | .cpu_dai_name = "samsung-i2s.0", |
101 | .codec_dai_name = "wm5100-aif1", | 101 | .codec_dai_name = "wm5100-aif1", |
102 | .platform_name = "samsung-audio", | 102 | .platform_name = "samsung-i2s.0", |
103 | .codec_name = "wm5100.1-001a", | 103 | .codec_name = "wm5100.1-001a", |
104 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | 104 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
105 | SND_SOC_DAIFMT_CBM_CFM, | 105 | SND_SOC_DAIFMT_CBM_CFM, |
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index 321d51134e47..c7e965f80d2e 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c | |||
@@ -364,7 +364,7 @@ static struct snd_soc_dai_link neo1973_dai[] = { | |||
364 | { /* Hifi Playback - for similatious use with voice below */ | 364 | { /* Hifi Playback - for similatious use with voice below */ |
365 | .name = "WM8753", | 365 | .name = "WM8753", |
366 | .stream_name = "WM8753 HiFi", | 366 | .stream_name = "WM8753 HiFi", |
367 | .platform_name = "samsung-audio", | 367 | .platform_name = "s3c24xx-iis", |
368 | .cpu_dai_name = "s3c24xx-iis", | 368 | .cpu_dai_name = "s3c24xx-iis", |
369 | .codec_dai_name = "wm8753-hifi", | 369 | .codec_dai_name = "wm8753-hifi", |
370 | .codec_name = "wm8753.0-001a", | 370 | .codec_name = "wm8753.0-001a", |
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index c86081992dfd..ecd509048771 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c | |||
@@ -543,7 +543,7 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
543 | ret = PTR_ERR(pcm->cclk); | 543 | ret = PTR_ERR(pcm->cclk); |
544 | goto err1; | 544 | goto err1; |
545 | } | 545 | } |
546 | clk_enable(pcm->cclk); | 546 | clk_prepare_enable(pcm->cclk); |
547 | 547 | ||
548 | /* record our pcm structure for later use in the callbacks */ | 548 | /* record our pcm structure for later use in the callbacks */ |
549 | dev_set_drvdata(&pdev->dev, pcm); | 549 | dev_set_drvdata(&pdev->dev, pcm); |
@@ -568,7 +568,7 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
568 | ret = -ENOENT; | 568 | ret = -ENOENT; |
569 | goto err4; | 569 | goto err4; |
570 | } | 570 | } |
571 | clk_enable(pcm->pclk); | 571 | clk_prepare_enable(pcm->pclk); |
572 | 572 | ||
573 | s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start | 573 | s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start |
574 | + S3C_PCM_RXFIFO; | 574 | + S3C_PCM_RXFIFO; |
@@ -589,17 +589,25 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
589 | goto err5; | 589 | goto err5; |
590 | } | 590 | } |
591 | 591 | ||
592 | ret = asoc_dma_platform_register(&pdev->dev); | ||
593 | if (ret) { | ||
594 | dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); | ||
595 | goto err6; | ||
596 | } | ||
597 | |||
592 | return 0; | 598 | return 0; |
593 | 599 | ||
600 | err6: | ||
601 | snd_soc_unregister_dai(&pdev->dev); | ||
594 | err5: | 602 | err5: |
595 | clk_disable(pcm->pclk); | 603 | clk_disable_unprepare(pcm->pclk); |
596 | clk_put(pcm->pclk); | 604 | clk_put(pcm->pclk); |
597 | err4: | 605 | err4: |
598 | iounmap(pcm->regs); | 606 | iounmap(pcm->regs); |
599 | err3: | 607 | err3: |
600 | release_mem_region(mem_res->start, resource_size(mem_res)); | 608 | release_mem_region(mem_res->start, resource_size(mem_res)); |
601 | err2: | 609 | err2: |
602 | clk_disable(pcm->cclk); | 610 | clk_disable_unprepare(pcm->cclk); |
603 | clk_put(pcm->cclk); | 611 | clk_put(pcm->cclk); |
604 | err1: | 612 | err1: |
605 | return ret; | 613 | return ret; |
@@ -610,6 +618,7 @@ static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) | |||
610 | struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; | 618 | struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; |
611 | struct resource *mem_res; | 619 | struct resource *mem_res; |
612 | 620 | ||
621 | asoc_dma_platform_unregister(&pdev->dev); | ||
613 | snd_soc_unregister_dai(&pdev->dev); | 622 | snd_soc_unregister_dai(&pdev->dev); |
614 | 623 | ||
615 | pm_runtime_disable(&pdev->dev); | 624 | pm_runtime_disable(&pdev->dev); |
@@ -619,8 +628,8 @@ static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) | |||
619 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 628 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
620 | release_mem_region(mem_res->start, resource_size(mem_res)); | 629 | release_mem_region(mem_res->start, resource_size(mem_res)); |
621 | 630 | ||
622 | clk_disable(pcm->cclk); | 631 | clk_disable_unprepare(pcm->cclk); |
623 | clk_disable(pcm->pclk); | 632 | clk_disable_unprepare(pcm->pclk); |
624 | clk_put(pcm->pclk); | 633 | clk_put(pcm->pclk); |
625 | clk_put(pcm->cclk); | 634 | clk_put(pcm->cclk); |
626 | 635 | ||
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index 21e12361a9cd..a5826ea9cad6 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c | |||
@@ -85,7 +85,7 @@ static struct snd_soc_dai_link rx1950_uda1380_dai[] = { | |||
85 | .cpu_dai_name = "s3c24xx-iis", | 85 | .cpu_dai_name = "s3c24xx-iis", |
86 | .codec_dai_name = "uda1380-hifi", | 86 | .codec_dai_name = "uda1380-hifi", |
87 | .init = rx1950_uda1380_init, | 87 | .init = rx1950_uda1380_init, |
88 | .platform_name = "samsung-audio", | 88 | .platform_name = "s3c24xx-iis", |
89 | .codec_name = "uda1380-codec.0-001a", | 89 | .codec_name = "uda1380-codec.0-001a", |
90 | .ops = &rx1950_ops, | 90 | .ops = &rx1950_ops, |
91 | }, | 91 | }, |
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index ac7701b3c5dc..edf5f527c5a2 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c | |||
@@ -162,11 +162,29 @@ static struct snd_soc_dai_driver s3c2412_i2s_dai = { | |||
162 | 162 | ||
163 | static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev) | 163 | static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev) |
164 | { | 164 | { |
165 | return s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); | 165 | int ret = 0; |
166 | |||
167 | ret = s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); | ||
168 | if (ret) { | ||
169 | pr_err("failed to register the dai\n"); | ||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | ret = asoc_dma_platform_register(&pdev->dev); | ||
174 | if (ret) { | ||
175 | pr_err("failed to register the DMA: %d\n", ret); | ||
176 | goto err; | ||
177 | } | ||
178 | |||
179 | return 0; | ||
180 | err: | ||
181 | snd_soc_unregister_dai(&pdev->dev); | ||
182 | return ret; | ||
166 | } | 183 | } |
167 | 184 | ||
168 | static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev) | 185 | static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev) |
169 | { | 186 | { |
187 | asoc_dma_platform_unregister(&pdev->dev); | ||
170 | snd_soc_unregister_dai(&pdev->dev); | 188 | snd_soc_unregister_dai(&pdev->dev); |
171 | return 0; | 189 | return 0; |
172 | } | 190 | } |
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 0aae3a3883dc..0022d51fd160 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c | |||
@@ -467,11 +467,29 @@ static struct snd_soc_dai_driver s3c24xx_i2s_dai = { | |||
467 | 467 | ||
468 | static __devinit int s3c24xx_iis_dev_probe(struct platform_device *pdev) | 468 | static __devinit int s3c24xx_iis_dev_probe(struct platform_device *pdev) |
469 | { | 469 | { |
470 | return snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai); | 470 | int ret = 0; |
471 | |||
472 | ret = s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); | ||
473 | if (ret) { | ||
474 | pr_err("failed to register the dai\n"); | ||
475 | return ret; | ||
476 | } | ||
477 | |||
478 | ret = asoc_dma_platform_register(&pdev->dev); | ||
479 | if (ret) { | ||
480 | pr_err("failed to register the dma: %d\n", ret); | ||
481 | goto err; | ||
482 | } | ||
483 | |||
484 | return 0; | ||
485 | err: | ||
486 | snd_soc_unregister_dai(&pdev->dev); | ||
487 | return ret; | ||
471 | } | 488 | } |
472 | 489 | ||
473 | static __devexit int s3c24xx_iis_dev_remove(struct platform_device *pdev) | 490 | static __devexit int s3c24xx_iis_dev_remove(struct platform_device *pdev) |
474 | { | 491 | { |
492 | asoc_dma_platform_unregister(&pdev->dev); | ||
475 | snd_soc_unregister_dai(&pdev->dev); | 493 | snd_soc_unregister_dai(&pdev->dev); |
476 | return 0; | 494 | return 0; |
477 | } | 495 | } |
diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c index 7ace6a87f41b..befabe8979f7 100644 --- a/sound/soc/samsung/s3c24xx_simtec_hermes.c +++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c | |||
@@ -82,7 +82,7 @@ static struct snd_soc_dai_link simtec_dai_aic33 = { | |||
82 | .codec_name = "tlv320aic3x-codec.0-001a", | 82 | .codec_name = "tlv320aic3x-codec.0-001a", |
83 | .cpu_dai_name = "s3c24xx-iis", | 83 | .cpu_dai_name = "s3c24xx-iis", |
84 | .codec_dai_name = "tlv320aic3x-hifi", | 84 | .codec_dai_name = "tlv320aic3x-hifi", |
85 | .platform_name = "samsung-audio", | 85 | .platform_name = "s3c24xx-iis", |
86 | .init = simtec_hermes_init, | 86 | .init = simtec_hermes_init, |
87 | }; | 87 | }; |
88 | 88 | ||
diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c index c42d5f00b0e1..5552f82c92a7 100644 --- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c +++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c | |||
@@ -71,7 +71,7 @@ static struct snd_soc_dai_link simtec_dai_aic23 = { | |||
71 | .codec_name = "tlv320aic3x-codec.0-001a", | 71 | .codec_name = "tlv320aic3x-codec.0-001a", |
72 | .cpu_dai_name = "s3c24xx-iis", | 72 | .cpu_dai_name = "s3c24xx-iis", |
73 | .codec_dai_name = "tlv320aic3x-hifi", | 73 | .codec_dai_name = "tlv320aic3x-hifi", |
74 | .platform_name = "samsung-audio", | 74 | .platform_name = "s3c24xx-iis", |
75 | .init = simtec_tlv320aic23_init, | 75 | .init = simtec_tlv320aic23_init, |
76 | }; | 76 | }; |
77 | 77 | ||
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index d731042e51b0..333e1b7f06c7 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c | |||
@@ -224,7 +224,7 @@ static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = { | |||
224 | .codec_dai_name = "uda134x-hifi", | 224 | .codec_dai_name = "uda134x-hifi", |
225 | .cpu_dai_name = "s3c24xx-iis", | 225 | .cpu_dai_name = "s3c24xx-iis", |
226 | .ops = &s3c24xx_uda134x_ops, | 226 | .ops = &s3c24xx_uda134x_ops, |
227 | .platform_name = "samsung-audio", | 227 | .platform_name = "s3c24xx-iis", |
228 | }; | 228 | }; |
229 | 229 | ||
230 | static struct snd_soc_card snd_soc_s3c24xx_uda134x = { | 230 | static struct snd_soc_card snd_soc_s3c24xx_uda134x = { |
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index f2dcb424ea25..58ae3237ef69 100644 --- a/sound/soc/samsung/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c | |||
@@ -189,7 +189,7 @@ static struct snd_soc_dai_link smartq_dai[] = { | |||
189 | .stream_name = "SmartQ Hi-Fi", | 189 | .stream_name = "SmartQ Hi-Fi", |
190 | .cpu_dai_name = "samsung-i2s.0", | 190 | .cpu_dai_name = "samsung-i2s.0", |
191 | .codec_dai_name = "wm8750-hifi", | 191 | .codec_dai_name = "wm8750-hifi", |
192 | .platform_name = "samsung-audio", | 192 | .platform_name = "samsung-i2s.0", |
193 | .codec_name = "wm8750.0-0x1a", | 193 | .codec_name = "wm8750.0-0x1a", |
194 | .init = smartq_wm8987_init, | 194 | .init = smartq_wm8987_init, |
195 | .ops = &smartq_hifi_ops, | 195 | .ops = &smartq_hifi_ops, |
diff --git a/sound/soc/samsung/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c index 720ba29bb7e4..c390aad68cfb 100644 --- a/sound/soc/samsung/smdk2443_wm9710.c +++ b/sound/soc/samsung/smdk2443_wm9710.c | |||
@@ -24,7 +24,7 @@ static struct snd_soc_dai_link smdk2443_dai[] = { | |||
24 | .cpu_dai_name = "samsung-ac97", | 24 | .cpu_dai_name = "samsung-ac97", |
25 | .codec_dai_name = "ac97-hifi", | 25 | .codec_dai_name = "ac97-hifi", |
26 | .codec_name = "ac97-codec", | 26 | .codec_name = "ac97-codec", |
27 | .platform_name = "samsung-audio", | 27 | .platform_name = "samsung-ac97", |
28 | }, | 28 | }, |
29 | }; | 29 | }; |
30 | 30 | ||
diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c index beaa9c15d697..a2f2363fe1c2 100644 --- a/sound/soc/samsung/smdk_spdif.c +++ b/sound/soc/samsung/smdk_spdif.c | |||
@@ -151,7 +151,7 @@ static struct snd_soc_ops smdk_spdif_ops = { | |||
151 | static struct snd_soc_dai_link smdk_dai = { | 151 | static struct snd_soc_dai_link smdk_dai = { |
152 | .name = "S/PDIF", | 152 | .name = "S/PDIF", |
153 | .stream_name = "S/PDIF PCM Playback", | 153 | .stream_name = "S/PDIF PCM Playback", |
154 | .platform_name = "samsung-audio", | 154 | .platform_name = "samsung-spdif", |
155 | .cpu_dai_name = "samsung-spdif", | 155 | .cpu_dai_name = "samsung-spdif", |
156 | .codec_dai_name = "dit-hifi", | 156 | .codec_dai_name = "dit-hifi", |
157 | .codec_name = "spdif-dit", | 157 | .codec_name = "spdif-dit", |
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index ade2809cf393..7e2b710763be 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c | |||
@@ -176,7 +176,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
176 | .stream_name = "Playback", | 176 | .stream_name = "Playback", |
177 | .cpu_dai_name = "samsung-i2s.0", | 177 | .cpu_dai_name = "samsung-i2s.0", |
178 | .codec_dai_name = "wm8580-hifi-playback", | 178 | .codec_dai_name = "wm8580-hifi-playback", |
179 | .platform_name = "samsung-audio", | 179 | .platform_name = "samsung-i2s.0", |
180 | .codec_name = "wm8580.0-001b", | 180 | .codec_name = "wm8580.0-001b", |
181 | .ops = &smdk_ops, | 181 | .ops = &smdk_ops, |
182 | }, | 182 | }, |
@@ -185,7 +185,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
185 | .stream_name = "Capture", | 185 | .stream_name = "Capture", |
186 | .cpu_dai_name = "samsung-i2s.0", | 186 | .cpu_dai_name = "samsung-i2s.0", |
187 | .codec_dai_name = "wm8580-hifi-capture", | 187 | .codec_dai_name = "wm8580-hifi-capture", |
188 | .platform_name = "samsung-audio", | 188 | .platform_name = "samsung-i2s.0", |
189 | .codec_name = "wm8580.0-001b", | 189 | .codec_name = "wm8580.0-001b", |
190 | .init = smdk_wm8580_init_paiftx, | 190 | .init = smdk_wm8580_init_paiftx, |
191 | .ops = &smdk_ops, | 191 | .ops = &smdk_ops, |
@@ -195,7 +195,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
195 | .stream_name = "Playback", | 195 | .stream_name = "Playback", |
196 | .cpu_dai_name = "samsung-i2s.x", | 196 | .cpu_dai_name = "samsung-i2s.x", |
197 | .codec_dai_name = "wm8580-hifi-playback", | 197 | .codec_dai_name = "wm8580-hifi-playback", |
198 | .platform_name = "samsung-audio", | 198 | .platform_name = "samsung-i2s.x", |
199 | .codec_name = "wm8580.0-001b", | 199 | .codec_name = "wm8580.0-001b", |
200 | .ops = &smdk_ops, | 200 | .ops = &smdk_ops, |
201 | }, | 201 | }, |
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c index fab5322e9f05..34239fe9afde 100644 --- a/sound/soc/samsung/smdk_wm8580pcm.c +++ b/sound/soc/samsung/smdk_wm8580pcm.c | |||
@@ -135,7 +135,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
135 | .stream_name = "Capture", | 135 | .stream_name = "Capture", |
136 | .cpu_dai_name = "samsung-pcm.0", | 136 | .cpu_dai_name = "samsung-pcm.0", |
137 | .codec_dai_name = "wm8580-hifi-capture", | 137 | .codec_dai_name = "wm8580-hifi-capture", |
138 | .platform_name = "samsung-audio", | 138 | .platform_name = "samsung-pcm.0", |
139 | .codec_name = "wm8580.0-001b", | 139 | .codec_name = "wm8580.0-001b", |
140 | .ops = &smdk_wm8580_pcm_ops, | 140 | .ops = &smdk_wm8580_pcm_ops, |
141 | }, | 141 | }, |
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index 48dd4dd9ee08..dd0aa8cb1a9e 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c | |||
@@ -127,7 +127,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
127 | .stream_name = "Pri_Dai", | 127 | .stream_name = "Pri_Dai", |
128 | .cpu_dai_name = "samsung-i2s.0", | 128 | .cpu_dai_name = "samsung-i2s.0", |
129 | .codec_dai_name = "wm8994-aif1", | 129 | .codec_dai_name = "wm8994-aif1", |
130 | .platform_name = "samsung-audio", | 130 | .platform_name = "samsung-i2s.0", |
131 | .codec_name = "wm8994-codec", | 131 | .codec_name = "wm8994-codec", |
132 | .init = smdk_wm8994_init_paiftx, | 132 | .init = smdk_wm8994_init_paiftx, |
133 | .ops = &smdk_ops, | 133 | .ops = &smdk_ops, |
@@ -136,7 +136,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
136 | .stream_name = "Sec_Dai", | 136 | .stream_name = "Sec_Dai", |
137 | .cpu_dai_name = "samsung-i2s.4", | 137 | .cpu_dai_name = "samsung-i2s.4", |
138 | .codec_dai_name = "wm8994-aif1", | 138 | .codec_dai_name = "wm8994-aif1", |
139 | .platform_name = "samsung-audio", | 139 | .platform_name = "samsung-i2s.4", |
140 | .codec_name = "wm8994-codec", | 140 | .codec_name = "wm8994-codec", |
141 | .ops = &smdk_ops, | 141 | .ops = &smdk_ops, |
142 | }, | 142 | }, |
diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c index 77ecba935119..15f6b44e9de3 100644 --- a/sound/soc/samsung/smdk_wm8994pcm.c +++ b/sound/soc/samsung/smdk_wm8994pcm.c | |||
@@ -116,7 +116,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
116 | .stream_name = "Primary PCM", | 116 | .stream_name = "Primary PCM", |
117 | .cpu_dai_name = "samsung-pcm.0", | 117 | .cpu_dai_name = "samsung-pcm.0", |
118 | .codec_dai_name = "wm8994-aif1", | 118 | .codec_dai_name = "wm8994-aif1", |
119 | .platform_name = "samsung-audio", | 119 | .platform_name = "samsung-pcm.0", |
120 | .codec_name = "wm8994-codec", | 120 | .codec_name = "wm8994-codec", |
121 | .ops = &smdk_wm8994_pcm_ops, | 121 | .ops = &smdk_wm8994_pcm_ops, |
122 | }, | 122 | }, |
diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c index 55b2ca7f3290..0d20e4ed27aa 100644 --- a/sound/soc/samsung/smdk_wm9713.c +++ b/sound/soc/samsung/smdk_wm9713.c | |||
@@ -42,7 +42,7 @@ static struct snd_soc_card smdk; | |||
42 | static struct snd_soc_dai_link smdk_dai = { | 42 | static struct snd_soc_dai_link smdk_dai = { |
43 | .name = "AC97", | 43 | .name = "AC97", |
44 | .stream_name = "AC97 PCM", | 44 | .stream_name = "AC97 PCM", |
45 | .platform_name = "samsung-audio", | 45 | .platform_name = "samsung-ac97", |
46 | .cpu_dai_name = "samsung-ac97", | 46 | .cpu_dai_name = "samsung-ac97", |
47 | .codec_dai_name = "wm9713-hifi", | 47 | .codec_dai_name = "wm9713-hifi", |
48 | .codec_name = "wm9713-codec", | 48 | .codec_name = "wm9713-codec", |
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index bc24c7af02b2..8606fc6cb37d 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c | |||
@@ -397,7 +397,7 @@ static __devinit int spdif_probe(struct platform_device *pdev) | |||
397 | ret = -ENOENT; | 397 | ret = -ENOENT; |
398 | goto err0; | 398 | goto err0; |
399 | } | 399 | } |
400 | clk_enable(spdif->pclk); | 400 | clk_prepare_enable(spdif->pclk); |
401 | 401 | ||
402 | spdif->sclk = clk_get(&pdev->dev, "sclk_spdif"); | 402 | spdif->sclk = clk_get(&pdev->dev, "sclk_spdif"); |
403 | if (IS_ERR(spdif->sclk)) { | 403 | if (IS_ERR(spdif->sclk)) { |
@@ -405,7 +405,7 @@ static __devinit int spdif_probe(struct platform_device *pdev) | |||
405 | ret = -ENOENT; | 405 | ret = -ENOENT; |
406 | goto err1; | 406 | goto err1; |
407 | } | 407 | } |
408 | clk_enable(spdif->sclk); | 408 | clk_prepare_enable(spdif->sclk); |
409 | 409 | ||
410 | /* Request S/PDIF Register's memory region */ | 410 | /* Request S/PDIF Register's memory region */ |
411 | if (!request_mem_region(mem_res->start, | 411 | if (!request_mem_region(mem_res->start, |
@@ -437,17 +437,24 @@ static __devinit int spdif_probe(struct platform_device *pdev) | |||
437 | 437 | ||
438 | spdif->dma_playback = &spdif_stereo_out; | 438 | spdif->dma_playback = &spdif_stereo_out; |
439 | 439 | ||
440 | return 0; | 440 | ret = asoc_dma_platform_register(&pdev->dev); |
441 | if (ret) { | ||
442 | dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); | ||
443 | goto err5; | ||
444 | } | ||
441 | 445 | ||
446 | return 0; | ||
447 | err5: | ||
448 | snd_soc_unregister_dai(&pdev->dev); | ||
442 | err4: | 449 | err4: |
443 | iounmap(spdif->regs); | 450 | iounmap(spdif->regs); |
444 | err3: | 451 | err3: |
445 | release_mem_region(mem_res->start, resource_size(mem_res)); | 452 | release_mem_region(mem_res->start, resource_size(mem_res)); |
446 | err2: | 453 | err2: |
447 | clk_disable(spdif->sclk); | 454 | clk_disable_unprepare(spdif->sclk); |
448 | clk_put(spdif->sclk); | 455 | clk_put(spdif->sclk); |
449 | err1: | 456 | err1: |
450 | clk_disable(spdif->pclk); | 457 | clk_disable_unprepare(spdif->pclk); |
451 | clk_put(spdif->pclk); | 458 | clk_put(spdif->pclk); |
452 | err0: | 459 | err0: |
453 | return ret; | 460 | return ret; |
@@ -458,6 +465,7 @@ static __devexit int spdif_remove(struct platform_device *pdev) | |||
458 | struct samsung_spdif_info *spdif = &spdif_info; | 465 | struct samsung_spdif_info *spdif = &spdif_info; |
459 | struct resource *mem_res; | 466 | struct resource *mem_res; |
460 | 467 | ||
468 | asoc_dma_platform_unregister(&pdev->dev); | ||
461 | snd_soc_unregister_dai(&pdev->dev); | 469 | snd_soc_unregister_dai(&pdev->dev); |
462 | 470 | ||
463 | iounmap(spdif->regs); | 471 | iounmap(spdif->regs); |
@@ -466,9 +474,9 @@ static __devexit int spdif_remove(struct platform_device *pdev) | |||
466 | if (mem_res) | 474 | if (mem_res) |
467 | release_mem_region(mem_res->start, resource_size(mem_res)); | 475 | release_mem_region(mem_res->start, resource_size(mem_res)); |
468 | 476 | ||
469 | clk_disable(spdif->sclk); | 477 | clk_disable_unprepare(spdif->sclk); |
470 | clk_put(spdif->sclk); | 478 | clk_put(spdif->sclk); |
471 | clk_disable(spdif->pclk); | 479 | clk_disable_unprepare(spdif->pclk); |
472 | clk_put(spdif->pclk); | 480 | clk_put(spdif->pclk); |
473 | 481 | ||
474 | return 0; | 482 | return 0; |
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index c7e1c28528a4..d7906a144195 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c | |||
@@ -198,7 +198,7 @@ static struct snd_soc_dai_link speyside_dai[] = { | |||
198 | .stream_name = "CPU-DSP", | 198 | .stream_name = "CPU-DSP", |
199 | .cpu_dai_name = "samsung-i2s.0", | 199 | .cpu_dai_name = "samsung-i2s.0", |
200 | .codec_dai_name = "wm0010-sdi1", | 200 | .codec_dai_name = "wm0010-sdi1", |
201 | .platform_name = "samsung-audio", | 201 | .platform_name = "samsung-i2s.0", |
202 | .codec_name = "spi0.0", | 202 | .codec_name = "spi0.0", |
203 | .init = speyside_wm0010_init, | 203 | .init = speyside_wm0010_init, |
204 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 204 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c index 9199649bf786..42e4c8e6b03e 100644 --- a/sound/soc/samsung/tobermory.c +++ b/sound/soc/samsung/tobermory.c | |||
@@ -110,7 +110,7 @@ static struct snd_soc_dai_link tobermory_dai[] = { | |||
110 | .stream_name = "CPU", | 110 | .stream_name = "CPU", |
111 | .cpu_dai_name = "samsung-i2s.0", | 111 | .cpu_dai_name = "samsung-i2s.0", |
112 | .codec_dai_name = "wm8962", | 112 | .codec_dai_name = "wm8962", |
113 | .platform_name = "samsung-audio", | 113 | .platform_name = "samsung-i2s.0", |
114 | .codec_name = "wm8962.1-001a", | 114 | .codec_name = "wm8962.1-001a", |
115 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 115 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
116 | | SND_SOC_DAIFMT_CBM_CFM, | 116 | | SND_SOC_DAIFMT_CBM_CFM, |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 9d7f30774a44..a606d0f93d1c 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
24 | #include <sound/soc.h> | 24 | #include <sound/soc.h> |
25 | #include <sound/pcm_params.h> | ||
25 | #include <sound/sh_fsi.h> | 26 | #include <sound/sh_fsi.h> |
26 | 27 | ||
27 | /* PortA/PortB register */ | 28 | /* PortA/PortB register */ |
@@ -189,6 +190,14 @@ typedef int (*set_rate_func)(struct device *dev, int rate, int enable); | |||
189 | */ | 190 | */ |
190 | 191 | ||
191 | /* | 192 | /* |
193 | * FSI clock | ||
194 | * | ||
195 | * FSIxCLK [CPG] (ick) -------> | | ||
196 | * |-> FSI_DIV (div)-> FSI2 | ||
197 | * FSIxCK [external] (xck) ---> | | ||
198 | */ | ||
199 | |||
200 | /* | ||
192 | * struct | 201 | * struct |
193 | */ | 202 | */ |
194 | 203 | ||
@@ -228,6 +237,20 @@ struct fsi_stream { | |||
228 | dma_addr_t dma; | 237 | dma_addr_t dma; |
229 | }; | 238 | }; |
230 | 239 | ||
240 | struct fsi_clk { | ||
241 | /* see [FSI clock] */ | ||
242 | struct clk *own; | ||
243 | struct clk *xck; | ||
244 | struct clk *ick; | ||
245 | struct clk *div; | ||
246 | int (*set_rate)(struct device *dev, | ||
247 | struct fsi_priv *fsi, | ||
248 | unsigned long rate); | ||
249 | |||
250 | unsigned long rate; | ||
251 | unsigned int count; | ||
252 | }; | ||
253 | |||
231 | struct fsi_priv { | 254 | struct fsi_priv { |
232 | void __iomem *base; | 255 | void __iomem *base; |
233 | struct fsi_master *master; | 256 | struct fsi_master *master; |
@@ -236,11 +259,17 @@ struct fsi_priv { | |||
236 | struct fsi_stream playback; | 259 | struct fsi_stream playback; |
237 | struct fsi_stream capture; | 260 | struct fsi_stream capture; |
238 | 261 | ||
262 | struct fsi_clk clock; | ||
263 | |||
239 | u32 fmt; | 264 | u32 fmt; |
240 | 265 | ||
241 | int chan_num:16; | 266 | int chan_num:16; |
242 | int clk_master:1; | 267 | int clk_master:1; |
268 | int clk_cpg:1; | ||
243 | int spdif:1; | 269 | int spdif:1; |
270 | int enable_stream:1; | ||
271 | int bit_clk_inv:1; | ||
272 | int lr_clk_inv:1; | ||
244 | 273 | ||
245 | long rate; | 274 | long rate; |
246 | }; | 275 | }; |
@@ -370,6 +399,11 @@ static int fsi_is_spdif(struct fsi_priv *fsi) | |||
370 | return fsi->spdif; | 399 | return fsi->spdif; |
371 | } | 400 | } |
372 | 401 | ||
402 | static int fsi_is_enable_stream(struct fsi_priv *fsi) | ||
403 | { | ||
404 | return fsi->enable_stream; | ||
405 | } | ||
406 | |||
373 | static int fsi_is_play(struct snd_pcm_substream *substream) | 407 | static int fsi_is_play(struct snd_pcm_substream *substream) |
374 | { | 408 | { |
375 | return substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 409 | return substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
@@ -717,14 +751,335 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) | |||
717 | /* | 751 | /* |
718 | * clock function | 752 | * clock function |
719 | */ | 753 | */ |
754 | static int fsi_clk_init(struct device *dev, | ||
755 | struct fsi_priv *fsi, | ||
756 | int xck, | ||
757 | int ick, | ||
758 | int div, | ||
759 | int (*set_rate)(struct device *dev, | ||
760 | struct fsi_priv *fsi, | ||
761 | unsigned long rate)) | ||
762 | { | ||
763 | struct fsi_clk *clock = &fsi->clock; | ||
764 | int is_porta = fsi_is_port_a(fsi); | ||
765 | |||
766 | clock->xck = NULL; | ||
767 | clock->ick = NULL; | ||
768 | clock->div = NULL; | ||
769 | clock->rate = 0; | ||
770 | clock->count = 0; | ||
771 | clock->set_rate = set_rate; | ||
772 | |||
773 | clock->own = devm_clk_get(dev, NULL); | ||
774 | if (IS_ERR(clock->own)) | ||
775 | return -EINVAL; | ||
776 | |||
777 | /* external clock */ | ||
778 | if (xck) { | ||
779 | clock->xck = devm_clk_get(dev, is_porta ? "xcka" : "xckb"); | ||
780 | if (IS_ERR(clock->xck)) { | ||
781 | dev_err(dev, "can't get xck clock\n"); | ||
782 | return -EINVAL; | ||
783 | } | ||
784 | if (clock->xck == clock->own) { | ||
785 | dev_err(dev, "cpu doesn't support xck clock\n"); | ||
786 | return -EINVAL; | ||
787 | } | ||
788 | } | ||
789 | |||
790 | /* FSIACLK/FSIBCLK */ | ||
791 | if (ick) { | ||
792 | clock->ick = devm_clk_get(dev, is_porta ? "icka" : "ickb"); | ||
793 | if (IS_ERR(clock->ick)) { | ||
794 | dev_err(dev, "can't get ick clock\n"); | ||
795 | return -EINVAL; | ||
796 | } | ||
797 | if (clock->ick == clock->own) { | ||
798 | dev_err(dev, "cpu doesn't support ick clock\n"); | ||
799 | return -EINVAL; | ||
800 | } | ||
801 | } | ||
802 | |||
803 | /* FSI-DIV */ | ||
804 | if (div) { | ||
805 | clock->div = devm_clk_get(dev, is_porta ? "diva" : "divb"); | ||
806 | if (IS_ERR(clock->div)) { | ||
807 | dev_err(dev, "can't get div clock\n"); | ||
808 | return -EINVAL; | ||
809 | } | ||
810 | if (clock->div == clock->own) { | ||
811 | dev_err(dev, "cpu doens't support div clock\n"); | ||
812 | return -EINVAL; | ||
813 | } | ||
814 | } | ||
815 | |||
816 | return 0; | ||
817 | } | ||
818 | |||
819 | #define fsi_clk_invalid(fsi) fsi_clk_valid(fsi, 0) | ||
820 | static void fsi_clk_valid(struct fsi_priv *fsi, unsigned long rate) | ||
821 | { | ||
822 | fsi->clock.rate = rate; | ||
823 | } | ||
824 | |||
825 | static int fsi_clk_is_valid(struct fsi_priv *fsi) | ||
826 | { | ||
827 | return fsi->clock.set_rate && | ||
828 | fsi->clock.rate; | ||
829 | } | ||
830 | |||
831 | static int fsi_clk_enable(struct device *dev, | ||
832 | struct fsi_priv *fsi, | ||
833 | unsigned long rate) | ||
834 | { | ||
835 | struct fsi_clk *clock = &fsi->clock; | ||
836 | int ret = -EINVAL; | ||
837 | |||
838 | if (!fsi_clk_is_valid(fsi)) | ||
839 | return ret; | ||
840 | |||
841 | if (0 == clock->count) { | ||
842 | ret = clock->set_rate(dev, fsi, rate); | ||
843 | if (ret < 0) { | ||
844 | fsi_clk_invalid(fsi); | ||
845 | return ret; | ||
846 | } | ||
847 | |||
848 | if (clock->xck) | ||
849 | clk_enable(clock->xck); | ||
850 | if (clock->ick) | ||
851 | clk_enable(clock->ick); | ||
852 | if (clock->div) | ||
853 | clk_enable(clock->div); | ||
854 | |||
855 | clock->count++; | ||
856 | } | ||
857 | |||
858 | return ret; | ||
859 | } | ||
860 | |||
861 | static int fsi_clk_disable(struct device *dev, | ||
862 | struct fsi_priv *fsi) | ||
863 | { | ||
864 | struct fsi_clk *clock = &fsi->clock; | ||
865 | |||
866 | if (!fsi_clk_is_valid(fsi)) | ||
867 | return -EINVAL; | ||
868 | |||
869 | if (1 == clock->count--) { | ||
870 | if (clock->xck) | ||
871 | clk_disable(clock->xck); | ||
872 | if (clock->ick) | ||
873 | clk_disable(clock->ick); | ||
874 | if (clock->div) | ||
875 | clk_disable(clock->div); | ||
876 | } | ||
877 | |||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | static int fsi_clk_set_ackbpf(struct device *dev, | ||
882 | struct fsi_priv *fsi, | ||
883 | int ackmd, int bpfmd) | ||
884 | { | ||
885 | u32 data = 0; | ||
886 | |||
887 | /* check ackmd/bpfmd relationship */ | ||
888 | if (bpfmd > ackmd) { | ||
889 | dev_err(dev, "unsupported rate (%d/%d)\n", ackmd, bpfmd); | ||
890 | return -EINVAL; | ||
891 | } | ||
892 | |||
893 | /* ACKMD */ | ||
894 | switch (ackmd) { | ||
895 | case 512: | ||
896 | data |= (0x0 << 12); | ||
897 | break; | ||
898 | case 256: | ||
899 | data |= (0x1 << 12); | ||
900 | break; | ||
901 | case 128: | ||
902 | data |= (0x2 << 12); | ||
903 | break; | ||
904 | case 64: | ||
905 | data |= (0x3 << 12); | ||
906 | break; | ||
907 | case 32: | ||
908 | data |= (0x4 << 12); | ||
909 | break; | ||
910 | default: | ||
911 | dev_err(dev, "unsupported ackmd (%d)\n", ackmd); | ||
912 | return -EINVAL; | ||
913 | } | ||
914 | |||
915 | /* BPFMD */ | ||
916 | switch (bpfmd) { | ||
917 | case 32: | ||
918 | data |= (0x0 << 8); | ||
919 | break; | ||
920 | case 64: | ||
921 | data |= (0x1 << 8); | ||
922 | break; | ||
923 | case 128: | ||
924 | data |= (0x2 << 8); | ||
925 | break; | ||
926 | case 256: | ||
927 | data |= (0x3 << 8); | ||
928 | break; | ||
929 | case 512: | ||
930 | data |= (0x4 << 8); | ||
931 | break; | ||
932 | case 16: | ||
933 | data |= (0x7 << 8); | ||
934 | break; | ||
935 | default: | ||
936 | dev_err(dev, "unsupported bpfmd (%d)\n", bpfmd); | ||
937 | return -EINVAL; | ||
938 | } | ||
939 | |||
940 | dev_dbg(dev, "ACKMD/BPFMD = %d/%d\n", ackmd, bpfmd); | ||
941 | |||
942 | fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data); | ||
943 | udelay(10); | ||
944 | |||
945 | return 0; | ||
946 | } | ||
947 | |||
948 | static int fsi_clk_set_rate_external(struct device *dev, | ||
949 | struct fsi_priv *fsi, | ||
950 | unsigned long rate) | ||
951 | { | ||
952 | struct clk *xck = fsi->clock.xck; | ||
953 | struct clk *ick = fsi->clock.ick; | ||
954 | unsigned long xrate; | ||
955 | int ackmd, bpfmd; | ||
956 | int ret = 0; | ||
957 | |||
958 | /* check clock rate */ | ||
959 | xrate = clk_get_rate(xck); | ||
960 | if (xrate % rate) { | ||
961 | dev_err(dev, "unsupported clock rate\n"); | ||
962 | return -EINVAL; | ||
963 | } | ||
964 | |||
965 | clk_set_parent(ick, xck); | ||
966 | clk_set_rate(ick, xrate); | ||
967 | |||
968 | bpfmd = fsi->chan_num * 32; | ||
969 | ackmd = xrate / rate; | ||
970 | |||
971 | dev_dbg(dev, "external/rate = %ld/%ld\n", xrate, rate); | ||
972 | |||
973 | ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd); | ||
974 | if (ret < 0) | ||
975 | dev_err(dev, "%s failed", __func__); | ||
976 | |||
977 | return ret; | ||
978 | } | ||
979 | |||
980 | static int fsi_clk_set_rate_cpg(struct device *dev, | ||
981 | struct fsi_priv *fsi, | ||
982 | unsigned long rate) | ||
983 | { | ||
984 | struct clk *ick = fsi->clock.ick; | ||
985 | struct clk *div = fsi->clock.div; | ||
986 | unsigned long target = 0; /* 12288000 or 11289600 */ | ||
987 | unsigned long actual, cout; | ||
988 | unsigned long diff, min; | ||
989 | unsigned long best_cout, best_act; | ||
990 | int adj; | ||
991 | int ackmd, bpfmd; | ||
992 | int ret = -EINVAL; | ||
993 | |||
994 | if (!(12288000 % rate)) | ||
995 | target = 12288000; | ||
996 | if (!(11289600 % rate)) | ||
997 | target = 11289600; | ||
998 | if (!target) { | ||
999 | dev_err(dev, "unsupported rate\n"); | ||
1000 | return ret; | ||
1001 | } | ||
1002 | |||
1003 | bpfmd = fsi->chan_num * 32; | ||
1004 | ackmd = target / rate; | ||
1005 | ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd); | ||
1006 | if (ret < 0) { | ||
1007 | dev_err(dev, "%s failed", __func__); | ||
1008 | return ret; | ||
1009 | } | ||
1010 | |||
1011 | /* | ||
1012 | * The clock flow is | ||
1013 | * | ||
1014 | * [CPG] = cout => [FSI_DIV] = audio => [FSI] => [codec] | ||
1015 | * | ||
1016 | * But, it needs to find best match of CPG and FSI_DIV | ||
1017 | * combination, since it is difficult to generate correct | ||
1018 | * frequency of audio clock from ick clock only. | ||
1019 | * Because ick is created from its parent clock. | ||
1020 | * | ||
1021 | * target = rate x [512/256/128/64]fs | ||
1022 | * cout = round(target x adjustment) | ||
1023 | * actual = cout / adjustment (by FSI-DIV) ~= target | ||
1024 | * audio = actual | ||
1025 | */ | ||
1026 | min = ~0; | ||
1027 | best_cout = 0; | ||
1028 | best_act = 0; | ||
1029 | for (adj = 1; adj < 0xffff; adj++) { | ||
1030 | |||
1031 | cout = target * adj; | ||
1032 | if (cout > 100000000) /* max clock = 100MHz */ | ||
1033 | break; | ||
1034 | |||
1035 | /* cout/actual audio clock */ | ||
1036 | cout = clk_round_rate(ick, cout); | ||
1037 | actual = cout / adj; | ||
1038 | |||
1039 | /* find best frequency */ | ||
1040 | diff = abs(actual - target); | ||
1041 | if (diff < min) { | ||
1042 | min = diff; | ||
1043 | best_cout = cout; | ||
1044 | best_act = actual; | ||
1045 | } | ||
1046 | } | ||
1047 | |||
1048 | ret = clk_set_rate(ick, best_cout); | ||
1049 | if (ret < 0) { | ||
1050 | dev_err(dev, "ick clock failed\n"); | ||
1051 | return -EIO; | ||
1052 | } | ||
1053 | |||
1054 | ret = clk_set_rate(div, clk_round_rate(div, best_act)); | ||
1055 | if (ret < 0) { | ||
1056 | dev_err(dev, "div clock failed\n"); | ||
1057 | return -EIO; | ||
1058 | } | ||
1059 | |||
1060 | dev_dbg(dev, "ick/div = %ld/%ld\n", | ||
1061 | clk_get_rate(ick), clk_get_rate(div)); | ||
1062 | |||
1063 | return ret; | ||
1064 | } | ||
1065 | |||
720 | static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, | 1066 | static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, |
721 | long rate, int enable) | 1067 | long rate, int enable) |
722 | { | 1068 | { |
723 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); | 1069 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); |
724 | int ret; | 1070 | int ret; |
725 | 1071 | ||
726 | if (!set_rate) | 1072 | /* |
727 | return 0; | 1073 | * CAUTION |
1074 | * | ||
1075 | * set_rate will be deleted | ||
1076 | */ | ||
1077 | if (!set_rate) { | ||
1078 | if (enable) | ||
1079 | return fsi_clk_enable(dev, fsi, rate); | ||
1080 | else | ||
1081 | return fsi_clk_disable(dev, fsi); | ||
1082 | } | ||
728 | 1083 | ||
729 | ret = set_rate(dev, rate, enable); | 1084 | ret = set_rate(dev, rate, enable); |
730 | if (ret < 0) /* error */ | 1085 | if (ret < 0) /* error */ |
@@ -792,10 +1147,9 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, | |||
792 | */ | 1147 | */ |
793 | static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) | 1148 | static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) |
794 | { | 1149 | { |
795 | u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; | ||
796 | int i; | 1150 | int i; |
797 | 1151 | ||
798 | if (enable_stream) { | 1152 | if (fsi_is_enable_stream(fsi)) { |
799 | /* | 1153 | /* |
800 | * stream mode | 1154 | * stream mode |
801 | * see | 1155 | * see |
@@ -953,8 +1307,6 @@ static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, | |||
953 | 1307 | ||
954 | static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) | 1308 | static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) |
955 | { | 1309 | { |
956 | u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; | ||
957 | |||
958 | /* | 1310 | /* |
959 | * we can use 16bit stream mode | 1311 | * we can use 16bit stream mode |
960 | * when "playback" and "16bit data" | 1312 | * when "playback" and "16bit data" |
@@ -962,7 +1314,7 @@ static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) | |||
962 | * see | 1314 | * see |
963 | * fsi_pio_push16() | 1315 | * fsi_pio_push16() |
964 | */ | 1316 | */ |
965 | if (enable_stream) | 1317 | if (fsi_is_enable_stream(fsi)) |
966 | io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | | 1318 | io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | |
967 | BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); | 1319 | BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); |
968 | else | 1320 | else |
@@ -1296,6 +1648,16 @@ static int fsi_hw_startup(struct fsi_priv *fsi, | |||
1296 | 1648 | ||
1297 | /* clock inversion (CKG2) */ | 1649 | /* clock inversion (CKG2) */ |
1298 | data = 0; | 1650 | data = 0; |
1651 | if (fsi->bit_clk_inv) | ||
1652 | data |= (1 << 0); | ||
1653 | if (fsi->lr_clk_inv) | ||
1654 | data |= (1 << 4); | ||
1655 | if (fsi_is_clk_master(fsi)) | ||
1656 | data <<= 8; | ||
1657 | /* FIXME | ||
1658 | * | ||
1659 | * SH_FSI_xxx_INV style will be removed | ||
1660 | */ | ||
1299 | if (SH_FSI_LRM_INV & flags) | 1661 | if (SH_FSI_LRM_INV & flags) |
1300 | data |= 1 << 12; | 1662 | data |= 1 << 12; |
1301 | if (SH_FSI_BRM_INV & flags) | 1663 | if (SH_FSI_BRM_INV & flags) |
@@ -1334,14 +1696,21 @@ static int fsi_hw_startup(struct fsi_priv *fsi, | |||
1334 | /* fifo init */ | 1696 | /* fifo init */ |
1335 | fsi_fifo_init(fsi, io, dev); | 1697 | fsi_fifo_init(fsi, io, dev); |
1336 | 1698 | ||
1699 | /* start master clock */ | ||
1700 | if (fsi_is_clk_master(fsi)) | ||
1701 | return fsi_set_master_clk(dev, fsi, fsi->rate, 1); | ||
1702 | |||
1337 | return 0; | 1703 | return 0; |
1338 | } | 1704 | } |
1339 | 1705 | ||
1340 | static void fsi_hw_shutdown(struct fsi_priv *fsi, | 1706 | static int fsi_hw_shutdown(struct fsi_priv *fsi, |
1341 | struct device *dev) | 1707 | struct device *dev) |
1342 | { | 1708 | { |
1709 | /* stop master clock */ | ||
1343 | if (fsi_is_clk_master(fsi)) | 1710 | if (fsi_is_clk_master(fsi)) |
1344 | fsi_set_master_clk(dev, fsi, fsi->rate, 0); | 1711 | return fsi_set_master_clk(dev, fsi, fsi->rate, 0); |
1712 | |||
1713 | return 0; | ||
1345 | } | 1714 | } |
1346 | 1715 | ||
1347 | static int fsi_dai_startup(struct snd_pcm_substream *substream, | 1716 | static int fsi_dai_startup(struct snd_pcm_substream *substream, |
@@ -1349,6 +1718,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
1349 | { | 1718 | { |
1350 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1719 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1351 | 1720 | ||
1721 | fsi_clk_invalid(fsi); | ||
1352 | fsi->rate = 0; | 1722 | fsi->rate = 0; |
1353 | 1723 | ||
1354 | return 0; | 1724 | return 0; |
@@ -1359,6 +1729,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream, | |||
1359 | { | 1729 | { |
1360 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1730 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1361 | 1731 | ||
1732 | fsi_clk_invalid(fsi); | ||
1362 | fsi->rate = 0; | 1733 | fsi->rate = 0; |
1363 | } | 1734 | } |
1364 | 1735 | ||
@@ -1372,13 +1743,16 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1372 | switch (cmd) { | 1743 | switch (cmd) { |
1373 | case SNDRV_PCM_TRIGGER_START: | 1744 | case SNDRV_PCM_TRIGGER_START: |
1374 | fsi_stream_init(fsi, io, substream); | 1745 | fsi_stream_init(fsi, io, substream); |
1375 | fsi_hw_startup(fsi, io, dai->dev); | 1746 | if (!ret) |
1376 | ret = fsi_stream_transfer(io); | 1747 | ret = fsi_hw_startup(fsi, io, dai->dev); |
1377 | if (0 == ret) | 1748 | if (!ret) |
1749 | ret = fsi_stream_transfer(io); | ||
1750 | if (!ret) | ||
1378 | fsi_stream_start(fsi, io); | 1751 | fsi_stream_start(fsi, io); |
1379 | break; | 1752 | break; |
1380 | case SNDRV_PCM_TRIGGER_STOP: | 1753 | case SNDRV_PCM_TRIGGER_STOP: |
1381 | fsi_hw_shutdown(fsi, dai->dev); | 1754 | if (!ret) |
1755 | ret = fsi_hw_shutdown(fsi, dai->dev); | ||
1382 | fsi_stream_stop(fsi, io); | 1756 | fsi_stream_stop(fsi, io); |
1383 | fsi_stream_quit(fsi, io); | 1757 | fsi_stream_quit(fsi, io); |
1384 | break; | 1758 | break; |
@@ -1414,7 +1788,6 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi) | |||
1414 | 1788 | ||
1415 | fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM; | 1789 | fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM; |
1416 | fsi->chan_num = 2; | 1790 | fsi->chan_num = 2; |
1417 | fsi->spdif = 1; | ||
1418 | 1791 | ||
1419 | return 0; | 1792 | return 0; |
1420 | } | 1793 | } |
@@ -1423,7 +1796,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
1423 | { | 1796 | { |
1424 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); | 1797 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); |
1425 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); | 1798 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); |
1426 | u32 flags = fsi_get_info_flags(fsi); | ||
1427 | int ret; | 1799 | int ret; |
1428 | 1800 | ||
1429 | /* set master/slave audio interface */ | 1801 | /* set master/slave audio interface */ |
@@ -1437,23 +1809,50 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
1437 | return -EINVAL; | 1809 | return -EINVAL; |
1438 | } | 1810 | } |
1439 | 1811 | ||
1440 | if (fsi_is_clk_master(fsi) && !set_rate) { | 1812 | /* set clock inversion */ |
1441 | dev_err(dai->dev, "platform doesn't have set_rate\n"); | 1813 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
1442 | return -EINVAL; | 1814 | case SND_SOC_DAIFMT_NB_IF: |
1443 | } | 1815 | fsi->bit_clk_inv = 0; |
1444 | 1816 | fsi->lr_clk_inv = 1; | |
1445 | /* set format */ | ||
1446 | switch (flags & SH_FSI_FMT_MASK) { | ||
1447 | case SH_FSI_FMT_DAI: | ||
1448 | ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
1449 | break; | 1817 | break; |
1450 | case SH_FSI_FMT_SPDIF: | 1818 | case SND_SOC_DAIFMT_IB_NF: |
1451 | ret = fsi_set_fmt_spdif(fsi); | 1819 | fsi->bit_clk_inv = 1; |
1820 | fsi->lr_clk_inv = 0; | ||
1452 | break; | 1821 | break; |
1822 | case SND_SOC_DAIFMT_IB_IF: | ||
1823 | fsi->bit_clk_inv = 1; | ||
1824 | fsi->lr_clk_inv = 1; | ||
1825 | break; | ||
1826 | case SND_SOC_DAIFMT_NB_NF: | ||
1453 | default: | 1827 | default: |
1454 | ret = -EINVAL; | 1828 | fsi->bit_clk_inv = 0; |
1829 | fsi->lr_clk_inv = 0; | ||
1830 | break; | ||
1831 | } | ||
1832 | |||
1833 | if (fsi_is_clk_master(fsi)) { | ||
1834 | /* | ||
1835 | * CAUTION | ||
1836 | * | ||
1837 | * set_rate will be deleted | ||
1838 | */ | ||
1839 | if (set_rate) | ||
1840 | dev_warn(dai->dev, "set_rate will be removed soon\n"); | ||
1841 | |||
1842 | if (fsi->clk_cpg) | ||
1843 | fsi_clk_init(dai->dev, fsi, 0, 1, 1, | ||
1844 | fsi_clk_set_rate_cpg); | ||
1845 | else | ||
1846 | fsi_clk_init(dai->dev, fsi, 1, 1, 0, | ||
1847 | fsi_clk_set_rate_external); | ||
1455 | } | 1848 | } |
1456 | 1849 | ||
1850 | /* set format */ | ||
1851 | if (fsi_is_spdif(fsi)) | ||
1852 | ret = fsi_set_fmt_spdif(fsi); | ||
1853 | else | ||
1854 | ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
1855 | |||
1457 | return ret; | 1856 | return ret; |
1458 | } | 1857 | } |
1459 | 1858 | ||
@@ -1462,19 +1861,13 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream, | |||
1462 | struct snd_soc_dai *dai) | 1861 | struct snd_soc_dai *dai) |
1463 | { | 1862 | { |
1464 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1863 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1465 | long rate = params_rate(params); | ||
1466 | int ret; | ||
1467 | 1864 | ||
1468 | if (!fsi_is_clk_master(fsi)) | 1865 | if (fsi_is_clk_master(fsi)) { |
1469 | return 0; | 1866 | fsi->rate = params_rate(params); |
1470 | 1867 | fsi_clk_valid(fsi, fsi->rate); | |
1471 | ret = fsi_set_master_clk(dai->dev, fsi, rate, 1); | 1868 | } |
1472 | if (ret < 0) | ||
1473 | return ret; | ||
1474 | |||
1475 | fsi->rate = rate; | ||
1476 | 1869 | ||
1477 | return ret; | 1870 | return 0; |
1478 | } | 1871 | } |
1479 | 1872 | ||
1480 | static const struct snd_soc_dai_ops fsi_dai_ops = { | 1873 | static const struct snd_soc_dai_ops fsi_dai_ops = { |
@@ -1498,7 +1891,7 @@ static struct snd_pcm_hardware fsi_pcm_hardware = { | |||
1498 | .rates = FSI_RATES, | 1891 | .rates = FSI_RATES, |
1499 | .rate_min = 8000, | 1892 | .rate_min = 8000, |
1500 | .rate_max = 192000, | 1893 | .rate_max = 192000, |
1501 | .channels_min = 1, | 1894 | .channels_min = 2, |
1502 | .channels_max = 2, | 1895 | .channels_max = 2, |
1503 | .buffer_bytes_max = 64 * 1024, | 1896 | .buffer_bytes_max = 64 * 1024, |
1504 | .period_bytes_min = 32, | 1897 | .period_bytes_min = 32, |
@@ -1586,14 +1979,14 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { | |||
1586 | .playback = { | 1979 | .playback = { |
1587 | .rates = FSI_RATES, | 1980 | .rates = FSI_RATES, |
1588 | .formats = FSI_FMTS, | 1981 | .formats = FSI_FMTS, |
1589 | .channels_min = 1, | 1982 | .channels_min = 2, |
1590 | .channels_max = 8, | 1983 | .channels_max = 2, |
1591 | }, | 1984 | }, |
1592 | .capture = { | 1985 | .capture = { |
1593 | .rates = FSI_RATES, | 1986 | .rates = FSI_RATES, |
1594 | .formats = FSI_FMTS, | 1987 | .formats = FSI_FMTS, |
1595 | .channels_min = 1, | 1988 | .channels_min = 2, |
1596 | .channels_max = 8, | 1989 | .channels_max = 2, |
1597 | }, | 1990 | }, |
1598 | .ops = &fsi_dai_ops, | 1991 | .ops = &fsi_dai_ops, |
1599 | }, | 1992 | }, |
@@ -1602,14 +1995,14 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { | |||
1602 | .playback = { | 1995 | .playback = { |
1603 | .rates = FSI_RATES, | 1996 | .rates = FSI_RATES, |
1604 | .formats = FSI_FMTS, | 1997 | .formats = FSI_FMTS, |
1605 | .channels_min = 1, | 1998 | .channels_min = 2, |
1606 | .channels_max = 8, | 1999 | .channels_max = 2, |
1607 | }, | 2000 | }, |
1608 | .capture = { | 2001 | .capture = { |
1609 | .rates = FSI_RATES, | 2002 | .rates = FSI_RATES, |
1610 | .formats = FSI_FMTS, | 2003 | .formats = FSI_FMTS, |
1611 | .channels_min = 1, | 2004 | .channels_min = 2, |
1612 | .channels_max = 8, | 2005 | .channels_max = 2, |
1613 | }, | 2006 | }, |
1614 | .ops = &fsi_dai_ops, | 2007 | .ops = &fsi_dai_ops, |
1615 | }, | 2008 | }, |
@@ -1624,15 +2017,29 @@ static struct snd_soc_platform_driver fsi_soc_platform = { | |||
1624 | /* | 2017 | /* |
1625 | * platform function | 2018 | * platform function |
1626 | */ | 2019 | */ |
1627 | static void fsi_handler_init(struct fsi_priv *fsi) | 2020 | static void fsi_port_info_init(struct fsi_priv *fsi, |
2021 | struct sh_fsi_port_info *info) | ||
2022 | { | ||
2023 | if (info->flags & SH_FSI_FMT_SPDIF) | ||
2024 | fsi->spdif = 1; | ||
2025 | |||
2026 | if (info->flags & SH_FSI_CLK_CPG) | ||
2027 | fsi->clk_cpg = 1; | ||
2028 | |||
2029 | if (info->flags & SH_FSI_ENABLE_STREAM_MODE) | ||
2030 | fsi->enable_stream = 1; | ||
2031 | } | ||
2032 | |||
2033 | static void fsi_handler_init(struct fsi_priv *fsi, | ||
2034 | struct sh_fsi_port_info *info) | ||
1628 | { | 2035 | { |
1629 | fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */ | 2036 | fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */ |
1630 | fsi->playback.priv = fsi; | 2037 | fsi->playback.priv = fsi; |
1631 | fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */ | 2038 | fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */ |
1632 | fsi->capture.priv = fsi; | 2039 | fsi->capture.priv = fsi; |
1633 | 2040 | ||
1634 | if (fsi->info->tx_id) { | 2041 | if (info->tx_id) { |
1635 | fsi->playback.slave.shdma_slave.slave_id = fsi->info->tx_id; | 2042 | fsi->playback.slave.shdma_slave.slave_id = info->tx_id; |
1636 | fsi->playback.handler = &fsi_dma_push_handler; | 2043 | fsi->playback.handler = &fsi_dma_push_handler; |
1637 | } | 2044 | } |
1638 | } | 2045 | } |
@@ -1642,10 +2049,16 @@ static int fsi_probe(struct platform_device *pdev) | |||
1642 | struct fsi_master *master; | 2049 | struct fsi_master *master; |
1643 | const struct platform_device_id *id_entry; | 2050 | const struct platform_device_id *id_entry; |
1644 | struct sh_fsi_platform_info *info = pdev->dev.platform_data; | 2051 | struct sh_fsi_platform_info *info = pdev->dev.platform_data; |
2052 | struct sh_fsi_port_info nul_info, *pinfo; | ||
2053 | struct fsi_priv *fsi; | ||
1645 | struct resource *res; | 2054 | struct resource *res; |
1646 | unsigned int irq; | 2055 | unsigned int irq; |
1647 | int ret; | 2056 | int ret; |
1648 | 2057 | ||
2058 | nul_info.flags = 0; | ||
2059 | nul_info.tx_id = 0; | ||
2060 | nul_info.rx_id = 0; | ||
2061 | |||
1649 | id_entry = pdev->id_entry; | 2062 | id_entry = pdev->id_entry; |
1650 | if (!id_entry) { | 2063 | if (!id_entry) { |
1651 | dev_err(&pdev->dev, "unknown fsi device\n"); | 2064 | dev_err(&pdev->dev, "unknown fsi device\n"); |
@@ -1678,22 +2091,28 @@ static int fsi_probe(struct platform_device *pdev) | |||
1678 | spin_lock_init(&master->lock); | 2091 | spin_lock_init(&master->lock); |
1679 | 2092 | ||
1680 | /* FSI A setting */ | 2093 | /* FSI A setting */ |
1681 | master->fsia.base = master->base; | 2094 | pinfo = (info) ? &info->port_a : &nul_info; |
1682 | master->fsia.master = master; | 2095 | fsi = &master->fsia; |
1683 | master->fsia.info = &info->port_a; | 2096 | fsi->base = master->base; |
1684 | fsi_handler_init(&master->fsia); | 2097 | fsi->master = master; |
1685 | ret = fsi_stream_probe(&master->fsia, &pdev->dev); | 2098 | fsi->info = pinfo; |
2099 | fsi_port_info_init(fsi, pinfo); | ||
2100 | fsi_handler_init(fsi, pinfo); | ||
2101 | ret = fsi_stream_probe(fsi, &pdev->dev); | ||
1686 | if (ret < 0) { | 2102 | if (ret < 0) { |
1687 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); | 2103 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); |
1688 | return ret; | 2104 | return ret; |
1689 | } | 2105 | } |
1690 | 2106 | ||
1691 | /* FSI B setting */ | 2107 | /* FSI B setting */ |
1692 | master->fsib.base = master->base + 0x40; | 2108 | pinfo = (info) ? &info->port_b : &nul_info; |
1693 | master->fsib.master = master; | 2109 | fsi = &master->fsib; |
1694 | master->fsib.info = &info->port_b; | 2110 | fsi->base = master->base + 0x40; |
1695 | fsi_handler_init(&master->fsib); | 2111 | fsi->master = master; |
1696 | ret = fsi_stream_probe(&master->fsib, &pdev->dev); | 2112 | fsi->info = pinfo; |
2113 | fsi_port_info_init(fsi, pinfo); | ||
2114 | fsi_handler_init(fsi, pinfo); | ||
2115 | ret = fsi_stream_probe(fsi, &pdev->dev); | ||
1697 | if (ret < 0) { | 2116 | if (ret < 0) { |
1698 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); | 2117 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); |
1699 | goto exit_fsia; | 2118 | goto exit_fsia; |
@@ -1702,7 +2121,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1702 | pm_runtime_enable(&pdev->dev); | 2121 | pm_runtime_enable(&pdev->dev); |
1703 | dev_set_drvdata(&pdev->dev, master); | 2122 | dev_set_drvdata(&pdev->dev, master); |
1704 | 2123 | ||
1705 | ret = request_irq(irq, &fsi_interrupt, 0, | 2124 | ret = devm_request_irq(&pdev->dev, irq, &fsi_interrupt, 0, |
1706 | id_entry->name, master); | 2125 | id_entry->name, master); |
1707 | if (ret) { | 2126 | if (ret) { |
1708 | dev_err(&pdev->dev, "irq request err\n"); | 2127 | dev_err(&pdev->dev, "irq request err\n"); |
@@ -1712,7 +2131,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1712 | ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); | 2131 | ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); |
1713 | if (ret < 0) { | 2132 | if (ret < 0) { |
1714 | dev_err(&pdev->dev, "cannot snd soc register\n"); | 2133 | dev_err(&pdev->dev, "cannot snd soc register\n"); |
1715 | goto exit_free_irq; | 2134 | goto exit_fsib; |
1716 | } | 2135 | } |
1717 | 2136 | ||
1718 | ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai, | 2137 | ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai, |
@@ -1726,8 +2145,6 @@ static int fsi_probe(struct platform_device *pdev) | |||
1726 | 2145 | ||
1727 | exit_snd_soc: | 2146 | exit_snd_soc: |
1728 | snd_soc_unregister_platform(&pdev->dev); | 2147 | snd_soc_unregister_platform(&pdev->dev); |
1729 | exit_free_irq: | ||
1730 | free_irq(irq, master); | ||
1731 | exit_fsib: | 2148 | exit_fsib: |
1732 | pm_runtime_disable(&pdev->dev); | 2149 | pm_runtime_disable(&pdev->dev); |
1733 | fsi_stream_remove(&master->fsib); | 2150 | fsi_stream_remove(&master->fsib); |
@@ -1743,7 +2160,6 @@ static int fsi_remove(struct platform_device *pdev) | |||
1743 | 2160 | ||
1744 | master = dev_get_drvdata(&pdev->dev); | 2161 | master = dev_get_drvdata(&pdev->dev); |
1745 | 2162 | ||
1746 | free_irq(master->irq, master); | ||
1747 | pm_runtime_disable(&pdev->dev); | 2163 | pm_runtime_disable(&pdev->dev); |
1748 | 2164 | ||
1749 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); | 2165 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); |
@@ -1774,10 +2190,6 @@ static void __fsi_resume(struct fsi_priv *fsi, | |||
1774 | return; | 2190 | return; |
1775 | 2191 | ||
1776 | fsi_hw_startup(fsi, io, dev); | 2192 | fsi_hw_startup(fsi, io, dev); |
1777 | |||
1778 | if (fsi_is_clk_master(fsi) && fsi->rate) | ||
1779 | fsi_set_master_clk(dev, fsi, fsi->rate, 1); | ||
1780 | |||
1781 | fsi_stream_start(fsi, io); | 2193 | fsi_stream_start(fsi, io); |
1782 | } | 2194 | } |
1783 | 2195 | ||
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 9d56f0218f41..e72f55428f0b 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
@@ -88,7 +88,7 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) | |||
88 | ret = snd_soc_write(codec, i, val); | 88 | ret = snd_soc_write(codec, i, val); |
89 | if (ret) | 89 | if (ret) |
90 | return ret; | 90 | return ret; |
91 | dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", | 91 | dev_dbg(codec->dev, "ASoC: Synced register %#x, value = %#x\n", |
92 | i, val); | 92 | i, val); |
93 | } | 93 | } |
94 | return 0; | 94 | return 0; |
@@ -156,7 +156,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) | |||
156 | 156 | ||
157 | /* Fall back to flat compression */ | 157 | /* Fall back to flat compression */ |
158 | if (i == ARRAY_SIZE(cache_types)) { | 158 | if (i == ARRAY_SIZE(cache_types)) { |
159 | dev_warn(codec->dev, "Could not match compress type: %d\n", | 159 | dev_warn(codec->dev, "ASoC: Could not match compress type: %d\n", |
160 | codec->compress_type); | 160 | codec->compress_type); |
161 | i = 0; | 161 | i = 0; |
162 | } | 162 | } |
@@ -166,7 +166,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) | |||
166 | 166 | ||
167 | if (codec->cache_ops->init) { | 167 | if (codec->cache_ops->init) { |
168 | if (codec->cache_ops->name) | 168 | if (codec->cache_ops->name) |
169 | dev_dbg(codec->dev, "Initializing %s cache for %s codec\n", | 169 | dev_dbg(codec->dev, "ASoC: Initializing %s cache for %s codec\n", |
170 | codec->cache_ops->name, codec->name); | 170 | codec->cache_ops->name, codec->name); |
171 | return codec->cache_ops->init(codec); | 171 | return codec->cache_ops->init(codec); |
172 | } | 172 | } |
@@ -181,7 +181,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec) | |||
181 | { | 181 | { |
182 | if (codec->cache_ops && codec->cache_ops->exit) { | 182 | if (codec->cache_ops && codec->cache_ops->exit) { |
183 | if (codec->cache_ops->name) | 183 | if (codec->cache_ops->name) |
184 | dev_dbg(codec->dev, "Destroying %s cache for %s codec\n", | 184 | dev_dbg(codec->dev, "ASoC: Destroying %s cache for %s codec\n", |
185 | codec->cache_ops->name, codec->name); | 185 | codec->cache_ops->name, codec->name); |
186 | return codec->cache_ops->exit(codec); | 186 | return codec->cache_ops->exit(codec); |
187 | } | 187 | } |
@@ -265,7 +265,7 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec) | |||
265 | name = "unknown"; | 265 | name = "unknown"; |
266 | 266 | ||
267 | if (codec->cache_ops->name) | 267 | if (codec->cache_ops->name) |
268 | dev_dbg(codec->dev, "Syncing %s cache for %s codec\n", | 268 | dev_dbg(codec->dev, "ASoC: Syncing %s cache for %s codec\n", |
269 | codec->cache_ops->name, codec->name); | 269 | codec->cache_ops->name, codec->name); |
270 | trace_snd_soc_cache_sync(codec, name, "start"); | 270 | trace_snd_soc_cache_sync(codec, name, "start"); |
271 | ret = codec->cache_ops->sync(codec); | 271 | ret = codec->cache_ops->sync(codec); |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 10d21be383f6..9c768bcb98a6 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -271,7 +271,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec) | |||
271 | codec->debugfs_codec_root = debugfs_create_dir(codec->name, | 271 | codec->debugfs_codec_root = debugfs_create_dir(codec->name, |
272 | debugfs_card_root); | 272 | debugfs_card_root); |
273 | if (!codec->debugfs_codec_root) { | 273 | if (!codec->debugfs_codec_root) { |
274 | dev_warn(codec->dev, "Failed to create codec debugfs directory\n"); | 274 | dev_warn(codec->dev, "ASoC: Failed to create codec debugfs" |
275 | " directory\n"); | ||
275 | return; | 276 | return; |
276 | } | 277 | } |
277 | 278 | ||
@@ -284,7 +285,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec) | |||
284 | codec->debugfs_codec_root, | 285 | codec->debugfs_codec_root, |
285 | codec, &codec_reg_fops); | 286 | codec, &codec_reg_fops); |
286 | if (!codec->debugfs_reg) | 287 | if (!codec->debugfs_reg) |
287 | dev_warn(codec->dev, "Failed to create codec register debugfs file\n"); | 288 | dev_warn(codec->dev, "ASoC: Failed to create codec register" |
289 | " debugfs file\n"); | ||
288 | 290 | ||
289 | snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root); | 291 | snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root); |
290 | } | 292 | } |
@@ -302,7 +304,7 @@ static void soc_init_platform_debugfs(struct snd_soc_platform *platform) | |||
302 | debugfs_card_root); | 304 | debugfs_card_root); |
303 | if (!platform->debugfs_platform_root) { | 305 | if (!platform->debugfs_platform_root) { |
304 | dev_warn(platform->dev, | 306 | dev_warn(platform->dev, |
305 | "Failed to create platform debugfs directory\n"); | 307 | "ASoC: Failed to create platform debugfs directory\n"); |
306 | return; | 308 | return; |
307 | } | 309 | } |
308 | 310 | ||
@@ -430,7 +432,7 @@ static void soc_init_card_debugfs(struct snd_soc_card *card) | |||
430 | &card->pop_time); | 432 | &card->pop_time); |
431 | if (!card->debugfs_pop_time) | 433 | if (!card->debugfs_pop_time) |
432 | dev_warn(card->dev, | 434 | dev_warn(card->dev, |
433 | "Failed to create pop time debugfs file\n"); | 435 | "ASoC: Failed to create pop time debugfs file\n"); |
434 | } | 436 | } |
435 | 437 | ||
436 | static void soc_cleanup_card_debugfs(struct snd_soc_card *card) | 438 | static void soc_cleanup_card_debugfs(struct snd_soc_card *card) |
@@ -475,7 +477,7 @@ struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, | |||
475 | !strcmp(card->rtd[i].dai_link->name, dai_link)) | 477 | !strcmp(card->rtd[i].dai_link->name, dai_link)) |
476 | return card->rtd[i].pcm->streams[stream].substream; | 478 | return card->rtd[i].pcm->streams[stream].substream; |
477 | } | 479 | } |
478 | dev_dbg(card->dev, "failed to find dai link %s\n", dai_link); | 480 | dev_dbg(card->dev, "ASoC: failed to find dai link %s\n", dai_link); |
479 | return NULL; | 481 | return NULL; |
480 | } | 482 | } |
481 | EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream); | 483 | EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream); |
@@ -489,7 +491,7 @@ struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, | |||
489 | if (!strcmp(card->rtd[i].dai_link->name, dai_link)) | 491 | if (!strcmp(card->rtd[i].dai_link->name, dai_link)) |
490 | return &card->rtd[i]; | 492 | return &card->rtd[i]; |
491 | } | 493 | } |
492 | dev_dbg(card->dev, "failed to find rtd %s\n", dai_link); | 494 | dev_dbg(card->dev, "ASoC: failed to find rtd %s\n", dai_link); |
493 | return NULL; | 495 | return NULL; |
494 | } | 496 | } |
495 | EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime); | 497 | EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime); |
@@ -519,7 +521,7 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec) | |||
519 | codec->card->snd_card->number, 0, codec->name); | 521 | codec->card->snd_card->number, 0, codec->name); |
520 | err = device_register(&codec->ac97->dev); | 522 | err = device_register(&codec->ac97->dev); |
521 | if (err < 0) { | 523 | if (err < 0) { |
522 | snd_printk(KERN_ERR "Can't register ac97 bus\n"); | 524 | dev_err(codec->dev, "ASoC: Can't register ac97 bus\n"); |
523 | codec->ac97->dev.bus = NULL; | 525 | codec->ac97->dev.bus = NULL; |
524 | return err; | 526 | return err; |
525 | } | 527 | } |
@@ -628,7 +630,8 @@ int snd_soc_suspend(struct device *dev) | |||
628 | */ | 630 | */ |
629 | if (codec->dapm.idle_bias_off) { | 631 | if (codec->dapm.idle_bias_off) { |
630 | dev_dbg(codec->dev, | 632 | dev_dbg(codec->dev, |
631 | "idle_bias_off CODEC on over suspend\n"); | 633 | "ASoC: idle_bias_off CODEC on" |
634 | " over suspend\n"); | ||
632 | break; | 635 | break; |
633 | } | 636 | } |
634 | case SND_SOC_BIAS_OFF: | 637 | case SND_SOC_BIAS_OFF: |
@@ -639,7 +642,8 @@ int snd_soc_suspend(struct device *dev) | |||
639 | regcache_mark_dirty(codec->control_data); | 642 | regcache_mark_dirty(codec->control_data); |
640 | break; | 643 | break; |
641 | default: | 644 | default: |
642 | dev_dbg(codec->dev, "CODEC is on over suspend\n"); | 645 | dev_dbg(codec->dev, "ASoC: CODEC is on" |
646 | " over suspend\n"); | ||
643 | break; | 647 | break; |
644 | } | 648 | } |
645 | } | 649 | } |
@@ -676,7 +680,7 @@ static void soc_resume_deferred(struct work_struct *work) | |||
676 | * so userspace apps are blocked from touching us | 680 | * so userspace apps are blocked from touching us |
677 | */ | 681 | */ |
678 | 682 | ||
679 | dev_dbg(card->dev, "starting resume work\n"); | 683 | dev_dbg(card->dev, "ASoC: starting resume work\n"); |
680 | 684 | ||
681 | /* Bring us up into D2 so that DAPM starts enabling things */ | 685 | /* Bring us up into D2 so that DAPM starts enabling things */ |
682 | snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2); | 686 | snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2); |
@@ -708,7 +712,8 @@ static void soc_resume_deferred(struct work_struct *work) | |||
708 | codec->suspended = 0; | 712 | codec->suspended = 0; |
709 | break; | 713 | break; |
710 | default: | 714 | default: |
711 | dev_dbg(codec->dev, "CODEC was on over suspend\n"); | 715 | dev_dbg(codec->dev, "ASoC: CODEC was on over" |
716 | " suspend\n"); | ||
712 | break; | 717 | break; |
713 | } | 718 | } |
714 | } | 719 | } |
@@ -758,7 +763,7 @@ static void soc_resume_deferred(struct work_struct *work) | |||
758 | if (card->resume_post) | 763 | if (card->resume_post) |
759 | card->resume_post(card); | 764 | card->resume_post(card); |
760 | 765 | ||
761 | dev_dbg(card->dev, "resume work completed\n"); | 766 | dev_dbg(card->dev, "ASoC: resume work completed\n"); |
762 | 767 | ||
763 | /* userspace can access us now we are back as we were before */ | 768 | /* userspace can access us now we are back as we were before */ |
764 | snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); | 769 | snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); |
@@ -790,12 +795,12 @@ int snd_soc_resume(struct device *dev) | |||
790 | ac97_control |= cpu_dai->driver->ac97_control; | 795 | ac97_control |= cpu_dai->driver->ac97_control; |
791 | } | 796 | } |
792 | if (ac97_control) { | 797 | if (ac97_control) { |
793 | dev_dbg(dev, "Resuming AC97 immediately\n"); | 798 | dev_dbg(dev, "ASoC: Resuming AC97 immediately\n"); |
794 | soc_resume_deferred(&card->deferred_resume_work); | 799 | soc_resume_deferred(&card->deferred_resume_work); |
795 | } else { | 800 | } else { |
796 | dev_dbg(dev, "Scheduling resume work\n"); | 801 | dev_dbg(dev, "ASoC: Scheduling resume work\n"); |
797 | if (!schedule_work(&card->deferred_resume_work)) | 802 | if (!schedule_work(&card->deferred_resume_work)) |
798 | dev_err(dev, "resume work item may be lost\n"); | 803 | dev_err(dev, "ASoC: resume work item may be lost\n"); |
799 | } | 804 | } |
800 | 805 | ||
801 | return 0; | 806 | return 0; |
@@ -818,7 +823,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
818 | struct snd_soc_dai *codec_dai, *cpu_dai; | 823 | struct snd_soc_dai *codec_dai, *cpu_dai; |
819 | const char *platform_name; | 824 | const char *platform_name; |
820 | 825 | ||
821 | dev_dbg(card->dev, "binding %s at idx %d\n", dai_link->name, num); | 826 | dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); |
822 | 827 | ||
823 | /* Find CPU DAI from registered DAIs*/ | 828 | /* Find CPU DAI from registered DAIs*/ |
824 | list_for_each_entry(cpu_dai, &dai_list, list) { | 829 | list_for_each_entry(cpu_dai, &dai_list, list) { |
@@ -836,7 +841,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
836 | } | 841 | } |
837 | 842 | ||
838 | if (!rtd->cpu_dai) { | 843 | if (!rtd->cpu_dai) { |
839 | dev_err(card->dev, "CPU DAI %s not registered\n", | 844 | dev_err(card->dev, "ASoC: CPU DAI %s not registered\n", |
840 | dai_link->cpu_dai_name); | 845 | dai_link->cpu_dai_name); |
841 | return -EPROBE_DEFER; | 846 | return -EPROBE_DEFER; |
842 | } | 847 | } |
@@ -867,14 +872,14 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
867 | } | 872 | } |
868 | 873 | ||
869 | if (!rtd->codec_dai) { | 874 | if (!rtd->codec_dai) { |
870 | dev_err(card->dev, "CODEC DAI %s not registered\n", | 875 | dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", |
871 | dai_link->codec_dai_name); | 876 | dai_link->codec_dai_name); |
872 | return -EPROBE_DEFER; | 877 | return -EPROBE_DEFER; |
873 | } | 878 | } |
874 | } | 879 | } |
875 | 880 | ||
876 | if (!rtd->codec) { | 881 | if (!rtd->codec) { |
877 | dev_err(card->dev, "CODEC %s not registered\n", | 882 | dev_err(card->dev, "ASoC: CODEC %s not registered\n", |
878 | dai_link->codec_name); | 883 | dai_link->codec_name); |
879 | return -EPROBE_DEFER; | 884 | return -EPROBE_DEFER; |
880 | } | 885 | } |
@@ -898,7 +903,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
898 | rtd->platform = platform; | 903 | rtd->platform = platform; |
899 | } | 904 | } |
900 | if (!rtd->platform) { | 905 | if (!rtd->platform) { |
901 | dev_err(card->dev, "platform %s not registered\n", | 906 | dev_err(card->dev, "ASoC: platform %s not registered\n", |
902 | dai_link->platform_name); | 907 | dai_link->platform_name); |
903 | return -EPROBE_DEFER; | 908 | return -EPROBE_DEFER; |
904 | } | 909 | } |
@@ -915,8 +920,8 @@ static int soc_remove_platform(struct snd_soc_platform *platform) | |||
915 | if (platform->driver->remove) { | 920 | if (platform->driver->remove) { |
916 | ret = platform->driver->remove(platform); | 921 | ret = platform->driver->remove(platform); |
917 | if (ret < 0) | 922 | if (ret < 0) |
918 | pr_err("asoc: failed to remove %s: %d\n", | 923 | dev_err(platform->dev, "ASoC: failed to remove %d\n", |
919 | platform->name, ret); | 924 | ret); |
920 | } | 925 | } |
921 | 926 | ||
922 | /* Make sure all DAPM widgets are freed */ | 927 | /* Make sure all DAPM widgets are freed */ |
@@ -937,9 +942,7 @@ static void soc_remove_codec(struct snd_soc_codec *codec) | |||
937 | if (codec->driver->remove) { | 942 | if (codec->driver->remove) { |
938 | err = codec->driver->remove(codec); | 943 | err = codec->driver->remove(codec); |
939 | if (err < 0) | 944 | if (err < 0) |
940 | dev_err(codec->dev, | 945 | dev_err(codec->dev, "ASoC: failed to remove %d\n", err); |
941 | "asoc: failed to remove %s: %d\n", | ||
942 | codec->name, err); | ||
943 | } | 946 | } |
944 | 947 | ||
945 | /* Make sure all DAPM widgets are freed */ | 948 | /* Make sure all DAPM widgets are freed */ |
@@ -971,8 +974,9 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) | |||
971 | if (codec_dai->driver->remove) { | 974 | if (codec_dai->driver->remove) { |
972 | err = codec_dai->driver->remove(codec_dai); | 975 | err = codec_dai->driver->remove(codec_dai); |
973 | if (err < 0) | 976 | if (err < 0) |
974 | pr_err("asoc: failed to remove %s: %d\n", | 977 | dev_err(codec_dai->dev, |
975 | codec_dai->name, err); | 978 | "ASoC: failed to remove %s: %d\n", |
979 | codec_dai->name, err); | ||
976 | } | 980 | } |
977 | codec_dai->probed = 0; | 981 | codec_dai->probed = 0; |
978 | list_del(&codec_dai->card_list); | 982 | list_del(&codec_dai->card_list); |
@@ -984,8 +988,9 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) | |||
984 | if (cpu_dai->driver->remove) { | 988 | if (cpu_dai->driver->remove) { |
985 | err = cpu_dai->driver->remove(cpu_dai); | 989 | err = cpu_dai->driver->remove(cpu_dai); |
986 | if (err < 0) | 990 | if (err < 0) |
987 | pr_err("asoc: failed to remove %s: %d\n", | 991 | dev_err(cpu_dai->dev, |
988 | cpu_dai->name, err); | 992 | "ASoC: failed to remove %s: %d\n", |
993 | cpu_dai->name, err); | ||
989 | } | 994 | } |
990 | cpu_dai->probed = 0; | 995 | cpu_dai->probed = 0; |
991 | list_del(&cpu_dai->card_list); | 996 | list_del(&cpu_dai->card_list); |
@@ -1099,8 +1104,7 @@ static int soc_probe_codec(struct snd_soc_card *card, | |||
1099 | ret = driver->probe(codec); | 1104 | ret = driver->probe(codec); |
1100 | if (ret < 0) { | 1105 | if (ret < 0) { |
1101 | dev_err(codec->dev, | 1106 | dev_err(codec->dev, |
1102 | "asoc: failed to probe CODEC %s: %d\n", | 1107 | "ASoC: failed to probe CODEC %d\n", ret); |
1103 | codec->name, ret); | ||
1104 | goto err_probe; | 1108 | goto err_probe; |
1105 | } | 1109 | } |
1106 | } | 1110 | } |
@@ -1163,8 +1167,7 @@ static int soc_probe_platform(struct snd_soc_card *card, | |||
1163 | ret = driver->probe(platform); | 1167 | ret = driver->probe(platform); |
1164 | if (ret < 0) { | 1168 | if (ret < 0) { |
1165 | dev_err(platform->dev, | 1169 | dev_err(platform->dev, |
1166 | "asoc: failed to probe platform %s: %d\n", | 1170 | "ASoC: failed to probe platform %d\n", ret); |
1167 | platform->name, ret); | ||
1168 | goto err_probe; | 1171 | goto err_probe; |
1169 | } | 1172 | } |
1170 | } | 1173 | } |
@@ -1229,7 +1232,7 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
1229 | else if (dailess && aux_dev->init) | 1232 | else if (dailess && aux_dev->init) |
1230 | ret = aux_dev->init(&codec->dapm); | 1233 | ret = aux_dev->init(&codec->dapm); |
1231 | if (ret < 0) { | 1234 | if (ret < 0) { |
1232 | dev_err(card->dev, "asoc: failed to init %s: %d\n", name, ret); | 1235 | dev_err(card->dev, "ASoC: failed to init %s: %d\n", name, ret); |
1233 | return ret; | 1236 | return ret; |
1234 | } | 1237 | } |
1235 | codec->name_prefix = temp; | 1238 | codec->name_prefix = temp; |
@@ -1253,7 +1256,7 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
1253 | ret = device_add(rtd->dev); | 1256 | ret = device_add(rtd->dev); |
1254 | if (ret < 0) { | 1257 | if (ret < 0) { |
1255 | dev_err(card->dev, | 1258 | dev_err(card->dev, |
1256 | "asoc: failed to register runtime device: %d\n", ret); | 1259 | "ASoC: failed to register runtime device: %d\n", ret); |
1257 | return ret; | 1260 | return ret; |
1258 | } | 1261 | } |
1259 | rtd->dev_registered = 1; | 1262 | rtd->dev_registered = 1; |
@@ -1262,14 +1265,13 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
1262 | ret = snd_soc_dapm_sys_add(rtd->dev); | 1265 | ret = snd_soc_dapm_sys_add(rtd->dev); |
1263 | if (ret < 0) | 1266 | if (ret < 0) |
1264 | dev_err(codec->dev, | 1267 | dev_err(codec->dev, |
1265 | "asoc: failed to add codec dapm sysfs entries: %d\n", | 1268 | "ASoC: failed to add codec dapm sysfs entries: %d\n", ret); |
1266 | ret); | ||
1267 | 1269 | ||
1268 | /* add codec sysfs entries */ | 1270 | /* add codec sysfs entries */ |
1269 | ret = device_create_file(rtd->dev, &dev_attr_codec_reg); | 1271 | ret = device_create_file(rtd->dev, &dev_attr_codec_reg); |
1270 | if (ret < 0) | 1272 | if (ret < 0) |
1271 | dev_err(codec->dev, | 1273 | dev_err(codec->dev, |
1272 | "asoc: failed to add codec sysfs files: %d\n", ret); | 1274 | "ASoC: failed to add codec sysfs files: %d\n", ret); |
1273 | 1275 | ||
1274 | #ifdef CONFIG_DEBUG_FS | 1276 | #ifdef CONFIG_DEBUG_FS |
1275 | /* add DPCM sysfs entries */ | 1277 | /* add DPCM sysfs entries */ |
@@ -1278,7 +1280,7 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
1278 | 1280 | ||
1279 | ret = soc_dpcm_debugfs_add(rtd); | 1281 | ret = soc_dpcm_debugfs_add(rtd); |
1280 | if (ret < 0) | 1282 | if (ret < 0) |
1281 | dev_err(rtd->dev, "asoc: failed to add dpcm sysfs entries: %d\n", ret); | 1283 | dev_err(rtd->dev, "ASoC: failed to add dpcm sysfs entries: %d\n", ret); |
1282 | 1284 | ||
1283 | out: | 1285 | out: |
1284 | #endif | 1286 | #endif |
@@ -1333,7 +1335,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1333 | struct snd_soc_dapm_widget *play_w, *capture_w; | 1335 | struct snd_soc_dapm_widget *play_w, *capture_w; |
1334 | int ret; | 1336 | int ret; |
1335 | 1337 | ||
1336 | dev_dbg(card->dev, "probe %s dai link %d late %d\n", | 1338 | dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n", |
1337 | card->name, num, order); | 1339 | card->name, num, order); |
1338 | 1340 | ||
1339 | /* config components */ | 1341 | /* config components */ |
@@ -1359,8 +1361,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1359 | if (cpu_dai->driver->probe) { | 1361 | if (cpu_dai->driver->probe) { |
1360 | ret = cpu_dai->driver->probe(cpu_dai); | 1362 | ret = cpu_dai->driver->probe(cpu_dai); |
1361 | if (ret < 0) { | 1363 | if (ret < 0) { |
1362 | pr_err("asoc: failed to probe CPU DAI %s: %d\n", | 1364 | dev_err(cpu_dai->dev, |
1363 | cpu_dai->name, ret); | 1365 | "ASoC: failed to probe CPU DAI %s: %d\n", |
1366 | cpu_dai->name, ret); | ||
1364 | module_put(cpu_dai->dev->driver->owner); | 1367 | module_put(cpu_dai->dev->driver->owner); |
1365 | return ret; | 1368 | return ret; |
1366 | } | 1369 | } |
@@ -1375,8 +1378,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1375 | if (codec_dai->driver->probe) { | 1378 | if (codec_dai->driver->probe) { |
1376 | ret = codec_dai->driver->probe(codec_dai); | 1379 | ret = codec_dai->driver->probe(codec_dai); |
1377 | if (ret < 0) { | 1380 | if (ret < 0) { |
1378 | pr_err("asoc: failed to probe CODEC DAI %s: %d\n", | 1381 | dev_err(codec_dai->dev, |
1379 | codec_dai->name, ret); | 1382 | "ASoC: failed to probe CODEC DAI %s: %d\n", |
1383 | codec_dai->name, ret); | ||
1380 | return ret; | 1384 | return ret; |
1381 | } | 1385 | } |
1382 | } | 1386 | } |
@@ -1396,13 +1400,14 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1396 | 1400 | ||
1397 | ret = device_create_file(rtd->dev, &dev_attr_pmdown_time); | 1401 | ret = device_create_file(rtd->dev, &dev_attr_pmdown_time); |
1398 | if (ret < 0) | 1402 | if (ret < 0) |
1399 | pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret); | 1403 | dev_warn(rtd->dev, "ASoC: failed to add pmdown_time sysfs: %d\n", |
1404 | ret); | ||
1400 | 1405 | ||
1401 | if (cpu_dai->driver->compress_dai) { | 1406 | if (cpu_dai->driver->compress_dai) { |
1402 | /*create compress_device"*/ | 1407 | /*create compress_device"*/ |
1403 | ret = soc_new_compress(rtd, num); | 1408 | ret = soc_new_compress(rtd, num); |
1404 | if (ret < 0) { | 1409 | if (ret < 0) { |
1405 | pr_err("asoc: can't create compress %s\n", | 1410 | dev_err(card->dev, "ASoC: can't create compress %s\n", |
1406 | dai_link->stream_name); | 1411 | dai_link->stream_name); |
1407 | return ret; | 1412 | return ret; |
1408 | } | 1413 | } |
@@ -1412,7 +1417,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1412 | /* create the pcm */ | 1417 | /* create the pcm */ |
1413 | ret = soc_new_pcm(rtd, num); | 1418 | ret = soc_new_pcm(rtd, num); |
1414 | if (ret < 0) { | 1419 | if (ret < 0) { |
1415 | pr_err("asoc: can't create pcm %s :%d\n", | 1420 | dev_err(card->dev, "ASoC: can't create pcm %s :%d\n", |
1416 | dai_link->stream_name, ret); | 1421 | dai_link->stream_name, ret); |
1417 | return ret; | 1422 | return ret; |
1418 | } | 1423 | } |
@@ -1424,7 +1429,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1424 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | 1429 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, |
1425 | capture_w, play_w); | 1430 | capture_w, play_w); |
1426 | if (ret != 0) { | 1431 | if (ret != 0) { |
1427 | dev_err(card->dev, "Can't link %s to %s: %d\n", | 1432 | dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", |
1428 | play_w->name, capture_w->name, ret); | 1433 | play_w->name, capture_w->name, ret); |
1429 | return ret; | 1434 | return ret; |
1430 | } | 1435 | } |
@@ -1436,7 +1441,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1436 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | 1441 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, |
1437 | capture_w, play_w); | 1442 | capture_w, play_w); |
1438 | if (ret != 0) { | 1443 | if (ret != 0) { |
1439 | dev_err(card->dev, "Can't link %s to %s: %d\n", | 1444 | dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", |
1440 | play_w->name, capture_w->name, ret); | 1445 | play_w->name, capture_w->name, ret); |
1441 | return ret; | 1446 | return ret; |
1442 | } | 1447 | } |
@@ -1473,7 +1478,8 @@ static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) | |||
1473 | 1478 | ||
1474 | ret = soc_ac97_dev_register(rtd->codec); | 1479 | ret = soc_ac97_dev_register(rtd->codec); |
1475 | if (ret < 0) { | 1480 | if (ret < 0) { |
1476 | pr_err("asoc: AC97 device register failed:%d\n", ret); | 1481 | dev_err(rtd->codec->dev, |
1482 | "ASoC: AC97 device register failed: %d\n", ret); | ||
1477 | return ret; | 1483 | return ret; |
1478 | } | 1484 | } |
1479 | 1485 | ||
@@ -1502,7 +1508,7 @@ static int soc_check_aux_dev(struct snd_soc_card *card, int num) | |||
1502 | return 0; | 1508 | return 0; |
1503 | } | 1509 | } |
1504 | 1510 | ||
1505 | dev_err(card->dev, "%s not registered\n", aux_dev->codec_name); | 1511 | dev_err(card->dev, "ASoC: %s not registered\n", aux_dev->codec_name); |
1506 | 1512 | ||
1507 | return -EPROBE_DEFER; | 1513 | return -EPROBE_DEFER; |
1508 | } | 1514 | } |
@@ -1518,7 +1524,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) | |||
1518 | if (!strcmp(codec->name, aux_dev->codec_name)) { | 1524 | if (!strcmp(codec->name, aux_dev->codec_name)) { |
1519 | if (codec->probed) { | 1525 | if (codec->probed) { |
1520 | dev_err(codec->dev, | 1526 | dev_err(codec->dev, |
1521 | "asoc: codec already probed"); | 1527 | "ASoC: codec already probed"); |
1522 | ret = -EBUSY; | 1528 | ret = -EBUSY; |
1523 | goto out; | 1529 | goto out; |
1524 | } | 1530 | } |
@@ -1526,7 +1532,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) | |||
1526 | } | 1532 | } |
1527 | } | 1533 | } |
1528 | /* codec not found */ | 1534 | /* codec not found */ |
1529 | dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name); | 1535 | dev_err(card->dev, "ASoC: codec %s not found", aux_dev->codec_name); |
1530 | return -EPROBE_DEFER; | 1536 | return -EPROBE_DEFER; |
1531 | 1537 | ||
1532 | found: | 1538 | found: |
@@ -1569,8 +1575,8 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec, | |||
1569 | codec->compress_type = compress_type; | 1575 | codec->compress_type = compress_type; |
1570 | ret = snd_soc_cache_init(codec); | 1576 | ret = snd_soc_cache_init(codec); |
1571 | if (ret < 0) { | 1577 | if (ret < 0) { |
1572 | dev_err(codec->dev, "Failed to set cache compression type: %d\n", | 1578 | dev_err(codec->dev, "ASoC: Failed to set cache compression" |
1573 | ret); | 1579 | " type: %d\n", ret); |
1574 | return ret; | 1580 | return ret; |
1575 | } | 1581 | } |
1576 | codec->cache_init = 1; | 1582 | codec->cache_init = 1; |
@@ -1626,8 +1632,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1626 | ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, | 1632 | ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, |
1627 | card->owner, 0, &card->snd_card); | 1633 | card->owner, 0, &card->snd_card); |
1628 | if (ret < 0) { | 1634 | if (ret < 0) { |
1629 | pr_err("asoc: can't create sound card for card %s: %d\n", | 1635 | dev_err(card->dev, "ASoC: can't create sound card for" |
1630 | card->name, ret); | 1636 | " card %s: %d\n", card->name, ret); |
1631 | goto base_error; | 1637 | goto base_error; |
1632 | } | 1638 | } |
1633 | card->snd_card->dev = card->dev; | 1639 | card->snd_card->dev = card->dev; |
@@ -1663,8 +1669,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1663 | for (i = 0; i < card->num_links; i++) { | 1669 | for (i = 0; i < card->num_links; i++) { |
1664 | ret = soc_probe_link_components(card, i, order); | 1670 | ret = soc_probe_link_components(card, i, order); |
1665 | if (ret < 0) { | 1671 | if (ret < 0) { |
1666 | pr_err("asoc: failed to instantiate card %s: %d\n", | 1672 | dev_err(card->dev, |
1667 | card->name, ret); | 1673 | "ASoC: failed to instantiate card %d\n", |
1674 | ret); | ||
1668 | goto probe_dai_err; | 1675 | goto probe_dai_err; |
1669 | } | 1676 | } |
1670 | } | 1677 | } |
@@ -1676,8 +1683,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1676 | for (i = 0; i < card->num_links; i++) { | 1683 | for (i = 0; i < card->num_links; i++) { |
1677 | ret = soc_probe_link_dais(card, i, order); | 1684 | ret = soc_probe_link_dais(card, i, order); |
1678 | if (ret < 0) { | 1685 | if (ret < 0) { |
1679 | pr_err("asoc: failed to instantiate card %s: %d\n", | 1686 | dev_err(card->dev, |
1680 | card->name, ret); | 1687 | "ASoC: failed to instantiate card %d\n", |
1688 | ret); | ||
1681 | goto probe_dai_err; | 1689 | goto probe_dai_err; |
1682 | } | 1690 | } |
1683 | } | 1691 | } |
@@ -1686,8 +1694,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1686 | for (i = 0; i < card->num_aux_devs; i++) { | 1694 | for (i = 0; i < card->num_aux_devs; i++) { |
1687 | ret = soc_probe_aux_dev(card, i); | 1695 | ret = soc_probe_aux_dev(card, i); |
1688 | if (ret < 0) { | 1696 | if (ret < 0) { |
1689 | pr_err("asoc: failed to add auxiliary devices %s: %d\n", | 1697 | dev_err(card->dev, |
1690 | card->name, ret); | 1698 | "ASoC: failed to add auxiliary devices %d\n", |
1699 | ret); | ||
1691 | goto probe_aux_dev_err; | 1700 | goto probe_aux_dev_err; |
1692 | } | 1701 | } |
1693 | } | 1702 | } |
@@ -1712,7 +1721,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1712 | dai_fmt); | 1721 | dai_fmt); |
1713 | if (ret != 0 && ret != -ENOTSUPP) | 1722 | if (ret != 0 && ret != -ENOTSUPP) |
1714 | dev_warn(card->rtd[i].codec_dai->dev, | 1723 | dev_warn(card->rtd[i].codec_dai->dev, |
1715 | "Failed to set DAI format: %d\n", | 1724 | "ASoC: Failed to set DAI format: %d\n", |
1716 | ret); | 1725 | ret); |
1717 | } | 1726 | } |
1718 | 1727 | ||
@@ -1723,7 +1732,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1723 | dai_fmt); | 1732 | dai_fmt); |
1724 | if (ret != 0 && ret != -ENOTSUPP) | 1733 | if (ret != 0 && ret != -ENOTSUPP) |
1725 | dev_warn(card->rtd[i].cpu_dai->dev, | 1734 | dev_warn(card->rtd[i].cpu_dai->dev, |
1726 | "Failed to set DAI format: %d\n", | 1735 | "ASoC: Failed to set DAI format: %d\n", |
1727 | ret); | 1736 | ret); |
1728 | } else if (dai_fmt) { | 1737 | } else if (dai_fmt) { |
1729 | /* Flip the polarity for the "CPU" end */ | 1738 | /* Flip the polarity for the "CPU" end */ |
@@ -1748,7 +1757,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1748 | dai_fmt); | 1757 | dai_fmt); |
1749 | if (ret != 0 && ret != -ENOTSUPP) | 1758 | if (ret != 0 && ret != -ENOTSUPP) |
1750 | dev_warn(card->rtd[i].cpu_dai->dev, | 1759 | dev_warn(card->rtd[i].cpu_dai->dev, |
1751 | "Failed to set DAI format: %d\n", | 1760 | "ASoC: Failed to set DAI format: %d\n", |
1752 | ret); | 1761 | ret); |
1753 | } | 1762 | } |
1754 | } | 1763 | } |
@@ -1775,7 +1784,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1775 | if (card->late_probe) { | 1784 | if (card->late_probe) { |
1776 | ret = card->late_probe(card); | 1785 | ret = card->late_probe(card); |
1777 | if (ret < 0) { | 1786 | if (ret < 0) { |
1778 | dev_err(card->dev, "%s late_probe() failed: %d\n", | 1787 | dev_err(card->dev, "ASoC: %s late_probe() failed: %d\n", |
1779 | card->name, ret); | 1788 | card->name, ret); |
1780 | goto probe_aux_dev_err; | 1789 | goto probe_aux_dev_err; |
1781 | } | 1790 | } |
@@ -1789,8 +1798,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1789 | 1798 | ||
1790 | ret = snd_card_register(card->snd_card); | 1799 | ret = snd_card_register(card->snd_card); |
1791 | if (ret < 0) { | 1800 | if (ret < 0) { |
1792 | pr_err("asoc: failed to register soundcard for %s: %d\n", | 1801 | dev_err(card->dev, "ASoC: failed to register soundcard %d\n", |
1793 | card->name, ret); | 1802 | ret); |
1794 | goto probe_aux_dev_err; | 1803 | goto probe_aux_dev_err; |
1795 | } | 1804 | } |
1796 | 1805 | ||
@@ -1799,8 +1808,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1799 | for (i = 0; i < card->num_rtd; i++) { | 1808 | for (i = 0; i < card->num_rtd; i++) { |
1800 | ret = soc_register_ac97_dai_link(&card->rtd[i]); | 1809 | ret = soc_register_ac97_dai_link(&card->rtd[i]); |
1801 | if (ret < 0) { | 1810 | if (ret < 0) { |
1802 | pr_err("asoc: failed to register AC97 %s: %d\n", | 1811 | dev_err(card->dev, "ASoC: failed to register AC97:" |
1803 | card->name, ret); | 1812 | " %d\n", ret); |
1804 | while (--i >= 0) | 1813 | while (--i >= 0) |
1805 | soc_unregister_ac97_dai_link(card->rtd[i].codec); | 1814 | soc_unregister_ac97_dai_link(card->rtd[i].codec); |
1806 | goto probe_aux_dev_err; | 1815 | goto probe_aux_dev_err; |
@@ -1846,7 +1855,7 @@ static int soc_probe(struct platform_device *pdev) | |||
1846 | return -EINVAL; | 1855 | return -EINVAL; |
1847 | 1856 | ||
1848 | dev_warn(&pdev->dev, | 1857 | dev_warn(&pdev->dev, |
1849 | "ASoC machine %s should use snd_soc_register_card()\n", | 1858 | "ASoC: machine %s should use snd_soc_register_card()\n", |
1850 | card->name); | 1859 | card->name); |
1851 | 1860 | ||
1852 | /* Bodge while we unpick instantiation */ | 1861 | /* Bodge while we unpick instantiation */ |
@@ -1996,7 +2005,7 @@ int snd_soc_platform_read(struct snd_soc_platform *platform, | |||
1996 | unsigned int ret; | 2005 | unsigned int ret; |
1997 | 2006 | ||
1998 | if (!platform->driver->read) { | 2007 | if (!platform->driver->read) { |
1999 | dev_err(platform->dev, "platform has no read back\n"); | 2008 | dev_err(platform->dev, "ASoC: platform has no read back\n"); |
2000 | return -1; | 2009 | return -1; |
2001 | } | 2010 | } |
2002 | 2011 | ||
@@ -2012,7 +2021,7 @@ int snd_soc_platform_write(struct snd_soc_platform *platform, | |||
2012 | unsigned int reg, unsigned int val) | 2021 | unsigned int reg, unsigned int val) |
2013 | { | 2022 | { |
2014 | if (!platform->driver->write) { | 2023 | if (!platform->driver->write) { |
2015 | dev_err(platform->dev, "platform has no write back\n"); | 2024 | dev_err(platform->dev, "ASoC: platform has no write back\n"); |
2016 | return -1; | 2025 | return -1; |
2017 | } | 2026 | } |
2018 | 2027 | ||
@@ -2283,7 +2292,8 @@ static int snd_soc_add_controls(struct snd_card *card, struct device *dev, | |||
2283 | err = snd_ctl_add(card, snd_soc_cnew(control, data, | 2292 | err = snd_ctl_add(card, snd_soc_cnew(control, data, |
2284 | control->name, prefix)); | 2293 | control->name, prefix)); |
2285 | if (err < 0) { | 2294 | if (err < 0) { |
2286 | dev_err(dev, "Failed to add %s: %d\n", control->name, err); | 2295 | dev_err(dev, "ASoC: Failed to add %s: %d\n", |
2296 | control->name, err); | ||
2287 | return err; | 2297 | return err; |
2288 | } | 2298 | } |
2289 | } | 2299 | } |
@@ -3534,15 +3544,14 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
3534 | * not both or neither. | 3544 | * not both or neither. |
3535 | */ | 3545 | */ |
3536 | if (!!link->codec_name == !!link->codec_of_node) { | 3546 | if (!!link->codec_name == !!link->codec_of_node) { |
3537 | dev_err(card->dev, | 3547 | dev_err(card->dev, "ASoC: Neither/both codec" |
3538 | "Neither/both codec name/of_node are set for %s\n", | 3548 | " name/of_node are set for %s\n", link->name); |
3539 | link->name); | ||
3540 | return -EINVAL; | 3549 | return -EINVAL; |
3541 | } | 3550 | } |
3542 | /* Codec DAI name must be specified */ | 3551 | /* Codec DAI name must be specified */ |
3543 | if (!link->codec_dai_name) { | 3552 | if (!link->codec_dai_name) { |
3544 | dev_err(card->dev, "codec_dai_name not set for %s\n", | 3553 | dev_err(card->dev, "ASoC: codec_dai_name not" |
3545 | link->name); | 3554 | " set for %s\n", link->name); |
3546 | return -EINVAL; | 3555 | return -EINVAL; |
3547 | } | 3556 | } |
3548 | 3557 | ||
@@ -3551,8 +3560,8 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
3551 | * can be left unspecified, and a dummy platform will be used. | 3560 | * can be left unspecified, and a dummy platform will be used. |
3552 | */ | 3561 | */ |
3553 | if (link->platform_name && link->platform_of_node) { | 3562 | if (link->platform_name && link->platform_of_node) { |
3554 | dev_err(card->dev, | 3563 | dev_err(card->dev, "ASoC: Both platform name/of_node" |
3555 | "Both platform name/of_node are set for %s\n", link->name); | 3564 | " are set for %s\n", link->name); |
3556 | return -EINVAL; | 3565 | return -EINVAL; |
3557 | } | 3566 | } |
3558 | 3567 | ||
@@ -3562,9 +3571,8 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
3562 | * name alone.. | 3571 | * name alone.. |
3563 | */ | 3572 | */ |
3564 | if (link->cpu_name && link->cpu_of_node) { | 3573 | if (link->cpu_name && link->cpu_of_node) { |
3565 | dev_err(card->dev, | 3574 | dev_err(card->dev, "ASoC: Neither/both " |
3566 | "Neither/both cpu name/of_node are set for %s\n", | 3575 | "cpu name/of_node are set for %s\n",link->name); |
3567 | link->name); | ||
3568 | return -EINVAL; | 3576 | return -EINVAL; |
3569 | } | 3577 | } |
3570 | /* | 3578 | /* |
@@ -3573,9 +3581,8 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
3573 | */ | 3581 | */ |
3574 | if (!link->cpu_dai_name && | 3582 | if (!link->cpu_dai_name && |
3575 | !(link->cpu_name || link->cpu_of_node)) { | 3583 | !(link->cpu_name || link->cpu_of_node)) { |
3576 | dev_err(card->dev, | 3584 | dev_err(card->dev, "ASoC: Neither cpu_dai_name nor " |
3577 | "Neither cpu_dai_name nor cpu_name/of_node are set for %s\n", | 3585 | "cpu_name/of_node are set for %s\n", link->name); |
3578 | link->name); | ||
3579 | return -EINVAL; | 3586 | return -EINVAL; |
3580 | } | 3587 | } |
3581 | } | 3588 | } |
@@ -3622,7 +3629,7 @@ int snd_soc_unregister_card(struct snd_soc_card *card) | |||
3622 | { | 3629 | { |
3623 | if (card->instantiated) | 3630 | if (card->instantiated) |
3624 | soc_cleanup_card_resources(card); | 3631 | soc_cleanup_card_resources(card); |
3625 | dev_dbg(card->dev, "Unregistered card '%s'\n", card->name); | 3632 | dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name); |
3626 | 3633 | ||
3627 | return 0; | 3634 | return 0; |
3628 | } | 3635 | } |
@@ -3679,8 +3686,8 @@ static inline char *fmt_multiple_name(struct device *dev, | |||
3679 | struct snd_soc_dai_driver *dai_drv) | 3686 | struct snd_soc_dai_driver *dai_drv) |
3680 | { | 3687 | { |
3681 | if (dai_drv->name == NULL) { | 3688 | if (dai_drv->name == NULL) { |
3682 | pr_err("asoc: error - multiple DAI %s registered with no name\n", | 3689 | dev_err(dev, "ASoC: error - multiple DAI %s registered with" |
3683 | dev_name(dev)); | 3690 | " no name\n", dev_name(dev)); |
3684 | return NULL; | 3691 | return NULL; |
3685 | } | 3692 | } |
3686 | 3693 | ||
@@ -3698,7 +3705,7 @@ int snd_soc_register_dai(struct device *dev, | |||
3698 | struct snd_soc_codec *codec; | 3705 | struct snd_soc_codec *codec; |
3699 | struct snd_soc_dai *dai; | 3706 | struct snd_soc_dai *dai; |
3700 | 3707 | ||
3701 | dev_dbg(dev, "dai register %s\n", dev_name(dev)); | 3708 | dev_dbg(dev, "ASoC: dai register %s\n", dev_name(dev)); |
3702 | 3709 | ||
3703 | dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); | 3710 | dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); |
3704 | if (dai == NULL) | 3711 | if (dai == NULL) |
@@ -3721,7 +3728,7 @@ int snd_soc_register_dai(struct device *dev, | |||
3721 | 3728 | ||
3722 | list_for_each_entry(codec, &codec_list, list) { | 3729 | list_for_each_entry(codec, &codec_list, list) { |
3723 | if (codec->dev == dev) { | 3730 | if (codec->dev == dev) { |
3724 | dev_dbg(dev, "Mapped DAI %s to CODEC %s\n", | 3731 | dev_dbg(dev, "ASoC: Mapped DAI %s to CODEC %s\n", |
3725 | dai->name, codec->name); | 3732 | dai->name, codec->name); |
3726 | dai->codec = codec; | 3733 | dai->codec = codec; |
3727 | break; | 3734 | break; |
@@ -3735,7 +3742,7 @@ int snd_soc_register_dai(struct device *dev, | |||
3735 | 3742 | ||
3736 | mutex_unlock(&client_mutex); | 3743 | mutex_unlock(&client_mutex); |
3737 | 3744 | ||
3738 | pr_debug("Registered DAI '%s'\n", dai->name); | 3745 | dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name); |
3739 | 3746 | ||
3740 | return 0; | 3747 | return 0; |
3741 | } | 3748 | } |
@@ -3761,7 +3768,7 @@ found: | |||
3761 | list_del(&dai->list); | 3768 | list_del(&dai->list); |
3762 | mutex_unlock(&client_mutex); | 3769 | mutex_unlock(&client_mutex); |
3763 | 3770 | ||
3764 | pr_debug("Unregistered DAI '%s'\n", dai->name); | 3771 | dev_dbg(dev, "ASoC: Unregistered DAI '%s'\n", dai->name); |
3765 | kfree(dai->name); | 3772 | kfree(dai->name); |
3766 | kfree(dai); | 3773 | kfree(dai); |
3767 | } | 3774 | } |
@@ -3780,7 +3787,7 @@ int snd_soc_register_dais(struct device *dev, | |||
3780 | struct snd_soc_dai *dai; | 3787 | struct snd_soc_dai *dai; |
3781 | int i, ret = 0; | 3788 | int i, ret = 0; |
3782 | 3789 | ||
3783 | dev_dbg(dev, "dai register %s #%Zu\n", dev_name(dev), count); | 3790 | dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count); |
3784 | 3791 | ||
3785 | for (i = 0; i < count; i++) { | 3792 | for (i = 0; i < count; i++) { |
3786 | 3793 | ||
@@ -3812,8 +3819,8 @@ int snd_soc_register_dais(struct device *dev, | |||
3812 | 3819 | ||
3813 | list_for_each_entry(codec, &codec_list, list) { | 3820 | list_for_each_entry(codec, &codec_list, list) { |
3814 | if (codec->dev == dev) { | 3821 | if (codec->dev == dev) { |
3815 | dev_dbg(dev, "Mapped DAI %s to CODEC %s\n", | 3822 | dev_dbg(dev, "ASoC: Mapped DAI %s to " |
3816 | dai->name, codec->name); | 3823 | "CODEC %s\n", dai->name, codec->name); |
3817 | dai->codec = codec; | 3824 | dai->codec = codec; |
3818 | break; | 3825 | break; |
3819 | } | 3826 | } |
@@ -3826,7 +3833,7 @@ int snd_soc_register_dais(struct device *dev, | |||
3826 | 3833 | ||
3827 | mutex_unlock(&client_mutex); | 3834 | mutex_unlock(&client_mutex); |
3828 | 3835 | ||
3829 | pr_debug("Registered DAI '%s'\n", dai->name); | 3836 | dev_dbg(dai->dev, "ASoC: Registered DAI '%s'\n", dai->name); |
3830 | } | 3837 | } |
3831 | 3838 | ||
3832 | return 0; | 3839 | return 0; |
@@ -3864,7 +3871,7 @@ int snd_soc_register_platform(struct device *dev, | |||
3864 | { | 3871 | { |
3865 | struct snd_soc_platform *platform; | 3872 | struct snd_soc_platform *platform; |
3866 | 3873 | ||
3867 | dev_dbg(dev, "platform register %s\n", dev_name(dev)); | 3874 | dev_dbg(dev, "ASoC: platform register %s\n", dev_name(dev)); |
3868 | 3875 | ||
3869 | platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL); | 3876 | platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL); |
3870 | if (platform == NULL) | 3877 | if (platform == NULL) |
@@ -3888,7 +3895,7 @@ int snd_soc_register_platform(struct device *dev, | |||
3888 | list_add(&platform->list, &platform_list); | 3895 | list_add(&platform->list, &platform_list); |
3889 | mutex_unlock(&client_mutex); | 3896 | mutex_unlock(&client_mutex); |
3890 | 3897 | ||
3891 | pr_debug("Registered platform '%s'\n", platform->name); | 3898 | dev_dbg(dev, "ASoC: Registered platform '%s'\n", platform->name); |
3892 | 3899 | ||
3893 | return 0; | 3900 | return 0; |
3894 | } | 3901 | } |
@@ -3914,7 +3921,7 @@ found: | |||
3914 | list_del(&platform->list); | 3921 | list_del(&platform->list); |
3915 | mutex_unlock(&client_mutex); | 3922 | mutex_unlock(&client_mutex); |
3916 | 3923 | ||
3917 | pr_debug("Unregistered platform '%s'\n", platform->name); | 3924 | dev_dbg(dev, "ASoC: Unregistered platform '%s'\n", platform->name); |
3918 | kfree(platform->name); | 3925 | kfree(platform->name); |
3919 | kfree(platform); | 3926 | kfree(platform); |
3920 | } | 3927 | } |
@@ -4007,7 +4014,7 @@ int snd_soc_register_codec(struct device *dev, | |||
4007 | codec->reg_size = reg_size; | 4014 | codec->reg_size = reg_size; |
4008 | /* it is necessary to make a copy of the default register cache | 4015 | /* it is necessary to make a copy of the default register cache |
4009 | * because in the case of using a compression type that requires | 4016 | * because in the case of using a compression type that requires |
4010 | * the default register cache to be marked as __devinitconst the | 4017 | * the default register cache to be marked as the |
4011 | * kernel might have freed the array by the time we initialize | 4018 | * kernel might have freed the array by the time we initialize |
4012 | * the cache. | 4019 | * the cache. |
4013 | */ | 4020 | */ |
@@ -4043,11 +4050,11 @@ int snd_soc_register_codec(struct device *dev, | |||
4043 | if (num_dai) { | 4050 | if (num_dai) { |
4044 | ret = snd_soc_register_dais(dev, dai_drv, num_dai); | 4051 | ret = snd_soc_register_dais(dev, dai_drv, num_dai); |
4045 | if (ret < 0) | 4052 | if (ret < 0) |
4046 | dev_err(codec->dev, "Failed to regster DAIs: %d\n", | 4053 | dev_err(codec->dev, "ASoC: Failed to regster" |
4047 | ret); | 4054 | " DAIs: %d\n", ret); |
4048 | } | 4055 | } |
4049 | 4056 | ||
4050 | pr_debug("Registered codec '%s'\n", codec->name); | 4057 | dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n", codec->name); |
4051 | return 0; | 4058 | return 0; |
4052 | 4059 | ||
4053 | fail: | 4060 | fail: |
@@ -4082,7 +4089,7 @@ found: | |||
4082 | list_del(&codec->list); | 4089 | list_del(&codec->list); |
4083 | mutex_unlock(&client_mutex); | 4090 | mutex_unlock(&client_mutex); |
4084 | 4091 | ||
4085 | pr_debug("Unregistered codec '%s'\n", codec->name); | 4092 | dev_dbg(codec->dev, "ASoC: Unregistered codec '%s'\n", codec->name); |
4086 | 4093 | ||
4087 | snd_soc_cache_exit(codec); | 4094 | snd_soc_cache_exit(codec); |
4088 | kfree(codec->reg_def_copy); | 4095 | kfree(codec->reg_def_copy); |
@@ -4106,7 +4113,7 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card, | |||
4106 | */ | 4113 | */ |
4107 | if (ret < 0 && ret != -EINVAL) { | 4114 | if (ret < 0 && ret != -EINVAL) { |
4108 | dev_err(card->dev, | 4115 | dev_err(card->dev, |
4109 | "Property '%s' could not be read: %d\n", | 4116 | "ASoC: Property '%s' could not be read: %d\n", |
4110 | propname, ret); | 4117 | propname, ret); |
4111 | return ret; | 4118 | return ret; |
4112 | } | 4119 | } |
@@ -4125,15 +4132,13 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
4125 | 4132 | ||
4126 | num_routes = of_property_count_strings(np, propname); | 4133 | num_routes = of_property_count_strings(np, propname); |
4127 | if (num_routes < 0 || num_routes & 1) { | 4134 | if (num_routes < 0 || num_routes & 1) { |
4128 | dev_err(card->dev, | 4135 | dev_err(card->dev, "ASoC: Property '%s' does not exist or its" |
4129 | "Property '%s' does not exist or its length is not even\n", | 4136 | " length is not even\n", propname); |
4130 | propname); | ||
4131 | return -EINVAL; | 4137 | return -EINVAL; |
4132 | } | 4138 | } |
4133 | num_routes /= 2; | 4139 | num_routes /= 2; |
4134 | if (!num_routes) { | 4140 | if (!num_routes) { |
4135 | dev_err(card->dev, | 4141 | dev_err(card->dev, "ASoC: Property '%s's length is zero\n", |
4136 | "Property '%s's length is zero\n", | ||
4137 | propname); | 4142 | propname); |
4138 | return -EINVAL; | 4143 | return -EINVAL; |
4139 | } | 4144 | } |
@@ -4142,7 +4147,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
4142 | GFP_KERNEL); | 4147 | GFP_KERNEL); |
4143 | if (!routes) { | 4148 | if (!routes) { |
4144 | dev_err(card->dev, | 4149 | dev_err(card->dev, |
4145 | "Could not allocate DAPM route table\n"); | 4150 | "ASoC: Could not allocate DAPM route table\n"); |
4146 | return -EINVAL; | 4151 | return -EINVAL; |
4147 | } | 4152 | } |
4148 | 4153 | ||
@@ -4150,9 +4155,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
4150 | ret = of_property_read_string_index(np, propname, | 4155 | ret = of_property_read_string_index(np, propname, |
4151 | 2 * i, &routes[i].sink); | 4156 | 2 * i, &routes[i].sink); |
4152 | if (ret) { | 4157 | if (ret) { |
4153 | dev_err(card->dev, | 4158 | dev_err(card->dev, "ASoC: Property '%s' index %d" |
4154 | "Property '%s' index %d could not be read: %d\n", | 4159 | " could not be read: %d\n", propname, 2 * i, |
4155 | propname, 2 * i, ret); | 4160 | ret); |
4156 | kfree(routes); | 4161 | kfree(routes); |
4157 | return -EINVAL; | 4162 | return -EINVAL; |
4158 | } | 4163 | } |
@@ -4160,8 +4165,8 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
4160 | (2 * i) + 1, &routes[i].source); | 4165 | (2 * i) + 1, &routes[i].source); |
4161 | if (ret) { | 4166 | if (ret) { |
4162 | dev_err(card->dev, | 4167 | dev_err(card->dev, |
4163 | "Property '%s' index %d could not be read: %d\n", | 4168 | "ASoC: Property '%s' index %d could not be" |
4164 | propname, (2 * i) + 1, ret); | 4169 | " read: %d\n", propname, (2 * i) + 1, ret); |
4165 | kfree(routes); | 4170 | kfree(routes); |
4166 | return -EINVAL; | 4171 | return -EINVAL; |
4167 | } | 4172 | } |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 6e35bcae02df..1e36bc81e5af 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -220,7 +220,7 @@ static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg) | |||
220 | else if (w->platform) | 220 | else if (w->platform) |
221 | return snd_soc_platform_read(w->platform, reg); | 221 | return snd_soc_platform_read(w->platform, reg); |
222 | 222 | ||
223 | dev_err(w->dapm->dev, "no valid widget read method\n"); | 223 | dev_err(w->dapm->dev, "ASoC: no valid widget read method\n"); |
224 | return -1; | 224 | return -1; |
225 | } | 225 | } |
226 | 226 | ||
@@ -231,7 +231,7 @@ static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val) | |||
231 | else if (w->platform) | 231 | else if (w->platform) |
232 | return snd_soc_platform_write(w->platform, reg, val); | 232 | return snd_soc_platform_write(w->platform, reg, val); |
233 | 233 | ||
234 | dev_err(w->dapm->dev, "no valid widget write method\n"); | 234 | dev_err(w->dapm->dev, "ASoC: no valid widget write method\n"); |
235 | return -1; | 235 | return -1; |
236 | } | 236 | } |
237 | 237 | ||
@@ -546,7 +546,7 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w) | |||
546 | wlist = kzalloc(wlistsize, GFP_KERNEL); | 546 | wlist = kzalloc(wlistsize, GFP_KERNEL); |
547 | if (wlist == NULL) { | 547 | if (wlist == NULL) { |
548 | dev_err(dapm->dev, | 548 | dev_err(dapm->dev, |
549 | "asoc: can't allocate widget list for %s\n", | 549 | "ASoC: can't allocate widget list for %s\n", |
550 | w->name); | 550 | w->name); |
551 | return -ENOMEM; | 551 | return -ENOMEM; |
552 | } | 552 | } |
@@ -595,9 +595,9 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w) | |||
595 | prefix); | 595 | prefix); |
596 | ret = snd_ctl_add(card, path->kcontrol); | 596 | ret = snd_ctl_add(card, path->kcontrol); |
597 | if (ret < 0) { | 597 | if (ret < 0) { |
598 | dev_err(dapm->dev, | 598 | dev_err(dapm->dev, "ASoC: failed to add widget" |
599 | "asoc: failed to add dapm kcontrol %s: %d\n", | 599 | " %s dapm kcontrol %s: %d\n", |
600 | path->long_name, ret); | 600 | w->name, path->long_name, ret); |
601 | kfree(wlist); | 601 | kfree(wlist); |
602 | kfree(path->long_name); | 602 | kfree(path->long_name); |
603 | path->long_name = NULL; | 603 | path->long_name = NULL; |
@@ -626,7 +626,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) | |||
626 | 626 | ||
627 | if (w->num_kcontrols != 1) { | 627 | if (w->num_kcontrols != 1) { |
628 | dev_err(dapm->dev, | 628 | dev_err(dapm->dev, |
629 | "asoc: mux %s has incorrect number of controls\n", | 629 | "ASoC: mux %s has incorrect number of controls\n", |
630 | w->name); | 630 | w->name); |
631 | return -EINVAL; | 631 | return -EINVAL; |
632 | } | 632 | } |
@@ -645,7 +645,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) | |||
645 | wlist = krealloc(wlist, wlistsize, GFP_KERNEL); | 645 | wlist = krealloc(wlist, wlistsize, GFP_KERNEL); |
646 | if (wlist == NULL) { | 646 | if (wlist == NULL) { |
647 | dev_err(dapm->dev, | 647 | dev_err(dapm->dev, |
648 | "asoc: can't allocate widget list for %s\n", w->name); | 648 | "ASoC: can't allocate widget list for %s\n", w->name); |
649 | return -ENOMEM; | 649 | return -ENOMEM; |
650 | } | 650 | } |
651 | wlist->num_widgets = wlistentries; | 651 | wlist->num_widgets = wlistentries; |
@@ -677,7 +677,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) | |||
677 | name + prefix_len, prefix); | 677 | name + prefix_len, prefix); |
678 | ret = snd_ctl_add(card, kcontrol); | 678 | ret = snd_ctl_add(card, kcontrol); |
679 | if (ret < 0) { | 679 | if (ret < 0) { |
680 | dev_err(dapm->dev, "failed to add kcontrol %s: %d\n", | 680 | dev_err(dapm->dev, "ASoC: failed to add kcontrol %s: %d\n", |
681 | w->name, ret); | 681 | w->name, ret); |
682 | kfree(wlist); | 682 | kfree(wlist); |
683 | return ret; | 683 | return ret; |
@@ -699,7 +699,7 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w) | |||
699 | { | 699 | { |
700 | if (w->num_kcontrols) | 700 | if (w->num_kcontrols) |
701 | dev_err(w->dapm->dev, | 701 | dev_err(w->dapm->dev, |
702 | "asoc: PGA controls not supported: '%s'\n", w->name); | 702 | "ASoC: PGA controls not supported: '%s'\n", w->name); |
703 | 703 | ||
704 | return 0; | 704 | return 0; |
705 | } | 705 | } |
@@ -725,7 +725,7 @@ static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) | |||
725 | case SNDRV_CTL_POWER_D3hot: | 725 | case SNDRV_CTL_POWER_D3hot: |
726 | case SNDRV_CTL_POWER_D3cold: | 726 | case SNDRV_CTL_POWER_D3cold: |
727 | if (widget->ignore_suspend) | 727 | if (widget->ignore_suspend) |
728 | dev_dbg(widget->dapm->dev, "%s ignoring suspend\n", | 728 | dev_dbg(widget->dapm->dev, "ASoC: %s ignoring suspend\n", |
729 | widget->name); | 729 | widget->name); |
730 | return widget->ignore_suspend; | 730 | return widget->ignore_suspend; |
731 | default: | 731 | default: |
@@ -757,14 +757,14 @@ static int dapm_list_add_widget(struct snd_soc_dapm_widget_list **list, | |||
757 | wlistentries * sizeof(struct snd_soc_dapm_widget *); | 757 | wlistentries * sizeof(struct snd_soc_dapm_widget *); |
758 | *list = krealloc(wlist, wlistsize, GFP_KERNEL); | 758 | *list = krealloc(wlist, wlistsize, GFP_KERNEL); |
759 | if (*list == NULL) { | 759 | if (*list == NULL) { |
760 | dev_err(w->dapm->dev, "can't allocate widget list for %s\n", | 760 | dev_err(w->dapm->dev, "ASoC: can't allocate widget list for %s\n", |
761 | w->name); | 761 | w->name); |
762 | return -ENOMEM; | 762 | return -ENOMEM; |
763 | } | 763 | } |
764 | wlist = *list; | 764 | wlist = *list; |
765 | 765 | ||
766 | /* insert the widget */ | 766 | /* insert the widget */ |
767 | dev_dbg(w->dapm->dev, "added %s in widget list pos %d\n", | 767 | dev_dbg(w->dapm->dev, "ASoC: added %s in widget list pos %d\n", |
768 | w->name, wlist->num_widgets); | 768 | w->name, wlist->num_widgets); |
769 | 769 | ||
770 | wlist->widgets[wlist->num_widgets] = w; | 770 | wlist->widgets[wlist->num_widgets] = w; |
@@ -844,7 +844,8 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, | |||
844 | int err; | 844 | int err; |
845 | err = dapm_list_add_widget(list, path->sink); | 845 | err = dapm_list_add_widget(list, path->sink); |
846 | if (err < 0) { | 846 | if (err < 0) { |
847 | dev_err(widget->dapm->dev, "could not add widget %s\n", | 847 | dev_err(widget->dapm->dev, |
848 | "ASoC: could not add widget %s\n", | ||
848 | widget->name); | 849 | widget->name); |
849 | return con; | 850 | return con; |
850 | } | 851 | } |
@@ -943,7 +944,8 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, | |||
943 | int err; | 944 | int err; |
944 | err = dapm_list_add_widget(list, path->source); | 945 | err = dapm_list_add_widget(list, path->source); |
945 | if (err < 0) { | 946 | if (err < 0) { |
946 | dev_err(widget->dapm->dev, "could not add widget %s\n", | 947 | dev_err(widget->dapm->dev, |
948 | "ASoC: could not add widget %s\n", | ||
947 | widget->name); | 949 | widget->name); |
948 | return con; | 950 | return con; |
949 | } | 951 | } |
@@ -1024,7 +1026,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, | |||
1024 | ret = regulator_allow_bypass(w->regulator, true); | 1026 | ret = regulator_allow_bypass(w->regulator, true); |
1025 | if (ret != 0) | 1027 | if (ret != 0) |
1026 | dev_warn(w->dapm->dev, | 1028 | dev_warn(w->dapm->dev, |
1027 | "Failed to bypass %s: %d\n", | 1029 | "ASoC: Failed to bypass %s: %d\n", |
1028 | w->name, ret); | 1030 | w->name, ret); |
1029 | } | 1031 | } |
1030 | 1032 | ||
@@ -1034,7 +1036,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, | |||
1034 | ret = regulator_allow_bypass(w->regulator, false); | 1036 | ret = regulator_allow_bypass(w->regulator, false); |
1035 | if (ret != 0) | 1037 | if (ret != 0) |
1036 | dev_warn(w->dapm->dev, | 1038 | dev_warn(w->dapm->dev, |
1037 | "Failed to unbypass %s: %d\n", | 1039 | "ASoC: Failed to unbypass %s: %d\n", |
1038 | w->name, ret); | 1040 | w->name, ret); |
1039 | } | 1041 | } |
1040 | 1042 | ||
@@ -1253,7 +1255,7 @@ static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm, | |||
1253 | ret = w->event(w, NULL, event); | 1255 | ret = w->event(w, NULL, event); |
1254 | trace_snd_soc_dapm_widget_event_done(w, event); | 1256 | trace_snd_soc_dapm_widget_event_done(w, event); |
1255 | if (ret < 0) | 1257 | if (ret < 0) |
1256 | pr_err("%s: %s event failed: %d\n", | 1258 | dev_err(dapm->dev, "ASoC: %s: %s event failed: %d\n", |
1257 | ev_name, w->name, ret); | 1259 | ev_name, w->name, ret); |
1258 | } | 1260 | } |
1259 | } | 1261 | } |
@@ -1402,7 +1404,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm, | |||
1402 | 1404 | ||
1403 | if (ret < 0) | 1405 | if (ret < 0) |
1404 | dev_err(w->dapm->dev, | 1406 | dev_err(w->dapm->dev, |
1405 | "Failed to apply widget power: %d\n", ret); | 1407 | "ASoC: Failed to apply widget power: %d\n", ret); |
1406 | } | 1408 | } |
1407 | 1409 | ||
1408 | if (!list_empty(&pending)) | 1410 | if (!list_empty(&pending)) |
@@ -1431,20 +1433,21 @@ static void dapm_widget_update(struct snd_soc_dapm_context *dapm) | |||
1431 | (w->event_flags & SND_SOC_DAPM_PRE_REG)) { | 1433 | (w->event_flags & SND_SOC_DAPM_PRE_REG)) { |
1432 | ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG); | 1434 | ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG); |
1433 | if (ret != 0) | 1435 | if (ret != 0) |
1434 | pr_err("%s DAPM pre-event failed: %d\n", | 1436 | dev_err(dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n", |
1435 | w->name, ret); | 1437 | w->name, ret); |
1436 | } | 1438 | } |
1437 | 1439 | ||
1438 | ret = soc_widget_update_bits_locked(w, update->reg, update->mask, | 1440 | ret = soc_widget_update_bits_locked(w, update->reg, update->mask, |
1439 | update->val); | 1441 | update->val); |
1440 | if (ret < 0) | 1442 | if (ret < 0) |
1441 | pr_err("%s DAPM update failed: %d\n", w->name, ret); | 1443 | dev_err(dapm->dev, "ASoC: %s DAPM update failed: %d\n", |
1444 | w->name, ret); | ||
1442 | 1445 | ||
1443 | if (w->event && | 1446 | if (w->event && |
1444 | (w->event_flags & SND_SOC_DAPM_POST_REG)) { | 1447 | (w->event_flags & SND_SOC_DAPM_POST_REG)) { |
1445 | ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG); | 1448 | ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG); |
1446 | if (ret != 0) | 1449 | if (ret != 0) |
1447 | pr_err("%s DAPM post-event failed: %d\n", | 1450 | dev_err(dapm->dev, "ASoC: %s DAPM post-event failed: %d\n", |
1448 | w->name, ret); | 1451 | w->name, ret); |
1449 | } | 1452 | } |
1450 | } | 1453 | } |
@@ -1466,7 +1469,7 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) | |||
1466 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); | 1469 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); |
1467 | if (ret != 0) | 1470 | if (ret != 0) |
1468 | dev_err(d->dev, | 1471 | dev_err(d->dev, |
1469 | "Failed to turn on bias: %d\n", ret); | 1472 | "ASoC: Failed to turn on bias: %d\n", ret); |
1470 | } | 1473 | } |
1471 | 1474 | ||
1472 | /* Prepare for a STADDBY->ON or ON->STANDBY transition */ | 1475 | /* Prepare for a STADDBY->ON or ON->STANDBY transition */ |
@@ -1474,7 +1477,7 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) | |||
1474 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE); | 1477 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE); |
1475 | if (ret != 0) | 1478 | if (ret != 0) |
1476 | dev_err(d->dev, | 1479 | dev_err(d->dev, |
1477 | "Failed to prepare bias: %d\n", ret); | 1480 | "ASoC: Failed to prepare bias: %d\n", ret); |
1478 | } | 1481 | } |
1479 | } | 1482 | } |
1480 | 1483 | ||
@@ -1492,7 +1495,7 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) | |||
1492 | d->target_bias_level == SND_SOC_BIAS_OFF)) { | 1495 | d->target_bias_level == SND_SOC_BIAS_OFF)) { |
1493 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); | 1496 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); |
1494 | if (ret != 0) | 1497 | if (ret != 0) |
1495 | dev_err(d->dev, "Failed to apply standby bias: %d\n", | 1498 | dev_err(d->dev, "ASoC: Failed to apply standby bias: %d\n", |
1496 | ret); | 1499 | ret); |
1497 | } | 1500 | } |
1498 | 1501 | ||
@@ -1501,7 +1504,8 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) | |||
1501 | d->target_bias_level == SND_SOC_BIAS_OFF) { | 1504 | d->target_bias_level == SND_SOC_BIAS_OFF) { |
1502 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF); | 1505 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF); |
1503 | if (ret != 0) | 1506 | if (ret != 0) |
1504 | dev_err(d->dev, "Failed to turn off bias: %d\n", ret); | 1507 | dev_err(d->dev, "ASoC: Failed to turn off bias: %d\n", |
1508 | ret); | ||
1505 | 1509 | ||
1506 | if (d->dev) | 1510 | if (d->dev) |
1507 | pm_runtime_put(d->dev); | 1511 | pm_runtime_put(d->dev); |
@@ -1512,7 +1516,7 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) | |||
1512 | d->target_bias_level == SND_SOC_BIAS_ON) { | 1516 | d->target_bias_level == SND_SOC_BIAS_ON) { |
1513 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON); | 1517 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON); |
1514 | if (ret != 0) | 1518 | if (ret != 0) |
1515 | dev_err(d->dev, "Failed to apply active bias: %d\n", | 1519 | dev_err(d->dev, "ASoC: Failed to apply active bias: %d\n", |
1516 | ret); | 1520 | ret); |
1517 | } | 1521 | } |
1518 | } | 1522 | } |
@@ -1838,7 +1842,7 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, | |||
1838 | 1842 | ||
1839 | if (!dapm->debugfs_dapm) { | 1843 | if (!dapm->debugfs_dapm) { |
1840 | dev_warn(dapm->dev, | 1844 | dev_warn(dapm->dev, |
1841 | "Failed to create DAPM debugfs directory\n"); | 1845 | "ASoC: Failed to create DAPM debugfs directory\n"); |
1842 | return; | 1846 | return; |
1843 | } | 1847 | } |
1844 | 1848 | ||
@@ -2123,7 +2127,7 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, | |||
2123 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); | 2127 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); |
2124 | 2128 | ||
2125 | if (!w) { | 2129 | if (!w) { |
2126 | dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); | 2130 | dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin); |
2127 | return -EINVAL; | 2131 | return -EINVAL; |
2128 | } | 2132 | } |
2129 | 2133 | ||
@@ -2212,8 +2216,16 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, | |||
2212 | if (!wsource) | 2216 | if (!wsource) |
2213 | wsource = wtsource; | 2217 | wsource = wtsource; |
2214 | 2218 | ||
2215 | if (wsource == NULL || wsink == NULL) | 2219 | if (wsource == NULL) { |
2220 | dev_err(dapm->dev, "ASoC: no source widget found for %s\n", | ||
2221 | route->source); | ||
2216 | return -ENODEV; | 2222 | return -ENODEV; |
2223 | } | ||
2224 | if (wsink == NULL) { | ||
2225 | dev_err(dapm->dev, "ASoC: no sink widget found for %s\n", | ||
2226 | route->sink); | ||
2227 | return -ENODEV; | ||
2228 | } | ||
2217 | 2229 | ||
2218 | path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); | 2230 | path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); |
2219 | if (!path) | 2231 | if (!path) |
@@ -2308,7 +2320,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, | |||
2308 | return 0; | 2320 | return 0; |
2309 | 2321 | ||
2310 | err: | 2322 | err: |
2311 | dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n", | 2323 | dev_warn(dapm->dev, "ASoC: no dapm match for %s --> %s --> %s\n", |
2312 | source, control, sink); | 2324 | source, control, sink); |
2313 | kfree(path); | 2325 | kfree(path); |
2314 | return ret; | 2326 | return ret; |
@@ -2325,7 +2337,7 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, | |||
2325 | 2337 | ||
2326 | if (route->control) { | 2338 | if (route->control) { |
2327 | dev_err(dapm->dev, | 2339 | dev_err(dapm->dev, |
2328 | "Removal of routes with controls not supported\n"); | 2340 | "ASoC: Removal of routes with controls not supported\n"); |
2329 | return -EINVAL; | 2341 | return -EINVAL; |
2330 | } | 2342 | } |
2331 | 2343 | ||
@@ -2360,7 +2372,7 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, | |||
2360 | list_del(&path->list_source); | 2372 | list_del(&path->list_source); |
2361 | kfree(path); | 2373 | kfree(path); |
2362 | } else { | 2374 | } else { |
2363 | dev_warn(dapm->dev, "Route %s->%s does not exist\n", | 2375 | dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n", |
2364 | source, sink); | 2376 | source, sink); |
2365 | } | 2377 | } |
2366 | 2378 | ||
@@ -2389,8 +2401,10 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, | |||
2389 | for (i = 0; i < num; i++) { | 2401 | for (i = 0; i < num; i++) { |
2390 | r = snd_soc_dapm_add_route(dapm, route); | 2402 | r = snd_soc_dapm_add_route(dapm, route); |
2391 | if (r < 0) { | 2403 | if (r < 0) { |
2392 | dev_err(dapm->dev, "Failed to add route %s->%s\n", | 2404 | dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n", |
2393 | route->source, route->sink); | 2405 | route->source, |
2406 | route->control ? route->control : "direct", | ||
2407 | route->sink); | ||
2394 | ret = r; | 2408 | ret = r; |
2395 | } | 2409 | } |
2396 | route++; | 2410 | route++; |
@@ -2438,19 +2452,19 @@ static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm, | |||
2438 | int count = 0; | 2452 | int count = 0; |
2439 | 2453 | ||
2440 | if (!source) { | 2454 | if (!source) { |
2441 | dev_err(dapm->dev, "Unable to find source %s for weak route\n", | 2455 | dev_err(dapm->dev, "ASoC: Unable to find source %s for weak route\n", |
2442 | route->source); | 2456 | route->source); |
2443 | return -ENODEV; | 2457 | return -ENODEV; |
2444 | } | 2458 | } |
2445 | 2459 | ||
2446 | if (!sink) { | 2460 | if (!sink) { |
2447 | dev_err(dapm->dev, "Unable to find sink %s for weak route\n", | 2461 | dev_err(dapm->dev, "ASoC: Unable to find sink %s for weak route\n", |
2448 | route->sink); | 2462 | route->sink); |
2449 | return -ENODEV; | 2463 | return -ENODEV; |
2450 | } | 2464 | } |
2451 | 2465 | ||
2452 | if (route->control || route->connected) | 2466 | if (route->control || route->connected) |
2453 | dev_warn(dapm->dev, "Ignoring control for weak route %s->%s\n", | 2467 | dev_warn(dapm->dev, "ASoC: Ignoring control for weak route %s->%s\n", |
2454 | route->source, route->sink); | 2468 | route->source, route->sink); |
2455 | 2469 | ||
2456 | list_for_each_entry(path, &source->sinks, list_source) { | 2470 | list_for_each_entry(path, &source->sinks, list_source) { |
@@ -2461,10 +2475,10 @@ static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm, | |||
2461 | } | 2475 | } |
2462 | 2476 | ||
2463 | if (count == 0) | 2477 | if (count == 0) |
2464 | dev_err(dapm->dev, "No path found for weak route %s->%s\n", | 2478 | dev_err(dapm->dev, "ASoC: No path found for weak route %s->%s\n", |
2465 | route->source, route->sink); | 2479 | route->source, route->sink); |
2466 | if (count > 1) | 2480 | if (count > 1) |
2467 | dev_warn(dapm->dev, "%d paths found for weak route %s->%s\n", | 2481 | dev_warn(dapm->dev, "ASoC: %d paths found for weak route %s->%s\n", |
2468 | count, route->source, route->sink); | 2482 | count, route->source, route->sink); |
2469 | 2483 | ||
2470 | return 0; | 2484 | return 0; |
@@ -2601,7 +2615,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, | |||
2601 | 2615 | ||
2602 | if (snd_soc_volsw_is_stereo(mc)) | 2616 | if (snd_soc_volsw_is_stereo(mc)) |
2603 | dev_warn(widget->dapm->dev, | 2617 | dev_warn(widget->dapm->dev, |
2604 | "Control '%s' is stereo, which is not supported\n", | 2618 | "ASoC: Control '%s' is stereo, which is not supported\n", |
2605 | kcontrol->id.name); | 2619 | kcontrol->id.name); |
2606 | 2620 | ||
2607 | ucontrol->value.integer.value[0] = | 2621 | ucontrol->value.integer.value[0] = |
@@ -2644,7 +2658,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
2644 | 2658 | ||
2645 | if (snd_soc_volsw_is_stereo(mc)) | 2659 | if (snd_soc_volsw_is_stereo(mc)) |
2646 | dev_warn(widget->dapm->dev, | 2660 | dev_warn(widget->dapm->dev, |
2647 | "Control '%s' is stereo, which is not supported\n", | 2661 | "ASoC: Control '%s' is stereo, which is not supported\n", |
2648 | kcontrol->id.name); | 2662 | kcontrol->id.name); |
2649 | 2663 | ||
2650 | val = (ucontrol->value.integer.value[0] & mask); | 2664 | val = (ucontrol->value.integer.value[0] & mask); |
@@ -3021,7 +3035,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
3021 | w->regulator = devm_regulator_get(dapm->dev, w->name); | 3035 | w->regulator = devm_regulator_get(dapm->dev, w->name); |
3022 | if (IS_ERR(w->regulator)) { | 3036 | if (IS_ERR(w->regulator)) { |
3023 | ret = PTR_ERR(w->regulator); | 3037 | ret = PTR_ERR(w->regulator); |
3024 | dev_err(dapm->dev, "Failed to request %s: %d\n", | 3038 | dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n", |
3025 | w->name, ret); | 3039 | w->name, ret); |
3026 | return NULL; | 3040 | return NULL; |
3027 | } | 3041 | } |
@@ -3031,7 +3045,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
3031 | w->clk = devm_clk_get(dapm->dev, w->name); | 3045 | w->clk = devm_clk_get(dapm->dev, w->name); |
3032 | if (IS_ERR(w->clk)) { | 3046 | if (IS_ERR(w->clk)) { |
3033 | ret = PTR_ERR(w->clk); | 3047 | ret = PTR_ERR(w->clk); |
3034 | dev_err(dapm->dev, "Failed to request %s: %d\n", | 3048 | dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n", |
3035 | w->name, ret); | 3049 | w->name, ret); |
3036 | return NULL; | 3050 | return NULL; |
3037 | } | 3051 | } |
@@ -3182,7 +3196,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, | |||
3182 | if (config->formats) { | 3196 | if (config->formats) { |
3183 | fmt = ffs(config->formats) - 1; | 3197 | fmt = ffs(config->formats) - 1; |
3184 | } else { | 3198 | } else { |
3185 | dev_warn(w->dapm->dev, "Invalid format %llx specified\n", | 3199 | dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n", |
3186 | config->formats); | 3200 | config->formats); |
3187 | fmt = 0; | 3201 | fmt = 0; |
3188 | } | 3202 | } |
@@ -3215,7 +3229,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, | |||
3215 | params, source); | 3229 | params, source); |
3216 | if (ret != 0) { | 3230 | if (ret != 0) { |
3217 | dev_err(source->dev, | 3231 | dev_err(source->dev, |
3218 | "hw_params() failed: %d\n", ret); | 3232 | "ASoC: hw_params() failed: %d\n", ret); |
3219 | goto out; | 3233 | goto out; |
3220 | } | 3234 | } |
3221 | } | 3235 | } |
@@ -3226,7 +3240,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, | |||
3226 | sink); | 3240 | sink); |
3227 | if (ret != 0) { | 3241 | if (ret != 0) { |
3228 | dev_err(sink->dev, | 3242 | dev_err(sink->dev, |
3229 | "hw_params() failed: %d\n", ret); | 3243 | "ASoC: hw_params() failed: %d\n", ret); |
3230 | goto out; | 3244 | goto out; |
3231 | } | 3245 | } |
3232 | } | 3246 | } |
@@ -3235,14 +3249,14 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, | |||
3235 | case SND_SOC_DAPM_POST_PMU: | 3249 | case SND_SOC_DAPM_POST_PMU: |
3236 | ret = snd_soc_dai_digital_mute(sink, 0); | 3250 | ret = snd_soc_dai_digital_mute(sink, 0); |
3237 | if (ret != 0 && ret != -ENOTSUPP) | 3251 | if (ret != 0 && ret != -ENOTSUPP) |
3238 | dev_warn(sink->dev, "Failed to unmute: %d\n", ret); | 3252 | dev_warn(sink->dev, "ASoC: Failed to unmute: %d\n", ret); |
3239 | ret = 0; | 3253 | ret = 0; |
3240 | break; | 3254 | break; |
3241 | 3255 | ||
3242 | case SND_SOC_DAPM_PRE_PMD: | 3256 | case SND_SOC_DAPM_PRE_PMD: |
3243 | ret = snd_soc_dai_digital_mute(sink, 1); | 3257 | ret = snd_soc_dai_digital_mute(sink, 1); |
3244 | if (ret != 0 && ret != -ENOTSUPP) | 3258 | if (ret != 0 && ret != -ENOTSUPP) |
3245 | dev_warn(sink->dev, "Failed to mute: %d\n", ret); | 3259 | dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret); |
3246 | ret = 0; | 3260 | ret = 0; |
3247 | break; | 3261 | break; |
3248 | 3262 | ||
@@ -3281,11 +3295,11 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, | |||
3281 | template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 3295 | template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | |
3282 | SND_SOC_DAPM_PRE_PMD; | 3296 | SND_SOC_DAPM_PRE_PMD; |
3283 | 3297 | ||
3284 | dev_dbg(card->dev, "adding %s widget\n", link_name); | 3298 | dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name); |
3285 | 3299 | ||
3286 | w = snd_soc_dapm_new_control(&card->dapm, &template); | 3300 | w = snd_soc_dapm_new_control(&card->dapm, &template); |
3287 | if (!w) { | 3301 | if (!w) { |
3288 | dev_err(card->dev, "Failed to create %s widget\n", | 3302 | dev_err(card->dev, "ASoC: Failed to create %s widget\n", |
3289 | link_name); | 3303 | link_name); |
3290 | return -ENOMEM; | 3304 | return -ENOMEM; |
3291 | } | 3305 | } |
@@ -3319,12 +3333,12 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, | |||
3319 | template.name = dai->driver->playback.stream_name; | 3333 | template.name = dai->driver->playback.stream_name; |
3320 | template.sname = dai->driver->playback.stream_name; | 3334 | template.sname = dai->driver->playback.stream_name; |
3321 | 3335 | ||
3322 | dev_dbg(dai->dev, "adding %s widget\n", | 3336 | dev_dbg(dai->dev, "ASoC: adding %s widget\n", |
3323 | template.name); | 3337 | template.name); |
3324 | 3338 | ||
3325 | w = snd_soc_dapm_new_control(dapm, &template); | 3339 | w = snd_soc_dapm_new_control(dapm, &template); |
3326 | if (!w) { | 3340 | if (!w) { |
3327 | dev_err(dapm->dev, "Failed to create %s widget\n", | 3341 | dev_err(dapm->dev, "ASoC: Failed to create %s widget\n", |
3328 | dai->driver->playback.stream_name); | 3342 | dai->driver->playback.stream_name); |
3329 | } | 3343 | } |
3330 | 3344 | ||
@@ -3337,12 +3351,12 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, | |||
3337 | template.name = dai->driver->capture.stream_name; | 3351 | template.name = dai->driver->capture.stream_name; |
3338 | template.sname = dai->driver->capture.stream_name; | 3352 | template.sname = dai->driver->capture.stream_name; |
3339 | 3353 | ||
3340 | dev_dbg(dai->dev, "adding %s widget\n", | 3354 | dev_dbg(dai->dev, "ASoC: adding %s widget\n", |
3341 | template.name); | 3355 | template.name); |
3342 | 3356 | ||
3343 | w = snd_soc_dapm_new_control(dapm, &template); | 3357 | w = snd_soc_dapm_new_control(dapm, &template); |
3344 | if (!w) { | 3358 | if (!w) { |
3345 | dev_err(dapm->dev, "Failed to create %s widget\n", | 3359 | dev_err(dapm->dev, "ASoC: Failed to create %s widget\n", |
3346 | dai->driver->capture.stream_name); | 3360 | dai->driver->capture.stream_name); |
3347 | } | 3361 | } |
3348 | 3362 | ||
@@ -3518,11 +3532,11 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | |||
3518 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); | 3532 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); |
3519 | 3533 | ||
3520 | if (!w) { | 3534 | if (!w) { |
3521 | dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); | 3535 | dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); |
3522 | return -EINVAL; | 3536 | return -EINVAL; |
3523 | } | 3537 | } |
3524 | 3538 | ||
3525 | dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin); | 3539 | dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin); |
3526 | w->connected = 1; | 3540 | w->connected = 1; |
3527 | w->force = 1; | 3541 | w->force = 1; |
3528 | dapm_mark_dirty(w, "force enable"); | 3542 | dapm_mark_dirty(w, "force enable"); |
@@ -3605,7 +3619,7 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, | |||
3605 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, false); | 3619 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, false); |
3606 | 3620 | ||
3607 | if (!w) { | 3621 | if (!w) { |
3608 | dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); | 3622 | dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); |
3609 | return -EINVAL; | 3623 | return -EINVAL; |
3610 | } | 3624 | } |
3611 | 3625 | ||
@@ -3664,7 +3678,7 @@ void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec) | |||
3664 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 3678 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
3665 | struct snd_soc_dapm_widget *w; | 3679 | struct snd_soc_dapm_widget *w; |
3666 | 3680 | ||
3667 | dev_dbg(codec->dev, "Auto NC: DAPMs: card:%p codec:%p\n", | 3681 | dev_dbg(codec->dev, "ASoC: Auto NC: DAPMs: card:%p codec:%p\n", |
3668 | &card->dapm, &codec->dapm); | 3682 | &card->dapm, &codec->dapm); |
3669 | 3683 | ||
3670 | list_for_each_entry(w, &card->widgets, list) { | 3684 | list_for_each_entry(w, &card->widgets, list) { |
@@ -3674,7 +3688,7 @@ void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec) | |||
3674 | case snd_soc_dapm_input: | 3688 | case snd_soc_dapm_input: |
3675 | case snd_soc_dapm_output: | 3689 | case snd_soc_dapm_output: |
3676 | case snd_soc_dapm_micbias: | 3690 | case snd_soc_dapm_micbias: |
3677 | dev_dbg(codec->dev, "Auto NC: Checking widget %s\n", | 3691 | dev_dbg(codec->dev, "ASoC: Auto NC: Checking widget %s\n", |
3678 | w->name); | 3692 | w->name); |
3679 | if (!snd_soc_dapm_widget_in_card_paths(card, w)) { | 3693 | if (!snd_soc_dapm_widget_in_card_paths(card, w)) { |
3680 | dev_dbg(codec->dev, | 3694 | dev_dbg(codec->dev, |
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index bbc125748a38..111b7d921e89 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c | |||
@@ -317,3 +317,5 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream) | |||
317 | return 0; | 317 | return 0; |
318 | } | 318 | } |
319 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); | 319 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); |
320 | |||
321 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 1ab5fe04bfcc..0bb5cccd7766 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c | |||
@@ -66,7 +66,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | |||
66 | struct snd_soc_dapm_context *dapm; | 66 | struct snd_soc_dapm_context *dapm; |
67 | struct snd_soc_jack_pin *pin; | 67 | struct snd_soc_jack_pin *pin; |
68 | int enable; | 68 | int enable; |
69 | int oldstatus; | ||
70 | 69 | ||
71 | trace_snd_soc_jack_report(jack, mask, status); | 70 | trace_snd_soc_jack_report(jack, mask, status); |
72 | 71 | ||
@@ -78,8 +77,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | |||
78 | 77 | ||
79 | mutex_lock(&jack->mutex); | 78 | mutex_lock(&jack->mutex); |
80 | 79 | ||
81 | oldstatus = jack->status; | ||
82 | |||
83 | jack->status &= ~mask; | 80 | jack->status &= ~mask; |
84 | jack->status |= status & mask; | 81 | jack->status |= status & mask; |
85 | 82 | ||
@@ -172,12 +169,13 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, | |||
172 | 169 | ||
173 | for (i = 0; i < count; i++) { | 170 | for (i = 0; i < count; i++) { |
174 | if (!pins[i].pin) { | 171 | if (!pins[i].pin) { |
175 | printk(KERN_ERR "No name for pin %d\n", i); | 172 | dev_err(jack->codec->dev, "ASoC: No name for pin %d\n", |
173 | i); | ||
176 | return -EINVAL; | 174 | return -EINVAL; |
177 | } | 175 | } |
178 | if (!pins[i].mask) { | 176 | if (!pins[i].mask) { |
179 | printk(KERN_ERR "No mask for pin %d (%s)\n", i, | 177 | dev_err(jack->codec->dev, "ASoC: No mask for pin %d" |
180 | pins[i].pin); | 178 | " (%s)\n", i, pins[i].pin); |
181 | return -EINVAL; | 179 | return -EINVAL; |
182 | } | 180 | } |
183 | 181 | ||
@@ -297,13 +295,13 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, | |||
297 | 295 | ||
298 | for (i = 0; i < count; i++) { | 296 | for (i = 0; i < count; i++) { |
299 | if (!gpio_is_valid(gpios[i].gpio)) { | 297 | if (!gpio_is_valid(gpios[i].gpio)) { |
300 | printk(KERN_ERR "Invalid gpio %d\n", | 298 | dev_err(jack->codec->dev, "ASoC: Invalid gpio %d\n", |
301 | gpios[i].gpio); | 299 | gpios[i].gpio); |
302 | ret = -EINVAL; | 300 | ret = -EINVAL; |
303 | goto undo; | 301 | goto undo; |
304 | } | 302 | } |
305 | if (!gpios[i].name) { | 303 | if (!gpios[i].name) { |
306 | printk(KERN_ERR "No name for gpio %d\n", | 304 | dev_err(jack->codec->dev, "ASoC: No name for gpio %d\n", |
307 | gpios[i].gpio); | 305 | gpios[i].gpio); |
308 | ret = -EINVAL; | 306 | ret = -EINVAL; |
309 | goto undo; | 307 | goto undo; |
@@ -332,7 +330,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, | |||
332 | if (gpios[i].wake) { | 330 | if (gpios[i].wake) { |
333 | ret = irq_set_irq_wake(gpio_to_irq(gpios[i].gpio), 1); | 331 | ret = irq_set_irq_wake(gpio_to_irq(gpios[i].gpio), 1); |
334 | if (ret != 0) | 332 | if (ret != 0) |
335 | printk(KERN_ERR | 333 | dev_err(jack->codec->dev, "ASoC: " |
336 | "Failed to mark GPIO %d as wake source: %d\n", | 334 | "Failed to mark GPIO %d as wake source: %d\n", |
337 | gpios[i].gpio, ret); | 335 | gpios[i].gpio, ret); |
338 | } | 336 | } |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index ef22d0bd9e9e..5c3ca2a34661 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -43,7 +43,7 @@ static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, | |||
43 | 43 | ||
44 | struct snd_soc_pcm_runtime *be = dpcm->be; | 44 | struct snd_soc_pcm_runtime *be = dpcm->be; |
45 | 45 | ||
46 | dev_dbg(be->dev, "pm: BE %s event %d dir %d\n", | 46 | dev_dbg(be->dev, "ASoC: BE %s event %d dir %d\n", |
47 | be->dai_link->name, event, dir); | 47 | be->dai_link->name, event, dir); |
48 | 48 | ||
49 | snd_soc_dapm_stream_event(be, dir, event); | 49 | snd_soc_dapm_stream_event(be, dir, event); |
@@ -70,18 +70,19 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, | |||
70 | */ | 70 | */ |
71 | if (!soc_dai->rate) { | 71 | if (!soc_dai->rate) { |
72 | dev_warn(soc_dai->dev, | 72 | dev_warn(soc_dai->dev, |
73 | "Not enforcing symmetric_rates due to race\n"); | 73 | "ASoC: Not enforcing symmetric_rates due to race\n"); |
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | 76 | ||
77 | dev_dbg(soc_dai->dev, "Symmetry forces %dHz rate\n", soc_dai->rate); | 77 | dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", soc_dai->rate); |
78 | 78 | ||
79 | ret = snd_pcm_hw_constraint_minmax(substream->runtime, | 79 | ret = snd_pcm_hw_constraint_minmax(substream->runtime, |
80 | SNDRV_PCM_HW_PARAM_RATE, | 80 | SNDRV_PCM_HW_PARAM_RATE, |
81 | soc_dai->rate, soc_dai->rate); | 81 | soc_dai->rate, soc_dai->rate); |
82 | if (ret < 0) { | 82 | if (ret < 0) { |
83 | dev_err(soc_dai->dev, | 83 | dev_err(soc_dai->dev, |
84 | "Unable to apply rate symmetry constraint: %d\n", ret); | 84 | "ASoC: Unable to apply rate symmetry constraint: %d\n", |
85 | ret); | ||
85 | return ret; | 86 | return ret; |
86 | } | 87 | } |
87 | 88 | ||
@@ -118,7 +119,7 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream, | |||
118 | sample_sizes[i], bits); | 119 | sample_sizes[i], bits); |
119 | if (ret != 0) | 120 | if (ret != 0) |
120 | dev_warn(dai->dev, | 121 | dev_warn(dai->dev, |
121 | "Failed to set MSB %d/%d: %d\n", | 122 | "ASoC: Failed to set MSB %d/%d: %d\n", |
122 | bits, sample_sizes[i], ret); | 123 | bits, sample_sizes[i], ret); |
123 | } | 124 | } |
124 | } | 125 | } |
@@ -149,8 +150,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
149 | if (cpu_dai->driver->ops->startup) { | 150 | if (cpu_dai->driver->ops->startup) { |
150 | ret = cpu_dai->driver->ops->startup(substream, cpu_dai); | 151 | ret = cpu_dai->driver->ops->startup(substream, cpu_dai); |
151 | if (ret < 0) { | 152 | if (ret < 0) { |
152 | dev_err(cpu_dai->dev, "can't open interface %s: %d\n", | 153 | dev_err(cpu_dai->dev, "ASoC: can't open interface" |
153 | cpu_dai->name, ret); | 154 | " %s: %d\n", cpu_dai->name, ret); |
154 | goto out; | 155 | goto out; |
155 | } | 156 | } |
156 | } | 157 | } |
@@ -158,8 +159,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
158 | if (platform->driver->ops && platform->driver->ops->open) { | 159 | if (platform->driver->ops && platform->driver->ops->open) { |
159 | ret = platform->driver->ops->open(substream); | 160 | ret = platform->driver->ops->open(substream); |
160 | if (ret < 0) { | 161 | if (ret < 0) { |
161 | dev_err(platform->dev, "can't open platform %s: %d\n", | 162 | dev_err(platform->dev, "ASoC: can't open platform" |
162 | platform->name, ret); | 163 | " %s: %d\n", platform->name, ret); |
163 | goto platform_err; | 164 | goto platform_err; |
164 | } | 165 | } |
165 | } | 166 | } |
@@ -167,8 +168,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
167 | if (codec_dai->driver->ops->startup) { | 168 | if (codec_dai->driver->ops->startup) { |
168 | ret = codec_dai->driver->ops->startup(substream, codec_dai); | 169 | ret = codec_dai->driver->ops->startup(substream, codec_dai); |
169 | if (ret < 0) { | 170 | if (ret < 0) { |
170 | dev_err(codec_dai->dev, "can't open codec %s: %d\n", | 171 | dev_err(codec_dai->dev, "ASoC: can't open codec" |
171 | codec_dai->name, ret); | 172 | " %s: %d\n", codec_dai->name, ret); |
172 | goto codec_dai_err; | 173 | goto codec_dai_err; |
173 | } | 174 | } |
174 | } | 175 | } |
@@ -176,7 +177,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
176 | if (rtd->dai_link->ops && rtd->dai_link->ops->startup) { | 177 | if (rtd->dai_link->ops && rtd->dai_link->ops->startup) { |
177 | ret = rtd->dai_link->ops->startup(substream); | 178 | ret = rtd->dai_link->ops->startup(substream); |
178 | if (ret < 0) { | 179 | if (ret < 0) { |
179 | pr_err("asoc: %s startup failed: %d\n", | 180 | pr_err("ASoC: %s startup failed: %d\n", |
180 | rtd->dai_link->name, ret); | 181 | rtd->dai_link->name, ret); |
181 | goto machine_err; | 182 | goto machine_err; |
182 | } | 183 | } |
@@ -238,18 +239,18 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
238 | ret = -EINVAL; | 239 | ret = -EINVAL; |
239 | snd_pcm_limit_hw_rates(runtime); | 240 | snd_pcm_limit_hw_rates(runtime); |
240 | if (!runtime->hw.rates) { | 241 | if (!runtime->hw.rates) { |
241 | printk(KERN_ERR "asoc: %s <-> %s No matching rates\n", | 242 | printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n", |
242 | codec_dai->name, cpu_dai->name); | 243 | codec_dai->name, cpu_dai->name); |
243 | goto config_err; | 244 | goto config_err; |
244 | } | 245 | } |
245 | if (!runtime->hw.formats) { | 246 | if (!runtime->hw.formats) { |
246 | printk(KERN_ERR "asoc: %s <-> %s No matching formats\n", | 247 | printk(KERN_ERR "ASoC: %s <-> %s No matching formats\n", |
247 | codec_dai->name, cpu_dai->name); | 248 | codec_dai->name, cpu_dai->name); |
248 | goto config_err; | 249 | goto config_err; |
249 | } | 250 | } |
250 | if (!runtime->hw.channels_min || !runtime->hw.channels_max || | 251 | if (!runtime->hw.channels_min || !runtime->hw.channels_max || |
251 | runtime->hw.channels_min > runtime->hw.channels_max) { | 252 | runtime->hw.channels_min > runtime->hw.channels_max) { |
252 | printk(KERN_ERR "asoc: %s <-> %s No matching channels\n", | 253 | printk(KERN_ERR "ASoC: %s <-> %s No matching channels\n", |
253 | codec_dai->name, cpu_dai->name); | 254 | codec_dai->name, cpu_dai->name); |
254 | goto config_err; | 255 | goto config_err; |
255 | } | 256 | } |
@@ -270,12 +271,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
270 | goto config_err; | 271 | goto config_err; |
271 | } | 272 | } |
272 | 273 | ||
273 | pr_debug("asoc: %s <-> %s info:\n", | 274 | pr_debug("ASoC: %s <-> %s info:\n", |
274 | codec_dai->name, cpu_dai->name); | 275 | codec_dai->name, cpu_dai->name); |
275 | pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates); | 276 | pr_debug("ASoC: rate mask 0x%x\n", runtime->hw.rates); |
276 | pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, | 277 | pr_debug("ASoC: min ch %d max ch %d\n", runtime->hw.channels_min, |
277 | runtime->hw.channels_max); | 278 | runtime->hw.channels_max); |
278 | pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, | 279 | pr_debug("ASoC: min rate %d max rate %d\n", runtime->hw.rate_min, |
279 | runtime->hw.rate_max); | 280 | runtime->hw.rate_max); |
280 | 281 | ||
281 | dynamic: | 282 | dynamic: |
@@ -330,7 +331,7 @@ static void close_delayed_work(struct work_struct *work) | |||
330 | 331 | ||
331 | mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); | 332 | mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); |
332 | 333 | ||
333 | pr_debug("pop wq checking: %s status: %s waiting: %s\n", | 334 | dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n", |
334 | codec_dai->driver->playback.stream_name, | 335 | codec_dai->driver->playback.stream_name, |
335 | codec_dai->playback_active ? "active" : "inactive", | 336 | codec_dai->playback_active ? "active" : "inactive", |
336 | codec_dai->pop_wait ? "yes" : "no"); | 337 | codec_dai->pop_wait ? "yes" : "no"); |
@@ -444,7 +445,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
444 | if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) { | 445 | if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) { |
445 | ret = rtd->dai_link->ops->prepare(substream); | 446 | ret = rtd->dai_link->ops->prepare(substream); |
446 | if (ret < 0) { | 447 | if (ret < 0) { |
447 | pr_err("asoc: machine prepare error: %d\n", ret); | 448 | dev_err(rtd->card->dev, "ASoC: machine prepare error:" |
449 | " %d\n", ret); | ||
448 | goto out; | 450 | goto out; |
449 | } | 451 | } |
450 | } | 452 | } |
@@ -452,8 +454,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
452 | if (platform->driver->ops && platform->driver->ops->prepare) { | 454 | if (platform->driver->ops && platform->driver->ops->prepare) { |
453 | ret = platform->driver->ops->prepare(substream); | 455 | ret = platform->driver->ops->prepare(substream); |
454 | if (ret < 0) { | 456 | if (ret < 0) { |
455 | dev_err(platform->dev, "platform prepare error: %d\n", | 457 | dev_err(platform->dev, "ASoC: platform prepare error:" |
456 | ret); | 458 | " %d\n", ret); |
457 | goto out; | 459 | goto out; |
458 | } | 460 | } |
459 | } | 461 | } |
@@ -461,7 +463,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
461 | if (codec_dai->driver->ops->prepare) { | 463 | if (codec_dai->driver->ops->prepare) { |
462 | ret = codec_dai->driver->ops->prepare(substream, codec_dai); | 464 | ret = codec_dai->driver->ops->prepare(substream, codec_dai); |
463 | if (ret < 0) { | 465 | if (ret < 0) { |
464 | dev_err(codec_dai->dev, "DAI prepare error: %d\n", | 466 | dev_err(codec_dai->dev, "ASoC: DAI prepare error: %d\n", |
465 | ret); | 467 | ret); |
466 | goto out; | 468 | goto out; |
467 | } | 469 | } |
@@ -470,7 +472,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
470 | if (cpu_dai->driver->ops->prepare) { | 472 | if (cpu_dai->driver->ops->prepare) { |
471 | ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); | 473 | ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); |
472 | if (ret < 0) { | 474 | if (ret < 0) { |
473 | dev_err(cpu_dai->dev, "DAI prepare error: %d\n", | 475 | dev_err(cpu_dai->dev, "ASoC: DAI prepare error: %d\n", |
474 | ret); | 476 | ret); |
475 | goto out; | 477 | goto out; |
476 | } | 478 | } |
@@ -512,7 +514,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
512 | if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) { | 514 | if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) { |
513 | ret = rtd->dai_link->ops->hw_params(substream, params); | 515 | ret = rtd->dai_link->ops->hw_params(substream, params); |
514 | if (ret < 0) { | 516 | if (ret < 0) { |
515 | pr_err("asoc: machine hw_params failed: %d\n", ret); | 517 | dev_err(rtd->card->dev, "ASoC: machine hw_params" |
518 | " failed: %d\n", ret); | ||
516 | goto out; | 519 | goto out; |
517 | } | 520 | } |
518 | } | 521 | } |
@@ -520,8 +523,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
520 | if (codec_dai->driver->ops->hw_params) { | 523 | if (codec_dai->driver->ops->hw_params) { |
521 | ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); | 524 | ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); |
522 | if (ret < 0) { | 525 | if (ret < 0) { |
523 | dev_err(codec_dai->dev, "can't set %s hw params: %d\n", | 526 | dev_err(codec_dai->dev, "ASoC: can't set %s hw params:" |
524 | codec_dai->name, ret); | 527 | " %d\n", codec_dai->name, ret); |
525 | goto codec_err; | 528 | goto codec_err; |
526 | } | 529 | } |
527 | } | 530 | } |
@@ -529,7 +532,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
529 | if (cpu_dai->driver->ops->hw_params) { | 532 | if (cpu_dai->driver->ops->hw_params) { |
530 | ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai); | 533 | ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai); |
531 | if (ret < 0) { | 534 | if (ret < 0) { |
532 | dev_err(cpu_dai->dev, "%s hw params failed: %d\n", | 535 | dev_err(cpu_dai->dev, "ASoC: %s hw params failed: %d\n", |
533 | cpu_dai->name, ret); | 536 | cpu_dai->name, ret); |
534 | goto interface_err; | 537 | goto interface_err; |
535 | } | 538 | } |
@@ -538,7 +541,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
538 | if (platform->driver->ops && platform->driver->ops->hw_params) { | 541 | if (platform->driver->ops && platform->driver->ops->hw_params) { |
539 | ret = platform->driver->ops->hw_params(substream, params); | 542 | ret = platform->driver->ops->hw_params(substream, params); |
540 | if (ret < 0) { | 543 | if (ret < 0) { |
541 | dev_err(platform->dev, "%s hw params failed: %d\n", | 544 | dev_err(platform->dev, "ASoC: %s hw params failed: %d\n", |
542 | platform->name, ret); | 545 | platform->name, ret); |
543 | goto platform_err; | 546 | goto platform_err; |
544 | } | 547 | } |
@@ -760,7 +763,7 @@ static void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) | |||
760 | struct snd_soc_dpcm *dpcm, *d; | 763 | struct snd_soc_dpcm *dpcm, *d; |
761 | 764 | ||
762 | list_for_each_entry_safe(dpcm, d, &fe->dpcm[stream].be_clients, list_be) { | 765 | list_for_each_entry_safe(dpcm, d, &fe->dpcm[stream].be_clients, list_be) { |
763 | dev_dbg(fe->dev, "BE %s disconnect check for %s\n", | 766 | dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n", |
764 | stream ? "capture" : "playback", | 767 | stream ? "capture" : "playback", |
765 | dpcm->be->dai_link->name); | 768 | dpcm->be->dai_link->name); |
766 | 769 | ||
@@ -815,7 +818,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, | |||
815 | } | 818 | } |
816 | } | 819 | } |
817 | 820 | ||
818 | dev_err(card->dev, "can't get %s BE for %s\n", | 821 | dev_err(card->dev, "ASoC: can't get %s BE for %s\n", |
819 | stream ? "capture" : "playback", widget->name); | 822 | stream ? "capture" : "playback", widget->name); |
820 | return NULL; | 823 | return NULL; |
821 | } | 824 | } |
@@ -866,7 +869,7 @@ static int dpcm_path_get(struct snd_soc_pcm_runtime *fe, | |||
866 | /* get number of valid DAI paths and their widgets */ | 869 | /* get number of valid DAI paths and their widgets */ |
867 | paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, &list); | 870 | paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, &list); |
868 | 871 | ||
869 | dev_dbg(fe->dev, "found %d audio %s paths\n", paths, | 872 | dev_dbg(fe->dev, "ASoC: found %d audio %s paths\n", paths, |
870 | stream ? "capture" : "playback"); | 873 | stream ? "capture" : "playback"); |
871 | 874 | ||
872 | *list_ = list; | 875 | *list_ = list; |
@@ -903,7 +906,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, | |||
903 | if (widget && widget_in_list(list, widget)) | 906 | if (widget && widget_in_list(list, widget)) |
904 | continue; | 907 | continue; |
905 | 908 | ||
906 | dev_dbg(fe->dev, "pruning %s BE %s for %s\n", | 909 | dev_dbg(fe->dev, "ASoC: pruning %s BE %s for %s\n", |
907 | stream ? "capture" : "playback", | 910 | stream ? "capture" : "playback", |
908 | dpcm->be->dai_link->name, fe->dai_link->name); | 911 | dpcm->be->dai_link->name, fe->dai_link->name); |
909 | dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; | 912 | dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; |
@@ -911,7 +914,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, | |||
911 | prune++; | 914 | prune++; |
912 | } | 915 | } |
913 | 916 | ||
914 | dev_dbg(fe->dev, "found %d old BE paths for pruning\n", prune); | 917 | dev_dbg(fe->dev, "ASoC: found %d old BE paths for pruning\n", prune); |
915 | return prune; | 918 | return prune; |
916 | } | 919 | } |
917 | 920 | ||
@@ -932,7 +935,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, | |||
932 | /* is there a valid BE rtd for this widget */ | 935 | /* is there a valid BE rtd for this widget */ |
933 | be = dpcm_get_be(card, list->widgets[i], stream); | 936 | be = dpcm_get_be(card, list->widgets[i], stream); |
934 | if (!be) { | 937 | if (!be) { |
935 | dev_err(fe->dev, "no BE found for %s\n", | 938 | dev_err(fe->dev, "ASoC: no BE found for %s\n", |
936 | list->widgets[i]->name); | 939 | list->widgets[i]->name); |
937 | continue; | 940 | continue; |
938 | } | 941 | } |
@@ -948,7 +951,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, | |||
948 | /* newly connected FE and BE */ | 951 | /* newly connected FE and BE */ |
949 | err = dpcm_be_connect(fe, be, stream); | 952 | err = dpcm_be_connect(fe, be, stream); |
950 | if (err < 0) { | 953 | if (err < 0) { |
951 | dev_err(fe->dev, "can't connect %s\n", | 954 | dev_err(fe->dev, "ASoC: can't connect %s\n", |
952 | list->widgets[i]->name); | 955 | list->widgets[i]->name); |
953 | break; | 956 | break; |
954 | } else if (err == 0) /* already connected */ | 957 | } else if (err == 0) /* already connected */ |
@@ -959,7 +962,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, | |||
959 | new++; | 962 | new++; |
960 | } | 963 | } |
961 | 964 | ||
962 | dev_dbg(fe->dev, "found %d new BE paths\n", new); | 965 | dev_dbg(fe->dev, "ASoC: found %d new BE paths\n", new); |
963 | return new; | 966 | return new; |
964 | } | 967 | } |
965 | 968 | ||
@@ -998,7 +1001,7 @@ static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe, | |||
998 | snd_soc_dpcm_get_substream(be, stream); | 1001 | snd_soc_dpcm_get_substream(be, stream); |
999 | 1002 | ||
1000 | if (be->dpcm[stream].users == 0) | 1003 | if (be->dpcm[stream].users == 0) |
1001 | dev_err(be->dev, "no users %s at close - state %d\n", | 1004 | dev_err(be->dev, "ASoC: no users %s at close - state %d\n", |
1002 | stream ? "capture" : "playback", | 1005 | stream ? "capture" : "playback", |
1003 | be->dpcm[stream].state); | 1006 | be->dpcm[stream].state); |
1004 | 1007 | ||
@@ -1032,7 +1035,7 @@ static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) | |||
1032 | 1035 | ||
1033 | /* first time the dpcm is open ? */ | 1036 | /* first time the dpcm is open ? */ |
1034 | if (be->dpcm[stream].users == DPCM_MAX_BE_USERS) | 1037 | if (be->dpcm[stream].users == DPCM_MAX_BE_USERS) |
1035 | dev_err(be->dev, "too many users %s at open %d\n", | 1038 | dev_err(be->dev, "ASoC: too many users %s at open %d\n", |
1036 | stream ? "capture" : "playback", | 1039 | stream ? "capture" : "playback", |
1037 | be->dpcm[stream].state); | 1040 | be->dpcm[stream].state); |
1038 | 1041 | ||
@@ -1043,15 +1046,15 @@ static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) | |||
1043 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE)) | 1046 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE)) |
1044 | continue; | 1047 | continue; |
1045 | 1048 | ||
1046 | dev_dbg(be->dev, "dpcm: open BE %s\n", be->dai_link->name); | 1049 | dev_dbg(be->dev, "ASoC: open BE %s\n", be->dai_link->name); |
1047 | 1050 | ||
1048 | be_substream->runtime = be->dpcm[stream].runtime; | 1051 | be_substream->runtime = be->dpcm[stream].runtime; |
1049 | err = soc_pcm_open(be_substream); | 1052 | err = soc_pcm_open(be_substream); |
1050 | if (err < 0) { | 1053 | if (err < 0) { |
1051 | dev_err(be->dev, "BE open failed %d\n", err); | 1054 | dev_err(be->dev, "ASoC: BE open failed %d\n", err); |
1052 | be->dpcm[stream].users--; | 1055 | be->dpcm[stream].users--; |
1053 | if (be->dpcm[stream].users < 0) | 1056 | if (be->dpcm[stream].users < 0) |
1054 | dev_err(be->dev, "no users %s at unwind %d\n", | 1057 | dev_err(be->dev, "ASoC: no users %s at unwind %d\n", |
1055 | stream ? "capture" : "playback", | 1058 | stream ? "capture" : "playback", |
1056 | be->dpcm[stream].state); | 1059 | be->dpcm[stream].state); |
1057 | 1060 | ||
@@ -1076,7 +1079,7 @@ unwind: | |||
1076 | continue; | 1079 | continue; |
1077 | 1080 | ||
1078 | if (be->dpcm[stream].users == 0) | 1081 | if (be->dpcm[stream].users == 0) |
1079 | dev_err(be->dev, "no users %s at close %d\n", | 1082 | dev_err(be->dev, "ASoC: no users %s at close %d\n", |
1080 | stream ? "capture" : "playback", | 1083 | stream ? "capture" : "playback", |
1081 | be->dpcm[stream].state); | 1084 | be->dpcm[stream].state); |
1082 | 1085 | ||
@@ -1128,16 +1131,16 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) | |||
1128 | 1131 | ||
1129 | ret = dpcm_be_dai_startup(fe, fe_substream->stream); | 1132 | ret = dpcm_be_dai_startup(fe, fe_substream->stream); |
1130 | if (ret < 0) { | 1133 | if (ret < 0) { |
1131 | dev_err(fe->dev,"dpcm: failed to start some BEs %d\n", ret); | 1134 | dev_err(fe->dev,"ASoC: failed to start some BEs %d\n", ret); |
1132 | goto be_err; | 1135 | goto be_err; |
1133 | } | 1136 | } |
1134 | 1137 | ||
1135 | dev_dbg(fe->dev, "dpcm: open FE %s\n", fe->dai_link->name); | 1138 | dev_dbg(fe->dev, "ASoC: open FE %s\n", fe->dai_link->name); |
1136 | 1139 | ||
1137 | /* start the DAI frontend */ | 1140 | /* start the DAI frontend */ |
1138 | ret = soc_pcm_open(fe_substream); | 1141 | ret = soc_pcm_open(fe_substream); |
1139 | if (ret < 0) { | 1142 | if (ret < 0) { |
1140 | dev_err(fe->dev,"dpcm: failed to start FE %d\n", ret); | 1143 | dev_err(fe->dev,"ASoC: failed to start FE %d\n", ret); |
1141 | goto unwind; | 1144 | goto unwind; |
1142 | } | 1145 | } |
1143 | 1146 | ||
@@ -1172,7 +1175,7 @@ static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream) | |||
1172 | continue; | 1175 | continue; |
1173 | 1176 | ||
1174 | if (be->dpcm[stream].users == 0) | 1177 | if (be->dpcm[stream].users == 0) |
1175 | dev_err(be->dev, "no users %s at close - state %d\n", | 1178 | dev_err(be->dev, "ASoC: no users %s at close - state %d\n", |
1176 | stream ? "capture" : "playback", | 1179 | stream ? "capture" : "playback", |
1177 | be->dpcm[stream].state); | 1180 | be->dpcm[stream].state); |
1178 | 1181 | ||
@@ -1183,7 +1186,7 @@ static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream) | |||
1183 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)) | 1186 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)) |
1184 | continue; | 1187 | continue; |
1185 | 1188 | ||
1186 | dev_dbg(be->dev, "dpcm: close BE %s\n", | 1189 | dev_dbg(be->dev, "ASoC: close BE %s\n", |
1187 | dpcm->fe->dai_link->name); | 1190 | dpcm->fe->dai_link->name); |
1188 | 1191 | ||
1189 | soc_pcm_close(be_substream); | 1192 | soc_pcm_close(be_substream); |
@@ -1204,7 +1207,7 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream) | |||
1204 | /* shutdown the BEs */ | 1207 | /* shutdown the BEs */ |
1205 | dpcm_be_dai_shutdown(fe, substream->stream); | 1208 | dpcm_be_dai_shutdown(fe, substream->stream); |
1206 | 1209 | ||
1207 | dev_dbg(fe->dev, "dpcm: close FE %s\n", fe->dai_link->name); | 1210 | dev_dbg(fe->dev, "ASoC: close FE %s\n", fe->dai_link->name); |
1208 | 1211 | ||
1209 | /* now shutdown the frontend */ | 1212 | /* now shutdown the frontend */ |
1210 | soc_pcm_close(substream); | 1213 | soc_pcm_close(substream); |
@@ -1243,7 +1246,7 @@ static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) | |||
1243 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) | 1246 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) |
1244 | continue; | 1247 | continue; |
1245 | 1248 | ||
1246 | dev_dbg(be->dev, "dpcm: hw_free BE %s\n", | 1249 | dev_dbg(be->dev, "ASoC: hw_free BE %s\n", |
1247 | dpcm->fe->dai_link->name); | 1250 | dpcm->fe->dai_link->name); |
1248 | 1251 | ||
1249 | soc_pcm_hw_free(be_substream); | 1252 | soc_pcm_hw_free(be_substream); |
@@ -1262,12 +1265,12 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream) | |||
1262 | mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); | 1265 | mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); |
1263 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; | 1266 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; |
1264 | 1267 | ||
1265 | dev_dbg(fe->dev, "dpcm: hw_free FE %s\n", fe->dai_link->name); | 1268 | dev_dbg(fe->dev, "ASoC: hw_free FE %s\n", fe->dai_link->name); |
1266 | 1269 | ||
1267 | /* call hw_free on the frontend */ | 1270 | /* call hw_free on the frontend */ |
1268 | err = soc_pcm_hw_free(substream); | 1271 | err = soc_pcm_hw_free(substream); |
1269 | if (err < 0) | 1272 | if (err < 0) |
1270 | dev_err(fe->dev,"dpcm: hw_free FE %s failed\n", | 1273 | dev_err(fe->dev,"ASoC: hw_free FE %s failed\n", |
1271 | fe->dai_link->name); | 1274 | fe->dai_link->name); |
1272 | 1275 | ||
1273 | /* only hw_params backends that are either sinks or sources | 1276 | /* only hw_params backends that are either sinks or sources |
@@ -1305,7 +1308,7 @@ static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) | |||
1305 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE)) | 1308 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE)) |
1306 | continue; | 1309 | continue; |
1307 | 1310 | ||
1308 | dev_dbg(be->dev, "dpcm: hw_params BE %s\n", | 1311 | dev_dbg(be->dev, "ASoC: hw_params BE %s\n", |
1309 | dpcm->fe->dai_link->name); | 1312 | dpcm->fe->dai_link->name); |
1310 | 1313 | ||
1311 | /* copy params for each dpcm */ | 1314 | /* copy params for each dpcm */ |
@@ -1318,7 +1321,7 @@ static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) | |||
1318 | &dpcm->hw_params); | 1321 | &dpcm->hw_params); |
1319 | if (ret < 0) { | 1322 | if (ret < 0) { |
1320 | dev_err(be->dev, | 1323 | dev_err(be->dev, |
1321 | "dpcm: hw_params BE fixup failed %d\n", | 1324 | "ASoC: hw_params BE fixup failed %d\n", |
1322 | ret); | 1325 | ret); |
1323 | goto unwind; | 1326 | goto unwind; |
1324 | } | 1327 | } |
@@ -1327,7 +1330,7 @@ static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) | |||
1327 | ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); | 1330 | ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); |
1328 | if (ret < 0) { | 1331 | if (ret < 0) { |
1329 | dev_err(dpcm->be->dev, | 1332 | dev_err(dpcm->be->dev, |
1330 | "dpcm: hw_params BE failed %d\n", ret); | 1333 | "ASoC: hw_params BE failed %d\n", ret); |
1331 | goto unwind; | 1334 | goto unwind; |
1332 | } | 1335 | } |
1333 | 1336 | ||
@@ -1374,18 +1377,18 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream, | |||
1374 | sizeof(struct snd_pcm_hw_params)); | 1377 | sizeof(struct snd_pcm_hw_params)); |
1375 | ret = dpcm_be_dai_hw_params(fe, substream->stream); | 1378 | ret = dpcm_be_dai_hw_params(fe, substream->stream); |
1376 | if (ret < 0) { | 1379 | if (ret < 0) { |
1377 | dev_err(fe->dev,"dpcm: hw_params BE failed %d\n", ret); | 1380 | dev_err(fe->dev,"ASoC: hw_params BE failed %d\n", ret); |
1378 | goto out; | 1381 | goto out; |
1379 | } | 1382 | } |
1380 | 1383 | ||
1381 | dev_dbg(fe->dev, "dpcm: hw_params FE %s rate %d chan %x fmt %d\n", | 1384 | dev_dbg(fe->dev, "ASoC: hw_params FE %s rate %d chan %x fmt %d\n", |
1382 | fe->dai_link->name, params_rate(params), | 1385 | fe->dai_link->name, params_rate(params), |
1383 | params_channels(params), params_format(params)); | 1386 | params_channels(params), params_format(params)); |
1384 | 1387 | ||
1385 | /* call hw_params on the frontend */ | 1388 | /* call hw_params on the frontend */ |
1386 | ret = soc_pcm_hw_params(substream, params); | 1389 | ret = soc_pcm_hw_params(substream, params); |
1387 | if (ret < 0) { | 1390 | if (ret < 0) { |
1388 | dev_err(fe->dev,"dpcm: hw_params FE failed %d\n", ret); | 1391 | dev_err(fe->dev,"ASoC: hw_params FE failed %d\n", ret); |
1389 | dpcm_be_dai_hw_free(fe, stream); | 1392 | dpcm_be_dai_hw_free(fe, stream); |
1390 | } else | 1393 | } else |
1391 | fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS; | 1394 | fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS; |
@@ -1401,12 +1404,12 @@ static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm, | |||
1401 | { | 1404 | { |
1402 | int ret; | 1405 | int ret; |
1403 | 1406 | ||
1404 | dev_dbg(dpcm->be->dev, "dpcm: trigger BE %s cmd %d\n", | 1407 | dev_dbg(dpcm->be->dev, "ASoC: trigger BE %s cmd %d\n", |
1405 | dpcm->fe->dai_link->name, cmd); | 1408 | dpcm->fe->dai_link->name, cmd); |
1406 | 1409 | ||
1407 | ret = soc_pcm_trigger(substream, cmd); | 1410 | ret = soc_pcm_trigger(substream, cmd); |
1408 | if (ret < 0) | 1411 | if (ret < 0) |
1409 | dev_err(dpcm->be->dev,"dpcm: trigger BE failed %d\n", ret); | 1412 | dev_err(dpcm->be->dev,"ASoC: trigger BE failed %d\n", ret); |
1410 | 1413 | ||
1411 | return ret; | 1414 | return ret; |
1412 | } | 1415 | } |
@@ -1517,12 +1520,12 @@ static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1517 | case SND_SOC_DPCM_TRIGGER_PRE: | 1520 | case SND_SOC_DPCM_TRIGGER_PRE: |
1518 | /* call trigger on the frontend before the backend. */ | 1521 | /* call trigger on the frontend before the backend. */ |
1519 | 1522 | ||
1520 | dev_dbg(fe->dev, "dpcm: pre trigger FE %s cmd %d\n", | 1523 | dev_dbg(fe->dev, "ASoC: pre trigger FE %s cmd %d\n", |
1521 | fe->dai_link->name, cmd); | 1524 | fe->dai_link->name, cmd); |
1522 | 1525 | ||
1523 | ret = soc_pcm_trigger(substream, cmd); | 1526 | ret = soc_pcm_trigger(substream, cmd); |
1524 | if (ret < 0) { | 1527 | if (ret < 0) { |
1525 | dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); | 1528 | dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); |
1526 | goto out; | 1529 | goto out; |
1527 | } | 1530 | } |
1528 | 1531 | ||
@@ -1533,11 +1536,11 @@ static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1533 | 1536 | ||
1534 | ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); | 1537 | ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); |
1535 | if (ret < 0) { | 1538 | if (ret < 0) { |
1536 | dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); | 1539 | dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); |
1537 | goto out; | 1540 | goto out; |
1538 | } | 1541 | } |
1539 | 1542 | ||
1540 | dev_dbg(fe->dev, "dpcm: post trigger FE %s cmd %d\n", | 1543 | dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n", |
1541 | fe->dai_link->name, cmd); | 1544 | fe->dai_link->name, cmd); |
1542 | 1545 | ||
1543 | ret = soc_pcm_trigger(substream, cmd); | 1546 | ret = soc_pcm_trigger(substream, cmd); |
@@ -1545,17 +1548,17 @@ static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1545 | case SND_SOC_DPCM_TRIGGER_BESPOKE: | 1548 | case SND_SOC_DPCM_TRIGGER_BESPOKE: |
1546 | /* bespoke trigger() - handles both FE and BEs */ | 1549 | /* bespoke trigger() - handles both FE and BEs */ |
1547 | 1550 | ||
1548 | dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd %d\n", | 1551 | dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd %d\n", |
1549 | fe->dai_link->name, cmd); | 1552 | fe->dai_link->name, cmd); |
1550 | 1553 | ||
1551 | ret = soc_pcm_bespoke_trigger(substream, cmd); | 1554 | ret = soc_pcm_bespoke_trigger(substream, cmd); |
1552 | if (ret < 0) { | 1555 | if (ret < 0) { |
1553 | dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); | 1556 | dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); |
1554 | goto out; | 1557 | goto out; |
1555 | } | 1558 | } |
1556 | break; | 1559 | break; |
1557 | default: | 1560 | default: |
1558 | dev_err(fe->dev, "dpcm: invalid trigger cmd %d for %s\n", cmd, | 1561 | dev_err(fe->dev, "ASoC: invalid trigger cmd %d for %s\n", cmd, |
1559 | fe->dai_link->name); | 1562 | fe->dai_link->name); |
1560 | ret = -EINVAL; | 1563 | ret = -EINVAL; |
1561 | goto out; | 1564 | goto out; |
@@ -1598,12 +1601,12 @@ static int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) | |||
1598 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) | 1601 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) |
1599 | continue; | 1602 | continue; |
1600 | 1603 | ||
1601 | dev_dbg(be->dev, "dpcm: prepare BE %s\n", | 1604 | dev_dbg(be->dev, "ASoC: prepare BE %s\n", |
1602 | dpcm->fe->dai_link->name); | 1605 | dpcm->fe->dai_link->name); |
1603 | 1606 | ||
1604 | ret = soc_pcm_prepare(be_substream); | 1607 | ret = soc_pcm_prepare(be_substream); |
1605 | if (ret < 0) { | 1608 | if (ret < 0) { |
1606 | dev_err(be->dev, "dpcm: backend prepare failed %d\n", | 1609 | dev_err(be->dev, "ASoC: backend prepare failed %d\n", |
1607 | ret); | 1610 | ret); |
1608 | break; | 1611 | break; |
1609 | } | 1612 | } |
@@ -1620,13 +1623,13 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) | |||
1620 | 1623 | ||
1621 | mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); | 1624 | mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); |
1622 | 1625 | ||
1623 | dev_dbg(fe->dev, "dpcm: prepare FE %s\n", fe->dai_link->name); | 1626 | dev_dbg(fe->dev, "ASoC: prepare FE %s\n", fe->dai_link->name); |
1624 | 1627 | ||
1625 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; | 1628 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; |
1626 | 1629 | ||
1627 | /* there is no point preparing this FE if there are no BEs */ | 1630 | /* there is no point preparing this FE if there are no BEs */ |
1628 | if (list_empty(&fe->dpcm[stream].be_clients)) { | 1631 | if (list_empty(&fe->dpcm[stream].be_clients)) { |
1629 | dev_err(fe->dev, "dpcm: no backend DAIs enabled for %s\n", | 1632 | dev_err(fe->dev, "ASoC: no backend DAIs enabled for %s\n", |
1630 | fe->dai_link->name); | 1633 | fe->dai_link->name); |
1631 | ret = -EINVAL; | 1634 | ret = -EINVAL; |
1632 | goto out; | 1635 | goto out; |
@@ -1639,7 +1642,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) | |||
1639 | /* call prepare on the frontend */ | 1642 | /* call prepare on the frontend */ |
1640 | ret = soc_pcm_prepare(substream); | 1643 | ret = soc_pcm_prepare(substream); |
1641 | if (ret < 0) { | 1644 | if (ret < 0) { |
1642 | dev_err(fe->dev,"dpcm: prepare FE %s failed\n", | 1645 | dev_err(fe->dev,"ASoC: prepare FE %s failed\n", |
1643 | fe->dai_link->name); | 1646 | fe->dai_link->name); |
1644 | goto out; | 1647 | goto out; |
1645 | } | 1648 | } |
@@ -1673,33 +1676,33 @@ static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream) | |||
1673 | enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; | 1676 | enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; |
1674 | int err; | 1677 | int err; |
1675 | 1678 | ||
1676 | dev_dbg(fe->dev, "runtime %s close on FE %s\n", | 1679 | dev_dbg(fe->dev, "ASoC: runtime %s close on FE %s\n", |
1677 | stream ? "capture" : "playback", fe->dai_link->name); | 1680 | stream ? "capture" : "playback", fe->dai_link->name); |
1678 | 1681 | ||
1679 | if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) { | 1682 | if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) { |
1680 | /* call bespoke trigger - FE takes care of all BE triggers */ | 1683 | /* call bespoke trigger - FE takes care of all BE triggers */ |
1681 | dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd stop\n", | 1684 | dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd stop\n", |
1682 | fe->dai_link->name); | 1685 | fe->dai_link->name); |
1683 | 1686 | ||
1684 | err = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_STOP); | 1687 | err = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_STOP); |
1685 | if (err < 0) | 1688 | if (err < 0) |
1686 | dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err); | 1689 | dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err); |
1687 | } else { | 1690 | } else { |
1688 | dev_dbg(fe->dev, "dpcm: trigger FE %s cmd stop\n", | 1691 | dev_dbg(fe->dev, "ASoC: trigger FE %s cmd stop\n", |
1689 | fe->dai_link->name); | 1692 | fe->dai_link->name); |
1690 | 1693 | ||
1691 | err = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_STOP); | 1694 | err = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_STOP); |
1692 | if (err < 0) | 1695 | if (err < 0) |
1693 | dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err); | 1696 | dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err); |
1694 | } | 1697 | } |
1695 | 1698 | ||
1696 | err = dpcm_be_dai_hw_free(fe, stream); | 1699 | err = dpcm_be_dai_hw_free(fe, stream); |
1697 | if (err < 0) | 1700 | if (err < 0) |
1698 | dev_err(fe->dev,"dpcm: hw_free FE failed %d\n", err); | 1701 | dev_err(fe->dev,"ASoC: hw_free FE failed %d\n", err); |
1699 | 1702 | ||
1700 | err = dpcm_be_dai_shutdown(fe, stream); | 1703 | err = dpcm_be_dai_shutdown(fe, stream); |
1701 | if (err < 0) | 1704 | if (err < 0) |
1702 | dev_err(fe->dev,"dpcm: shutdown FE failed %d\n", err); | 1705 | dev_err(fe->dev,"ASoC: shutdown FE failed %d\n", err); |
1703 | 1706 | ||
1704 | /* run the stream event for each BE */ | 1707 | /* run the stream event for each BE */ |
1705 | dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_NOP); | 1708 | dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_NOP); |
@@ -1715,7 +1718,7 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) | |||
1715 | enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; | 1718 | enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; |
1716 | int ret; | 1719 | int ret; |
1717 | 1720 | ||
1718 | dev_dbg(fe->dev, "runtime %s open on FE %s\n", | 1721 | dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n", |
1719 | stream ? "capture" : "playback", fe->dai_link->name); | 1722 | stream ? "capture" : "playback", fe->dai_link->name); |
1720 | 1723 | ||
1721 | /* Only start the BE if the FE is ready */ | 1724 | /* Only start the BE if the FE is ready */ |
@@ -1761,22 +1764,22 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) | |||
1761 | 1764 | ||
1762 | if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) { | 1765 | if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) { |
1763 | /* call trigger on the frontend - FE takes care of all BE triggers */ | 1766 | /* call trigger on the frontend - FE takes care of all BE triggers */ |
1764 | dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd start\n", | 1767 | dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd start\n", |
1765 | fe->dai_link->name); | 1768 | fe->dai_link->name); |
1766 | 1769 | ||
1767 | ret = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START); | 1770 | ret = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START); |
1768 | if (ret < 0) { | 1771 | if (ret < 0) { |
1769 | dev_err(fe->dev,"dpcm: bespoke trigger FE failed %d\n", ret); | 1772 | dev_err(fe->dev,"ASoC: bespoke trigger FE failed %d\n", ret); |
1770 | goto hw_free; | 1773 | goto hw_free; |
1771 | } | 1774 | } |
1772 | } else { | 1775 | } else { |
1773 | dev_dbg(fe->dev, "dpcm: trigger FE %s cmd start\n", | 1776 | dev_dbg(fe->dev, "ASoC: trigger FE %s cmd start\n", |
1774 | fe->dai_link->name); | 1777 | fe->dai_link->name); |
1775 | 1778 | ||
1776 | ret = dpcm_be_dai_trigger(fe, stream, | 1779 | ret = dpcm_be_dai_trigger(fe, stream, |
1777 | SNDRV_PCM_TRIGGER_START); | 1780 | SNDRV_PCM_TRIGGER_START); |
1778 | if (ret < 0) { | 1781 | if (ret < 0) { |
1779 | dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); | 1782 | dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); |
1780 | goto hw_free; | 1783 | goto hw_free; |
1781 | } | 1784 | } |
1782 | } | 1785 | } |
@@ -1805,7 +1808,7 @@ static int dpcm_run_new_update(struct snd_soc_pcm_runtime *fe, int stream) | |||
1805 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; | 1808 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; |
1806 | ret = dpcm_run_update_startup(fe, stream); | 1809 | ret = dpcm_run_update_startup(fe, stream); |
1807 | if (ret < 0) | 1810 | if (ret < 0) |
1808 | dev_err(fe->dev, "failed to startup some BEs\n"); | 1811 | dev_err(fe->dev, "ASoC: failed to startup some BEs\n"); |
1809 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; | 1812 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; |
1810 | 1813 | ||
1811 | return ret; | 1814 | return ret; |
@@ -1818,7 +1821,7 @@ static int dpcm_run_old_update(struct snd_soc_pcm_runtime *fe, int stream) | |||
1818 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; | 1821 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; |
1819 | ret = dpcm_run_update_shutdown(fe, stream); | 1822 | ret = dpcm_run_update_shutdown(fe, stream); |
1820 | if (ret < 0) | 1823 | if (ret < 0) |
1821 | dev_err(fe->dev, "failed to shutdown some BEs\n"); | 1824 | dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n"); |
1822 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; | 1825 | fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; |
1823 | 1826 | ||
1824 | return ret; | 1827 | return ret; |
@@ -1853,7 +1856,7 @@ int soc_dpcm_runtime_update(struct snd_soc_dapm_widget *widget) | |||
1853 | continue; | 1856 | continue; |
1854 | 1857 | ||
1855 | /* DAPM sync will call this to update DSP paths */ | 1858 | /* DAPM sync will call this to update DSP paths */ |
1856 | dev_dbg(fe->dev, "DPCM runtime update for FE %s\n", | 1859 | dev_dbg(fe->dev, "ASoC: DPCM runtime update for FE %s\n", |
1857 | fe->dai_link->name); | 1860 | fe->dai_link->name); |
1858 | 1861 | ||
1859 | /* skip if FE doesn't have playback capability */ | 1862 | /* skip if FE doesn't have playback capability */ |
@@ -1862,7 +1865,7 @@ int soc_dpcm_runtime_update(struct snd_soc_dapm_widget *widget) | |||
1862 | 1865 | ||
1863 | paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); | 1866 | paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); |
1864 | if (paths < 0) { | 1867 | if (paths < 0) { |
1865 | dev_warn(fe->dev, "%s no valid %s path\n", | 1868 | dev_warn(fe->dev, "ASoC: %s no valid %s path\n", |
1866 | fe->dai_link->name, "playback"); | 1869 | fe->dai_link->name, "playback"); |
1867 | mutex_unlock(&card->mutex); | 1870 | mutex_unlock(&card->mutex); |
1868 | return paths; | 1871 | return paths; |
@@ -1891,7 +1894,7 @@ capture: | |||
1891 | 1894 | ||
1892 | paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); | 1895 | paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); |
1893 | if (paths < 0) { | 1896 | if (paths < 0) { |
1894 | dev_warn(fe->dev, "%s no valid %s path\n", | 1897 | dev_warn(fe->dev, "ASoC: %s no valid %s path\n", |
1895 | fe->dai_link->name, "capture"); | 1898 | fe->dai_link->name, "capture"); |
1896 | mutex_unlock(&card->mutex); | 1899 | mutex_unlock(&card->mutex); |
1897 | return paths; | 1900 | return paths; |
@@ -1934,7 +1937,7 @@ int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute) | |||
1934 | if (be->dai_link->ignore_suspend) | 1937 | if (be->dai_link->ignore_suspend) |
1935 | continue; | 1938 | continue; |
1936 | 1939 | ||
1937 | dev_dbg(be->dev, "BE digital mute %s\n", be->dai_link->name); | 1940 | dev_dbg(be->dev, "ASoC: BE digital mute %s\n", be->dai_link->name); |
1938 | 1941 | ||
1939 | if (drv->ops->digital_mute && dai->playback_active) | 1942 | if (drv->ops->digital_mute && dai->playback_active) |
1940 | drv->ops->digital_mute(dai, mute); | 1943 | drv->ops->digital_mute(dai, mute); |
@@ -1955,7 +1958,7 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) | |||
1955 | fe->dpcm[stream].runtime = fe_substream->runtime; | 1958 | fe->dpcm[stream].runtime = fe_substream->runtime; |
1956 | 1959 | ||
1957 | if (dpcm_path_get(fe, stream, &list) <= 0) { | 1960 | if (dpcm_path_get(fe, stream, &list) <= 0) { |
1958 | dev_dbg(fe->dev, "asoc: %s no valid %s route\n", | 1961 | dev_dbg(fe->dev, "ASoC: %s no valid %s route\n", |
1959 | fe->dai_link->name, stream ? "capture" : "playback"); | 1962 | fe->dai_link->name, stream ? "capture" : "playback"); |
1960 | } | 1963 | } |
1961 | 1964 | ||
@@ -2039,11 +2042,11 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) | |||
2039 | capture, &pcm); | 2042 | capture, &pcm); |
2040 | } | 2043 | } |
2041 | if (ret < 0) { | 2044 | if (ret < 0) { |
2042 | dev_err(rtd->card->dev, "can't create pcm for %s\n", | 2045 | dev_err(rtd->card->dev, "ASoC: can't create pcm for %s\n", |
2043 | rtd->dai_link->name); | 2046 | rtd->dai_link->name); |
2044 | return ret; | 2047 | return ret; |
2045 | } | 2048 | } |
2046 | dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name); | 2049 | dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name); |
2047 | 2050 | ||
2048 | /* DAPM dai link stream work */ | 2051 | /* DAPM dai link stream work */ |
2049 | INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); | 2052 | INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); |
@@ -2097,7 +2100,9 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) | |||
2097 | if (platform->driver->pcm_new) { | 2100 | if (platform->driver->pcm_new) { |
2098 | ret = platform->driver->pcm_new(rtd); | 2101 | ret = platform->driver->pcm_new(rtd); |
2099 | if (ret < 0) { | 2102 | if (ret < 0) { |
2100 | dev_err(platform->dev, "pcm constructor failed\n"); | 2103 | dev_err(platform->dev, |
2104 | "ASoC: pcm constructor failed: %d\n", | ||
2105 | ret); | ||
2101 | return ret; | 2106 | return ret; |
2102 | } | 2107 | } |
2103 | } | 2108 | } |
diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c index bf99296bce95..49653375970b 100644 --- a/sound/soc/tegra/tegra20_das.c +++ b/sound/soc/tegra/tegra20_das.c | |||
@@ -210,7 +210,7 @@ static int __devexit tegra20_das_remove(struct platform_device *pdev) | |||
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |
212 | 212 | ||
213 | static const struct of_device_id tegra20_das_of_match[] __devinitconst = { | 213 | static const struct of_device_id tegra20_das_of_match[] = { |
214 | { .compatible = "nvidia,tegra20-das", }, | 214 | { .compatible = "nvidia,tegra20-das", }, |
215 | {}, | 215 | {}, |
216 | }; | 216 | }; |
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 0832e8afd73c..2ae8af86edbd 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c | |||
@@ -463,12 +463,12 @@ static int __devexit tegra20_i2s_platform_remove(struct platform_device *pdev) | |||
463 | return 0; | 463 | return 0; |
464 | } | 464 | } |
465 | 465 | ||
466 | static const struct of_device_id tegra20_i2s_of_match[] __devinitconst = { | 466 | static const struct of_device_id tegra20_i2s_of_match[] = { |
467 | { .compatible = "nvidia,tegra20-i2s", }, | 467 | { .compatible = "nvidia,tegra20-i2s", }, |
468 | {}, | 468 | {}, |
469 | }; | 469 | }; |
470 | 470 | ||
471 | static const struct dev_pm_ops tegra20_i2s_pm_ops __devinitconst = { | 471 | static const struct dev_pm_ops tegra20_i2s_pm_ops = { |
472 | SET_RUNTIME_PM_OPS(tegra20_i2s_runtime_suspend, | 472 | SET_RUNTIME_PM_OPS(tegra20_i2s_runtime_suspend, |
473 | tegra20_i2s_runtime_resume, NULL) | 473 | tegra20_i2s_runtime_resume, NULL) |
474 | }; | 474 | }; |
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index 3ebc8670ba00..d9641ef7b1ee 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c | |||
@@ -373,7 +373,7 @@ static int __devexit tegra20_spdif_platform_remove(struct platform_device *pdev) | |||
373 | return 0; | 373 | return 0; |
374 | } | 374 | } |
375 | 375 | ||
376 | static const struct dev_pm_ops tegra20_spdif_pm_ops __devinitconst = { | 376 | static const struct dev_pm_ops tegra20_spdif_pm_ops = { |
377 | SET_RUNTIME_PM_OPS(tegra20_spdif_runtime_suspend, | 377 | SET_RUNTIME_PM_OPS(tegra20_spdif_runtime_suspend, |
378 | tegra20_spdif_runtime_resume, NULL) | 378 | tegra20_spdif_runtime_resume, NULL) |
379 | }; | 379 | }; |
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index bf5610122c76..2269170b0df4 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c | |||
@@ -288,7 +288,7 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif) | |||
288 | } | 288 | } |
289 | EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source); | 289 | EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source); |
290 | 290 | ||
291 | static const char * const configlink_clocks[] __devinitconst = { | 291 | static const char * const configlink_clocks[] = { |
292 | "i2s0", | 292 | "i2s0", |
293 | "i2s1", | 293 | "i2s1", |
294 | "i2s2", | 294 | "i2s2", |
@@ -603,12 +603,12 @@ static int __devexit tegra30_ahub_remove(struct platform_device *pdev) | |||
603 | return 0; | 603 | return 0; |
604 | } | 604 | } |
605 | 605 | ||
606 | static const struct of_device_id tegra30_ahub_of_match[] __devinitconst = { | 606 | static const struct of_device_id tegra30_ahub_of_match[] = { |
607 | { .compatible = "nvidia,tegra30-ahub", }, | 607 | { .compatible = "nvidia,tegra30-ahub", }, |
608 | {}, | 608 | {}, |
609 | }; | 609 | }; |
610 | 610 | ||
611 | static const struct dev_pm_ops tegra30_ahub_pm_ops __devinitconst = { | 611 | static const struct dev_pm_ops tegra30_ahub_pm_ops = { |
612 | SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend, | 612 | SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend, |
613 | tegra30_ahub_runtime_resume, NULL) | 613 | tegra30_ahub_runtime_resume, NULL) |
614 | }; | 614 | }; |
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 44184228d1f0..bf0e089e7997 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c | |||
@@ -508,12 +508,12 @@ static int __devexit tegra30_i2s_platform_remove(struct platform_device *pdev) | |||
508 | return 0; | 508 | return 0; |
509 | } | 509 | } |
510 | 510 | ||
511 | static const struct of_device_id tegra30_i2s_of_match[] __devinitconst = { | 511 | static const struct of_device_id tegra30_i2s_of_match[] = { |
512 | { .compatible = "nvidia,tegra30-i2s", }, | 512 | { .compatible = "nvidia,tegra30-i2s", }, |
513 | {}, | 513 | {}, |
514 | }; | 514 | }; |
515 | 515 | ||
516 | static const struct dev_pm_ops tegra30_i2s_pm_ops __devinitconst = { | 516 | static const struct dev_pm_ops tegra30_i2s_pm_ops = { |
517 | SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend, | 517 | SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend, |
518 | tegra30_i2s_runtime_resume, NULL) | 518 | tegra30_i2s_runtime_resume, NULL) |
519 | }; | 519 | }; |
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 76cb1b363b71..523795a6e83e 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c | |||
@@ -242,7 +242,7 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev) | |||
242 | return 0; | 242 | return 0; |
243 | } | 243 | } |
244 | 244 | ||
245 | static const struct of_device_id tegra_alc5632_of_match[] __devinitconst = { | 245 | static const struct of_device_id tegra_alc5632_of_match[] = { |
246 | { .compatible = "nvidia,tegra-audio-alc5632", }, | 246 | { .compatible = "nvidia,tegra-audio-alc5632", }, |
247 | {}, | 247 | {}, |
248 | }; | 248 | }; |
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index ea9166d5c4eb..effe5b41b5f9 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c | |||
@@ -200,7 +200,7 @@ static int __devexit tegra_wm8753_driver_remove(struct platform_device *pdev) | |||
200 | return 0; | 200 | return 0; |
201 | } | 201 | } |
202 | 202 | ||
203 | static const struct of_device_id tegra_wm8753_of_match[] __devinitconst = { | 203 | static const struct of_device_id tegra_wm8753_of_match[] = { |
204 | { .compatible = "nvidia,tegra-audio-wm8753", }, | 204 | { .compatible = "nvidia,tegra-audio-wm8753", }, |
205 | {}, | 205 | {}, |
206 | }; | 206 | }; |
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index cee13b7bfb94..0f794126fbe4 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c | |||
@@ -417,7 +417,7 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) | |||
417 | return 0; | 417 | return 0; |
418 | } | 418 | } |
419 | 419 | ||
420 | static const struct of_device_id tegra_wm8903_of_match[] __devinitconst = { | 420 | static const struct of_device_id tegra_wm8903_of_match[] = { |
421 | { .compatible = "nvidia,tegra-audio-wm8903", }, | 421 | { .compatible = "nvidia,tegra-audio-wm8903", }, |
422 | {}, | 422 | {}, |
423 | }; | 423 | }; |
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index e69a4f7000d6..4a255a4d0c47 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c | |||
@@ -195,7 +195,7 @@ static int __devexit tegra_snd_trimslice_remove(struct platform_device *pdev) | |||
195 | return 0; | 195 | return 0; |
196 | } | 196 | } |
197 | 197 | ||
198 | static const struct of_device_id trimslice_of_match[] __devinitconst = { | 198 | static const struct of_device_id trimslice_of_match[] = { |
199 | { .compatible = "nvidia,tegra-audio-trimslice", }, | 199 | { .compatible = "nvidia,tegra-audio-trimslice", }, |
200 | {}, | 200 | {}, |
201 | }; | 201 | }; |
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index 54f7e25b6f7d..651a52a95fd7 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c | |||
@@ -33,7 +33,7 @@ struct snd_soc_dai_link mop500_dai_links[] = { | |||
33 | .stream_name = "ab8500_0", | 33 | .stream_name = "ab8500_0", |
34 | .cpu_dai_name = "ux500-msp-i2s.1", | 34 | .cpu_dai_name = "ux500-msp-i2s.1", |
35 | .codec_dai_name = "ab8500-codec-dai.0", | 35 | .codec_dai_name = "ab8500-codec-dai.0", |
36 | .platform_name = "ux500-pcm.0", | 36 | .platform_name = "ux500-msp-i2s.1", |
37 | .codec_name = "ab8500-codec.0", | 37 | .codec_name = "ab8500-codec.0", |
38 | .init = mop500_ab8500_machine_init, | 38 | .init = mop500_ab8500_machine_init, |
39 | .ops = mop500_ab8500_ops, | 39 | .ops = mop500_ab8500_ops, |
@@ -43,7 +43,7 @@ struct snd_soc_dai_link mop500_dai_links[] = { | |||
43 | .stream_name = "ab8500_1", | 43 | .stream_name = "ab8500_1", |
44 | .cpu_dai_name = "ux500-msp-i2s.3", | 44 | .cpu_dai_name = "ux500-msp-i2s.3", |
45 | .codec_dai_name = "ab8500-codec-dai.1", | 45 | .codec_dai_name = "ab8500-codec-dai.1", |
46 | .platform_name = "ux500-pcm.0", | 46 | .platform_name = "ux500-msp-i2s.3", |
47 | .codec_name = "ab8500-codec.0", | 47 | .codec_name = "ab8500-codec.0", |
48 | .init = NULL, | 48 | .init = NULL, |
49 | .ops = mop500_ab8500_ops, | 49 | .ops = mop500_ab8500_ops, |
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index be94bf9bf94f..478b4b60e0cc 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include "ux500_msp_i2s.h" | 29 | #include "ux500_msp_i2s.h" |
30 | #include "ux500_msp_dai.h" | 30 | #include "ux500_msp_dai.h" |
31 | #include "ux500_pcm.h" | ||
31 | 32 | ||
32 | static int setup_pcm_multichan(struct snd_soc_dai *dai, | 33 | static int setup_pcm_multichan(struct snd_soc_dai *dai, |
33 | struct ux500_msp_config *msp_config) | 34 | struct ux500_msp_config *msp_config) |
@@ -398,11 +399,28 @@ static int ux500_msp_dai_startup(struct snd_pcm_substream *substream, | |||
398 | return ret; | 399 | return ret; |
399 | } | 400 | } |
400 | 401 | ||
401 | /* Enable clock */ | 402 | /* Prepare and enable clocks */ |
402 | dev_dbg(dai->dev, "%s: Enabling MSP-clock.\n", __func__); | 403 | dev_dbg(dai->dev, "%s: Enabling MSP-clocks.\n", __func__); |
403 | clk_enable(drvdata->clk); | 404 | ret = clk_prepare_enable(drvdata->pclk); |
405 | if (ret) { | ||
406 | dev_err(drvdata->msp->dev, | ||
407 | "%s: Failed to prepare/enable pclk!\n", __func__); | ||
408 | goto err_pclk; | ||
409 | } | ||
404 | 410 | ||
405 | return 0; | 411 | ret = clk_prepare_enable(drvdata->clk); |
412 | if (ret) { | ||
413 | dev_err(drvdata->msp->dev, | ||
414 | "%s: Failed to prepare/enable clk!\n", __func__); | ||
415 | goto err_clk; | ||
416 | } | ||
417 | |||
418 | return ret; | ||
419 | err_clk: | ||
420 | clk_disable_unprepare(drvdata->pclk); | ||
421 | err_pclk: | ||
422 | regulator_disable(drvdata->reg_vape); | ||
423 | return ret; | ||
406 | } | 424 | } |
407 | 425 | ||
408 | static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream, | 426 | static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream, |
@@ -428,8 +446,9 @@ static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream, | |||
428 | __func__, dai->id, snd_pcm_stream_str(substream)); | 446 | __func__, dai->id, snd_pcm_stream_str(substream)); |
429 | } | 447 | } |
430 | 448 | ||
431 | /* Disable clock */ | 449 | /* Disable and unprepare clocks */ |
432 | clk_disable(drvdata->clk); | 450 | clk_disable_unprepare(drvdata->clk); |
451 | clk_disable_unprepare(drvdata->pclk); | ||
433 | 452 | ||
434 | /* Disable regulator */ | 453 | /* Disable regulator */ |
435 | ret = regulator_disable(drvdata->reg_vape); | 454 | ret = regulator_disable(drvdata->reg_vape); |
@@ -780,6 +799,14 @@ static int __devinit ux500_msp_drv_probe(struct platform_device *pdev) | |||
780 | } | 799 | } |
781 | prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50); | 800 | prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50); |
782 | 801 | ||
802 | drvdata->pclk = clk_get(&pdev->dev, "apb_pclk"); | ||
803 | if (IS_ERR(drvdata->pclk)) { | ||
804 | ret = (int)PTR_ERR(drvdata->pclk); | ||
805 | dev_err(&pdev->dev, "%s: ERROR: clk_get of pclk failed (%d)!\n", | ||
806 | __func__, ret); | ||
807 | goto err_pclk; | ||
808 | } | ||
809 | |||
783 | drvdata->clk = clk_get(&pdev->dev, NULL); | 810 | drvdata->clk = clk_get(&pdev->dev, NULL); |
784 | if (IS_ERR(drvdata->clk)) { | 811 | if (IS_ERR(drvdata->clk)) { |
785 | ret = (int)PTR_ERR(drvdata->clk); | 812 | ret = (int)PTR_ERR(drvdata->clk); |
@@ -806,12 +833,23 @@ static int __devinit ux500_msp_drv_probe(struct platform_device *pdev) | |||
806 | goto err_init_msp; | 833 | goto err_init_msp; |
807 | } | 834 | } |
808 | 835 | ||
836 | ret = ux500_pcm_register_platform(pdev); | ||
837 | if (ret < 0) { | ||
838 | dev_err(&pdev->dev, | ||
839 | "Error: %s: Failed to register PCM platform device!\n", | ||
840 | __func__); | ||
841 | goto err_reg_plat; | ||
842 | } | ||
843 | |||
809 | return 0; | 844 | return 0; |
810 | 845 | ||
846 | err_reg_plat: | ||
847 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); | ||
811 | err_init_msp: | 848 | err_init_msp: |
812 | clk_put(drvdata->clk); | 849 | clk_put(drvdata->clk); |
813 | |||
814 | err_clk: | 850 | err_clk: |
851 | clk_put(drvdata->pclk); | ||
852 | err_pclk: | ||
815 | devm_regulator_put(drvdata->reg_vape); | 853 | devm_regulator_put(drvdata->reg_vape); |
816 | 854 | ||
817 | return ret; | 855 | return ret; |
@@ -821,12 +859,15 @@ static int __devexit ux500_msp_drv_remove(struct platform_device *pdev) | |||
821 | { | 859 | { |
822 | struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(&pdev->dev); | 860 | struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(&pdev->dev); |
823 | 861 | ||
862 | ux500_pcm_unregister_platform(pdev); | ||
863 | |||
824 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); | 864 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); |
825 | 865 | ||
826 | devm_regulator_put(drvdata->reg_vape); | 866 | devm_regulator_put(drvdata->reg_vape); |
827 | prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); | 867 | prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); |
828 | 868 | ||
829 | clk_put(drvdata->clk); | 869 | clk_put(drvdata->clk); |
870 | clk_put(drvdata->pclk); | ||
830 | 871 | ||
831 | ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp); | 872 | ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp); |
832 | 873 | ||
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h index 98202a34a5dd..9c778d9c3838 100644 --- a/sound/soc/ux500/ux500_msp_dai.h +++ b/sound/soc/ux500/ux500_msp_dai.h | |||
@@ -69,6 +69,7 @@ struct ux500_msp_i2s_drvdata { | |||
69 | /* Clocks */ | 69 | /* Clocks */ |
70 | unsigned int master_clk; | 70 | unsigned int master_clk; |
71 | struct clk *clk; | 71 | struct clk *clk; |
72 | struct clk *pclk; | ||
72 | 73 | ||
73 | /* Regulators */ | 74 | /* Regulators */ |
74 | int vape_opp_constraint; | 75 | int vape_opp_constraint; |
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 1a04e248453c..894c9f4bb9f6 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c | |||
@@ -282,7 +282,7 @@ static struct snd_soc_platform_driver ux500_pcm_soc_drv = { | |||
282 | .pcm_new = ux500_pcm_new, | 282 | .pcm_new = ux500_pcm_new, |
283 | }; | 283 | }; |
284 | 284 | ||
285 | static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev) | 285 | int __devinit ux500_pcm_register_platform(struct platform_device *pdev) |
286 | { | 286 | { |
287 | int ret; | 287 | int ret; |
288 | 288 | ||
@@ -296,23 +296,12 @@ static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev) | |||
296 | 296 | ||
297 | return 0; | 297 | return 0; |
298 | } | 298 | } |
299 | EXPORT_SYMBOL_GPL(ux500_pcm_register_platform); | ||
299 | 300 | ||
300 | static int __devinit ux500_pcm_drv_remove(struct platform_device *pdev) | 301 | int __devexit ux500_pcm_unregister_platform(struct platform_device *pdev) |
301 | { | 302 | { |
302 | snd_soc_unregister_platform(&pdev->dev); | 303 | snd_soc_unregister_platform(&pdev->dev); |
303 | 304 | ||
304 | return 0; | 305 | return 0; |
305 | } | 306 | } |
306 | 307 | EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform); | |
307 | static struct platform_driver ux500_pcm_driver = { | ||
308 | .driver = { | ||
309 | .name = "ux500-pcm", | ||
310 | .owner = THIS_MODULE, | ||
311 | }, | ||
312 | |||
313 | .probe = ux500_pcm_drv_probe, | ||
314 | .remove = __devexit_p(ux500_pcm_drv_remove), | ||
315 | }; | ||
316 | module_platform_driver(ux500_pcm_driver); | ||
317 | |||
318 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h index 77ed44d371e9..76d344476afc 100644 --- a/sound/soc/ux500/ux500_pcm.h +++ b/sound/soc/ux500/ux500_pcm.h | |||
@@ -32,4 +32,7 @@ | |||
32 | #define UX500_PLATFORM_PERIODS_MAX 48 | 32 | #define UX500_PLATFORM_PERIODS_MAX 48 |
33 | #define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE) | 33 | #define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE) |
34 | 34 | ||
35 | int ux500_pcm_register_platform(struct platform_device *pdev); | ||
36 | int ux500_pcm_unregister_platform(struct platform_device *pdev); | ||
37 | |||
35 | #endif | 38 | #endif |
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index c83f6143c0eb..eeefbce3873c 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
@@ -148,6 +148,7 @@ struct snd_usb_midi_out_endpoint { | |||
148 | struct snd_usb_midi_out_endpoint* ep; | 148 | struct snd_usb_midi_out_endpoint* ep; |
149 | struct snd_rawmidi_substream *substream; | 149 | struct snd_rawmidi_substream *substream; |
150 | int active; | 150 | int active; |
151 | bool autopm_reference; | ||
151 | uint8_t cable; /* cable number << 4 */ | 152 | uint8_t cable; /* cable number << 4 */ |
152 | uint8_t state; | 153 | uint8_t state; |
153 | #define STATE_UNKNOWN 0 | 154 | #define STATE_UNKNOWN 0 |
@@ -1076,7 +1077,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | |||
1076 | return -ENXIO; | 1077 | return -ENXIO; |
1077 | } | 1078 | } |
1078 | err = usb_autopm_get_interface(umidi->iface); | 1079 | err = usb_autopm_get_interface(umidi->iface); |
1079 | if (err < 0) | 1080 | port->autopm_reference = err >= 0; |
1081 | if (err < 0 && err != -EACCES) | ||
1080 | return -EIO; | 1082 | return -EIO; |
1081 | substream->runtime->private_data = port; | 1083 | substream->runtime->private_data = port; |
1082 | port->state = STATE_UNKNOWN; | 1084 | port->state = STATE_UNKNOWN; |
@@ -1087,9 +1089,11 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | |||
1087 | static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) | 1089 | static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) |
1088 | { | 1090 | { |
1089 | struct snd_usb_midi* umidi = substream->rmidi->private_data; | 1091 | struct snd_usb_midi* umidi = substream->rmidi->private_data; |
1092 | struct usbmidi_out_port *port = substream->runtime->private_data; | ||
1090 | 1093 | ||
1091 | substream_open(substream, 0); | 1094 | substream_open(substream, 0); |
1092 | usb_autopm_put_interface(umidi->iface); | 1095 | if (port->autopm_reference) |
1096 | usb_autopm_put_interface(umidi->iface); | ||
1093 | return 0; | 1097 | return 0; |
1094 | } | 1098 | } |
1095 | 1099 | ||
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 5c12a3fe8c3e..ef6fa24fc473 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -459,7 +459,7 @@ static int configure_endpoint(struct snd_usb_substream *subs) | |||
459 | return ret; | 459 | return ret; |
460 | 460 | ||
461 | if (subs->sync_endpoint) | 461 | if (subs->sync_endpoint) |
462 | ret = snd_usb_endpoint_set_params(subs->data_endpoint, | 462 | ret = snd_usb_endpoint_set_params(subs->sync_endpoint, |
463 | subs->pcm_format, | 463 | subs->pcm_format, |
464 | subs->channels, | 464 | subs->channels, |
465 | subs->period_bytes, | 465 | subs->period_bytes, |